32 const ndn::time::steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE =
33 ndn::time::steady_clock::TimePoint::min();
38 , m_scheduler(face.getIoService())
39 , m_confParam(confParam)
40 , m_namePrefixTable(namePrefixTable)
41 , m_routingTable(routingTable)
43 [this] (const
ndn::Name& routerName, const
Lsa::Type& lsaType,
44 const uint64_t& sequenceNumber) {
45 return isLsaNew(routerName, lsaType, sequenceNumber);
47 , m_lsaRefreshTime(ndn::time::seconds(m_confParam.getLsaRefreshTime()))
48 , m_adjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval())
49 , m_thisRouterPrefix(m_confParam.getRouterPrefix())
50 , m_sequencingManager(m_confParam.getStateFileDir(), m_confParam.getHyperbolicState())
51 , m_onNewLsaConnection(m_sync.onNewLsa->connect(
52 [
this] (
const ndn::Name& updateName, uint64_t sequenceNumber,
53 const ndn::Name& originRouter) {
54 ndn::Name lsaInterest{updateName};
55 lsaInterest.appendNumber(sequenceNumber);
56 expressInterest(lsaInterest, 0);
58 , m_segmentPublisher(m_face, keyChain)
59 , m_isBuildAdjLsaSheduled(
false)
65 Lsdb::buildAndInstallOwnNameLsa()
67 NameLsa nameLsa(m_thisRouterPrefix, m_sequencingManager.getNameLsaSeq() + 1,
68 getLsaExpirationTimePoint(), m_confParam.getNamePrefixList());
69 m_sequencingManager.increaseNameLsaSeq();
70 m_sequencingManager.writeSeqNoToFile();
71 m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
73 installLsa(std::make_shared<NameLsa>(nameLsa));
77 Lsdb::buildAndInstallOwnCoordinateLsa()
79 CoordinateLsa corLsa(m_thisRouterPrefix, m_sequencingManager.getCorLsaSeq() + 1,
80 getLsaExpirationTimePoint(), m_confParam.getCorR(),
81 m_confParam.getCorTheta());
82 m_sequencingManager.increaseCorLsaSeq();
83 m_sequencingManager.writeSeqNoToFile();
87 m_sync.publishRoutingUpdate(Lsa::Type::COORDINATE, m_sequencingManager.getCorLsaSeq());
90 installLsa(std::make_shared<CoordinateLsa>(corLsa));
94 Lsdb::scheduleAdjLsaBuild()
100 NLSR_LOG_DEBUG(
"Adjacency LSA not built. Currently in hyperbolic routing state.");
104 if (m_isBuildAdjLsaSheduled) {
105 NLSR_LOG_DEBUG(
"Rescheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
108 NLSR_LOG_DEBUG(
"Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
109 m_isBuildAdjLsaSheduled =
true;
111 m_scheduledAdjLsaBuild = m_scheduler.schedule(m_adjLsaBuildInterval, [
this] { buildAdjLsa(); });
116 Lsdb::writeLog()
const
118 if ((T::type() == Lsa::Type::COORDINATE &&
120 (T::type() == Lsa::Type::ADJACENCY &&
125 NLSR_LOG_DEBUG(
"---------------" << T::type() <<
" LSDB-------------------");
126 auto lsaRange = m_lsdb.get<
byType>().equal_range(T::type());
127 for (
auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
128 auto lsaPtr = std::static_pointer_cast<T>(*lsaIt);
134 Lsdb::writeLog()
const
136 writeLog<CoordinateLsa>();
142 Lsdb::processInterest(
const ndn::Name& name,
const ndn::Interest& interest)
144 ndn::Name interestName(interest.getName());
147 if (interestName[-2].isVersion()) {
149 if (m_segmentPublisher.replyFromStore(interestName)) {
154 interestName = interestName.getSubName(0, interestName.size() - 2);
155 NLSR_LOG_TRACE(
"Interest w/o segment and version: " << interestName);
159 lsaIncrementSignal(Statistics::PacketType::RCV_LSA_INTEREST);
161 std::string chkString(
"LSA");
165 ndn::Name originRouter = m_confParam.getNetwork();
166 originRouter.append(interestName.getSubName(lsaPosition + 1,
167 interestName.size() - lsaPosition - 3));
170 if (originRouter == m_thisRouterPrefix && lsaPosition >= 0) {
171 uint64_t seqNo = interestName[-1].toNumber();
174 std::string lsaType = interestName[-2].toUri();
176 std::istringstream(lsaType) >> interestedLsType;
177 if (interestedLsType == Lsa::Type::BASE) {
178 NLSR_LOG_WARN(
"Received unrecognized LSA type: " << lsaType);
182 incrementInterestRcvdStats(interestedLsType);
183 if (processInterestForLsa(interest, originRouter, interestedLsType, seqNo)) {
184 lsaIncrementSignal(Statistics::PacketType::SENT_LSA_DATA);
188 else if (
auto lsaSegment = m_lsaStorage.find(interest)) {
189 NLSR_LOG_TRACE(
"Found data in lsa storage. Sending the data for " << interest.getName());
190 m_face.put(*lsaSegment);
195 Lsdb::processInterestForLsa(
const ndn::Interest& interest,
const ndn::Name& originRouter,
199 if (
auto lsaPtr = findLsa(originRouter, lsaType)) {
200 NLSR_LOG_TRACE(
"Verifying SeqNo for " << lsaType <<
" is same as requested.");
201 if (lsaPtr->getSeqNo() == seqNo) {
202 m_segmentPublisher.publish(interest.getName(), interest.getName(),
203 lsaPtr->wireEncode(),
204 m_lsaRefreshTime, m_confParam.getSigningInfo());
205 incrementDataSentStats(lsaType);
216 Lsdb::installLsa(std::shared_ptr<Lsa> lsa)
218 auto timeToExpire = m_lsaRefreshTime;
220 auto chkLsa = findLsa(lsa->getOriginRouter(), lsa->getType());
221 if (chkLsa ==
nullptr) {
224 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
229 if (lsa->getOriginRouter() != m_thisRouterPrefix) {
231 m_namePrefixTable.addEntry(lsa->getOriginRouter(), lsa->getOriginRouter());
233 if (lsa->getType() == Lsa::Type::NAME) {
234 auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
235 for (
const auto& name : nlsa->getNpl().getNames()) {
236 if (name != m_thisRouterPrefix) {
237 m_namePrefixTable.addEntry(name, nlsa->getOriginRouter());
242 auto duration = lsa->getExpirationTimePoint() - ndn::time::system_clock::now();
243 if (duration > ndn::time::seconds(0)) {
244 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
248 if ((lsa->getType() == Lsa::Type::ADJACENCY && m_confParam.getHyperbolicState() !=
HYPERBOLIC_STATE_ON)||
249 (lsa->getType() == Lsa::Type::COORDINATE && m_confParam.getHyperbolicState() !=
HYPERBOLIC_STATE_OFF)) {
250 m_routingTable.scheduleRoutingTableCalculation();
253 lsa->setExpiringEventId(scheduleLsaExpiration(lsa, timeToExpire));
256 else if (chkLsa->getSeqNo() < lsa->getSeqNo()) {
259 chkLsa->setSeqNo(lsa->getSeqNo());
260 chkLsa->setExpirationTimePoint(lsa->getExpirationTimePoint());
262 if (lsa->getType() == Lsa::Type::NAME) {
263 auto chkNameLsa = std::static_pointer_cast<NameLsa>(chkLsa);
264 auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
265 chkNameLsa->getNpl().sort();
266 nlsa->getNpl().sort();
267 if (!chkNameLsa->isEqualContent(*nlsa)) {
270 std::list<ndn::Name> newNames = nlsa->getNpl().getNames();
271 std::list<ndn::Name> oldNames = chkNameLsa->getNpl().getNames();
272 std::list<ndn::Name> namesToAdd;
273 std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
274 std::inserter(namesToAdd, namesToAdd.begin()));
275 for (
const auto& name : namesToAdd) {
276 chkNameLsa->addName(name);
277 if (nlsa->getOriginRouter() != m_thisRouterPrefix && name != m_thisRouterPrefix) {
278 m_namePrefixTable.addEntry(name, nlsa->getOriginRouter());
282 chkNameLsa->getNpl().sort();
285 std::list<ndn::Name> namesToRemove;
286 std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
287 std::inserter(namesToRemove, namesToRemove.begin()));
288 for (
const auto& name : namesToRemove) {
289 NLSR_LOG_DEBUG(
"Removing name" << name <<
" from Name LSA no longer advertised.");
290 chkNameLsa->removeName(name);
291 if (nlsa->getOriginRouter() != m_thisRouterPrefix && name != m_thisRouterPrefix) {
292 m_namePrefixTable.removeEntry(name, nlsa->getOriginRouter());
297 else if (lsa->getType() == Lsa::Type::ADJACENCY) {
298 auto chkAdjLsa = std::static_pointer_cast<AdjLsa>(chkLsa);
299 auto alsa = std::static_pointer_cast<AdjLsa>(lsa);
300 if (!chkAdjLsa->isEqualContent(*alsa)) {
301 chkAdjLsa->resetAdl();
302 for (
const auto& adjacent : alsa->getAdl()) {
303 chkAdjLsa->addAdjacent(adjacent);
305 m_routingTable.scheduleRoutingTableCalculation();
309 auto chkCorLsa = std::static_pointer_cast<CoordinateLsa>(chkLsa);
310 auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
311 if (!chkCorLsa->isEqualContent(*clsa)) {
312 chkCorLsa->setCorRadius(clsa->getCorRadius());
313 chkCorLsa->setCorTheta(clsa->getCorTheta());
315 m_routingTable.scheduleRoutingTableCalculation();
320 if (chkLsa->getOriginRouter() != m_thisRouterPrefix) {
321 auto duration = lsa->getExpirationTimePoint() - ndn::time::system_clock::now();
322 if (duration > ndn::time::seconds(0)) {
323 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
326 chkLsa->getExpiringEventId().cancel();
327 chkLsa->setExpiringEventId(scheduleLsaExpiration(chkLsa, timeToExpire));
334 Lsdb::removeLsa(
const ndn::Name& router, Lsa::Type lsaType)
336 auto lsaIt = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
338 if (lsaIt != m_lsdb.end()) {
339 auto lsaPtr = *lsaIt;
344 if (lsaPtr->getOriginRouter() != m_thisRouterPrefix) {
345 m_namePrefixTable.removeEntry(lsaPtr->getOriginRouter(), lsaPtr->getOriginRouter());
347 if (lsaType == Lsa::Type::NAME) {
348 auto nlsaPtr = std::static_pointer_cast<NameLsa>(lsaPtr);
349 for (
const auto& name : nlsaPtr->getNpl().getNames()) {
350 if (name != m_thisRouterPrefix) {
351 m_namePrefixTable.removeEntry(name, nlsaPtr->getOriginRouter());
367 m_isBuildAdjLsaSheduled =
false;
369 if (m_confParam.getAdjacencyList().isAdjLsaBuildable(m_confParam.getInterestRetryNumber())) {
371 int adjBuildCount = m_adjBuildCount;
373 if (adjBuildCount > 0) {
375 if (m_confParam.getAdjacencyList().getNumOfActiveNeighbor() > 0) {
377 buildAndInstallOwnAdjLsa();
386 removeLsa(m_thisRouterPrefix, Lsa::Type::ADJACENCY);
388 m_routingTable.scheduleRoutingTableCalculation();
393 m_adjBuildCount = m_adjBuildCount - adjBuildCount;
400 m_isBuildAdjLsaSheduled =
true;
401 auto schedulingTime = ndn::time::seconds(m_confParam.getInterestRetryNumber() *
402 m_confParam.getInterestResendTime());
403 m_scheduledAdjLsaBuild = m_scheduler.schedule(schedulingTime, [
this] { buildAdjLsa(); });
408 Lsdb::buildAndInstallOwnAdjLsa()
410 AdjLsa adjLsa(m_thisRouterPrefix, m_sequencingManager.getAdjLsaSeq() + 1,
411 getLsaExpirationTimePoint(),
412 m_confParam.getAdjacencyList().getNumOfActiveNeighbor(),
413 m_confParam.getAdjacencyList());
414 m_sequencingManager.increaseAdjLsaSeq();
415 m_sequencingManager.writeSeqNoToFile();
419 m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
422 installLsa(std::make_shared<AdjLsa>(adjLsa));
426 Lsdb::expireOrRefreshLsa(std::shared_ptr<Lsa> lsa)
428 NLSR_LOG_DEBUG(
"ExpireOrRefreshLsa called for " << lsa->getType());
429 NLSR_LOG_DEBUG(
"OriginRouter: " << lsa->getOriginRouter() <<
" Seq No: " << lsa->getSeqNo());
431 auto lsaIt = m_lsdb.get<byName>().find(std::make_tuple(lsa->getOriginRouter(), lsa->getType()));
434 if (lsaIt != m_lsdb.end()) {
435 auto lsaPtr = *lsaIt;
439 if (lsaPtr->getSeqNo() == lsa->getSeqNo()) {
440 if (lsaPtr->getOriginRouter() == m_thisRouterPrefix) {
441 NLSR_LOG_DEBUG(
"Own " << lsaPtr->getType() <<
" LSA, so refreshing it.");
444 lsaPtr->setSeqNo(lsaPtr->getSeqNo() + 1);
445 m_sequencingManager.setLsaSeq(lsaPtr->getSeqNo(), lsaPtr->getType());
446 lsaPtr->setExpirationTimePoint(getLsaExpirationTimePoint());
450 lsaPtr->setExpiringEventId(scheduleLsaExpiration(lsaPtr, m_lsaRefreshTime));
451 m_sequencingManager.writeSeqNoToFile();
452 m_sync.publishRoutingUpdate(lsaPtr->getType(), m_sequencingManager.getLsaSeq(lsaPtr->getType()));
456 NLSR_LOG_DEBUG(
"Other's " << lsaPtr->getType() <<
" LSA, so removing from LSDB");
457 removeLsa(lsaPtr->getOriginRouter(), lsaPtr->getType());
464 Lsdb::expressInterest(
const ndn::Name& interestName, uint32_t timeoutCount,
465 ndn::time::steady_clock::TimePoint deadline)
468 lsaIncrementSignal(Statistics::PacketType::SENT_LSA_INTEREST);
470 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
471 deadline = ndn::time::steady_clock::now() + ndn::time::seconds(
static_cast<int>(
LSA_REFRESH_TIME_MAX));
474 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
476 uint64_t seqNo = interestName[-1].toNumber();
479 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
480 m_highestSeqNo[lsaName] = seqNo;
483 else if (seqNo > m_highestSeqNo[lsaName]) {
484 m_highestSeqNo[lsaName] = seqNo;
487 else if (seqNo < m_highestSeqNo[lsaName]) {
491 ndn::Interest interest(interestName);
492 ndn::util::SegmentFetcher::Options options;
493 options.interestLifetime = m_confParam.getLsaInterestLifetime();
495 NLSR_LOG_DEBUG(
"Fetching Data for LSA: " << interestName <<
" Seq number: " << seqNo);
496 auto fetcher = ndn::util::SegmentFetcher::start(m_face, interest,
497 m_confParam.getValidator(), options);
499 auto it = m_fetchers.insert(fetcher).first;
501 fetcher->afterSegmentValidated.connect([
this] (
const ndn::Data& data) {
503 afterSegmentValidatedSignal(data);
506 auto lsaSegment = std::make_shared<const ndn::Data>(data);
507 m_lsaStorage.insert(*lsaSegment);
508 const ndn::Name& segmentName = lsaSegment->getName();
511 [
this, segmentName] { m_lsaStorage.erase(segmentName); });
514 fetcher->onComplete.connect([=] (
const ndn::ConstBufferPtr& bufferPtr) {
515 m_lsaStorage.erase(ndn::Name(lsaName).appendNumber(seqNo - 1));
516 afterFetchLsa(bufferPtr, interestName);
517 m_fetchers.erase(it);
520 fetcher->onError.connect([=] (uint32_t errorCode,
const std::string& msg) {
521 onFetchLsaError(errorCode, msg, interestName, timeoutCount, deadline, lsaName, seqNo);
522 m_fetchers.erase(it);
526 std::istringstream(interestName[-2].toUri()) >> lsaType;
527 incrementInterestSentStats(lsaType);
531 Lsdb::onFetchLsaError(uint32_t errorCode,
const std::string& msg,
const ndn::Name& interestName,
532 uint32_t retransmitNo,
const ndn::time::steady_clock::TimePoint& deadline,
533 ndn::Name lsaName, uint64_t seqNo)
535 NLSR_LOG_DEBUG(
"Failed to fetch LSA: " << lsaName <<
", Error code: " << errorCode
536 <<
", Message: " << msg);
538 if (ndn::time::steady_clock::now() < deadline) {
539 auto it = m_highestSeqNo.find(lsaName);
540 if (it != m_highestSeqNo.end() && it->second == seqNo) {
545 ndn::time::seconds delay = m_confParam.getLsaInterestLifetime();
547 if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
548 delay = ndn::time::seconds(0);
550 m_scheduler.schedule(delay, std::bind(&Lsdb::expressInterest,
this,
551 interestName, retransmitNo + 1, deadline));
557 Lsdb::afterFetchLsa(
const ndn::ConstBufferPtr& bufferPtr,
const ndn::Name& interestName)
559 NLSR_LOG_DEBUG(
"Received data for LSA interest: " << interestName);
560 lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
562 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
563 uint64_t seqNo = interestName[-1].toNumber();
565 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
566 m_highestSeqNo[lsaName] = seqNo;
568 else if (seqNo > m_highestSeqNo[lsaName]) {
569 m_highestSeqNo[lsaName] = seqNo;
570 NLSR_LOG_TRACE(
"SeqNo for LSA(name): " << interestName <<
" updated");
572 else if (seqNo < m_highestSeqNo[lsaName]) {
576 std::string chkString(
"LSA");
579 if (lsaPosition >= 0) {
581 ndn::Name originRouter = m_confParam.getNetwork();
582 originRouter.append(interestName.getSubName(lsaPosition + 1,
583 interestName.size() - lsaPosition - 3));
586 Lsa::Type interestedLsType;
587 std::istringstream(interestName[-2].toUri()) >> interestedLsType;
589 if (interestedLsType == Lsa::Type::BASE) {
590 NLSR_LOG_WARN(
"Received unrecognized LSA Type: " << interestName[-2].toUri());
594 ndn::Block block(bufferPtr);
595 if (interestedLsType == Lsa::Type::NAME) {
596 lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_DATA);
597 if (isLsaNew(originRouter, interestedLsType, seqNo)) {
598 installLsa(std::make_shared<NameLsa>(block));
601 else if (interestedLsType == Lsa::Type::ADJACENCY) {
602 lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_DATA);
603 if (isLsaNew(originRouter, interestedLsType, seqNo)) {
604 installLsa(std::make_shared<AdjLsa>(block));
607 else if (interestedLsType == Lsa::Type::COORDINATE) {
608 lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_DATA);
609 if (isLsaNew(originRouter, interestedLsType, seqNo)) {
610 installLsa(std::make_shared<CoordinateLsa>(block));
614 catch (
const std::exception& e) {
A class to house all the configuration parameters for NLSR.
Data abstraction for CoordinateLsa CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH Lsa HyperbolicRadi...
Data abstraction for Lsa Lsa := LSA-TYPE TLV-LENGTH Name SequenceNumber ExpirationTimePoint.
Lsdb(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam, NamePrefixTable &namePrefixTable, RoutingTable &routingTable)
Data abstraction for NameLsa NameLsa := NAME-LSA-TYPE TLV-LENGTH Lsa Name+.
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
#define INIT_LOGGER(name)
#define NLSR_LOG_TRACE(x)
int32_t getNameComponentPosition(const ndn::Name &name, const std::string &searchString)
search a name component in ndn::Name and return the position of the component
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California,...
@ LSA_REFRESH_TIME_DEFAULT