blob: 9f78680891316073125f44a53a986cf6108bee44 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -07002/**
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070020 */
21
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080022#include "face.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070023#include "detail/face-impl.hpp"
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070024
Junxiao Shi468abc32014-11-04 09:12:47 -070025#include "encoding/tlv.hpp"
Junxiao Shic6acc7a2015-06-23 10:03:56 -070026#include "security/signing-helpers.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080027#include "util/time.hpp"
28#include "util/random.hpp"
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070029#include "util/face-uri.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070030
Junxiao Shiae0b4182016-08-08 22:53:17 +000031// A callback scheduled through io.post and io.dispatch may be invoked after the face
32// is destructed. To prevent this situation, these macros captures Face::m_impl as weak_ptr,
33// and skips callback execution if the face has been destructed.
34#define IO_CAPTURE_WEAK_IMPL(OP) \
35 { \
36 weak_ptr<Impl> implWeak(m_impl); \
37 m_ioService.OP([=] { \
38 auto impl = implWeak.lock(); \
39 if (impl != nullptr) {
40#define IO_CAPTURE_WEAK_IMPL_END \
41 } \
42 }); \
43 }
44
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070045namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080046
Junxiao Shi103d8ed2016-08-07 20:34:10 +000047Face::Face(shared_ptr<Transport> transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070048 : m_internalIoService(new boost::asio::io_service())
49 , m_ioService(*m_internalIoService)
50 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000051 , m_impl(make_shared<Impl>(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070052{
Junxiao Shi103d8ed2016-08-07 20:34:10 +000053 construct(transport, *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080054}
55
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070056Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070057 : m_ioService(ioService)
58 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000059 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070060{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080061 construct(nullptr, *m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070062}
63
Junxiao Shi103d8ed2016-08-07 20:34:10 +000064Face::Face(const std::string& host, const std::string& port)
Junxiao Shi2cced062014-11-02 21:27:38 -070065 : m_internalIoService(new boost::asio::io_service())
66 , m_ioService(*m_internalIoService)
67 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000068 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080069{
Joao Pereira68c0d882015-05-19 14:27:55 -040070 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080071}
72
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070073Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
74 : m_internalIoService(new boost::asio::io_service())
75 , m_ioService(*m_internalIoService)
Junxiao Shiae0b4182016-08-08 22:53:17 +000076 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070077{
78 construct(transport, keyChain);
79}
80
81Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070082 : m_ioService(ioService)
83 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000084 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080085{
Joao Pereira68c0d882015-05-19 14:27:55 -040086 construct(transport, *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070087}
88
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070089Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070090 : m_ioService(ioService)
Junxiao Shiae0b4182016-08-08 22:53:17 +000091 , m_impl(make_shared<Impl>(*this))
Junxiao Shiedd834e2014-10-28 20:28:58 -070092{
Joao Pereira68c0d882015-05-19 14:27:55 -040093 construct(transport, keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080094}
95
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080096shared_ptr<Transport>
97Face::makeDefaultTransport()
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070098{
99 // transport=unix:///var/run/nfd.sock
100 // transport=tcp://localhost:6363
101
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700102 std::string transportUri;
103
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000104 const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
105 if (transportEnviron != nullptr) {
106 transportUri = transportEnviron;
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700107 }
108 else {
109 ConfigFile config;
110 transportUri = config.getParsedConfiguration().get<std::string>("transport", "");
111 }
112
113 if (transportUri.empty()) {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800114 // transport not specified, use default Unix transport.
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700115 return UnixTransport::create("");
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800116 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700117
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800118 std::string protocol;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800119 try {
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700120 util::FaceUri uri(transportUri);
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800121 protocol = uri.getScheme();
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700122
123 if (protocol == "unix") {
124 return UnixTransport::create(transportUri);
125 }
126 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6") {
127 return TcpTransport::create(transportUri);
128 }
129 else {
130 BOOST_THROW_EXCEPTION(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
131 }
132 }
133 catch (const Transport::Error& error) {
134 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800135 }
136 catch (const util::FaceUri::Error& error) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700137 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800138 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700139}
140
141void
Joao Pereira68c0d882015-05-19 14:27:55 -0400142Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800143{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800144 if (transport == nullptr) {
145 transport = makeDefaultTransport();
146 }
147 BOOST_ASSERT(transport != nullptr);
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800148 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800149
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800150 m_nfdController.reset(new nfd::Controller(*this, keyChain));
151
Junxiao Shiae0b4182016-08-08 22:53:17 +0000152 IO_CAPTURE_WEAK_IMPL(post) {
153 impl->ensureConnected(false);
154 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800155}
156
Joao Pereira68c0d882015-05-19 14:27:55 -0400157Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700158
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800159shared_ptr<Transport>
160Face::getTransport()
161{
162 return m_transport;
163}
164
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800165const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700166Face::expressInterest(const Interest& interest,
167 const DataCallback& afterSatisfied,
168 const NackCallback& afterNacked,
169 const TimeoutCallback& afterTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800170{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700171 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800172
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700173 // Use `interestToExpress` to avoid wire format creation for the original Interest
Eric Newberry83872fd2015-08-06 17:01:24 -0700174 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700175 BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
Eric Newberry83872fd2015-08-06 17:01:24 -0700176 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700177
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700178 // If the same ioService thread, dispatch directly calls the method
Junxiao Shiae0b4182016-08-08 22:53:17 +0000179 IO_CAPTURE_WEAK_IMPL(dispatch) {
180 impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
181 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800182
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800183 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
184}
185
186const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700187Face::expressInterest(const Interest& interest,
188 const OnData& onData,
189 const OnTimeout& onTimeout)
190{
191 return this->expressInterest(
192 interest,
193 [onData] (const Interest& interest, const Data& data) {
194 if (onData != nullptr) {
195 onData(interest, const_cast<Data&>(data));
196 }
197 },
198 [onTimeout] (const Interest& interest, const lp::Nack& nack) {
199 if (onTimeout != nullptr) {
200 onTimeout(interest);
201 }
202 },
203 onTimeout
204 );
205}
206
207const PendingInterestId*
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000208Face::expressInterest(const Name& name, const Interest& tmpl,
209 const OnData& onData, const OnTimeout& onTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800210{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000211 return expressInterest(Interest(tmpl).setName(name).setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800212 onData, onTimeout);
213}
214
215void
Junxiao Shiae0b4182016-08-08 22:53:17 +0000216Face::removePendingInterest(const PendingInterestId* pendingInterestId)
217{
218 IO_CAPTURE_WEAK_IMPL(post) {
219 impl->asyncRemovePendingInterest(pendingInterestId);
220 } IO_CAPTURE_WEAK_IMPL_END
221}
222
223void
224Face::removeAllPendingInterests()
225{
226 IO_CAPTURE_WEAK_IMPL(post) {
227 impl->asyncRemoveAllPendingInterests();
228 } IO_CAPTURE_WEAK_IMPL_END
229}
230
231size_t
232Face::getNPendingInterests() const
233{
234 return m_impl->m_pendingInterestTable.size();
235}
236
237void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800238Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800239{
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000240 Block wire = data.wireEncode();
241
Eric Newberry4d261b62016-11-10 13:40:09 -0700242 lp::Packet packet;
243 bool hasLpFields = false;
244
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000245 shared_ptr<lp::CachePolicyTag> cachePolicyTag = data.getTag<lp::CachePolicyTag>();
246 if (cachePolicyTag != nullptr) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000247 packet.add<lp::CachePolicyField>(*cachePolicyTag);
Eric Newberry4d261b62016-11-10 13:40:09 -0700248 hasLpFields = true;
249 }
250
251 shared_ptr<lp::CongestionMarkTag> congestionMarkTag = data.getTag<lp::CongestionMarkTag>();
252 if (congestionMarkTag != nullptr) {
253 packet.add<lp::CongestionMarkField>(*congestionMarkTag);
254 hasLpFields = true;
255 }
256
257 if (hasLpFields) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000258 packet.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
259 wire = packet.wireEncode();
260 }
261
262 if (wire.size() > MAX_NDN_PACKET_SIZE)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700263 BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700264
Junxiao Shiae0b4182016-08-08 22:53:17 +0000265 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000266 impl->asyncSend(wire);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000267 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800268}
269
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800270void
Eric Newberry83872fd2015-08-06 17:01:24 -0700271Face::put(const lp::Nack& nack)
272{
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000273 lp::Packet packet;
274 packet.add<lp::NackField>(nack.getHeader());
275 const Block& interestWire = nack.getInterest().wireEncode();
276 packet.add<lp::FragmentField>(std::make_pair(interestWire.begin(), interestWire.end()));
277
Eric Newberry4d261b62016-11-10 13:40:09 -0700278 shared_ptr<lp::CongestionMarkTag> congestionMarkTag = nack.getTag<lp::CongestionMarkTag>();
279 if (congestionMarkTag != nullptr) {
280 packet.add<lp::CongestionMarkField>(*congestionMarkTag);
281 }
282
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000283 Block wire = packet.wireEncode();
284
285 if (wire.size() > MAX_NDN_PACKET_SIZE)
286 BOOST_THROW_EXCEPTION(Error("Nack size exceeds maximum limit"));
Eric Newberry83872fd2015-08-06 17:01:24 -0700287
Junxiao Shiae0b4182016-08-08 22:53:17 +0000288 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000289 impl->asyncSend(wire);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000290 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700291}
292
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800293const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000294Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000295 const InterestCallback& onInterest,
296 const RegisterPrefixFailureCallback& onFailure,
297 const security::SigningInfo& signingInfo,
298 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700299{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000300 return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700301}
302
303const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000304Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000305 const InterestCallback& onInterest,
306 const RegisterPrefixSuccessCallback& onSuccess,
307 const RegisterPrefixFailureCallback& onFailure,
308 const security::SigningInfo& signingInfo,
309 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700310{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000311 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700312
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000313 nfd::CommandOptions options;
314 options.setSigningInfo(signingInfo);
Junxiao Shi388ec252014-11-02 15:19:57 -0700315
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000316 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
317 onSuccess, onFailure, flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700318}
319
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700320const InterestFilterId*
321Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000322 const InterestCallback& onInterest)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700323{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000324 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700325
Junxiao Shiae0b4182016-08-08 22:53:17 +0000326 IO_CAPTURE_WEAK_IMPL(post) {
327 impl->asyncSetInterestFilter(filter);
328 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700329
330 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700331}
332
Joao Pereira0b3cac52015-07-02 14:49:49 -0400333#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
334
335const RegisteredPrefixId*
336Face::setInterestFilter(const InterestFilter& interestFilter,
337 const OnInterest& onInterest,
338 const RegisterPrefixSuccessCallback& onSuccess,
339 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700340 const security::v1::IdentityCertificate& certificate,
Joao Pereira0b3cac52015-07-02 14:49:49 -0400341 uint64_t flags)
342{
343 security::SigningInfo signingInfo;
344 if (!certificate.getName().empty()) {
345 signingInfo = signingByCertificate(certificate.getName());
346 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000347 return setInterestFilter(interestFilter, onInterest, onSuccess, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400348}
349
350const RegisteredPrefixId*
351Face::setInterestFilter(const InterestFilter& interestFilter,
352 const OnInterest& onInterest,
353 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700354 const security::v1::IdentityCertificate& certificate,
Joao Pereira0b3cac52015-07-02 14:49:49 -0400355 uint64_t flags)
356{
357 security::SigningInfo signingInfo;
358 if (!certificate.getName().empty()) {
359 signingInfo = signingByCertificate(certificate.getName());
360 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000361 return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400362}
363
364const RegisteredPrefixId*
365Face::setInterestFilter(const InterestFilter& interestFilter,
366 const OnInterest& onInterest,
367 const RegisterPrefixSuccessCallback& onSuccess,
368 const RegisterPrefixFailureCallback& onFailure,
369 const Name& identity,
370 uint64_t flags)
371{
372 security::SigningInfo signingInfo = signingByIdentity(identity);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400373 return setInterestFilter(interestFilter, onInterest,
374 onSuccess, onFailure,
375 signingInfo, flags);
376}
377
378const RegisteredPrefixId*
379Face::setInterestFilter(const InterestFilter& interestFilter,
380 const OnInterest& onInterest,
381 const RegisterPrefixFailureCallback& onFailure,
382 const Name& identity,
383 uint64_t flags)
384{
385 security::SigningInfo signingInfo = signingByIdentity(identity);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000386 return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400387}
388
389#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
390
391const RegisteredPrefixId*
392Face::registerPrefix(const Name& prefix,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000393 const RegisterPrefixSuccessCallback& onSuccess,
394 const RegisterPrefixFailureCallback& onFailure,
395 const security::SigningInfo& signingInfo,
396 uint64_t flags)
Joao Pereira0b3cac52015-07-02 14:49:49 -0400397{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000398 nfd::CommandOptions options;
399 options.setSigningInfo(signingInfo);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400400
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000401 return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400402}
403
404#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700405const RegisteredPrefixId*
406Face::registerPrefix(const Name& prefix,
407 const RegisterPrefixSuccessCallback& onSuccess,
408 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700409 const security::v1::IdentityCertificate& certificate,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700410 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700411{
Joao Pereira0b3cac52015-07-02 14:49:49 -0400412 security::SigningInfo signingInfo;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700413 if (!certificate.getName().empty()) {
Joao Pereira0b3cac52015-07-02 14:49:49 -0400414 signingInfo = signingByCertificate(certificate.getName());
Junxiao Shi388ec252014-11-02 15:19:57 -0700415 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000416 return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700417}
418
419const RegisteredPrefixId*
420Face::registerPrefix(const Name& prefix,
421 const RegisterPrefixSuccessCallback& onSuccess,
422 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700423 const Name& identity,
424 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700425{
Joao Pereira0b3cac52015-07-02 14:49:49 -0400426 security::SigningInfo signingInfo = signingByIdentity(identity);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000427 return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700428}
Joao Pereira0b3cac52015-07-02 14:49:49 -0400429#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700430
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700431void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800432Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800433{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000434 IO_CAPTURE_WEAK_IMPL(post) {
435 impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr);
436 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800437}
438
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700439void
440Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
441{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000442 IO_CAPTURE_WEAK_IMPL(post) {
443 impl->asyncUnsetInterestFilter(interestFilterId);
444 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700445}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700446
447void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700448Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
449 const UnregisterPrefixSuccessCallback& onSuccess,
450 const UnregisterPrefixFailureCallback& onFailure)
451{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000452 IO_CAPTURE_WEAK_IMPL(post) {
453 impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure);
454 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700455}
456
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800457void
Junxiao Shic828dfc2016-09-15 13:26:22 +0000458Face::doProcessEvents(const time::milliseconds& timeout, bool keepThread)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800459{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500460 if (m_ioService.stopped()) {
461 m_ioService.reset(); // ensure that run()/poll() will do some work
462 }
463
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700464 try {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800465 if (timeout < time::milliseconds::zero()) {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000466 // do not block if timeout is negative, but process pending events
467 m_ioService.poll();
468 return;
469 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800470
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800471 if (timeout > time::milliseconds::zero()) {
472 boost::asio::io_service& ioService = m_ioService;
473 unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000474 m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.scheduleEvent(timeout,
475 [&ioService, &work] {
476 ioService.stop();
477 work.reset();
478 });
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800479 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700480
481 if (keepThread) {
482 // work will ensure that m_ioService is running until work object exists
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800483 m_impl->m_ioServiceWork.reset(new boost::asio::io_service::work(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800484 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700485
Junxiao Shi2cced062014-11-02 21:27:38 -0700486 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700487 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700488 catch (...) {
489 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700490 m_impl->m_pendingInterestTable.clear();
491 m_impl->m_registeredPrefixTable.clear();
492 throw;
493 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700494}
495
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800496void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700497Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700498{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000499 IO_CAPTURE_WEAK_IMPL(post) {
500 this->asyncShutdown();
501 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700502}
503
504void
505Face::asyncShutdown()
506{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700507 m_impl->m_pendingInterestTable.clear();
508 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800509
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700510 if (m_transport->isConnected())
511 m_transport->close();
512
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700513 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700514}
515
Eric Newberry83872fd2015-08-06 17:01:24 -0700516/**
517 * @brief extract local fields from NDNLPv2 packet and tag onto a network layer packet
518 */
Eric Newberry4d261b62016-11-10 13:40:09 -0700519template<typename NetPkt>
Eric Newberry83872fd2015-08-06 17:01:24 -0700520static void
Eric Newberry4d261b62016-11-10 13:40:09 -0700521extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
Eric Newberry83872fd2015-08-06 17:01:24 -0700522{
523 if (lpPacket.has<lp::IncomingFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000524 netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700525 }
Eric Newberry4d261b62016-11-10 13:40:09 -0700526
527 if (lpPacket.has<lp::CongestionMarkField>()) {
528 netPacket.setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
529 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700530}
531
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800532void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800533Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800534{
Eric Newberry83872fd2015-08-06 17:01:24 -0700535 lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
536 // no need to distinguish
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800537
Eric Newberry83872fd2015-08-06 17:01:24 -0700538 Buffer::const_iterator begin, end;
539 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
540 Block netPacket(&*begin, std::distance(begin, end));
541 switch (netPacket.type()) {
542 case tlv::Interest: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000543 auto interest = make_shared<Interest>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700544 if (lpPacket.has<lp::NackField>()) {
545 auto nack = make_shared<lp::Nack>(std::move(*interest));
546 nack->setHeader(lpPacket.get<lp::NackField>());
547 extractLpLocalFields(*nack, lpPacket);
548 m_impl->nackPendingInterests(*nack);
549 }
550 else {
551 extractLpLocalFields(*interest, lpPacket);
552 m_impl->processInterestFilters(*interest);
553 }
554 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800555 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700556 case tlv::Data: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000557 auto data = make_shared<Data>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700558 extractLpLocalFields(*data, lpPacket);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700559 m_impl->satisfyPendingInterests(*data);
Eric Newberry83872fd2015-08-06 17:01:24 -0700560 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800561 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700562 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800563}
564
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800565} // namespace ndn