blob: 53eb4c002822fe85ab3aa047f9a2482e9565bb48 [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 Afanasyev1013fd02017-01-03 13:19:03 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -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 Afanasyev258ec2b2014-05-14 16:15:37 -070020 */
21
22#ifndef NDN_DETAIL_FACE_IMPL_HPP
23#define NDN_DETAIL_FACE_IMPL_HPP
24
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070025#include "../face.hpp"
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080026#include "container-with-on-empty-signal.hpp"
Junxiao Shib6e276f2017-08-14 20:10:04 +000027#include "lp-field-tag.hpp"
Junxiao Shi4460e822017-08-07 22:02:45 +000028#include "pending-interest.hpp"
29#include "registered-prefix.hpp"
Eric Newberry83872fd2015-08-06 17:01:24 -070030#include "../lp/packet.hpp"
Junxiao Shi4b469982015-12-03 18:20:19 +000031#include "../lp/tags.hpp"
Junxiao Shi4460e822017-08-07 22:02:45 +000032#include "../mgmt/nfd/command-options.hpp"
33#include "../mgmt/nfd/controller.hpp"
34#include "../transport/tcp-transport.hpp"
35#include "../transport/unix-transport.hpp"
36#include "../util/config-file.hpp"
37#include "../util/logger.hpp"
38#include "../util/scheduler.hpp"
39#include "../util/signal.hpp"
40
41NDN_LOG_INIT(ndn.Face);
42// INFO level: prefix registration, etc.
43//
44// DEBUG level: packet logging.
45// Each log entry starts with a direction symbol ('<' denotes an outgoing packet, '>' denotes an
46// incoming packet) and a packet type symbol ('I' denotes an Interest, 'D' denotes a Data, 'N'
47// denotes a Nack). Interest is printed as its string representation, Data is printed as name only,
48// Nack is printed as the Interest followed by the Nack reason and delimited by a '~' symbol. A
49// log line about an incoming packet may be followed by zero or more lines about Interest matching
50// InterestFilter, Data satisfying Interest, or Nack rejecting Interest, which are also written at
51// DEBUG level.
52//
53// TRACE level: more detailed unstructured messages.
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070054
55namespace ndn {
56
Junxiao Shib6e276f2017-08-14 20:10:04 +000057/** @brief implementation detail of Face
Junxiao Shi103d8ed2016-08-07 20:34:10 +000058 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070059class Face::Impl : noncopyable
60{
61public:
Junxiao Shib6e276f2017-08-14 20:10:04 +000062 using PendingInterestTable = ContainerWithOnEmptySignal<shared_ptr<PendingInterest>>;
63 using InterestFilterTable = std::list<shared_ptr<InterestFilterRecord>>;
64 using RegisteredPrefixTable = ContainerWithOnEmptySignal<shared_ptr<RegisteredPrefix>>;
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070065
66 explicit
67 Impl(Face& face)
68 : m_face(face)
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080069 , m_scheduler(m_face.getIoService())
70 , m_processEventsTimeoutEvent(m_scheduler)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070071 {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080072 auto postOnEmptyPitOrNoRegisteredPrefixes = [this] {
Junxiao Shi103d8ed2016-08-07 20:34:10 +000073 this->m_face.getIoService().post([this] { this->onEmptyPitOrNoRegisteredPrefixes(); });
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080074 // without this extra "post", transport can get paused (-async_read) and then resumed
75 // (+async_read) from within onInterest/onData callback. After onInterest/onData
76 // finishes, there is another +async_read with the same memory block. A few of such
77 // async_read duplications can cause various effects and result in segfault.
78 };
79
80 m_pendingInterestTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
81 m_registeredPrefixTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070082 }
83
Junxiao Shi103d8ed2016-08-07 20:34:10 +000084public: // consumer
Junxiao Shia1ea5062014-12-27 22:33:39 -070085 void
Eric Newberry83872fd2015-08-06 17:01:24 -070086 asyncExpressInterest(shared_ptr<const Interest> interest,
87 const DataCallback& afterSatisfied,
88 const NackCallback& afterNacked,
89 const TimeoutCallback& afterTimeout)
Junxiao Shia1ea5062014-12-27 22:33:39 -070090 {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080091 this->ensureConnected(true);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070092
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000093 const Interest& interest2 = *interest;
Junxiao Shi103d8ed2016-08-07 20:34:10 +000094 auto entry = m_pendingInterestTable.insert(make_shared<PendingInterest>(
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000095 std::move(interest), afterSatisfied, afterNacked, afterTimeout, ref(m_scheduler))).first;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080096 (*entry)->setDeleter([this, entry] { m_pendingInterestTable.erase(entry); });
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070097
Junxiao Shib6e276f2017-08-14 20:10:04 +000098 lp::Packet lpPacket;
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000099 addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest2);
100 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest2);
Eric Newberry83872fd2015-08-06 17:01:24 -0700101
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000102 m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest2.wireEncode(),
103 'I', interest2.getName()));
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700104 }
105
106 void
107 asyncRemovePendingInterest(const PendingInterestId* pendingInterestId)
108 {
109 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
110 }
111
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700112 void
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500113 asyncRemoveAllPendingInterests()
114 {
115 m_pendingInterestTable.clear();
116 }
117
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000118 /** @return whether the Data should be sent to the forwarder, if it does not come from the forwarder
119 */
120 bool
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000121 satisfyPendingInterests(const Data& data)
122 {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000123 bool hasAppMatch = false, hasForwarderMatch = false;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000124 for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000125 if (!(*entry)->getInterest()->matchesData(data)) {
126 ++entry;
127 continue;
128 }
129
130 shared_ptr<PendingInterest> matchedEntry = *entry;
131 NDN_LOG_DEBUG(" satisfying " << *matchedEntry->getInterest() <<
132 " from " << matchedEntry->getOrigin());
133 entry = m_pendingInterestTable.erase(entry);
134
135 if (matchedEntry->getOrigin() == PendingInterestOrigin::APP) {
136 hasAppMatch = true;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000137 matchedEntry->invokeDataCallback(data);
138 }
139 else {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000140 hasForwarderMatch = true;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000141 }
142 }
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000143 // if Data matches no pending Interest record, it is sent to the forwarder as unsolicited Data
144 return hasForwarderMatch || !hasAppMatch;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000145 }
146
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000147 /** @return whether the Nack should be sent to the forwarder, if it does not come from the forwarder
148 */
149 bool
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000150 nackPendingInterests(const lp::Nack& nack)
151 {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000152 bool shouldSendToForwarder = false;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000153 for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000154 if (!nack.getInterest().matchesInterest(*(*entry)->getInterest())) {
155 ++entry;
156 continue;
157 }
158
159 shared_ptr<PendingInterest> matchedEntry = *entry;
160 NDN_LOG_DEBUG(" nacking " << *matchedEntry->getInterest() <<
161 " from " << matchedEntry->getOrigin());
162 entry = m_pendingInterestTable.erase(entry);
163
164 // TODO #4228 record Nack on PendingInterest record, and send Nack only if all InterestFilters have Nacked
165
166 if (matchedEntry->getOrigin() == PendingInterestOrigin::APP) {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000167 matchedEntry->invokeNackCallback(nack);
168 }
169 else {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000170 shouldSendToForwarder = true;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000171 }
172 }
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000173 return shouldSendToForwarder;
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000174 }
175
176public: // producer
177 void
178 asyncSetInterestFilter(shared_ptr<InterestFilterRecord> interestFilterRecord)
179 {
Junxiao Shi4460e822017-08-07 22:02:45 +0000180 NDN_LOG_INFO("setting InterestFilter: " << interestFilterRecord->getFilter());
181 m_interestFilterTable.push_back(std::move(interestFilterRecord));
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000182 }
183
184 void
185 asyncUnsetInterestFilter(const InterestFilterId* interestFilterId)
186 {
187 InterestFilterTable::iterator i = std::find_if(m_interestFilterTable.begin(),
188 m_interestFilterTable.end(),
189 MatchInterestFilterId(interestFilterId));
190 if (i != m_interestFilterTable.end()) {
Junxiao Shi4460e822017-08-07 22:02:45 +0000191 NDN_LOG_INFO("unsetting InterestFilter: " << (*i)->getFilter());
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000192 m_interestFilterTable.erase(i);
193 }
194 }
195
196 void
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000197 processIncomingInterest(shared_ptr<const Interest> interest)
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000198 {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000199 const Interest& interest2 = *interest;
200 auto entry = m_pendingInterestTable.insert(make_shared<PendingInterest>(
201 std::move(interest), ref(m_scheduler))).first;
202 (*entry)->setDeleter([this, entry] { m_pendingInterestTable.erase(entry); });
203
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000204 for (const auto& filter : m_interestFilterTable) {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000205 if (filter->doesMatch(interest2.getName())) {
Junxiao Shi4460e822017-08-07 22:02:45 +0000206 NDN_LOG_DEBUG(" matches " << filter->getFilter());
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000207 filter->invokeInterestCallback(interest2);
208 // TODO #4228 record number of matched InterestFilters on PendingInterest record
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000209 }
210 }
211 }
212
213 void
Junxiao Shib6e276f2017-08-14 20:10:04 +0000214 asyncPutData(const Data& data)
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700215 {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000216 bool shouldSendToForwarder = satisfyPendingInterests(data);
217 if (!shouldSendToForwarder) {
218 return;
219 }
220
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800221 this->ensureConnected(true);
Junxiao Shib6e276f2017-08-14 20:10:04 +0000222
223 lp::Packet lpPacket;
224 addFieldFromTag<lp::CachePolicyField, lp::CachePolicyTag>(lpPacket, data);
225 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
226
227 m_face.m_transport->send(finishEncoding(std::move(lpPacket), data.wireEncode(),
228 'D', data.getName()));
229 }
230
231 void
232 asyncPutNack(const lp::Nack& nack)
233 {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000234 bool shouldSendToForwarder = nackPendingInterests(nack);
235 if (!shouldSendToForwarder) {
236 return;
237 }
238
Junxiao Shib6e276f2017-08-14 20:10:04 +0000239 this->ensureConnected(true);
240
241 lp::Packet lpPacket;
242 lpPacket.add<lp::NackField>(nack.getHeader());
243 addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
244
245 const Interest& interest = nack.getInterest();
246 m_face.m_transport->send(finishEncoding(std::move(lpPacket), interest.wireEncode(),
247 'N', interest.getName()));
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700248 }
249
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000250public: // prefix registration
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700251 const RegisteredPrefixId*
252 registerPrefix(const Name& prefix,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000253 shared_ptr<InterestFilterRecord> filter,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700254 const RegisterPrefixSuccessCallback& onSuccess,
255 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700256 uint64_t flags,
Junxiao Shi388ec252014-11-02 15:19:57 -0700257 const nfd::CommandOptions& options)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700258 {
Junxiao Shi4460e822017-08-07 22:02:45 +0000259 NDN_LOG_INFO("registering prefix: " << prefix);
260 auto record = make_shared<RegisteredPrefix>(prefix, filter, options);
261
Junxiao Shie7c7f152016-08-20 22:36:22 +0000262 nfd::ControlParameters params;
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400263 params.setName(prefix);
264 params.setFlags(flags);
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000265 m_face.m_nfdController->start<nfd::RibRegisterCommand>(
266 params,
Junxiao Shi4460e822017-08-07 22:02:45 +0000267 [=] (const nfd::ControlParameters&) { this->afterPrefixRegistered(record, onSuccess); },
268 [=] (const nfd::ControlResponse& resp) {
269 NDN_LOG_INFO("register prefix failed: " << record->getPrefix());
270 onFailure(record->getPrefix(), resp.getText());
271 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000272 options);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700273
Junxiao Shi4460e822017-08-07 22:02:45 +0000274 return reinterpret_cast<const RegisteredPrefixId*>(record.get());
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700275 }
276
277 void
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000278 afterPrefixRegistered(shared_ptr<RegisteredPrefix> registeredPrefix,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700279 const RegisterPrefixSuccessCallback& onSuccess)
280 {
Junxiao Shi4460e822017-08-07 22:02:45 +0000281 NDN_LOG_INFO("registered prefix: " << registeredPrefix->getPrefix());
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800282 m_registeredPrefixTable.insert(registeredPrefix);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700283
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000284 if (registeredPrefix->getFilter() != nullptr) {
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700285 // it was a combined operation
286 m_interestFilterTable.push_back(registeredPrefix->getFilter());
287 }
288
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000289 if (onSuccess != nullptr) {
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700290 onSuccess(registeredPrefix->getPrefix());
291 }
292 }
293
294 void
295 asyncUnregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
296 const UnregisterPrefixSuccessCallback& onSuccess,
297 const UnregisterPrefixFailureCallback& onFailure)
298 {
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400299 auto i = std::find_if(m_registeredPrefixTable.begin(),
300 m_registeredPrefixTable.end(),
301 MatchRegisteredPrefixId(registeredPrefixId));
302 if (i != m_registeredPrefixTable.end()) {
303 RegisteredPrefix& record = **i;
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400304 const shared_ptr<InterestFilterRecord>& filter = record.getFilter();
305
306 if (filter != nullptr) {
307 // it was a combined operation
308 m_interestFilterTable.remove(filter);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700309 }
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400310
Junxiao Shi4460e822017-08-07 22:02:45 +0000311 NDN_LOG_INFO("unregistering prefix: " << record.getPrefix());
312
Junxiao Shie7c7f152016-08-20 22:36:22 +0000313 nfd::ControlParameters params;
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400314 params.setName(record.getPrefix());
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000315 m_face.m_nfdController->start<nfd::RibUnregisterCommand>(
316 params,
Junxiao Shie7c7f152016-08-20 22:36:22 +0000317 [=] (const nfd::ControlParameters&) { this->finalizeUnregisterPrefix(i, onSuccess); },
Junxiao Shi4460e822017-08-07 22:02:45 +0000318 [=] (const nfd::ControlResponse& resp) {
319 NDN_LOG_INFO("unregister prefix failed: " << params.getName());
320 onFailure(resp.getText());
321 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000322 record.getCommandOptions());
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400323 }
Alexander Afanasyev851228a2014-10-20 15:55:28 -0400324 else {
Joao Pereiraba1e3b92015-06-01 17:50:37 -0400325 if (onFailure != nullptr) {
Alexander Afanasyev851228a2014-10-20 15:55:28 -0400326 onFailure("Unrecognized PrefixId");
327 }
328 }
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700329
330 // there cannot be two registered prefixes with the same id
331 }
332
333 void
334 finalizeUnregisterPrefix(RegisteredPrefixTable::iterator item,
335 const UnregisterPrefixSuccessCallback& onSuccess)
336 {
Junxiao Shi4460e822017-08-07 22:02:45 +0000337 NDN_LOG_INFO("unregistered prefix: " << (*item)->getPrefix());
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700338 m_registeredPrefixTable.erase(item);
339
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000340 if (onSuccess != nullptr) {
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700341 onSuccess();
342 }
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700343 }
344
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000345public: // IO routine
346 void
347 ensureConnected(bool wantResume)
348 {
349 if (!m_face.m_transport->isConnected())
350 m_face.m_transport->connect(m_face.m_ioService,
351 [=] (const Block& wire) { m_face.onReceiveElement(wire); });
352
353 if (wantResume && !m_face.m_transport->isReceiving()) {
354 m_face.m_transport->resume();
355 }
356 }
357
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700358 void
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800359 onEmptyPitOrNoRegisteredPrefixes()
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700360 {
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800361 if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
362 m_face.m_transport->pause();
363 if (!m_ioServiceWork) {
364 m_processEventsTimeoutEvent.cancel();
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700365 }
366 }
367 }
368
369private:
Junxiao Shib6e276f2017-08-14 20:10:04 +0000370 /** @brief Finish packet encoding
371 * @param lpPacket NDNLP packet without FragmentField
372 * @param wire wire encoding of Interest or Data
373 * @param pktType packet type, 'I' for Interest, 'D' for Data, 'N' for Nack
374 * @param name packet name
375 * @return wire encoding of either NDNLP or bare network packet
376 * @throw Face::OversizedPacketError wire encoding exceeds limit
377 */
378 Block
379 finishEncoding(lp::Packet&& lpPacket, Block wire, char pktType, const Name& name)
380 {
381 if (!lpPacket.empty()) {
382 lpPacket.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
383 wire = lpPacket.wireEncode();
384 }
385
386 if (wire.size() > MAX_NDN_PACKET_SIZE) {
387 BOOST_THROW_EXCEPTION(Face::OversizedPacketError(pktType, name, wire.size()));
388 }
389
390 return wire;
391 }
392
393private:
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700394 Face& m_face;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800395 util::Scheduler m_scheduler;
396 util::scheduler::ScopedEventId m_processEventsTimeoutEvent;
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700397
398 PendingInterestTable m_pendingInterestTable;
399 InterestFilterTable m_interestFilterTable;
400 RegisteredPrefixTable m_registeredPrefixTable;
401
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800402 unique_ptr<boost::asio::io_service::work> m_ioServiceWork; // if thread needs to be preserved
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700403
404 friend class Face;
405};
406
407} // namespace ndn
408
409#endif // NDN_DETAIL_FACE_IMPL_HPP