blob: b36f9551a7a0d0db5b2122bfc036bd87dde3f7a5 [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())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070039 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070040 , m_impl(new Impl(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070041{
Joao Pereira68c0d882015-05-19 14:27:55 -040042 construct(*m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080043}
44
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070045Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070046 : m_ioService(ioService)
47 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070048 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070049 , m_impl(new Impl(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070050{
Joao Pereira68c0d882015-05-19 14:27:55 -040051 construct(*m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070052}
53
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080054Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Junxiao Shi2cced062014-11-02 21:27:38 -070055 : m_internalIoService(new boost::asio::io_service())
56 , m_ioService(*m_internalIoService)
57 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070058 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080059{
Joao Pereira68c0d882015-05-19 14:27:55 -040060 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080061}
62
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080063Face::Face(const shared_ptr<Transport>& transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070064 : m_internalIoService(new boost::asio::io_service())
65 , m_ioService(*m_internalIoService)
66 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070067 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070068 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080069{
Joao Pereira68c0d882015-05-19 14:27:55 -040070 construct(transport, *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080071}
72
73Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070074 boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070075 : m_ioService(ioService)
76 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070077 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070078 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080079{
Joao Pereira68c0d882015-05-19 14:27:55 -040080 construct(transport, *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070081}
82
83Face::Face(shared_ptr<Transport> transport,
84 boost::asio::io_service& ioService,
85 KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070086 : m_ioService(ioService)
87 , m_internalKeyChain(nullptr)
Junxiao Shiedd834e2014-10-28 20:28:58 -070088 , m_isDirectNfdFibManagementRequested(false)
89 , m_impl(new Impl(*this))
90{
Joao Pereira68c0d882015-05-19 14:27:55 -040091 construct(transport, keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080092}
93
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080094void
Joao Pereira68c0d882015-05-19 14:27:55 -040095Face::construct(KeyChain& keyChain)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070096{
97 // transport=unix:///var/run/nfd.sock
98 // transport=tcp://localhost:6363
99
100 const ConfigFile::Parsed& parsed = m_impl->m_config.getParsedConfiguration();
101
102 const auto transportType = parsed.get_optional<std::string>("transport");
103 if (!transportType)
104 {
105 // transport not specified, use default Unix transport.
106 construct(UnixTransport::create(m_impl->m_config), keyChain);
107 return;
108 }
109
110 unique_ptr<util::FaceUri> uri;
111 try
112 {
113 uri.reset(new util::FaceUri(*transportType));
114 }
115 catch (const util::FaceUri::Error& error)
116 {
117 throw ConfigFile::Error(error.what());
118 }
119
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700120 const std::string protocol = uri->getScheme();
121
122 if (protocol == "unix")
123 {
124 construct(UnixTransport::create(m_impl->m_config), keyChain);
125
126 }
127 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6")
128 {
129 construct(TcpTransport::create(m_impl->m_config), keyChain);
130 }
131 else
132 {
133 throw ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\"");
134 }
135}
136
137void
Joao Pereira68c0d882015-05-19 14:27:55 -0400138Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800139{
Joao Pereira68c0d882015-05-19 14:27:55 -0400140 m_nfdController.reset(new nfd::Controller(*this, keyChain));
Junxiao Shiedd834e2014-10-28 20:28:58 -0700141
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700142 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800143 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800144
Junxiao Shi2cced062014-11-02 21:27:38 -0700145 m_impl->m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
146 m_impl->m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
Junxiao Shia1ea5062014-12-27 22:33:39 -0700147 m_impl->ensureConnected(false);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800148
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600149 std::string protocol = "nrd-0.1";
150
151 try
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800152 {
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700153 protocol = m_impl->m_config.getParsedConfiguration().get<std::string>("protocol");
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600154 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700155 catch (boost::property_tree::ptree_bad_path& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600156 {
157 // protocol not specified
158 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700159 catch (boost::property_tree::ptree_bad_data& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600160 {
161 throw ConfigFile::Error(error.what());
162 }
163
164 if (isSupportedNrdProtocol(protocol))
165 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700166 // do nothing
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600167 }
Steve DiBenedettoacab8802014-03-24 11:15:57 -0600168 else if (isSupportedNfdProtocol(protocol))
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600169 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700170 m_isDirectNfdFibManagementRequested = true;
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800171 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700172 else
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600173 {
174 throw Face::Error("Cannot create controller for unsupported protocol \"" + protocol + "\"");
175 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800176}
177
Joao Pereira68c0d882015-05-19 14:27:55 -0400178Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700179
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800180const PendingInterestId*
181Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
182{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700183 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800184
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700185 // Use `interestToExpress` to avoid wire format creation for the original Interest
186 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
187 throw Error("Interest size exceeds maximum limit");
188
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700189 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400190 m_ioService.dispatch([=] { m_impl->asyncExpressInterest(interestToExpress, onData, onTimeout); });
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800191
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800192 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
193}
194
195const PendingInterestId*
196Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800197 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800198 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
199{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700200 return expressInterest(Interest(tmpl)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700201 .setName(name)
202 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800203 onData, onTimeout);
204}
205
206void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800207Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800208{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700209 // Use original `data`, since wire format should already exist for the original Data
210 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
211 throw Error("Data size exceeds maximum limit");
212
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700213 shared_ptr<const Data> dataPtr;
214 try {
215 dataPtr = data.shared_from_this();
216 }
217 catch (const bad_weak_ptr& e) {
218 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
219 << std::endl;
220 dataPtr = make_shared<Data>(data);
221 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800222
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700223 // If the same ioService thread, dispatch directly calls the method
Joao Pereira68c0d882015-05-19 14:27:55 -0400224 m_ioService.dispatch([=] { m_impl->asyncPutData(dataPtr); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800225}
226
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800227void
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
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700233size_t
234Face::getNPendingInterests() const
235{
236 return m_impl->m_pendingInterestTable.size();
237}
238
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800239const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000240Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800241 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700242 const RegisterPrefixSuccessCallback& onSuccess,
243 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700244 const IdentityCertificate& certificate,
245 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700246{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700247 shared_ptr<InterestFilterRecord> filter =
248 make_shared<InterestFilterRecord>(interestFilter, onInterest);
249
Junxiao Shi388ec252014-11-02 15:19:57 -0700250 nfd::CommandOptions options;
251 if (certificate.getName().empty()) {
252 options.setSigningDefault();
253 }
254 else {
255 options.setSigningCertificate(certificate);
256 }
257
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700258 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
259 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700260 flags, options);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700261}
262
263const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000264Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700265 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700266 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700267 const IdentityCertificate& certificate,
268 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700269{
270 shared_ptr<InterestFilterRecord> filter =
271 make_shared<InterestFilterRecord>(interestFilter, onInterest);
272
Junxiao Shi388ec252014-11-02 15:19:57 -0700273 nfd::CommandOptions options;
274 if (certificate.getName().empty()) {
275 options.setSigningDefault();
276 }
277 else {
278 options.setSigningCertificate(certificate);
279 }
280
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700281 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
282 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700283 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700284}
285
286const RegisteredPrefixId*
287Face::setInterestFilter(const InterestFilter& interestFilter,
288 const OnInterest& onInterest,
289 const RegisterPrefixSuccessCallback& onSuccess,
290 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700291 const Name& identity,
292 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700293{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700294 shared_ptr<InterestFilterRecord> filter =
295 make_shared<InterestFilterRecord>(interestFilter, onInterest);
296
Junxiao Shi388ec252014-11-02 15:19:57 -0700297 nfd::CommandOptions options;
298 options.setSigningIdentity(identity);
299
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700300 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
301 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700302 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700303}
304
305const RegisteredPrefixId*
306Face::setInterestFilter(const InterestFilter& interestFilter,
307 const OnInterest& onInterest,
308 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700309 const Name& identity,
310 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700311{
312 shared_ptr<InterestFilterRecord> filter =
313 make_shared<InterestFilterRecord>(interestFilter, onInterest);
314
Junxiao Shi388ec252014-11-02 15:19:57 -0700315 nfd::CommandOptions options;
316 options.setSigningIdentity(identity);
317
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700318 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
319 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700320 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700321}
322
323
324const InterestFilterId*
325Face::setInterestFilter(const InterestFilter& interestFilter,
326 const OnInterest& onInterest)
327{
328 shared_ptr<InterestFilterRecord> filter =
329 make_shared<InterestFilterRecord>(interestFilter, onInterest);
330
Joao Pereira68c0d882015-05-19 14:27:55 -0400331 getIoService().post([=] { m_impl->asyncSetInterestFilter(filter); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700332
333 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700334}
335
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700336const RegisteredPrefixId*
337Face::registerPrefix(const Name& prefix,
338 const RegisterPrefixSuccessCallback& onSuccess,
339 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700340 const IdentityCertificate& certificate,
341 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700342{
Junxiao Shi388ec252014-11-02 15:19:57 -0700343 nfd::CommandOptions options;
344 if (certificate.getName().empty()) {
345 options.setSigningDefault();
346 }
347 else {
348 options.setSigningCertificate(certificate);
349 }
350
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700351 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
352 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700353 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700354}
355
356const RegisteredPrefixId*
357Face::registerPrefix(const Name& prefix,
358 const RegisterPrefixSuccessCallback& onSuccess,
359 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700360 const Name& identity,
361 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700362{
Junxiao Shi388ec252014-11-02 15:19:57 -0700363 nfd::CommandOptions options;
364 options.setSigningIdentity(identity);
365
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700366 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
367 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700368 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700369}
370
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700371void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800372Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800373{
Joao Pereira68c0d882015-05-19 14:27:55 -0400374 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
375 UnregisterPrefixSuccessCallback(),
376 UnregisterPrefixFailureCallback()); });
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800377}
378
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700379void
380Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
381{
Joao Pereira68c0d882015-05-19 14:27:55 -0400382 m_ioService.post([=] { m_impl->asyncUnsetInterestFilter(interestFilterId); });
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700383}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700384
385void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700386Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
387 const UnregisterPrefixSuccessCallback& onSuccess,
388 const UnregisterPrefixFailureCallback& onFailure)
389{
Joao Pereira68c0d882015-05-19 14:27:55 -0400390 m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700391}
392
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800393void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700394Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
395 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800396{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500397 if (m_ioService.stopped()) {
398 m_ioService.reset(); // ensure that run()/poll() will do some work
399 }
400
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700401 try {
402 if (timeout < time::milliseconds::zero())
403 {
404 // do not block if timeout is negative, but process pending events
Junxiao Shi2cced062014-11-02 21:27:38 -0700405 m_ioService.poll();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700406 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800407 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800408
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700409 if (timeout > time::milliseconds::zero())
410 {
411 m_impl->m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
412 m_impl->m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
413 }
414
415 if (keepThread) {
416 // work will ensure that m_ioService is running until work object exists
Junxiao Shi2cced062014-11-02 21:27:38 -0700417 m_impl->m_ioServiceWork = make_shared<boost::asio::io_service::work>(ref(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800418 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700419
Junxiao Shi2cced062014-11-02 21:27:38 -0700420 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700421 }
422 catch (Face::ProcessEventsTimeout&) {
423 // break
424 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700425 }
426 catch (...) {
427 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700428 m_impl->m_pendingInterestTable.clear();
429 m_impl->m_registeredPrefixTable.clear();
430 throw;
431 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700432}
433
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800434void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700435Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700436{
Joao Pereira68c0d882015-05-19 14:27:55 -0400437 m_ioService.post([this] { this->asyncShutdown(); });
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700438}
439
440void
441Face::asyncShutdown()
442{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700443 m_impl->m_pendingInterestTable.clear();
444 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800445
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700446 if (m_transport->isConnected())
447 m_transport->close();
448
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700449 m_impl->m_pitTimeoutCheckTimer->cancel();
450 m_impl->m_processEventsTimeoutTimer->cancel();
451 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700452
453 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700454}
455
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800456void
457Face::fireProcessEventsTimeout(const boost::system::error_code& error)
458{
459 if (!error) // can fire for some other reason, e.g., cancelled
460 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700461}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800462
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800463
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800464void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800465Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800466{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800467 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
468
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600469 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800470 {
Alexander Afanasyevea719672015-02-10 20:25:23 -0800471 shared_ptr<Interest> interest = make_shared<Interest>(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800472 if (&block != &blockFromDaemon)
473 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800474
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700475 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800476 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600477 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800478 {
Alexander Afanasyevea719672015-02-10 20:25:23 -0800479 shared_ptr<Data> data = make_shared<Data>(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800480 if (&block != &blockFromDaemon)
481 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800482
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700483 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800484
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700485 if (m_impl->m_pendingInterestTable.empty()) {
486 m_impl->m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800487 }
488 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800489 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800490}
491
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800492
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800493
494} // namespace ndn