blob: 3722fda898f648fc0742ac44f2d4ae47dc882453 [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 Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * Based on code originally written by Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070022 */
23
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080024#include "face.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070025#include "detail/face-impl.hpp"
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070026
Junxiao Shi468abc32014-11-04 09:12:47 -070027#include "encoding/tlv.hpp"
Junxiao Shiedd834e2014-10-28 20:28:58 -070028#include "security/key-chain.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080029#include "util/time.hpp"
30#include "util/random.hpp"
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070031#include "util/face-uri.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070032
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070033namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080034
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080035Face::Face()
Junxiao Shi2cced062014-11-02 21:27:38 -070036 : m_internalIoService(new boost::asio::io_service())
37 , m_ioService(*m_internalIoService)
38 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070039 , m_impl(new Impl(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070040{
Joao Pereira68c0d882015-05-19 14:27:55 -040041 construct(*m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080042}
43
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070044Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070045 : m_ioService(ioService)
46 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070047 , m_impl(new Impl(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070048{
Joao Pereira68c0d882015-05-19 14:27:55 -040049 construct(*m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070050}
51
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080052Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Junxiao Shi2cced062014-11-02 21:27:38 -070053 : m_internalIoService(new boost::asio::io_service())
54 , m_ioService(*m_internalIoService)
55 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070056 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080057{
Joao Pereira68c0d882015-05-19 14:27:55 -040058 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080059}
60
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080061Face::Face(const shared_ptr<Transport>& transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070062 : m_internalIoService(new boost::asio::io_service())
63 , m_ioService(*m_internalIoService)
64 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070065 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080066{
Joao Pereira68c0d882015-05-19 14:27:55 -040067 construct(transport, *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080068}
69
70Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070071 boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070072 : m_ioService(ioService)
73 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070074 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080075{
Joao Pereira68c0d882015-05-19 14:27:55 -040076 construct(transport, *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070077}
78
79Face::Face(shared_ptr<Transport> transport,
80 boost::asio::io_service& ioService,
81 KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070082 : m_ioService(ioService)
83 , m_internalKeyChain(nullptr)
Junxiao Shiedd834e2014-10-28 20:28:58 -070084 , m_impl(new Impl(*this))
85{
Joao Pereira68c0d882015-05-19 14:27:55 -040086 construct(transport, keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080087}
88
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080089void
Joao Pereira68c0d882015-05-19 14:27:55 -040090Face::construct(KeyChain& keyChain)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070091{
92 // transport=unix:///var/run/nfd.sock
93 // transport=tcp://localhost:6363
94
95 const ConfigFile::Parsed& parsed = m_impl->m_config.getParsedConfiguration();
96
97 const auto transportType = parsed.get_optional<std::string>("transport");
98 if (!transportType)
99 {
100 // transport not specified, use default Unix transport.
101 construct(UnixTransport::create(m_impl->m_config), keyChain);
102 return;
103 }
104
105 unique_ptr<util::FaceUri> uri;
106 try
107 {
108 uri.reset(new util::FaceUri(*transportType));
109 }
110 catch (const util::FaceUri::Error& error)
111 {
112 throw ConfigFile::Error(error.what());
113 }
114
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700115 const std::string protocol = uri->getScheme();
116
117 if (protocol == "unix")
118 {
119 construct(UnixTransport::create(m_impl->m_config), keyChain);
120
121 }
122 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6")
123 {
124 construct(TcpTransport::create(m_impl->m_config), keyChain);
125 }
126 else
127 {
128 throw ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\"");
129 }
130}
131
132void
Joao Pereira68c0d882015-05-19 14:27:55 -0400133Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800134{
Joao Pereira68c0d882015-05-19 14:27:55 -0400135 m_nfdController.reset(new nfd::Controller(*this, keyChain));
Junxiao Shiedd834e2014-10-28 20:28:58 -0700136
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700137 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800138 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800139
Junxiao Shi2cced062014-11-02 21:27:38 -0700140 m_impl->m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
141 m_impl->m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
Junxiao Shia1ea5062014-12-27 22:33:39 -0700142 m_impl->ensureConnected(false);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800143}
144
Joao Pereira68c0d882015-05-19 14:27:55 -0400145Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700146
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800147const PendingInterestId*
148Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
149{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700150 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800151
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700152 // Use `interestToExpress` to avoid wire format creation for the original Interest
153 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
154 throw Error("Interest size exceeds maximum limit");
155
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700156 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400157 m_ioService.dispatch([=] { m_impl->asyncExpressInterest(interestToExpress, onData, onTimeout); });
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800158
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800159 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
160}
161
162const PendingInterestId*
163Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800164 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800165 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
166{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700167 return expressInterest(Interest(tmpl)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700168 .setName(name)
169 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800170 onData, onTimeout);
171}
172
173void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800174Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800175{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700176 // Use original `data`, since wire format should already exist for the original Data
177 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
178 throw Error("Data size exceeds maximum limit");
179
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700180 shared_ptr<const Data> dataPtr;
181 try {
182 dataPtr = data.shared_from_this();
183 }
184 catch (const bad_weak_ptr& e) {
185 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
186 << std::endl;
187 dataPtr = make_shared<Data>(data);
188 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800189
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700190 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400191 m_ioService.dispatch([=] { m_impl->asyncPutData(dataPtr); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800192}
193
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800194void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800195Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800196{
Joao Pereira68c0d882015-05-19 14:27:55 -0400197 m_ioService.post([=] { m_impl->asyncRemovePendingInterest(pendingInterestId); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800198}
199
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700200size_t
201Face::getNPendingInterests() const
202{
203 return m_impl->m_pendingInterestTable.size();
204}
205
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800206const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000207Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800208 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700209 const RegisterPrefixSuccessCallback& onSuccess,
210 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700211 const IdentityCertificate& certificate,
212 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700213{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700214 shared_ptr<InterestFilterRecord> filter =
215 make_shared<InterestFilterRecord>(interestFilter, onInterest);
216
Junxiao Shi388ec252014-11-02 15:19:57 -0700217 nfd::CommandOptions options;
218 if (certificate.getName().empty()) {
219 options.setSigningDefault();
220 }
221 else {
222 options.setSigningCertificate(certificate);
223 }
224
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700225 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
226 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700227 flags, options);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700228}
229
230const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000231Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700232 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700233 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700234 const IdentityCertificate& certificate,
235 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700236{
237 shared_ptr<InterestFilterRecord> filter =
238 make_shared<InterestFilterRecord>(interestFilter, onInterest);
239
Junxiao Shi388ec252014-11-02 15:19:57 -0700240 nfd::CommandOptions options;
241 if (certificate.getName().empty()) {
242 options.setSigningDefault();
243 }
244 else {
245 options.setSigningCertificate(certificate);
246 }
247
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700248 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
249 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700250 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700251}
252
253const RegisteredPrefixId*
254Face::setInterestFilter(const InterestFilter& interestFilter,
255 const OnInterest& onInterest,
256 const RegisterPrefixSuccessCallback& onSuccess,
257 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700258 const Name& identity,
259 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700260{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700261 shared_ptr<InterestFilterRecord> filter =
262 make_shared<InterestFilterRecord>(interestFilter, onInterest);
263
Junxiao Shi388ec252014-11-02 15:19:57 -0700264 nfd::CommandOptions options;
265 options.setSigningIdentity(identity);
266
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700267 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
268 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700269 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700270}
271
272const RegisteredPrefixId*
273Face::setInterestFilter(const InterestFilter& interestFilter,
274 const OnInterest& onInterest,
275 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700276 const Name& identity,
277 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700278{
279 shared_ptr<InterestFilterRecord> filter =
280 make_shared<InterestFilterRecord>(interestFilter, onInterest);
281
Junxiao Shi388ec252014-11-02 15:19:57 -0700282 nfd::CommandOptions options;
283 options.setSigningIdentity(identity);
284
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700285 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
286 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700287 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700288}
289
290
291const InterestFilterId*
292Face::setInterestFilter(const InterestFilter& interestFilter,
293 const OnInterest& onInterest)
294{
295 shared_ptr<InterestFilterRecord> filter =
296 make_shared<InterestFilterRecord>(interestFilter, onInterest);
297
Joao Pereira68c0d882015-05-19 14:27:55 -0400298 getIoService().post([=] { m_impl->asyncSetInterestFilter(filter); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700299
300 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700301}
302
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700303const RegisteredPrefixId*
304Face::registerPrefix(const Name& prefix,
305 const RegisterPrefixSuccessCallback& onSuccess,
306 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700307 const IdentityCertificate& certificate,
308 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700309{
Junxiao Shi388ec252014-11-02 15:19:57 -0700310 nfd::CommandOptions options;
311 if (certificate.getName().empty()) {
312 options.setSigningDefault();
313 }
314 else {
315 options.setSigningCertificate(certificate);
316 }
317
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700318 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
319 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700320 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700321}
322
323const RegisteredPrefixId*
324Face::registerPrefix(const Name& prefix,
325 const RegisterPrefixSuccessCallback& onSuccess,
326 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700327 const Name& identity,
328 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700329{
Junxiao Shi388ec252014-11-02 15:19:57 -0700330 nfd::CommandOptions options;
331 options.setSigningIdentity(identity);
332
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700333 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
334 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700335 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700336}
337
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700338void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800339Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800340{
Joao Pereira68c0d882015-05-19 14:27:55 -0400341 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
342 UnregisterPrefixSuccessCallback(),
343 UnregisterPrefixFailureCallback()); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800344}
345
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700346void
347Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
348{
Joao Pereira68c0d882015-05-19 14:27:55 -0400349 m_ioService.post([=] { m_impl->asyncUnsetInterestFilter(interestFilterId); });
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700350}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700351
352void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700353Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
354 const UnregisterPrefixSuccessCallback& onSuccess,
355 const UnregisterPrefixFailureCallback& onFailure)
356{
Joao Pereira68c0d882015-05-19 14:27:55 -0400357 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700358}
359
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800360void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700361Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
362 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800363{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500364 if (m_ioService.stopped()) {
365 m_ioService.reset(); // ensure that run()/poll() will do some work
366 }
367
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700368 try {
369 if (timeout < time::milliseconds::zero())
370 {
371 // do not block if timeout is negative, but process pending events
Junxiao Shi2cced062014-11-02 21:27:38 -0700372 m_ioService.poll();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700373 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800374 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800375
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700376 if (timeout > time::milliseconds::zero())
377 {
378 m_impl->m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
379 m_impl->m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
380 }
381
382 if (keepThread) {
383 // work will ensure that m_ioService is running until work object exists
Junxiao Shi2cced062014-11-02 21:27:38 -0700384 m_impl->m_ioServiceWork = make_shared<boost::asio::io_service::work>(ref(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800385 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700386
Junxiao Shi2cced062014-11-02 21:27:38 -0700387 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700388 }
389 catch (Face::ProcessEventsTimeout&) {
390 // break
391 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700392 }
393 catch (...) {
394 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700395 m_impl->m_pendingInterestTable.clear();
396 m_impl->m_registeredPrefixTable.clear();
397 throw;
398 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700399}
400
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800401void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700402Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700403{
Joao Pereira68c0d882015-05-19 14:27:55 -0400404 m_ioService.post([this] { this->asyncShutdown(); });
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700405}
406
407void
408Face::asyncShutdown()
409{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700410 m_impl->m_pendingInterestTable.clear();
411 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800412
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700413 if (m_transport->isConnected())
414 m_transport->close();
415
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700416 m_impl->m_pitTimeoutCheckTimer->cancel();
417 m_impl->m_processEventsTimeoutTimer->cancel();
418 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700419
420 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700421}
422
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800423void
424Face::fireProcessEventsTimeout(const boost::system::error_code& error)
425{
426 if (!error) // can fire for some other reason, e.g., cancelled
427 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700428}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800429
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800430
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800431void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800432Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800433{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800434 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
435
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600436 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800437 {
Alexander Afanasyevea719672015-02-10 20:25:23 -0800438 shared_ptr<Interest> interest = make_shared<Interest>(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800439 if (&block != &blockFromDaemon)
440 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800441
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700442 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800443 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600444 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800445 {
Alexander Afanasyevea719672015-02-10 20:25:23 -0800446 shared_ptr<Data> data = make_shared<Data>(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800447 if (&block != &blockFromDaemon)
448 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800449
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700450 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800451
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700452 if (m_impl->m_pendingInterestTable.empty()) {
453 m_impl->m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800454 }
455 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800456 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800457}
458
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800459
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800460
461} // namespace ndn