29 #include <ndn-cxx/security/signing-helpers.hpp> 30 #include <ndn-cxx/util/segment-fetcher.hpp> 40 ndn::KeyChain& keyChain,
41 const ndn::security::SigningInfo& signingInfo,
42 const ndn::time::milliseconds& freshnessPeriod,
43 const std::string& content)
51 size_t totalLength = 0;
52 totalLength += outBuffer.prependByteArray(reinterpret_cast<const uint8_t*>(m_content.c_str()),
58 const std::string m_content;
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();
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);
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);
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,
95 NLSR_LOG_DEBUG(
"Failed to fetch LSA: " << lsaName <<
", Error code: " << errorCode
96 <<
", Message: " << msg);
98 if (ndn::time::steady_clock::now() < deadline) {
99 SequenceNumberMap::const_iterator it = m_highestSeqNo.find(lsaName);
101 if (it != m_highestSeqNo.end() && it->second == seqNo) {
108 if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
109 delay = ndn::time::seconds(0);
113 interestName, retransmitNo + 1, deadline));
119 Lsdb::afterFetchLsa(
const ndn::ConstBufferPtr& bufferPtr, ndn::Name& interestName)
121 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(ndn::Name(interestName));
122 data->setContent(bufferPtr);
124 NLSR_LOG_DEBUG(
"Received data for LSA(name): " << data->getName());
126 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
127 uint64_t seqNo = interestName[-1].toNumber();
129 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
130 m_highestSeqNo[lsaName] = seqNo;
132 else if (seqNo > m_highestSeqNo[lsaName]) {
133 m_highestSeqNo[lsaName] = seqNo;
134 NLSR_LOG_TRACE(
"SeqNo for LSA(name): " << data->getName() <<
" updated");
136 else if (seqNo < m_highestSeqNo[lsaName]) {
140 onContentValidated(data);
144 Lsdb::cancelScheduleLsaExpiringEvent(ndn::EventId eid)
146 m_scheduler.cancelEvent(eid);
157 return nlsa1.
getKey() == key;
165 getLsaExpirationTimePoint(),
178 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
181 if (it != m_nameLsdb.end()) {
192 if (nameLsaCheck != 0) {
205 Lsdb::scheduleNameLsaExpiration(
const ndn::Name& key,
int seqNo,
206 const ndn::time::seconds& expTime)
208 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
209 std::bind(&Lsdb::expireOrRefreshNameLsa,
this, key, seqNo));
215 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
218 if (chkNameLsa == 0) {
230 for (std::list<ndn::Name>::iterator it = nameList.begin(); it != nameList.end();
239 ndn::time::system_clock::now();
240 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
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) {
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());
292 ndn::time::system_clock::now();
293 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
307 Lsdb::addNameLsa(
NameLsa& nlsa)
309 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
313 if (it == m_nameLsdb.end()) {
314 m_nameLsdb.push_back(nlsa);
323 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
326 if (it != m_nameLsdb.end()) {
331 if ((*it).getOrigRouter() !=
334 (*it).getOrigRouter());
335 for (
const auto& name : it->getNpl().getNames()) {
341 m_nameLsdb.erase(it);
348 Lsdb::doesNameLsaExist(
const ndn::Name& key)
350 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
353 if (it == m_nameLsdb.end()) {
363 for (std::list<NameLsa>::iterator it = m_nameLsdb.begin();
364 it != m_nameLsdb.end() ; it++) {
369 const std::list<NameLsa>&
384 return clsa.
getKey() == key;
392 getLsaExpirationTimePoint(),
411 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
414 if (it != m_corLsdb.end()) {
442 Lsdb::scheduleCoordinateLsaExpiration(
const ndn::Name& key,
int seqNo,
443 const ndn::time::seconds& expTime)
445 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
446 std::bind(&Lsdb::expireOrRefreshCoordinateLsa,
453 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
456 if (chkCorLsa == 0) {
460 addCoordinateLsa(clsa);
473 ndn::time::system_clock::now();
474 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
476 scheduleCoordinateLsaExpiration(clsa.
getKey(),
498 ndn::time::system_clock::now();
499 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
515 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
519 if (it == m_corLsdb.end()) {
520 m_corLsdb.push_back(clsa);
529 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
533 if (it != m_corLsdb.end()) {
548 Lsdb::doesCoordinateLsaExist(
const ndn::Name& key)
550 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
554 if (it == m_corLsdb.end()) {
564 for (std::list<CoordinateLsa>::iterator it = m_corLsdb.begin();
565 it != m_corLsdb.end() ; it++) {
570 const std::list<CoordinateLsa>&
585 return alsa.
getKey() == key;
595 NLSR_LOG_DEBUG(
"Adjacency LSA not built. Currently in hyperbolic routing state.");
600 NLSR_LOG_DEBUG(
"Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
602 m_scheduler.scheduleEvent(m_adjLsaBuildInterval, std::bind(&Lsdb::buildAdjLsa,
this));
618 if (adjBuildCount > 0) {
651 m_scheduler.scheduleEvent(ndn::time::seconds(schedulingTime),
652 std::bind(&Lsdb::buildAdjLsa,
this));
657 Lsdb::addAdjLsa(
AdjLsa& alsa)
659 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
663 if (it == m_adjLsdb.end()) {
664 m_adjLsdb.push_back(alsa);
673 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
676 if (it != m_adjLsdb.end()) {
687 if (adjLsaCheck != 0) {
700 Lsdb::scheduleAdjLsaExpiration(
const ndn::Name& key,
int seqNo,
701 const ndn::time::seconds& expTime)
703 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
704 std::bind(&Lsdb::expireOrRefreshAdjLsa,
this, key, seqNo));
710 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
713 if (chkAdjLsa == 0) {
723 ndn::time::system_clock::now();
724 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
726 scheduleAdjLsaExpiration(alsa.
getKey(),
747 ndn::time::system_clock::now();
748 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
766 getLsaExpirationTimePoint(),
783 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
786 if (it != m_adjLsdb.end()) {
789 (*it).removeNptEntries(m_nlsr);
797 Lsdb::doesAdjLsaExist(
const ndn::Name& key)
799 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
802 if (it == m_adjLsdb.end()) {
808 const std::list<AdjLsa>&
817 m_lsaRefreshTime = lsaRefreshTime;
823 m_thisRouterPrefix = trp;
834 Lsdb::expireOrRefreshNameLsa(
const ndn::Name& lsaKey, uint64_t seqNo)
840 if (chkNameLsa != 0) {
877 Lsdb::expireOrRefreshAdjLsa(
const ndn::Name& lsaKey, uint64_t seqNo)
883 if (chkAdjLsa != 0) {
924 Lsdb::expireOrRefreshCoordinateLsa(
const ndn::Name& lsaKey,
931 if (chkCorLsa != 0) {
972 ndn::time::steady_clock::TimePoint deadline)
977 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
978 deadline = ndn::time::steady_clock::now() + ndn::time::seconds(static_cast<int>(
LSA_REFRESH_TIME_MAX));
981 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
983 uint64_t seqNo = interestName[-1].toNumber();
986 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
987 m_highestSeqNo[lsaName] = seqNo;
990 else if (seqNo > m_highestSeqNo[lsaName]) {
991 m_highestSeqNo[lsaName] = seqNo;
994 else if (seqNo < m_highestSeqNo[lsaName]) {
998 ndn::Interest interest(interestName);
1001 NLSR_LOG_DEBUG(
"Fetching Data for LSA: " << interestName <<
" Seq number: " << seqNo);
1002 ndn::util::SegmentFetcher::fetch(m_nlsr.
getNlsrFace(), interest,
1004 std::bind(&Lsdb::afterFetchLsa,
this, _1, interestName),
1005 std::bind(&Lsdb::onFetchLsaError,
this, _1, _2, interestName,
1006 timeoutCount, deadline, lsaName, seqNo));
1009 std::istringstream(interestName[-2].toUri()) >> lsaType;
1021 NLSR_LOG_ERROR(
"lsaType " << lsaType <<
" not recognized; failed Statistics::PacketType conversion");
1031 const ndn::Name& interestName(interest.getName());
1034 std::string chkString(
"LSA");
1037 if (lsaPosition >= 0) {
1041 originRouter.append(interestName.getSubName(lsaPosition + 1,
1042 interest.getName().size() - lsaPosition - 3));
1044 uint64_t seqNo = interestName[-1].toNumber();
1048 std::istringstream(interestName[-2].toUri()) >> interestedLsType;
1051 processInterestForNameLsa(interest, originRouter.append(std::to_string(interestedLsType)),
1055 processInterestForAdjacencyLsa(interest, originRouter.append(std::to_string(interestedLsType)),
1059 processInterestForCoordinateLsa(interest, originRouter.append(std::to_string(interestedLsType)),
1063 NLSR_LOG_WARN(
"Received unrecognized LSA type: " << interestedLsType);
1073 Lsdb::putLsaData(
const ndn::Interest& interest,
const std::string& 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());
1091 Lsdb::processInterestForNameLsa(
const ndn::Interest& interest,
1092 const ndn::Name& lsaKey,
1101 std::string content = nameLsa->
serialize();
1102 putLsaData(interest,content);
1121 Lsdb::processInterestForAdjacencyLsa(
const ndn::Interest& interest,
1122 const ndn::Name& lsaKey,
1126 NLSR_LOG_ERROR(
"Received interest for an adjacency LSA when hyperbolic routing is enabled");
1135 std::string content = adjLsa->
serialize();
1136 putLsaData(interest,content);
1155 Lsdb::processInterestForCoordinateLsa(
const ndn::Interest& interest,
1156 const ndn::Name& lsaKey,
1160 NLSR_LOG_ERROR(
"Received Interest for a coordinate LSA when link-state routing is enabled");
1165 NLSR_LOG_DEBUG(
"CoordinateLsa interest " << interest <<
" received");
1169 std::string content = corLsa->
serialize();
1170 putLsaData(interest,content);
1184 Lsdb::onContentValidated(
const std::shared_ptr<const ndn::Data>& data)
1186 const ndn::Name& dataName = data->getName();
1187 NLSR_LOG_DEBUG(
"Data validation successful for LSA: " << dataName);
1189 std::string chkString(
"LSA");
1192 if (lsaPosition >= 0) {
1196 originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
1198 uint64_t seqNo = dataName[-1].toNumber();
1199 std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()),
1200 data->getContent().value_size());
1203 std::istringstream(dataName[-2].toUri()) >> interestedLsType;
1206 processContentNameLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1210 processContentAdjacencyLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1214 processContentCoordinateLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
1218 NLSR_LOG_WARN(
"Received unrecognized LSA Type: " << interestedLsType);
1227 Lsdb::processContentNameLsa(
const ndn::Name& lsaKey,
1228 uint64_t lsSeqNo, std::string& dataContent)
1244 Lsdb::processContentAdjacencyLsa(
const ndn::Name& lsaKey,
1245 uint64_t lsSeqNo, std::string& dataContent)
1261 Lsdb::processContentCoordinateLsa(
const ndn::Name& lsaKey,
1262 uint64_t lsSeqNo, std::string& dataContent)
1277 ndn::time::system_clock::TimePoint
1278 Lsdb::getLsaExpirationTimePoint()
1280 ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
1281 expirationTimePoint = expirationTimePoint +
1283 return expirationTimePoint;
1290 for (std::list<AdjLsa>::iterator it = m_adjLsdb.begin();
1291 it != m_adjLsdb.end() ; it++) {
1302 return doesAdjLsaExist(key);
1304 return doesCoordinateLsaExist(key);
1306 return doesNameLsaExist(key);
1314 const uint64_t& sequenceNumber) {
1315 ndn::Name lsaKey = routerName;
1316 lsaKey.append(std::to_string(lsaType));
bool installAdjLsa(AdjLsa &alsa)
Installs an adj. LSA into the LSDB.
const std::list< NameLsa > & getNameLsdb() const
uint32_t getInterestResendTime() const
void setAdjLsaSeq(uint64_t alsn)
bool getIsBuildAdjLsaSheduled()
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
void scheduleAdjLsaBuild()
Schedules a build of this router's LSA.
bool removeNameLsa(const ndn::Name &key)
Remove a name LSA from the LSDB.
ConfParameter & getConfParameter()
static bool corLsaCompareByKey(const CoordinateLsa &clsa, const ndn::Name &key)
Compares whether an LSA object is the same as a key.
const ndn::time::system_clock::TimePoint & getExpirationTimePoint() const
std::string serialize() const override
Returns the data this adjacency LSA has.
std::list< ndn::Name > getNames() const
Lsdb(Nlsr &nlsr, ndn::Scheduler &scheduler)
bool isLsaNew(const ndn::Name &routerName, const Lsa::Type &lsaType, const uint64_t &sequenceNumber)
void setLsSeqNo(uint32_t lsn)
uint64_t getCorLsaSeq() const
bool deserialize(const std::string &content) noexceptoverride
Initializes this LSA object with content's data.
void writeLog() const override
NamePrefixTable & getNamePrefixTable()
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()
bool isEqualContent(AdjLsa &alsa)
uint64_t getAdjLsaSeq() const
ndn::EventId getExpiringEventId() const
#define NLSR_LOG_DEBUG(x)
const ndn::Name & getRouterPrefix() const
void incrementAdjBuildCount()
uint64_t getNameLsaSeq() const
void writeLog() const override
bool deserialize(const std::string &content) noexceptoverride
Initializes this adj. LSA from the supplied content.
RoutingTable & getRoutingTable()
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 <)
virtual size_t generate(ndn::EncodingBuffer &outBuffer)
In a derived class, write the octets into outBuffer.
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.
const std::list< CoordinateLsa > & getCoordinateLsdb() const
const ndn::Name & getOrigRouter() const
LsaContentPublisher(ndn::Face &face, ndn::KeyChain &keyChain, const ndn::security::SigningInfo &signingInfo, const ndn::time::milliseconds &freshnessPeriod, const std::string &content)
uint32_t getInterestRetryNumber() const
AdjacencyList & getAdjacencyList()
bool isCoordinateLsaNew(const ndn::Name &key, uint64_t seqNo)
Returns whether a cor. LSA from a router is new or not.
uint32_t getLsSeqNo() const
std::vector< double > getCorTheta() const
void writeLog() const override
CoordinateLsa * findCoordinateLsa(const ndn::Name &key)
Finds a cor. LSA in the LSDB.
void setAdjBuildCount(int64_t abc)
void setLsaRefreshTime(const ndn::time::seconds &lsaRefreshTime)
bool isNameLsaNew(const ndn::Name &key, uint64_t seqNo)
void scheduleRoutingTableCalculation(Nlsr &pnlsr)
Schedules a calculation event in the event scheduler only if one isn't already scheduled.
ndn::security::v2::KeyChain & getKeyChain()
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)
int32_t getNumOfActiveNeighbor()
void setIsBuildAdjLsaSheduled(bool iabls)
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.
bool isAdjLsaNew(const ndn::Name &key, uint64_t seqNo)
Returns whether an LSA is new.
bool removeAdjLsa(const ndn::Name &key)
Removes an adj. LSA from the LSDB.
void setNameLsaSeq(uint64_t nlsn)
void setExpiringEventId(const ndn::EventId leei)
bool isEqualContent(const CoordinateLsa &clsa)
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-2017, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
NamePrefixList & getNamePrefixList()
ndn::util::signal::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
void setThisRouterPrefix(std::string trp)
bool installNameLsa(NameLsa &nlsa)
Installs a name LSA into the LSDB.
void setCorRadius(double cr)
const std::vector< double > getCorTheta() const
void addNptEntries(Nlsr &pnlsr)
Installs this LSA's name prefixes into the NPT.
const ndn::Name & getNetwork() const
long int getAdjBuildCount()
void writeSeqNoToFile() const
ndn::Face & getNlsrFace()
static bool adjLsaCompareByKey(AdjLsa &alsa, const ndn::Name &key)
Returns whether an adj. LSA object is from some router.
void setCorLsaSeq(uint64_t clsn)
const ndn::Name getKey() const
Gets the key for this LSA.
bool buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
bool buildAndInstallOwnCoordinateLsa()
Builds a cor. LSA for this router and installs it into the LSDB.
void addName(const ndn::Name &name)
int32_t getHyperbolicState() const
bool deserialize(const std::string &content) noexceptoverride
Initializes this coordinate LSA with the data in 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.
const ndn::security::SigningInfo & getSigningInfo()
provides a publisher of Status Dataset or other segmented octet stream
ndn::security::ValidatorConfig & getValidator()
const std::list< AdjLsa > & getAdjLsdb() const
AdjLsa * findAdjLsa(const ndn::Name &key)
Finds an adj. LSA in the LSDB.
uint32_t getRouterDeadInterval() const
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)
void increaseNameLsaSeq()
void publishRoutingUpdate(const Lsa::Type &type, const uint64_t &seqNo)
Instruct ChronoSync to publish an update.
double getCorRadius() const
void addEntry(const ndn::Name &name, const ndn::Name &destRouter)
Adds a destination to the specified name prefix.