NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
ndn-l3-protocol.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-l3-protocol.hpp"
21 
22 #include "ns3/packet.h"
23 #include "ns3/node.h"
24 #include "ns3/log.h"
25 #include "ns3/callback.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/trace-source-accessor.h"
28 #include "ns3/object-vector.h"
29 #include "ns3/pointer.h"
30 #include "ns3/simulator.h"
31 
33 
34 #include "../helper/ndn-stack-helper.hpp"
35 #include "cs/ndn-content-store.hpp"
36 
37 #include <boost/property_tree/info_parser.hpp>
38 
39 #include "ns3/ndnSIM/NFD/daemon/fw/forwarder.hpp"
40 #include "ns3/ndnSIM/NFD/daemon/face/internal-face.hpp"
41 #include "ns3/ndnSIM/NFD/daemon/face/internal-transport.hpp"
42 #include "ns3/ndnSIM/NFD/daemon/mgmt/fib-manager.hpp"
43 #include "ns3/ndnSIM/NFD/daemon/mgmt/face-manager.hpp"
44 #include "ns3/ndnSIM/NFD/daemon/mgmt/strategy-choice-manager.hpp"
45 #include "ns3/ndnSIM/NFD/daemon/mgmt/forwarder-status-manager.hpp"
46 // #include "ns3/ndnSIM/NFD/daemon/mgmt/general-config-section.hpp"
47 #include "ns3/ndnSIM/NFD/daemon/mgmt/tables-config-section.hpp"
48 #include "ns3/ndnSIM/NFD/daemon/mgmt/command-authenticator.hpp"
49 
50 #include "ns3/ndnSIM/NFD/rib/rib-manager.hpp"
51 
52 #include "ns3/ndnSIM/NFD/daemon/face/null-face.hpp"
53 #include "ns3/ndnSIM/NFD/daemon/face/internal-face.hpp"
54 
55 #include "ns3/ndnSIM/NFD/core/config-file.hpp"
56 
57 #include <ndn-cxx/mgmt/dispatcher.hpp>
58 
59 NS_LOG_COMPONENT_DEFINE("ndn.L3Protocol");
60 
61 namespace ns3 {
62 namespace ndn {
63 
64 const uint16_t L3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
65 const uint16_t L3Protocol::IP_STACK_PORT = 9695;
66 
68 
69 TypeId
71 {
72  static TypeId tid =
73  TypeId("ns3::ndn::L3Protocol")
74  .SetGroupName("ndn")
75  .SetParent<Object>()
76  .AddConstructor<L3Protocol>()
77 
78  .AddTraceSource("OutInterests", "OutInterests",
79  MakeTraceSourceAccessor(&L3Protocol::m_outInterests),
80  "ns3::ndn::L3Protocol::InterestTraceCallback")
81  .AddTraceSource("InInterests", "InInterests",
82  MakeTraceSourceAccessor(&L3Protocol::m_inInterests),
83  "ns3::ndn::L3Protocol::InterestTraceCallback")
84 
86 
87  .AddTraceSource("OutData", "OutData", MakeTraceSourceAccessor(&L3Protocol::m_outData),
88  "ns3::ndn::L3Protocol::DataTraceCallback")
89  .AddTraceSource("InData", "InData", MakeTraceSourceAccessor(&L3Protocol::m_inData),
90  "ns3::ndn::L3Protocol::DataTraceCallback")
91 
93 
94  .AddTraceSource("OutNack", "OutNack", MakeTraceSourceAccessor(&L3Protocol::m_outNack),
95  "ns3::ndn::L3Protocol::NackTraceCallback")
96  .AddTraceSource("InNack", "InNack", MakeTraceSourceAccessor(&L3Protocol::m_inNack),
97  "ns3::ndn::L3Protocol::NackTraceCallback")
98 
100 
101  .AddTraceSource("SatisfiedInterests", "SatisfiedInterests",
102  MakeTraceSourceAccessor(&L3Protocol::m_satisfiedInterests),
103  "ns3::ndn::L3Protocol::SatisfiedInterestsCallback")
104  .AddTraceSource("TimedOutInterests", "TimedOutInterests",
105  MakeTraceSourceAccessor(&L3Protocol::m_timedOutInterests),
106  "ns3::ndn::L3Protocol::TimedOutInterestsCallback")
107  ;
108  return tid;
109 }
110 
112 private:
113  Impl()
114  {
115  // Do not modify initial config file. Use helpers to set specific NFD parameters
116  std::string initialConfig =
117  "general\n"
118  "{\n"
119  "}\n"
120  "\n"
121  "tables\n"
122  "{\n"
123  " cs_max_packets 100\n"
124  "\n"
125  " strategy_choice\n"
126  " {\n"
127  " / /localhost/nfd/strategy/best-route\n"
128  " /localhost /localhost/nfd/strategy/multicast\n"
129  " /localhost/nfd /localhost/nfd/strategy/best-route\n"
130  " /ndn/multicast /localhost/nfd/strategy/multicast\n"
131  " }\n"
132  "}\n"
133  "\n"
134  // "face_system\n"
135  // "{\n"
136  // "}\n"
137  "\n"
138  "authorizations\n"
139  "{\n"
140  " authorize\n"
141  " {\n"
142  " certfile any\n"
143  " privileges\n"
144  " {\n"
145  " faces\n"
146  " fib\n"
147  " strategy-choice\n"
148  " }\n"
149  " }\n"
150  "}\n"
151  "\n"
152  "rib\n"
153  "{\n"
154  " localhost_security\n"
155  " {\n"
156  " trust-anchor\n"
157  " {\n"
158  " type any\n"
159  " }\n"
160  " }\n"
161  "}\n"
162  "\n";
163 
164  std::istringstream input(initialConfig);
165  boost::property_tree::read_info(input, m_config);
166  }
167 
168  friend class L3Protocol;
169 
170  std::shared_ptr<nfd::Forwarder> m_forwarder;
171 
172  std::shared_ptr<nfd::Face> m_internalFace;
173  std::shared_ptr<::ndn::Face> m_internalClientFace;
174  std::shared_ptr<nfd::CommandAuthenticator> m_authenticator;
175 
176  std::shared_ptr<nfd::Face> m_internalRibFace;
177  std::shared_ptr<::ndn::Face> m_internalRibClientFace;
178 
179  std::unique_ptr<::ndn::mgmt::Dispatcher> m_dispatcher;
180  std::unique_ptr<::ndn::mgmt::Dispatcher> m_dispatcherRib;
181  std::shared_ptr<nfd::FibManager> m_fibManager;
182  std::shared_ptr<nfd::FaceManager> m_faceManager;
183  std::shared_ptr<nfd::StrategyChoiceManager> m_strategyChoiceManager;
184  std::shared_ptr<nfd::ForwarderStatusManager> m_forwarderStatusManager;
185  std::shared_ptr<nfd::rib::RibManager> m_ribManager;
186 
187  std::shared_ptr<nfd::face::FaceSystem> m_faceSystem;
188 
189  nfd::ConfigSection m_config;
190 
191  Ptr<ContentStore> m_csFromNdnSim;
192  PolicyCreationCallback m_policy;
193 };
194 
196  : m_impl(new Impl())
197 {
198  NS_LOG_FUNCTION(this);
199 }
200 
202 {
203  NS_LOG_FUNCTION(this);
204 }
205 
206 void
207 L3Protocol::initialize()
208 {
209  m_impl->m_forwarder = make_shared<nfd::Forwarder>();
210 
211  initializeManagement();
212 
213  nfd::FaceTable& faceTable = m_impl->m_forwarder->getFaceTable();
215 
216  if (!this->getConfig().get<bool>("ndnSIM.disable_rib_manager", false)) {
217  Simulator::ScheduleWithContext(m_node->GetId(), Seconds(0), &L3Protocol::initializeRibManager, this);
218  }
219 
220  m_impl->m_forwarder->beforeSatisfyInterest.connect(std::ref(m_satisfiedInterests));
221  m_impl->m_forwarder->beforeExpirePendingInterest.connect(std::ref(m_timedOutInterests));
222 }
223 
225 {
226 public:
227  IgnoreSections(const std::vector<std::string>& ignored)
228  : m_ignored(ignored)
229  {
230  }
231 
232  void
233  operator()(const std::string& filename, const std::string& sectionName,
234  const nfd::ConfigSection& section, bool isDryRun)
235 
236  {
237  if (std::find(m_ignored.begin(), m_ignored.end(), sectionName) == m_ignored.end()) {
238  nfd::ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
239  }
240  }
241 private:
242  std::vector<std::string> m_ignored;
243 };
244 
245 void
247 {
248  m_impl->m_internalFace->sendInterest(interest);
249 }
250 
251 void
253 {
254  m_impl->m_policy = policy;
255 }
256 
257 void
258 L3Protocol::initializeManagement()
259 {
260  auto& forwarder = m_impl->m_forwarder;
261  using namespace nfd;
262 
263  m_impl->m_faceSystem = make_shared<nfd::face::FaceSystem>(forwarder->getFaceTable(), nullptr);
264 
265  std::tie(m_impl->m_internalFace, m_impl->m_internalClientFace) = face::makeInternalFace(StackHelper::getKeyChain());
266  forwarder->getFaceTable().addReserved(m_impl->m_internalFace, face::FACEID_INTERNAL_FACE);
267  m_impl->m_dispatcher.reset(new ::ndn::mgmt::Dispatcher(*m_impl->m_internalClientFace, StackHelper::getKeyChain()));
268 
269  m_impl->m_authenticator = CommandAuthenticator::create();
270 
271  m_impl->m_fibManager.reset(new FibManager(forwarder->getFib(),
272  forwarder->getFaceTable(),
273  *m_impl->m_dispatcher,
274  *m_impl->m_authenticator));
275 
276  // Cannot be disabled for now
277  // if (!this->getConfig().get<bool>("ndnSIM.disable_face_manager", false))
278 
279  m_impl->m_faceManager.reset(new FaceManager(*m_impl->m_faceSystem,
280  *m_impl->m_dispatcher,
281  *m_impl->m_authenticator));
282  // }
283  // else {
284  // this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("faces");
285  // }
286 
287  if (!this->getConfig().get<bool>("ndnSIM.disable_strategy_choice_manager", false)) {
288  m_impl->m_strategyChoiceManager.reset(new StrategyChoiceManager(forwarder->getStrategyChoice(),
289  *m_impl->m_dispatcher,
290  *m_impl->m_authenticator));
291  }
292  else {
293  this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("strategy-choice");
294  }
295 
296  if (!this->getConfig().get<bool>("ndnSIM.disable_forwarder_status_manager", false)) {
297  m_impl->m_forwarderStatusManager.reset(new ForwarderStatusManager(*forwarder, *m_impl->m_dispatcher));
298  }
299 
300  ConfigFile config(&ConfigFile::ignoreUnknownSection);
301 
302  // if we use NFD's CS, we have to specify a replacement policy
303  m_impl->m_csFromNdnSim = GetObject<ContentStore>();
304  if (m_impl->m_csFromNdnSim == nullptr) {
305  forwarder->getCs().setPolicy(m_impl->m_policy());
306  }
307 
308  TablesConfigSection tablesConfig(*forwarder);
309  tablesConfig.setConfigFile(config);
310 
311  m_impl->m_authenticator->setConfigFile(config);
312 
313  // if (!this->getConfig().get<bool>("ndnSIM.disable_face_manager", false)) {
314  m_impl->m_faceManager->setConfigFile(config);
315  // }
316 
317  // apply config
318  config.parse(m_impl->m_config, false, "ndnSIM.conf");
319 
320  tablesConfig.ensureConfigured();
321 
322  // add FIB entry for NFD Management Protocol
323  Name topPrefix("/localhost/nfd");
324  auto entry = forwarder->getFib().insert(topPrefix).first;
325  entry->addNextHop(*(m_impl->m_internalFace), 0);
326  m_impl->m_dispatcher->addTopPrefix(topPrefix, false);
327 }
328 
329 void
330 L3Protocol::initializeRibManager()
331 {
332  using namespace nfd;
333 
334  std::tie(m_impl->m_internalRibFace, m_impl->m_internalRibClientFace) = face::makeInternalFace(StackHelper::getKeyChain());
335  m_impl->m_forwarder->getFaceTable().add(m_impl->m_internalRibFace);
336 
337  m_impl->m_dispatcherRib.reset(new ::ndn::mgmt::Dispatcher(*m_impl->m_internalRibClientFace, StackHelper::getKeyChain()));
338 
339  m_impl->m_ribManager = make_shared<rib::RibManager>(*(m_impl->m_dispatcherRib), *(m_impl->m_internalRibClientFace),
341 
342  ConfigFile config([] (const std::string& filename, const std::string& sectionName,
343  const ConfigSection& section, bool isDryRun) {
344  // Ignore "log" and sections belonging to NFD,
345  // but raise an error if we're missing a handler for a "rib" section.
346  if (sectionName != "rib" || sectionName == "log") {
347  // do nothing
348  }
349  else {
350  // missing RIB section
351  ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
352  }
353  });
354 
355  m_impl->m_ribManager->setConfigFile(config);
356 
357  // apply config
358  config.parse(m_impl->m_config, false, "ndnSIM.conf");
359 
360  m_impl->m_ribManager->registerWithNfd();
361 }
362 
363 shared_ptr<nfd::Forwarder>
365 {
366  return m_impl->m_forwarder;
367 }
368 
369 shared_ptr<nfd::FibManager>
371 {
372  return m_impl->m_fibManager;
373 }
374 
375 shared_ptr<nfd::StrategyChoiceManager>
377 {
378  return m_impl->m_strategyChoiceManager;
379 }
380 
383 {
384  return m_impl->m_config;
385 }
386 
387 /*
388  * This method is called by AddAgregate and completes the aggregation
389  * by setting the node in the ndn stack
390  */
391 void
393 {
394  if (m_node == nullptr) {
395  m_node = GetObject<Node>();
396  if (m_node != nullptr) {
397  initialize();
398 
399  NS_ASSERT(m_impl->m_forwarder != nullptr);
400  m_impl->m_csFromNdnSim = GetObject<ContentStore>();
401  if (m_impl->m_csFromNdnSim != nullptr) {
402  m_impl->m_forwarder->setCsFromNdnSim(m_impl->m_csFromNdnSim);
403  }
404  }
405  }
406 
407  Object::NotifyNewAggregate();
408 }
409 
410 void
412 {
413  NS_LOG_FUNCTION(this);
414 
415  // MUST HAPPEN BEFORE Simulator IS DESTROYED
416  m_impl.reset();
417 
418  nfd::scheduler::getGlobalScheduler().cancelAllEvents();
419 
420  m_node = 0;
421 
422  Object::DoDispose();
423 }
424 
426 L3Protocol::addFace(shared_ptr<Face> face)
427 {
428  NS_LOG_FUNCTION(this << face.get());
429 
430  m_impl->m_forwarder->addFace(face);
431 
432  std::weak_ptr<Face> weakFace = face;
433 
434  // // Connect Signals to TraceSource
435  face->afterReceiveInterest.connect([this, weakFace](const Interest& interest) {
436  shared_ptr<Face> face = weakFace.lock();
437  if (face != nullptr) {
438  this->m_inInterests(interest, *face);
439  }
440  });
441 
442  face->afterReceiveData.connect([this, weakFace](const Data& data) {
443  shared_ptr<Face> face = weakFace.lock();
444  if (face != nullptr) {
445  this->m_inData(data, *face);
446  }
447  });
448 
449  face->afterReceiveNack.connect([this, weakFace](const lp::Nack& nack) {
450  shared_ptr<Face> face = weakFace.lock();
451  if (face != nullptr) {
452  this->m_inNack(nack, *face);
453  }
454  });
455 
456  auto tracingLink = face->getLinkService();
457  NS_LOG_LOGIC("Adding trace sources for afterSendInterest and afterSendData");
458  tracingLink->afterSendInterest.connect([this, weakFace](const Interest& interest) {
459  shared_ptr<Face> face = weakFace.lock();
460  if (face != nullptr) {
461  this->m_outInterests(interest, *face);
462  }
463  });
464 
465  tracingLink->afterSendData.connect([this, weakFace](const Data& data) {
466  shared_ptr<Face> face = weakFace.lock();
467  if (face != nullptr) {
468  this->m_outData(data, *face);
469  }
470  });
471 
472  tracingLink->afterSendNack.connect([this, weakFace](const lp::Nack& nack) {
473  shared_ptr<Face> face = weakFace.lock();
474  if (face != nullptr) {
475  this->m_outNack(nack, *face);
476  }
477  });
478 
479  return face->getId();
480 }
481 
482 shared_ptr<Face>
484 {
485  return m_impl->m_forwarder->getFaceTable().get(id)->shared_from_this();
486 }
487 
488 shared_ptr<Face>
489 L3Protocol::getFaceByNetDevice(Ptr<NetDevice> netDevice) const
490 {
491  for (auto& i : m_impl->m_forwarder->getFaceTable()) {
492  auto transport = dynamic_cast<NetDeviceTransport*>(i.getTransport());
493  if (transport == nullptr)
494  continue;
495 
496  if (transport->GetNetDevice() == netDevice)
497  return i.shared_from_this();
498  }
499  return nullptr;
500 }
501 
502 Ptr<L3Protocol>
503 L3Protocol::getL3Protocol(Ptr<Object> node)
504 {
505  Ptr<L3Protocol> retval = node->GetObject<L3Protocol>();
506  NS_ASSERT_MSG(retval != nullptr, "L3Protocol is not aggregated on this object");
507  return retval;
508 }
509 
510 } // namespace ndn
511 } // namespace ns3
shared_ptr< Face > getFaceByNetDevice(Ptr< NetDevice > netDevice) const
Remove face from ndn stack (remove callbacks)
static const uint16_t IP_STACK_PORT
TCP/UDP port for NDN stack.
Copyright (c) 2011-2015 Regents of the University of California.
shared_ptr< Face > makeNullFace(const FaceUri &uri)
Definition: null-face.cpp:37
std::tuple< shared_ptr< Face >, shared_ptr< ndn::Face > > makeInternalFace(ndn::KeyChain &clientKeyChain)
make a pair of forwarder-side face and client-side face that are connected with each other ...
shared_ptr< nfd::Forwarder > getForwarder()
Get smart pointer to nfd::Forwarder installed on the node.
static const uint16_t ETHERNET_FRAME_TYPE
Ethernet Frame Type of Ndn.
NS_OBJECT_ENSURE_REGISTERED(ContentStore)
nfd::ConfigSection & getConfig()
Get NFD config (boost::property_tree)
configuration file parsing utility
Definition: config-file.hpp:58
const FaceId FACEID_INTERNAL_FACE
identifies the InternalFace used in management
Definition: face.hpp:44
shared_ptr< Face > getFaceById(nfd::FaceId face) const
Get face by face ID.
void ensureConfigured()
apply default configuration, if tables section was omitted in configuration file
void operator()(const std::string &filename, const std::string &sectionName, const nfd::ConfigSection &section, bool isDryRun)
std::function< std::unique_ptr< nfd::cs::Policy >)> PolicyCreationCallback
implement the Forwarder Status of NFD Management Protocol.
shared_ptr< nfd::FibManager > getFibManager()
Get smart pointer to nfd::FibManager, used by node&#39;s NFD.
virtual void NotifyNewAggregate()
This function will notify other components connected to the node that a new stack member is now conne...
FibManager
Definition: fib-manager.cpp:36
ndn mgmt Dispatcher
Copyright (c) 2013-2017 Regents of the University of California.
Definition: dispatcher.cpp:26
represents a Network Nack
Definition: nack.hpp:40
static TypeId GetTypeId()
Interface ID.
container of all faces
Definition: face-table.hpp:37
void setCsReplacementPolicy(const PolicyCreationCallback &policy)
Set the replacement policy of NFD&#39;s CS.
static void throwErrorOnUnknownSection(const std::string &filename, const std::string &sectionName, const ConfigSection &section, bool isDryRun)
Definition: config-file.cpp:40
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
nfd::FaceId addFace(shared_ptr< Face > face)
Add face to NDN stack.
Copyright (c) 2011-2015 Regents of the University of California.
boost::property_tree::ptree ConfigSection
a config file section
L3Protocol()
Default constructor.
ndn L3Protocol
Copyright (c) 2011-2015 Regents of the University of California.
shared_ptr< nfd::StrategyChoiceManager > getStrategyChoiceManager()
Get smart pointer to nfd::StrategyChoiceManager, used by node&#39;s NFD.
Implementation network-layer of NDN stack.
static Ptr< L3Protocol > getL3Protocol(Ptr< Object > node)
handles &#39;tables&#39; config section
virtual void DoDispose(void)
Do cleanup.
void injectInterest(const Interest &interest)
Inject interest through internal Face.
void addReserved(shared_ptr< Face > face, FaceId faceId)
add a special face with a reserved FaceId
Definition: face-table.cpp:70
IgnoreSections(const std::vector< std::string > &ignored)
static KeyChain & getKeyChain()
const FaceId FACEID_NULL
identifies the NullFace that drops every packet
Definition: face.hpp:48
uint64_t FaceId
identifies a face
Definition: face.hpp:39
void parse(const std::string &filename, bool isDryRun)
Definition: config-file.cpp:83
void setConfigFile(ConfigFile &configFile)
Scheduler & getGlobalScheduler()
Definition: scheduler.cpp:37