blob: a1c6408a06b6753fad32fc9a50ab169c00e2f15b [file] [log] [blame]
Junxiao Shia60d9362014-11-12 09:38:21 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesavento537dc3a2016-02-18 19:35:26 +01003 * Copyright (c) 2013-2016 Regents of the University of California.
Junxiao Shia60d9362014-11-12 09:38:21 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "dummy-client-face.hpp"
Junxiao Shi7357ef22016-09-07 02:39:37 +000023#include "../lp/tags.hpp"
24#include "../mgmt/nfd/controller.hpp"
25#include "../mgmt/nfd/control-response.hpp"
Junxiao Shia60d9362014-11-12 09:38:21 -070026#include "../transport/transport.hpp"
Junxiao Shia60d9362014-11-12 09:38:21 -070027
Davide Pesavento537dc3a2016-02-18 19:35:26 +010028#include <boost/asio/io_service.hpp>
29
Junxiao Shia60d9362014-11-12 09:38:21 -070030namespace ndn {
31namespace util {
32
Junxiao Shia1478db2016-09-09 04:13:15 +000033const DummyClientFace::Options DummyClientFace::DEFAULT_OPTIONS{true, false};
Junxiao Shia60d9362014-11-12 09:38:21 -070034
35class DummyClientFace::Transport : public ndn::Transport
36{
37public:
38 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020039 receive(Block block) const
Junxiao Shia60d9362014-11-12 09:38:21 -070040 {
Eric Newberry83872fd2015-08-06 17:01:24 -070041 block.encode();
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020042 if (m_receiveCallback) {
Junxiao Shia60d9362014-11-12 09:38:21 -070043 m_receiveCallback(block);
Eric Newberry83872fd2015-08-06 17:01:24 -070044 }
Junxiao Shia60d9362014-11-12 09:38:21 -070045 }
46
47 virtual void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020048 close() override
Junxiao Shia60d9362014-11-12 09:38:21 -070049 {
50 }
51
52 virtual void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020053 pause() override
Junxiao Shia60d9362014-11-12 09:38:21 -070054 {
55 }
56
57 virtual void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020058 resume() override
Junxiao Shia60d9362014-11-12 09:38:21 -070059 {
60 }
61
62 virtual void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020063 send(const Block& wire) override
Junxiao Shia60d9362014-11-12 09:38:21 -070064 {
Junxiao Shi27913b42014-12-23 14:49:38 -070065 onSendBlock(wire);
Junxiao Shia60d9362014-11-12 09:38:21 -070066 }
67
68 virtual void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020069 send(const Block& header, const Block& payload) override
Junxiao Shia60d9362014-11-12 09:38:21 -070070 {
Alexander Afanasyevea719672015-02-10 20:25:23 -080071 EncodingBuffer encoder(header.size() + payload.size(), header.size() + payload.size());
72 encoder.appendByteArray(header.wire(), header.size());
73 encoder.appendByteArray(payload.wire(), payload.size());
74
75 this->send(encoder.block());
Junxiao Shia60d9362014-11-12 09:38:21 -070076 }
77
78 boost::asio::io_service&
79 getIoService()
80 {
81 return *m_ioService;
82 }
83
Junxiao Shi27913b42014-12-23 14:49:38 -070084public:
85 Signal<Transport, Block> onSendBlock;
Junxiao Shia60d9362014-11-12 09:38:21 -070086};
87
Alexander Afanasyev3a6da362015-12-29 20:31:03 -080088DummyClientFace::DummyClientFace(const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
89 : Face(make_shared<DummyClientFace::Transport>())
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070090 , m_internalKeyChain(new KeyChain)
91 , m_keyChain(*m_internalKeyChain)
92{
93 this->construct(options);
94}
95
96DummyClientFace::DummyClientFace(KeyChain& keyChain,
97 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
98 : Face(make_shared<DummyClientFace::Transport>(), keyChain)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070099 , m_keyChain(keyChain)
Junxiao Shia60d9362014-11-12 09:38:21 -0700100{
101 this->construct(options);
102}
103
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800104DummyClientFace::DummyClientFace(boost::asio::io_service& ioService,
105 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
106 : Face(make_shared<DummyClientFace::Transport>(), ioService)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700107 , m_internalKeyChain(new KeyChain)
108 , m_keyChain(*m_internalKeyChain)
109{
110 this->construct(options);
111}
112
113DummyClientFace::DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain,
114 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
115 : Face(make_shared<DummyClientFace::Transport>(), ioService, keyChain)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700116 , m_keyChain(keyChain)
Junxiao Shia60d9362014-11-12 09:38:21 -0700117{
118 this->construct(options);
119}
120
121void
122DummyClientFace::construct(const Options& options)
123{
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800124 static_pointer_cast<Transport>(getTransport())->onSendBlock.connect([this] (const Block& blockFromDaemon) {
Eric Newberrye3e25052015-11-28 20:37:08 -0700125 Block packet(blockFromDaemon);
126 packet.encode();
127 lp::Packet lpPacket(packet);
Alexander Afanasyevea719672015-02-10 20:25:23 -0800128
Eric Newberrye3e25052015-11-28 20:37:08 -0700129 Buffer::const_iterator begin, end;
130 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
131 Block block(&*begin, std::distance(begin, end));
Alexander Afanasyevea719672015-02-10 20:25:23 -0800132
Eric Newberrye3e25052015-11-28 20:37:08 -0700133 if (block.type() == tlv::Interest) {
134 shared_ptr<Interest> interest = make_shared<Interest>(block);
135 if (lpPacket.has<lp::NackField>()) {
136 shared_ptr<lp::Nack> nack = make_shared<lp::Nack>(std::move(*interest));
137 nack->setHeader(lpPacket.get<lp::NackField>());
138 if (lpPacket.has<lp::NextHopFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000139 nack->setTag(make_shared<lp::NextHopFaceIdTag>(lpPacket.get<lp::NextHopFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700140 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700141 onSendNack(*nack);
Eric Newberry83872fd2015-08-06 17:01:24 -0700142 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700143 else {
144 if (lpPacket.has<lp::NextHopFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000145 interest->setTag(make_shared<lp::NextHopFaceIdTag>(lpPacket.get<lp::NextHopFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700146 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700147 onSendInterest(*interest);
Eric Newberry83872fd2015-08-06 17:01:24 -0700148 }
Junxiao Shi27913b42014-12-23 14:49:38 -0700149 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700150 else if (block.type() == tlv::Data) {
151 shared_ptr<Data> data = make_shared<Data>(block);
152
153 if (lpPacket.has<lp::CachePolicyField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000154 data->setTag(make_shared<lp::CachePolicyTag>(lpPacket.get<lp::CachePolicyField>()));
Eric Newberrye3e25052015-11-28 20:37:08 -0700155 }
156
157 onSendData(*data);
Junxiao Shi27913b42014-12-23 14:49:38 -0700158 }
159 });
160
Junxiao Shia60d9362014-11-12 09:38:21 -0700161 if (options.enablePacketLogging)
162 this->enablePacketLogging();
163
164 if (options.enableRegistrationReply)
165 this->enableRegistrationReply();
166}
167
168void
169DummyClientFace::enablePacketLogging()
170{
Junxiao Shi27913b42014-12-23 14:49:38 -0700171 onSendInterest.connect([this] (const Interest& interest) {
172 this->sentInterests.push_back(interest);
173 });
174 onSendData.connect([this] (const Data& data) {
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800175 this->sentData.push_back(data);
Junxiao Shi27913b42014-12-23 14:49:38 -0700176 });
Eric Newberry83872fd2015-08-06 17:01:24 -0700177 onSendNack.connect([this] (const lp::Nack& nack) {
178 this->sentNacks.push_back(nack);
179 });
Junxiao Shia60d9362014-11-12 09:38:21 -0700180}
181
182void
183DummyClientFace::enableRegistrationReply()
184{
Junxiao Shi27913b42014-12-23 14:49:38 -0700185 onSendInterest.connect([this] (const Interest& interest) {
Junxiao Shia60d9362014-11-12 09:38:21 -0700186 static const Name localhostRegistration("/localhost/nfd/rib");
187 if (!localhostRegistration.isPrefixOf(interest.getName()))
188 return;
189
190 nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
191 params.setFaceId(1);
192 params.setOrigin(0);
193 if (interest.getName().get(3) == name::Component("register")) {
194 params.setCost(0);
195 }
196
197 nfd::ControlResponse resp;
198 resp.setCode(200);
199 resp.setBody(params.wireEncode());
200
201 shared_ptr<Data> data = make_shared<Data>(interest.getName());
202 data->setContent(resp.wireEncode());
203
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700204 m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
Junxiao Shia60d9362014-11-12 09:38:21 -0700205
206 this->getIoService().post([this, data] { this->receive(*data); });
Junxiao Shi27913b42014-12-23 14:49:38 -0700207 });
Junxiao Shia60d9362014-11-12 09:38:21 -0700208}
209
210template<typename Packet>
211void
212DummyClientFace::receive(const Packet& packet)
213{
Eric Newberry83872fd2015-08-06 17:01:24 -0700214 lp::Packet lpPacket(packet.wireEncode());
Alexander Afanasyevea719672015-02-10 20:25:23 -0800215
Junxiao Shi4b469982015-12-03 18:20:19 +0000216 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag =
217 static_cast<const TagHost&>(packet).getTag<lp::IncomingFaceIdTag>();
218 if (incomingFaceIdTag != nullptr) {
219 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
Alexander Afanasyevea719672015-02-10 20:25:23 -0800220 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700221
Junxiao Shi4b469982015-12-03 18:20:19 +0000222 shared_ptr<lp::NextHopFaceIdTag> nextHopFaceIdTag =
223 static_cast<const TagHost&>(packet).getTag<lp::NextHopFaceIdTag>();
224 if (nextHopFaceIdTag != nullptr) {
225 lpPacket.add<lp::NextHopFaceIdField>(*nextHopFaceIdTag);
Alexander Afanasyevea719672015-02-10 20:25:23 -0800226 }
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800227 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
Junxiao Shia60d9362014-11-12 09:38:21 -0700228}
229
230template void
231DummyClientFace::receive<Interest>(const Interest& packet);
232
233template void
234DummyClientFace::receive<Data>(const Data& packet);
235
Eric Newberry83872fd2015-08-06 17:01:24 -0700236template<>
237void
238DummyClientFace::receive<lp::Nack>(const lp::Nack& nack)
239{
240 lp::Packet lpPacket;
241 lpPacket.add<lp::NackField>(nack.getHeader());
242 Block interest = nack.getInterest().wireEncode();
243 lpPacket.add<lp::FragmentField>(make_pair(interest.begin(), interest.end()));
244
Junxiao Shi4b469982015-12-03 18:20:19 +0000245 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = nack.getTag<lp::IncomingFaceIdTag>();
246 if (incomingFaceIdTag != nullptr) {
247 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
Eric Newberry83872fd2015-08-06 17:01:24 -0700248 }
249
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800250 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
Eric Newberry83872fd2015-08-06 17:01:24 -0700251}
Junxiao Shia60d9362014-11-12 09:38:21 -0700252
Junxiao Shia60d9362014-11-12 09:38:21 -0700253} // namespace util
254} // namespace ndn