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; -*- */
2 /*
3  * Copyright (c) 2013-2017 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 "face.hpp"
23 #include "detail/face-impl.hpp"
24 
25 #include "encoding/tlv.hpp"
26 #include "net/face-uri.hpp"
28 #include "util/random.hpp"
29 #include "util/time.hpp"
30 
31 #include "ns3/node-list.h"
32 #include "ns3/ndnSIM/helper/ndn-stack-helper.hpp"
33 #include "ns3/ndnSIM/NFD/daemon/face/generic-link-service.hpp"
34 #include "ns3/ndnSIM/NFD/daemon/face/internal-transport.hpp"
35 
36 // NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
37 
38 // A callback scheduled through io.post and io.dispatch may be invoked after the face
39 // is destructed. To prevent this situation, these macros captures Face::m_impl as weak_ptr,
40 // and skips callback execution if the face has been destructed.
41 
42 #define IO_CAPTURE_WEAK_IMPL(OP) \
43  { \
44  weak_ptr<Impl> implWeak(m_impl); \
45  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] { \
46  auto impl = implWeak.lock(); \
47  if (impl != nullptr) {
48 #define IO_CAPTURE_WEAK_IMPL_END \
49  } \
50  }); \
51  }
52 
53 namespace ndn {
54 
55 Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
56  : Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
57  name.toUri() + " encodes into " + to_string(wireSize) + " octets, "
58  "exceeding the implementation limit of " + to_string(MAX_NDN_PACKET_SIZE) + " octets")
59  , pktType(pktType)
60  , name(name)
61  , wireSize(wireSize)
62 {
63 }
64 
65 Face::Face(shared_ptr<Transport> transport)
66  : m_impl(new Impl(*this))
67 {
68  construct(transport, ns3::ndn::StackHelper::getKeyChain());
69 }
70 
71 Face::Face(boost::asio::io_service& ioService)
72  : m_impl(new Impl(*this))
73 {
74  construct(nullptr, ns3::ndn::StackHelper::getKeyChain());
75 }
76 
77 Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
78  : m_impl(new Impl(*this))
79 {
80  construct(std::move(transport), keyChain);
81 }
82 
83 Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
84  : m_impl(new Impl(*this))
85 {
86  construct(transport, ns3::ndn::StackHelper::getKeyChain());
87 }
88 
89 Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
90  : m_impl(new Impl(*this))
91 {
92  construct(std::move(transport), keyChain);
93 }
94 
95 shared_ptr<Transport>
96 Face::makeDefaultTransport()
97 {
98  ns3::Ptr<ns3::Node> node = ns3::NodeList::GetNode(ns3::Simulator::GetContext());
99  NS_ASSERT_MSG(node->GetObject<ns3::ndn::L3Protocol>() != 0,
100  "NDN stack should be installed on the node " << node);
101 
102  auto uri = ::nfd::FaceUri("ndnFace://" + boost::lexical_cast<std::string>(node->GetId()));
103 
105  serviceOpts.allowLocalFields = true;
106 
107  auto nfdFace = make_shared<::nfd::Face>(make_unique<::nfd::face::GenericLinkService>(serviceOpts),
108  make_unique<::nfd::face::InternalForwarderTransport>(uri, uri));
109  auto forwarderTransport = static_cast<::nfd::face::InternalForwarderTransport*>(nfdFace->getTransport());
110 
111  auto clientTransport = make_shared<::nfd::face::InternalClientTransport>();
112  clientTransport->connectToForwarder(forwarderTransport);
113 
114  node->GetObject<ns3::ndn::L3Protocol>()->addFace(nfdFace);;
115 
116  return clientTransport;
117 }
118 
119 void
120 Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
121 {
122  if (transport == nullptr) {
123  transport = makeDefaultTransport();
124  }
125  BOOST_ASSERT(transport != nullptr);
126  m_transport = std::move(transport);
127 
128  m_nfdController = make_unique<nfd::Controller>(*this, keyChain);
129 
130  IO_CAPTURE_WEAK_IMPL(post) {
131  impl->ensureConnected(false);
133 }
134 
135 Face::~Face() = default;
136 
137 shared_ptr<Transport>
138 Face::getTransport()
139 {
140  return m_transport;
141 }
142 
143 const PendingInterestId*
145  const DataCallback& afterSatisfied,
146  const NackCallback& afterNacked,
147  const TimeoutCallback& afterTimeout)
148 {
149  shared_ptr<Interest> interest2 = make_shared<Interest>(interest);
150  interest2->getNonce();
151  NDN_LOG_DEBUG("<I " << *interest2);
152 
153  IO_CAPTURE_WEAK_IMPL(dispatch) {
154  impl->asyncExpressInterest(interest2, afterSatisfied, afterNacked, afterTimeout);
156 
157  return reinterpret_cast<const PendingInterestId*>(interest2.get());
158 }
159 
160 void
161 Face::removePendingInterest(const PendingInterestId* pendingInterestId)
162 {
163  IO_CAPTURE_WEAK_IMPL(post) {
164  impl->asyncRemovePendingInterest(pendingInterestId);
166 }
167 
168 void
170 {
171  IO_CAPTURE_WEAK_IMPL(post) {
172  impl->asyncRemoveAllPendingInterests();
174 }
175 
176 size_t
178 {
179  return m_impl->m_pendingInterestTable.size();
180 }
181 
182 void
184 {
185  NDN_LOG_DEBUG("<D " << data.getName());
186  IO_CAPTURE_WEAK_IMPL(dispatch) {
187  impl->asyncPutData(data);
189 }
190 
191 void
193 {
194  NDN_LOG_DEBUG("<N " << nack.getInterest() << '~' << nack.getHeader().getReason());
195  IO_CAPTURE_WEAK_IMPL(dispatch) {
196  impl->asyncPutNack(nack);
198 }
199 
200 const RegisteredPrefixId*
202  const InterestCallback& onInterest,
203  const RegisterPrefixFailureCallback& onFailure,
204  const security::SigningInfo& signingInfo,
205  uint64_t flags)
206 {
207  return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
208 }
209 
210 const RegisteredPrefixId*
212  const InterestCallback& onInterest,
213  const RegisterPrefixSuccessCallback& onSuccess,
214  const RegisterPrefixFailureCallback& onFailure,
215  const security::SigningInfo& signingInfo,
216  uint64_t flags)
217 {
218  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
219 
220  nfd::CommandOptions options;
221  options.setSigningInfo(signingInfo);
222 
223  return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
224  onSuccess, onFailure, flags, options);
225 }
226 
227 const InterestFilterId*
229  const InterestCallback& onInterest)
230 {
231  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
232 
233  IO_CAPTURE_WEAK_IMPL(post) {
234  impl->asyncSetInterestFilter(filter);
236 
237  return reinterpret_cast<const InterestFilterId*>(filter.get());
238 }
239 
240 const RegisteredPrefixId*
242  const RegisterPrefixSuccessCallback& onSuccess,
243  const RegisterPrefixFailureCallback& onFailure,
244  const security::SigningInfo& signingInfo,
245  uint64_t flags)
246 {
247  nfd::CommandOptions options;
248  options.setSigningInfo(signingInfo);
249 
250  return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
251 }
252 
253 void
254 Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
255 {
256  IO_CAPTURE_WEAK_IMPL(post) {
257  impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr);
259 }
260 
261 void
262 Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
263 {
264  IO_CAPTURE_WEAK_IMPL(post) {
265  impl->asyncUnsetInterestFilter(interestFilterId);
267 }
268 
269 void
270 Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
271  const UnregisterPrefixSuccessCallback& onSuccess,
272  const UnregisterPrefixFailureCallback& onFailure)
273 {
274  IO_CAPTURE_WEAK_IMPL(post) {
275  impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure);
277 }
278 
279 void
281 {
282 }
283 
284 void
286 {
287  IO_CAPTURE_WEAK_IMPL(post) {
288  this->asyncShutdown();
290 }
291 
292 void
293 Face::asyncShutdown()
294 {
295  m_impl->m_pendingInterestTable.clear();
296  m_impl->m_registeredPrefixTable.clear();
297 
298  if (m_transport->isConnected())
299  m_transport->close();
300 }
301 
305 template<typename NetPkt>
306 static void
307 extractLpLocalFields(NetPkt& netPacket, const lp::Packet& lpPacket)
308 {
309  addTagFromField<lp::IncomingFaceIdTag, lp::IncomingFaceIdField>(netPacket, lpPacket);
310  addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(netPacket, lpPacket);
311 
312  if (lpPacket.has<lp::HopCountTagField>()) {
313  netPacket.setTag(make_shared<lp::HopCountTag>(lpPacket.get<lp::HopCountTagField>() + 1));
314  }
315 }
316 
317 void
318 Face::onReceiveElement(const Block& blockFromDaemon)
319 {
320  lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
321  // no need to distinguish
322 
323  Buffer::const_iterator begin, end;
324  std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
325  Block netPacket(&*begin, std::distance(begin, end));
326  switch (netPacket.type()) {
327  case tlv::Interest: {
328  auto interest = make_shared<Interest>(netPacket);
329  if (lpPacket.has<lp::NackField>()) {
330  auto nack = make_shared<lp::Nack>(std::move(*interest));
331  nack->setHeader(lpPacket.get<lp::NackField>());
332  extractLpLocalFields(*nack, lpPacket);
333  NDN_LOG_DEBUG(">N " << nack->getInterest() << '~' << nack->getHeader().getReason());
334  m_impl->nackPendingInterests(*nack);
335  }
336  else {
337  extractLpLocalFields(*interest, lpPacket);
338  NDN_LOG_DEBUG(">I " << *interest);
339  m_impl->processIncomingInterest(std::move(interest));
340  }
341  break;
342  }
343  case tlv::Data: {
344  auto data = make_shared<Data>(netPacket);
345  extractLpLocalFields(*data, lpPacket);
346  NDN_LOG_DEBUG(">D " << data->getName());
347  m_impl->satisfyPendingInterests(*data);
348  break;
349  }
350  }
351 }
352 
353 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
virtual void doProcessEvents(time::milliseconds timeout, bool keepThread)
Definition: face.cpp:280
const NackHeader & getHeader() const
Definition: nack.hpp:65
function< void(const std::string &)> UnregisterPrefixFailureCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command fails.
Definition: face.hpp:90
virtual ~Face()
#define IO_CAPTURE_WEAK_IMPL_END
Definition: face.cpp:48
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:201
declares the set of Interests a producer can serve, which starts with a name prefix, plus an optional regular expression
boost::posix_time::time_duration milliseconds(long duration)
Definition: asio.hpp:117
const Interest & getInterest() const
Definition: nack.hpp:53
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
represents an Interest packet
Definition: interest.hpp:42
bool has() const
Definition: packet.hpp:78
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:307
Signing parameters passed to KeyChain.
void unregisterPrefix(const RegisteredPrefixId *registeredPrefixId, const UnregisterPrefixSuccessCallback &onSuccess, const UnregisterPrefixFailureCallback &onFailure)
Unregister prefix from RIB.
Definition: face.cpp:270
represents a Network Nack
Definition: nack.hpp:40
void removeAllPendingInterests()
Cancel all previously expressed Interests.
Definition: face.cpp:169
#define NDN_LOG_DEBUG(expression)
Definition: logger.hpp:35
implements a forwarder-side transport that can be paired with another
FIELD::ValueType get(size_t index=0) const
Definition: packet.hpp:101
contains options for ControlCommand execution
void shutdown()
Shutdown face operations.
Definition: face.cpp:285
function< void(const Name &, const std::string &)> RegisterPrefixFailureCallback
Callback invoked when registerPrefix or setInterestFilter command fails.
Definition: face.hpp:80
function< void(const Name &)> RegisterPrefixSuccessCallback
Callback invoked when registerPrefix or setInterestFilter command succeeds.
Definition: face.hpp:75
Represents an absolute name.
Definition: name.hpp:42
represents the underlying protocol and address used by a Face
Definition: face-uri.hpp:43
void unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
Remove the registered prefix entry with the registeredPrefixId.
Definition: face.cpp:254
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:70
Options that control the behavior of GenericLinkService.
const Name & getName() const
Get name.
Definition: data.hpp:121
NackReason getReason() const
#define IO_CAPTURE_WEAK_IMPL(OP)
Definition: face.cpp:42
size_t getNPendingInterests() const
Get number of pending Interests.
Definition: face.cpp:177
function< void()> UnregisterPrefixSuccessCallback
Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds.
Definition: face.hpp:85
static KeyChain & getKeyChain()
void put(Data data)
Publish data packet.
Definition: face.cpp:183
OversizedPacketError(char pktType, const Name &name, size_t wireSize)
Constructor.
Definition: face.cpp:55
std::string to_string(const V &v)
Definition: backports.hpp:84
const PendingInterestId * expressInterest(const Interest &interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
Express Interest.
Definition: face.cpp:144
function< void(const Interest &)> TimeoutCallback
Callback invoked when expressed Interest times out.
Definition: face.hpp:65
function< void(const Interest &, const lp::Nack &)> NackCallback
Callback invoked when Nack is sent in response to expressed Interest.
Definition: face.hpp:60
Represents a Data packet.
Definition: data.hpp:35
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:241
Face(shared_ptr< Transport > transport=nullptr)
Create Face using given transport (or default transport if omitted)
Definition: face.cpp:65
ndn security v2 KeyChain
Definition: key-chain.cpp:76
function< void(const Interest &, const Data &)> DataCallback
Callback invoked when expressed Interest gets satisfied with a Data packet.
Definition: face.hpp:55
void removePendingInterest(const PendingInterestId *pendingInterestId)
Cancel previously expressed Interest.
Definition: face.cpp:161
const size_t MAX_NDN_PACKET_SIZE
practical limit of network layer packet size
Definition: tlv.hpp:39