blob: cf2d1e452bf2504e7d3ec785dd1eee2ef725320e [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"
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 Shiedd834e2014-10-28 20:28:58 -070035 : m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070036 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070037 , m_impl(new Impl(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070038{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070039 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070040 construct(make_shared<UnixTransport>(socketName),
Junxiao Shiedd834e2014-10-28 20:28:58 -070041 make_shared<boost::asio::io_service>(),
42 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080043}
44
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080045Face::Face(const shared_ptr<boost::asio::io_service>& ioService)
Junxiao Shiedd834e2014-10-28 20:28:58 -070046 : m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070047 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070048 , m_impl(new Impl(*this))
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080049{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070050 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070051 construct(make_shared<UnixTransport>(socketName),
Junxiao Shiedd834e2014-10-28 20:28:58 -070052 ioService,
53 m_internalKeyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080054}
55
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070056class NullIoDeleter
57{
58public:
59 void
60 operator()(boost::asio::io_service*)
61 {
62 }
63};
64
65Face::Face(boost::asio::io_service& ioService)
Junxiao Shiedd834e2014-10-28 20:28:58 -070066 : 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 Afanasyev691c3ce2014-04-23 14:28:04 -070069{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070070 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070071 construct(make_shared<UnixTransport>(socketName),
Junxiao Shiedd834e2014-10-28 20:28:58 -070072 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()),
73 m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070074}
75
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080076Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Junxiao Shiedd834e2014-10-28 20:28:58 -070077 : m_internalKeyChain(new KeyChain())
78 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080079{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070080 construct(make_shared<TcpTransport>(host, port),
Junxiao Shiedd834e2014-10-28 20:28:58 -070081 make_shared<boost::asio::io_service>(),
82 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080083}
84
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080085Face::Face(const shared_ptr<Transport>& transport)
Junxiao Shiedd834e2014-10-28 20:28:58 -070086 : m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070087 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070088 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080089{
90 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070091 make_shared<boost::asio::io_service>(),
92 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080093}
94
95Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070096 boost::asio::io_service& ioService)
Junxiao Shiedd834e2014-10-28 20:28:58 -070097 : m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070098 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070099 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800100{
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -0700101 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -0700102 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()),
103 m_internalKeyChain);
104}
105
106Face::Face(shared_ptr<Transport> transport,
107 boost::asio::io_service& ioService,
108 KeyChain& keyChain)
109 : m_internalKeyChain(nullptr)
110 , m_isDirectNfdFibManagementRequested(false)
111 , m_impl(new Impl(*this))
112{
113 construct(transport,
114 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()),
115 &keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800116}
117
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800118void
Junxiao Shiedd834e2014-10-28 20:28:58 -0700119Face::construct(shared_ptr<Transport> transport,
120 shared_ptr<boost::asio::io_service> ioService,
121 KeyChain* keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800122{
Junxiao Shiedd834e2014-10-28 20:28:58 -0700123 m_nfdController = new nfd::Controller(*this, *keyChain);
124
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700125 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800126 m_transport = transport;
127 m_ioService = ioService;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800128
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700129 m_impl->m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(ref(*m_ioService));
130 m_impl->m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(ref(*m_ioService));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800131
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600132 std::string protocol = "nrd-0.1";
133
134 try
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800135 {
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700136 protocol = m_impl->m_config.getParsedConfiguration().get<std::string>("protocol");
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600137 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700138 catch (boost::property_tree::ptree_bad_path& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600139 {
140 // protocol not specified
141 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700142 catch (boost::property_tree::ptree_bad_data& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600143 {
144 throw ConfigFile::Error(error.what());
145 }
146
147 if (isSupportedNrdProtocol(protocol))
148 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700149 // do nothing
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600150 }
Steve DiBenedettoacab8802014-03-24 11:15:57 -0600151 else if (isSupportedNfdProtocol(protocol))
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600152 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700153 m_isDirectNfdFibManagementRequested = true;
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800154 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700155 else
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600156 {
157 throw Face::Error("Cannot create controller for unsupported protocol \"" + protocol + "\"");
158 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800159}
160
Junxiao Shiedd834e2014-10-28 20:28:58 -0700161Face::~Face()
162{
163 if (m_internalKeyChain != nullptr) {
164 delete m_internalKeyChain;
165 }
166
167 delete m_nfdController;
168 delete m_impl;
169}
170
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800171const PendingInterestId*
172Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
173{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700174 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800175
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700176 // Use `interestToExpress` to avoid wire format creation for the original Interest
177 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
178 throw Error("Interest size exceeds maximum limit");
179
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700180 // If the same ioService thread, dispatch directly calls the method
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700181 m_ioService->dispatch(bind(&Impl::asyncExpressInterest, m_impl,
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700182 interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800183
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800184 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
185}
186
187const PendingInterestId*
188Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800189 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800190 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
191{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700192 return expressInterest(Interest(tmpl)
193 .setName(name)
194 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800195 onData, onTimeout);
196}
197
198void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800199Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800200{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700201 // Use original `data`, since wire format should already exist for the original Data
202 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
203 throw Error("Data size exceeds maximum limit");
204
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700205 shared_ptr<const Data> dataPtr;
206 try {
207 dataPtr = data.shared_from_this();
208 }
209 catch (const bad_weak_ptr& e) {
210 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
211 << std::endl;
212 dataPtr = make_shared<Data>(data);
213 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800214
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700215 // If the same ioService thread, dispatch directly calls the method
216 m_ioService->dispatch(bind(&Impl::asyncPutData, m_impl, dataPtr));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800217}
218
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800219void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800220Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800221{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700222 m_ioService->post(bind(&Impl::asyncRemovePendingInterest, m_impl, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800223}
224
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700225size_t
226Face::getNPendingInterests() const
227{
228 return m_impl->m_pendingInterestTable.size();
229}
230
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800231const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000232Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800233 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700234 const RegisterPrefixSuccessCallback& onSuccess,
235 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700236 const IdentityCertificate& certificate,
237 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700238{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700239 shared_ptr<InterestFilterRecord> filter =
240 make_shared<InterestFilterRecord>(interestFilter, onInterest);
241
Junxiao Shi388ec252014-11-02 15:19:57 -0700242 nfd::CommandOptions options;
243 if (certificate.getName().empty()) {
244 options.setSigningDefault();
245 }
246 else {
247 options.setSigningCertificate(certificate);
248 }
249
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);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700253}
254
255const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000256Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700257 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700258 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700259 const IdentityCertificate& certificate,
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;
266 if (certificate.getName().empty()) {
267 options.setSigningDefault();
268 }
269 else {
270 options.setSigningCertificate(certificate);
271 }
272
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700273 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
274 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700275 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700276}
277
278const RegisteredPrefixId*
279Face::setInterestFilter(const InterestFilter& interestFilter,
280 const OnInterest& onInterest,
281 const RegisterPrefixSuccessCallback& onSuccess,
282 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700283 const Name& identity,
284 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700285{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700286 shared_ptr<InterestFilterRecord> filter =
287 make_shared<InterestFilterRecord>(interestFilter, onInterest);
288
Junxiao Shi388ec252014-11-02 15:19:57 -0700289 nfd::CommandOptions options;
290 options.setSigningIdentity(identity);
291
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700292 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
293 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700294 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700295}
296
297const RegisteredPrefixId*
298Face::setInterestFilter(const InterestFilter& interestFilter,
299 const OnInterest& onInterest,
300 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700301 const Name& identity,
302 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700303{
304 shared_ptr<InterestFilterRecord> filter =
305 make_shared<InterestFilterRecord>(interestFilter, onInterest);
306
Junxiao Shi388ec252014-11-02 15:19:57 -0700307 nfd::CommandOptions options;
308 options.setSigningIdentity(identity);
309
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700310 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
311 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700312 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700313}
314
315
316const InterestFilterId*
317Face::setInterestFilter(const InterestFilter& interestFilter,
318 const OnInterest& onInterest)
319{
320 shared_ptr<InterestFilterRecord> filter =
321 make_shared<InterestFilterRecord>(interestFilter, onInterest);
322
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700323 getIoService().post(bind(&Impl::asyncSetInterestFilter, m_impl, filter));
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700324
325 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700326}
327
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700328const RegisteredPrefixId*
329Face::registerPrefix(const Name& prefix,
330 const RegisterPrefixSuccessCallback& onSuccess,
331 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700332 const IdentityCertificate& certificate,
333 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700334{
Junxiao Shi388ec252014-11-02 15:19:57 -0700335 nfd::CommandOptions options;
336 if (certificate.getName().empty()) {
337 options.setSigningDefault();
338 }
339 else {
340 options.setSigningCertificate(certificate);
341 }
342
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700343 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
344 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700345 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700346}
347
348const RegisteredPrefixId*
349Face::registerPrefix(const Name& prefix,
350 const RegisterPrefixSuccessCallback& onSuccess,
351 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700352 const Name& identity,
353 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700354{
Junxiao Shi388ec252014-11-02 15:19:57 -0700355 nfd::CommandOptions options;
356 options.setSigningIdentity(identity);
357
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700358 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
359 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700360 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700361}
362
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700363void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800364Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800365{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700366 m_ioService->post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700367 UnregisterPrefixSuccessCallback(), UnregisterPrefixFailureCallback()));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800368}
369
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700370void
371Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
372{
373 m_ioService->post(bind(&Impl::asyncUnsetInterestFilter, m_impl, interestFilterId));
374}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700375
376void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700377Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
378 const UnregisterPrefixSuccessCallback& onSuccess,
379 const UnregisterPrefixFailureCallback& onFailure)
380{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700381 m_ioService->post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700382 onSuccess, onFailure));
383}
384
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800385void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700386Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
387 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800388{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700389 try {
390 if (timeout < time::milliseconds::zero())
391 {
392 // do not block if timeout is negative, but process pending events
393 m_ioService->poll();
394 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800395 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800396
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700397 if (timeout > time::milliseconds::zero())
398 {
399 m_impl->m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
400 m_impl->m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
401 }
402
403 if (keepThread) {
404 // work will ensure that m_ioService is running until work object exists
405 m_impl->m_ioServiceWork = make_shared<boost::asio::io_service::work>(ref(*m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800406 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700407
408 m_ioService->run();
409 m_ioService->reset(); // so it is possible to run processEvents again (if necessary)
410 }
411 catch (Face::ProcessEventsTimeout&) {
412 // break
413 m_impl->m_ioServiceWork.reset();
414 m_ioService->reset();
415 }
416 catch (...) {
417 m_impl->m_ioServiceWork.reset();
418 m_ioService->reset();
419 m_impl->m_pendingInterestTable.clear();
420 m_impl->m_registeredPrefixTable.clear();
421 throw;
422 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700423}
424
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800425void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700426Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700427{
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700428 m_ioService->post(bind(&Face::asyncShutdown, this));
429}
430
431void
432Face::asyncShutdown()
433{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700434 m_impl->m_pendingInterestTable.clear();
435 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800436
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700437 if (m_transport->isConnected())
438 m_transport->close();
439
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700440 m_impl->m_pitTimeoutCheckTimer->cancel();
441 m_impl->m_processEventsTimeoutTimer->cancel();
442 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700443
444 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700445}
446
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800447void
448Face::fireProcessEventsTimeout(const boost::system::error_code& error)
449{
450 if (!error) // can fire for some other reason, e.g., cancelled
451 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700452}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800453
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800454
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800455void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800456Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800457{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800458 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
459
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600460 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800461 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700462 shared_ptr<Interest> interest = make_shared<Interest>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800463 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800464 if (&block != &blockFromDaemon)
465 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800466
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700467 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800468 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600469 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800470 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700471 shared_ptr<Data> data = make_shared<Data>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800472 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800473 if (&block != &blockFromDaemon)
474 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800475
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700476 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800477
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700478 if (m_impl->m_pendingInterestTable.empty()) {
479 m_impl->m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800480 }
481 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800482 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800483}
484
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800485
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800486
487} // namespace ndn