NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: 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 namespace ndn {
38 
40  : m_impl(new Impl(*this))
41 {
42  construct(nullptr, ns3::ndn::StackHelper::getKeyChain());
43 }
44 
45 Face::Face(boost::asio::io_service& ioService)
46  : m_impl(new Impl(*this))
47 {
48  construct(nullptr, ns3::ndn::StackHelper::getKeyChain());
49 }
50 
51 Face::Face(shared_ptr<Transport> transport)
52  : m_impl(new Impl(*this))
53 {
54  construct(transport, ns3::ndn::StackHelper::getKeyChain());
55 }
56 
57 Face::Face(shared_ptr<Transport> transport,
58  boost::asio::io_service& ioService)
59  : m_impl(new Impl(*this))
60 {
61  construct(transport, ns3::ndn::StackHelper::getKeyChain());
62 }
63 
64 Face::Face(shared_ptr<Transport> transport,
65  boost::asio::io_service& ioService,
66  KeyChain& keyChain)
67  : m_impl(new Impl(*this))
68 {
69  construct(transport, keyChain);
70 }
71 
72 shared_ptr<Transport>
73 Face::makeDefaultTransport()
74 {
75  ns3::Ptr<ns3::Node> node = ns3::NodeList::GetNode(ns3::Simulator::GetContext());
76  NS_ASSERT_MSG(node->GetObject<ns3::ndn::L3Protocol>() != 0,
77  "NDN stack should be installed on the node " << node);
78 
79  auto uri = ::nfd::FaceUri("ndnFace://" + boost::lexical_cast<std::string>(node->GetId()));
80 
82  serviceOpts.allowLocalFields = true;
83 
84  auto nfdFace = make_shared<::nfd::Face>(make_unique<::nfd::face::GenericLinkService>(serviceOpts),
85  make_unique<::nfd::face::InternalForwarderTransport>(uri, uri));
86  auto forwarderTransport = static_cast<::nfd::face::InternalForwarderTransport*>(nfdFace->getTransport());
87 
88  auto clientTransport = make_shared<::nfd::face::InternalClientTransport>();
89  clientTransport->connectToForwarder(forwarderTransport);
90 
91  node->GetObject<ns3::ndn::L3Protocol>()->addFace(nfdFace);;
92 
93  return clientTransport;
94 }
95 
96 void
97 Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
98 {
99  if (transport == nullptr) {
100  transport = makeDefaultTransport();
101  }
102  BOOST_ASSERT(transport != nullptr);
103  m_transport = transport;
104 
105  m_nfdController.reset(new nfd::Controller(*this, keyChain));
106 }
107 
108 Face::~Face() = default;
109 
110 shared_ptr<Transport>
111 Face::getTransport()
112 {
113  return m_transport;
114 }
115 
116 const PendingInterestId*
118  const DataCallback& afterSatisfied,
119  const NackCallback& afterNacked,
120  const TimeoutCallback& afterTimeout)
121 {
122  shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
123 
124  // Use `interestToExpress` to avoid wire format creation for the original Interest
125  if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE) {
126  BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
127  }
128 
129  // If the same ioService thread, dispatch directly calls the method
130  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
131  m_impl->asyncExpressInterest(interestToExpress, afterSatisfied,
132  afterNacked, afterTimeout);
133  });
134 
135  return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
136 }
137 
138 const PendingInterestId*
140  const OnData& onData,
141  const OnTimeout& onTimeout)
142 {
143  return this->expressInterest(
144  interest,
145  [onData] (const Interest& interest, const Data& data) {
146  if (onData != nullptr) {
147  onData(interest, const_cast<Data&>(data));
148  }
149  },
150  [onTimeout] (const Interest& interest, const lp::Nack& nack) {
151  if (onTimeout != nullptr) {
152  onTimeout(interest);
153  }
154  },
155  onTimeout
156  );
157 }
158 
159 const PendingInterestId*
161  const Interest& tmpl,
162  const OnData& onData, const OnTimeout& onTimeout/* = nullptr*/)
163 {
164  return expressInterest(Interest(tmpl)
165  .setName(name)
166  .setNonce(0),
167  onData, onTimeout);
168 }
169 
170 void
171 Face::put(const Data& data)
172 {
173  // Use original `data`, since wire format should already exist for the original Data
174  if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
175  BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
176 
177  shared_ptr<const Data> dataPtr;
178  try {
179  dataPtr = data.shared_from_this();
180  }
181  catch (const bad_weak_ptr& e) {
182  std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
183  << std::endl;
184  dataPtr = make_shared<Data>(data);
185  }
186 
187  // If the same ioService thread, dispatch directly calls the method
188  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncPutData(dataPtr); });
189 }
190 
191 void
192 Face::put(const lp::Nack& nack)
193 {
194  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncPutNack(make_shared<lp::Nack>(nack)); });
195 }
196 
197 void
198 Face::removePendingInterest(const PendingInterestId* pendingInterestId)
199 {
200  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncRemovePendingInterest(pendingInterestId); });
201 }
202 
203 void
205 {
206  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncRemoveAllPendingInterests(); });
207 }
208 
209 size_t
211 {
212  return m_impl->m_pendingInterestTable.size();
213 }
214 
215 const RegisteredPrefixId*
217  const OnInterest& onInterest,
218  const RegisterPrefixFailureCallback& onFailure,
219  const security::SigningInfo& signingInfo,
220  uint64_t flags)
221 {
222  return setInterestFilter(interestFilter,
223  onInterest,
225  onFailure,
226  signingInfo,
227  flags);
228 }
229 
230 const RegisteredPrefixId*
232  const OnInterest& onInterest,
233  const RegisterPrefixSuccessCallback& onSuccess,
234  const RegisterPrefixFailureCallback& onFailure,
235  const security::SigningInfo& signingInfo,
236  uint64_t flags)
237 {
238  shared_ptr<InterestFilterRecord> filter =
239  make_shared<InterestFilterRecord>(interestFilter, onInterest);
240 
241  nfd::CommandOptions options;
242  options.setSigningInfo(signingInfo);
243 
244  return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
245  onSuccess, onFailure,
246  flags, options);
247 }
248 
249 const InterestFilterId*
251  const OnInterest& onInterest)
252 {
253  shared_ptr<InterestFilterRecord> filter =
254  make_shared<InterestFilterRecord>(interestFilter, onInterest);
255 
256  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
257  m_impl->asyncSetInterestFilter(filter);
258  });
259 
260  return reinterpret_cast<const InterestFilterId*>(filter.get());
261 }
262 
263 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
264 
265 const RegisteredPrefixId*
266 Face::setInterestFilter(const InterestFilter& interestFilter,
267  const OnInterest& onInterest,
268  const RegisterPrefixSuccessCallback& onSuccess,
269  const RegisterPrefixFailureCallback& onFailure,
270  const IdentityCertificate& certificate,
271  uint64_t flags)
272 {
273  security::SigningInfo signingInfo;
274  if (!certificate.getName().empty()) {
275  signingInfo = signingByCertificate(certificate.getName());
276  }
277  return setInterestFilter(interestFilter, onInterest,
278  onSuccess, onFailure,
279  signingInfo, flags);
280 }
281 
282 const RegisteredPrefixId*
283 Face::setInterestFilter(const InterestFilter& interestFilter,
284  const OnInterest& onInterest,
285  const RegisterPrefixFailureCallback& onFailure,
286  const IdentityCertificate& certificate,
287  uint64_t flags)
288 {
289  security::SigningInfo signingInfo;
290  if (!certificate.getName().empty()) {
291  signingInfo = signingByCertificate(certificate.getName());
292  }
293  return setInterestFilter(interestFilter, onInterest,
294  onFailure, signingInfo, flags);
295 }
296 
297 const RegisteredPrefixId*
298 Face::setInterestFilter(const InterestFilter& interestFilter,
299  const OnInterest& onInterest,
300  const RegisterPrefixSuccessCallback& onSuccess,
301  const RegisterPrefixFailureCallback& onFailure,
302  const Name& identity,
303  uint64_t flags)
304 {
305  security::SigningInfo signingInfo = signingByIdentity(identity);
306 
307  return setInterestFilter(interestFilter, onInterest,
308  onSuccess, onFailure,
309  signingInfo, flags);
310 }
311 
312 const RegisteredPrefixId*
313 Face::setInterestFilter(const InterestFilter& interestFilter,
314  const OnInterest& onInterest,
315  const RegisterPrefixFailureCallback& onFailure,
316  const Name& identity,
317  uint64_t flags)
318 {
319  security::SigningInfo signingInfo = signingByIdentity(identity);
320 
321  return setInterestFilter(interestFilter, onInterest,
322  onFailure, signingInfo, flags);
323 }
324 
325 #endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
326 
327 const RegisteredPrefixId*
329  const RegisterPrefixSuccessCallback& onSuccess,
330  const RegisterPrefixFailureCallback& onFailure,
331  const security::SigningInfo& signingInfo,
332  uint64_t flags)
333 {
334 
335  nfd::CommandOptions options;
336  options.setSigningInfo(signingInfo);
337 
338  return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
339  onSuccess, onFailure,
340  flags, options);
341 }
342 
343 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
344 const RegisteredPrefixId*
345 Face::registerPrefix(const Name& prefix,
346  const RegisterPrefixSuccessCallback& onSuccess,
347  const RegisterPrefixFailureCallback& onFailure,
348  const IdentityCertificate& certificate,
349  uint64_t flags)
350 {
351  security::SigningInfo signingInfo;
352  if (!certificate.getName().empty()) {
353  signingInfo = signingByCertificate(certificate.getName());
354  }
355  return registerPrefix(prefix, onSuccess,
356  onFailure, signingInfo, flags);
357 }
358 
359 const RegisteredPrefixId*
360 Face::registerPrefix(const Name& prefix,
361  const RegisterPrefixSuccessCallback& onSuccess,
362  const RegisterPrefixFailureCallback& onFailure,
363  const Name& identity,
364  uint64_t flags)
365 {
366  security::SigningInfo signingInfo = signingByIdentity(identity);
367  return registerPrefix(prefix, onSuccess,
368  onFailure, signingInfo, flags);
369 }
370 #endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
371 
372 void
373 Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
374 {
375  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
378 }
379 
380 void
381 Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
382 {
383  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncUnsetInterestFilter(interestFilterId); });
384 }
385 
386 void
387 Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
388  const UnregisterPrefixSuccessCallback& onSuccess,
389  const UnregisterPrefixFailureCallback& onFailure)
390 {
391  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
392 }
393 
394 void
395 Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
396  bool keepThread/* = false*/)
397 {
398 }
399 
400 void
402 {
403  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [this] { this->asyncShutdown(); });
404 }
405 
406 void
407 Face::asyncShutdown()
408 {
409  m_impl->m_pendingInterestTable.clear();
410  m_impl->m_registeredPrefixTable.clear();
411 
412  if (m_transport->isConnected())
413  m_transport->close();
414 }
415 
419 template<typename NETPKT>
420 static void
421 extractLpLocalFields(NETPKT& netPacket, const lp::Packet& lpPacket)
422 {
423  if (lpPacket.has<lp::IncomingFaceIdField>()) {
424  netPacket.setTag(make_shared<lp::IncomingFaceIdTag>(lpPacket.get<lp::IncomingFaceIdField>()));
425  }
426 }
427 
428 void
429 Face::onReceiveElement(const Block& blockFromDaemon)
430 {
431  lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
432  // no need to distinguish
433 
434  Buffer::const_iterator begin, end;
435  std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
436  Block netPacket(&*begin, std::distance(begin, end));
437  switch (netPacket.type()) {
438  case tlv::Interest: {
439  shared_ptr<Interest> interest = make_shared<Interest>(netPacket);
440  if (lpPacket.has<lp::NackField>()) {
441  auto nack = make_shared<lp::Nack>(std::move(*interest));
442  nack->setHeader(lpPacket.get<lp::NackField>());
443  extractLpLocalFields(*nack, lpPacket);
444  m_impl->nackPendingInterests(*nack);
445  }
446  else {
447  extractLpLocalFields(*interest, lpPacket);
448  m_impl->processInterestFilters(*interest);
449  }
450  break;
451  }
452  case tlv::Data: {
453  shared_ptr<Data> data = make_shared<Data>(netPacket);
454  extractLpLocalFields(*data, lpPacket);
455  m_impl->satisfyPendingInterests(*data);
456  break;
457  }
458  }
459 }
460 
461 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
function< void(const std::string &)> UnregisterPrefixFailureCallback
Callback called when unregisterPrefix or unsetInterestFilter command fails.
Definition: face.hpp:114
bool allowLocalFields
enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy ...
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:360
The packet signing interface.
Definition: key-chain.hpp:48
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
represents an Interest packet
Definition: interest.hpp:45
function< void(const Interest &)> OnTimeout
Callback called when expressed Interest times out.
Definition: face.hpp:89
bool has() const
Definition: packet.hpp:75
function< void(const InterestFilter &, const Interest &)> OnInterest
Callback called when incoming Interest matches the specified InterestFilter.
Definition: face.hpp:94
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:387
represents a Network Nack
Definition: nack.hpp:40
Face()
Create a new Face using the default transport (UnixTransport)
Definition: face.cpp:39
void removeAllPendingInterests()
Cancel all previously expressed Interests.
Definition: face.cpp:204
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
const RegisteredPrefixId * setInterestFilter(const InterestFilter &interestFilter, const OnInterest &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:216
size_t getNPendingInterests() const
Get number of pending Interests.
Definition: face.cpp:210
void shutdown()
Shutdown face operations.
Definition: face.cpp:401
SigningInfo signingByIdentity(const Name &identity)
NFD Management protocol - ControlCommand client.
function< void(const Name &, const std::string &)> RegisterPrefixFailureCallback
Callback called when registerPrefix or setInterestFilter command fails.
Definition: face.hpp:104
function< void(const Name &)> RegisterPrefixSuccessCallback
Callback called when registerPrefix or setInterestFilter command succeeds.
Definition: face.hpp:99
Name abstraction to represent an absolute name.
Definition: name.hpp:46
void unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
Remove the registered prefix entry with the registeredPrefixId.
Definition: face.cpp:373
CommandOptions & setSigningInfo(const security::SigningInfo &signingInfo)
sets signing parameters
Implementation network-layer of NDN stack.
Options that control the behavior of GenericLinkService.
function< void(const Interest &, Data &)> OnData
Callback called when expressed Interest gets satisfied with Data packet.
Definition: face.hpp:83
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Definition: data.cpp:52
function< void()> UnregisterPrefixSuccessCallback
Callback called when unregisterPrefix or unsetInterestFilter command succeeds.
Definition: face.hpp:109
bool empty() const
Check if name is emtpy.
Definition: name.hpp:398
static KeyChain & getKeyChain()
const PendingInterestId * expressInterest(const Interest &interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
Express Interest.
Definition: face.cpp:117
void processEvents(const time::milliseconds &timeout=time::milliseconds::zero(), bool keepThread=false)
Process any data to receive or call timeout callbacks.
Definition: face.cpp:395
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:421
function< void(const Interest &)> TimeoutCallback
Callback called when expressed Interest times out.
Definition: face.hpp:77
function< void(const Interest &, const lp::Nack &)> NackCallback
Callback called when Nack is sent in response to expressed Interest.
Definition: face.hpp:72
represents a Data packet
Definition: data.hpp:39
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:328
function< void(const Interest &, const Data &)> DataCallback
Callback called 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:198
void put(const Data &data)
Publish data packet.
Definition: face.cpp:171
const size_t MAX_NDN_PACKET_SIZE
practical limit of network layer packet size
Definition: tlv.hpp:39