blob: 8e59ce98371b9a676f16e25ffd431738bc0b0218 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi4460e822017-08-07 22:02:45 +00002/*
Alexander Afanasyev4c9a3d52017-01-03 17:45:19 -08003 * Copyright (c) 2013-2017 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 Shi25467942017-06-30 02:53:14 +000026#include "net/face-uri.hpp"
Junxiao Shic6acc7a2015-06-23 10:03:56 -070027#include "security/signing-helpers.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080028#include "util/random.hpp"
Junxiao Shi4460e822017-08-07 22:02:45 +000029#include "util/time.hpp"
30
31// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070032
Junxiao Shib6e276f2017-08-14 20:10:04 +000033// A callback scheduled through io.post and io.dispatch may be invoked after the face is destructed.
34// To prevent this situation, use these macros to capture Face::m_impl as weak_ptr and skip callback
35// execution if the face has been destructed.
Junxiao Shiae0b4182016-08-08 22:53:17 +000036#define IO_CAPTURE_WEAK_IMPL(OP) \
37 { \
38 weak_ptr<Impl> implWeak(m_impl); \
39 m_ioService.OP([=] { \
40 auto impl = implWeak.lock(); \
41 if (impl != nullptr) {
42#define IO_CAPTURE_WEAK_IMPL_END \
43 } \
44 }); \
45 }
46
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070047namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080048
Junxiao Shib6e276f2017-08-14 20:10:04 +000049Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
50 : Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
51 name.toUri() + " encodes into " + to_string(wireSize) + " octets, "
52 "exceeding the implementation limit of " + to_string(MAX_NDN_PACKET_SIZE) + " octets")
53 , pktType(pktType)
54 , name(name)
55 , wireSize(wireSize)
56{
57}
58
Junxiao Shi103d8ed2016-08-07 20:34:10 +000059Face::Face(shared_ptr<Transport> transport)
Junxiao Shib6e276f2017-08-14 20:10:04 +000060 : m_internalIoService(make_unique<boost::asio::io_service>())
Junxiao Shi2cced062014-11-02 21:27:38 -070061 , m_ioService(*m_internalIoService)
Junxiao Shib6e276f2017-08-14 20:10:04 +000062 , m_internalKeyChain(make_unique<KeyChain>())
Junxiao Shiae0b4182016-08-08 22:53:17 +000063 , m_impl(make_shared<Impl>(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070064{
Junxiao Shib6e276f2017-08-14 20:10:04 +000065 construct(std::move(transport), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080066}
67
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070068Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070069 : m_ioService(ioService)
Junxiao Shib6e276f2017-08-14 20:10:04 +000070 , m_internalKeyChain(make_unique<KeyChain>())
Junxiao Shiae0b4182016-08-08 22:53:17 +000071 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070072{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -080073 construct(nullptr, *m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070074}
75
Junxiao Shi103d8ed2016-08-07 20:34:10 +000076Face::Face(const std::string& host, const std::string& port)
Junxiao Shib6e276f2017-08-14 20:10:04 +000077 : m_internalIoService(make_unique<boost::asio::io_service>())
Junxiao Shi2cced062014-11-02 21:27:38 -070078 , m_ioService(*m_internalIoService)
Junxiao Shib6e276f2017-08-14 20:10:04 +000079 , m_internalKeyChain(make_unique<KeyChain>())
Junxiao Shiae0b4182016-08-08 22:53:17 +000080 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080081{
Joao Pereira68c0d882015-05-19 14:27:55 -040082 construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080083}
84
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070085Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
Junxiao Shib6e276f2017-08-14 20:10:04 +000086 : m_internalIoService(make_unique<boost::asio::io_service>())
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070087 , m_ioService(*m_internalIoService)
Junxiao Shiae0b4182016-08-08 22:53:17 +000088 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070089{
Junxiao Shib6e276f2017-08-14 20:10:04 +000090 construct(std::move(transport), keyChain);
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -070091}
92
93Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070094 : m_ioService(ioService)
Junxiao Shib6e276f2017-08-14 20:10:04 +000095 , m_internalKeyChain(make_unique<KeyChain>())
Junxiao Shiae0b4182016-08-08 22:53:17 +000096 , m_impl(make_shared<Impl>(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080097{
Junxiao Shib6e276f2017-08-14 20:10:04 +000098 construct(std::move(transport), *m_internalKeyChain);
Junxiao Shiedd834e2014-10-28 20:28:58 -070099}
100
Alexander Afanasyev8cf1c562016-06-23 16:01:55 -0700101Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -0700102 : m_ioService(ioService)
Junxiao Shiae0b4182016-08-08 22:53:17 +0000103 , m_impl(make_shared<Impl>(*this))
Junxiao Shiedd834e2014-10-28 20:28:58 -0700104{
Junxiao Shib6e276f2017-08-14 20:10:04 +0000105 construct(std::move(transport), keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800106}
107
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800108shared_ptr<Transport>
109Face::makeDefaultTransport()
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700110{
111 // transport=unix:///var/run/nfd.sock
112 // transport=tcp://localhost:6363
113
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700114 std::string transportUri;
115
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000116 const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
117 if (transportEnviron != nullptr) {
118 transportUri = transportEnviron;
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700119 }
120 else {
121 ConfigFile config;
122 transportUri = config.getParsedConfiguration().get<std::string>("transport", "");
123 }
124
125 if (transportUri.empty()) {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800126 // transport not specified, use default Unix transport.
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700127 return UnixTransport::create("");
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800128 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700129
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800130 std::string protocol;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800131 try {
Junxiao Shi25467942017-06-30 02:53:14 +0000132 FaceUri uri(transportUri);
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800133 protocol = uri.getScheme();
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700134
135 if (protocol == "unix") {
136 return UnixTransport::create(transportUri);
137 }
138 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6") {
139 return TcpTransport::create(transportUri);
140 }
141 else {
142 BOOST_THROW_EXCEPTION(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
143 }
144 }
145 catch (const Transport::Error& error) {
146 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800147 }
Junxiao Shi25467942017-06-30 02:53:14 +0000148 catch (const FaceUri::Error& error) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700149 BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800150 }
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700151}
152
153void
Joao Pereira68c0d882015-05-19 14:27:55 -0400154Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800155{
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800156 if (transport == nullptr) {
157 transport = makeDefaultTransport();
158 }
159 BOOST_ASSERT(transport != nullptr);
Junxiao Shib6e276f2017-08-14 20:10:04 +0000160 m_transport = std::move(transport);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800161
Junxiao Shib6e276f2017-08-14 20:10:04 +0000162 m_nfdController = make_unique<nfd::Controller>(*this, keyChain);
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800163
Junxiao Shiae0b4182016-08-08 22:53:17 +0000164 IO_CAPTURE_WEAK_IMPL(post) {
165 impl->ensureConnected(false);
166 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800167}
168
Joao Pereira68c0d882015-05-19 14:27:55 -0400169Face::~Face() = default;
Junxiao Shiedd834e2014-10-28 20:28:58 -0700170
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800171shared_ptr<Transport>
172Face::getTransport()
173{
174 return m_transport;
175}
176
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800177const PendingInterestId*
Eric Newberry83872fd2015-08-06 17:01:24 -0700178Face::expressInterest(const Interest& interest,
179 const DataCallback& afterSatisfied,
180 const NackCallback& afterNacked,
181 const TimeoutCallback& afterTimeout)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800182{
Junxiao Shib6e276f2017-08-14 20:10:04 +0000183 shared_ptr<Interest> interest2 = make_shared<Interest>(interest);
184 interest2->getNonce();
185 NDN_LOG_DEBUG("<I " << *interest2);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800186
Junxiao Shiae0b4182016-08-08 22:53:17 +0000187 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shib6e276f2017-08-14 20:10:04 +0000188 impl->asyncExpressInterest(interest2, afterSatisfied, afterNacked, afterTimeout);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000189 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800190
Junxiao Shib6e276f2017-08-14 20:10:04 +0000191 return reinterpret_cast<const PendingInterestId*>(interest2.get());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800192}
193
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800194void
Junxiao Shiae0b4182016-08-08 22:53:17 +0000195Face::removePendingInterest(const PendingInterestId* pendingInterestId)
196{
197 IO_CAPTURE_WEAK_IMPL(post) {
198 impl->asyncRemovePendingInterest(pendingInterestId);
199 } IO_CAPTURE_WEAK_IMPL_END
200}
201
202void
203Face::removeAllPendingInterests()
204{
205 IO_CAPTURE_WEAK_IMPL(post) {
206 impl->asyncRemoveAllPendingInterests();
207 } IO_CAPTURE_WEAK_IMPL_END
208}
209
210size_t
211Face::getNPendingInterests() const
212{
213 return m_impl->m_pendingInterestTable.size();
214}
215
216void
Junxiao Shib6e276f2017-08-14 20:10:04 +0000217Face::put(Data data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800218{
Junxiao Shi4460e822017-08-07 22:02:45 +0000219 NDN_LOG_DEBUG("<D " << data.getName());
Junxiao Shiae0b4182016-08-08 22:53:17 +0000220 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shib6e276f2017-08-14 20:10:04 +0000221 impl->asyncPutData(data);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000222 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800223}
224
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800225void
Junxiao Shib6e276f2017-08-14 20:10:04 +0000226Face::put(lp::Nack nack)
Eric Newberry83872fd2015-08-06 17:01:24 -0700227{
Junxiao Shi4460e822017-08-07 22:02:45 +0000228 NDN_LOG_DEBUG("<N " << nack.getInterest() << '~' << nack.getHeader().getReason());
Junxiao Shiae0b4182016-08-08 22:53:17 +0000229 IO_CAPTURE_WEAK_IMPL(dispatch) {
Junxiao Shib6e276f2017-08-14 20:10:04 +0000230 impl->asyncPutNack(nack);
Junxiao Shiae0b4182016-08-08 22:53:17 +0000231 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700232}
233
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800234const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000235Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000236 const InterestCallback& onInterest,
237 const RegisterPrefixFailureCallback& onFailure,
238 const security::SigningInfo& signingInfo,
239 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700240{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000241 return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700242}
243
244const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000245Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000246 const InterestCallback& onInterest,
247 const RegisterPrefixSuccessCallback& onSuccess,
248 const RegisterPrefixFailureCallback& onFailure,
249 const security::SigningInfo& signingInfo,
250 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700251{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000252 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700253
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000254 nfd::CommandOptions options;
255 options.setSigningInfo(signingInfo);
Junxiao Shi388ec252014-11-02 15:19:57 -0700256
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000257 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
258 onSuccess, onFailure, flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700259}
260
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700261const InterestFilterId*
262Face::setInterestFilter(const InterestFilter& interestFilter,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000263 const InterestCallback& onInterest)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700264{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000265 auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700266
Junxiao Shiae0b4182016-08-08 22:53:17 +0000267 IO_CAPTURE_WEAK_IMPL(post) {
268 impl->asyncSetInterestFilter(filter);
269 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700270
271 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700272}
273
Joao Pereira0b3cac52015-07-02 14:49:49 -0400274const RegisteredPrefixId*
275Face::registerPrefix(const Name& prefix,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000276 const RegisterPrefixSuccessCallback& onSuccess,
277 const RegisterPrefixFailureCallback& onFailure,
278 const security::SigningInfo& signingInfo,
279 uint64_t flags)
Joao Pereira0b3cac52015-07-02 14:49:49 -0400280{
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000281 nfd::CommandOptions options;
282 options.setSigningInfo(signingInfo);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400283
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000284 return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400285}
286
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700287void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800288Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800289{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000290 IO_CAPTURE_WEAK_IMPL(post) {
291 impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr);
292 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800293}
294
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700295void
296Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
297{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000298 IO_CAPTURE_WEAK_IMPL(post) {
299 impl->asyncUnsetInterestFilter(interestFilterId);
300 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700301}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700302
303void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700304Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
305 const UnregisterPrefixSuccessCallback& onSuccess,
306 const UnregisterPrefixFailureCallback& onFailure)
307{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000308 IO_CAPTURE_WEAK_IMPL(post) {
309 impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure);
310 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700311}
312
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800313void
Junxiao Shi2ed9e072017-08-13 16:45:48 +0000314Face::doProcessEvents(time::milliseconds timeout, bool keepThread)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800315{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500316 if (m_ioService.stopped()) {
317 m_ioService.reset(); // ensure that run()/poll() will do some work
318 }
319
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700320 try {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800321 if (timeout < time::milliseconds::zero()) {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000322 // do not block if timeout is negative, but process pending events
323 m_ioService.poll();
324 return;
325 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800326
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800327 if (timeout > time::milliseconds::zero()) {
328 boost::asio::io_service& ioService = m_ioService;
329 unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000330 m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.scheduleEvent(timeout,
331 [&ioService, &work] {
332 ioService.stop();
333 work.reset();
334 });
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800335 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700336
337 if (keepThread) {
338 // work will ensure that m_ioService is running until work object exists
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800339 m_impl->m_ioServiceWork.reset(new boost::asio::io_service::work(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800340 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700341
Junxiao Shi2cced062014-11-02 21:27:38 -0700342 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700343 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700344 catch (...) {
345 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700346 m_impl->m_pendingInterestTable.clear();
347 m_impl->m_registeredPrefixTable.clear();
348 throw;
349 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700350}
351
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800352void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700353Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700354{
Junxiao Shiae0b4182016-08-08 22:53:17 +0000355 IO_CAPTURE_WEAK_IMPL(post) {
356 this->asyncShutdown();
357 } IO_CAPTURE_WEAK_IMPL_END
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700358}
359
360void
361Face::asyncShutdown()
362{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700363 m_impl->m_pendingInterestTable.clear();
364 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800365
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700366 if (m_transport->isConnected())
367 m_transport->close();
368
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700369 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700370}
371
Eric Newberry83872fd2015-08-06 17:01:24 -0700372/**
373 * @brief extract local fields from NDNLPv2 packet and tag onto a network layer packet
374 */
Eric Newberry4d261b62016-11-10 13:40:09 -0700375template<typename NetPkt>
Eric Newberry83872fd2015-08-06 17:01:24 -0700376static void
Eric Newberry4d261b62016-11-10 13:40:09 -0700377extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
Eric Newberry83872fd2015-08-06 17:01:24 -0700378{
379 if (lpPacket.has<lp::IncomingFaceIdField>()) {
Junxiao Shi4b469982015-12-03 18:20:19 +0000380 netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
Eric Newberry83872fd2015-08-06 17:01:24 -0700381 }
Eric Newberry4d261b62016-11-10 13:40:09 -0700382
383 if (lpPacket.has<lp::CongestionMarkField>()) {
384 netPacket.setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
385 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700386}
387
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800388void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800389Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800390{
Eric Newberry83872fd2015-08-06 17:01:24 -0700391 lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
392 // no need to distinguish
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800393
Eric Newberry83872fd2015-08-06 17:01:24 -0700394 Buffer::const_iterator begin, end;
395 std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
396 Block netPacket(&*begin, std::distance(begin, end));
397 switch (netPacket.type()) {
398 case tlv::Interest: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000399 auto interest = make_shared<Interest>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700400 if (lpPacket.has<lp::NackField>()) {
401 auto nack = make_shared<lp::Nack>(std::move(*interest));
402 nack->setHeader(lpPacket.get<lp::NackField>());
403 extractLpLocalFields(*nack, lpPacket);
Junxiao Shi4460e822017-08-07 22:02:45 +0000404 NDN_LOG_DEBUG(">N " << nack->getInterest() << '~' << nack->getHeader().getReason());
Eric Newberry83872fd2015-08-06 17:01:24 -0700405 m_impl->nackPendingInterests(*nack);
406 }
407 else {
408 extractLpLocalFields(*interest, lpPacket);
Junxiao Shi4460e822017-08-07 22:02:45 +0000409 NDN_LOG_DEBUG(">I " << *interest);
Eric Newberry83872fd2015-08-06 17:01:24 -0700410 m_impl->processInterestFilters(*interest);
411 }
412 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800413 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700414 case tlv::Data: {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000415 auto data = make_shared<Data>(netPacket);
Eric Newberry83872fd2015-08-06 17:01:24 -0700416 extractLpLocalFields(*data, lpPacket);
Junxiao Shi4460e822017-08-07 22:02:45 +0000417 NDN_LOG_DEBUG(">D " << data->getName());
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700418 m_impl->satisfyPendingInterests(*data);
Eric Newberry83872fd2015-08-06 17:01:24 -0700419 break;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800420 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700421 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800422}
423
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800424} // namespace ndn