lsdb.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "lsdb.hpp"
23 
24 #include "logger.hpp"
25 #include "nlsr.hpp"
27 #include "utility/name-helper.hpp"
28 
29 #include <ndn-cxx/security/signing-helpers.hpp>
30 #include <ndn-cxx/util/segment-fetcher.hpp>
31 
32 namespace nlsr {
33 
34 INIT_LOGGER("Lsdb");
35 
36 class LsaContentPublisher : public SegmentPublisher<ndn::Face>
37 {
38 public:
39  LsaContentPublisher(ndn::Face& face,
40  ndn::KeyChain& keyChain,
41  const ndn::security::SigningInfo& signingInfo,
42  const ndn::time::milliseconds& freshnessPeriod,
43  const std::string& content)
44  : SegmentPublisher(face, keyChain, signingInfo, freshnessPeriod)
45  , m_content(content)
46  {
47  }
48 
49  virtual size_t
50  generate(ndn::EncodingBuffer& outBuffer) {
51  size_t totalLength = 0;
52  totalLength += outBuffer.prependByteArray(reinterpret_cast<const uint8_t*>(m_content.c_str()),
53  m_content.size());
54  return totalLength;
55  }
56 
57 private:
58  const std::string m_content;
59 };
60 
61 const ndn::Name::Component Lsdb::NAME_COMPONENT = ndn::Name::Component("lsdb");
62 const ndn::time::seconds Lsdb::GRACE_PERIOD = ndn::time::seconds(10);
63 const ndn::time::steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE =
64  ndn::time::steady_clock::TimePoint::min();
65 
66 Lsdb::Lsdb(Nlsr& nlsr, ndn::Scheduler& scheduler)
67  : m_nlsr(nlsr)
68  , m_scheduler(scheduler)
69  , m_sync(m_nlsr.getNlsrFace(),
70  [this] (const ndn::Name& routerName, const Lsa::Type& lsaType,
71  const uint64_t& sequenceNumber) {
72  return isLsaNew(routerName, lsaType, sequenceNumber);
73  }, m_nlsr.getConfParameter())
74  , m_lsaRefreshTime(0)
75  , m_adjLsaBuildInterval(ADJ_LSA_BUILD_INTERVAL_DEFAULT)
76  , m_sequencingManager()
77  , m_onNewLsaConnection(m_sync.onNewLsa->connect(
78  [this] (const ndn::Name& updateName, const uint64_t& sequenceNumber) {
79  ndn::Name lsaInterest{updateName};
80  lsaInterest.appendNumber(sequenceNumber);
81  expressInterest(lsaInterest, 0);
82  }))
83 {
84 }
85 
86 void
87 Lsdb::onFetchLsaError(uint32_t errorCode,
88  const std::string& msg,
89  ndn::Name& interestName,
90  uint32_t retransmitNo,
91  const ndn::time::steady_clock::TimePoint& deadline,
92  ndn::Name lsaName,
93  uint64_t seqNo)
94 {
95  NLSR_LOG_DEBUG("Failed to fetch LSA: " << lsaName << ", Error code: " << errorCode
96  << ", Message: " << msg);
97 
98  if (ndn::time::steady_clock::now() < deadline) {
99  SequenceNumberMap::const_iterator it = m_highestSeqNo.find(lsaName);
100 
101  if (it != m_highestSeqNo.end() && it->second == seqNo) {
102  // If the SegmentFetcher failed due to an Interest timeout, it is safe to re-express
103  // immediately since at the least the LSA Interest lifetime has elapsed.
104  // Otherwise, it is necessary to delay the Interest re-expression to prevent
105  // the potential for constant Interest flooding.
106  ndn::time::seconds delay = m_nlsr.getConfParameter().getLsaInterestLifetime();
107 
108  if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
109  delay = ndn::time::seconds(0);
110  }
111 
112  m_scheduler.scheduleEvent(delay, std::bind(&Lsdb::expressInterest, this,
113  interestName, retransmitNo + 1, deadline));
114  }
115  }
116 }
117 
118 void
119 Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, ndn::Name& interestName)
120 {
121  std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(ndn::Name(interestName));
122  data->setContent(bufferPtr);
123 
124  NLSR_LOG_DEBUG("Received data for LSA(name): " << data->getName());
125 
126  ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
127  uint64_t seqNo = interestName[-1].toNumber();
128 
129  if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
130  m_highestSeqNo[lsaName] = seqNo;
131  }
132  else if (seqNo > m_highestSeqNo[lsaName]) {
133  m_highestSeqNo[lsaName] = seqNo;
134  NLSR_LOG_TRACE("SeqNo for LSA(name): " << data->getName() << " updated");
135  }
136  else if (seqNo < m_highestSeqNo[lsaName]) {
137  return;
138  }
139 
140  onContentValidated(data);
141 }
142 
143 void
144 Lsdb::cancelScheduleLsaExpiringEvent(ndn::EventId eid)
145 {
146  m_scheduler.cancelEvent(eid);
147 }
148 
154 static bool
155 nameLsaCompareByKey(const NameLsa& nlsa1, const ndn::Name& key)
156 {
157  return nlsa1.getKey() == key;
158 }
159 
160 bool
162 {
163  NameLsa nameLsa(m_nlsr.getConfParameter().getRouterPrefix(),
164  m_sequencingManager.getNameLsaSeq() + 1,
165  getLsaExpirationTimePoint(),
166  m_nlsr.getNamePrefixList());
167  m_sequencingManager.increaseNameLsaSeq();
168 
169  m_sequencingManager.writeSeqNoToFile();
170  m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
171 
172  return installNameLsa(nameLsa);
173 }
174 
175 NameLsa*
176 Lsdb::findNameLsa(const ndn::Name& key)
177 {
178  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
179  m_nameLsdb.end(),
180  std::bind(nameLsaCompareByKey, _1, key));
181  if (it != m_nameLsdb.end()) {
182  return &(*it);
183  }
184  return 0;
185 }
186 
187 bool
188 Lsdb::isNameLsaNew(const ndn::Name& key, uint64_t seqNo)
189 {
190  NameLsa* nameLsaCheck = findNameLsa(key);
191  // Is the name in the LSDB
192  if (nameLsaCheck != 0) {
193  // And the supplied seq no is the highest so far
194  if (nameLsaCheck->getLsSeqNo() < seqNo) {
195  return true;
196  }
197  else {
198  return false;
199  }
200  }
201  return true;
202 }
203 
204 ndn::EventId
205 Lsdb::scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
206  const ndn::time::seconds& expTime)
207 {
208  return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
209  std::bind(&Lsdb::expireOrRefreshNameLsa, this, key, seqNo));
210 }
211 
212 bool
214 {
215  ndn::time::seconds timeToExpire = m_lsaRefreshTime;
216  NameLsa* chkNameLsa = findNameLsa(nlsa.getKey());
217  // Determines if the name LSA is new or not.
218  if (chkNameLsa == 0) {
219  addNameLsa(nlsa);
220  NLSR_LOG_DEBUG("New Name LSA");
221  NLSR_LOG_DEBUG("Adding Name Lsa");
222  nlsa.writeLog();
223 
224  if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
225  // If this name LSA is from another router, add the advertised
226  // prefixes to the NPT.
227  m_nlsr.getNamePrefixTable().addEntry(nlsa.getOrigRouter(),
228  nlsa.getOrigRouter());
229  std::list<ndn::Name> nameList = nlsa.getNpl().getNames();
230  for (std::list<ndn::Name>::iterator it = nameList.begin(); it != nameList.end();
231  it++) {
232  if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
233  m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
234  }
235  }
236  }
237  if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
238  ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
239  ndn::time::system_clock::now();
240  timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
241  }
242  nlsa.setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
243  nlsa.getLsSeqNo(),
244  timeToExpire));
245  }
246  // Else this is a known name LSA, so we are updating it.
247  else {
248  if (chkNameLsa->getLsSeqNo() < nlsa.getLsSeqNo()) {
249  NLSR_LOG_DEBUG("Updated Name LSA. Updating LSDB");
250  NLSR_LOG_DEBUG("Deleting Name Lsa");
251  chkNameLsa->writeLog();
252  chkNameLsa->setLsSeqNo(nlsa.getLsSeqNo());
254  chkNameLsa->getNpl().sort();
255  nlsa.getNpl().sort();
256  // Obtain the set difference of the current and the incoming
257  // name prefix sets, and add those.
258  std::list<ndn::Name> newNames = nlsa.getNpl().getNames();
259  std::list<ndn::Name> oldNames = chkNameLsa->getNpl().getNames();
260  std::list<ndn::Name> namesToAdd;
261  std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
262  std::inserter(namesToAdd, namesToAdd.begin()));
263  for (std::list<ndn::Name>::iterator it = namesToAdd.begin();
264  it != namesToAdd.end(); ++it) {
265  chkNameLsa->addName((*it));
266  if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
267  if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
268  m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
269  }
270  }
271  }
272 
273  chkNameLsa->getNpl().sort();
274 
275  // Also remove any names that are no longer being advertised.
276  std::list<ndn::Name> namesToRemove;
277  std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
278  std::inserter(namesToRemove, namesToRemove.begin()));
279  for (std::list<ndn::Name>::iterator it = namesToRemove.begin();
280  it != namesToRemove.end(); ++it) {
281  NLSR_LOG_DEBUG("Removing name LSA no longer advertised: " << (*it).toUri());
282  chkNameLsa->removeName((*it));
283  if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
284  if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
285  m_nlsr.getNamePrefixTable().removeEntry((*it), nlsa.getOrigRouter());
286  }
287  }
288  }
289 
290  if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
291  ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
292  ndn::time::system_clock::now();
293  timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
294  }
295  cancelScheduleLsaExpiringEvent(chkNameLsa->getExpiringEventId());
296  chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
297  nlsa.getLsSeqNo(),
298  timeToExpire));
299  NLSR_LOG_DEBUG("Adding Name Lsa");
300  chkNameLsa->writeLog();
301  }
302  }
303  return true;
304 }
305 
306 bool
307 Lsdb::addNameLsa(NameLsa& nlsa)
308 {
309  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
310  m_nameLsdb.end(),
311  std::bind(nameLsaCompareByKey, _1,
312  nlsa.getKey()));
313  if (it == m_nameLsdb.end()) {
314  m_nameLsdb.push_back(nlsa);
315  return true;
316  }
317  return false;
318 }
319 
320 bool
321 Lsdb::removeNameLsa(const ndn::Name& key)
322 {
323  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
324  m_nameLsdb.end(),
325  std::bind(nameLsaCompareByKey, _1, key));
326  if (it != m_nameLsdb.end()) {
327  NLSR_LOG_DEBUG("Deleting Name Lsa");
328  (*it).writeLog();
329  // If the requested name LSA is not ours, we also need to remove
330  // its entries from the NPT.
331  if ((*it).getOrigRouter() !=
332  m_nlsr.getConfParameter().getRouterPrefix()) {
333  m_nlsr.getNamePrefixTable().removeEntry((*it).getOrigRouter(),
334  (*it).getOrigRouter());
335  for (const auto& name : it->getNpl().getNames()) {
336  if (name != m_nlsr.getConfParameter().getRouterPrefix()) {
337  m_nlsr.getNamePrefixTable().removeEntry(name, it->getOrigRouter());
338  }
339  }
340  }
341  m_nameLsdb.erase(it);
342  return true;
343  }
344  return false;
345 }
346 
347 bool
348 Lsdb::doesNameLsaExist(const ndn::Name& key)
349 {
350  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
351  m_nameLsdb.end(),
352  std::bind(nameLsaCompareByKey, _1, key));
353  if (it == m_nameLsdb.end()) {
354  return false;
355  }
356  return true;
357 }
358 
359 void
361 {
362  NLSR_LOG_DEBUG("---------------Name LSDB-------------------");
363  for (std::list<NameLsa>::iterator it = m_nameLsdb.begin();
364  it != m_nameLsdb.end() ; it++) {
365  (*it).writeLog();
366  }
367 }
368 
369 const std::list<NameLsa>&
371 {
372  return m_nameLsdb;
373 }
374 
375 // Cor LSA and LSDB related Functions start here
376 
381 static bool
382 corLsaCompareByKey(const CoordinateLsa& clsa, const ndn::Name& key)
383 {
384  return clsa.getKey() == key;
385 }
386 
387 bool
389 {
391  m_sequencingManager.getCorLsaSeq() + 1,
392  getLsaExpirationTimePoint(),
393  m_nlsr.getConfParameter().getCorR(),
394  m_nlsr.getConfParameter().getCorTheta());
395 
396  // Sync coordinate LSAs if using HR or HR dry run.
398  m_sequencingManager.increaseCorLsaSeq();
399  m_sequencingManager.writeSeqNoToFile();
400  m_sync.publishRoutingUpdate(Lsa::Type::COORDINATE, m_sequencingManager.getCorLsaSeq());
401  }
402 
403  installCoordinateLsa(corLsa);
404 
405  return true;
406 }
407 
409 Lsdb::findCoordinateLsa(const ndn::Name& key)
410 {
411  std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
412  m_corLsdb.end(),
413  std::bind(corLsaCompareByKey, _1, key));
414  if (it != m_corLsdb.end()) {
415  return &(*it);
416  }
417  return 0;
418 }
419 
420 bool
421 Lsdb::isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo)
422 {
423  CoordinateLsa* clsa = findCoordinateLsa(key);
424  // Is the coordinate LSA in the LSDB already
425  if (clsa != 0) {
426  // And the seq no is newer (higher) than the current one
427  if (clsa->getLsSeqNo() < seqNo) {
428  return true;
429  }
430  else {
431  return false;
432  }
433  }
434  return true;
435 }
436 
437  // Schedules a refresh/expire event in the scheduler.
438  // \param key The name of the router that published the LSA.
439  // \param seqNo the seq. no. associated with the LSA to check.
440  // \param expTime How long to wait before triggering the event.
441 ndn::EventId
442 Lsdb::scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
443  const ndn::time::seconds& expTime)
444 {
445  return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
446  std::bind(&Lsdb::expireOrRefreshCoordinateLsa,
447  this, key, seqNo));
448 }
449 
450 bool
452 {
453  ndn::time::seconds timeToExpire = m_lsaRefreshTime;
454  CoordinateLsa* chkCorLsa = findCoordinateLsa(clsa.getKey());
455  // Checking whether the LSA is new or not.
456  if (chkCorLsa == 0) {
457  NLSR_LOG_DEBUG("New Coordinate LSA. Adding to LSDB");
458  NLSR_LOG_DEBUG("Adding Coordinate Lsa");
459  clsa.writeLog();
460  addCoordinateLsa(clsa);
461 
462  // Register the LSA's origin router prefix
463  if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
464  m_nlsr.getNamePrefixTable().addEntry(clsa.getOrigRouter(),
465  clsa.getOrigRouter());
466  }
469  }
470  // Set the expiration time for the new LSA.
471  if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
472  ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
473  ndn::time::system_clock::now();
474  timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
475  }
476  scheduleCoordinateLsaExpiration(clsa.getKey(),
477  clsa.getLsSeqNo(), timeToExpire);
478  }
479  // We are just updating this LSA.
480  else {
481  if (chkCorLsa->getLsSeqNo() < clsa.getLsSeqNo()) {
482  NLSR_LOG_DEBUG("Updated Coordinate LSA. Updating LSDB");
483  NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
484  chkCorLsa->writeLog();
485  chkCorLsa->setLsSeqNo(clsa.getLsSeqNo());
487  // If the new LSA contains new routing information, update the LSDB with it.
488  if (!chkCorLsa->isEqualContent(clsa)) {
489  chkCorLsa->setCorRadius(clsa.getCorRadius());
490  chkCorLsa->setCorTheta(clsa.getCorTheta());
493  }
494  }
495  // If this is an LSA from another router, refresh its expiration time.
496  if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
497  ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
498  ndn::time::system_clock::now();
499  timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
500  }
501  cancelScheduleLsaExpiringEvent(chkCorLsa->getExpiringEventId());
502  chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(clsa.getKey(),
503  clsa.getLsSeqNo(),
504  timeToExpire));
505  NLSR_LOG_DEBUG("Adding Coordinate Lsa");
506  chkCorLsa->writeLog();
507  }
508  }
509  return true;
510 }
511 
512 bool
513 Lsdb::addCoordinateLsa(CoordinateLsa& clsa)
514 {
515  std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
516  m_corLsdb.end(),
517  std::bind(corLsaCompareByKey, _1,
518  clsa.getKey()));
519  if (it == m_corLsdb.end()) {
520  m_corLsdb.push_back(clsa);
521  return true;
522  }
523  return false;
524 }
525 
526 bool
527 Lsdb::removeCoordinateLsa(const ndn::Name& key)
528 {
529  std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
530  m_corLsdb.end(),
531  std::bind(corLsaCompareByKey,
532  _1, key));
533  if (it != m_corLsdb.end()) {
534  NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
535  it->writeLog();
536 
537  if (it->getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
538  m_nlsr.getNamePrefixTable().removeEntry(it->getOrigRouter(), it->getOrigRouter());
539  }
540 
541  m_corLsdb.erase(it);
542  return true;
543  }
544  return false;
545 }
546 
547 bool
548 Lsdb::doesCoordinateLsaExist(const ndn::Name& key)
549 {
550  std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
551  m_corLsdb.end(),
552  std::bind(corLsaCompareByKey,
553  _1, key));
554  if (it == m_corLsdb.end()) {
555  return false;
556  }
557  return true;
558 }
559 
560 void
562 {
563  NLSR_LOG_DEBUG("---------------Cor LSDB-------------------");
564  for (std::list<CoordinateLsa>::iterator it = m_corLsdb.begin();
565  it != m_corLsdb.end() ; it++) {
566  (*it).writeLog();
567  }
568 }
569 
570 const std::list<CoordinateLsa>&
572 {
573  return m_corLsdb;
574 }
575 
576 // Adj LSA and LSDB related function starts here
577 
582 static bool
583 adjLsaCompareByKey(AdjLsa& alsa, const ndn::Name& key)
584 {
585  return alsa.getKey() == key;
586 }
587 
588 void
590 {
591  m_nlsr.incrementAdjBuildCount();
592 
594  // Don't build adjacency LSAs in hyperbolic routing
595  NLSR_LOG_DEBUG("Adjacency LSA not built. Currently in hyperbolic routing state.");
596  return;
597  }
598 
599  if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
600  NLSR_LOG_DEBUG("Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
601 
602  m_scheduler.scheduleEvent(m_adjLsaBuildInterval, std::bind(&Lsdb::buildAdjLsa, this));
603  m_nlsr.setIsBuildAdjLsaSheduled(true);
604  }
605 }
606 
607 void
608 Lsdb::buildAdjLsa()
609 {
610  NLSR_LOG_TRACE("Lsdb::buildAdjLsa called");
611 
612  m_nlsr.setIsBuildAdjLsaSheduled(false);
613 
615 
616  int adjBuildCount = m_nlsr.getAdjBuildCount();
617  // Only do the adjLsa build if there's one scheduled
618  if (adjBuildCount > 0) {
619  // It only makes sense to do the adjLsa build if we have neighbors
620  if (m_nlsr.getAdjacencyList().getNumOfActiveNeighbor() > 0) {
621  NLSR_LOG_DEBUG("Building and installing own Adj LSA");
623  }
624  // We have no active neighbors, meaning no one can route through
625  // us. So delete our entry in the LSDB. This prevents this
626  // router from refreshing the LSA, eventually causing other
627  // routers to delete it, too.
628  else {
629  NLSR_LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors");
630  // Get this router's key
631  ndn::Name key = m_nlsr.getConfParameter().getRouterPrefix();
632  key.append(std::to_string(Lsa::Type::ADJACENCY));
633 
634  removeAdjLsa(key);
635  // Recompute routing table after removal
637  }
638  // In the case that during building the adj LSA, the FIB has to
639  // wait on an Interest response, the number of scheduled adj LSA
640  // builds could change, so we shouldn't just set it to 0.
641  m_nlsr.setAdjBuildCount(m_nlsr.getAdjBuildCount() - adjBuildCount);
642  }
643  }
644  // We are still waiting to know the adjacency status of some
645  // neighbor, so schedule a build for later (when all that has
646  // hopefully finished)
647  else {
648  m_nlsr.setIsBuildAdjLsaSheduled(true);
649  int schedulingTime = m_nlsr.getConfParameter().getInterestRetryNumber() *
651  m_scheduler.scheduleEvent(ndn::time::seconds(schedulingTime),
652  std::bind(&Lsdb::buildAdjLsa, this));
653  }
654 }
655 
656 bool
657 Lsdb::addAdjLsa(AdjLsa& alsa)
658 {
659  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
660  m_adjLsdb.end(),
661  std::bind(adjLsaCompareByKey, _1,
662  alsa.getKey()));
663  if (it == m_adjLsdb.end()) {
664  m_adjLsdb.push_back(alsa);
665  return true;
666  }
667  return false;
668 }
669 
670 AdjLsa*
671 Lsdb::findAdjLsa(const ndn::Name& key)
672 {
673  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
674  m_adjLsdb.end(),
675  std::bind(adjLsaCompareByKey, _1, key));
676  if (it != m_adjLsdb.end()) {
677  return &(*it);
678  }
679  return 0;
680 }
681 
682 bool
683 Lsdb::isAdjLsaNew(const ndn::Name& key, uint64_t seqNo)
684 {
685  AdjLsa* adjLsaCheck = findAdjLsa(key);
686  // If it is in the LSDB
687  if (adjLsaCheck != 0) {
688  // And the supplied seq no is newer (higher) than the current one.
689  if (adjLsaCheck->getLsSeqNo() < seqNo) {
690  return true;
691  }
692  else {
693  return false;
694  }
695  }
696  return true;
697 }
698 
699 ndn::EventId
700 Lsdb::scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
701  const ndn::time::seconds& expTime)
702 {
703  return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
704  std::bind(&Lsdb::expireOrRefreshAdjLsa, this, key, seqNo));
705 }
706 
707 bool
709 {
710  ndn::time::seconds timeToExpire = m_lsaRefreshTime;
711  AdjLsa* chkAdjLsa = findAdjLsa(alsa.getKey());
712  // If this adj. LSA is not in the LSDB already
713  if (chkAdjLsa == 0) {
714  NLSR_LOG_DEBUG("New Adj LSA. Adding to LSDB");
715  NLSR_LOG_DEBUG("Adding Adj Lsa");
716  alsa.writeLog();
717  addAdjLsa(alsa);
718  // Add any new name prefixes to the NPT
719  alsa.addNptEntries(m_nlsr);
721  if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
722  ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
723  ndn::time::system_clock::now();
724  timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
725  }
726  scheduleAdjLsaExpiration(alsa.getKey(),
727  alsa.getLsSeqNo(), timeToExpire);
728  }
729  else {
730  if (chkAdjLsa->getLsSeqNo() < alsa.getLsSeqNo()) {
731  NLSR_LOG_DEBUG("Updated Adj LSA. Updating LSDB");
732  NLSR_LOG_DEBUG("Deleting Adj Lsa");
733  chkAdjLsa->writeLog();
734  chkAdjLsa->setLsSeqNo(alsa.getLsSeqNo());
736  // If the new adj LSA has new content, update the contents of
737  // the LSDB entry. Additionally, since we've changed the
738  // contents of the LSDB, we have to schedule a routing
739  // calculation.
740  if (!chkAdjLsa->isEqualContent(alsa)) {
741  chkAdjLsa->getAdl().reset();
742  chkAdjLsa->getAdl().addAdjacents(alsa.getAdl());
744  }
745  if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
746  ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
747  ndn::time::system_clock::now();
748  timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
749  }
750  cancelScheduleLsaExpiringEvent(chkAdjLsa->getExpiringEventId());
751  chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(alsa.getKey(),
752  alsa.getLsSeqNo(),
753  timeToExpire));
754  NLSR_LOG_DEBUG("Adding Adj Lsa");
755  chkAdjLsa->writeLog();
756  }
757  }
758  return true;
759 }
760 
761 bool
763 {
764  AdjLsa adjLsa(m_nlsr.getConfParameter().getRouterPrefix(),
765  m_sequencingManager.getAdjLsaSeq() + 1,
766  getLsaExpirationTimePoint(),
768  m_nlsr.getAdjacencyList());
769 
770  //Sync adjacency LSAs if link-state or dry-run HR is enabled.
772  m_sequencingManager.increaseAdjLsaSeq();
773  m_sequencingManager.writeSeqNoToFile();
774  m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
775  }
776 
777  return installAdjLsa(adjLsa);
778 }
779 
780 bool
781 Lsdb::removeAdjLsa(const ndn::Name& key)
782 {
783  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
784  m_adjLsdb.end(),
785  std::bind(adjLsaCompareByKey, _1, key));
786  if (it != m_adjLsdb.end()) {
787  NLSR_LOG_DEBUG("Deleting Adj Lsa");
788  (*it).writeLog();
789  (*it).removeNptEntries(m_nlsr);
790  m_adjLsdb.erase(it);
791  return true;
792  }
793  return false;
794 }
795 
796 bool
797 Lsdb::doesAdjLsaExist(const ndn::Name& key)
798 {
799  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
800  m_adjLsdb.end(),
801  std::bind(adjLsaCompareByKey, _1, key));
802  if (it == m_adjLsdb.end()) {
803  return false;
804  }
805  return true;
806 }
807 
808 const std::list<AdjLsa>&
810 {
811  return m_adjLsdb;
812 }
813 
814 void
815 Lsdb::setLsaRefreshTime(const ndn::time::seconds& lsaRefreshTime)
816 {
817  m_lsaRefreshTime = lsaRefreshTime;
818 }
819 
820 void
822 {
823  m_thisRouterPrefix = trp;
824 }
825 
826  // This function determines whether a name LSA should be refreshed
827  // or expired. The conditions for getting refreshed are: it is still
828  // in the LSDB, it hasn't been updated by something else already (as
829  // evidenced by its seq. no.), and this is the originating router for
830  // the LSA. Is it let expire in all other cases.
831  // lsaKey is the key of the LSA's publishing router.
832  // seqNo is the seq. no. of the candidate LSA.
833 void
834 Lsdb::expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo)
835 {
836  NLSR_LOG_DEBUG("Lsdb::expireOrRefreshNameLsa Called");
837  NLSR_LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
838  NameLsa* chkNameLsa = findNameLsa(lsaKey);
839  // If this name LSA exists in the LSDB
840  if (chkNameLsa != 0) {
841  NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getLsSeqNo());
842  // If its seq no is the one we are expecting.
843  if (chkNameLsa->getLsSeqNo() == seqNo) {
844  if (chkNameLsa->getOrigRouter() == m_thisRouterPrefix) {
845  NLSR_LOG_DEBUG("Own Name LSA, so refreshing it");
846  NLSR_LOG_DEBUG("Deleting Name Lsa");
847  chkNameLsa->writeLog();
848  chkNameLsa->setLsSeqNo(chkNameLsa->getLsSeqNo() + 1);
849  m_sequencingManager.setNameLsaSeq(chkNameLsa->getLsSeqNo());
850  chkNameLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
851  NLSR_LOG_DEBUG("Adding Name Lsa");
852  chkNameLsa->writeLog();
853  // schedule refreshing event again
854  chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(chkNameLsa->getKey(),
855  chkNameLsa->getLsSeqNo(),
856  m_lsaRefreshTime));
857  m_sequencingManager.writeSeqNoToFile();
858  m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
859  }
860  // Since we cannot refresh other router's LSAs, our only choice is to expire.
861  else {
862  NLSR_LOG_DEBUG("Other's Name LSA, so removing from LSDB");
863  removeNameLsa(lsaKey);
864  }
865  }
866  }
867 }
868 
869  // This function determines whether an adj. LSA should be refreshed
870  // or expired. The conditions for getting refreshed are: it is still
871  // in the LSDB, it hasn't been updated by something else already (as
872  // evidenced by its seq. no.), and this is the originating router for
873  // the LSA. Is it let expire in all other cases.
874  // lsaKey is the key of the LSA's publishing router.
875  // seqNo is the seq. no. of the candidate LSA.
876 void
877 Lsdb::expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo)
878 {
879  NLSR_LOG_DEBUG("Lsdb::expireOrRefreshAdjLsa Called");
880  NLSR_LOG_DEBUG("LSA Key: " << lsaKey << " Seq No: " << seqNo);
881  AdjLsa* chkAdjLsa = findAdjLsa(lsaKey);
882  // If this is a valid LSA
883  if (chkAdjLsa != 0) {
884  NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getLsSeqNo());
885  // And if it hasn't been updated for some other reason
886  if (chkAdjLsa->getLsSeqNo() == seqNo) {
887  // If it is our own LSA
888  if (chkAdjLsa->getOrigRouter() == m_thisRouterPrefix) {
889  NLSR_LOG_DEBUG("Own Adj LSA, so refreshing it");
890  NLSR_LOG_DEBUG("Deleting Adj Lsa");
891  chkAdjLsa->writeLog();
892  chkAdjLsa->setLsSeqNo(chkAdjLsa->getLsSeqNo() + 1);
893  m_sequencingManager.setAdjLsaSeq(chkAdjLsa->getLsSeqNo());
894  chkAdjLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
895  NLSR_LOG_DEBUG("Adding Adj Lsa");
896  chkAdjLsa->writeLog();
897  // schedule refreshing event again
898  chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(chkAdjLsa->getKey(),
899  chkAdjLsa->getLsSeqNo(),
900  m_lsaRefreshTime));
901  m_sequencingManager.writeSeqNoToFile();
902  m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
903  }
904  // An LSA from another router is expiring
905  else {
906  NLSR_LOG_DEBUG("Other's Adj LSA, so removing from LSDB");
907  removeAdjLsa(lsaKey);
908  }
909  // We have changed the contents of the LSDB, so we have to
910  // schedule a routing calculation
912  }
913  }
914 }
915 
916  // This function determines whether an adj. LSA should be refreshed
917  // or expired. The conditions for getting refreshed are: it is still
918  // in the LSDB, it hasn't been updated by something else already (as
919  // evidenced by its seq. no.), and this is the originating router for
920  // the LSA. It is let expire in all other cases.
921  // lsaKey is the key of the LSA's publishing router.
922  // seqNo is the seq. no. of the candidate LSA.
923 void
924 Lsdb::expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
925  uint64_t seqNo)
926 {
927  NLSR_LOG_DEBUG("Lsdb::expireOrRefreshCorLsa Called ");
928  NLSR_LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
929  CoordinateLsa* chkCorLsa = findCoordinateLsa(lsaKey);
930  // Whether the LSA is in the LSDB or not.
931  if (chkCorLsa != 0) {
932  NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getLsSeqNo());
933  // Whether the LSA has been updated without our knowledge.
934  if (chkCorLsa->getLsSeqNo() == seqNo) {
935  if (chkCorLsa->getOrigRouter() == m_thisRouterPrefix) {
936  NLSR_LOG_DEBUG("Own Cor LSA, so refreshing it");
937  NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
938  chkCorLsa->writeLog();
939  chkCorLsa->setLsSeqNo(chkCorLsa->getLsSeqNo() + 1);
941  m_sequencingManager.setCorLsaSeq(chkCorLsa->getLsSeqNo());
942  }
943 
944  chkCorLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
945  NLSR_LOG_DEBUG("Adding Coordinate Lsa");
946  chkCorLsa->writeLog();
947  // schedule refreshing event again
948  chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(
949  chkCorLsa->getKey(),
950  chkCorLsa->getLsSeqNo(),
951  m_lsaRefreshTime));
952  // Only sync coordinate LSAs if link-state routing is disabled
954  m_sequencingManager.writeSeqNoToFile();
955  m_sync.publishRoutingUpdate(Lsa::Type::COORDINATE, m_sequencingManager.getCorLsaSeq());
956  }
957  }
958  // We can't refresh other router's LSAs, so we remove it.
959  else {
960  NLSR_LOG_DEBUG("Other's Cor LSA, so removing from LSDB");
961  removeCoordinateLsa(lsaKey);
962  }
965  }
966  }
967  }
968 }
969 
970 void
971 Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
972  ndn::time::steady_clock::TimePoint deadline)
973 {
974  // increment SENT_LSA_INTEREST
976 
977  if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
978  deadline = ndn::time::steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
979  }
980  // The first component of the interest is the name.
981  ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
982  // The seq no is the last
983  uint64_t seqNo = interestName[-1].toNumber();
984 
985  // If the LSA is not found in the list currently.
986  if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
987  m_highestSeqNo[lsaName] = seqNo;
988  }
989  // If the new seq no is higher, that means the LSA is valid
990  else if (seqNo > m_highestSeqNo[lsaName]) {
991  m_highestSeqNo[lsaName] = seqNo;
992  }
993  // Otherwise, its an old/invalid LSA
994  else if (seqNo < m_highestSeqNo[lsaName]) {
995  return;
996  }
997 
998  ndn::Interest interest(interestName);
999  interest.setInterestLifetime(m_nlsr.getConfParameter().getLsaInterestLifetime());
1000 
1001  NLSR_LOG_DEBUG("Fetching Data for LSA: " << interestName << " Seq number: " << seqNo);
1002  ndn::util::SegmentFetcher::fetch(m_nlsr.getNlsrFace(), interest,
1003  m_nlsr.getValidator(),
1004  std::bind(&Lsdb::afterFetchLsa, this, _1, interestName),
1005  std::bind(&Lsdb::onFetchLsaError, this, _1, _2, interestName,
1006  timeoutCount, deadline, lsaName, seqNo));
1007  // increment a specific SENT_LSA_INTEREST
1008  Lsa::Type lsaType;
1009  std::istringstream(interestName[-2].toUri()) >> lsaType;
1010  switch (lsaType) {
1011  case Lsa::Type::ADJACENCY:
1013  break;
1014  case Lsa::Type::COORDINATE:
1016  break;
1017  case Lsa::Type::NAME:
1019  break;
1020  default:
1021  NLSR_LOG_ERROR("lsaType " << lsaType << " not recognized; failed Statistics::PacketType conversion");
1022  }
1023 }
1024 
1025 void
1026 Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
1027 {
1028  // increment RCV_LSA_INTEREST
1030 
1031  const ndn::Name& interestName(interest.getName());
1032  NLSR_LOG_DEBUG("Interest received for LSA: " << interestName);
1033 
1034  std::string chkString("LSA");
1035  int32_t lsaPosition = util::getNameComponentPosition(interest.getName(), chkString);
1036 
1037  if (lsaPosition >= 0) {
1038 
1039  // Forms the name of the router that the Interest packet came from.
1040  ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
1041  originRouter.append(interestName.getSubName(lsaPosition + 1,
1042  interest.getName().size() - lsaPosition - 3));
1043 
1044  uint64_t seqNo = interestName[-1].toNumber();
1045  NLSR_LOG_DEBUG("LSA sequence number from interest: " << seqNo);
1046 
1047  Lsa::Type interestedLsType;
1048  std::istringstream(interestName[-2].toUri()) >> interestedLsType;
1049 
1050  if (interestedLsType == Lsa::Type::NAME) {
1051  processInterestForNameLsa(interest, originRouter.append(std::to_string(interestedLsType)),
1052  seqNo);
1053  }
1054  else if (interestedLsType == Lsa::Type::ADJACENCY) {
1055  processInterestForAdjacencyLsa(interest, originRouter.append(std::to_string(interestedLsType)),
1056  seqNo);
1057  }
1058  else if (interestedLsType == Lsa::Type::COORDINATE) {
1059  processInterestForCoordinateLsa(interest, originRouter.append(std::to_string(interestedLsType)),
1060  seqNo);
1061  }
1062  else {
1063  NLSR_LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
1064  }
1066  }
1067 }
1068 
1069  // \brief Sends LSA data.
1070  // \param interest The Interest that warranted the data.
1071  // \param content The data that the Interest was seeking.
1072 void
1073 Lsdb::putLsaData(const ndn::Interest& interest, const std::string& content)
1074 {
1075  LsaContentPublisher publisher(m_nlsr.getNlsrFace(),
1076  m_nlsr.getKeyChain(),
1077  m_nlsr.getSigningInfo(),
1078  m_lsaRefreshTime,
1079  content);
1080  NLSR_LOG_DEBUG("Sending requested data ( " << content << ") for interest (" << interest
1081  << ") to be published and added to face.");
1082  publisher.publish(interest.getName());
1083 }
1084 
1085  // \brief Finds and sends a requested name LSA.
1086  // \param interest The interest that seeks the name LSA.
1087  // \param lsaKey The LSA that the Interest is seeking.
1088  // \param seqNo A sequence number to ensure that we are sending the
1089  // version that was requested.
1090 void
1091 Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
1092  const ndn::Name& lsaKey,
1093  uint64_t seqNo)
1094 {
1095  // increment RCV_NAME_LSA_INTEREST
1097  NLSR_LOG_DEBUG("nameLsa interest " << interest << " received");
1098  NameLsa* nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
1099  if (nameLsa != 0) {
1100  if (nameLsa->getLsSeqNo() == seqNo) {
1101  std::string content = nameLsa->serialize();
1102  putLsaData(interest,content);
1103  // increment SENT_NAME_LSA_DATA
1105  }
1106  else {
1107  NLSR_LOG_TRACE("SeqNo for nameLsa does not match");
1108  }
1109  }
1110  else {
1111  NLSR_LOG_TRACE(interest << " was not found in this lsdb");
1112  }
1113 }
1114 
1115  // \brief Finds and sends a requested adj. LSA.
1116  // \param interest The interest that seeks the adj. LSA.
1117  // \param lsaKey The LSA that the Interest is seeking.
1118  // \param seqNo A sequence number to ensure that we are sending the
1119  // version that was requested.
1120 void
1121 Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
1122  const ndn::Name& lsaKey,
1123  uint64_t seqNo)
1124 {
1126  NLSR_LOG_ERROR("Received interest for an adjacency LSA when hyperbolic routing is enabled");
1127  }
1128 
1129  // increment RCV_ADJ_LSA_INTEREST
1131  NLSR_LOG_DEBUG("AdjLsa interest " << interest << " received");
1132  AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
1133  if (adjLsa != 0) {
1134  if (adjLsa->getLsSeqNo() == seqNo) {
1135  std::string content = adjLsa->serialize();
1136  putLsaData(interest,content);
1137  // increment SENT_ADJ_LSA_DATA
1139  }
1140  else {
1141  NLSR_LOG_TRACE("SeqNo for AdjLsa does not match");
1142  }
1143  }
1144  else {
1145  NLSR_LOG_TRACE(interest << " was not found in this lsdb");
1146  }
1147 }
1148 
1149  // \brief Finds and sends a requested cor. LSA.
1150  // \param interest The interest that seeks the cor. LSA.
1151  // \param lsaKey The LSA that the Interest is seeking.
1152  // \param seqNo A sequence number to ensure that we are sending the
1153  // version that was requested.
1154 void
1155 Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
1156  const ndn::Name& lsaKey,
1157  uint64_t seqNo)
1158 {
1160  NLSR_LOG_ERROR("Received Interest for a coordinate LSA when link-state routing is enabled");
1161  }
1162 
1163  // increment RCV_COORD_LSA_INTEREST
1165  NLSR_LOG_DEBUG("CoordinateLsa interest " << interest << " received");
1166  CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
1167  if (corLsa != 0) {
1168  if (corLsa->getLsSeqNo() == seqNo) {
1169  std::string content = corLsa->serialize();
1170  putLsaData(interest,content);
1171  // increment SENT_COORD_LSA_DATA
1173  }
1174  else {
1175  NLSR_LOG_TRACE("SeqNo for CoordinateLsa does not match");
1176  }
1177  }
1178  else {
1179  NLSR_LOG_TRACE(interest << " was not found in this lsdb");
1180  }
1181 }
1182 
1183 void
1184 Lsdb::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
1185 {
1186  const ndn::Name& dataName = data->getName();
1187  NLSR_LOG_DEBUG("Data validation successful for LSA: " << dataName);
1188 
1189  std::string chkString("LSA");
1190  int32_t lsaPosition = util::getNameComponentPosition(dataName, chkString);
1191 
1192  if (lsaPosition >= 0) {
1193 
1194  // Extracts the prefix of the originating router from the data.
1195  ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
1196  originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
1197 
1198  uint64_t seqNo = dataName[-1].toNumber();
1199  std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()),
1200  data->getContent().value_size());
1201 
1202  Lsa::Type interestedLsType;
1203  std::istringstream(dataName[-2].toUri()) >> interestedLsType;
1204 
1205  if (interestedLsType == Lsa::Type::NAME) {
1206  processContentNameLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1207  dataContent);
1208  }
1209  else if (interestedLsType == Lsa::Type::ADJACENCY) {
1210  processContentAdjacencyLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1211  dataContent);
1212  }
1213  else if (interestedLsType == Lsa::Type::COORDINATE) {
1214  processContentCoordinateLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1215  dataContent);
1216  }
1217  else {
1218  NLSR_LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
1219  }
1220 
1221  // increment RCV_LSA_DATA
1223  }
1224 }
1225 
1226 void
1227 Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
1228  uint64_t lsSeqNo, std::string& dataContent)
1229 {
1230  // increment RCV_NAME_LSA_DATA
1232  if (isNameLsaNew(lsaKey, lsSeqNo)) {
1233  NameLsa nameLsa;
1234  if (nameLsa.deserialize(dataContent)) {
1235  installNameLsa(nameLsa);
1236  }
1237  else {
1238  NLSR_LOG_DEBUG("LSA data decoding error :(");
1239  }
1240  }
1241 }
1242 
1243 void
1244 Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
1245  uint64_t lsSeqNo, std::string& dataContent)
1246 {
1247  // increment RCV_ADJ_LSA_DATA
1249  if (isAdjLsaNew(lsaKey, lsSeqNo)) {
1250  AdjLsa adjLsa;
1251  if (adjLsa.deserialize(dataContent)) {
1252  installAdjLsa(adjLsa);
1253  }
1254  else {
1255  NLSR_LOG_DEBUG("LSA data decoding error :(");
1256  }
1257  }
1258 }
1259 
1260 void
1261 Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
1262  uint64_t lsSeqNo, std::string& dataContent)
1263 {
1264  // increment RCV_COORD_LSA_DATA
1266  if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
1267  CoordinateLsa corLsa;
1268  if (corLsa.deserialize(dataContent)) {
1269  installCoordinateLsa(corLsa);
1270  }
1271  else {
1272  NLSR_LOG_DEBUG("LSA data decoding error :(");
1273  }
1274  }
1275 }
1276 
1277 ndn::time::system_clock::TimePoint
1278 Lsdb::getLsaExpirationTimePoint()
1279 {
1280  ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
1281  expirationTimePoint = expirationTimePoint +
1282  ndn::time::seconds(m_nlsr.getConfParameter().getRouterDeadInterval());
1283  return expirationTimePoint;
1284 }
1285 
1286 void
1288 {
1289  NLSR_LOG_DEBUG("---------------Adj LSDB-------------------");
1290  for (std::list<AdjLsa>::iterator it = m_adjLsdb.begin();
1291  it != m_adjLsdb.end() ; it++) {
1292  (*it).writeLog();
1293  }
1294 }
1295 
1296 //-----utility function -----
1297 bool
1298 Lsdb::doesLsaExist(const ndn::Name& key, const Lsa::Type& lsType)
1299 {
1300  switch (lsType) {
1301  case Lsa::Type::ADJACENCY:
1302  return doesAdjLsaExist(key);
1303  case Lsa::Type::COORDINATE:
1304  return doesCoordinateLsaExist(key);
1305  case Lsa::Type::NAME:
1306  return doesNameLsaExist(key);
1307  default:
1308  return false;
1309  }
1310 }
1311 
1312 bool
1313 Lsdb::isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType,
1314  const uint64_t& sequenceNumber) {
1315  ndn::Name lsaKey = routerName;
1316  lsaKey.append(std::to_string(lsaType));
1317 
1318  switch (lsaType) {
1319  case Lsa::Type::ADJACENCY:
1320  return isAdjLsaNew(lsaKey, sequenceNumber);
1321  case Lsa::Type::COORDINATE:
1322  return isCoordinateLsaNew(lsaKey, sequenceNumber);
1323  case Lsa::Type::NAME:
1324  return isNameLsaNew(lsaKey, sequenceNumber);
1325  default:
1326  return false;
1327  }
1328 }
1329 
1330 } // namespace nlsr
bool installAdjLsa(AdjLsa &alsa)
Installs an adj. LSA into the LSDB.
Definition: lsdb.cpp:708
const std::list< NameLsa > & getNameLsdb() const
Definition: lsdb.cpp:370
uint32_t getInterestResendTime() const
#define NLSR_LOG_WARN(x)
Definition: logger.hpp:47
void setAdjLsaSeq(uint64_t alsn)
bool getIsBuildAdjLsaSheduled()
Definition: nlsr.hpp:199
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
Definition: tlv-nlsr.hpp:27
void scheduleAdjLsaBuild()
Schedules a build of this router&#39;s LSA.
Definition: lsdb.cpp:589
bool removeNameLsa(const ndn::Name &key)
Remove a name LSA from the LSDB.
Definition: lsdb.cpp:321
void writeNameLsdbLog()
Definition: lsdb.cpp:360
ConfParameter & getConfParameter()
Definition: nlsr.hpp:133
double getCorR() const
static bool corLsaCompareByKey(const CoordinateLsa &clsa, const ndn::Name &key)
Compares whether an LSA object is the same as a key.
Definition: lsdb.cpp:382
const ndn::time::system_clock::TimePoint & getExpirationTimePoint() const
Definition: lsa.hpp:88
std::string serialize() const override
Returns the data this adjacency LSA has.
Definition: lsa.cpp:222
std::list< ndn::Name > getNames() const
Lsdb(Nlsr &nlsr, ndn::Scheduler &scheduler)
Definition: lsdb.cpp:66
bool isLsaNew(const ndn::Name &routerName, const Lsa::Type &lsaType, const uint64_t &sequenceNumber)
Definition: lsdb.cpp:1313
AdjacencyList & getAdl()
Definition: lsa.hpp:252
void setLsSeqNo(uint32_t lsn)
Definition: lsa.hpp:64
uint64_t getCorLsaSeq() const
void writeAdjLsdbLog()
Definition: lsdb.cpp:1287
bool deserialize(const std::string &content) noexceptoverride
Initializes this LSA object with content&#39;s data.
Definition: lsa.cpp:93
void writeLog() const override
Definition: lsa.cpp:284
NamePrefixTable & getNamePrefixTable()
Definition: nlsr.hpp:169
std::unique_ptr< OnNewLsa > onNewLsa
static bool nameLsaCompareByKey(const NameLsa &nlsa1, const ndn::Name &key)
Compares if a name LSA is the same as the one specified by key.
Definition: lsdb.cpp:155
NamePrefixList & getNpl()
Definition: lsa.hpp:176
bool isEqualContent(AdjLsa &alsa)
Definition: lsa.cpp:216
uint64_t getAdjLsaSeq() const
ndn::EventId getExpiringEventId() const
Definition: lsa.hpp:106
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:41
const ndn::Name & getRouterPrefix() const
void incrementAdjBuildCount()
Definition: nlsr.hpp:187
uint64_t getNameLsaSeq() const
void writeLog() const override
Definition: lsa.cpp:194
bool deserialize(const std::string &content) noexceptoverride
Initializes this adj. LSA from the supplied content.
Definition: lsa.cpp:235
void writeCorLsdbLog()
Definition: lsdb.cpp:561
RoutingTable & getRoutingTable()
Definition: nlsr.hpp:163
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California.
bool isAdjLsaBuildable(const uint32_t interestRetryNo) const
Determines whether this list can be used to build an adj. LSA.
void setExpirationTimePoint(const ndn::time::system_clock::TimePoint &lt)
Definition: lsa.hpp:94
virtual size_t generate(ndn::EncodingBuffer &outBuffer)
In a derived class, write the octets into outBuffer.
Definition: lsdb.cpp:50
const ndn::time::seconds & getLsaInterestLifetime() const
#define INIT_LOGGER(name)
Definition: logger.hpp:35
void removeEntry(const ndn::Name &name, const ndn::Name &destRouter)
Removes a destination from a name prefix table entry.
const std::list< CoordinateLsa > & getCoordinateLsdb() const
Definition: lsdb.cpp:571
const ndn::Name & getOrigRouter() const
Definition: lsa.hpp:76
LsaContentPublisher(ndn::Face &face, ndn::KeyChain &keyChain, const ndn::security::SigningInfo &signingInfo, const ndn::time::milliseconds &freshnessPeriod, const std::string &content)
Definition: lsdb.cpp:39
uint32_t getInterestRetryNumber() const
AdjacencyList & getAdjacencyList()
Definition: nlsr.hpp:139
bool isCoordinateLsaNew(const ndn::Name &key, uint64_t seqNo)
Returns whether a cor. LSA from a router is new or not.
Definition: lsdb.cpp:421
uint32_t getLsSeqNo() const
Definition: lsa.hpp:70
std::vector< double > getCorTheta() const
void writeLog() const override
Definition: lsa.cpp:124
CoordinateLsa * findCoordinateLsa(const ndn::Name &key)
Finds a cor. LSA in the LSDB.
Definition: lsdb.cpp:409
void setAdjBuildCount(int64_t abc)
Definition: nlsr.hpp:193
void setLsaRefreshTime(const ndn::time::seconds &lsaRefreshTime)
Definition: lsdb.cpp:815
bool isNameLsaNew(const ndn::Name &key, uint64_t seqNo)
Definition: lsdb.cpp:188
void scheduleRoutingTableCalculation(Nlsr &pnlsr)
Schedules a calculation event in the event scheduler only if one isn&#39;t already scheduled.
ndn::security::v2::KeyChain & getKeyChain()
Definition: nlsr.hpp:329
bool installCoordinateLsa(CoordinateLsa &clsa)
Installs a cor. LSA into the LSDB.
Definition: lsdb.cpp:451
NameLsa * findNameLsa(const ndn::Name &key)
Returns the name LSA with the given key.
Definition: lsdb.cpp:176
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Definition: lsdb.cpp:1026
void expressInterest(const ndn::Name &interestName, uint32_t timeoutCount, ndn::time::steady_clock::TimePoint deadline=DEFAULT_LSA_RETRIEVAL_DEADLINE)
Definition: lsdb.cpp:971
bool doesLsaExist(const ndn::Name &key, const Lsa::Type &lsType)
Definition: lsdb.cpp:1298
int32_t getNumOfActiveNeighbor()
void setIsBuildAdjLsaSheduled(bool iabls)
Definition: nlsr.hpp:205
static int32_t getNameComponentPosition(const ndn::Name &name, const std::string &searchString)
search a name component in ndn::Name and return the position of the component
Definition: name-helper.hpp:44
std::string serialize() const override
Returns the data that this name LSA has.
Definition: lsa.cpp:81
bool isAdjLsaNew(const ndn::Name &key, uint64_t seqNo)
Returns whether an LSA is new.
Definition: lsdb.cpp:683
bool removeAdjLsa(const ndn::Name &key)
Removes an adj. LSA from the LSDB.
Definition: lsdb.cpp:781
void setNameLsaSeq(uint64_t nlsn)
void setExpiringEventId(const ndn::EventId leei)
Definition: lsa.hpp:100
bool isEqualContent(const CoordinateLsa &clsa)
Definition: lsa.cpp:141
void setCorTheta(std::vector< double > ct)
Definition: lsa.hpp:378
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:50
static const ndn::Name::Component NAME_COMPONENT
Definition: lsdb.hpp:376
void removeName(const ndn::Name &name)
Definition: lsa.hpp:194
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
NamePrefixList & getNamePrefixList()
Definition: nlsr.hpp:145
Lsdb & getLsdb()
Definition: nlsr.hpp:157
ndn::util::signal::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
Definition: lsdb.hpp:378
void setThisRouterPrefix(std::string trp)
Definition: lsdb.cpp:821
bool installNameLsa(NameLsa &nlsa)
Installs a name LSA into the LSDB.
Definition: lsdb.cpp:213
void setCorRadius(double cr)
Definition: lsa.hpp:366
const std::vector< double > getCorTheta() const
Definition: lsa.hpp:372
void addNptEntries(Nlsr &pnlsr)
Installs this LSA&#39;s name prefixes into the NPT.
Definition: lsa.cpp:264
const ndn::Name & getNetwork() const
long int getAdjBuildCount()
Definition: nlsr.hpp:181
ndn::Face & getNlsrFace()
Definition: nlsr.hpp:151
static bool adjLsaCompareByKey(AdjLsa &alsa, const ndn::Name &key)
Returns whether an adj. LSA object is from some router.
Definition: lsdb.cpp:583
void setCorLsaSeq(uint64_t clsn)
const ndn::Name getKey() const
Gets the key for this LSA.
Definition: lsa.cpp:50
bool buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
Definition: lsdb.cpp:161
bool buildAndInstallOwnCoordinateLsa()
Builds a cor. LSA for this router and installs it into the LSDB.
Definition: lsdb.cpp:388
void addName(const ndn::Name &name)
Definition: lsa.hpp:188
int32_t getHyperbolicState() const
bool deserialize(const std::string &content) noexceptoverride
Initializes this coordinate LSA with the data in content.
Definition: lsa.cpp:170
void addAdjacents(AdjacencyList &adl)
Copies the adjacencies in a list to this one.
std::string serialize() const override
Returns the data that this coordinate LSA represents.
Definition: lsa.cpp:159
const ndn::security::SigningInfo & getSigningInfo()
Definition: nlsr.hpp:341
provides a publisher of Status Dataset or other segmented octet stream
ndn::security::ValidatorConfig & getValidator()
Definition: nlsr.hpp:306
const std::list< AdjLsa > & getAdjLsdb() const
Definition: lsdb.cpp:809
AdjLsa * findAdjLsa(const ndn::Name &key)
Finds an adj. LSA in the LSDB.
Definition: lsdb.cpp:671
uint32_t getRouterDeadInterval() const
bool buildAndInstallOwnAdjLsa()
Wrapper event to build and install an adj. LSA for this router.
Definition: lsdb.cpp:762
bool removeCoordinateLsa(const ndn::Name &key)
Removes a cor. LSA from the LSDB.
Definition: lsdb.cpp:527
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:38
void publishRoutingUpdate(const Lsa::Type &type, const uint64_t &seqNo)
Instruct ChronoSync to publish an update.
double getCorRadius() const
Definition: lsa.hpp:360
void addEntry(const ndn::Name &name, const ndn::Name &destRouter)
Adds a destination to the specified name prefix.