blob: b52a54d0479b2f29e9e1826778e22dc5e91c5fc5 [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
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070032namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080033
Junxiao Shi103d8ed2016-08-07 20:34:10 +000034Face::Face(shared_ptr<Transport> transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070035 : m_internalIoService(new boost::asio::io_service())
36 , m_ioService(*m_internalIoService)
37 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070038 , m_impl(new Impl(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070039{
Junxiao Shi103d8ed2016-08-07 20:34:10 +000040 construct(transport, *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080041}
42
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070043Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070044 : m_ioService(ioService)
45 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070046 , m_impl(new Impl(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070047{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080048 construct(nullptr, *m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070049}
50
Junxiao Shi103d8ed2016-08-07 20:34:10 +000051Face::Face(const std::string& host, const std::string& port)
Junxiao Shi2cced062014-11-02 21:27:38 -070052 : m_internalIoService(new boost::asio::io_service())
53 , m_ioService(*m_internalIoService)
54 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070055 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080056{
Joao Pereira68c0d882015-05-19 14:27:55 -040057 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080058}
59
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070060Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
61 : m_internalIoService(new boost::asio::io_service())
62 , m_ioService(*m_internalIoService)
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070063 , m_impl(new Impl(*this))
64{
65 construct(transport, keyChain);
66}
67
68Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070069 : m_ioService(ioService)
70 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070071 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080072{
Joao Pereira68c0d882015-05-19 14:27:55 -040073 construct(transport, *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070074}
75
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070076Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070077 : m_ioService(ioService)
Junxiao Shiedd834e2014-10-28 20:28:58 -070078 , m_impl(new Impl(*this))
79{
Joao Pereira68c0d882015-05-19 14:27:55 -040080 construct(transport, keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080081}
82
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080083shared_ptr<Transport>
84Face::makeDefaultTransport()
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070085{
86 // transport=unix:///var/run/nfd.sock
87 // transport=tcp://localhost:6363
88
Alexander Afanasyev57e00362016-06-23 13:22:54 -070089 std::string transportUri;
90
Junxiao Shi103d8ed2016-08-07 20:34:10 +000091 const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
92 if (transportEnviron != nullptr) {
93 transportUri = transportEnviron;
Alexander Afanasyev57e00362016-06-23 13:22:54 -070094 }
95 else {
96 ConfigFile config;
97 transportUri = config.getParsedConfiguration().get<std::string>("transport", "");
98 }
99
100 if (transportUri.empty()) {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800101 // transport not specified, use default Unix transport.
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700102 return UnixTransport::create("");
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800103 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700104
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800105 std::string protocol;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800106 try {
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700107 util::FaceUri uri(transportUri);
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800108 protocol = uri.getScheme();
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700109
110 if (protocol == "unix") {
111 return UnixTransport::create(transportUri);
112 }
113 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6") {
114 return TcpTransport::create(transportUri);
115 }
116 else {
117 BOOST_THROW_EXCEPTION(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
118 }
119 }
120 catch (const Transport::Error& error) {
121 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800122 }
123 catch (const util::FaceUri::Error& error) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700124 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800125 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700126}
127
128void
Joao Pereira68c0d882015-05-19 14:27:55 -0400129Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800130{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800131 if (transport == nullptr) {
132 transport = makeDefaultTransport();
133 }
134 BOOST_ASSERT(transport != nullptr);
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800135 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800136
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800137 m_nfdController.reset(new nfd::Controller(*this, keyChain));
138
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700139 m_ioService.post([=] { m_impl->ensureConnected(false); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800140}
141
Joao Pereira68c0d882015-05-19 14:27:55 -0400142Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700143
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800144shared_ptr<Transport>
145Face::getTransport()
146{
147 return m_transport;
148}
149
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800150const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700151Face::expressInterest(const Interest& interest,
152 const DataCallback& afterSatisfied,
153 const NackCallback& afterNacked,
154 const TimeoutCallback& afterTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800155{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700156 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800157
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700158 // Use `interestToExpress` to avoid wire format creation for the original Interest
Eric Newberry83872fd2015-08-06 17:01:24 -0700159 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700160 BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
Eric Newberry83872fd2015-08-06 17:01:24 -0700161 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700162
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700163 // If the same ioService thread, dispatch directly calls the method
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000164 m_ioService.dispatch([=] {
165 m_impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
166 });
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800167
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800168 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
169}
170
171const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700172Face::expressInterest(const Interest& interest,
173 const OnData& onData,
174 const OnTimeout& onTimeout)
175{
176 return this->expressInterest(
177 interest,
178 [onData] (const Interest& interest, const Data& data) {
179 if (onData != nullptr) {
180 onData(interest, const_cast<Data&>(data));
181 }
182 },
183 [onTimeout] (const Interest& interest, const lp::Nack& nack) {
184 if (onTimeout != nullptr) {
185 onTimeout(interest);
186 }
187 },
188 onTimeout
189 );
190}
191
192const PendingInterestId*
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000193Face::expressInterest(const Name& name, const Interest& tmpl,
194 const OnData& onData, const OnTimeout& onTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800195{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000196 return expressInterest(Interest(tmpl).setName(name).setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800197 onData, onTimeout);
198}
199
200void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800201Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800202{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700203 // Use original `data`, since wire format should already exist for the original Data
204 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700205 BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700206
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700207 shared_ptr<const Data> dataPtr;
208 try {
209 dataPtr = data.shared_from_this();
210 }
211 catch (const bad_weak_ptr& e) {
212 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
213 << std::endl;
214 dataPtr = make_shared<Data>(data);
215 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800216
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700217 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400218 m_ioService.dispatch([=] { m_impl->asyncPutData(dataPtr); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800219}
220
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800221void
Eric Newberry83872fd2015-08-06 17:01:24 -0700222Face::put(const lp::Nack& nack)
223{
224 m_ioService.dispatch([=] { m_impl->asyncPutNack(make_shared<lp::Nack>(nack)); });
225}
226
227void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800228Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800229{
Joao Pereira68c0d882015-05-19 14:27:55 -0400230 m_ioService.post([=] { m_impl->asyncRemovePendingInterest(pendingInterestId); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800231}
232
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500233void
234Face::removeAllPendingInterests()
235{
236 m_ioService.post([=] { m_impl->asyncRemoveAllPendingInterests(); });
237}
238
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700239size_t
240Face::getNPendingInterests() const
241{
242 return m_impl->m_pendingInterestTable.size();
243}
244
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800245const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000246Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000247 const InterestCallback& onInterest,
248 const RegisterPrefixFailureCallback& onFailure,
249 const security::SigningInfo& signingInfo,
250 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700251{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000252 return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700253}
254
255const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000256Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000257 const InterestCallback& onInterest,
258 const RegisterPrefixSuccessCallback& onSuccess,
259 const RegisterPrefixFailureCallback& onFailure,
260 const security::SigningInfo& signingInfo,
261 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700262{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000263 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700264
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000265 nfd::CommandOptions options;
266 options.setSigningInfo(signingInfo);
Junxiao Shi388ec252014-11-02 15:19:57 -0700267
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000268 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
269 onSuccess, onFailure, flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700270}
271
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700272const InterestFilterId*
273Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000274 const InterestCallback& onInterest)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700275{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000276 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700277
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000278 m_ioService.post([=] { m_impl->asyncSetInterestFilter(filter); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700279
280 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700281}
282
Joao Pereira0b3cac52015-07-02 14:49:49 -0400283#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
284
285const RegisteredPrefixId*
286Face::setInterestFilter(const InterestFilter& interestFilter,
287 const OnInterest& onInterest,
288 const RegisterPrefixSuccessCallback& onSuccess,
289 const RegisterPrefixFailureCallback& onFailure,
290 const IdentityCertificate& certificate,
291 uint64_t flags)
292{
293 security::SigningInfo signingInfo;
294 if (!certificate.getName().empty()) {
295 signingInfo = signingByCertificate(certificate.getName());
296 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000297 return setInterestFilter(interestFilter, onInterest, onSuccess, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400298}
299
300const RegisteredPrefixId*
301Face::setInterestFilter(const InterestFilter& interestFilter,
302 const OnInterest& onInterest,
303 const RegisterPrefixFailureCallback& onFailure,
304 const IdentityCertificate& certificate,
305 uint64_t flags)
306{
307 security::SigningInfo signingInfo;
308 if (!certificate.getName().empty()) {
309 signingInfo = signingByCertificate(certificate.getName());
310 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000311 return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400312}
313
314const RegisteredPrefixId*
315Face::setInterestFilter(const InterestFilter& interestFilter,
316 const OnInterest& onInterest,
317 const RegisterPrefixSuccessCallback& onSuccess,
318 const RegisterPrefixFailureCallback& onFailure,
319 const Name& identity,
320 uint64_t flags)
321{
322 security::SigningInfo signingInfo = signingByIdentity(identity);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400323 return setInterestFilter(interestFilter, onInterest,
324 onSuccess, onFailure,
325 signingInfo, flags);
326}
327
328const RegisteredPrefixId*
329Face::setInterestFilter(const InterestFilter& interestFilter,
330 const OnInterest& onInterest,
331 const RegisterPrefixFailureCallback& onFailure,
332 const Name& identity,
333 uint64_t flags)
334{
335 security::SigningInfo signingInfo = signingByIdentity(identity);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000336 return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400337}
338
339#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
340
341const RegisteredPrefixId*
342Face::registerPrefix(const Name& prefix,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000343 const RegisterPrefixSuccessCallback& onSuccess,
344 const RegisterPrefixFailureCallback& onFailure,
345 const security::SigningInfo& signingInfo,
346 uint64_t flags)
Joao Pereira0b3cac52015-07-02 14:49:49 -0400347{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000348 nfd::CommandOptions options;
349 options.setSigningInfo(signingInfo);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400350
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000351 return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400352}
353
354#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700355const RegisteredPrefixId*
356Face::registerPrefix(const Name& prefix,
357 const RegisterPrefixSuccessCallback& onSuccess,
358 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700359 const IdentityCertificate& certificate,
360 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700361{
Joao Pereira0b3cac52015-07-02 14:49:49 -0400362 security::SigningInfo signingInfo;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700363 if (!certificate.getName().empty()) {
Joao Pereira0b3cac52015-07-02 14:49:49 -0400364 signingInfo = signingByCertificate(certificate.getName());
Junxiao Shi388ec252014-11-02 15:19:57 -0700365 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000366 return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700367}
368
369const RegisteredPrefixId*
370Face::registerPrefix(const Name& prefix,
371 const RegisterPrefixSuccessCallback& onSuccess,
372 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700373 const Name& identity,
374 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700375{
Joao Pereira0b3cac52015-07-02 14:49:49 -0400376 security::SigningInfo signingInfo = signingByIdentity(identity);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000377 return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700378}
Joao Pereira0b3cac52015-07-02 14:49:49 -0400379#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700380
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700381void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800382Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800383{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000384 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800385}
386
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700387void
388Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
389{
Joao Pereira68c0d882015-05-19 14:27:55 -0400390 m_ioService.post([=] { m_impl->asyncUnsetInterestFilter(interestFilterId); });
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700391}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700392
393void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700394Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
395 const UnregisterPrefixSuccessCallback& onSuccess,
396 const UnregisterPrefixFailureCallback& onFailure)
397{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000398 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700399}
400
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800401void
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000402Face::processEvents(const time::milliseconds& timeout, bool keepThread)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800403{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500404 if (m_ioService.stopped()) {
405 m_ioService.reset(); // ensure that run()/poll() will do some work
406 }
407
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700408 try {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800409 if (timeout < time::milliseconds::zero()) {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000410 // do not block if timeout is negative, but process pending events
411 m_ioService.poll();
412 return;
413 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800414
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800415 if (timeout > time::milliseconds::zero()) {
416 boost::asio::io_service& ioService = m_ioService;
417 unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000418 m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.scheduleEvent(timeout,
419 [&ioService, &work] {
420 ioService.stop();
421 work.reset();
422 });
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800423 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700424
425 if (keepThread) {
426 // work will ensure that m_ioService is running until work object exists
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800427 m_impl->m_ioServiceWork.reset(new boost::asio::io_service::work(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800428 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700429
Junxiao Shi2cced062014-11-02 21:27:38 -0700430 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700431 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700432 catch (...) {
433 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700434 m_impl->m_pendingInterestTable.clear();
435 m_impl->m_registeredPrefixTable.clear();
436 throw;
437 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700438}
439
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800440void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700441Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700442{
Joao Pereira68c0d882015-05-19 14:27:55 -0400443 m_ioService.post([this] { this->asyncShutdown(); });
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700444}
445
446void
447Face::asyncShutdown()
448{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700449 m_impl->m_pendingInterestTable.clear();
450 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800451
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700452 if (m_transport->isConnected())
453 m_transport->close();
454
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700455 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700456}
457
Eric Newberry83872fd2015-08-06 17:01:24 -0700458/**
459 * @brief extract local fields from NDNLPv2 packet and tag onto a network layer packet
460 */
461template<typename NETPKT>
462static void
463extractLpLocalFields(NETPKT& netPacket, const lp::Packet& lpPacket)
464{
465 if (lpPacket.has<lp::IncomingFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000466 netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700467 }
468}
469
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800470void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800471Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800472{
Eric Newberry83872fd2015-08-06 17:01:24 -0700473 lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
474 // no need to distinguish
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800475
Eric Newberry83872fd2015-08-06 17:01:24 -0700476 Buffer::const_iterator begin, end;
477 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
478 Block netPacket(&*begin, std::distance(begin, end));
479 switch (netPacket.type()) {
480 case tlv::Interest: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000481 auto interest = make_shared<Interest>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700482 if (lpPacket.has<lp::NackField>()) {
483 auto nack = make_shared<lp::Nack>(std::move(*interest));
484 nack->setHeader(lpPacket.get<lp::NackField>());
485 extractLpLocalFields(*nack, lpPacket);
486 m_impl->nackPendingInterests(*nack);
487 }
488 else {
489 extractLpLocalFields(*interest, lpPacket);
490 m_impl->processInterestFilters(*interest);
491 }
492 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800493 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700494 case tlv::Data: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000495 auto data = make_shared<Data>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700496 extractLpLocalFields(*data, lpPacket);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700497 m_impl->satisfyPendingInterests(*data);
Eric Newberry83872fd2015-08-06 17:01:24 -0700498 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800499 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700500 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800501}
502
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800503} // namespace ndn