lsdb: rebuild using boost::multi_index to replace 3 LSA lists
refs: #4127
Co-authored-by: Nick Gordon <nmgordon@memphis.edu>
Change-Id: Ic179f90019e472157b0d61c6db02a4afaf4843b6
diff --git a/src/lsa/adj-lsa.cpp b/src/lsa/adj-lsa.cpp
index e7dbf95..f3b04da 100644
--- a/src/lsa/adj-lsa.cpp
+++ b/src/lsa/adj-lsa.cpp
@@ -24,7 +24,7 @@
namespace nlsr {
-AdjLsa::AdjLsa(const ndn::Name& originRouter, uint32_t seqNo,
+AdjLsa::AdjLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::TimePoint& timepoint,
uint32_t noLink, AdjacencyList& adl)
: Lsa(originRouter, seqNo, timepoint)
@@ -72,7 +72,7 @@
const ndn::Block&
AdjLsa::wireEncode() const
{
- if (m_wire.hasWire() && m_baseWire.hasWire()) {
+ if (m_wire.hasWire()) {
return m_wire;
}
@@ -99,7 +99,7 @@
m_wire.parse();
- ndn::Block::element_const_iterator val = m_wire.elements_begin();
+ auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
Lsa::wireDecode(*val);
@@ -123,22 +123,29 @@
m_adl = adl;
}
-std::ostream&
-operator<<(std::ostream& os, const AdjLsa& lsa)
+std::string
+AdjLsa::toString() const
{
- os << lsa.toString();
- os << " Adjacents:\n";
+ std::ostringstream os;
+ os << Lsa::toString();
+ os << " Adjacent(s):\n";
int adjacencyIndex = 0;
- for (const Adjacent& adjacency : lsa.getAdl()) {
- os << " Adjacent " << adjacencyIndex++
- << ": (name=" << adjacency.getName()
- << ", uri=" << adjacency.getFaceUri()
- << ", cost=" << adjacency.getLinkCost() << ")\n";
+ for (const auto& adjacency : m_adl) {
+ os << " Adjacent " << adjacencyIndex++
+ << ": (name=" << adjacency.getName()
+ << ", uri=" << adjacency.getFaceUri()
+ << ", cost=" << adjacency.getLinkCost() << ")\n";
}
- return os;
+ return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const AdjLsa& lsa)
+{
+ return os << lsa.toString();
}
} // namespace nlsr
diff --git a/src/lsa/adj-lsa.hpp b/src/lsa/adj-lsa.hpp
index 12e9346..9857cc8 100644
--- a/src/lsa/adj-lsa.hpp
+++ b/src/lsa/adj-lsa.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2020, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#ifndef NLSR_LSA_ADJ_LSA_HPP
#define NLSR_LSA_ADJ_LSA_HPP
@@ -41,7 +41,7 @@
AdjLsa() = default;
- AdjLsa(const ndn::Name& originR, uint32_t seqNo,
+ AdjLsa(const ndn::Name& originR, uint64_t seqNo,
const ndn::time::system_clock::TimePoint& timepoint,
uint32_t noLink, AdjacencyList& adl);
@@ -50,6 +50,12 @@
Lsa::Type
getType() const override
{
+ return type();
+ }
+
+ static constexpr Lsa::Type
+ type()
+ {
return Lsa::Type::ADJACENCY;
}
@@ -99,18 +105,19 @@
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
- wireEncode() const;
+ wireEncode() const override;
void
wireDecode(const ndn::Block& wire);
+ std::string
+ toString() const override;
+
private:
uint32_t m_noLink;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
AdjacencyList m_adl;
-
- mutable ndn::Block m_wire;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
diff --git a/src/lsa/coordinate-lsa.cpp b/src/lsa/coordinate-lsa.cpp
index b195e39..4109c64 100644
--- a/src/lsa/coordinate-lsa.cpp
+++ b/src/lsa/coordinate-lsa.cpp
@@ -26,7 +26,7 @@
namespace nlsr {
-CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::TimePoint& timepoint,
double radius, std::vector<double> angles)
: Lsa(originRouter, seqNo, timepoint)
@@ -84,7 +84,7 @@
const ndn::Block&
CoordinateLsa::wireEncode() const
{
- if (m_wire.hasWire() && m_baseWire.hasWire()) {
+ if (m_wire.hasWire()) {
return m_wire;
}
@@ -113,7 +113,7 @@
m_wire.parse();
- ndn::Block::element_const_iterator val = m_wire.elements_begin();
+ auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
Lsa::wireDecode(*val);
@@ -143,17 +143,24 @@
m_hyperbolicAngles = angles;
}
-std::ostream&
-operator<<(std::ostream& os, const CoordinateLsa& lsa)
+std::string
+CoordinateLsa::toString() const
{
- os << lsa.toString();
- os << " Hyperbolic Radius : " << lsa.getCorRadius() << "\n";
+ std::ostringstream os;
+ os << Lsa::toString();
+ os << " Hyperbolic Radius : " << m_hyperbolicRadius << "\n";
int i = 0;
- for (const auto& value : lsa.getCorTheta()) {
+ for (const auto& value : m_hyperbolicAngles) {
os << " Hyperbolic Theta " << i++ << " : " << value << "\n";
}
- return os;
+ return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa)
+{
+ return os << lsa.toString();
}
} // namespace nlsr
diff --git a/src/lsa/coordinate-lsa.hpp b/src/lsa/coordinate-lsa.hpp
index abeea2c..4b07627 100644
--- a/src/lsa/coordinate-lsa.hpp
+++ b/src/lsa/coordinate-lsa.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2020, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#ifndef NLSR_LSA_COORDINATE_LSA_HPP
#define NLSR_LSA_COORDINATE_LSA_HPP
@@ -38,7 +38,7 @@
public:
CoordinateLsa() = default;
- CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+ CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::TimePoint& timepoint,
double radius, std::vector<double> angles);
@@ -47,6 +47,12 @@
Lsa::Type
getType() const override
{
+ return type();
+ }
+
+ static constexpr Lsa::Type
+ type()
+ {
return Lsa::Type::COORDINATE;
}
@@ -84,16 +90,17 @@
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
- wireEncode() const;
+ wireEncode() const override;
void
wireDecode(const ndn::Block& wire);
+ std::string
+ toString() const override;
+
private:
double m_hyperbolicRadius = 0.0;
std::vector<double> m_hyperbolicAngles;
-
- mutable ndn::Block m_wire;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
diff --git a/src/lsa/lsa.cpp b/src/lsa/lsa.cpp
index 73ddbe7..dd8267e 100644
--- a/src/lsa/lsa.cpp
+++ b/src/lsa/lsa.cpp
@@ -27,7 +27,7 @@
namespace nlsr {
-Lsa::Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
ndn::time::system_clock::TimePoint expirationTimePoint)
: m_originRouter(originRouter)
, m_seqNo(seqNo)
@@ -35,12 +35,6 @@
{
}
-ndn::Name
-Lsa::getKey() const
-{
- return ndn::Name(m_originRouter).append(boost::lexical_cast<std::string>((getType())));
-}
-
template<ndn::encoding::Tag TAG>
size_t
Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
@@ -70,20 +64,12 @@
m_originRouter.clear();
m_seqNo = 0;
- m_baseWire = wire;
+ ndn::Block baseWire = wire;
+ baseWire.parse();
- if (m_baseWire.type() != ndn::tlv::nlsr::Lsa) {
- std::stringstream error;
- error << "Expected Lsa Block, but Block is of a different type: #"
- << m_baseWire.type();
- BOOST_THROW_EXCEPTION(Error(error.str()));
- }
+ auto val = baseWire.elements_begin();
- m_baseWire.parse();
-
- ndn::Block::element_const_iterator val = m_baseWire.elements_begin();
-
- if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::Name) {
+ if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
m_originRouter.wireDecode(*val);
}
else {
@@ -92,7 +78,7 @@
++val;
- if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
+ if (val != baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
m_seqNo = ndn::readNonNegativeInteger(*val);
++val;
}
@@ -100,7 +86,7 @@
BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
}
- if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
+ if (val != baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
m_expirationTimePoint = ndn::time::fromString(readString(*val));
}
else {
diff --git a/src/lsa/lsa.hpp b/src/lsa/lsa.hpp
index 1bd4382..a44a594 100644
--- a/src/lsa/lsa.hpp
+++ b/src/lsa/lsa.hpp
@@ -60,7 +60,7 @@
};
protected:
- Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+ Lsa(const ndn::Name& originRouter, uint64_t seqNo,
ndn::time::system_clock::TimePoint expirationTimePoint);
Lsa() = default;
@@ -70,16 +70,13 @@
~Lsa() = default;
virtual Type
- getType() const
- {
- return Type::BASE;
- }
+ getType() const = 0;
void
setSeqNo(uint64_t seqNo)
{
m_seqNo = seqNo;
- m_baseWire.reset();
+ m_wire.reset();
}
uint64_t
@@ -94,6 +91,12 @@
return m_originRouter;
}
+ ndn::Name
+ getOriginRouterCopy() const
+ {
+ return m_originRouter;
+ }
+
const ndn::time::system_clock::TimePoint&
getExpirationTimePoint() const
{
@@ -104,7 +107,7 @@
setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
{
m_expirationTimePoint = lt;
- m_baseWire.reset();
+ m_wire.reset();
}
void
@@ -119,18 +122,15 @@
return m_expiringEventId;
}
- /*! \brief Gets the key for this LSA.
-
- Format is: \<router name\>/\<LSA type>\
- */
- ndn::Name
- getKey() const;
-
/*! Get data common to all LSA types.
*/
- std::string
+ virtual std::string
toString() const;
+ virtual const ndn::Block&
+ wireEncode() const = 0;
+
+protected:
template<ndn::encoding::Tag TAG>
size_t
wireEncode(ndn::EncodingImpl<TAG>& block) const;
@@ -144,7 +144,7 @@
ndn::time::system_clock::TimePoint m_expirationTimePoint;
ndn::scheduler::EventId m_expiringEventId;
- mutable ndn::Block m_baseWire;
+ mutable ndn::Block m_wire;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
diff --git a/src/lsa/name-lsa.cpp b/src/lsa/name-lsa.cpp
index f73014b..cfdfd77 100644
--- a/src/lsa/name-lsa.cpp
+++ b/src/lsa/name-lsa.cpp
@@ -24,9 +24,9 @@
namespace nlsr {
-NameLsa::NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+NameLsa::NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::TimePoint& timepoint,
- NamePrefixList& npl)
+ const NamePrefixList& npl)
: Lsa(originRouter, seqNo, timepoint)
{
for (const auto& name : npl.getNames()) {
@@ -64,7 +64,7 @@
const ndn::Block&
NameLsa::wireEncode() const
{
- if (m_wire.hasWire() && m_baseWire.hasWire()) {
+ if (m_wire.hasWire()) {
return m_wire;
}
@@ -91,7 +91,7 @@
m_wire.parse();
- ndn::Block::element_const_iterator val = m_wire.elements_begin();
+ auto val = m_wire.elements_begin();
if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
Lsa::wireDecode(*val);
@@ -121,18 +121,24 @@
return m_npl == other.getNpl();
}
-std::ostream&
-operator<<(std::ostream& os, const NameLsa& lsa)
+std::string
+NameLsa::toString() const
{
- os << lsa.toString();
+ std::ostringstream os;
+ os << Lsa::toString();
os << " Names:\n";
int i = 0;
- auto names = lsa.getNpl().getNames();
- for (const auto& name : names) {
+ for (const auto& name : m_npl.getNames()) {
os << " Name " << i++ << ": " << name << "\n";
}
- return os;
+ return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa)
+{
+ return os << lsa.toString();
}
} // namespace nlsr
diff --git a/src/lsa/name-lsa.hpp b/src/lsa/name-lsa.hpp
index 3223839..5e9c8d5 100644
--- a/src/lsa/name-lsa.hpp
+++ b/src/lsa/name-lsa.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2020, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#ifndef NLSR_LSA_NAME_LSA_HPP
#define NLSR_LSA_NAME_LSA_HPP
@@ -37,15 +37,21 @@
public:
NameLsa() = default;
- NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+ NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
const ndn::time::system_clock::TimePoint& timepoint,
- NamePrefixList& npl);
+ const NamePrefixList& npl);
NameLsa(const ndn::Block& block);
Lsa::Type
getType() const override
{
+ return type();
+ }
+
+ static constexpr Lsa::Type
+ type()
+ {
return Lsa::Type::NAME;
}
@@ -83,14 +89,16 @@
wireEncode(ndn::EncodingImpl<TAG>& block) const;
const ndn::Block&
- wireEncode() const;
+ wireEncode() const override;
void
wireDecode(const ndn::Block& wire);
+ std::string
+ toString() const override;
+
private:
NamePrefixList m_npl;
- mutable ndn::Block m_wire;
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
diff --git a/src/lsdb.cpp b/src/lsdb.cpp
index 9913751..fb4bcb7 100644
--- a/src/lsdb.cpp
+++ b/src/lsdb.cpp
@@ -25,14 +25,10 @@
#include "nlsr.hpp"
#include "utility/name-helper.hpp"
-#include <ndn-cxx/security/signing-helpers.hpp>
-
namespace nlsr {
INIT_LOGGER(Lsdb);
-const ndn::Name::Component Lsdb::NAME_COMPONENT = ndn::Name::Component("lsdb");
-const ndn::time::seconds Lsdb::GRACE_PERIOD = ndn::time::seconds(10);
const ndn::time::steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE =
ndn::time::steady_clock::TimePoint::min();
@@ -49,8 +45,8 @@
return isLsaNew(routerName, lsaType, sequenceNumber);
}, m_confParam)
, m_lsaRefreshTime(ndn::time::seconds(m_confParam.getLsaRefreshTime()))
- , m_thisRouterPrefix(m_confParam.getRouterPrefix().toUri())
, m_adjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval())
+ , m_thisRouterPrefix(m_confParam.getRouterPrefix())
, m_sequencingManager(m_confParam.getStateFileDir(), m_confParam.getHyperbolicState())
, m_onNewLsaConnection(m_sync.onNewLsa->connect(
[this] (const ndn::Name& updateName, uint64_t sequenceNumber,
@@ -65,521 +61,33 @@
{
}
-Lsdb::~Lsdb()
-{
- for (const auto& sp : m_fetchers) {
- sp->stop();
- }
-}
-
void
-Lsdb::onFetchLsaError(uint32_t errorCode,
- const std::string& msg,
- const ndn::Name& interestName,
- uint32_t retransmitNo,
- const ndn::time::steady_clock::TimePoint& deadline,
- ndn::Name lsaName,
- uint64_t seqNo)
-{
- NLSR_LOG_DEBUG("Failed to fetch LSA: " << lsaName << ", Error code: " << errorCode
- << ", Message: " << msg);
-
- if (ndn::time::steady_clock::now() < deadline) {
- auto it = m_highestSeqNo.find(lsaName);
- if (it != m_highestSeqNo.end() && it->second == seqNo) {
- // If the SegmentFetcher failed due to an Interest timeout, it is safe to re-express
- // immediately since at the least the LSA Interest lifetime has elapsed.
- // Otherwise, it is necessary to delay the Interest re-expression to prevent
- // the potential for constant Interest flooding.
- ndn::time::seconds delay = m_confParam.getLsaInterestLifetime();
-
- if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
- delay = ndn::time::seconds(0);
- }
-
- m_scheduler.schedule(delay, std::bind(&Lsdb::expressInterest, this,
- interestName, retransmitNo + 1, deadline));
- }
- }
-}
-
-void
-Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName)
-{
- NLSR_LOG_DEBUG("Received data for LSA interest: " << interestName);
-
- ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
- 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;
- NLSR_LOG_TRACE("SeqNo for LSA(name): " << interestName << " updated");
- }
- else if (seqNo < m_highestSeqNo[lsaName]) {
- return;
- }
-
- std::string chkString("LSA");
- int32_t lsaPosition = util::getNameComponentPosition(interestName, chkString);
-
- if (lsaPosition >= 0) {
- // Extracts the prefix of the originating router from the data.
- ndn::Name originRouter = m_confParam.getNetwork();
- originRouter.append(interestName.getSubName(lsaPosition + 1,
- interestName.size() - lsaPosition - 3));
-
- try {
- ndn::Block block(bufferPtr);
- Lsa::Type interestedLsType;
- std::istringstream(interestName[-2].toUri()) >> interestedLsType;
-
- if (interestedLsType == Lsa::Type::NAME) {
- processContentNameLsa(originRouter.append(boost::lexical_cast<std::string>(interestedLsType)),
- seqNo,
- block);
- }
- else if (interestedLsType == Lsa::Type::ADJACENCY) {
- processContentAdjacencyLsa(originRouter.append(boost::lexical_cast<std::string>(interestedLsType)),
- seqNo,
- block);
- }
- else if (interestedLsType == Lsa::Type::COORDINATE) {
- processContentCoordinateLsa(originRouter.append(boost::lexical_cast<std::string>(interestedLsType)),
- seqNo,
- block);
- }
- else {
- NLSR_LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
- }
- }
- catch (const std::exception& e) {
- NLSR_LOG_TRACE("LSA data decoding error :( " << e.what());
- return;
- }
-
- lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
- }
-}
-
- /*! \brief Compares if a name LSA is the same as the one specified by key
-
- \param nlsa1 A name LSA object
- \param key A key of an originating router to compare to nlsa1
- */
-static bool
-nameLsaCompareByKey(const NameLsa& nlsa1, const ndn::Name& key)
-{
- return nlsa1.getKey() == key;
-}
-
-bool
Lsdb::buildAndInstallOwnNameLsa()
{
- NameLsa nameLsa(m_confParam.getRouterPrefix(),
- m_sequencingManager.getNameLsaSeq() + 1,
- getLsaExpirationTimePoint(),
- m_confParam.getNamePrefixList());
+ NameLsa nameLsa(m_thisRouterPrefix, m_sequencingManager.getNameLsaSeq() + 1,
+ getLsaExpirationTimePoint(), m_confParam.getNamePrefixList());
m_sequencingManager.increaseNameLsaSeq();
-
m_sequencingManager.writeSeqNoToFile();
m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
- return installNameLsa(nameLsa);
-}
-
-NameLsa*
-Lsdb::findNameLsa(const ndn::Name& key)
-{
- auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
- std::bind(nameLsaCompareByKey, _1, key));
- if (it != m_nameLsdb.end()) {
- return &*it;
- }
- return nullptr;
-}
-
-bool
-Lsdb::isNameLsaNew(const ndn::Name& key, uint64_t seqNo)
-{
- NameLsa* nameLsaCheck = findNameLsa(key);
- // Is the name in the LSDB
- if (nameLsaCheck != nullptr) {
- // And the supplied seq no is the highest so far
- if (nameLsaCheck->getSeqNo() < seqNo) {
- return true;
- }
- else {
- return false;
- }
- }
- return true;
-}
-
-ndn::scheduler::EventId
-Lsdb::scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
- const ndn::time::seconds& expTime)
-{
- return m_scheduler.schedule(expTime + GRACE_PERIOD,
- std::bind(&Lsdb::expireOrRefreshNameLsa, this, key, seqNo));
-}
-
-bool
-Lsdb::installNameLsa(NameLsa& nlsa)
-{
- NLSR_LOG_TRACE("installNameLsa");
- ndn::time::seconds timeToExpire = m_lsaRefreshTime;
- NameLsa* chkNameLsa = findNameLsa(nlsa.getKey());
- // Determines if the name LSA is new or not.
- if (chkNameLsa == nullptr) {
- addNameLsa(nlsa);
- NLSR_LOG_DEBUG("New Name LSA");
- NLSR_LOG_DEBUG("Adding Name Lsa");
- NLSR_LOG_DEBUG(nlsa);
-
- NLSR_LOG_TRACE("nlsa.getOriginRouter(): " << nlsa.getOriginRouter());
- NLSR_LOG_TRACE("m_confParam.getRouterPrefix(): " << m_confParam.getRouterPrefix());
-
- if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- // If this name LSA is from another router, add the advertised
- // prefixes to the NPT.
- m_namePrefixTable.addEntry(nlsa.getOriginRouter(), nlsa.getOriginRouter());
-
- for (const auto& name : nlsa.getNpl().getNames()) {
- if (name != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.addEntry(name, nlsa.getOriginRouter());
- }
- }
- auto duration = nlsa.getExpirationTimePoint() - ndn::time::system_clock::now();
- timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
- }
-
- nlsa.setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
- nlsa.getSeqNo(),
- timeToExpire));
- }
- // Else this is a known name LSA, so we are updating it.
- else {
- NLSR_LOG_TRACE("Known name lsa");
- NLSR_LOG_TRACE("chkNameLsa->getSeqNo(): " << chkNameLsa->getSeqNo());
- NLSR_LOG_TRACE("nlsa.getSeqNo(): " << nlsa.getSeqNo());
- if (chkNameLsa->getSeqNo() < nlsa.getSeqNo()) {
- NLSR_LOG_DEBUG("Updated Name LSA. Updating LSDB");
- NLSR_LOG_DEBUG("Deleting Name Lsa");
- NLSR_LOG_DEBUG(chkNameLsa);
- chkNameLsa->setSeqNo(nlsa.getSeqNo());
- chkNameLsa->setExpirationTimePoint(nlsa.getExpirationTimePoint());
- chkNameLsa->getNpl().sort();
- nlsa.getNpl().sort();
- // Obtain the set difference of the current and the incoming
- // name prefix sets, and add those.
- std::list<ndn::Name> newNames = nlsa.getNpl().getNames();
- std::list<ndn::Name> oldNames = chkNameLsa->getNpl().getNames();
- std::list<ndn::Name> namesToAdd;
- std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
- std::inserter(namesToAdd, namesToAdd.begin()));
- for (const auto& name : namesToAdd) {
- chkNameLsa->addName(name);
- if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- if (name != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.addEntry(name, nlsa.getOriginRouter());
- }
- }
- }
-
- chkNameLsa->getNpl().sort();
-
- // Also remove any names that are no longer being advertised.
- std::list<ndn::Name> namesToRemove;
- std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
- std::inserter(namesToRemove, namesToRemove.begin()));
- for (const auto& name : namesToRemove) {
- NLSR_LOG_DEBUG("Removing name LSA no longer advertised: " << name);
- chkNameLsa->removeName(name);
- if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- if (name != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.removeEntry(name, nlsa.getOriginRouter());
- }
- }
- }
-
- if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- auto duration = nlsa.getExpirationTimePoint() - ndn::time::system_clock::now();
- timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
- }
- chkNameLsa->getExpiringEventId().cancel();
- chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
- nlsa.getSeqNo(),
- timeToExpire));
- NLSR_LOG_DEBUG("Adding Name Lsa");
- NLSR_LOG_DEBUG(chkNameLsa);
- }
- }
- return true;
-}
-
-bool
-Lsdb::addNameLsa(NameLsa& nlsa)
-{
- auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
- std::bind(nameLsaCompareByKey, _1, nlsa.getKey()));
- if (it == m_nameLsdb.end()) {
- m_nameLsdb.push_back(nlsa);
- return true;
- }
- return false;
-}
-
-bool
-Lsdb::removeNameLsa(const ndn::Name& key)
-{
- auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
- std::bind(nameLsaCompareByKey, _1, key));
- if (it != m_nameLsdb.end()) {
- NLSR_LOG_DEBUG("Deleting Name Lsa");
- NLSR_LOG_DEBUG(*it);
- // If the requested name LSA is not ours, we also need to remove
- // its entries from the NPT.
- if (it->getOriginRouter() != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.removeEntry(it->getOriginRouter(), it->getOriginRouter());
-
- for (const auto& name : it->getNpl().getNames()) {
- if (name != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.removeEntry(name, it->getOriginRouter());
- }
- }
- }
- m_nameLsdb.erase(it);
- return true;
- }
- return false;
-}
-
-bool
-Lsdb::doesNameLsaExist(const ndn::Name& key)
-{
- auto it = std::find_if(m_nameLsdb.begin(), m_nameLsdb.end(),
- std::bind(nameLsaCompareByKey, _1, key));
- return it != m_nameLsdb.end();
+ installLsa(std::make_shared<NameLsa>(nameLsa));
}
void
-Lsdb::writeNameLsdbLog()
-{
- NLSR_LOG_TRACE("---------------Name LSDB-------------------");
- for (const auto& nlsa : m_nameLsdb) {
- NLSR_LOG_TRACE(nlsa);
- }
-}
-
-const std::list<NameLsa>&
-Lsdb::getNameLsdb() const
-{
- return m_nameLsdb;
-}
-
-// Cor LSA and LSDB related Functions start here
-
-/*! \brief Compares whether an LSA object is the same as a key.
- \param clsa The cor. LSA to check the identity of.
- \param key The key of the publishing router to check against.
-*/
-static bool
-corLsaCompareByKey(const CoordinateLsa& clsa, const ndn::Name& key)
-{
- return clsa.getKey() == key;
-}
-
-bool
Lsdb::buildAndInstallOwnCoordinateLsa()
{
- CoordinateLsa corLsa(m_confParam.getRouterPrefix(),
- m_sequencingManager.getCorLsaSeq() + 1,
- getLsaExpirationTimePoint(),
- m_confParam.getCorR(),
+ CoordinateLsa corLsa(m_thisRouterPrefix, m_sequencingManager.getCorLsaSeq() + 1,
+ getLsaExpirationTimePoint(), m_confParam.getCorR(),
m_confParam.getCorTheta());
+ m_sequencingManager.increaseCorLsaSeq();
+ m_sequencingManager.writeSeqNoToFile();
// Sync coordinate LSAs if using HR or HR dry run.
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
- m_sequencingManager.increaseCorLsaSeq();
- m_sequencingManager.writeSeqNoToFile();
m_sync.publishRoutingUpdate(Lsa::Type::COORDINATE, m_sequencingManager.getCorLsaSeq());
}
- installCoordinateLsa(corLsa);
-
- return true;
-}
-
-CoordinateLsa*
-Lsdb::findCoordinateLsa(const ndn::Name& key)
-{
- auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
- std::bind(corLsaCompareByKey, _1, key));
- if (it != m_corLsdb.end()) {
- return &*it;
- }
- return nullptr;
-}
-
-bool
-Lsdb::isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo)
-{
- CoordinateLsa* clsa = findCoordinateLsa(key);
- // Is the coordinate LSA in the LSDB already
- if (clsa != nullptr) {
- // And the seq no is newer (higher) than the current one
- if (clsa->getSeqNo() < seqNo) {
- return true;
- }
- else {
- return false;
- }
- }
- return true;
-}
-
- // Schedules a refresh/expire event in the scheduler.
- // \param key The name of the router that published the LSA.
- // \param seqNo the seq. no. associated with the LSA to check.
- // \param expTime How long to wait before triggering the event.
-ndn::scheduler::EventId
-Lsdb::scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
- const ndn::time::seconds& expTime)
-{
- return m_scheduler.schedule(expTime + GRACE_PERIOD,
- std::bind(&Lsdb::expireOrRefreshCoordinateLsa, this, key, seqNo));
-}
-
-bool
-Lsdb::installCoordinateLsa(CoordinateLsa& clsa)
-{
- ndn::time::seconds timeToExpire = m_lsaRefreshTime;
- CoordinateLsa* chkCorLsa = findCoordinateLsa(clsa.getKey());
- // Checking whether the LSA is new or not.
- if (chkCorLsa == nullptr) {
- NLSR_LOG_DEBUG("New Coordinate LSA. Adding to LSDB");
- NLSR_LOG_DEBUG("Adding Coordinate Lsa");
- NLSR_LOG_DEBUG(clsa);
- addCoordinateLsa(clsa);
-
- // Register the LSA's origin router prefix
- if (clsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.addEntry(clsa.getOriginRouter(), clsa.getOriginRouter());
- }
- if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
- m_routingTable.scheduleRoutingTableCalculation();
- }
- // Set the expiration time for the new LSA.
- if (clsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- auto duration = clsa.getExpirationTimePoint() - ndn::time::system_clock::now();
- timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
- }
- scheduleCoordinateLsaExpiration(clsa.getKey(), clsa.getSeqNo(), timeToExpire);
- }
- // We are just updating this LSA.
- else {
- if (chkCorLsa->getSeqNo() < clsa.getSeqNo()) {
- NLSR_LOG_DEBUG("Updated Coordinate LSA. Updating LSDB");
- NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
- NLSR_LOG_DEBUG(chkCorLsa);
- chkCorLsa->setSeqNo(clsa.getSeqNo());
- chkCorLsa->setExpirationTimePoint(clsa.getExpirationTimePoint());
- // If the new LSA contains new routing information, update the LSDB with it.
- if (!chkCorLsa->isEqualContent(clsa)) {
- chkCorLsa->setCorRadius(clsa.getCorRadius());
- chkCorLsa->setCorTheta(clsa.getCorTheta());
- if (m_confParam.getHyperbolicState() >= HYPERBOLIC_STATE_ON) {
- m_routingTable.scheduleRoutingTableCalculation();
- }
- }
- // If this is an LSA from another router, refresh its expiration time.
- if (clsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- auto duration = clsa.getExpirationTimePoint() - ndn::time::system_clock::now();
- timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
- }
- chkCorLsa->getExpiringEventId().cancel();
- chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(clsa.getKey(),
- clsa.getSeqNo(),
- timeToExpire));
- NLSR_LOG_DEBUG("Adding Coordinate Lsa");
- NLSR_LOG_DEBUG(chkCorLsa);
- }
- }
- return true;
-}
-
-bool
-Lsdb::addCoordinateLsa(CoordinateLsa& clsa)
-{
- auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
- std::bind(corLsaCompareByKey, _1, clsa.getKey()));
- if (it == m_corLsdb.end()) {
- m_corLsdb.push_back(clsa);
- return true;
- }
- return false;
-}
-
-bool
-Lsdb::removeCoordinateLsa(const ndn::Name& key)
-{
- auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
- std::bind(corLsaCompareByKey, _1, key));
-
- if (it != m_corLsdb.end()) {
- NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
- NLSR_LOG_DEBUG(*it);
-
- if (it->getOriginRouter() != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.removeEntry(it->getOriginRouter(), it->getOriginRouter());
- }
-
- m_corLsdb.erase(it);
- return true;
- }
- return false;
-}
-
-bool
-Lsdb::doesCoordinateLsaExist(const ndn::Name& key)
-{
- auto it = std::find_if(m_corLsdb.begin(), m_corLsdb.end(),
- std::bind(corLsaCompareByKey, _1, key));
- return it != m_corLsdb.end();
-}
-
-void
-Lsdb::writeCorLsdbLog()
-{
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
- return;
- }
-
- NLSR_LOG_DEBUG("---------------Cor LSDB-------------------");
- for (const auto& corLsa : m_corLsdb) {
- NLSR_LOG_DEBUG(corLsa);
- }
-}
-
-const std::list<CoordinateLsa>&
-Lsdb::getCoordinateLsdb() const
-{
- return m_corLsdb;
-}
-
-// Adj LSA and LSDB related function starts here
-
- /*! \brief Returns whether an adj. LSA object is from some router.
- \param alsa The adj. LSA object.
- \param key The router name that you want to compare the LSA with.
- */
-static bool
-adjLsaCompareByKey(AdjLsa& alsa, const ndn::Name& key)
-{
- return alsa.getKey() == key;
+ installLsa(std::make_shared<CoordinateLsa>(corLsa));
}
void
@@ -603,10 +111,258 @@
m_scheduledAdjLsaBuild = m_scheduler.schedule(m_adjLsaBuildInterval, [this] { buildAdjLsa(); });
}
+template<typename T>
+void
+Lsdb::writeLog() const
+{
+ if ((T::type() == Lsa::Type::COORDINATE &&
+ m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) ||
+ (T::type() == Lsa::Type::ADJACENCY &&
+ m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON)) {
+ return;
+ }
+
+ NLSR_LOG_DEBUG("---------------" << T::type() << " LSDB-------------------");
+ auto lsaRange = m_lsdb.get<byType>().equal_range(T::type());
+ for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
+ auto lsaPtr = std::static_pointer_cast<T>(*lsaIt);
+ NLSR_LOG_DEBUG(lsaPtr->toString());
+ }
+}
+
+void
+Lsdb::writeLog() const
+{
+ writeLog<CoordinateLsa>();
+ writeLog<NameLsa>();
+ writeLog<AdjLsa>();
+}
+
+void
+Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
+{
+ ndn::Name interestName(interest.getName());
+ NLSR_LOG_DEBUG("Interest received for LSA: " << interestName);
+
+ if (interestName[-2].isVersion()) {
+ // Interest for particular segment
+ if (m_segmentPublisher.replyFromStore(interestName)) {
+ NLSR_LOG_TRACE("Reply from SegmentPublisher storage");
+ return;
+ }
+ // Remove version and segment
+ interestName = interestName.getSubName(0, interestName.size() - 2);
+ NLSR_LOG_TRACE("Interest w/o segment and version: " << interestName);
+ }
+
+ // increment RCV_LSA_INTEREST
+ lsaIncrementSignal(Statistics::PacketType::RCV_LSA_INTEREST);
+
+ std::string chkString("LSA");
+ int32_t lsaPosition = util::getNameComponentPosition(interestName, chkString);
+
+ // Forms the name of the router that the Interest packet came from.
+ ndn::Name originRouter = m_confParam.getNetwork();
+ originRouter.append(interestName.getSubName(lsaPosition + 1,
+ interestName.size() - lsaPosition - 3));
+
+ // if the interest is for this router's LSA
+ if (originRouter == m_thisRouterPrefix && lsaPosition >= 0) {
+ uint64_t seqNo = interestName[-1].toNumber();
+ NLSR_LOG_DEBUG("LSA sequence number from interest: " << seqNo);
+
+ std::string lsaType = interestName[-2].toUri();
+ Lsa::Type interestedLsType;
+ std::istringstream(lsaType) >> interestedLsType;
+ if (interestedLsType == Lsa::Type::BASE) {
+ NLSR_LOG_WARN("Received unrecognized LSA type: " << lsaType);
+ return;
+ }
+
+ incrementInterestRcvdStats(interestedLsType);
+ if (processInterestForLsa(interest, originRouter, interestedLsType, seqNo)) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_LSA_DATA);
+ }
+ }
+ // else the interest is for other router's LSA, serve signed data from LsaSegmentStorage
+ else if (auto lsaSegment = m_lsaStorage.find(interest)) {
+ NLSR_LOG_TRACE("Found data in lsa storage. Sending the data for " << interest.getName());
+ m_face.put(*lsaSegment);
+ }
+}
+
+bool
+Lsdb::processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
+ Lsa::Type lsaType, uint64_t seqNo)
+{
+ NLSR_LOG_DEBUG(interest << " received for " << lsaType);
+ if (auto lsaPtr = findLsa(originRouter, lsaType)) {
+ NLSR_LOG_TRACE("Verifying SeqNo for " << lsaType << " is same as requested.");
+ if (lsaPtr->getSeqNo() == seqNo) {
+ m_segmentPublisher.publish(interest.getName(), interest.getName(),
+ lsaPtr->wireEncode(),
+ m_lsaRefreshTime, m_confParam.getSigningInfo());
+ incrementDataSentStats(lsaType);
+ return true;
+ }
+ }
+ else {
+ NLSR_LOG_TRACE(interest << " was not found in our LSDB");
+ }
+ return false;
+}
+
+void
+Lsdb::installLsa(shared_ptr<Lsa> lsa)
+{
+ auto timeToExpire = m_lsaRefreshTime;
+
+ auto chkLsa = findLsa(lsa->getOriginRouter(), lsa->getType());
+ if (chkLsa == nullptr) {
+ NLSR_LOG_DEBUG("Adding " << lsa->getType() << " LSA");
+ NLSR_LOG_DEBUG(lsa->toString());
+ ndn::time::seconds timeToExpire = m_lsaRefreshTime;
+
+ m_lsdb.emplace(lsa);
+
+ // Add any new name prefixes to the NPT if from another router
+ if (lsa->getOriginRouter() != m_thisRouterPrefix) {
+ // Pass the origin router as both the name to register and where it came from.
+ m_namePrefixTable.addEntry(lsa->getOriginRouter(), lsa->getOriginRouter());
+
+ if (lsa->getType() == Lsa::Type::NAME) {
+ auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
+ for (const auto& name : nlsa->getNpl().getNames()) {
+ if (name != m_thisRouterPrefix) {
+ m_namePrefixTable.addEntry(name, nlsa->getOriginRouter());
+ }
+ }
+ }
+
+ auto duration = lsa->getExpirationTimePoint() - ndn::time::system_clock::now();
+ if (duration > ndn::time::seconds(0)) {
+ timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
+ }
+ }
+
+ if ((lsa->getType() == Lsa::Type::ADJACENCY && m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_ON)||
+ (lsa->getType() == Lsa::Type::COORDINATE && m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF)) {
+ m_routingTable.scheduleRoutingTableCalculation();
+ }
+
+ lsa->setExpiringEventId(scheduleLsaExpiration(lsa, timeToExpire));
+ }
+ // Else this is a known name LSA, so we are updating it.
+ else if (chkLsa->getSeqNo() < lsa->getSeqNo()) {
+ NLSR_LOG_DEBUG("Updating " << lsa->getType() << " LSA:");
+ NLSR_LOG_DEBUG(chkLsa->toString());
+ chkLsa->setSeqNo(lsa->getSeqNo());
+ chkLsa->setExpirationTimePoint(lsa->getExpirationTimePoint());
+
+ if (lsa->getType() == Lsa::Type::NAME) {
+ auto chkNameLsa = std::static_pointer_cast<NameLsa>(chkLsa);
+ auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
+ chkNameLsa->getNpl().sort();
+ nlsa->getNpl().sort();
+ if (!chkNameLsa->isEqualContent(*nlsa)) {
+ // Obtain the set difference of the current and the incoming
+ // name prefix sets, and add those.
+ std::list<ndn::Name> newNames = nlsa->getNpl().getNames();
+ std::list<ndn::Name> oldNames = chkNameLsa->getNpl().getNames();
+ std::list<ndn::Name> namesToAdd;
+ std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
+ std::inserter(namesToAdd, namesToAdd.begin()));
+ for (const auto& name : namesToAdd) {
+ chkNameLsa->addName(name);
+ if (nlsa->getOriginRouter() != m_thisRouterPrefix && name != m_thisRouterPrefix) {
+ m_namePrefixTable.addEntry(name, nlsa->getOriginRouter());
+ }
+ }
+
+ chkNameLsa->getNpl().sort();
+
+ // Also remove any names that are no longer being advertised.
+ std::list<ndn::Name> namesToRemove;
+ std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
+ std::inserter(namesToRemove, namesToRemove.begin()));
+ for (const auto& name : namesToRemove) {
+ NLSR_LOG_DEBUG("Removing name" << name << " from Name LSA no longer advertised.");
+ chkNameLsa->removeName(name);
+ if (nlsa->getOriginRouter() != m_thisRouterPrefix && name != m_thisRouterPrefix) {
+ m_namePrefixTable.removeEntry(name, nlsa->getOriginRouter());
+ }
+ }
+ }
+ }
+ else if (lsa->getType() == Lsa::Type::ADJACENCY) {
+ auto chkAdjLsa = std::static_pointer_cast<AdjLsa>(chkLsa);
+ auto alsa = std::static_pointer_cast<AdjLsa>(lsa);
+ if (!chkAdjLsa->isEqualContent(*alsa)) {
+ chkAdjLsa->resetAdl();
+ for (const auto& adjacent : alsa->getAdl()) {
+ chkAdjLsa->addAdjacent(adjacent);
+ }
+ m_routingTable.scheduleRoutingTableCalculation();
+ }
+ }
+ else {
+ auto chkCorLsa = std::static_pointer_cast<CoordinateLsa>(chkLsa);
+ auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
+ if (!chkCorLsa->isEqualContent(*clsa)) {
+ chkCorLsa->setCorRadius(clsa->getCorRadius());
+ chkCorLsa->setCorTheta(clsa->getCorTheta());
+ if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
+ m_routingTable.scheduleRoutingTableCalculation();
+ }
+ }
+ }
+
+ if (chkLsa->getOriginRouter() != m_thisRouterPrefix) {
+ auto duration = lsa->getExpirationTimePoint() - ndn::time::system_clock::now();
+ if (duration > ndn::time::seconds(0)) {
+ timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
+ }
+ }
+ chkLsa->getExpiringEventId().cancel();
+ chkLsa->setExpiringEventId(scheduleLsaExpiration(chkLsa, timeToExpire));
+ NLSR_LOG_DEBUG("Updated " << lsa->getType() << " LSA:");
+ NLSR_LOG_DEBUG(chkLsa->toString());
+ }
+}
+
+bool
+Lsdb::removeLsa(const ndn::Name& router, Lsa::Type lsaType)
+{
+ auto lsaIt = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
+
+ if (lsaIt != m_lsdb.end()) {
+ auto lsaPtr = *lsaIt;
+ NLSR_LOG_DEBUG("Removing " << lsaType << " LSA:");
+ NLSR_LOG_DEBUG(lsaPtr->toString());
+ // If the requested name LSA is not ours, we also need to remove
+ // its entries from the NPT.
+ if (lsaPtr->getOriginRouter() != m_thisRouterPrefix) {
+ m_namePrefixTable.removeEntry(lsaPtr->getOriginRouter(), lsaPtr->getOriginRouter());
+
+ if (lsaType == Lsa::Type::NAME) {
+ auto nlsaPtr = std::static_pointer_cast<NameLsa>(lsaPtr);
+ for (const auto& name : nlsaPtr->getNpl().getNames()) {
+ if (name != m_thisRouterPrefix) {
+ m_namePrefixTable.removeEntry(name, nlsaPtr->getOriginRouter());
+ }
+ }
+ }
+ }
+ m_lsdb.erase(lsaIt);
+ return true;
+ }
+ return false;
+}
+
void
Lsdb::buildAdjLsa()
{
- NLSR_LOG_TRACE("Lsdb::buildAdjLsa called");
+ NLSR_LOG_TRACE("buildAdjLsa called");
m_isBuildAdjLsaSheduled = false;
@@ -626,11 +382,8 @@
// routers to delete it, too.
else {
NLSR_LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors");
- // Get this router's key
- ndn::Name key = m_confParam.getRouterPrefix();
- key.append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
- removeAdjLsa(key);
+ removeLsa(m_thisRouterPrefix, Lsa::Type::ADJACENCY);
// Recompute routing table after removal
m_routingTable.scheduleRoutingTableCalculation();
}
@@ -651,303 +404,57 @@
}
}
-bool
-Lsdb::addAdjLsa(AdjLsa& alsa)
-{
- auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
- std::bind(adjLsaCompareByKey, _1, alsa.getKey()));
- if (it == m_adjLsdb.end()) {
- m_adjLsdb.push_back(alsa);
- // Add any new name prefixes to the NPT
- // Only add NPT entries if this is an adj LSA from another router.
- if (alsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- // Pass the originating router as both the name to register and
- // where it came from.
- m_namePrefixTable.addEntry(alsa.getOriginRouter(), alsa.getOriginRouter());
- }
- return true;
- }
- return false;
-}
-
-AdjLsa*
-Lsdb::findAdjLsa(const ndn::Name& key)
-{
- auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
- std::bind(adjLsaCompareByKey, _1, key));
- if (it != m_adjLsdb.end()) {
- return &*it;
- }
- return nullptr;
-}
-
-bool
-Lsdb::isAdjLsaNew(const ndn::Name& key, uint64_t seqNo)
-{
- AdjLsa* adjLsaCheck = findAdjLsa(key);
- // If it is in the LSDB
- if (adjLsaCheck != nullptr) {
- // And the supplied seq no is newer (higher) than the current one.
- if (adjLsaCheck->getSeqNo() < seqNo) {
- return true;
- }
- else {
- return false;
- }
- }
- return true;
-}
-
-ndn::scheduler::EventId
-Lsdb::scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
- const ndn::time::seconds& expTime)
-{
- return m_scheduler.schedule(expTime + GRACE_PERIOD,
- std::bind(&Lsdb::expireOrRefreshAdjLsa, this, key, seqNo));
-}
-
-bool
-Lsdb::installAdjLsa(AdjLsa& alsa)
-{
- ndn::time::seconds timeToExpire = m_lsaRefreshTime;
- AdjLsa* chkAdjLsa = findAdjLsa(alsa.getKey());
- // If this adj. LSA is not in the LSDB already
- if (chkAdjLsa == nullptr) {
- NLSR_LOG_DEBUG("New Adj LSA. Adding to LSDB");
- NLSR_LOG_DEBUG("Adding Adj Lsa");
- NLSR_LOG_DEBUG(alsa);
- addAdjLsa(alsa);
-
- m_routingTable.scheduleRoutingTableCalculation();
- if (alsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
- ndn::time::system_clock::now();
- timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
- }
- scheduleAdjLsaExpiration(alsa.getKey(), alsa.getSeqNo(), timeToExpire);
- }
- else {
- if (chkAdjLsa->getSeqNo() < alsa.getSeqNo()) {
- NLSR_LOG_DEBUG("Updated Adj LSA. Updating LSDB");
- NLSR_LOG_DEBUG("Deleting Adj Lsa");
- NLSR_LOG_DEBUG(chkAdjLsa);
- chkAdjLsa->setSeqNo(alsa.getSeqNo());
- chkAdjLsa->setExpirationTimePoint(alsa.getExpirationTimePoint());
- // If the new adj LSA has new content, update the contents of
- // the LSDB entry. Additionally, since we've changed the
- // contents of the LSDB, we have to schedule a routing
- // calculation.
- if (!chkAdjLsa->isEqualContent(alsa)) {
- chkAdjLsa->resetAdl();
- for (const auto& adjacent : alsa.getAdl()) {
- chkAdjLsa->addAdjacent(adjacent);
- }
- m_routingTable.scheduleRoutingTableCalculation();
- }
- if (alsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
- auto duration = alsa.getExpirationTimePoint() - ndn::time::system_clock::now();
- timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
- }
- chkAdjLsa->getExpiringEventId().cancel();
- chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(alsa.getKey(),
- alsa.getSeqNo(),
- timeToExpire));
- NLSR_LOG_DEBUG("Adding Adj Lsa");
- NLSR_LOG_DEBUG(chkAdjLsa);
- }
- }
- return true;
-}
-
-bool
+void
Lsdb::buildAndInstallOwnAdjLsa()
{
- AdjLsa adjLsa(m_confParam.getRouterPrefix(),
- m_sequencingManager.getAdjLsaSeq() + 1,
+ AdjLsa adjLsa(m_thisRouterPrefix, m_sequencingManager.getAdjLsaSeq() + 1,
getLsaExpirationTimePoint(),
m_confParam.getAdjacencyList().getNumOfActiveNeighbor(),
m_confParam.getAdjacencyList());
+ m_sequencingManager.increaseAdjLsaSeq();
+ m_sequencingManager.writeSeqNoToFile();
//Sync adjacency LSAs if link-state or dry-run HR is enabled.
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_ON) {
- m_sequencingManager.increaseAdjLsaSeq();
- m_sequencingManager.writeSeqNoToFile();
m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
}
- return installAdjLsa(adjLsa);
+ installLsa(std::make_shared<AdjLsa>(adjLsa));
}
-bool
-Lsdb::removeAdjLsa(const ndn::Name& key)
-{
- auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
- std::bind(adjLsaCompareByKey, _1, key));
- if (it != m_adjLsdb.end()) {
- NLSR_LOG_DEBUG("Deleting Adj Lsa");
- NLSR_LOG_DEBUG(*it);
- if (it->getOriginRouter() != m_confParam.getRouterPrefix()) {
- m_namePrefixTable.removeEntry(it->getOriginRouter(), it->getOriginRouter());
- }
- m_adjLsdb.erase(it);
- return true;
- }
- return false;
-}
-
-bool
-Lsdb::doesAdjLsaExist(const ndn::Name& key)
-{
- auto it = std::find_if(m_adjLsdb.begin(), m_adjLsdb.end(),
- std::bind(adjLsaCompareByKey, _1, key));
- return it != m_adjLsdb.end();
-}
-
-const std::list<AdjLsa>&
-Lsdb::getAdjLsdb() const
-{
- return m_adjLsdb;
-}
-
- // This function determines whether a name LSA should be refreshed
- // or expired. The conditions for getting refreshed are: it is still
- // in the LSDB, it hasn't been updated by something else already (as
- // evidenced by its seq. no.), and this is the originating router for
- // the LSA. Is it let expire in all other cases.
- // lsaKey is the key of the LSA's publishing router.
- // seqNo is the seq. no. of the candidate LSA.
void
-Lsdb::expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo)
+Lsdb::expireOrRefreshLsa(std::shared_ptr<Lsa> lsa)
{
- NLSR_LOG_DEBUG("Lsdb::expireOrRefreshNameLsa Called");
- NLSR_LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
- NameLsa* chkNameLsa = findNameLsa(lsaKey);
+ NLSR_LOG_DEBUG("ExpireOrRefreshLsa called for " << lsa->getType());
+ NLSR_LOG_DEBUG("OriginRouter: " << lsa->getOriginRouter() << " Seq No: " << lsa->getSeqNo());
+
+ auto lsaIt = m_lsdb.get<byName>().find(std::make_tuple(lsa->getOriginRouter(), lsa->getType()));
+
// If this name LSA exists in the LSDB
- if (chkNameLsa != nullptr) {
- NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getSeqNo());
+ if (lsaIt != m_lsdb.end()) {
+ auto lsaPtr = *lsaIt;
+ NLSR_LOG_DEBUG(lsaPtr->toString());
+ NLSR_LOG_DEBUG("LSA Exists with seq no: " << lsaPtr->getSeqNo());
// If its seq no is the one we are expecting.
- if (chkNameLsa->getSeqNo() == seqNo) {
- if (chkNameLsa->getOriginRouter() == m_thisRouterPrefix) {
- NLSR_LOG_DEBUG("Own Name LSA, so refreshing it");
- NLSR_LOG_DEBUG("Deleting Name Lsa");
- NLSR_LOG_DEBUG(chkNameLsa);
- chkNameLsa->setSeqNo(chkNameLsa->getSeqNo() + 1);
- m_sequencingManager.setNameLsaSeq(chkNameLsa->getSeqNo());
- chkNameLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
- NLSR_LOG_DEBUG("Adding Name Lsa");
- NLSR_LOG_DEBUG(chkNameLsa);
+ if (lsaPtr->getSeqNo() == lsa->getSeqNo()) {
+ if (lsaPtr->getOriginRouter() == m_thisRouterPrefix) {
+ NLSR_LOG_DEBUG("Own " << lsaPtr->getType() << " LSA, so refreshing it.");
+ NLSR_LOG_DEBUG("Current LSA:");
+ NLSR_LOG_DEBUG(lsaPtr->toString());
+ lsaPtr->setSeqNo(lsaPtr->getSeqNo() + 1);
+ m_sequencingManager.setLsaSeq(lsaPtr->getSeqNo(), lsaPtr->getType());
+ lsaPtr->setExpirationTimePoint(getLsaExpirationTimePoint());
+ NLSR_LOG_DEBUG("Updated LSA:");
+ NLSR_LOG_DEBUG(lsaPtr->toString());
// schedule refreshing event again
- chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(chkNameLsa->getKey(),
- chkNameLsa->getSeqNo(),
- m_lsaRefreshTime));
+ lsaPtr->setExpiringEventId(scheduleLsaExpiration(lsaPtr, m_lsaRefreshTime));
m_sequencingManager.writeSeqNoToFile();
- m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
+ m_sync.publishRoutingUpdate(lsaPtr->getType(), m_sequencingManager.getLsaSeq(lsaPtr->getType()));
}
// Since we cannot refresh other router's LSAs, our only choice is to expire.
else {
- NLSR_LOG_DEBUG("Other's Name LSA, so removing from LSDB");
- removeNameLsa(lsaKey);
- }
- }
- }
-}
-
- // This function determines whether an adj. LSA should be refreshed
- // or expired. The conditions for getting refreshed are: it is still
- // in the LSDB, it hasn't been updated by something else already (as
- // evidenced by its seq. no.), and this is the originating router for
- // the LSA. Is it let expire in all other cases.
- // lsaKey is the key of the LSA's publishing router.
- // seqNo is the seq. no. of the candidate LSA.
-void
-Lsdb::expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo)
-{
- NLSR_LOG_DEBUG("Lsdb::expireOrRefreshAdjLsa Called");
- NLSR_LOG_DEBUG("LSA Key: " << lsaKey << " Seq No: " << seqNo);
- AdjLsa* chkAdjLsa = findAdjLsa(lsaKey);
- // If this is a valid LSA
- if (chkAdjLsa != nullptr) {
- NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getSeqNo());
- // And if it hasn't been updated for some other reason
- if (chkAdjLsa->getSeqNo() == seqNo) {
- // If it is our own LSA
- if (chkAdjLsa->getOriginRouter() == m_thisRouterPrefix) {
- NLSR_LOG_DEBUG("Own Adj LSA, so refreshing it");
- NLSR_LOG_DEBUG("Deleting Adj Lsa");
- NLSR_LOG_DEBUG(chkAdjLsa);
- chkAdjLsa->setSeqNo(chkAdjLsa->getSeqNo() + 1);
- m_sequencingManager.setAdjLsaSeq(chkAdjLsa->getSeqNo());
- chkAdjLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
- NLSR_LOG_DEBUG("Adding Adj Lsa");
- NLSR_LOG_DEBUG(chkAdjLsa);
- // schedule refreshing event again
- chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(chkAdjLsa->getKey(),
- chkAdjLsa->getSeqNo(),
- m_lsaRefreshTime));
- m_sequencingManager.writeSeqNoToFile();
- m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
- }
- // An LSA from another router is expiring
- else {
- NLSR_LOG_DEBUG("Other's Adj LSA, so removing from LSDB");
- removeAdjLsa(lsaKey);
- }
- // We have changed the contents of the LSDB, so we have to
- // schedule a routing calculation
- m_routingTable.scheduleRoutingTableCalculation();
- }
- }
-}
-
- // This function determines whether an adj. LSA should be refreshed
- // or expired. The conditions for getting refreshed are: it is still
- // in the LSDB, it hasn't been updated by something else already (as
- // evidenced by its seq. no.), and this is the originating router for
- // the LSA. It is let expire in all other cases.
- // lsaKey is the key of the LSA's publishing router.
- // seqNo is the seq. no. of the candidate LSA.
-void
-Lsdb::expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
- uint64_t seqNo)
-{
- NLSR_LOG_DEBUG("Lsdb::expireOrRefreshCorLsa Called ");
- NLSR_LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
- CoordinateLsa* chkCorLsa = findCoordinateLsa(lsaKey);
- // Whether the LSA is in the LSDB or not.
- if (chkCorLsa != nullptr) {
- NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getSeqNo());
- // Whether the LSA has been updated without our knowledge.
- if (chkCorLsa->getSeqNo() == seqNo) {
- if (chkCorLsa->getOriginRouter() == m_thisRouterPrefix) {
- NLSR_LOG_DEBUG("Own Cor LSA, so refreshing it");
- NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
- NLSR_LOG_DEBUG(chkCorLsa);
- chkCorLsa->setSeqNo(chkCorLsa->getSeqNo() + 1);
- if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
- m_sequencingManager.setCorLsaSeq(chkCorLsa->getSeqNo());
- }
-
- chkCorLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
- NLSR_LOG_DEBUG("Adding Coordinate Lsa");
- NLSR_LOG_DEBUG(chkCorLsa);
- // schedule refreshing event again
- chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(
- chkCorLsa->getKey(),
- chkCorLsa->getSeqNo(),
- m_lsaRefreshTime));
- // Only sync coordinate LSAs if link-state routing is disabled
- if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
- m_sequencingManager.writeSeqNoToFile();
- m_sync.publishRoutingUpdate(Lsa::Type::COORDINATE, m_sequencingManager.getCorLsaSeq());
- }
- }
- // We can't refresh other router's LSAs, so we remove it.
- else {
- NLSR_LOG_DEBUG("Other's Cor LSA, so removing from LSDB");
- removeCoordinateLsa(lsaKey);
- }
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
- m_routingTable.scheduleRoutingTableCalculation();
+ NLSR_LOG_DEBUG("Other's " << lsaPtr->getType() << " LSA, so removing from LSDB");
+ removeLsa(lsaPtr->getOriginRouter(), lsaPtr->getType());
}
}
}
@@ -1015,281 +522,99 @@
m_fetchers.erase(it);
});
- // increment a specific SENT_LSA_INTEREST
Lsa::Type lsaType;
std::istringstream(interestName[-2].toUri()) >> lsaType;
- switch (lsaType) {
- case Lsa::Type::ADJACENCY:
- lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
- break;
- case Lsa::Type::COORDINATE:
- lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_INTEREST);
- break;
- case Lsa::Type::NAME:
- lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_INTEREST);
- break;
- default:
- NLSR_LOG_ERROR("lsaType " << lsaType << " not recognized; failed Statistics::PacketType conversion");
+ incrementInterestSentStats(lsaType);
+}
+
+void
+Lsdb::onFetchLsaError(uint32_t errorCode, const std::string& msg, const ndn::Name& interestName,
+ uint32_t retransmitNo, const ndn::time::steady_clock::TimePoint& deadline,
+ ndn::Name lsaName, uint64_t seqNo)
+{
+ NLSR_LOG_DEBUG("Failed to fetch LSA: " << lsaName << ", Error code: " << errorCode
+ << ", Message: " << msg);
+
+ if (ndn::time::steady_clock::now() < deadline) {
+ auto it = m_highestSeqNo.find(lsaName);
+ if (it != m_highestSeqNo.end() && it->second == seqNo) {
+ // If the SegmentFetcher failed due to an Interest timeout, it is safe to re-express
+ // immediately since at the least the LSA Interest lifetime has elapsed.
+ // Otherwise, it is necessary to delay the Interest re-expression to prevent
+ // the potential for constant Interest flooding.
+ ndn::time::seconds delay = m_confParam.getLsaInterestLifetime();
+
+ if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
+ delay = ndn::time::seconds(0);
+ }
+ m_scheduler.schedule(delay, std::bind(&Lsdb::expressInterest, this,
+ interestName, retransmitNo + 1, deadline));
+ }
}
}
void
-Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
+Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName)
{
- ndn::Name interestName(interest.getName());
- NLSR_LOG_DEBUG("Interest received for LSA: " << interestName);
+ NLSR_LOG_DEBUG("Received data for LSA interest: " << interestName);
+ lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
- if (interestName[-2].isVersion()) {
- // Interest for particular segment
- if (m_segmentPublisher.replyFromStore(interestName)) {
- NLSR_LOG_TRACE("Reply from SegmentPublisher storage");
- return;
- }
- // Remove version and segment
- interestName = interestName.getSubName(0, interestName.size() - 2);
- NLSR_LOG_TRACE("Interest w/o segment and version: " << interestName);
+ ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
+ uint64_t seqNo = interestName[-1].toNumber();
+
+ if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
+ m_highestSeqNo[lsaName] = seqNo;
}
-
- // increment RCV_LSA_INTEREST
- lsaIncrementSignal(Statistics::PacketType::RCV_LSA_INTEREST);
+ else if (seqNo > m_highestSeqNo[lsaName]) {
+ m_highestSeqNo[lsaName] = seqNo;
+ NLSR_LOG_TRACE("SeqNo for LSA(name): " << interestName << " updated");
+ }
+ else if (seqNo < m_highestSeqNo[lsaName]) {
+ return;
+ }
std::string chkString("LSA");
int32_t lsaPosition = util::getNameComponentPosition(interestName, chkString);
- // Forms the name of the router that the Interest packet came from.
- ndn::Name originRouter = m_confParam.getNetwork();
- originRouter.append(interestName.getSubName(lsaPosition + 1,
- interestName.size() - lsaPosition - 3));
+ if (lsaPosition >= 0) {
+ // Extracts the prefix of the originating router from the data.
+ ndn::Name originRouter = m_confParam.getNetwork();
+ originRouter.append(interestName.getSubName(lsaPosition + 1,
+ interestName.size() - lsaPosition - 3));
- // if the interest is for this router's LSA
- if (originRouter == m_confParam.getRouterPrefix() && lsaPosition >= 0) {
- uint64_t seqNo = interestName[-1].toNumber();
- NLSR_LOG_DEBUG("LSA sequence number from interest: " << seqNo);
+ try {
+ Lsa::Type interestedLsType;
+ std::istringstream(interestName[-2].toUri()) >> interestedLsType;
- std::string lsaType = interestName[-2].toUri();
- Lsa::Type interestedLsType;
- std::istringstream(lsaType) >> interestedLsType;
+ if (interestedLsType == Lsa::Type::BASE) {
+ NLSR_LOG_WARN("Received unrecognized LSA Type: " << interestName[-2].toUri());
+ return;
+ }
- if (interestedLsType == Lsa::Type::NAME) {
- processInterestForNameLsa(interest, originRouter.append(lsaType), seqNo);
+ ndn::Block block(bufferPtr);
+ if (interestedLsType == Lsa::Type::NAME) {
+ lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_DATA);
+ if (isLsaNew(originRouter, interestedLsType, seqNo)) {
+ installLsa(std::make_shared<NameLsa>(block));
+ }
+ }
+ else if (interestedLsType == Lsa::Type::ADJACENCY) {
+ lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_DATA);
+ if (isLsaNew(originRouter, interestedLsType, seqNo)) {
+ installLsa(std::make_shared<AdjLsa>(block));
+ }
+ }
+ else if (interestedLsType == Lsa::Type::COORDINATE) {
+ lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_DATA);
+ if (isLsaNew(originRouter, interestedLsType, seqNo)) {
+ installLsa(std::make_shared<CoordinateLsa>(block));
+ }
+ }
}
- else if (interestedLsType == Lsa::Type::ADJACENCY) {
- processInterestForAdjacencyLsa(interest, originRouter.append(lsaType), seqNo);
+ catch (const std::exception& e) {
+ NLSR_LOG_TRACE("LSA data decoding error :( " << e.what());
+ return;
}
- else if (interestedLsType == Lsa::Type::COORDINATE) {
- processInterestForCoordinateLsa(interest, originRouter.append(lsaType), seqNo);
- }
- else {
- NLSR_LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
- }
- lsaIncrementSignal(Statistics::PacketType::SENT_LSA_DATA);
- }
- else { // else the interest is for other router's lsa, serve from LsaSegmentStorage
- std::shared_ptr<const ndn::Data> lsaSegment = m_lsaStorage.find(interest);
- if (lsaSegment) {
- NLSR_LOG_TRACE("Found data in lsa storage. Sending the data for " << interest.getName());
- m_face.put(*lsaSegment);
- }
- else {
- NLSR_LOG_TRACE(interest << " was not found in this lsa storage.");
- }
- }
-}
-
- // \brief Finds and sends a requested name LSA.
- // \param interest The interest that seeks the name LSA.
- // \param lsaKey The LSA that the Interest is seeking.
- // \param seqNo A sequence number to ensure that we are sending the
- // version that was requested.
-void
-Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
- const ndn::Name& lsaKey,
- uint64_t seqNo)
-{
- // increment RCV_NAME_LSA_INTEREST
- lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_INTEREST);
- NLSR_LOG_DEBUG("nameLsa interest " << interest << " received");
- NameLsa* nameLsa = findNameLsa(lsaKey);
- if (nameLsa != nullptr) {
- NLSR_LOG_TRACE("Verifying SeqNo for NameLsa is same as requested.");
- if (nameLsa->getSeqNo() == seqNo) {
- m_segmentPublisher.publish(interest.getName(), interest.getName(),
- nameLsa->wireEncode(),
- m_lsaRefreshTime, m_confParam.getSigningInfo());
-
- lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
- }
- else {
- NLSR_LOG_TRACE("SeqNo for nameLsa does not match");
- }
- }
- else {
- NLSR_LOG_TRACE(interest << " was not found in this lsdb");
- }
-}
-
- // \brief Finds and sends a requested adj. LSA.
- // \param interest The interest that seeks the adj. LSA.
- // \param lsaKey The LSA that the Interest is seeking.
- // \param seqNo A sequence number to ensure that we are sending the
- // version that was requested.
-void
-Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
- const ndn::Name& lsaKey,
- uint64_t seqNo)
-{
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
- NLSR_LOG_ERROR("Received interest for an adjacency LSA when hyperbolic routing is enabled");
- }
-
- lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_INTEREST);
- NLSR_LOG_DEBUG("AdjLsa interest " << interest << " received");
- AdjLsa* adjLsa = findAdjLsa(lsaKey);
- if (adjLsa != nullptr) {
- NLSR_LOG_TRACE("Verifying SeqNo for AdjLsa is same as requested.");
- if (adjLsa->getSeqNo() == seqNo) {
- m_segmentPublisher.publish(interest.getName(), interest.getName(),
- adjLsa->wireEncode(),
- m_lsaRefreshTime, m_confParam.getSigningInfo());
-
- lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
- }
- else {
- NLSR_LOG_TRACE("SeqNo for AdjLsa does not match");
- }
- }
- else {
- NLSR_LOG_TRACE(interest << " was not found in this lsdb");
- }
-}
-
- // \brief Finds and sends a requested cor. LSA.
- // \param interest The interest that seeks the cor. LSA.
- // \param lsaKey The LSA that the Interest is seeking.
- // \param seqNo A sequence number to ensure that we are sending the
- // version that was requested.
-void
-Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
- const ndn::Name& lsaKey,
- uint64_t seqNo)
-{
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
- NLSR_LOG_ERROR("Received Interest for a coordinate LSA when link-state routing is enabled");
- }
-
- lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_INTEREST);
- NLSR_LOG_DEBUG("CoordinateLsa interest " << interest << " received");
- CoordinateLsa* corLsa = findCoordinateLsa(lsaKey);
- if (corLsa != nullptr) {
- NLSR_LOG_TRACE("Verifying SeqNo for CoordinateLsa is same as requested.");
- if (corLsa->getSeqNo() == seqNo) {
- m_segmentPublisher.publish(interest.getName(), interest.getName(),
- corLsa->wireEncode(),
- m_lsaRefreshTime, m_confParam.getSigningInfo());
-
- lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
- }
- else {
- NLSR_LOG_TRACE("SeqNo for CoordinateLsa does not match");
- }
- }
- else {
- NLSR_LOG_TRACE(interest << " was not found in this lsdb");
- }
-}
-
-void
-Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
- uint64_t lsSeqNo, const ndn::Block& block)
-{
- lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_DATA);
- if (isNameLsaNew(lsaKey, lsSeqNo)) {
- NameLsa nameLsa(block);
- installNameLsa(nameLsa);
- }
-}
-
-void
-Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
- uint64_t lsSeqNo, const ndn::Block& block)
-{
- lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_DATA);
- if (isAdjLsaNew(lsaKey, lsSeqNo)) {
- AdjLsa adjLsa(block);
- installAdjLsa(adjLsa);
- }
-}
-
-void
-Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
- uint64_t lsSeqNo, const ndn::Block& block)
-{
- lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_DATA);
- if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
- CoordinateLsa corLsa(block);
- installCoordinateLsa(corLsa);
- }
-}
-
-ndn::time::system_clock::TimePoint
-Lsdb::getLsaExpirationTimePoint()
-{
- ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
- expirationTimePoint = expirationTimePoint +
- ndn::time::seconds(m_confParam.getRouterDeadInterval());
- return expirationTimePoint;
-}
-
-void
-Lsdb::writeAdjLsdbLog()
-{
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
- return;
- }
-
- NLSR_LOG_TRACE("---------------Adj LSDB-------------------");
- for (const auto& adj : m_adjLsdb) {
- NLSR_LOG_TRACE(adj);
- }
-}
-
-//-----utility function -----
-bool
-Lsdb::doesLsaExist(const ndn::Name& key, const Lsa::Type& lsType)
-{
- switch (lsType) {
- case Lsa::Type::ADJACENCY:
- return doesAdjLsaExist(key);
-
- case Lsa::Type::COORDINATE:
- return doesCoordinateLsaExist(key);
-
- case Lsa::Type::NAME:
- return doesNameLsaExist(key);
-
- default:
- return false;
- }
-}
-
-bool
-Lsdb::isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType,
- const uint64_t& sequenceNumber) {
- ndn::Name lsaKey = routerName;
- lsaKey.append(boost::lexical_cast<std::string>(lsaType));
-
- switch (lsaType) {
- case Lsa::Type::ADJACENCY:
- return isAdjLsaNew(lsaKey, sequenceNumber);
-
- case Lsa::Type::COORDINATE:
- return isCoordinateLsaNew(lsaKey, sequenceNumber);
-
- case Lsa::Type::NAME:
- return isNameLsaNew(lsaKey, sequenceNumber);
-
- default:
- return false;
}
}
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
index bdb1d32..a342284 100644
--- a/src/lsdb.hpp
+++ b/src/lsdb.hpp
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#ifndef NLSR_LSDB_HPP
#define NLSR_LSDB_HPP
@@ -39,6 +39,10 @@
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/composite_key.hpp>
+
#include <PSync/segment-publisher.hpp>
#include <utility>
@@ -46,153 +50,52 @@
namespace nlsr {
+namespace bmi = boost::multi_index;
+using namespace ndn::literals::time_literals;
+
+static constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
+
class Lsdb
{
public:
Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam,
NamePrefixTable& namePrefixTable, RoutingTable& routingTable);
- ~Lsdb();
+ ~Lsdb()
+ {
+ for (const auto& sp : m_fetchers) {
+ sp->stop();
+ }
+ }
+ /*! \brief Returns whether the LSDB contains some LSA.
+ */
bool
- isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType, const uint64_t& sequenceNumber);
-
- bool
- doesLsaExist(const ndn::Name& key, const Lsa::Type& lsType);
+ doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
+ {
+ return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
+ }
/*! \brief Builds a name LSA for this router and then installs it
into the LSDB.
*/
- bool
+ void
buildAndInstallOwnNameLsa();
- /*! \brief Returns the name LSA with the given key.
- \param key The name of the router that the desired LSA comes from.
- */
- NameLsa*
- findNameLsa(const ndn::Name& key);
-
- /*! \brief Installs a name LSA into the LSDB
- \param nlsa The name LSA to install into the LSDB.
- */
- bool
- installNameLsa(NameLsa& nlsa);
-
- /*! \brief Remove a name LSA from the LSDB.
- \param key The name of the router that published the LSA to remove.
-
- This function will remove a name LSA from the LSDB by finding an
- LSA whose name matches key. This removal also causes the NPT to
- remove those name prefixes if no more LSAs advertise them.
- */
- bool
- removeNameLsa(const ndn::Name& key);
-
- /*! Returns whether a seq. no. from a certain router signals a new LSA.
- \param key The name of the originating router.
- \param seqNo The sequence number to check.
- */
- bool
- isNameLsaNew(const ndn::Name& key, uint64_t seqNo);
-
- void
- writeNameLsdbLog();
-
- const std::list<NameLsa>&
- getNameLsdb() const;
-
/*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
- bool
- buildAndInstallOwnCoordinateLsa();
-
- /*! \brief Finds a cor. LSA in the LSDB.
- \param key The name of the originating router that published the LSA.
- */
- CoordinateLsa*
- findCoordinateLsa(const ndn::Name& key);
-
- /*! \brief Installs a cor. LSA into the LSDB.
- \param clsa The cor. LSA to install.
- */
- bool
- installCoordinateLsa(CoordinateLsa& clsa);
-
- /*! \brief Removes a cor. LSA from the LSDB.
- \param key The name of the router that published the LSA to remove.
-
- Removes the coordinate LSA whose origin router name matches that
- given by key. Additionally, ask the NPT to remove the prefix,
- which will occur if no other LSAs point there.
- */
- bool
- removeCoordinateLsa(const ndn::Name& key);
-
- /*! \brief Returns whether a cor. LSA from a router is new or not.
- \param key The name prefix of the originating router.
- \param seqNo The sequence number of the candidate LSA.
- */
- bool
- isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo);
-
void
- writeCorLsdbLog();
-
- const std::list<CoordinateLsa>&
- getCoordinateLsdb() const;
-
- //function related to Adj LSDB
+ buildAndInstallOwnCoordinateLsa();
/*! \brief Schedules a build of this router's LSA. */
void
scheduleAdjLsaBuild();
- /*! \brief Wrapper event to build and install an adj. LSA for this router. */
- bool
- buildAndInstallOwnAdjLsa();
-
- /*! \brief Removes an adj. LSA from the LSDB.
- \param key The name of the publishing router whose LSA to remove.
- */
- bool
- removeAdjLsa(const ndn::Name& key);
-
- /*! \brief Returns whether an LSA is new.
- \param key The name of the publishing router.
- \param seqNo The seq. no. of the candidate LSA.
-
- This function determines whether the LSA with the name key and
- seq. no. seqNo would be new to this LSDB.
- */
- bool
- isAdjLsaNew(const ndn::Name& key, uint64_t seqNo);
-
- /*! \brief Installs an adj. LSA into the LSDB.
- \param alsa The adj. LSA to add to the LSDB.
- */
- bool
- installAdjLsa(AdjLsa& alsa);
-
- /*! \brief Finds an adj. LSA in the LSDB.
- \param key The name of the publishing router whose LSA to find.
- */
- AdjLsa*
- findAdjLsa(const ndn::Name& key);
-
- const std::list<AdjLsa>&
- getAdjLsdb() const;
+ template<typename T>
+ void
+ writeLog() const;
void
- setAdjLsaBuildInterval(uint32_t interval)
- {
- m_adjLsaBuildInterval = ndn::time::seconds(interval);
- }
-
- void
- writeAdjLsdbLog();
-
- void
- expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
- ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
+ writeLog() const;
/* \brief Process interest which can be either:
* 1) Discovery interest from segment fetcher:
@@ -204,40 +107,143 @@
processInterest(const ndn::Name& name, const ndn::Interest& interest);
bool
- getIsBuildAdjLsaSheduled()
+ getIsBuildAdjLsaSheduled() const
{
return m_isBuildAdjLsaSheduled;
}
SyncLogicHandler&
- getSync() {
+ getSync()
+ {
return m_sync;
}
-private:
- /* \brief Add a name LSA to the LSDB if it isn't already there.
- \param nlsa The candidade name LSA.
+ template<typename T>
+ std::shared_ptr<T>
+ findLsa(const ndn::Name& router) const
+ {
+ return std::static_pointer_cast<T>(findLsa(router, T::type()));
+ }
+
+ struct name_hash {
+ int
+ operator()(const ndn::Name& name) const {
+ return std::hash<ndn::Name>{}(name);
+ }
+ };
+
+ struct enum_class_hash {
+ template<typename T>
+ int
+ operator()(T t) const {
+ return static_cast<int>(t);
+ }
+ };
+
+ struct byName{};
+ struct byType{};
+
+ using LsaContainer = boost::multi_index_container<
+ std::shared_ptr<Lsa>,
+ bmi::indexed_by<
+ bmi::hashed_unique<
+ bmi::tag<byName>,
+ bmi::composite_key<
+ Lsa,
+ bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
+ bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
+ >,
+ bmi::composite_key_hash<name_hash, enum_class_hash>
+ >,
+ bmi::hashed_non_unique<
+ bmi::tag<byType>,
+ bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
+ enum_class_hash
+ >
+ >
+ >;
+
+ template<typename T>
+ std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
+ LsaContainer::index<Lsdb::byType>::type::iterator>
+ getLsdbIterator() const
+ {
+ return m_lsdb.get<byType>().equal_range(T::type());
+ }
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ std::shared_ptr<Lsa>
+ findLsa(const ndn::Name& router, Lsa::Type lsaType) const
+ {
+ auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
+ return it != m_lsdb.end() ? *it : nullptr;
+ }
+
+ void
+ incrementDataSentStats(Lsa::Type lsaType) {
+ if (lsaType == Lsa::Type::NAME) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
+ }
+ else if (lsaType == Lsa::Type::ADJACENCY) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
+ }
+ else if (lsaType == Lsa::Type::COORDINATE) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
+ }
+ }
+
+ void
+ incrementInterestRcvdStats(Lsa::Type lsaType) {
+ if (lsaType == Lsa::Type::NAME) {
+ lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_INTEREST);
+ }
+ else if (lsaType == Lsa::Type::ADJACENCY) {
+ lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_INTEREST);
+ }
+ else if (lsaType == Lsa::Type::COORDINATE) {
+ lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_INTEREST);
+ }
+ }
+
+ void
+ incrementInterestSentStats(Lsa::Type lsaType) {
+ if (lsaType == Lsa::Type::NAME) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_INTEREST);
+ }
+ else if (lsaType == Lsa::Type::ADJACENCY) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
+ }
+ else if (lsaType == Lsa::Type::COORDINATE) {
+ lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_INTEREST);
+ }
+ }
+
+ /*! Returns whether a seq. no. from a certain router signals a new LSA.
+ \param originRouter The name of the originating router.
+ \param lsaType The type of the LSA.
+ \param seqNo The sequence number to check.
*/
bool
- addNameLsa(NameLsa& nlsa);
+ isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t lsSeqNo)
+ {
+ // Is the name in the LSDB and the supplied seq no is the highest so far
+ auto lsaPtr = findLsa(originRouter, lsaType);
+ return lsaPtr ? lsaPtr->getSeqNo() < lsSeqNo : true;
+ }
- /*! \brief Returns whether the LSDB contains some LSA.
- \param key The name of the publishing router whose LSA to check for.
+ void
+ installLsa(shared_ptr<Lsa> lsa);
+
+ /*! \brief Remove a name LSA from the LSDB.
+ \param router The name of the router that published the LSA to remove.
+ \param lsaType The type of the LSA.
+
+ This function will remove a name LSA from the LSDB by finding an
+ LSA whose name matches key. This removal also causes the NPT to
+ remove those name prefixes if no more LSAs advertise them.
*/
bool
- doesNameLsaExist(const ndn::Name& key);
-
- /*! \brief Adds a cor. LSA to the LSDB if it isn't already there.
- \param clsa The candidate cor. LSA.
- */
- bool
- addCoordinateLsa(CoordinateLsa& clsa);
-
- /*! \brief Returns whether a cor. LSA is in the LSDB.
- \param key The name of the router that published the queried LSA.
- */
- bool
- doesCoordinateLsaExist(const ndn::Name& key);
+ removeLsa(const ndn::Name& router, Lsa::Type lsaType);
/*! \brief Attempts to construct an adj. LSA.
@@ -249,84 +255,34 @@
void
buildAdjLsa();
- /*! \brief Adds an adj. LSA to the LSDB if it isn't already there.
- \param alsa The candidate adj. LSA to add to the LSDB.
- */
- bool
- addAdjLsa(AdjLsa& alsa);
-
- /*! \brief Returns whether the LSDB contains an LSA.
- \param key The name of a router whose LSA to check for in the LSDB.
- */
- bool
- doesAdjLsaExist(const ndn::Name& key);
+ /*! \brief Wrapper event to build and install an adj. LSA for this router. */
+ void
+ buildAndInstallOwnAdjLsa();
/*! \brief Schedules a refresh/expire event in the scheduler.
- \param key The name of the router that published the LSA.
- \param seqNo The seq. no. associated with the LSA.
+ \param lsa The LSA.
\param expTime How many seconds to wait before triggering the event.
*/
ndn::scheduler::EventId
- scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
- const ndn::time::seconds& expTime);
+ scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime)
+ {
+ return m_scheduler.schedule(expTime + GRACE_PERIOD, [this, lsa] { expireOrRefreshLsa(lsa); });
+ }
/*! \brief Either allow to expire, or refresh a name LSA.
- \param lsaKey The name of the router that published the LSA.
- \param seqNo The seq. no. of the LSA to check.
+ \param lsa The LSA.
*/
void
- expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo);
+ expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- /*! \brief Schedules an expire/refresh event in the LSA.
- \param key The name of the router whose LSA is in question.
- \param seqNo The sequence number of the LSA to check.
- \param expTime The number of seconds to wait before triggering the event.
- */
- ndn::scheduler::EventId
- scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
- const ndn::time::seconds& expTime);
-
-private:
- void
- expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo);
-
- ndn::scheduler::EventId
- scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
- const ndn::time::seconds& expTime);
+ bool
+ processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
+ Lsa::Type lsaType, uint64_t seqNo);
void
- expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
- uint64_t seqNo);
+ expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
+ ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
- void
- processInterestForNameLsa(const ndn::Interest& interest,
- const ndn::Name& lsaKey,
- uint64_t seqNo);
-
- void
- processInterestForAdjacencyLsa(const ndn::Interest& interest,
- const ndn::Name& lsaKey,
- uint64_t seqNo);
-
- void
- processInterestForCoordinateLsa(const ndn::Interest& interest,
- const ndn::Name& lsaKey,
- uint64_t seqNo);
-
- void
- processContentNameLsa(const ndn::Name& lsaKey,
- uint64_t lsSeqNo, const ndn::Block& block);
-
- void
- processContentAdjacencyLsa(const ndn::Name& lsaKey,
- uint64_t lsSeqNo, const ndn::Block& block);
-
- void
- processContentCoordinateLsa(const ndn::Name& lsaKey,
- uint64_t lsSeqNo, const ndn::Block& block);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*!
\brief Error callback when SegmentFetcher fails to return an LSA
@@ -342,13 +298,10 @@
is reached.
*/
void
- onFetchLsaError(uint32_t errorCode,
- const std::string& msg,
- const ndn::Name& interestName,
- uint32_t retransmitNo,
+ onFetchLsaError(uint32_t errorCode, const std::string& msg,
+ const ndn::Name& interestName, uint32_t retransmitNo,
const ndn::time::steady_clock::TimePoint& deadline,
- ndn::Name lsaName,
- uint64_t seqNo);
+ ndn::Name lsaName, uint64_t seqNo);
/*!
\brief Success callback when SegmentFetcher returns a valid LSA
@@ -365,17 +318,17 @@
afterSegmentValidatedSignal(data);
}
-private:
ndn::time::system_clock::TimePoint
- getLsaExpirationTimePoint();
+ getLsaExpirationTimePoint() const
+ {
+ return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
+ }
public:
- static const ndn::Name::Component NAME_COMPONENT;
-
ndn::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
ndn::util::signal::Signal<Lsdb, const ndn::Data&> afterSegmentValidatedSignal;
-private:
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ndn::Face& m_face;
ndn::Scheduler m_scheduler;
@@ -383,32 +336,20 @@
NamePrefixTable& m_namePrefixTable;
RoutingTable& m_routingTable;
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
SyncLogicHandler m_sync;
-private:
- std::list<NameLsa> m_nameLsdb;
- std::list<AdjLsa> m_adjLsdb;
- std::list<CoordinateLsa> m_corLsdb;
+ LsaContainer m_lsdb;
ndn::time::seconds m_lsaRefreshTime;
- std::string m_thisRouterPrefix;
-
- typedef std::map<ndn::Name, uint64_t> SequenceNumberMap;
+ ndn::time::seconds m_adjLsaBuildInterval;
+ const ndn::Name& m_thisRouterPrefix;
// 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 ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- ndn::time::seconds m_adjLsaBuildInterval;
+ std::map<ndn::Name, uint64_t> m_highestSeqNo;
SequencingManager m_sequencingManager;
-private:
ndn::util::signal::ScopedConnection m_onNewLsaConnection;
std::set<std::shared_ptr<ndn::util::SegmentFetcher>> m_fetchers;
@@ -418,8 +359,10 @@
int64_t m_adjBuildCount;
ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
ndn::InMemoryStoragePersistent m_lsaStorage;
+
+ const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component("lsdb");
+ static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
};
} // namespace nlsr
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index b2c6118..f3da897 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#include "nlsr.hpp"
#include "adjacent.hpp"
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index 9d7f032..cc8ee3c 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -44,7 +44,6 @@
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/security/certificate-fetcher-direct-fetch.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/signing-info.hpp>
diff --git a/src/publisher/dataset-interest-handler.cpp b/src/publisher/dataset-interest-handler.cpp
index 24c6e1a..373b62b 100644
--- a/src/publisher/dataset-interest-handler.cpp
+++ b/src/publisher/dataset-interest-handler.cpp
@@ -50,44 +50,26 @@
{
dispatcher.addStatusDataset(ADJACENCIES_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
- std::bind(&DatasetInterestHandler::publishAdjStatus, this, _1, _2, _3));
+ std::bind(&DatasetInterestHandler::publishLsaStatus<AdjLsa>, this, _1, _2, _3));
dispatcher.addStatusDataset(COORDINATES_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
- std::bind(&DatasetInterestHandler::publishCoordinateStatus, this, _1, _2, _3));
+ std::bind(&DatasetInterestHandler::publishLsaStatus<CoordinateLsa>, this, _1, _2, _3));
dispatcher.addStatusDataset(NAMES_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
- std::bind(&DatasetInterestHandler::publishNameStatus, this, _1, _2, _3));
+ std::bind(&DatasetInterestHandler::publishLsaStatus<NameLsa>, this, _1, _2, _3));
dispatcher.addStatusDataset(RT_DATASET,
ndn::mgmt::makeAcceptAllAuthorization(),
std::bind(&DatasetInterestHandler::publishRtStatus, this, _1, _2, _3));
}
+template <typename T>
void
-DatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+DatasetInterestHandler::publishLsaStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context)
{
- for (const auto& adjLsa : m_lsdb.getAdjLsdb()) {
- context.append(adjLsa.wireEncode());
- }
- context.end();
-}
-
-void
-DatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
- ndn::mgmt::StatusDatasetContext& context)
-{
- for (const auto& coordinateLsa : m_lsdb.getCoordinateLsdb()) {
- context.append(coordinateLsa.wireEncode());
- }
- context.end();
-}
-
-void
-DatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
- ndn::mgmt::StatusDatasetContext& context)
-{
- for (const auto& nameLsa : m_lsdb.getNameLsdb()) {
- context.append(nameLsa.wireEncode());
+ auto lsaRange = m_lsdb.getLsdbIterator<T>();
+ for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
+ context.append((*lsaIt)->wireEncode());
}
context.end();
}
diff --git a/src/publisher/dataset-interest-handler.hpp b/src/publisher/dataset-interest-handler.hpp
index b39ac25..cfd21c9 100644
--- a/src/publisher/dataset-interest-handler.hpp
+++ b/src/publisher/dataset-interest-handler.hpp
@@ -82,24 +82,13 @@
publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
- /*! \brief provide adjacent status dataset
+ /*! \brief provide LSA status dataset
*/
+ template <typename T>
void
- publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
+ publishLsaStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
- /*! \brief provide coordinate status dataset
- */
- void
- publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
- ndn::mgmt::StatusDatasetContext& context);
-
- /*! \brief provide name status dataset
- */
- void
- publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
- ndn::mgmt::StatusDatasetContext& context);
-
private:
ndn::mgmt::Dispatcher& m_dispatcher;
const Lsdb& m_lsdb;
diff --git a/src/route/map.hpp b/src/route/map.hpp
index ae92d25..be62d2d 100644
--- a/src/route/map.hpp
+++ b/src/route/map.hpp
@@ -22,6 +22,7 @@
#define NLSR_MAP_HPP
#include "common.hpp"
+#include "lsa/adj-lsa.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
@@ -81,8 +82,9 @@
{
BOOST_STATIC_ASSERT_MSG(is_iterator<IteratorType>::value, "IteratorType must be an iterator!");
for (auto lsa = begin; lsa != end; lsa++) {
- addEntry(lsa->getOriginRouter());
- for (const auto& adjacent : lsa->getAdl().getAdjList()) {
+ auto adjLsa = std::static_pointer_cast<AdjLsa>(*lsa);
+ addEntry(adjLsa->getOriginRouter());
+ for (const auto& adjacent : adjLsa->getAdl().getAdjList()) {
addEntry(adjacent.getName());
}
}
@@ -98,7 +100,7 @@
{
BOOST_STATIC_ASSERT_MSG(is_iterator<IteratorType>::value, "IteratorType must be an iterator!");
for (auto lsa = begin; lsa != end; lsa++) {
- addEntry(lsa->getOriginRouter());
+ addEntry((*lsa)->getOriginRouter());
}
}
diff --git a/src/route/routing-table-calculator.cpp b/src/route/routing-table-calculator.cpp
index 04cc78f..2d283eb 100644
--- a/src/route/routing-table-calculator.cpp
+++ b/src/route/routing-table-calculator.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2020, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#include "routing-table-calculator.hpp"
#include "lsdb.hpp"
@@ -61,13 +61,15 @@
}
void
-RoutingTableCalculator::makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map& pMap)
+RoutingTableCalculator::makeAdjMatrix(const Lsdb& lsdb, Map& pMap)
{
// For each LSA represented in the map
- for (const auto& adjLsa : adjLsaList) {
- ndn::optional<int32_t> row = pMap.getMappingNoByRouterName(adjLsa.getOriginRouter());
+ auto lsaRange = lsdb.getLsdbIterator<AdjLsa>();
+ for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
+ auto adjLsa = std::static_pointer_cast<AdjLsa>(*lsaIt);
+ ndn::optional<int32_t> row = pMap.getMappingNoByRouterName(adjLsa->getOriginRouter());
- std::list<Adjacent> adl = adjLsa.getAdl().getAdjList();
+ std::list<Adjacent> adl = adjLsa->getAdl().getAdjList();
// For each adjacency represented in the LSA
for (const auto& adjacent : adl) {
ndn::optional<int32_t> col = pMap.getMappingNoByRouterName(adjacent.getName());
@@ -217,7 +219,6 @@
linkCosts = new double[vNoLink];
}
-
void
RoutingTableCalculator::freeLinks()
{
@@ -232,12 +233,12 @@
void
LinkStateRoutingTableCalculator::calculatePath(Map& pMap, RoutingTable& rt,
ConfParameter& confParam,
- const std::list<AdjLsa>& adjLsaList)
+ const Lsdb& lsdb)
{
NLSR_LOG_DEBUG("LinkStateRoutingTableCalculator::calculatePath Called");
allocateAdjMatrix();
initMatrix();
- makeAdjMatrix(adjLsaList, pMap);
+ makeAdjMatrix(lsdb, pMap);
writeAdjMatrixLog(pMap);
ndn::optional<int32_t> sourceRouter =
pMap.getMappingNoByRouterName(confParam.getRouterPrefix());
@@ -497,15 +498,8 @@
double distance = UNKNOWN_DISTANCE;
- ndn::Name srcLsaKey = src;
- srcLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
-
- CoordinateLsa* srcLsa = lsdb.findCoordinateLsa(srcLsaKey);
-
- ndn::Name destLsaKey = dest;
- destLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
-
- CoordinateLsa* destLsa = lsdb.findCoordinateLsa(destLsaKey);
+ auto srcLsa = lsdb.findLsa<CoordinateLsa>(src);
+ auto destLsa = lsdb.findLsa<CoordinateLsa>(dest);
// Coordinate LSAs do not exist for these routers
if (srcLsa == nullptr || destLsa == nullptr) {
diff --git a/src/route/routing-table-calculator.hpp b/src/route/routing-table-calculator.hpp
index 16d64d7..9c0c6b5 100644
--- a/src/route/routing-table-calculator.hpp
+++ b/src/route/routing-table-calculator.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2020, The University of Memphis,
* Regents of the University of California
*
@@ -16,8 +16,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- *
- **/
+ */
#ifndef NLSR_ROUTING_TABLE_CALCULATOR_HPP
#define NLSR_ROUTING_TABLE_CALCULATOR_HPP
@@ -25,6 +24,7 @@
#include "common.hpp"
#include "lsa/lsa.hpp"
#include "lsa/adj-lsa.hpp"
+#include "lsdb.hpp"
#include "conf-parameter.hpp"
#include <list>
@@ -56,11 +56,11 @@
initMatrix();
/*! \brief Constructs an adj. matrix to calculate with.
- \param adjLsaList The Adjacency Lsa list.
+ \param lsdb Reference to the Lsdb
\param pMap The map to populate with the adj. data.
*/
void
- makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map& pMap);
+ makeAdjMatrix(const Lsdb& lsdb, Map& pMap);
/*! \brief Writes a formated adjacent matrix to DEBUG log
\param map The map containing adjacent matrix data
@@ -137,7 +137,7 @@
void
calculatePath(Map& pMap, RoutingTable& rt, ConfParameter& confParam,
- const std::list<AdjLsa>& adjLsaList);
+ const Lsdb& lsdb);
private:
/*! \brief Performs a Dijkstra's calculation over the adjacency matrix.
diff --git a/src/route/routing-table.cpp b/src/route/routing-table.cpp
index a2ec12b..74d3c11 100644
--- a/src/route/routing-table.cpp
+++ b/src/route/routing-table.cpp
@@ -52,9 +52,7 @@
void
RoutingTable::calculate()
{
- m_lsdb.writeCorLsdbLog();
- m_lsdb.writeNameLsdbLog();
- m_lsdb.writeAdjLsdbLog();
+ m_lsdb.writeLog();
m_namePrefixTable.writeLog();
if (m_isRoutingTableCalculating == false) {
// setting routing table calculation
@@ -63,14 +61,10 @@
bool isHrEnabled = m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF;
if ((!isHrEnabled &&
- m_lsdb
- .doesLsaExist(ndn::Name{m_confParam.getRouterPrefix()}
- .append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY)), Lsa::Type::ADJACENCY))
+ m_lsdb.doesLsaExist(m_confParam.getRouterPrefix(), Lsa::Type::ADJACENCY))
||
(isHrEnabled &&
- m_lsdb
- .doesLsaExist(ndn::Name{m_confParam.getRouterPrefix()}
- .append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE)), Lsa::Type::COORDINATE))) {
+ m_lsdb.doesLsaExist(m_confParam.getRouterPrefix(), Lsa::Type::COORDINATE))) {
if (m_lsdb.getIsBuildAdjLsaSheduled() != 1) {
NLSR_LOG_TRACE("Clearing old routing table");
clearRoutingTable();
@@ -80,8 +74,8 @@
NLSR_LOG_DEBUG("Calculating routing table");
// calculate Link State routing
- if ((m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF)
- || (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_DRY_RUN)) {
+ if ((m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) ||
+ (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_DRY_RUN)) {
calculateLsRoutingTable();
}
// calculate hyperbolic routing
@@ -126,25 +120,26 @@
void
RoutingTable::calculateLsRoutingTable()
{
- NLSR_LOG_DEBUG("RoutingTable::calculateLsRoutingTable Called");
+ NLSR_LOG_TRACE("CalculateLsRoutingTable Called");
Map map;
- map.createFromAdjLsdb(m_lsdb.getAdjLsdb().begin(), m_lsdb.getAdjLsdb().end());
+ auto lsaRange = m_lsdb.getLsdbIterator<AdjLsa>();
+ map.createFromAdjLsdb(lsaRange.first, lsaRange.second);
map.writeLog();
size_t nRouters = map.getMapSize();
LinkStateRoutingTableCalculator calculator(nRouters);
- calculator.calculatePath(map, *this, m_confParam, m_lsdb.getAdjLsdb());
+ calculator.calculatePath(map, *this, m_confParam, m_lsdb);
}
void
RoutingTable::calculateHypRoutingTable(bool isDryRun)
{
Map map;
- map.createFromCoordinateLsdb(m_lsdb.getCoordinateLsdb().begin(),
- m_lsdb.getCoordinateLsdb().end());
+ auto lsaRange = m_lsdb.getLsdbIterator<CoordinateLsa>();
+ map.createFromCoordinateLsdb(lsaRange.first, lsaRange.second);
map.writeLog();
size_t nRouters = map.getMapSize();
diff --git a/src/sequencing-manager.hpp b/src/sequencing-manager.hpp
index 0c8504f..9cb349d 100644
--- a/src/sequencing-manager.hpp
+++ b/src/sequencing-manager.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2020, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
@@ -17,12 +17,13 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
#ifndef NLSR_SEQUENCING_MANAGER_HPP
#define NLSR_SEQUENCING_MANAGER_HPP
#include "conf-parameter.hpp"
+#include "lsa/lsa.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/face.hpp>
@@ -38,6 +39,39 @@
public:
SequencingManager(const std::string& filePath, int hypState);
+ void
+ setLsaSeq(uint64_t seqNo, Lsa::Type lsaType)
+ {
+ switch (lsaType) {
+ case Lsa::Type::ADJACENCY:
+ m_adjLsaSeq = seqNo;
+ break;
+ case Lsa::Type::COORDINATE:
+ m_corLsaSeq = seqNo;
+ break;
+ case Lsa::Type::NAME:
+ m_nameLsaSeq = seqNo;
+ break;
+ default:
+ return;
+ }
+ }
+
+ uint64_t
+ getLsaSeq(Lsa::Type lsaType)
+ {
+ switch (lsaType) {
+ case Lsa::Type::ADJACENCY:
+ return m_adjLsaSeq;
+ case Lsa::Type::COORDINATE:
+ return m_corLsaSeq;
+ case Lsa::Type::NAME:
+ return m_nameLsaSeq;
+ default:
+ return 0;
+ }
+ }
+
uint64_t
getNameLsaSeq() const
{
diff --git a/src/tlv-nlsr.hpp b/src/tlv-nlsr.hpp
index 93cfd2d..a445e52 100644
--- a/src/tlv-nlsr.hpp
+++ b/src/tlv-nlsr.hpp
@@ -22,8 +22,6 @@
#ifndef NLSR_TLV_NLSR_HPP
#define NLSR_TLV_NLSR_HPP
-#include <ndn-cxx/encoding/tlv.hpp>
-
namespace ndn {
namespace tlv {
namespace nlsr {