nlsr.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "nlsr.hpp"
23 #include "adjacent.hpp"
24 #include "logger.hpp"
25 
26 #include <cstdlib>
27 #include <string>
28 #include <sstream>
29 #include <cstdio>
30 #include <unistd.h>
31 #include <vector>
32 
33 #include <ndn-cxx/net/face-uri.hpp>
34 #include <ndn-cxx/signature.hpp>
35 
36 namespace nlsr {
37 
38 INIT_LOGGER(Nlsr);
39 
40 const ndn::Name Nlsr::LOCALHOST_PREFIX = ndn::Name("/localhost/nlsr");
41 
42 Nlsr::Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::Face& face, ndn::KeyChain& keyChain)
43  : m_nlsrFace(face)
44  , m_scheduler(scheduler)
45  , m_keyChain(keyChain)
46  , m_confParam()
47  , m_adjacencyList()
48  , m_namePrefixList()
49  , m_configFileName("nlsr.conf")
50  , m_nlsrLsdb(*this, scheduler)
51  , m_adjBuildCount(0)
52  , m_isBuildAdjLsaSheduled(false)
53  , m_isRouteCalculationScheduled(false)
54  , m_isRoutingTableCalculating(false)
55  , m_routingTable(scheduler)
56  , m_fib(m_nlsrFace, scheduler, m_adjacencyList, m_confParam, m_keyChain)
57  , m_namePrefixTable(*this, m_routingTable.afterRoutingChange)
58  , m_dispatcher(m_nlsrFace, m_keyChain)
59  , m_datasetHandler(m_nlsrLsdb,
60  m_routingTable,
61  m_dispatcher,
62  m_nlsrFace,
63  m_keyChain)
64  , m_helloProtocol(*this, scheduler)
65  , m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(m_nlsrFace))
66  , m_controller(m_nlsrFace, m_keyChain)
67  , m_faceDatasetController(m_nlsrFace, m_keyChain)
68  , m_prefixUpdateProcessor(m_dispatcher,
69  m_nlsrFace,
70  m_namePrefixList,
71  m_nlsrLsdb)
72  , m_nfdRibCommandProcessor(m_dispatcher,
73  m_namePrefixList,
74  m_nlsrLsdb)
75  , m_statsCollector(m_nlsrLsdb, m_helloProtocol)
76  , m_faceMonitor(m_nlsrFace)
77  , m_firstHelloInterval(FIRST_HELLO_INTERVAL_DEFAULT)
78 {
79  m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
80  m_faceMonitor.start();
81 }
82 
83 void
84 Nlsr::registrationFailed(const ndn::Name& name)
85 {
86  NLSR_LOG_ERROR("ERROR: Failed to register prefix in local hub's daemon");
87  BOOST_THROW_EXCEPTION(Error("Error: Prefix registration failed"));
88 }
89 
90 void
91 Nlsr::onRegistrationSuccess(const ndn::Name& name)
92 {
93  NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
94 }
95 
96 void
98 {
99  ndn::Name name(m_confParam.getRouterPrefix());
100  name.append("nlsr");
101  name.append("INFO");
102 
103  NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
104 
105  m_nlsrFace.setInterestFilter(name,
107  &m_helloProtocol, _1, _2),
108  std::bind(&Nlsr::onRegistrationSuccess, this, _1),
109  std::bind(&Nlsr::registrationFailed, this, _1),
110  m_signingInfo,
111  ndn::nfd::ROUTE_FLAG_CAPTURE);
112 }
113 
114 void
116 {
117  ndn::Name name = m_confParam.getLsaPrefix();
118 
119  NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
120 
121  m_nlsrFace.setInterestFilter(name,
122  std::bind(&Lsdb::processInterest,
123  &m_nlsrLsdb, _1, _2),
124  std::bind(&Nlsr::onRegistrationSuccess, this, _1),
125  std::bind(&Nlsr::registrationFailed, this, _1),
126  m_signingInfo,
127  ndn::nfd::ROUTE_FLAG_CAPTURE);
128 }
129 
130 
131 void
132 Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
133 {
134  try {
135  // false since we want to have control over the registration process
136  m_dispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
137  }
138  catch (const std::exception& e) {
139  NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
140  }
141 }
142 
143 void
145 {
146  const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
147 
148  m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
149  m_fib.setStrategy(m_confParam.getChronosyncPrefix(), strategy, 0);
150 }
151 
152 void
153 Nlsr::canonizeContinuation(std::list<Adjacent>::iterator iterator,
154  std::function<void(void)> finally)
155 {
156  canonizeNeighborUris(iterator, [this, finally] (std::list<Adjacent>::iterator iterator) {
157  canonizeContinuation(iterator, finally);
158  },
159  finally);
160 }
161 
162 void
163 Nlsr::canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
164  std::function<void(std::list<Adjacent>::iterator)> then,
165  std::function<void(void)> finally)
166 {
167  if (currentNeighbor != m_adjacencyList.getAdjList().end()) {
168  ndn::FaceUri uri(currentNeighbor->getFaceUri());
169  uri.canonize([then, currentNeighbor] (ndn::FaceUri canonicalUri) {
170  NLSR_LOG_DEBUG("Canonized URI: " << currentNeighbor->getFaceUri()
171  << " to: " << canonicalUri);
172  currentNeighbor->setFaceUri(canonicalUri);
173  then(std::next(currentNeighbor));
174  },
175  [then, currentNeighbor] (const std::string& reason) {
176  NLSR_LOG_ERROR("Could not canonize URI: " << currentNeighbor->getFaceUri()
177  << " because: " << reason);
178  then(std::next(currentNeighbor));
179  },
180  m_nlsrFace.getIoService(),
182  }
183  // We have finished canonizing all neighbors, so call finally()
184  else {
185  finally();
186  }
187 }
188 
189 void
190 Nlsr::loadCertToPublish(const ndn::security::v2::Certificate& certificate)
191 {
192  NLSR_LOG_TRACE("Loading cert to publish.");
193  m_certStore.insert(certificate);
194  m_validator.loadAnchor("Authoritative-Certificate",
195  ndn::security::v2::Certificate(certificate));
196  m_prefixUpdateProcessor.getValidator().
197  loadAnchor("Authoritative-Certificate",
198  ndn::security::v2::Certificate(certificate));
199 }
200 
201 void
202 Nlsr::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
203 {
204  NLSR_LOG_TRACE("NLSR: Connect to SegmentFetcher.");
205 
206  fetcher.afterSegmentValidated.connect(std::bind(&Nlsr::afterFetcherSignalEmitted,
207  this, _1));
208 }
209 
210 void
211 Nlsr::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
212 {
213  NLSR_LOG_TRACE("SegmentFetcher fetched a data segment. Start inserting cert to own cert store.");
214  ndn::Name keyName = lsaSegment.getSignature().getKeyLocator().getName();
215  if (getCertificate(keyName) == nullptr) {
216  publishCertFromCache(keyName);
217  }
218  else {
219  NLSR_LOG_TRACE("Certificate is already in the store: " << keyName);
220  }
221 }
222 
223 void
224 Nlsr::publishCertFromCache(const ndn::Name& keyName)
225 {
226  const ndn::security::v2::Certificate* cert = m_validator.getUnverifiedCertCache()
227  .find(keyName);
228  if (cert != nullptr) {
229  m_certStore.insert(*cert);
230  NLSR_LOG_TRACE(*cert);
231  NLSR_LOG_TRACE("Setting interest filter for: "
232  << ndn::security::v2::extractKeyNameFromCertName(cert->getName()));
233  m_nlsrFace.setInterestFilter(ndn::security::v2::extractKeyNameFromCertName(cert->getName()),
234  std::bind(&Nlsr::onKeyInterest,
235  this, _1, _2),
236  std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
237  std::bind(&Nlsr::registrationFailed, this, _1),
238  m_signingInfo,
239  ndn::nfd::ROUTE_FLAG_CAPTURE);
240 
241  if (!cert->getKeyName().equals(cert->getSignature().getKeyLocator().getName())) {
242  publishCertFromCache(cert->getSignature().getKeyLocator().getName());
243  }
244  }
245  else {
246  NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache. ");
247  }
248 }
249 
250 void
252 {
253  NLSR_LOG_DEBUG("Initializing Nlsr");
254  m_confParam.buildRouterPrefix();
255  m_datasetHandler.setRouterNameCommandPrefix(m_confParam.getRouterPrefix());
256  m_nlsrLsdb.setLsaRefreshTime(ndn::time::seconds(m_confParam.getLsaRefreshTime()));
257  m_nlsrLsdb.setThisRouterPrefix(m_confParam.getRouterPrefix().toUri());
258  m_fib.setEntryRefreshTime(2 * m_confParam.getLsaRefreshTime());
259 
260  m_nlsrLsdb.getSequencingManager().setSeqFileDirectory(m_confParam.getSeqFileDir());
262 
263  m_nlsrLsdb.getSyncLogicHandler().createSyncSocket(m_confParam.getChronosyncPrefix(),
264  m_confParam.getSyncInterestLifetime());
265 
266  // Logging start
267  m_confParam.writeLog();
268  m_adjacencyList.writeLog();
269  NLSR_LOG_DEBUG(m_namePrefixList);
270  // Logging end
271 
272  initializeKey();
273  setStrategies();
274 
275  NLSR_LOG_DEBUG("Default NLSR identity: " << m_signingInfo.getSignerName());
276 
279 
280  // add top-level prefixes: router and localhost prefix
281  addDispatcherTopPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"));
283 
284  initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
285  std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));
286 
287  enableIncomingFaceIdIndication();
288 
289  // Set event intervals
290  setFirstHelloInterval(m_confParam.getFirstHelloInterval());
291  m_nlsrLsdb.setAdjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval());
292  m_routingTable.setRoutingCalcInterval(m_confParam.getRoutingCalcInterval());
293 
294  m_nlsrLsdb.buildAndInstallOwnNameLsa();
295 
296  // Install coordinate LSAs if using HR or dry-run HR.
297  if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
298  m_nlsrLsdb.buildAndInstallOwnCoordinateLsa();
299  }
300 
301  registerKeyPrefix();
302  registerLocalhostPrefix();
303  registerRouterPrefix();
304 
305  m_helloProtocol.scheduleInterest(m_firstHelloInterval);
306 
307  // Need to set direct neighbors' costs to 0 for hyperbolic routing
308  if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
309 
310  std::list<Adjacent>& neighbors = m_adjacencyList.getAdjList();
311 
312  for (std::list<Adjacent>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
313  it->setLinkCost(0);
314  }
315  }
316 }
317 
318 void
320 {
321  NLSR_LOG_DEBUG("Initializing Key ...");
322 
323  ndn::Name nlsrInstanceName = m_confParam.getRouterPrefix();
324  nlsrInstanceName.append("nlsr");
325 
326  try {
327  m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
328  } catch (const std::exception& e) {
329  NLSR_LOG_WARN(e.what());
330  }
331 
332  auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
333  auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
334 
335  ndn::security::v2::Certificate certificate;
336 
337  ndn::Name certificateName = nlsrInstanceKey.getName();
338  certificateName.append("NA");
339  certificateName.appendVersion();
340  certificate.setName(certificateName);
341 
342  // set metainfo
343  certificate.setContentType(ndn::tlv::ContentType_Key);
344  certificate.setFreshnessPeriod(ndn::time::days(365));
345 
346  // set content
347  certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
348 
349  // set signature-info
350  ndn::SignatureInfo signatureInfo;
351  signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
352  ndn::time::system_clock::now()
353  + ndn::time::days(365)));
354  try {
355  m_keyChain.sign(certificate,
356  ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.getRouterPrefix()))
357  .setSignatureInfo(signatureInfo));
358  }
359  catch (const std::exception& e) {
360  NLSR_LOG_WARN("ERROR: Router's " << e.what()
361  << "NLSR is running without security."
362  << " If security is enabled NLSR will not converge.");
363 
364  std::cerr << "Router's " << e.what() << ". NLSR is running without security "
365  << "(Only for testing, should not be used in production.)"
366  << " If security is enabled NLSR will not converge." << std::endl;
367  }
368 
369  m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
370  nlsrInstanceName);
371 
372  loadCertToPublish(certificate);
373 
374  m_defaultCertName = certificate.getName();
375 }
376 
377 void
378 Nlsr::registerKeyPrefix()
379 {
380  // Start listening for the interest of this router's NLSR certificate
381  ndn::Name nlsrKeyPrefix = getConfParameter().getRouterPrefix();
382  nlsrKeyPrefix.append("nlsr");
383  nlsrKeyPrefix.append("KEY");
384 
385  m_nlsrFace.setInterestFilter(nlsrKeyPrefix,
386  std::bind(&Nlsr::onKeyInterest,
387  this, _1, _2),
388  std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
389  std::bind(&Nlsr::registrationFailed, this, _1),
390  m_signingInfo,
391  ndn::nfd::ROUTE_FLAG_CAPTURE);
392 
393  // Start listening for the interest of this router's certificate
394  ndn::Name routerKeyPrefix = getConfParameter().getRouterPrefix();
395  routerKeyPrefix.append("KEY");
396 
397  m_nlsrFace.setInterestFilter(routerKeyPrefix,
398  std::bind(&Nlsr::onKeyInterest,
399  this, _1, _2),
400  std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
401  std::bind(&Nlsr::registrationFailed, this, _1),
402  m_signingInfo,
403  ndn::nfd::ROUTE_FLAG_CAPTURE);
404 
405  // Start listening for the interest of this router's operator's certificate
406  ndn::Name operatorKeyPrefix = getConfParameter().getNetwork();
407  operatorKeyPrefix.append(getConfParameter().getSiteName());
408  operatorKeyPrefix.append(std::string("%C1.Operator"));
409 
410  m_nlsrFace.setInterestFilter(operatorKeyPrefix,
411  std::bind(&Nlsr::onKeyInterest,
412  this, _1, _2),
413  std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
414  std::bind(&Nlsr::registrationFailed, this, _1),
415  m_signingInfo,
416  ndn::nfd::ROUTE_FLAG_CAPTURE);
417 
418  // Start listening for the interest of this router's site's certificate
419  ndn::Name siteKeyPrefix = getConfParameter().getNetwork();
420  siteKeyPrefix.append(getConfParameter().getSiteName());
421  siteKeyPrefix.append("KEY");
422 
423  m_nlsrFace.setInterestFilter(siteKeyPrefix,
424  std::bind(&Nlsr::onKeyInterest,
425  this, _1, _2),
426  std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
427  std::bind(&Nlsr::registrationFailed, this, _1),
428  m_signingInfo,
429  ndn::nfd::ROUTE_FLAG_CAPTURE);
430 }
431 
432 void
433 Nlsr::registerLocalhostPrefix()
434 {
435  m_nlsrFace.registerPrefix(LOCALHOST_PREFIX,
436  std::bind(&Nlsr::onRegistrationSuccess, this, _1),
437  std::bind(&Nlsr::registrationFailed, this, _1));
438 }
439 
440 void
441 Nlsr::registerRouterPrefix()
442 {
443  m_nlsrFace.registerPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"),
444  std::bind(&Nlsr::onRegistrationSuccess, this, _1),
445  std::bind(&Nlsr::registrationFailed, this, _1));
446 }
447 
448 void
449 Nlsr::onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
450 {
451  NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
452 
453  const ndn::Name& interestName = interest.getName();
454  const ndn::security::v2::Certificate* cert = getCertificate(interestName);
455 
456  if (cert == nullptr) {
457  NLSR_LOG_DEBUG("Certificate is not found for: " << interest);
458  return; // cert is not found
459  }
460 
461  m_nlsrFace.put(*cert);
462 }
463 
464 void
465 Nlsr::onKeyPrefixRegSuccess(const ndn::Name& name)
466 {
467  NLSR_LOG_DEBUG("KEY prefix: " << name << " registration is successful.");
468 }
469 
470 void
471 Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNotification)
472 {
473  NLSR_LOG_TRACE("Nlsr::onFaceEventNotification called");
474 
475  switch (faceEventNotification.getKind()) {
476  case ndn::nfd::FACE_EVENT_DESTROYED: {
477  uint64_t faceId = faceEventNotification.getFaceId();
478 
479  auto adjacent = m_adjacencyList.findAdjacent(faceId);
480 
481  if (adjacent != m_adjacencyList.end()) {
482  NLSR_LOG_DEBUG("Face to " << adjacent->getName() << " with face id: " << faceId << " destroyed");
483 
484  adjacent->setFaceId(0);
485 
486  // Only trigger an Adjacency LSA build if this node is changing
487  // from ACTIVE to INACTIVE since this rebuild will effectively
488  // cancel the previous Adjacency LSA refresh event and schedule
489  // a new one further in the future.
490  //
491  // Continuously scheduling the refresh in the future will block
492  // the router from refreshing its Adjacency LSA. Since other
493  // routers' Name prefixes' expiration times are updated when
494  // this router refreshes its Adjacency LSA, the other routers'
495  // prefixes will expire and be removed from the RIB.
496  //
497  // This check is required to fix Bug #2733 for now. This check
498  // would be unnecessary to fix Bug #2733 when Issue #2732 is
499  // completed, but the check also helps with optimization so it
500  // can remain even when Issue #2732 is implemented.
501  if (adjacent->getStatus() == Adjacent::STATUS_ACTIVE) {
502  adjacent->setStatus(Adjacent::STATUS_INACTIVE);
503 
504  // A new adjacency LSA cannot be built until the neighbor is marked INACTIVE and
505  // has met the HELLO retry threshold
506  adjacent->setInterestTimedOutNo(m_confParam.getInterestRetryNumber());
507 
508  if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
510  }
511  else {
512  m_nlsrLsdb.scheduleAdjLsaBuild();
513  }
514  }
515  }
516  break;
517  }
518  case ndn::nfd::FACE_EVENT_CREATED: {
519  // Find the neighbor in our adjacency list
520  ndn::FaceUri faceUri;
521  try {
522  faceUri = ndn::FaceUri(faceEventNotification.getRemoteUri());
523  }
524  catch (const std::exception& e) {
525  NLSR_LOG_WARN(e.what());
526  return;
527  }
528  auto adjacent = m_adjacencyList.findAdjacent(faceUri);
529 
530  // If we have a neighbor by that FaceUri and it has no FaceId, we
531  // have a match.
532  if (adjacent != m_adjacencyList.end()) {
533  NLSR_LOG_DEBUG("Face creation event matches neighbor: " << adjacent->getName()
534  << ". New Face ID: " << faceEventNotification.getFaceId()
535  << ". Registering prefixes.");
536  adjacent->setFaceId(faceEventNotification.getFaceId());
537 
538  registerAdjacencyPrefixes(*adjacent, ndn::time::milliseconds::max());
539 
540  if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
542  }
543  else {
544  m_nlsrLsdb.scheduleAdjLsaBuild();
545  }
546  }
547  break;
548  }
549  default:
550  break;
551  }
552 }
553 
554 void
556  const FetchDatasetTimeoutCallback& onFetchFailure)
557 {
558  NLSR_LOG_TRACE("Initializing Faces...");
559 
560  m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);
561 
562 }
563 
564 void
565 Nlsr::processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces)
566 {
567  NLSR_LOG_DEBUG("Processing face dataset");
568 
569  // Iterate over each neighbor listed in nlsr.conf
570  for (auto& adjacent : m_adjacencyList.getAdjList()) {
571 
572  const std::string faceUriString = adjacent.getFaceUri().toString();
573  // Check the list of FaceStatus objects we got for a match
574  for (const ndn::nfd::FaceStatus& faceStatus : faces) {
575  // Set the adjacency FaceID if we find a URI match and it was
576  // previously unset. Change the boolean to true.
577  if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
578  NLSR_LOG_DEBUG("FaceUri: " << faceStatus.getRemoteUri() <<
579  " FaceId: "<< faceStatus.getFaceId());
580  adjacent.setFaceId(faceStatus.getFaceId());
581  // Register the prefixes for each neighbor
582  this->registerAdjacencyPrefixes(adjacent, ndn::time::milliseconds::max());
583  }
584  }
585  // If this adjacency has no information in this dataset, then one
586  // of two things is happening: 1. NFD is starting slowly and this
587  // Face wasn't ready yet, or 2. NFD is configured
588  // incorrectly and this Face isn't available.
589  if (adjacent.getFaceId() == 0) {
590  NLSR_LOG_WARN("The adjacency " << adjacent.getName() <<
591  " has no Face information in this dataset.");
592  }
593  }
594 
595  scheduleDatasetFetch();
596 }
597 
598 void
600  const ndn::time::milliseconds& timeout)
601 {
602  ndn::FaceUri faceUri = adj.getFaceUri();
603  double linkCost = adj.getLinkCost();
604  const ndn::Name& adjName = adj.getName();
605 
606  m_fib.registerPrefix(adjName, faceUri, linkCost,
607  timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
608 
609  m_fib.registerPrefix(m_confParam.getChronosyncPrefix(),
610  faceUri, linkCost, timeout,
611  ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
612 
613  m_fib.registerPrefix(m_confParam.getLsaPrefix(),
614  faceUri, linkCost, timeout,
615  ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
616 }
617 
618 void
620  const std::string& msg,
621  uint32_t nRetriesSoFar)
622 {
623  NLSR_LOG_DEBUG("onFaceDatasetFetchTimeout");
624  // If we have exceeded the maximum attempt count, do not try again.
625  if (nRetriesSoFar++ < m_confParam.getFaceDatasetFetchTries()) {
626  NLSR_LOG_DEBUG("Failed to fetch dataset: " << msg << ". Attempting retry #" << nRetriesSoFar);
627  m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset,
628  this, _1),
630  this, _1, _2, nRetriesSoFar));
631  }
632  else {
633  NLSR_LOG_ERROR("Failed to fetch dataset: " << msg << ". Exceeded limit of " <<
634  m_confParam.getFaceDatasetFetchTries() << ", so not trying again this time.");
635  // If we fail to fetch it, just do nothing until the next
636  // interval. Since this is a backup mechanism, we aren't as
637  // concerned with retrying.
638  scheduleDatasetFetch();
639  }
640 }
641 
642 void
643 Nlsr::scheduleDatasetFetch()
644 {
645  NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval());
646 
647  m_scheduler.scheduleEvent(m_confParam.getFaceDatasetFetchInterval(),
648  [this] {
649  this->initializeFaces(
650  [this] (const std::vector<ndn::nfd::FaceStatus>& faces) {
651  this->processFaceDataset(faces);
652  },
653  [this] (uint32_t code, const std::string& msg) {
654  this->onFaceDatasetFetchTimeout(code, msg, 0);
655  });
656  });
657 }
658 
659 void
660 Nlsr::enableIncomingFaceIdIndication()
661 {
662  NLSR_LOG_DEBUG("Enabling incoming face id indication for local face.");
663 
664  m_controller.start<ndn::nfd::FaceUpdateCommand>(
665  ndn::nfd::ControlParameters()
666  .setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED, true),
667  bind(&Nlsr::onFaceIdIndicationSuccess, this, _1),
668  bind(&Nlsr::onFaceIdIndicationFailure, this, _1));
669 }
670 
671 void
672 Nlsr::onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp)
673 {
674  NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
675  << "for face id " << cp.getFaceId());
676 }
677 
678 void
679 Nlsr::onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr)
680 {
681  std::ostringstream os;
682  os << "Failed to enable incoming face id indication feature: " <<
683  "(code: " << cr.getCode() << ", reason: " << cr.getText() << ")";
684 
685  NLSR_LOG_DEBUG(os.str());
686 }
687 
688 void
690 {
691  m_nlsrFace.processEvents();
692 }
693 
694 } // namespace nlsr
void initializeFaces(const FetchDatasetCallback &onFetchSuccess, const FetchDatasetTimeoutCallback &onFetchFailure)
Initializes neighbors&#39; Faces using information from NFD.
Definition: nlsr.cpp:555
void onFaceDatasetFetchTimeout(uint32_t code, const std::string &reason, uint32_t nRetriesSoFar)
Definition: nlsr.cpp:619
#define NLSR_LOG_WARN(x)
Definition: logger.hpp:40
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
Definition: tlv-nlsr.hpp:28
const ndn::time::milliseconds & getSyncInterestLifetime() const
void initialize()
Definition: nlsr.cpp:251
void scheduleAdjLsaBuild()
Schedules a build of this router&#39;s LSA.
Definition: lsdb.cpp:598
std::function< void(uint32_t, const std::string &)> FetchDatasetTimeoutCallback
Definition: nlsr.hpp:71
ConfParameter & getConfParameter()
Definition: nlsr.hpp:121
void setAdjLsaBuildInterval(uint32_t interval)
Definition: lsdb.hpp:182
const ndn::FaceUri & getFaceUri() const
Definition: adjacent.hpp:69
void setStrategies()
Definition: nlsr.cpp:144
const std::string & getSeqFileDir() const
void connectToFetcher(ndn::util::SegmentFetcher &fetcher)
Definition: nlsr.cpp:202
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:38
const ndn::Name & getRouterPrefix() const
std::function< void(const std::vector< ndn::nfd::FaceStatus > &)> FetchDatasetCallback
Definition: nlsr.hpp:70
void initiateSeqNoFromFile(int hypState)
void setStrategy(const ndn::Name &name, const std::string &strategy, uint32_t count)
Definition: fib.cpp:306
SyncLogicHandler & getSyncLogicHandler()
Definition: lsdb.hpp:49
RoutingTable & getRoutingTable()
Definition: nlsr.hpp:169
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
void setLsaInterestFilter()
Definition: nlsr.cpp:115
void addDispatcherTopPrefix(const ndn::Name &topPrefix)
Add top level prefixes for Dispatcher.
Definition: nlsr.cpp:132
static const ndn::Name LOCALHOST_PREFIX
Definition: nlsr.hpp:496
void scheduleInterest(uint32_t seconds)
Schedules a Hello Interest event.
void registerAdjacencyPrefixes(const Adjacent &adj, const ndn::time::milliseconds &timeout)
Registers NLSR-specific prefixes for a neighbor (Adjacent)
Definition: nlsr.cpp:599
#define INIT_LOGGER(name)
Definition: logger.hpp:35
void canonizeNeighborUris(std::list< Adjacent >::iterator currentNeighbor, std::function< void(std::list< Adjacent >::iterator)> then, std::function< void(void)> finally)
Canonize the URI for this and all proceeding neighbors in a list.
Definition: nlsr.cpp:163
uint32_t getInterestRetryNumber() const
ndn::security::ValidatorConfig & getValidator()
const ndn::Name & getName() const
Definition: adjacent.hpp:57
void insert(const ndn::security::v2::Certificate &certificate)
const ndn::Name & getLsaPrefix() const
void setLsaRefreshTime(const ndn::time::seconds &lsaRefreshTime)
Definition: lsdb.cpp:824
void scheduleRoutingTableCalculation(Nlsr &pnlsr)
Schedules a calculation event in the event scheduler only if one isn&#39;t already scheduled.
void onRegistrationSuccess(const ndn::Name &name)
Definition: nlsr.cpp:91
void setEntryRefreshTime(int32_t fert)
Definition: fib.hpp:109
void loadCertToPublish(const ndn::security::v2::Certificate &certificate)
Add a certificate NLSR claims to be authoritative for to the certificate store.
Definition: nlsr.cpp:190
void publishCertFromCache(const ndn::Name &keyName)
Retrieves the chain of certificates from Validator&#39;s cache and store them in Nlsr&#39;s own CertificateSt...
Definition: nlsr.cpp:224
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Processes a Hello Interest from a neighbor.
void setInfoInterestFilter()
Definition: nlsr.cpp:97
void afterFetcherSignalEmitted(const ndn::Data &lsaSegment)
Callback when SegmentFetcher retrieves a segment.
Definition: nlsr.cpp:211
SequencingManager & getSequencingManager()
Definition: lsdb.hpp:194
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Definition: lsdb.cpp:1040
uint32_t getLsaRefreshTime() const
void setRoutingCalcInterval(uint32_t interval)
const ndn::Name & getChronosyncPrefix() const
A neighbor reachable over a Face.
Definition: adjacent.hpp:38
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
void registrationFailed(const ndn::Name &name)
Definition: nlsr.cpp:84
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
uint32_t getAdjLsaBuildInterval() const
AdjacencyList::iterator findAdjacent(const ndn::Name &adjName)
const ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION
Definition: common.hpp:41
void setThisRouterPrefix(std::string trp)
Definition: lsdb.cpp:830
uint32_t getFirstHelloInterval() const
uint32_t getFaceDatasetFetchTries() const
const ndn::Name & getNetwork() const
void startEventLoop()
Definition: nlsr.cpp:689
const ndn::security::v2::Certificate * getCertificate(const ndn::Name &certificateKeyName)
Find a certificate.
Definition: nlsr.hpp:341
Nlsr(boost::asio::io_service &ioService, ndn::Scheduler &scheduler, ndn::Face &face, ndn::KeyChain &keyChain)
Definition: nlsr.cpp:42
void setRouterNameCommandPrefix(const ndn::Name &routerName)
void createSyncSocket(const ndn::Name &syncPrefix, const ndn::time::milliseconds &syncInterestLifetime=ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
Create and configure a socket to enable ChronoSync for this NLSR.
bool buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
Definition: lsdb.cpp:163
bool buildAndInstallOwnCoordinateLsa()
Builds a cor. LSA for this router and installs it into the LSDB.
Definition: lsdb.cpp:397
int32_t getHyperbolicState() const
uint64_t getLinkCost() const
Definition: adjacent.hpp:81
uint32_t getRoutingCalcInterval() const
void setSeqFileDirectory(std::string filePath)
Set the sequence file directory.
void processFaceDataset(const std::vector< ndn::nfd::FaceStatus > &faces)
Consumes a Face StatusDataset to configure NLSR neighbors.
Definition: nlsr.cpp:565
const ndn::time::seconds getFaceDatasetFetchInterval() const
std::list< Adjacent > & getAdjList()
void initializeKey()
Definition: nlsr.cpp:319
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:37
const_iterator end() const
void registerPrefix(const ndn::Name &namePrefix, const ndn::FaceUri &faceUri, uint64_t faceCost, const ndn::time::milliseconds &timeout, uint64_t flags, uint8_t times)
Inform NFD of a next-hop.
Definition: fib.cpp:199