28 #include <ndn-cxx/security/signing-helpers.hpp> 35 const ndn::time::seconds Lsdb::GRACE_PERIOD = ndn::time::seconds(10);
36 const ndn::time::steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE =
37 ndn::time::steady_clock::TimePoint::min();
42 , m_scheduler(face.getIoService())
43 , m_confParam(confParam)
44 , m_namePrefixTable(namePrefixTable)
45 , m_routingTable(routingTable)
47 [this] (const
ndn::Name& routerName, const
Lsa::Type& lsaType,
48 const uint64_t& sequenceNumber) {
49 return isLsaNew(routerName, lsaType, sequenceNumber);
55 , m_onNewLsaConnection(m_sync.
onNewLsa->connect(
56 [
this] (
const ndn::Name& updateName, uint64_t sequenceNumber,
57 const ndn::Name& originRouter) {
58 ndn::Name lsaInterest{updateName};
59 lsaInterest.appendNumber(sequenceNumber);
62 , m_segmentPublisher(m_face, keyChain)
63 , m_isBuildAdjLsaSheduled(
false)
70 for (
const auto& sp : m_fetchers) {
76 Lsdb::onFetchLsaError(uint32_t errorCode,
77 const std::string& msg,
78 const ndn::Name& interestName,
79 uint32_t retransmitNo,
80 const ndn::time::steady_clock::TimePoint& deadline,
84 NLSR_LOG_DEBUG(
"Failed to fetch LSA: " << lsaName <<
", Error code: " << errorCode
85 <<
", Message: " << msg);
87 if (ndn::time::steady_clock::now() < deadline) {
88 auto it = m_highestSeqNo.find(lsaName);
89 if (it != m_highestSeqNo.end() && it->second == seqNo) {
96 if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
97 delay = ndn::time::seconds(0);
101 interestName, retransmitNo + 1, deadline));
107 Lsdb::afterFetchLsa(
const ndn::ConstBufferPtr& bufferPtr,
const ndn::Name& interestName)
109 auto data = std::make_shared<ndn::Data>(ndn::Name(interestName));
111 data->setContent(ndn::Block(bufferPtr));
113 catch (
const std::exception& e) {
114 NDN_LOG_ERROR(
"LSA content not recognized: " << e.what());
118 NLSR_LOG_DEBUG(
"Received data for LSA(name): " << data->getName());
120 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
121 uint64_t seqNo = interestName[-1].toNumber();
123 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
124 m_highestSeqNo[lsaName] = seqNo;
126 else if (seqNo > m_highestSeqNo[lsaName]) {
127 m_highestSeqNo[lsaName] = seqNo;
128 NLSR_LOG_TRACE(
"SeqNo for LSA(name): " << data->getName() <<
" updated");
130 else if (seqNo < m_highestSeqNo[lsaName]) {
134 onContentValidated(data);
145 return nlsa1.
getKey() == key;
153 getLsaExpirationTimePoint(),
166 auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
168 if (it != m_nameLsdb.end()) {
179 if (nameLsaCheck !=
nullptr) {
191 ndn::scheduler::EventId
192 Lsdb::scheduleNameLsaExpiration(
const ndn::Name& key,
int seqNo,
193 const ndn::time::seconds& expTime)
195 return m_scheduler.schedule(expTime + GRACE_PERIOD,
196 std::bind(&Lsdb::expireOrRefreshNameLsa,
this, key, seqNo));
203 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
206 if (chkNameLsa ==
nullptr) {
226 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
250 std::list<ndn::Name> namesToAdd;
251 std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
252 std::inserter(namesToAdd, namesToAdd.begin()));
253 for (
const auto& name : namesToAdd) {
265 std::list<ndn::Name> namesToRemove;
266 std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
267 std::inserter(namesToRemove, namesToRemove.begin()));
268 for (
const auto& name : namesToRemove) {
269 NLSR_LOG_DEBUG(
"Removing name LSA no longer advertised: " << name);
280 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
294 Lsdb::addNameLsa(
NameLsa& nlsa)
296 auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
298 if (it == m_nameLsdb.end()) {
299 m_nameLsdb.push_back(nlsa);
308 auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
310 if (it != m_nameLsdb.end()) {
316 m_namePrefixTable.
removeEntry(it->getOrigRouter(), it->getOrigRouter());
318 for (
const auto& name : it->getNpl().getNames()) {
320 m_namePrefixTable.
removeEntry(name, it->getOrigRouter());
324 m_nameLsdb.erase(it);
331 Lsdb::doesNameLsaExist(
const ndn::Name& key)
333 auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
335 return it != m_nameLsdb.end();
342 for (
const auto& nlsa : m_nameLsdb) {
347 const std::list<NameLsa>&
362 return clsa.
getKey() == key;
370 getLsaExpirationTimePoint(),
389 auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
391 if (it != m_corLsdb.end()) {
402 if (clsa !=
nullptr) {
418 ndn::scheduler::EventId
419 Lsdb::scheduleCoordinateLsaExpiration(
const ndn::Name& key,
int seqNo,
420 const ndn::time::seconds& expTime)
422 return m_scheduler.schedule(expTime + GRACE_PERIOD,
423 std::bind(&Lsdb::expireOrRefreshCoordinateLsa,
this, key, seqNo));
429 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
432 if (chkCorLsa ==
nullptr) {
436 addCoordinateLsa(clsa);
449 ndn::time::system_clock::now();
450 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
452 scheduleCoordinateLsaExpiration(clsa.
getKey(),
474 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
490 auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
492 if (it == m_corLsdb.end()) {
493 m_corLsdb.push_back(clsa);
502 auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
505 if (it != m_corLsdb.end()) {
510 m_namePrefixTable.
removeEntry(it->getOrigRouter(), it->getOrigRouter());
520 Lsdb::doesCoordinateLsaExist(
const ndn::Name& key)
522 auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
524 return it != m_corLsdb.end();
535 for (
const auto& corLsa : m_corLsdb) {
540 const std::list<CoordinateLsa>&
555 return alsa.
getKey() == key;
565 NLSR_LOG_DEBUG(
"Adjacency LSA not built. Currently in hyperbolic routing state.");
569 if (m_isBuildAdjLsaSheduled) {
570 NLSR_LOG_DEBUG(
"Rescheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
573 NLSR_LOG_DEBUG(
"Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
574 m_isBuildAdjLsaSheduled =
true;
576 m_scheduledAdjLsaBuild = m_scheduler.schedule(m_adjLsaBuildInterval, [
this] { buildAdjLsa(); });
584 m_isBuildAdjLsaSheduled =
false;
588 int adjBuildCount = m_adjBuildCount;
590 if (adjBuildCount > 0) {
613 m_adjBuildCount = m_adjBuildCount - adjBuildCount;
620 m_isBuildAdjLsaSheduled =
true;
623 m_scheduledAdjLsaBuild = m_scheduler.schedule(schedulingTime, [
this] { buildAdjLsa(); });
628 Lsdb::addAdjLsa(
AdjLsa& alsa)
630 auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
632 if (it == m_adjLsdb.end()) {
633 m_adjLsdb.push_back(alsa);
649 auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
651 if (it != m_adjLsdb.end()) {
662 if (adjLsaCheck !=
nullptr) {
674 ndn::scheduler::EventId
675 Lsdb::scheduleAdjLsaExpiration(
const ndn::Name& key,
int seqNo,
676 const ndn::time::seconds& expTime)
678 return m_scheduler.schedule(expTime + GRACE_PERIOD,
679 std::bind(&Lsdb::expireOrRefreshAdjLsa,
this, key, seqNo));
685 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
688 if (chkAdjLsa ==
nullptr) {
697 ndn::time::system_clock::now();
698 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
720 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
738 getLsaExpirationTimePoint(),
755 auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
757 if (it != m_adjLsdb.end()) {
761 m_namePrefixTable.
removeEntry(it->getOrigRouter(), it->getOrigRouter());
770 Lsdb::doesAdjLsaExist(
const ndn::Name& key)
772 auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
774 return it != m_adjLsdb.end();
777 const std::list<AdjLsa>&
791 Lsdb::expireOrRefreshNameLsa(
const ndn::Name& lsaKey, uint64_t seqNo)
797 if (chkNameLsa !=
nullptr) {
834 Lsdb::expireOrRefreshAdjLsa(
const ndn::Name& lsaKey, uint64_t seqNo)
840 if (chkAdjLsa !=
nullptr) {
881 Lsdb::expireOrRefreshCoordinateLsa(
const ndn::Name& lsaKey,
888 if (chkCorLsa !=
nullptr) {
929 ndn::time::steady_clock::TimePoint deadline)
934 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
935 deadline = ndn::time::steady_clock::now() + ndn::time::seconds(static_cast<int>(
LSA_REFRESH_TIME_MAX));
938 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
940 uint64_t seqNo = interestName[-1].toNumber();
943 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
944 m_highestSeqNo[lsaName] = seqNo;
947 else if (seqNo > m_highestSeqNo[lsaName]) {
948 m_highestSeqNo[lsaName] = seqNo;
951 else if (seqNo < m_highestSeqNo[lsaName]) {
955 ndn::Interest interest(interestName);
956 ndn::util::SegmentFetcher::Options options;
959 NLSR_LOG_DEBUG(
"Fetching Data for LSA: " << interestName <<
" Seq number: " << seqNo);
960 auto fetcher = ndn::util::SegmentFetcher::start(m_face, interest,
963 auto it = m_fetchers.insert(fetcher).first;
965 fetcher->afterSegmentValidated.connect([
this] (
const ndn::Data& data) {
970 auto lsaSegment = std::make_shared<const ndn::Data>(data);
971 m_lsaStorage.insert(*lsaSegment);
972 const ndn::Name& segmentName = lsaSegment->getName();
975 [
this, segmentName] { m_lsaStorage.erase(segmentName); });
978 fetcher->onComplete.connect([=] (
const ndn::ConstBufferPtr& bufferPtr) {
979 m_lsaStorage.erase(ndn::Name(lsaName).appendNumber(seqNo - 1));
980 afterFetchLsa(bufferPtr, interestName);
981 m_fetchers.erase(it);
984 fetcher->onError.connect([=] (uint32_t errorCode,
const std::string& msg) {
985 onFetchLsaError(errorCode, msg, interestName, timeoutCount, deadline, lsaName, seqNo);
986 m_fetchers.erase(it);
991 std::istringstream(interestName[-2].toUri()) >> lsaType;
1003 NLSR_LOG_ERROR(
"lsaType " << lsaType <<
" not recognized; failed Statistics::PacketType conversion");
1010 ndn::Name interestName(interest.getName());
1013 if (interestName[-2].isVersion()) {
1015 if (m_segmentPublisher.replyFromStore(interestName)) {
1020 interestName = interestName.getSubName(0, interestName.size() - 2);
1021 NLSR_LOG_TRACE(
"Interest w/o segment and version: " << interestName);
1027 std::string chkString(
"LSA");
1031 ndn::Name originRouter = m_confParam.
getNetwork();
1032 originRouter.append(interestName.getSubName(lsaPosition + 1,
1033 interestName.size() - lsaPosition - 3));
1036 if (originRouter == m_confParam.
getRouterPrefix() && lsaPosition >= 0) {
1037 uint64_t seqNo = interestName[-1].toNumber();
1040 std::string lsaType = interestName[-2].toUri();
1042 std::istringstream(lsaType) >> interestedLsType;
1045 processInterestForNameLsa(interest, originRouter.append(lsaType), seqNo);
1048 processInterestForAdjacencyLsa(interest, originRouter.append(lsaType), seqNo);
1051 processInterestForCoordinateLsa(interest, originRouter.append(lsaType), seqNo);
1054 NLSR_LOG_WARN(
"Received unrecognized LSA type: " << interestedLsType);
1059 std::shared_ptr<const ndn::Data> lsaSegment = m_lsaStorage.find(interest);
1061 NLSR_LOG_TRACE(
"Found data in lsa storage. Sending the data for " << interest.getName());
1062 m_face.put(*lsaSegment);
1065 NLSR_LOG_TRACE(interest <<
" was not found in this lsa storage.");
1076 Lsdb::processInterestForNameLsa(
const ndn::Interest& interest,
1077 const ndn::Name& lsaKey,
1084 if (nameLsa !=
nullptr) {
1085 NLSR_LOG_TRACE(
"Verifying SeqNo for NameLsa is same as requested.");
1087 std::string content = nameLsa->
serialize();
1088 m_segmentPublisher.publish(interest.getName(), interest.getName(),
1089 ndn::encoding::makeStringBlock(ndn::tlv::Content, content),
1109 Lsdb::processInterestForAdjacencyLsa(
const ndn::Interest& interest,
1110 const ndn::Name& lsaKey,
1114 NLSR_LOG_ERROR(
"Received interest for an adjacency LSA when hyperbolic routing is enabled");
1120 if (adjLsa !=
nullptr) {
1121 NLSR_LOG_TRACE(
"Verifying SeqNo for AdjLsa is same as requested.");
1123 std::string content = adjLsa->
serialize();
1124 m_segmentPublisher.publish(interest.getName(), interest.getName(),
1125 ndn::encoding::makeStringBlock(ndn::tlv::Content, content),
1145 Lsdb::processInterestForCoordinateLsa(
const ndn::Interest& interest,
1146 const ndn::Name& lsaKey,
1150 NLSR_LOG_ERROR(
"Received Interest for a coordinate LSA when link-state routing is enabled");
1154 NLSR_LOG_DEBUG(
"CoordinateLsa interest " << interest <<
" received");
1156 if (corLsa !=
nullptr) {
1157 NLSR_LOG_TRACE(
"Verifying SeqNo for CoordinateLsa is same as requested.");
1159 std::string content = corLsa->
serialize();
1160 m_segmentPublisher.publish(interest.getName(), interest.getName(),
1161 ndn::encoding::makeStringBlock(ndn::tlv::Content, content),
1176 Lsdb::onContentValidated(
const std::shared_ptr<const ndn::Data>& data)
1178 const ndn::Name& dataName = data->getName();
1179 NLSR_LOG_DEBUG(
"Data validation successful for LSA: " << dataName);
1181 std::string chkString(
"LSA");
1184 if (lsaPosition >= 0) {
1187 ndn::Name originRouter = m_confParam.
getNetwork();
1188 originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
1190 uint64_t seqNo = dataName[-1].toNumber();
1191 std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()),
1192 data->getContent().value_size());
1195 std::istringstream(dataName[-2].toUri()) >> interestedLsType;
1198 processContentNameLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1202 processContentAdjacencyLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1206 processContentCoordinateLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1210 NLSR_LOG_WARN(
"Received unrecognized LSA Type: " << interestedLsType);
1218 Lsdb::processContentNameLsa(
const ndn::Name& lsaKey,
1219 uint64_t lsSeqNo, std::string& dataContent)
1234 Lsdb::processContentAdjacencyLsa(
const ndn::Name& lsaKey,
1235 uint64_t lsSeqNo, std::string& dataContent)
1250 Lsdb::processContentCoordinateLsa(
const ndn::Name& lsaKey,
1251 uint64_t lsSeqNo, std::string& dataContent)
1265 ndn::time::system_clock::TimePoint
1266 Lsdb::getLsaExpirationTimePoint()
1268 ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
1269 expirationTimePoint = expirationTimePoint +
1271 return expirationTimePoint;
1282 for (
const auto& adj : m_adjLsdb) {
1293 return doesAdjLsaExist(key);
1295 return doesCoordinateLsaExist(key);
1297 return doesNameLsaExist(key);
1305 const uint64_t& sequenceNumber) {
1306 ndn::Name lsaKey = routerName;
1307 lsaKey.append(std::to_string(lsaType));
bool installAdjLsa(AdjLsa &alsa)
Installs an adj. LSA into the LSDB.
uint32_t getLsSeqNo() const
ndn::security::ValidatorConfig & getValidator()
A class to house all the configuration parameters for NLSR.
void setAdjLsaSeq(uint64_t alsn)
void scheduleAdjLsaBuild()
Schedules a build of this router's LSA.
bool removeNameLsa(const ndn::Name &key)
Remove a name LSA from the LSDB.
bool deserialize(const std::string &content) noexcept override
Initializes this coordinate LSA with the data in content.
void writeSeqNoToFile() const
const ndn::time::system_clock::TimePoint & getExpirationTimePoint() const
uint64_t getCorLsaSeq() const
static bool corLsaCompareByKey(const CoordinateLsa &clsa, const ndn::Name &key)
Compares whether an LSA object is the same as a key.
uint32_t getAdjLsaBuildInterval() const
uint32_t getLsaRefreshTime() const
const std::string & getStateFileDir() const
std::string serialize() const override
Returns the data this adjacency LSA has.
const std::list< NameLsa > & getNameLsdb() const
bool isLsaNew(const ndn::Name &routerName, const Lsa::Type &lsaType, const uint64_t &sequenceNumber)
const std::list< CoordinateLsa > & getCoordinateLsdb() const
void setLsSeqNo(uint32_t lsn)
void scheduleRoutingTableCalculation()
Schedules a calculation event in the event scheduler only if one isn't already scheduled.
void writeLog() const override
std::list< ndn::Name > getNames() const
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.
NamePrefixList & getNpl()
const ndn::security::SigningInfo & getSigningInfo() const
AdjacencyList & getAdjacencyList()
#define NLSR_LOG_DEBUG(x)
const ndn::Name & getRouterPrefix() const
Lsdb(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam, NamePrefixTable &namePrefixTable, RoutingTable &routingTable)
void writeLog() const override
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
uint64_t getAdjLsaSeq() const
void setExpirationTimePoint(const ndn::time::system_clock::TimePoint <)
int32_t getNumOfActiveNeighbor() const
const ndn::Name getKey() const
Gets the key for this LSA.
double getCorRadius() const
const ndn::time::seconds & getLsaInterestLifetime() const
#define INIT_LOGGER(name)
void removeEntry(const ndn::Name &name, const ndn::Name &destRouter)
Removes a destination from a name prefix table entry.
bool isCoordinateLsaNew(const ndn::Name &key, uint64_t seqNo)
Returns whether a cor. LSA from a router is new or not.
uint32_t getInterestRetryNumber() const
void writeLog() const override
CoordinateLsa * findCoordinateLsa(const ndn::Name &key)
Finds a cor. LSA in the LSDB.
ndn::util::signal::Signal< Lsdb, const ndn::Data & > afterSegmentValidatedSignal
bool isNameLsaNew(const ndn::Name &key, uint64_t seqNo)
bool deserialize(const std::string &content) noexcept override
Initializes this LSA object with content's data.
bool installCoordinateLsa(CoordinateLsa &clsa)
Installs a cor. LSA into the LSDB.
NameLsa * findNameLsa(const ndn::Name &key)
Returns the name LSA with the given key.
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
void expressInterest(const ndn::Name &interestName, uint32_t timeoutCount, ndn::time::steady_clock::TimePoint deadline=DEFAULT_LSA_RETRIEVAL_DEADLINE)
bool doesLsaExist(const ndn::Name &key, const Lsa::Type &lsType)
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
std::string serialize() const override
Returns the data that this name LSA has.
const std::vector< double > getCorTheta() const
bool isAdjLsaNew(const ndn::Name &key, uint64_t seqNo)
Returns whether an LSA is new.
const ndn::Name & getOrigRouter() const
bool removeAdjLsa(const ndn::Name &key)
Removes an adj. LSA from the LSDB.
void setNameLsaSeq(uint64_t nlsn)
const ndn::Name & getNetwork() const
int32_t getHyperbolicState() const
uint64_t getNameLsaSeq() const
void setExpiringEventId(ndn::scheduler::EventId eid)
void setCorTheta(std::vector< double > ct)
#define NLSR_LOG_ERROR(x)
static const ndn::Name::Component NAME_COMPONENT
void removeName(const ndn::Name &name)
Copyright (c) 2014-2019, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
NamePrefixList & getNamePrefixList()
ndn::util::signal::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
bool installNameLsa(NameLsa &nlsa)
Installs a name LSA into the LSDB.
void setCorRadius(double cr)
const std::list< AdjLsa > & getAdjLsdb() const
static bool adjLsaCompareByKey(AdjLsa &alsa, const ndn::Name &key)
Returns whether an adj. LSA object is from some router.
void setCorLsaSeq(uint64_t clsn)
bool buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
bool isAdjLsaBuildable(const uint32_t interestRetryNo) const
Determines whether this list can be used to build an adj. LSA.
bool buildAndInstallOwnCoordinateLsa()
Builds a cor. LSA for this router and installs it into the LSDB.
void addName(const ndn::Name &name)
bool deserialize(const std::string &content) noexcept override
Initializes this adj. LSA from the supplied content.
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.
ndn::scheduler::EventId getExpiringEventId() const
uint32_t getRouterDeadInterval() const
uint32_t getInterestResendTime() const
AdjLsa * findAdjLsa(const ndn::Name &key)
Finds an adj. LSA in the LSDB.
bool buildAndInstallOwnAdjLsa()
Wrapper event to build and install an adj. LSA for this router.
bool removeCoordinateLsa(const ndn::Name &key)
Removes a cor. LSA from the LSDB.
#define NLSR_LOG_TRACE(x)
bool isEqualContent(const CoordinateLsa &clsa) const
void increaseNameLsaSeq()
std::vector< double > getCorTheta() const
bool isEqualContent(const AdjLsa &alsa) const
void publishRoutingUpdate(const Lsa::Type &type, const uint64_t &seqNo)
Instruct ChronoSync to publish an update.
void addEntry(const ndn::Name &name, const ndn::Name &destRouter)
Adds a destination to the specified name prefix.