NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
face.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "face.hpp"
23 #include "detail/face-impl.hpp"
24 
25 #include "encoding/tlv.hpp"
26 #include "security/key-chain.hpp"
28 #include "util/time.hpp"
29 #include "util/random.hpp"
30 #include "util/face-uri.hpp"
31 
32 #include "ns3/node-list.h"
33 #include "ns3/ndnSIM/helper/ndn-stack-helper.hpp"
34 #include "ns3/ndnSIM/NFD/daemon/face/generic-link-service.hpp"
35 #include "ns3/ndnSIM/NFD/daemon/face/internal-transport.hpp"
36 
37 // A callback scheduled through io.post and io.dispatch may be invoked after the face
38 // is destructed. To prevent this situation, these macros captures Face::m_impl as weak_ptr,
39 // and skips callback execution if the face has been destructed.
40 #define IO_CAPTURE_WEAK_IMPL(OP) \
41  { \
42  weak_ptr<Impl> implWeak(m_impl); \
43  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { \
44  auto impl = implWeak.lock(); \
45  if (impl != nullptr) {
46 #define IO_CAPTURE_WEAK_IMPL_END \
47  } \
48  }); \
49  }
50 
51 namespace ndn {
52 
53 Face::Face(shared_ptr<Transport> transport)
54  : m_impl(new Impl(*this))
55 {
56  construct(transport, ns3::ndn::StackHelper::getKeyChain());
57 }
58 
59 Face::Face(boost::asio::io_service& ioService)
60  : m_impl(new Impl(*this))
61 {
62  construct(nullptr, ns3::ndn::StackHelper::getKeyChain());
63 }
64 
65 Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
66  : m_impl(new Impl(*this))
67 {
68  construct(transport, keyChain);
69 }
70 
71 Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
72  : m_impl(new Impl(*this))
73 {
74  construct(transport, ns3::ndn::StackHelper::getKeyChain());
75 }
76 
77 Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
78  : m_impl(new Impl(*this))
79 {
80  construct(transport, keyChain);
81 }
82 
83 shared_ptr<Transport>
84 Face::makeDefaultTransport()
85 {
86  ns3::Ptr<ns3::Node> node = ns3::NodeList::GetNode(ns3::Simulator::GetContext());
87  NS_ASSERT_MSG(node->GetObject<ns3::ndn::L3Protocol>() != 0,
88  "NDN stack should be installed on the node " << node);
89 
90  auto uri = ::nfd::FaceUri("ndnFace://" + boost::lexical_cast<std::string>(node->GetId()));
91 
93  serviceOpts.allowLocalFields = true;
94 
95  auto nfdFace = make_shared<::nfd::Face>(make_unique<::nfd::face::GenericLinkService>(serviceOpts),
96  make_unique<::nfd::face::InternalForwarderTransport>(uri, uri));
97  auto forwarderTransport = static_cast<::nfd::face::InternalForwarderTransport*>(nfdFace->getTransport());
98 
99  auto clientTransport = make_shared<::nfd::face::InternalClientTransport>();
100  clientTransport->connectToForwarder(forwarderTransport);
101 
102  node->GetObject<ns3::ndn::L3Protocol>()->addFace(nfdFace);;
103 
104  return clientTransport;
105 }
106 
107 void
108 Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
109 {
110  if (transport == nullptr) {
111  transport = makeDefaultTransport();
112  }
113  BOOST_ASSERT(transport != nullptr);
114  m_transport = transport;
115 
116  m_nfdController.reset(new nfd::Controller(*this, keyChain));
117 
118  IO_CAPTURE_WEAK_IMPL(post) {
119  impl->ensureConnected(false);
121 }
122 
123 Face::~Face() = default;
124 
125 shared_ptr<Transport>
126 Face::getTransport()
127 {
128  return m_transport;
129 }
130 
131 const PendingInterestId*
133  const DataCallback& afterSatisfied,
134  const NackCallback& afterNacked,
135  const TimeoutCallback& afterTimeout)
136 {
137  shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
138 
139  // Use `interestToExpress` to avoid wire format creation for the original Interest
140  if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE) {
141  BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
142  }
143 
144  // If the same ioService thread, dispatch directly calls the method
145  IO_CAPTURE_WEAK_IMPL(dispatch) {
146  impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
148 
149  return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
150 }
151 
152 const PendingInterestId*
154  const OnData& onData,
155  const OnTimeout& onTimeout)
156 {
157  return this->expressInterest(
158  interest,
159  [onData] (const Interest& interest, const Data& data) {
160  if (onData != nullptr) {
161  onData(interest, const_cast<Data&>(data));
162  }
163  },
164  [onTimeout] (const Interest& interest, const lp::Nack& nack) {
165  if (onTimeout != nullptr) {
166  onTimeout(interest);
167  }
168  },
169  onTimeout
170  );
171 }
172 
173 const PendingInterestId*
175  const OnData& onData, const OnTimeout& onTimeout)
176 {
177  return expressInterest(Interest(tmpl).setName(name).setNonce(0),
178  onData, onTimeout);
179 }
180 
181 void
182 Face::removePendingInterest(const PendingInterestId* pendingInterestId)
183 {
184  IO_CAPTURE_WEAK_IMPL(post) {
185  impl->asyncRemovePendingInterest(pendingInterestId);
187 }
188 
189 void
191 {
192  IO_CAPTURE_WEAK_IMPL(post) {
193  impl->asyncRemoveAllPendingInterests();
195 }
196 
197 size_t
199 {
200  return m_impl->m_pendingInterestTable.size();
201 }
202 
203 void
204 Face::put(const Data& data)
205 {
206  Block wire = data.wireEncode();
207 
208  lp::Packet packet;
209  bool hasLpFields = false;
210 
211  shared_ptr<lp::CachePolicyTag> cachePolicyTag = data.getTag<lp::CachePolicyTag>();
212  if (cachePolicyTag != nullptr) {
213  packet.add<lp::CachePolicyField>(*cachePolicyTag);
214  hasLpFields = true;
215  }
216 
217  shared_ptr<lp::CongestionMarkTag> congestionMarkTag = data.getTag<lp::CongestionMarkTag>();
218  if (congestionMarkTag != nullptr) {
219  packet.add<lp::CongestionMarkField>(*congestionMarkTag);
220  hasLpFields = true;
221  }
222 
223  if (hasLpFields) {
224  packet.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
225  wire = packet.wireEncode();
226  }
227 
228  if (wire.size() > MAX_NDN_PACKET_SIZE)
229  BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
230 
231  IO_CAPTURE_WEAK_IMPL(dispatch) {
232  impl->asyncSend(wire);
234 }
235 
236 void
237 Face::put(const lp::Nack& nack)
238 {
239  lp::Packet packet;
240  packet.add<lp::NackField>(nack.getHeader());
241  const Block& interestWire = nack.getInterest().wireEncode();
242  packet.add<lp::FragmentField>(std::make_pair(interestWire.begin(), interestWire.end()));
243 
244  shared_ptr<lp::CongestionMarkTag> congestionMarkTag = nack.getTag<lp::CongestionMarkTag>();
245  if (congestionMarkTag != nullptr) {
246  packet.add<lp::CongestionMarkField>(*congestionMarkTag);
247  }
248 
249  Block wire = packet.wireEncode();
250 
251  if (wire.size() > MAX_NDN_PACKET_SIZE)
252  BOOST_THROW_EXCEPTION(Error("Nack size exceeds maximum limit"));
253 
254  IO_CAPTURE_WEAK_IMPL(dispatch) {
255  impl->asyncSend(wire);
257 }
258 
259 const RegisteredPrefixId*
261  const InterestCallback& onInterest,
262  const RegisterPrefixFailureCallback& onFailure,
263  const security::SigningInfo& signingInfo,
264  uint64_t flags)
265 {
266  return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
267 }
268 
269 const RegisteredPrefixId*
271  const InterestCallback& onInterest,
272  const RegisterPrefixSuccessCallback& onSuccess,
273  const RegisterPrefixFailureCallback& onFailure,
274  const security::SigningInfo& signingInfo,
275  uint64_t flags)
276 {
277  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
278 
279  nfd::CommandOptions options;
280  options.setSigningInfo(signingInfo);
281 
282  return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
283  onSuccess, onFailure, flags, options);
284 }
285 
286 const InterestFilterId*
288  const InterestCallback& onInterest)
289 {
290  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
291 
292  IO_CAPTURE_WEAK_IMPL(post) {
293  impl->asyncSetInterestFilter(filter);
295 
296  return reinterpret_cast<const InterestFilterId*>(filter.get());
297 }
298 
299 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
300 
301 const RegisteredPrefixId*
302 Face::setInterestFilter(const InterestFilter& interestFilter,
303  const OnInterest& onInterest,
304  const RegisterPrefixSuccessCallback& onSuccess,
305  const RegisterPrefixFailureCallback& onFailure,
306  const security::v1::IdentityCertificate& certificate,
307  uint64_t flags)
308 {
309  security::SigningInfo signingInfo;
310  if (!certificate.getName().empty()) {
311  signingInfo = signingByCertificate(certificate.getName());
312  }
313  return setInterestFilter(interestFilter, onInterest, onSuccess, onFailure, signingInfo, flags);
314 }
315 
316 const RegisteredPrefixId*
317 Face::setInterestFilter(const InterestFilter& interestFilter,
318  const OnInterest& onInterest,
319  const RegisterPrefixFailureCallback& onFailure,
320  const security::v1::IdentityCertificate& certificate,
321  uint64_t flags)
322 {
323  security::SigningInfo signingInfo;
324  if (!certificate.getName().empty()) {
325  signingInfo = signingByCertificate(certificate.getName());
326  }
327  return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
328 }
329 
330 const RegisteredPrefixId*
331 Face::setInterestFilter(const InterestFilter& interestFilter,
332  const OnInterest& onInterest,
333  const RegisterPrefixSuccessCallback& onSuccess,
334  const RegisterPrefixFailureCallback& onFailure,
335  const Name& identity,
336  uint64_t flags)
337 {
338  security::SigningInfo signingInfo = signingByIdentity(identity);
339  return setInterestFilter(interestFilter, onInterest,
340  onSuccess, onFailure,
341  signingInfo, flags);
342 }
343 
344 const RegisteredPrefixId*
345 Face::setInterestFilter(const InterestFilter& interestFilter,
346  const OnInterest& onInterest,
347  const RegisterPrefixFailureCallback& onFailure,
348  const Name& identity,
349  uint64_t flags)
350 {
351  security::SigningInfo signingInfo = signingByIdentity(identity);
352  return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
353 }
354 
355 #endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
356 
357 const RegisteredPrefixId*
359  const RegisterPrefixSuccessCallback& onSuccess,
360  const RegisterPrefixFailureCallback& onFailure,
361  const security::SigningInfo& signingInfo,
362  uint64_t flags)
363 {
364  nfd::CommandOptions options;
365  options.setSigningInfo(signingInfo);
366 
367  return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
368 }
369 
370 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
371 const RegisteredPrefixId*
372 Face::registerPrefix(const Name& prefix,
373  const RegisterPrefixSuccessCallback& onSuccess,
374  const RegisterPrefixFailureCallback& onFailure,
375  const security::v1::IdentityCertificate& certificate,
376  uint64_t flags)
377 {
378  security::SigningInfo signingInfo;
379  if (!certificate.getName().empty()) {
380  signingInfo = signingByCertificate(certificate.getName());
381  }
382  return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
383 }
384 
385 const RegisteredPrefixId*
386 Face::registerPrefix(const Name& prefix,
387  const RegisterPrefixSuccessCallback& onSuccess,
388  const RegisterPrefixFailureCallback& onFailure,
389  const Name& identity,
390  uint64_t flags)
391 {
392  security::SigningInfo signingInfo = signingByIdentity(identity);
393  return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
394 }
395 #endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
396 
397 void
398 Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
399 {
400  IO_CAPTURE_WEAK_IMPL(post) {
401  impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr);
403 }
404 
405 void
406 Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
407 {
408  IO_CAPTURE_WEAK_IMPL(post) {
409  impl->asyncUnsetInterestFilter(interestFilterId);
411 }
412 
413 void
414 Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
415  const UnregisterPrefixSuccessCallback& onSuccess,
416  const UnregisterPrefixFailureCallback& onFailure)
417 {
418  IO_CAPTURE_WEAK_IMPL(post) {
419  impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure);
421 }
422 
423 void
424 Face::doProcessEvents(const time::milliseconds& timeout, bool keepThread)
425 {
426 }
427 
428 void
430 {
431  IO_CAPTURE_WEAK_IMPL(post) {
432  this->asyncShutdown();
434 }
435 
436 void
437 Face::asyncShutdown()
438 {
439  m_impl->m_pendingInterestTable.clear();
440  m_impl->m_registeredPrefixTable.clear();
441 
442  if (m_transport->isConnected())
443  m_transport->close();
444 }
445 
449 template<typename NetPkt>
450 static void
451 extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
452 {
453  if (lpPacket.has<lp::IncomingFaceIdField>()) {
454  netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
455  }
456 
457  if (lpPacket.has<lp::CongestionMarkField>()) {
458  netPacket.setTag(make_shared<lp::CongestionMarkTag>(lpPacket.get<lp::CongestionMarkField>()));
459  }
460 }
461 
462 void
463 Face::onReceiveElement(const Block& blockFromDaemon)
464 {
465  lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
466  // no need to distinguish
467 
468  Buffer::const_iterator begin, end;
469  std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
470  Block netPacket(&*begin, std::distance(begin, end));
471  switch (netPacket.type()) {
472  case tlv::Interest: {
473  auto interest = make_shared<Interest>(netPacket);
474  if (lpPacket.has<lp::NackField>()) {
475  auto nack = make_shared<lp::Nack>(std::move(*interest));
476  nack->setHeader(lpPacket.get<lp::NackField>());
477  extractLpLocalFields(*nack, lpPacket);
478  m_impl->nackPendingInterests(*nack);
479  }
480  else {
481  extractLpLocalFields(*interest, lpPacket);
482  m_impl->processInterestFilters(*interest);
483  }
484  break;
485  }
486  case tlv::Data: {
487  auto data = make_shared<Data>(netPacket);
488  extractLpLocalFields(*data, lpPacket);
489  m_impl->satisfyPendingInterests(*data);
490  break;
491  }
492  }
493 }
494 
495 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
shared_ptr< T > getTag() const
get a tag item
Definition: tag-host.hpp:67
size_t wireEncode(EncodingImpl< TAG > &encoder) const
append packet to encoder
Definition: packet.cpp:42
function< void(const std::string &)> UnregisterPrefixFailureCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command fails.
Definition: face.hpp:120
#define IO_CAPTURE_WEAK_IMPL_END
Definition: face.cpp:46
bool allowLocalFields
enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy ...
const RegisteredPrefixId * setInterestFilter(const InterestFilter &interestFilter, const InterestCallback &onInterest, const RegisterPrefixFailureCallback &onFailure, const security::SigningInfo &signingInfo=security::SigningInfo(), uint64_t flags=nfd::ROUTE_FLAG_CHILD_INHERIT)
Set InterestFilter to dispatch incoming matching interest to onInterest callback and register the fil...
Definition: face.cpp:260
Packet & add(const typename FIELD::ValueType &value)
add a FIELD with value
Definition: packet.hpp:156
represents the underlying protocol and address used by a Face
Definition: face-uri.hpp:44
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:318
declares the set of Interests a producer can serve, which starts with a name prefix, plus an optional regular expression
The packet signing interface.
Definition: key-chain.hpp:47
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
represents an Interest packet
Definition: interest.hpp:42
function< void(const Interest &)> OnTimeout
Callback invoked when expressed Interest times out.
Definition: face.hpp:89
const NackHeader & getHeader() const
Definition: nack.hpp:65
bool has() const
Definition: packet.hpp:75
static void extractLpLocalFields(NetPkt &netPacket, const lp::Packet &lpPacket)
extract local fields from NDNLPv2 packet and tag onto a network layer packet
Definition: face.cpp:451
function< void(const InterestFilter &, const Interest &)> OnInterest
Callback invoked when incoming Interest matches the specified InterestFilter.
Definition: face.hpp:100
virtual void doProcessEvents(const time::milliseconds &timeout, bool keepThread)
Definition: face.cpp:424
Signing parameters passed to KeyChain.
SigningInfo signingByCertificate(const Name &certName)
void unregisterPrefix(const RegisteredPrefixId *registeredPrefixId, const UnregisterPrefixSuccessCallback &onSuccess, const UnregisterPrefixFailureCallback &onFailure)
Unregister prefix from RIB.
Definition: face.cpp:414
represents a Network Nack
Definition: nack.hpp:40
provides a tag type for simple types
Definition: tag.hpp:58
void removeAllPendingInterests()
Cancel all previously expressed Interests.
Definition: face.cpp:190
size_t size() const
Definition: block.cpp:504
FIELD::ValueType get(size_t index=0) const
Definition: packet.hpp:100
implements a forwarder-side transport that can be paired with another
contains options for ControlCommand execution
size_t getNPendingInterests() const
Get number of pending Interests.
Definition: face.cpp:198
void shutdown()
Shutdown face operations.
Definition: face.cpp:429
SigningInfo signingByIdentity(const Name &identity)
NFD Management protocol client.
Definition: controller.hpp:51
Buffer::const_iterator begin() const
Definition: block.cpp:477
function< void(const Name &, const std::string &)> RegisterPrefixFailureCallback
Callback invoked when registerPrefix or setInterestFilter command fails.
Definition: face.hpp:110
function< void(const Name &)> RegisterPrefixSuccessCallback
Callback invoked when registerPrefix or setInterestFilter command succeeds.
Definition: face.hpp:105
Name abstraction to represent an absolute name.
Definition: name.hpp:46
Buffer::const_iterator end() const
Definition: block.cpp:486
void unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
Remove the registered prefix entry with the registeredPrefixId.
Definition: face.cpp:398
CommandOptions & setSigningInfo(const security::SigningInfo &signingInfo)
sets signing parameters
Implementation network-layer of NDN stack.
function< void(const InterestFilter &, const Interest &)> InterestCallback
Callback invoked when incoming Interest matches the specified InterestFilter.
Definition: face.hpp:94
Options that control the behavior of GenericLinkService.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: interest.cpp:217
function< void(const Interest &, Data &)> OnData
Callback invoked when expressed Interest gets satisfied with Data packet.
Definition: face.hpp:83
#define IO_CAPTURE_WEAK_IMPL(OP)
Copyright (c) 2013-2016 Regents of the University of California.
Definition: face.cpp:40
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Definition: data.cpp:52
function< void()> UnregisterPrefixSuccessCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds.
Definition: face.hpp:115
bool empty() const
Check if name is emtpy.
Definition: name.hpp:390
static KeyChain & getKeyChain()
const PendingInterestId * expressInterest(const Interest &interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
Express Interest.
Definition: face.cpp:132
function< void(const Interest &)> TimeoutCallback
Callback invoked when expressed Interest times out.
Definition: face.hpp:77
function< void(const Interest &, const lp::Nack &)> NackCallback
Callback invoked when Nack is sent in response to expressed Interest.
Definition: face.hpp:72
represents a Data packet
Definition: data.hpp:37
const RegisteredPrefixId * registerPrefix(const Name &prefix, const RegisterPrefixSuccessCallback &onSuccess, const RegisterPrefixFailureCallback &onFailure, const security::SigningInfo &signingInfo=security::SigningInfo(), uint64_t flags=nfd::ROUTE_FLAG_CHILD_INHERIT)
Register prefix with the connected NDN forwarder.
Definition: face.cpp:358
Face(shared_ptr< Transport > transport=nullptr)
Create Face using given transport (or default transport if omitted)
Definition: face.cpp:53
const Interest & getInterest() const
Definition: nack.hpp:53
function< void(const Interest &, const Data &)> DataCallback
Callback invoked when expressed Interest gets satisfied with a Data packet.
Definition: face.hpp:67
void removePendingInterest(const PendingInterestId *pendingInterestId)
Cancel previously expressed Interest.
Definition: face.cpp:182
void put(const Data &data)
Publish data packet.
Definition: face.cpp:204
const size_t MAX_NDN_PACKET_SIZE
practical limit of network layer packet size
Definition: tlv.hpp:39