NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: 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; -*- */
2 /*
3  * Copyright (c) 2013-2019 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * 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.
20  */
21 
22 #include "ndn-cxx/face.hpp"
23 #include "ndn-cxx/encoding/tlv.hpp"
25 #include "ndn-cxx/net/face-uri.hpp"
27 #include "ndn-cxx/util/random.hpp"
28 #include "ndn-cxx/util/time.hpp"
29 
30 #include "ns3/node-list.h"
31 #include "ns3/ndnSIM/helper/ndn-stack-helper.hpp"
32 #include "ns3/ndnSIM/NFD/daemon/face/generic-link-service.hpp"
33 #include "ns3/ndnSIM/NFD/daemon/face/internal-transport.hpp"
34 
35 // NDN_LOG_INIT(ndn.Face) is declared in face-impl.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 
41 #define IO_CAPTURE_WEAK_IMPL(OP) \
42  { \
43  weak_ptr<Impl> implWeak(m_impl); \
44  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { \
45  auto impl = implWeak.lock(); \
46  if (impl != nullptr) {
47 #define IO_CAPTURE_WEAK_IMPL_END \
48  } \
49  }); \
50  }
51 
52 namespace ndn {
53 
54 Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
55  : Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
56  name.toUri() + " encodes into " + to_string(wireSize) + " octets, "
57  "exceeding the implementation limit of " + to_string(MAX_NDN_PACKET_SIZE) + " octets")
58  , pktType(pktType)
59  , name(name)
60  , wireSize(wireSize)
61 {
62 }
63 
65  : m_impl(new Impl(*this))
66 {
67  construct(nullptr, ns3::ndn::StackHelper::getKeyChain());
68 }
69 
70 Face::Face(shared_ptr<Transport> transport)
71  : m_impl(new Impl(*this))
72 {
73  construct(transport, ns3::ndn::StackHelper::getKeyChain());
74 }
75 
76 Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
77  : m_impl(new Impl(*this))
78 {
79  construct(std::move(transport), keyChain);
80 }
81 
82 shared_ptr<Transport>
83 Face::makeDefaultTransport()
84 {
85  ns3::Ptr<ns3::Node> node = ns3::NodeList::GetNode(ns3::Simulator::GetContext());
86  NS_ASSERT_MSG(node->GetObject<ns3::ndn::L3Protocol>() != 0,
87  "NDN stack should be installed on the node " << node);
88 
89  auto uri = ::nfd::FaceUri("ndnFace://" + boost::lexical_cast<std::string>(node->GetId()));
90 
92  serviceOpts.allowLocalFields = true;
93 
94  auto nfdFace = make_shared<::nfd::Face>(make_unique<::nfd::face::GenericLinkService>(serviceOpts),
95  make_unique<::nfd::face::InternalForwarderTransport>(uri, uri));
96  auto forwarderTransport = static_cast<::nfd::face::InternalForwarderTransport*>(nfdFace->getTransport());
97 
98  auto clientTransport = make_shared<::nfd::face::InternalClientTransport>();
99  clientTransport->connectToForwarder(forwarderTransport);
100 
101  node->GetObject<ns3::ndn::L3Protocol>()->addFace(nfdFace);;
102 
103  return clientTransport;
104 }
105 
106 void
107 Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
108 {
109  if (transport == nullptr) {
110  transport = makeDefaultTransport();
111  }
112  BOOST_ASSERT(transport != nullptr);
113  m_transport = std::move(transport);
114 
115  m_nfdController = make_unique<nfd::Controller>(*this, keyChain);
116 
117  IO_CAPTURE_WEAK_IMPL(post) {
118  impl->ensureConnected(false);
120 }
121 
122 Face::~Face() = default;
123 
124 shared_ptr<Transport>
125 Face::getTransport()
126 {
127  return m_transport;
128 }
129 
130 PendingInterestHandle
132  const DataCallback& afterSatisfied,
133  const NackCallback& afterNacked,
134  const TimeoutCallback& afterTimeout)
135 {
136  auto interest2 = make_shared<Interest>(interest);
137  interest2->getNonce();
138 
139  IO_CAPTURE_WEAK_IMPL(post) {
140  impl->asyncExpressInterest(interest2, afterSatisfied, afterNacked, afterTimeout);
142 
143  return PendingInterestHandle(*this, reinterpret_cast<const PendingInterestId*>(interest2.get()));
144 }
145 
146 void
147 Face::removePendingInterest(const PendingInterestId* pendingInterestId)
148 {
149  IO_CAPTURE_WEAK_IMPL(post) {
150  impl->asyncRemovePendingInterest(pendingInterestId);
152 }
153 
154 void
156 {
157  IO_CAPTURE_WEAK_IMPL(post) {
158  impl->asyncRemoveAllPendingInterests();
160 }
161 
162 size_t
164 {
165  return m_impl->m_pendingInterestTable.size();
166 }
167 
168 void
170 {
171  IO_CAPTURE_WEAK_IMPL(post) {
172  impl->asyncPutData(data);
174 }
175 
176 void
178 {
179  IO_CAPTURE_WEAK_IMPL(post) {
180  impl->asyncPutNack(nack);
182 }
183 
186  const InterestCallback& onInterest,
187  const RegisterPrefixFailureCallback& onFailure,
188  const security::SigningInfo& signingInfo,
189  uint64_t flags)
190 {
191  return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
192 }
193 
196  const InterestCallback& onInterest,
197  const RegisterPrefixSuccessCallback& onSuccess,
198  const RegisterPrefixFailureCallback& onFailure,
199  const security::SigningInfo& signingInfo,
200  uint64_t flags)
201 {
202  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
203 
204  nfd::CommandOptions options;
205  options.setSigningInfo(signingInfo);
206 
207  auto id = m_impl->registerPrefix(interestFilter.getPrefix(), filter,
208  onSuccess, onFailure, flags, options);
209  return RegisteredPrefixHandle(*this, id);
210 }
211 
214  const InterestCallback& onInterest)
215 {
216  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
217 
218  IO_CAPTURE_WEAK_IMPL(post) {
219  impl->asyncSetInterestFilter(filter);
221 
222  auto id = reinterpret_cast<const InterestFilterId*>(filter.get());
223  return InterestFilterHandle(*this, id);
224 }
225 
228  const RegisterPrefixSuccessCallback& onSuccess,
229  const RegisterPrefixFailureCallback& onFailure,
230  const security::SigningInfo& signingInfo,
231  uint64_t flags)
232 {
233  nfd::CommandOptions options;
234  options.setSigningInfo(signingInfo);
235 
236  auto id = m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
237  return RegisteredPrefixHandle(*this, id);
238 }
239 
240 void
241 Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
242 {
243  IO_CAPTURE_WEAK_IMPL(post) {
244  impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr);
246 }
247 
248 void
249 Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
250 {
251  IO_CAPTURE_WEAK_IMPL(post) {
252  impl->asyncUnsetInterestFilter(interestFilterId);
254 }
255 
256 void
257 Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
258  const UnregisterPrefixSuccessCallback& onSuccess,
259  const UnregisterPrefixFailureCallback& onFailure)
260 {
261  IO_CAPTURE_WEAK_IMPL(post) {
262  impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure);
264 }
265 
266 void
267 Face::doProcessEvents(time::milliseconds timeout, bool keepThread)
268 {
269 }
270 
271 void
273 {
274  IO_CAPTURE_WEAK_IMPL(post) {
275  this->asyncShutdown();
277 }
278 
279 void
280 Face::asyncShutdown()
281 {
282  m_impl->m_pendingInterestTable.clear();
283  m_impl->m_registeredPrefixTable.clear();
284 
285  if (m_transport->isConnected())
286  m_transport->close();
287 }
288 
292 template<typename NetPkt>
293 static void
294 extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
295 {
296  addTagFromField<lp::IncomingFaceIdTag, lp::IncomingFaceIdField>(netPacket, lpPacket);
297  addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(netPacket, lpPacket);
298 
299  if (lpPacket.has<lp::HopCountTagField>()) {
300  netPacket.setTag(make_shared<lp::HopCountTag>(lpPacket.get<lp::HopCountTagField>() + 1));
301  }
302 }
303 
304 void
305 Face::onReceiveElement(const Block& blockFromDaemon)
306 {
307  lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
308  // no need to distinguish
309 
310  Buffer::const_iterator begin, end;
311  std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
312  Block netPacket(&*begin, std::distance(begin, end));
313  switch (netPacket.type()) {
314  case tlv::Interest: {
315  auto interest = make_shared<Interest>(netPacket);
316  if (lpPacket.has<lp::NackField>()) {
317  auto nack = make_shared<lp::Nack>(std::move(*interest));
318  nack->setHeader(lpPacket.get<lp::NackField>());
319  extractLpLocalFields(*nack, lpPacket);
320  NDN_LOG_DEBUG(">N " << nack->getInterest() << '~' << nack->getHeader().getReason());
321  m_impl->nackPendingInterests(*nack);
322  }
323  else {
324  extractLpLocalFields(*interest, lpPacket);
325  NDN_LOG_DEBUG(">I " << *interest);
326  m_impl->processIncomingInterest(std::move(interest));
327  }
328  break;
329  }
330  case tlv::Data: {
331  auto data = make_shared<Data>(netPacket);
332  extractLpLocalFields(*data, lpPacket);
333  NDN_LOG_DEBUG(">D " << data->getName());
334  m_impl->satisfyPendingInterests(*data);
335  break;
336  }
337  }
338 }
339 
340 PendingInterestHandle::PendingInterestHandle(Face& face, const PendingInterestId* id)
341  : CancelHandle([&face, id] { face.removePendingInterest(id); })
342  , m_id(id)
343 {
344 }
345 
346 RegisteredPrefixHandle::RegisteredPrefixHandle(Face& face, const RegisteredPrefixId* id)
347  : CancelHandle([&face, id] { face.unregisterPrefix(id, nullptr, nullptr); })
348  , m_face(&face)
349  , m_id(id)
350 {
351  // The lambda passed to CancelHandle constructor cannot call this->unregister,
352  // because base class destructor cannot access the member fields of this subclass.
353 }
354 
355 void
357  const UnregisterPrefixFailureCallback& onFailure)
358 {
359  if (m_id == nullptr) {
360  if (onFailure != nullptr) {
361  onFailure("RegisteredPrefixHandle is empty");
362  }
363  return;
364  }
365 
366  m_face->unregisterPrefix(m_id, onSuccess, onFailure);
367  m_face = nullptr;
368  m_id = nullptr;
369 }
370 
371 InterestFilterHandle::InterestFilterHandle(Face& face, const InterestFilterId* id)
372  : CancelHandle([&face, id] { face.unsetInterestFilter(id); })
373  , m_id(id)
374 {
375 }
376 
377 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
virtual void doProcessEvents(time::milliseconds timeout, bool keepThread)
Definition: face.cpp:267
The interface of signing key management.
Definition: key-chain.hpp:46
function< void(const std::string &)> UnregisterPrefixFailureCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command fails.
Definition: face.hpp:88
virtual ~Face()
void unregister(const UnregisterPrefixSuccessCallback &onSuccess=nullptr, const UnregisterPrefixFailureCallback &onFailure=nullptr)
Unregister the prefix.
Definition: face.cpp:356
implementation detail of Face
Definition: face-impl.hpp:60
bool allowLocalFields
enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
const Name & getPrefix() const
declares the set of Interests a producer can serve, which starts with a name prefix,...
#define IO_CAPTURE_WEAK_IMPL_END
Definition: face.cpp:47
#define NDN_LOG_DEBUG(expression)
Definition: logger.hpp:108
Represents an Interest packet.
Definition: interest.hpp:44
bool has() const
Definition: packet.hpp:74
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:294
Signing parameters passed to KeyChain.
void unregisterPrefix(const RegisteredPrefixId *registeredPrefixId, const UnregisterPrefixSuccessCallback &onSuccess, const UnregisterPrefixFailureCallback &onFailure)
Unregister prefix from RIB.
Definition: face.cpp:257
represents a Network Nack
Definition: nack.hpp:38
Declare a field.
Definition: field-decl.hpp:181
void removeAllPendingInterests()
Cancel all previously expressed Interests.
Definition: face.cpp:155
FIELD::ValueType get(size_t index=0) const
Definition: packet.hpp:97
RegisteredPrefixHandle 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:227
contains options for ControlCommand execution
#define IO_CAPTURE_WEAK_IMPL(OP)
Definition: face.cpp:41
A handle of pending Interest.
Definition: face.hpp:497
size_t getNPendingInterests() const
Get number of pending Interests.
Definition: face.cpp:163
void shutdown()
Shutdown face operations.
Definition: face.cpp:272
Provide a communication channel with local or remote NDN forwarder.
Definition: face.hpp:93
function< void(const Name &, const std::string &)> RegisterPrefixFailureCallback
Callback invoked when registerPrefix or setInterestFilter command fails.
Definition: face.hpp:78
function< void(const Name &)> RegisterPrefixSuccessCallback
Callback invoked when registerPrefix or setInterestFilter command succeeds.
Definition: face.hpp:73
Represents an absolute name.
Definition: name.hpp:43
represents the underlying protocol and address used by a Face
Definition: face-uri.hpp:44
void unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
Remove the registered prefix entry with the registeredPrefixId.
Definition: face.cpp:241
CommandOptions & setSigningInfo(const security::SigningInfo &signingInfo)
sets signing parameters
PendingInterestHandle expressInterest(const Interest &interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
Express Interest.
Definition: face.cpp:131
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:68
Options that control the behavior of GenericLinkService.
RegisteredPrefixHandle() noexcept
Definition: face.hpp:537
InterestFilterHandle() noexcept=default
function< void()> UnregisterPrefixSuccessCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds.
Definition: face.hpp:83
static KeyChain & getKeyChain()
void put(Data data)
Publish data packet.
Definition: face.cpp:169
OversizedPacketError(char pktType, const Name &name, size_t wireSize)
Constructor.
Definition: face.cpp:54
std::string to_string(const V &v)
Definition: backports.hpp:67
A handle of registered Interest filter.
Definition: face.hpp:599
PendingInterestHandle() noexcept=default
function< void(const Interest &)> TimeoutCallback
Callback invoked when expressed Interest times out.
Definition: face.hpp:63
function< void(const Interest &, const lp::Nack &)> NackCallback
Callback invoked when Nack is sent in response to expressed Interest.
Definition: face.hpp:58
Represents a Data packet.
Definition: data.hpp:35
RegisteredPrefixHandle 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:185
Face(shared_ptr< Transport > transport=nullptr)
Create Face using given transport (or default transport if omitted)
Definition: face.cpp:70
ndn security v2 KeyChain
Definition: key-chain.cpp:69
A handle of registered prefix.
Definition: face.hpp:534
function< void(const Interest &, const Data &)> DataCallback
Callback invoked when expressed Interest gets satisfied with a Data packet.
Definition: face.hpp:53
void removePendingInterest(const PendingInterestId *pendingInterestId)
Cancel previously expressed Interest.
Definition: face.cpp:147
const size_t MAX_NDN_PACKET_SIZE
practical limit of network layer packet size
Definition: tlv.hpp:41