blob: be2aaa1fc773ef34af8803f6d1177d319beb2427 [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 Afanasyev9d158f02015-02-17 21:30:19 -08003 * Copyright (c) 2013-2015 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
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080034Face::Face()
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{
Joao Pereira68c0d882015-05-19 14:27:55 -040040 construct(*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{
Joao Pereira68c0d882015-05-19 14:27:55 -040048 construct(*m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070049}
50
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080051Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
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 Afanasyevf7ca3202014-02-14 22:28:31 -080060Face::Face(const shared_ptr<Transport>& transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070061 : m_internalIoService(new boost::asio::io_service())
62 , m_ioService(*m_internalIoService)
63 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070064 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080065{
Joao Pereira68c0d882015-05-19 14:27:55 -040066 construct(transport, *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080067}
68
69Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070070 boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070071 : m_ioService(ioService)
72 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070073 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080074{
Joao Pereira68c0d882015-05-19 14:27:55 -040075 construct(transport, *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070076}
77
78Face::Face(shared_ptr<Transport> transport,
79 boost::asio::io_service& ioService,
80 KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070081 : m_ioService(ioService)
82 , m_internalKeyChain(nullptr)
Junxiao Shiedd834e2014-10-28 20:28:58 -070083 , m_impl(new Impl(*this))
84{
Joao Pereira68c0d882015-05-19 14:27:55 -040085 construct(transport, keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080086}
87
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080088void
Joao Pereira68c0d882015-05-19 14:27:55 -040089Face::construct(KeyChain& keyChain)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070090{
91 // transport=unix:///var/run/nfd.sock
92 // transport=tcp://localhost:6363
93
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080094 ConfigFile config;
95 const auto& transportType = config.getParsedConfiguration()
96 .get_optional<std::string>("transport");
97 if (!transportType) {
98 // transport not specified, use default Unix transport.
99 construct(UnixTransport::create(config), keyChain);
100 return;
101 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700102
103 unique_ptr<util::FaceUri> uri;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800104 try {
105 uri.reset(new util::FaceUri(*transportType));
106 }
107 catch (const util::FaceUri::Error& error) {
108 throw ConfigFile::Error(error.what());
109 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700110
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700111 const std::string protocol = uri->getScheme();
112
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800113 if (protocol == "unix") {
114 construct(UnixTransport::create(config), keyChain);
115 }
116 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6") {
117 construct(TcpTransport::create(config), keyChain);
118 }
119 else {
120 throw ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\"");
121 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700122}
123
124void
Joao Pereira68c0d882015-05-19 14:27:55 -0400125Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800126{
Joao Pereira68c0d882015-05-19 14:27:55 -0400127 m_nfdController.reset(new nfd::Controller(*this, keyChain));
Junxiao Shiedd834e2014-10-28 20:28:58 -0700128
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800129 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800130
Junxiao Shia1ea5062014-12-27 22:33:39 -0700131 m_impl->ensureConnected(false);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800132}
133
Joao Pereira68c0d882015-05-19 14:27:55 -0400134Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700135
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800136const PendingInterestId*
137Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
138{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700139 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800140
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700141 // Use `interestToExpress` to avoid wire format creation for the original Interest
142 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
143 throw Error("Interest size exceeds maximum limit");
144
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700145 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400146 m_ioService.dispatch([=] { m_impl->asyncExpressInterest(interestToExpress, onData, onTimeout); });
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800147
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800148 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
149}
150
151const PendingInterestId*
152Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800153 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800154 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
155{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700156 return expressInterest(Interest(tmpl)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700157 .setName(name)
158 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800159 onData, onTimeout);
160}
161
162void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800163Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800164{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700165 // Use original `data`, since wire format should already exist for the original Data
166 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
167 throw Error("Data size exceeds maximum limit");
168
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700169 shared_ptr<const Data> dataPtr;
170 try {
171 dataPtr = data.shared_from_this();
172 }
173 catch (const bad_weak_ptr& e) {
174 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
175 << std::endl;
176 dataPtr = make_shared<Data>(data);
177 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800178
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700179 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400180 m_ioService.dispatch([=] { m_impl->asyncPutData(dataPtr); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800181}
182
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800183void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800184Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800185{
Joao Pereira68c0d882015-05-19 14:27:55 -0400186 m_ioService.post([=] { m_impl->asyncRemovePendingInterest(pendingInterestId); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800187}
188
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700189size_t
190Face::getNPendingInterests() const
191{
192 return m_impl->m_pendingInterestTable.size();
193}
194
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800195const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000196Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800197 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700198 const RegisterPrefixSuccessCallback& onSuccess,
199 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700200 const IdentityCertificate& certificate,
201 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700202{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700203 shared_ptr<InterestFilterRecord> filter =
204 make_shared<InterestFilterRecord>(interestFilter, onInterest);
205
Junxiao Shi388ec252014-11-02 15:19:57 -0700206 nfd::CommandOptions options;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700207 if (!certificate.getName().empty()) {
208 options.setSigningInfo(signingByCertificate(certificate.getName()));
Junxiao Shi388ec252014-11-02 15:19:57 -0700209 }
210
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700211 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
212 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700213 flags, options);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700214}
215
216const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000217Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700218 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700219 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700220 const IdentityCertificate& certificate,
221 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700222{
223 shared_ptr<InterestFilterRecord> filter =
224 make_shared<InterestFilterRecord>(interestFilter, onInterest);
225
Junxiao Shi388ec252014-11-02 15:19:57 -0700226 nfd::CommandOptions options;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700227 if (!certificate.getName().empty()) {
228 options.setSigningInfo(signingByCertificate(certificate.getName()));
Junxiao Shi388ec252014-11-02 15:19:57 -0700229 }
230
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700231 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
232 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700233 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700234}
235
236const RegisteredPrefixId*
237Face::setInterestFilter(const InterestFilter& interestFilter,
238 const OnInterest& onInterest,
239 const RegisterPrefixSuccessCallback& onSuccess,
240 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700241 const Name& identity,
242 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700243{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700244 shared_ptr<InterestFilterRecord> filter =
245 make_shared<InterestFilterRecord>(interestFilter, onInterest);
246
Junxiao Shi388ec252014-11-02 15:19:57 -0700247 nfd::CommandOptions options;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700248 options.setSigningInfo(signingByIdentity(identity));
Junxiao Shi388ec252014-11-02 15:19:57 -0700249
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700250 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
251 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700252 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700253}
254
255const RegisteredPrefixId*
256Face::setInterestFilter(const InterestFilter& interestFilter,
257 const OnInterest& onInterest,
258 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700259 const Name& identity,
260 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700261{
262 shared_ptr<InterestFilterRecord> filter =
263 make_shared<InterestFilterRecord>(interestFilter, onInterest);
264
Junxiao Shi388ec252014-11-02 15:19:57 -0700265 nfd::CommandOptions options;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700266 options.setSigningInfo(signingByIdentity(identity));
Junxiao Shi388ec252014-11-02 15:19:57 -0700267
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700268 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
269 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700270 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700271}
272
273
274const InterestFilterId*
275Face::setInterestFilter(const InterestFilter& interestFilter,
276 const OnInterest& onInterest)
277{
278 shared_ptr<InterestFilterRecord> filter =
279 make_shared<InterestFilterRecord>(interestFilter, onInterest);
280
Joao Pereira68c0d882015-05-19 14:27:55 -0400281 getIoService().post([=] { m_impl->asyncSetInterestFilter(filter); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700282
283 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700284}
285
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700286const RegisteredPrefixId*
287Face::registerPrefix(const Name& prefix,
288 const RegisterPrefixSuccessCallback& onSuccess,
289 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700290 const IdentityCertificate& certificate,
291 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700292{
Junxiao Shi388ec252014-11-02 15:19:57 -0700293 nfd::CommandOptions options;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700294 if (!certificate.getName().empty()) {
295 options.setSigningInfo(signingByCertificate(certificate.getName()));
Junxiao Shi388ec252014-11-02 15:19:57 -0700296 }
297
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700298 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
299 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700300 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700301}
302
303const RegisteredPrefixId*
304Face::registerPrefix(const Name& prefix,
305 const RegisterPrefixSuccessCallback& onSuccess,
306 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700307 const Name& identity,
308 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700309{
Junxiao Shi388ec252014-11-02 15:19:57 -0700310 nfd::CommandOptions options;
Junxiao Shic6acc7a2015-06-23 10:03:56 -0700311 options.setSigningInfo(signingByIdentity(identity));
Junxiao Shi388ec252014-11-02 15:19:57 -0700312
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700313 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
314 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700315 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700316}
317
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700318void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800319Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800320{
Joao Pereira68c0d882015-05-19 14:27:55 -0400321 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
322 UnregisterPrefixSuccessCallback(),
323 UnregisterPrefixFailureCallback()); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800324}
325
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700326void
327Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
328{
Joao Pereira68c0d882015-05-19 14:27:55 -0400329 m_ioService.post([=] { m_impl->asyncUnsetInterestFilter(interestFilterId); });
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700330}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700331
332void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700333Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
334 const UnregisterPrefixSuccessCallback& onSuccess,
335 const UnregisterPrefixFailureCallback& onFailure)
336{
Joao Pereira68c0d882015-05-19 14:27:55 -0400337 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700338}
339
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800340void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700341Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
342 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800343{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500344 if (m_ioService.stopped()) {
345 m_ioService.reset(); // ensure that run()/poll() will do some work
346 }
347
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700348 try {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800349 if (timeout < time::milliseconds::zero()) {
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700350 // do not block if timeout is negative, but process pending events
Junxiao Shi2cced062014-11-02 21:27:38 -0700351 m_ioService.poll();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700352 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800353 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800354
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800355 if (timeout > time::milliseconds::zero()) {
356 boost::asio::io_service& ioService = m_ioService;
357 unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
358 m_impl->m_processEventsTimeoutEvent =
359 m_impl->m_scheduler.scheduleEvent(timeout, [&ioService, &work] {
360 ioService.stop();
361 work.reset();
362 });
363 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700364
365 if (keepThread) {
366 // work will ensure that m_ioService is running until work object exists
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800367 m_impl->m_ioServiceWork.reset(new boost::asio::io_service::work(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800368 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700369
Junxiao Shi2cced062014-11-02 21:27:38 -0700370 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700371 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700372 catch (...) {
373 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700374 m_impl->m_pendingInterestTable.clear();
375 m_impl->m_registeredPrefixTable.clear();
376 throw;
377 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700378}
379
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800380void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700381Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700382{
Joao Pereira68c0d882015-05-19 14:27:55 -0400383 m_ioService.post([this] { this->asyncShutdown(); });
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700384}
385
386void
387Face::asyncShutdown()
388{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700389 m_impl->m_pendingInterestTable.clear();
390 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800391
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700392 if (m_transport->isConnected())
393 m_transport->close();
394
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700395 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700396}
397
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800398void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800399Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800400{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800401 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
402
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600403 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800404 {
Alexander Afanasyevea719672015-02-10 20:25:23 -0800405 shared_ptr<Interest> interest = make_shared<Interest>(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800406 if (&block != &blockFromDaemon)
407 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800408
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700409 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800410 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600411 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800412 {
Alexander Afanasyevea719672015-02-10 20:25:23 -0800413 shared_ptr<Data> data = make_shared<Data>(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800414 if (&block != &blockFromDaemon)
415 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800416
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700417 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800418 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800419 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800420}
421
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800422} // namespace ndn