blob: 79586c607df9be67ef1e262b6a1e7b036b4c4575 [file] [log] [blame]
Junxiao Shia60d9362014-11-12 09:38:21 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -08003 * Copyright (c) 2013-2017 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 Shic828dfc2016-09-15 13:26:22 +000023#include "../lp/packet.hpp"
Junxiao Shi7357ef22016-09-07 02:39:37 +000024#include "../lp/tags.hpp"
25#include "../mgmt/nfd/controller.hpp"
26#include "../mgmt/nfd/control-response.hpp"
Junxiao Shia60d9362014-11-12 09:38:21 -070027#include "../transport/transport.hpp"
Junxiao Shia60d9362014-11-12 09:38:21 -070028
Davide Pesavento537dc3a2016-02-18 19:35:26 +010029#include <boost/asio/io_service.hpp>
30
Junxiao Shia60d9362014-11-12 09:38:21 -070031namespace ndn {
32namespace util {
33
Junxiao Shia60d9362014-11-12 09:38:21 -070034class DummyClientFace::Transport : public ndn::Transport
35{
36public:
37 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020038 receive(Block block) const
Junxiao Shia60d9362014-11-12 09:38:21 -070039 {
Eric Newberry83872fd2015-08-06 17:01:24 -070040 block.encode();
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020041 if (m_receiveCallback) {
Junxiao Shia60d9362014-11-12 09:38:21 -070042 m_receiveCallback(block);
Eric Newberry83872fd2015-08-06 17:01:24 -070043 }
Junxiao Shia60d9362014-11-12 09:38:21 -070044 }
45
Davide Pesavento57c07df2016-12-11 18:41:45 -050046 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020047 close() override
Junxiao Shia60d9362014-11-12 09:38:21 -070048 {
49 }
50
Davide Pesavento57c07df2016-12-11 18:41:45 -050051 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020052 pause() override
Junxiao Shia60d9362014-11-12 09:38:21 -070053 {
54 }
55
Davide Pesavento57c07df2016-12-11 18:41:45 -050056 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020057 resume() override
Junxiao Shia60d9362014-11-12 09:38:21 -070058 {
59 }
60
Davide Pesavento57c07df2016-12-11 18:41:45 -050061 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020062 send(const Block& wire) override
Junxiao Shia60d9362014-11-12 09:38:21 -070063 {
Junxiao Shi27913b42014-12-23 14:49:38 -070064 onSendBlock(wire);
Junxiao Shia60d9362014-11-12 09:38:21 -070065 }
66
Davide Pesavento57c07df2016-12-11 18:41:45 -050067 void
Davide Pesaventoaeeb3fc2016-08-14 03:40:02 +020068 send(const Block& header, const Block& payload) override
Junxiao Shia60d9362014-11-12 09:38:21 -070069 {
Alexander Afanasyevea719672015-02-10 20:25:23 -080070 EncodingBuffer encoder(header.size() + payload.size(), header.size() + payload.size());
71 encoder.appendByteArray(header.wire(), header.size());
72 encoder.appendByteArray(payload.wire(), payload.size());
73
74 this->send(encoder.block());
Junxiao Shia60d9362014-11-12 09:38:21 -070075 }
76
77 boost::asio::io_service&
78 getIoService()
79 {
80 return *m_ioService;
81 }
82
Junxiao Shi27913b42014-12-23 14:49:38 -070083public:
84 Signal<Transport, Block> onSendBlock;
Junxiao Shia60d9362014-11-12 09:38:21 -070085};
86
Alexander Afanasyev3a6da362015-12-29 20:31:03 -080087DummyClientFace::DummyClientFace(const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
88 : Face(make_shared<DummyClientFace::Transport>())
Alexander Afanasyev80782e02017-01-04 13:16:54 -080089 , m_internalKeyChain(new KeyChain)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070090 , m_keyChain(*m_internalKeyChain)
91{
92 this->construct(options);
93}
94
Alexander Afanasyev80782e02017-01-04 13:16:54 -080095DummyClientFace::DummyClientFace(KeyChain& keyChain,
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070096 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
97 : Face(make_shared<DummyClientFace::Transport>(), keyChain)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070098 , m_keyChain(keyChain)
Junxiao Shia60d9362014-11-12 09:38:21 -070099{
100 this->construct(options);
101}
102
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800103DummyClientFace::DummyClientFace(boost::asio::io_service& ioService,
104 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
105 : Face(make_shared<DummyClientFace::Transport>(), ioService)
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800106 , m_internalKeyChain(new KeyChain)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700107 , m_keyChain(*m_internalKeyChain)
108{
109 this->construct(options);
110}
111
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800112DummyClientFace::DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain,
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700113 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
114 : Face(make_shared<DummyClientFace::Transport>(), ioService, keyChain)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700115 , m_keyChain(keyChain)
Junxiao Shia60d9362014-11-12 09:38:21 -0700116{
117 this->construct(options);
118}
119
120void
121DummyClientFace::construct(const Options& options)
122{
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800123 static_pointer_cast<Transport>(getTransport())->onSendBlock.connect([this] (const Block& blockFromDaemon) {
Eric Newberrye3e25052015-11-28 20:37:08 -0700124 Block packet(blockFromDaemon);
125 packet.encode();
126 lp::Packet lpPacket(packet);
Alexander Afanasyevea719672015-02-10 20:25:23 -0800127
Eric Newberrye3e25052015-11-28 20:37:08 -0700128 Buffer::const_iterator begin, end;
129 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
130 Block block(&*begin, std::distance(begin, end));
Alexander Afanasyevea719672015-02-10 20:25:23 -0800131
Eric Newberrye3e25052015-11-28 20:37:08 -0700132 if (block.type() == tlv::Interest) {
133 shared_ptr<Interest> interest = make_shared<Interest>(block);
134 if (lpPacket.has<lp::NackField>()) {
135 shared_ptr<lp::Nack> nack = make_shared<lp::Nack>(std::move(*interest));
136 nack->setHeader(lpPacket.get<lp::NackField>());
137 if (lpPacket.has<lp::NextHopFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000138 nack->setTag(make_shared<lp::NextHopFaceIdTag>(lpPacket.get<lp::NextHopFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700139 }
Eric Newberry4d261b62016-11-10 13:40:09 -0700140 if (lpPacket.has<lp::CongestionMarkField>()) {
141 nack->setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
142 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700143 onSendNack(*nack);
Eric Newberry83872fd2015-08-06 17:01:24 -0700144 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700145 else {
146 if (lpPacket.has<lp::NextHopFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000147 interest->setTag(make_shared<lp::NextHopFaceIdTag>(lpPacket.get<lp::NextHopFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700148 }
Eric Newberry4d261b62016-11-10 13:40:09 -0700149 if (lpPacket.has<lp::CongestionMarkField>()) {
150 interest->setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
151 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700152 onSendInterest(*interest);
Eric Newberry83872fd2015-08-06 17:01:24 -0700153 }
Junxiao Shi27913b42014-12-23 14:49:38 -0700154 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700155 else if (block.type() == tlv::Data) {
156 shared_ptr<Data> data = make_shared<Data>(block);
157
158 if (lpPacket.has<lp::CachePolicyField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000159 data->setTag(make_shared<lp::CachePolicyTag>(lpPacket.get<lp::CachePolicyField>()));
Eric Newberrye3e25052015-11-28 20:37:08 -0700160 }
Eric Newberry4d261b62016-11-10 13:40:09 -0700161 if (lpPacket.has<lp::CongestionMarkField>()) {
162 data->setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
163 }
Eric Newberrye3e25052015-11-28 20:37:08 -0700164
165 onSendData(*data);
Junxiao Shi27913b42014-12-23 14:49:38 -0700166 }
167 });
168
Junxiao Shia60d9362014-11-12 09:38:21 -0700169 if (options.enablePacketLogging)
170 this->enablePacketLogging();
171
172 if (options.enableRegistrationReply)
173 this->enableRegistrationReply();
Junxiao Shic828dfc2016-09-15 13:26:22 +0000174
175 m_processEventsOverride = options.processEventsOverride;
Junxiao Shia60d9362014-11-12 09:38:21 -0700176}
177
178void
179DummyClientFace::enablePacketLogging()
180{
Junxiao Shi27913b42014-12-23 14:49:38 -0700181 onSendInterest.connect([this] (const Interest& interest) {
182 this->sentInterests.push_back(interest);
183 });
184 onSendData.connect([this] (const Data& data) {
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800185 this->sentData.push_back(data);
Junxiao Shi27913b42014-12-23 14:49:38 -0700186 });
Eric Newberry83872fd2015-08-06 17:01:24 -0700187 onSendNack.connect([this] (const lp::Nack& nack) {
188 this->sentNacks.push_back(nack);
189 });
Junxiao Shia60d9362014-11-12 09:38:21 -0700190}
191
192void
193DummyClientFace::enableRegistrationReply()
194{
Junxiao Shi27913b42014-12-23 14:49:38 -0700195 onSendInterest.connect([this] (const Interest& interest) {
Junxiao Shia60d9362014-11-12 09:38:21 -0700196 static const Name localhostRegistration("/localhost/nfd/rib");
197 if (!localhostRegistration.isPrefixOf(interest.getName()))
198 return;
199
200 nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
201 params.setFaceId(1);
Davide Pesaventoe8e48c22017-04-13 00:35:33 -0400202 params.setOrigin(nfd::ROUTE_ORIGIN_APP);
Junxiao Shia60d9362014-11-12 09:38:21 -0700203 if (interest.getName().get(3) == name::Component("register")) {
204 params.setCost(0);
205 }
206
207 nfd::ControlResponse resp;
208 resp.setCode(200);
209 resp.setBody(params.wireEncode());
210
211 shared_ptr<Data> data = make_shared<Data>(interest.getName());
212 data->setContent(resp.wireEncode());
213
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700214 m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
Junxiao Shia60d9362014-11-12 09:38:21 -0700215
216 this->getIoService().post([this, data] { this->receive(*data); });
Junxiao Shi27913b42014-12-23 14:49:38 -0700217 });
Junxiao Shia60d9362014-11-12 09:38:21 -0700218}
219
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -0800220template<typename Field, typename Tag, typename Packet>
Eric Newberry4d261b62016-11-10 13:40:09 -0700221static void
222addFieldFromTag(lp::Packet& lpPacket, const Packet& packet)
223{
224 shared_ptr<Tag> tag = static_cast<const TagHost&>(packet).getTag<Tag>();
225 if (tag != nullptr) {
226 lpPacket.add<Field>(*tag);
227 }
228}
229
Junxiao Shia60d9362014-11-12 09:38:21 -0700230void
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -0800231DummyClientFace::receive(const Interest& interest)
Junxiao Shia60d9362014-11-12 09:38:21 -0700232{
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -0800233 lp::Packet lpPacket(interest.wireEncode());
Alexander Afanasyevea719672015-02-10 20:25:23 -0800234
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -0800235 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, interest);
236 addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest);
237 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest);
Eric Newberry83872fd2015-08-06 17:01:24 -0700238
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800239 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
Junxiao Shia60d9362014-11-12 09:38:21 -0700240}
241
Eric Newberry83872fd2015-08-06 17:01:24 -0700242void
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -0800243DummyClientFace::receive(const Data& data)
244{
245 lp::Packet lpPacket(data.wireEncode());
246
247 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, data);
248 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
249
250 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
251}
252
253void
254DummyClientFace::receive(const lp::Nack& nack)
Eric Newberry83872fd2015-08-06 17:01:24 -0700255{
256 lp::Packet lpPacket;
257 lpPacket.add<lp::NackField>(nack.getHeader());
258 Block interest = nack.getInterest().wireEncode();
259 lpPacket.add<lp::FragmentField>(make_pair(interest.begin(), interest.end()));
260
Zhiyi Zhang9cbd0102017-01-03 11:03:01 -0800261 addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
262 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
Eric Newberry83872fd2015-08-06 17:01:24 -0700263
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800264 static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
Eric Newberry83872fd2015-08-06 17:01:24 -0700265}
Junxiao Shia60d9362014-11-12 09:38:21 -0700266
Junxiao Shic828dfc2016-09-15 13:26:22 +0000267void
268DummyClientFace::doProcessEvents(const time::milliseconds& timeout, bool keepThread)
269{
270 if (m_processEventsOverride != nullptr) {
271 m_processEventsOverride(timeout);
272 }
273 else {
274 this->Face::doProcessEvents(timeout, keepThread);
275 }
276}
277
Junxiao Shia60d9362014-11-12 09:38:21 -0700278} // namespace util
279} // namespace ndn