src: Stop outdated LSA retrieval
refs: #1987
Change-Id: I5c2bbe75e4bb0a09d971a35db87591873f81a84b
diff --git a/src/lsdb.cpp b/src/lsdb.cpp
index 0b7e4e7..212ae42 100644
--- a/src/lsdb.cpp
+++ b/src/lsdb.cpp
@@ -34,6 +34,7 @@
INIT_LOGGER("Lsdb");
const ndn::time::seconds Lsdb::GRACE_PERIOD = ndn::time::seconds(10);
+const steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE = steady_clock::TimePoint::min();
using namespace std;
@@ -760,61 +761,68 @@
void
Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
- steady_clock::TimePoint deadline/* = steady_clock::TimePoint::min()*/)
+ steady_clock::TimePoint deadline)
{
- if (deadline == steady_clock::TimePoint::min()) {
- deadline = steady_clock::now() + m_lsaRefreshTime;
+ if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
+ deadline = steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
}
+ ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
+
ndn::Interest interest(interestName);
- uint64_t interestedLsSeqNo = interestName[-1].toNumber();
- _LOG_DEBUG("Expressing Interest for LSA(name): " << interestName
- << " Seq number: " << interestedLsSeqNo);
+ uint64_t seqNo = interestName[-1].toNumber();
+
+ if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
+ m_highestSeqNo[lsaName] = seqNo;
+ }
+ else if (seqNo > m_highestSeqNo[lsaName]) {
+ m_highestSeqNo[lsaName] = seqNo;
+ }
+ else if (seqNo < m_highestSeqNo[lsaName]) {
+ return;
+ }
+
interest.setInterestLifetime(m_nlsr.getConfParameter().getLsaInterestLifetime());
+
+ _LOG_DEBUG("Expressing Interest for LSA: " << interestName << " Seq number: " << seqNo);
m_nlsr.getNlsrFace().expressInterest(interest,
ndn::bind(&Lsdb::onContent,
- this, _2, deadline),
+ this, _2, deadline, lsaName, seqNo),
ndn::bind(&Lsdb::processInterestTimedOut,
- this, _1, timeoutCount, deadline));
+ this, _1, timeoutCount, deadline, lsaName, seqNo));
}
void
Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
{
- const ndn::Name& intName(interest.getName());
- _LOG_DEBUG("Interest recevied for LSA(name): " << intName);
+ const ndn::Name& interestName(interest.getName());
+ _LOG_DEBUG("Interest received for LSA: " << interestName);
+
string chkString("LSA");
- int32_t lsaPosition = util::getNameComponentPosition(interest.getName(),
- chkString);
+ int32_t lsaPosition = util::getNameComponentPosition(interest.getName(), chkString);
+
if (lsaPosition >= 0) {
- std::string interestedLsType;
- uint64_t interestedLsSeqNo;
- ndn::Name origRouter = m_nlsr.getConfParameter().getNetwork();
- origRouter.append(intName.getSubName(lsaPosition + 1,
- interest.getName().size() - lsaPosition - 3));
- interestedLsType = intName[-2].toUri();
- interestedLsSeqNo = intName[-1].toNumber();
- _LOG_DEBUG("LSA sequence number from interest: " << interestedLsSeqNo);
+
+ ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
+ originRouter.append(interestName.getSubName(lsaPosition + 1,
+ interest.getName().size() - lsaPosition - 3));
+
+ uint64_t seqNo = interestName[-1].toNumber();
+ _LOG_DEBUG("LSA sequence number from interest: " << seqNo);
+
+ std::string interestedLsType = interestName[-2].toUri();
+
if (interestedLsType == "name") {
- processInterestForNameLsa(interest,
- origRouter.append(interestedLsType),
- interestedLsSeqNo);
- return;
+ processInterestForNameLsa(interest, originRouter.append(interestedLsType), seqNo);
}
else if (interestedLsType == "adjacency") {
- processInterestForAdjacencyLsa(interest,
- origRouter.append(interestedLsType),
- interestedLsSeqNo);
- return;
+ processInterestForAdjacencyLsa(interest, originRouter.append(interestedLsType), seqNo);
}
else if (interestedLsType == "coordinate") {
- processInterestForCoordinateLsa(interest,
- origRouter.append(interestedLsType),
- interestedLsSeqNo);
- return;
+ processInterestForCoordinateLsa(interest, originRouter.append(interestedLsType), seqNo);
}
else {
- _LOG_DEBUG("Unrecognized LSA Type :(");
+ _LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
}
}
}
@@ -837,11 +845,11 @@
void
Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
- uint32_t interestedlsSeqNo)
+ uint64_t seqNo)
{
NameLsa* nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
if (nameLsa != 0) {
- if (nameLsa->getLsSeqNo() >= interestedlsSeqNo) {
+ if (nameLsa->getLsSeqNo() == seqNo) {
std::string content = nameLsa->getData();
putLsaData(interest,content);
}
@@ -851,11 +859,11 @@
void
Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
- uint32_t interestedlsSeqNo)
+ uint64_t seqNo)
{
AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
if (adjLsa != 0) {
- if (adjLsa->getLsSeqNo() >= interestedlsSeqNo) {
+ if (adjLsa->getLsSeqNo() == seqNo) {
std::string content = adjLsa->getData();
putLsaData(interest,content);
}
@@ -865,11 +873,11 @@
void
Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
- uint32_t interestedlsSeqNo)
+ uint64_t seqNo)
{
CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
if (corLsa != 0) {
- if (corLsa->getLsSeqNo() >= interestedlsSeqNo) {
+ if (corLsa->getLsSeqNo() == seqNo) {
std::string content = corLsa->getData();
putLsaData(interest,content);
}
@@ -878,7 +886,8 @@
void
Lsdb::onContent(const ndn::Data& data,
- const steady_clock::TimePoint& deadline)
+ const steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo)
{
_LOG_DEBUG("Received data for LSA(name): " << data.getName());
if (data.getSignature().hasKeyLocator()) {
@@ -889,13 +898,14 @@
m_nlsr.getValidator().validate(data,
ndn::bind(&Lsdb::onContentValidated, this, _1),
ndn::bind(&Lsdb::onContentValidationFailed, this, _1, _2,
- deadline));
+ deadline, lsaName, seqNo));
}
void
Lsdb::retryContentValidation(const ndn::shared_ptr<const ndn::Data>& data,
- const steady_clock::TimePoint& deadline)
+ const steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo)
{
_LOG_DEBUG("Retrying validation of LSA(name): " << data->getName());
if (data->getSignature().hasKeyLocator()) {
@@ -906,42 +916,39 @@
m_nlsr.getValidator().validate(*data,
ndn::bind(&Lsdb::onContentValidated, this, _1),
ndn::bind(&Lsdb::onContentValidationFailed, this, _1, _2,
- deadline));
+ deadline, lsaName, seqNo));
}
void
Lsdb::onContentValidated(const ndn::shared_ptr<const ndn::Data>& data)
{
const ndn::Name& dataName = data->getName();
- _LOG_DEBUG("Data validation successful for LSA(name): " << dataName);
- string dataContent(reinterpret_cast<const char*>(data->getContent().value()));
+ _LOG_DEBUG("Data validation successful for LSA: " << dataName);
+
string chkString("LSA");
int32_t lsaPosition = util::getNameComponentPosition(dataName, chkString);
+
if (lsaPosition >= 0) {
- std::string interestedLsType;
- uint64_t interestedLsSeqNo;
- ndn::Name origRouter = m_nlsr.getConfParameter().getNetwork();
- origRouter.append(dataName.getSubName(lsaPosition + 1,
- dataName.size() - lsaPosition - 4));
- interestedLsType = dataName[-3].toUri();
- interestedLsSeqNo = dataName[-2].toNumber();
+
+ ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
+ originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 4));
+
+ uint64_t seqNo = dataName[-2].toNumber();
+ string dataContent(reinterpret_cast<const char*>(data->getContent().value()));
+
+ std::string interestedLsType = dataName[-3].toUri();
+
if (interestedLsType == "name") {
- processContentNameLsa(origRouter.append(interestedLsType),
- interestedLsSeqNo, dataContent);
- return;
+ processContentNameLsa(originRouter.append(interestedLsType), seqNo, dataContent);
}
else if (interestedLsType == "adjacency") {
- processContentAdjacencyLsa(origRouter.append(interestedLsType),
- interestedLsSeqNo, dataContent);
- return;
+ processContentAdjacencyLsa(originRouter.append(interestedLsType), seqNo, dataContent);
}
else if (interestedLsType == "coordinate") {
- processContentCoordinateLsa(origRouter.append(interestedLsType),
- interestedLsSeqNo, dataContent);
- return;
+ processContentCoordinateLsa(originRouter.append(interestedLsType), seqNo, dataContent);
}
else {
- _LOG_DEBUG("Unrecognized LSA Type :(");
+ _LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
}
}
}
@@ -949,7 +956,8 @@
void
Lsdb::onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
const std::string& msg,
- const steady_clock::TimePoint& deadline)
+ const steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo)
{
_LOG_DEBUG("Validation Error: " << msg);
@@ -959,15 +967,21 @@
// Stop retrying if delayed re-validation will be scheduled pass the deadline
if (steady_clock::now() + m_nlsr.getConfParameter().getLsaInterestLifetime() < deadline) {
- _LOG_DEBUG("Scheduling revalidation");
- m_scheduler.scheduleEvent(m_nlsr.getConfParameter().getLsaInterestLifetime(),
- ndn::bind(&Lsdb::retryContentValidation, this, data, deadline));
+
+ SequenceNumberMap::const_iterator it = m_highestSeqNo.find(lsaName);
+
+ if (it != m_highestSeqNo.end() && it->second == seqNo) {
+ _LOG_DEBUG("Scheduling revalidation attempt");
+ m_scheduler.scheduleEvent(m_nlsr.getConfParameter().getLsaInterestLifetime(),
+ ndn::bind(&Lsdb::retryContentValidation, this, data,
+ deadline, lsaName, seqNo));
+ }
}
}
void
Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
- uint32_t lsSeqNo, std::string& dataContent)
+ uint64_t lsSeqNo, std::string& dataContent)
{
if (isNameLsaNew(lsaKey, lsSeqNo)) {
NameLsa nameLsa;
@@ -982,7 +996,7 @@
void
Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
- uint32_t lsSeqNo, std::string& dataContent)
+ uint64_t lsSeqNo, std::string& dataContent)
{
if (isAdjLsaNew(lsaKey, lsSeqNo)) {
AdjLsa adjLsa;
@@ -997,7 +1011,7 @@
void
Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
- uint32_t lsSeqNo, std::string& dataContent)
+ uint64_t lsSeqNo, std::string& dataContent)
{
if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
CoordinateLsa corLsa;
@@ -1012,13 +1026,19 @@
void
Lsdb::processInterestTimedOut(const ndn::Interest& interest, uint32_t retransmitNo,
- const ndn::time::steady_clock::TimePoint& deadline)
+ const ndn::time::steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo)
{
const ndn::Name& interestName = interest.getName();
- _LOG_DEBUG("Interest timed out for LSA(name): " << interestName);
+ _LOG_DEBUG("Interest timed out for LSA: " << interestName);
if (ndn::time::steady_clock::now() < deadline) {
- expressInterest(interestName, retransmitNo + 1, deadline);
+
+ SequenceNumberMap::const_iterator it = m_highestSeqNo.find(lsaName);
+
+ if (it != m_highestSeqNo.end() && it->second == seqNo) {
+ expressInterest(interestName, retransmitNo + 1, deadline);
+ }
}
}
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
index c6ab5e8..5d66f01 100644
--- a/src/lsdb.hpp
+++ b/src/lsdb.hpp
@@ -20,6 +20,7 @@
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
*
**/
+
#ifndef NLSR_LSDB_HPP
#define NLSR_LSDB_HPP
@@ -29,6 +30,7 @@
#include <ndn-cxx/util/time.hpp>
#include "lsa.hpp"
+#include "test-access-control.hpp"
namespace nlsr {
@@ -162,7 +164,7 @@
public:
void
expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
- steady_clock::TimePoint deadline = steady_clock::TimePoint::min());
+ steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
void
processInterest(const ndn::Name& name, const ndn::Interest& interest);
@@ -174,20 +176,21 @@
void
processInterestForNameLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
- uint32_t interestedlsSeqNo);
+ uint64_t seqNo);
void
processInterestForAdjacencyLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
- uint32_t interestedlsSeqNo);
+ uint64_t seqNo);
void
processInterestForCoordinateLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
- uint32_t interestedlsSeqNo);
+ uint64_t seqNo);
void
- onContent(const ndn::Data& data, const steady_clock::TimePoint& deadline);
+ onContent(const ndn::Data& data, const steady_clock::TimePoint& deadline,
+ ndn::Name lsaName, uint64_t seqNo);
/**
* @brief Retry validation after it fails
@@ -200,38 +203,43 @@
*/
void
retryContentValidation(const ndn::shared_ptr<const ndn::Data>& data,
- const steady_clock::TimePoint& deadline);
+ const steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo);
void
onContentValidated(const ndn::shared_ptr<const ndn::Data>& data);
void
onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, const std::string& msg,
- const steady_clock::TimePoint& deadline);
+ const steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo);
void
processContentNameLsa(const ndn::Name& lsaKey,
- uint32_t lsSeqNo, std::string& dataContent);
+ uint64_t lsSeqNo, std::string& dataContent);
void
processContentAdjacencyLsa(const ndn::Name& lsaKey,
- uint32_t lsSeqNo, std::string& dataContent);
+ uint64_t lsSeqNo, std::string& dataContent);
void
processContentCoordinateLsa(const ndn::Name& lsaKey,
- uint32_t lsSeqNo, std::string& dataContent);
+ uint64_t lsSeqNo, std::string& dataContent);
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
processInterestTimedOut(const ndn::Interest& interest, uint32_t retransmitNo,
- const steady_clock::TimePoint& deadline);
+ const steady_clock::TimePoint& deadline, ndn::Name lsaName,
+ uint64_t seqNo);
+private:
system_clock::TimePoint
getLsaExpirationTimePoint();
-private:
void
cancelScheduleLsaExpiringEvent(ndn::EventId eid);
+private:
Nlsr& m_nlsr;
ndn::Scheduler& m_scheduler;
@@ -244,7 +252,14 @@
seconds m_lsaRefreshTime;
std::string m_thisRouterPrefix;
+ typedef std::map<ndn::Name, uint64_t> SequenceNumberMap;
+
+ // Maps the name of an LSA to its highest known sequence number from sync;
+ // Used to stop NLSR from trying to fetch outdated LSAs
+ SequenceNumberMap m_highestSeqNo;
+
static const ndn::time::seconds GRACE_PERIOD;
+ static const steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
};
}//namespace nlsr
diff --git a/tests/test-lsdb.cpp b/tests/test-lsdb.cpp
index 077a381..23083c9 100644
--- a/tests/test-lsdb.cpp
+++ b/tests/test-lsdb.cpp
@@ -29,7 +29,6 @@
#include "lsa.hpp"
#include "name-prefix-list.hpp"
#include <boost/test/unit_test.hpp>
-#include <ndn-cxx/util/time.hpp>
namespace nlsr {
namespace test {
@@ -57,6 +56,8 @@
face->processEvents(ndn::time::milliseconds(1));
face->m_sentInterests.clear();
+
+ INIT_LOGGERS("/tmp", "DEBUG");
}
void
@@ -103,10 +104,62 @@
BOOST_FIXTURE_TEST_SUITE(TestLsdb, LsdbFixture)
+BOOST_AUTO_TEST_CASE(LsdbSync)
+{
+ ndn::Name interestName("/ndn/NLSR/LSA/cs/%C1.Router/router2/name");
+ uint64_t oldSeqNo = 82;
+
+ ndn::Name oldInterestName = interestName;
+ oldInterestName.appendNumber(oldSeqNo);
+
+ lsdb.expressInterest(oldInterestName, 0);
+ face->processEvents(ndn::time::milliseconds(1));
+
+ std::vector<ndn::Interest>& interests = face->m_sentInterests;
+
+ BOOST_REQUIRE(interests.size() > 0);
+ std::vector<ndn::Interest>::iterator it = interests.begin();
+
+ BOOST_CHECK_EQUAL(it->getName(), oldInterestName);
+ interests.clear();
+
+ steady_clock::TimePoint deadline = steady_clock::now() +
+ ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
+
+ // Simulate an LSA interest timeout
+ lsdb.processInterestTimedOut(oldInterestName, 0, deadline, interestName, oldSeqNo);
+ face->processEvents(ndn::time::milliseconds(1));
+
+ BOOST_REQUIRE(interests.size() > 0);
+ it = interests.begin();
+
+ BOOST_CHECK_EQUAL(it->getName(), oldInterestName);
+ interests.clear();
+
+ uint64_t newSeqNo = 83;
+
+ ndn::Name newInterestName = interestName;
+ newInterestName.appendNumber(newSeqNo);
+
+ lsdb.expressInterest(newInterestName, 0);
+ face->processEvents(ndn::time::milliseconds(1));
+
+ BOOST_REQUIRE(interests.size() > 0);
+ it = interests.begin();
+
+ BOOST_CHECK_EQUAL(it->getName(), newInterestName);
+ interests.clear();
+
+ // Simulate an LSA interest timeout where the sequence number is outdated
+ lsdb.processInterestTimedOut(oldInterestName, 0, deadline, interestName, oldSeqNo);
+ face->processEvents(ndn::time::milliseconds(1));
+
+ // Interest should not be expressed for outdated sequence number
+ BOOST_CHECK_EQUAL(interests.size(), 0);
+}
+
BOOST_AUTO_TEST_CASE(LsdbRemoveAndExists)
{
- INIT_LOGGERS("/tmp", "DEBUG");
-
ndn::time::system_clock::TimePoint testTimePoint = ndn::time::system_clock::now();
NamePrefixList npl1;