blob: 430f65e1e677a670fe0cc4b4c289fff18983ae86 [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 Afanasyev57e00362016-06-23 13:22:54 -07003 * Copyright (c) 2013-2016 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 Shiedd834e2014-10-28 20:28:58 -070026#include "security/key-chain.hpp"
Junxiao Shic6acc7a2015-06-23 10:03:56 -070027#include "security/signing-helpers.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080028#include "util/time.hpp"
29#include "util/random.hpp"
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070030#include "util/face-uri.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070031
Junxiao Shiae0b4182016-08-08 22:53:17 +000032// A callback scheduled through io.post and io.dispatch may be invoked after the face
33// is destructed. To prevent this situation, these macros captures Face::m_impl as weak_ptr,
34// and skips callback execution if the face has been destructed.
35#define IO_CAPTURE_WEAK_IMPL(OP) \
36 { \
37 weak_ptr<Impl> implWeak(m_impl); \
38 m_ioService.OP([=] { \
39 auto impl = implWeak.lock(); \
40 if (impl != nullptr) {
41#define IO_CAPTURE_WEAK_IMPL_END \
42 } \
43 }); \
44 }
45
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070046namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080047
Junxiao Shi103d8ed2016-08-07 20:34:10 +000048Face::Face(shared_ptr<Transport> transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070049 : m_internalIoService(new boost::asio::io_service())
50 , m_ioService(*m_internalIoService)
51 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000052 , m_impl(make_shared<Impl>(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070053{
Junxiao Shi103d8ed2016-08-07 20:34:10 +000054 construct(transport, *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080055}
56
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070057Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070058 : m_ioService(ioService)
59 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000060 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070061{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080062 construct(nullptr, *m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070063}
64
Junxiao Shi103d8ed2016-08-07 20:34:10 +000065Face::Face(const std::string& host, const std::string& port)
Junxiao Shi2cced062014-11-02 21:27:38 -070066 : m_internalIoService(new boost::asio::io_service())
67 , m_ioService(*m_internalIoService)
68 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000069 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080070{
Joao Pereira68c0d882015-05-19 14:27:55 -040071 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080072}
73
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070074Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
75 : m_internalIoService(new boost::asio::io_service())
76 , m_ioService(*m_internalIoService)
Junxiao Shiae0b4182016-08-08 22:53:17 +000077 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070078{
79 construct(transport, keyChain);
80}
81
82Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070083 : m_ioService(ioService)
84 , m_internalKeyChain(new KeyChain())
Junxiao Shiae0b4182016-08-08 22:53:17 +000085 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080086{
Joao Pereira68c0d882015-05-19 14:27:55 -040087 construct(transport, *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070088}
89
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070090Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070091 : m_ioService(ioService)
Junxiao Shiae0b4182016-08-08 22:53:17 +000092 , m_impl(make_shared<Impl>(*this))
Junxiao Shiedd834e2014-10-28 20:28:58 -070093{
Joao Pereira68c0d882015-05-19 14:27:55 -040094 construct(transport, keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080095}
96
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080097shared_ptr<Transport>
98Face::makeDefaultTransport()
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070099{
100 // transport=unix:///var/run/nfd.sock
101 // transport=tcp://localhost:6363
102
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700103 std::string transportUri;
104
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000105 const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
106 if (transportEnviron != nullptr) {
107 transportUri = transportEnviron;
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700108 }
109 else {
110 ConfigFile config;
111 transportUri = config.getParsedConfiguration().get<std::string>("transport", "");
112 }
113
114 if (transportUri.empty()) {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800115 // transport not specified, use default Unix transport.
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700116 return UnixTransport::create("");
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800117 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700118
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800119 std::string protocol;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800120 try {
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700121 util::FaceUri uri(transportUri);
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800122 protocol = uri.getScheme();
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700123
124 if (protocol == "unix") {
125 return UnixTransport::create(transportUri);
126 }
127 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6") {
128 return TcpTransport::create(transportUri);
129 }
130 else {
131 BOOST_THROW_EXCEPTION(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
132 }
133 }
134 catch (const Transport::Error& error) {
135 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800136 }
137 catch (const util::FaceUri::Error& error) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700138 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800139 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700140}
141
142void
Joao Pereira68c0d882015-05-19 14:27:55 -0400143Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800144{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800145 if (transport == nullptr) {
146 transport = makeDefaultTransport();
147 }
148 BOOST_ASSERT(transport != nullptr);
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800149 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800150
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800151 m_nfdController.reset(new nfd::Controller(*this, keyChain));
152
Junxiao Shiae0b4182016-08-08 22:53:17 +0000153 IO_CAPTURE_WEAK_IMPL(post) {
154 impl->ensureConnected(false);
155 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800156}
157
Joao Pereira68c0d882015-05-19 14:27:55 -0400158Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700159
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800160shared_ptr<Transport>
161Face::getTransport()
162{
163 return m_transport;
164}
165
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800166const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700167Face::expressInterest(const Interest& interest,
168 const DataCallback& afterSatisfied,
169 const NackCallback& afterNacked,
170 const TimeoutCallback& afterTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800171{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700172 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800173
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700174 // Use `interestToExpress` to avoid wire format creation for the original Interest
Eric Newberry83872fd2015-08-06 17:01:24 -0700175 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700176 BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
Eric Newberry83872fd2015-08-06 17:01:24 -0700177 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700178
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700179 // If the same ioService thread, dispatch directly calls the method
Junxiao Shiae0b4182016-08-08 22:53:17 +0000180 IO_CAPTURE_WEAK_IMPL(dispatch) {
181 impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
182 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800183
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800184 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
185}
186
187const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700188Face::expressInterest(const Interest& interest,
189 const OnData& onData,
190 const OnTimeout& onTimeout)
191{
192 return this->expressInterest(
193 interest,
194 [onData] (const Interest& interest, const Data& data) {
195 if (onData != nullptr) {
196 onData(interest, const_cast<Data&>(data));
197 }
198 },
199 [onTimeout] (const Interest& interest, const lp::Nack& nack) {
200 if (onTimeout != nullptr) {
201 onTimeout(interest);
202 }
203 },
204 onTimeout
205 );
206}
207
208const PendingInterestId*
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000209Face::expressInterest(const Name& name, const Interest& tmpl,
210 const OnData& onData, const OnTimeout& onTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800211{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000212 return expressInterest(Interest(tmpl).setName(name).setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800213 onData, onTimeout);
214}
215
216void
Junxiao Shiae0b4182016-08-08 22:53:17 +0000217Face::removePendingInterest(const PendingInterestId* pendingInterestId)
218{
219 IO_CAPTURE_WEAK_IMPL(post) {
220 impl->asyncRemovePendingInterest(pendingInterestId);
221 } IO_CAPTURE_WEAK_IMPL_END
222}
223
224void
225Face::removeAllPendingInterests()
226{
227 IO_CAPTURE_WEAK_IMPL(post) {
228 impl->asyncRemoveAllPendingInterests();
229 } IO_CAPTURE_WEAK_IMPL_END
230}
231
232size_t
233Face::getNPendingInterests() const
234{
235 return m_impl->m_pendingInterestTable.size();
236}
237
238void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800239Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800240{
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000241 Block wire = data.wireEncode();
242
Eric Newberry4d261b62016-11-10 13:40:09 -0700243 lp::Packet packet;
244 bool hasLpFields = false;
245
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000246 shared_ptr<lp::CachePolicyTag> cachePolicyTag = data.getTag<lp::CachePolicyTag>();
247 if (cachePolicyTag != nullptr) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000248 packet.add<lp::CachePolicyField>(*cachePolicyTag);
Eric Newberry4d261b62016-11-10 13:40:09 -0700249 hasLpFields = true;
250 }
251
252 shared_ptr<lp::CongestionMarkTag> congestionMarkTag = data.getTag<lp::CongestionMarkTag>();
253 if (congestionMarkTag != nullptr) {
254 packet.add<lp::CongestionMarkField>(*congestionMarkTag);
255 hasLpFields = true;
256 }
257
258 if (hasLpFields) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000259 packet.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
260 wire = packet.wireEncode();
261 }
262
263 if (wire.size() > MAX_NDN_PACKET_SIZE)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700264 BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700265
Junxiao Shiae0b4182016-08-08 22:53:17 +0000266 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000267 impl->asyncSend(wire);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000268 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800269}
270
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800271void
Eric Newberry83872fd2015-08-06 17:01:24 -0700272Face::put(const lp::Nack& nack)
273{
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000274 lp::Packet packet;
275 packet.add<lp::NackField>(nack.getHeader());
276 const Block& interestWire = nack.getInterest().wireEncode();
277 packet.add<lp::FragmentField>(std::make_pair(interestWire.begin(), interestWire.end()));
278
Eric Newberry4d261b62016-11-10 13:40:09 -0700279 shared_ptr<lp::CongestionMarkTag> congestionMarkTag = nack.getTag<lp::CongestionMarkTag>();
280 if (congestionMarkTag != nullptr) {
281 packet.add<lp::CongestionMarkField>(*congestionMarkTag);
282 }
283
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000284 Block wire = packet.wireEncode();
285
286 if (wire.size() > MAX_NDN_PACKET_SIZE)
287 BOOST_THROW_EXCEPTION(Error("Nack size exceeds maximum limit"));
Eric Newberry83872fd2015-08-06 17:01:24 -0700288
Junxiao Shiae0b4182016-08-08 22:53:17 +0000289 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shie7bb6c82016-08-08 23:16:35 +0000290 impl->asyncSend(wire);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000291 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700292}
293
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800294const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000295Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000296 const InterestCallback& onInterest,
297 const RegisterPrefixFailureCallback& onFailure,
298 const security::SigningInfo& signingInfo,
299 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700300{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000301 return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700302}
303
304const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000305Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000306 const InterestCallback& onInterest,
307 const RegisterPrefixSuccessCallback& onSuccess,
308 const RegisterPrefixFailureCallback& onFailure,
309 const security::SigningInfo& signingInfo,
310 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700311{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000312 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700313
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000314 nfd::CommandOptions options;
315 options.setSigningInfo(signingInfo);
Junxiao Shi388ec252014-11-02 15:19:57 -0700316
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000317 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
318 onSuccess, onFailure, flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700319}
320
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700321const InterestFilterId*
322Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000323 const InterestCallback& onInterest)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700324{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000325 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700326
Junxiao Shiae0b4182016-08-08 22:53:17 +0000327 IO_CAPTURE_WEAK_IMPL(post) {
328 impl->asyncSetInterestFilter(filter);
329 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700330
331 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700332}
333
Joao Pereira0b3cac52015-07-02 14:49:49 -0400334#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
335
336const RegisteredPrefixId*
337Face::setInterestFilter(const InterestFilter& interestFilter,
338 const OnInterest& onInterest,
339 const RegisterPrefixSuccessCallback& onSuccess,
340 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700341 const security::v1::IdentityCertificate& certificate,
Joao Pereira0b3cac52015-07-02 14:49:49 -0400342 uint64_t flags)
343{
344 security::SigningInfo signingInfo;
345 if (!certificate.getName().empty()) {
346 signingInfo = signingByCertificate(certificate.getName());
347 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000348 return setInterestFilter(interestFilter, onInterest, onSuccess, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400349}
350
351const RegisteredPrefixId*
352Face::setInterestFilter(const InterestFilter& interestFilter,
353 const OnInterest& onInterest,
354 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700355 const security::v1::IdentityCertificate& certificate,
Joao Pereira0b3cac52015-07-02 14:49:49 -0400356 uint64_t flags)
357{
358 security::SigningInfo signingInfo;
359 if (!certificate.getName().empty()) {
360 signingInfo = signingByCertificate(certificate.getName());
361 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000362 return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400363}
364
365const RegisteredPrefixId*
366Face::setInterestFilter(const InterestFilter& interestFilter,
367 const OnInterest& onInterest,
368 const RegisterPrefixSuccessCallback& onSuccess,
369 const RegisterPrefixFailureCallback& onFailure,
370 const Name& identity,
371 uint64_t flags)
372{
373 security::SigningInfo signingInfo = signingByIdentity(identity);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400374 return setInterestFilter(interestFilter, onInterest,
375 onSuccess, onFailure,
376 signingInfo, flags);
377}
378
379const RegisteredPrefixId*
380Face::setInterestFilter(const InterestFilter& interestFilter,
381 const OnInterest& onInterest,
382 const RegisterPrefixFailureCallback& onFailure,
383 const Name& identity,
384 uint64_t flags)
385{
386 security::SigningInfo signingInfo = signingByIdentity(identity);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000387 return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400388}
389
390#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
391
392const RegisteredPrefixId*
393Face::registerPrefix(const Name& prefix,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000394 const RegisterPrefixSuccessCallback& onSuccess,
395 const RegisterPrefixFailureCallback& onFailure,
396 const security::SigningInfo& signingInfo,
397 uint64_t flags)
Joao Pereira0b3cac52015-07-02 14:49:49 -0400398{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000399 nfd::CommandOptions options;
400 options.setSigningInfo(signingInfo);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400401
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000402 return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400403}
404
405#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700406const RegisteredPrefixId*
407Face::registerPrefix(const Name& prefix,
408 const RegisterPrefixSuccessCallback& onSuccess,
409 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700410 const security::v1::IdentityCertificate& certificate,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700411 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700412{
Joao Pereira0b3cac52015-07-02 14:49:49 -0400413 security::SigningInfo signingInfo;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700414 if (!certificate.getName().empty()) {
Joao Pereira0b3cac52015-07-02 14:49:49 -0400415 signingInfo = signingByCertificate(certificate.getName());
Junxiao Shi388ec252014-11-02 15:19:57 -0700416 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000417 return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700418}
419
420const RegisteredPrefixId*
421Face::registerPrefix(const Name& prefix,
422 const RegisterPrefixSuccessCallback& onSuccess,
423 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700424 const Name& identity,
425 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700426{
Joao Pereira0b3cac52015-07-02 14:49:49 -0400427 security::SigningInfo signingInfo = signingByIdentity(identity);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000428 return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700429}
Joao Pereira0b3cac52015-07-02 14:49:49 -0400430#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700431
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700432void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800433Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800434{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000435 IO_CAPTURE_WEAK_IMPL(post) {
436 impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr);
437 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800438}
439
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700440void
441Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
442{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000443 IO_CAPTURE_WEAK_IMPL(post) {
444 impl->asyncUnsetInterestFilter(interestFilterId);
445 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700446}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700447
448void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700449Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
450 const UnregisterPrefixSuccessCallback& onSuccess,
451 const UnregisterPrefixFailureCallback& onFailure)
452{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000453 IO_CAPTURE_WEAK_IMPL(post) {
454 impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure);
455 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700456}
457
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800458void
Junxiao Shic828dfc2016-09-15 13:26:22 +0000459Face::doProcessEvents(const time::milliseconds& timeout, bool keepThread)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800460{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500461 if (m_ioService.stopped()) {
462 m_ioService.reset(); // ensure that run()/poll() will do some work
463 }
464
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700465 try {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800466 if (timeout < time::milliseconds::zero()) {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000467 // do not block if timeout is negative, but process pending events
468 m_ioService.poll();
469 return;
470 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800471
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800472 if (timeout > time::milliseconds::zero()) {
473 boost::asio::io_service& ioService = m_ioService;
474 unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000475 m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.scheduleEvent(timeout,
476 [&ioService, &work] {
477 ioService.stop();
478 work.reset();
479 });
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800480 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700481
482 if (keepThread) {
483 // work will ensure that m_ioService is running until work object exists
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800484 m_impl->m_ioServiceWork.reset(new boost::asio::io_service::work(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800485 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700486
Junxiao Shi2cced062014-11-02 21:27:38 -0700487 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700488 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700489 catch (...) {
490 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700491 m_impl->m_pendingInterestTable.clear();
492 m_impl->m_registeredPrefixTable.clear();
493 throw;
494 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700495}
496
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800497void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700498Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700499{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000500 IO_CAPTURE_WEAK_IMPL(post) {
501 this->asyncShutdown();
502 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700503}
504
505void
506Face::asyncShutdown()
507{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700508 m_impl->m_pendingInterestTable.clear();
509 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800510
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700511 if (m_transport->isConnected())
512 m_transport->close();
513
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700514 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700515}
516
Eric Newberry83872fd2015-08-06 17:01:24 -0700517/**
518 * @brief extract local fields from NDNLPv2 packet and tag onto a network layer packet
519 */
Eric Newberry4d261b62016-11-10 13:40:09 -0700520template<typename NetPkt>
Eric Newberry83872fd2015-08-06 17:01:24 -0700521static void
Eric Newberry4d261b62016-11-10 13:40:09 -0700522extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
Eric Newberry83872fd2015-08-06 17:01:24 -0700523{
524 if (lpPacket.has<lp::IncomingFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000525 netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700526 }
Eric Newberry4d261b62016-11-10 13:40:09 -0700527
528 if (lpPacket.has<lp::CongestionMarkField>()) {
529 netPacket.setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
530 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700531}
532
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800533void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800534Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800535{
Eric Newberry83872fd2015-08-06 17:01:24 -0700536 lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
537 // no need to distinguish
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800538
Eric Newberry83872fd2015-08-06 17:01:24 -0700539 Buffer::const_iterator begin, end;
540 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
541 Block netPacket(&*begin, std::distance(begin, end));
542 switch (netPacket.type()) {
543 case tlv::Interest: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000544 auto interest = make_shared<Interest>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700545 if (lpPacket.has<lp::NackField>()) {
546 auto nack = make_shared<lp::Nack>(std::move(*interest));
547 nack->setHeader(lpPacket.get<lp::NackField>());
548 extractLpLocalFields(*nack, lpPacket);
549 m_impl->nackPendingInterests(*nack);
550 }
551 else {
552 extractLpLocalFields(*interest, lpPacket);
553 m_impl->processInterestFilters(*interest);
554 }
555 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800556 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700557 case tlv::Data: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000558 auto data = make_shared<Data>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700559 extractLpLocalFields(*data, lpPacket);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700560 m_impl->satisfyPendingInterests(*data);
Eric Newberry83872fd2015-08-06 17:01:24 -0700561 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800562 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700563 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800564}
565
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800566} // namespace ndn