blob: 61a23f5b55644598ba844ee1ffe69bf20db6d16f [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, The University of Memphis,
Vince Lehmanc2e51f62015-01-20 15:03:11 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
akmhoque3d06e792014-05-27 16:23:20 -050020 **/
Vince Lehmanc2e51f62015-01-20 15:03:11 -060021
akmhoque53353462014-04-22 08:43:45 -050022#include "lsdb.hpp"
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050023
akmhoque674b0b12014-05-20 14:33:28 -050024#include "logger.hpp"
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050025#include "nlsr.hpp"
26#include "publisher/segment-publisher.hpp"
27#include "utility/name-helper.hpp"
28
29#include <ndn-cxx/security/signing-helpers.hpp>
30#include <ndn-cxx/util/segment-fetcher.hpp>
31
32#include <string>
akmhoque53353462014-04-22 08:43:45 -050033
34namespace nlsr {
35
akmhoque674b0b12014-05-20 14:33:28 -050036INIT_LOGGER("Lsdb");
37
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050038class LsaContentPublisher : public SegmentPublisher<ndn::Face>
39{
40public:
41 LsaContentPublisher(ndn::Face& face,
42 ndn::KeyChain& keyChain,
43 const ndn::time::milliseconds& freshnessPeriod,
44 const std::string& content)
45 : SegmentPublisher(face, keyChain, freshnessPeriod)
46 , m_content(content)
47 {
48 }
49
50 virtual size_t
51 generate(ndn::EncodingBuffer& outBuffer) {
52 size_t totalLength = 0;
53 totalLength += outBuffer.prependByteArray(reinterpret_cast<const uint8_t*>(m_content.c_str()),
54 m_content.size());
55 return totalLength;
56 }
57
58private:
59 const std::string m_content;
60};
61
Jiewen Tana0497d82015-02-02 21:59:18 -080062const ndn::Name::Component Lsdb::NAME_COMPONENT = ndn::Name::Component("lsdb");
Vince Lehman18841082014-08-19 17:15:24 -050063const ndn::time::seconds Lsdb::GRACE_PERIOD = ndn::time::seconds(10);
Ashlesh Gawande5bf83172014-09-19 12:38:17 -050064const steady_clock::TimePoint Lsdb::DEFAULT_LSA_RETRIEVAL_DEADLINE = steady_clock::TimePoint::min();
Vince Lehman18841082014-08-19 17:15:24 -050065
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050066Lsdb::Lsdb(Nlsr& nlsr, ndn::Scheduler& scheduler)
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050067 : m_nlsr(nlsr)
68 , m_scheduler(scheduler)
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050069 , m_sync(m_nlsr.getNlsrFace(), *this, m_nlsr.getConfParameter())
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050070 , m_lsaRefreshTime(0)
71 , m_adjLsaBuildInterval(ADJ_LSA_BUILD_INTERVAL_DEFAULT)
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050072 , m_sequencingManager()
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050073{
74}
75
76void
77Lsdb::onFetchLsaError(uint32_t errorCode,
78 const std::string& msg,
79 ndn::Name& interestName,
80 uint32_t retransmitNo,
81 const ndn::time::steady_clock::TimePoint& deadline,
82 ndn::Name lsaName,
83 uint64_t seqNo)
84{
85 _LOG_DEBUG("Failed to fetch LSA: " << lsaName << ", Error code: " << errorCode
86 << ", Message: " << msg);
87
88 if (ndn::time::steady_clock::now() < deadline) {
89 SequenceNumberMap::const_iterator it = m_highestSeqNo.find(lsaName);
90
91 if (it != m_highestSeqNo.end() && it->second == seqNo) {
92 // If the SegmentFetcher failed due to an Interest timeout, it is safe to re-express
93 // immediately since at the least the LSA Interest lifetime has elapsed.
94 // Otherwise, it is necessary to delay the Interest re-expression to prevent
95 // the potential for constant Interest flooding.
96 ndn::time::seconds delay = m_nlsr.getConfParameter().getLsaInterestLifetime();
97
98 if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
99 delay = ndn::time::seconds(0);
100 }
101
102 m_scheduler.scheduleEvent(delay, std::bind(&Lsdb::expressInterest, this,
103 interestName, retransmitNo + 1, deadline));
104 }
105 }
106}
107
108void
109Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, ndn::Name& interestName)
110{
dmcoomes9f936662017-03-02 10:33:09 -0600111 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(ndn::Name(interestName));
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500112 data->setContent(bufferPtr);
113
114 _LOG_DEBUG("Received data for LSA(name): " << data->getName());
115
116 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
117 uint64_t seqNo = interestName[-1].toNumber();
118
119 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
120 m_highestSeqNo[lsaName] = seqNo;
121 }
122 else if (seqNo > m_highestSeqNo[lsaName]) {
123 m_highestSeqNo[lsaName] = seqNo;
dmcoomes9eaf3f42017-02-21 11:39:01 -0600124 _LOG_TRACE("SeqNo for LSA(name): " << data->getName() << " updated");
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500125 }
126 else if (seqNo < m_highestSeqNo[lsaName]) {
127 return;
128 }
129
130 onContentValidated(data);
131}
akmhoque53353462014-04-22 08:43:45 -0500132
133void
akmhoque31d1d4b2014-05-05 22:08:14 -0500134Lsdb::cancelScheduleLsaExpiringEvent(ndn::EventId eid)
akmhoque53353462014-04-22 08:43:45 -0500135{
Vince Lehman7c603292014-09-11 17:48:16 -0500136 m_scheduler.cancelEvent(eid);
akmhoque53353462014-04-22 08:43:45 -0500137}
138
Nick G97e34942016-07-11 14:46:27 -0500139 /*! \brief Compares if a name LSA is the same as the one specified by key
140
141 \param nlsa1 A name LSA object
142 \param key A key of an originating router to compare to nlsa1
143 */
akmhoque53353462014-04-22 08:43:45 -0500144static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500145nameLsaCompareByKey(const NameLsa& nlsa1, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500146{
147 return nlsa1.getKey() == key;
148}
149
akmhoque53353462014-04-22 08:43:45 -0500150bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500151Lsdb::buildAndInstallOwnNameLsa()
akmhoque53353462014-04-22 08:43:45 -0500152{
akmhoque31d1d4b2014-05-05 22:08:14 -0500153 NameLsa nameLsa(m_nlsr.getConfParameter().getRouterPrefix(),
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500154 m_sequencingManager.getNameLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500155 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500156 m_nlsr.getNamePrefixList());
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500157 m_sequencingManager.increaseNameLsaSeq();
158
159 m_sequencingManager.writeSeqNoToFile();
160 m_sync.publishRoutingUpdate(NameLsa::TYPE_STRING, m_sequencingManager.getNameLsaSeq());
161
akmhoque31d1d4b2014-05-05 22:08:14 -0500162 return installNameLsa(nameLsa);
akmhoque53353462014-04-22 08:43:45 -0500163}
164
akmhoqueb6450b12014-04-24 00:01:03 -0500165NameLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500166Lsdb::findNameLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500167{
168 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
169 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600170 std::bind(nameLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500171 if (it != m_nameLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500172 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500173 }
akmhoqueb6450b12014-04-24 00:01:03 -0500174 return 0;
akmhoque53353462014-04-22 08:43:45 -0500175}
176
177bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500178Lsdb::isNameLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500179{
akmhoqueb6450b12014-04-24 00:01:03 -0500180 NameLsa* nameLsaCheck = findNameLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500181 // Is the name in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500182 if (nameLsaCheck != 0) {
Nick G97e34942016-07-11 14:46:27 -0500183 // And the supplied seq no is the highest so far
akmhoque157b0a42014-05-13 00:26:37 -0500184 if (nameLsaCheck->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500185 return true;
186 }
akmhoque157b0a42014-05-13 00:26:37 -0500187 else {
akmhoque53353462014-04-22 08:43:45 -0500188 return false;
189 }
190 }
191 return true;
192}
193
194ndn::EventId
akmhoquec7a79b22014-05-26 08:06:19 -0500195Lsdb::scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
196 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500197{
Vince Lehman7c603292014-09-11 17:48:16 -0500198 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
dmcoomes9f936662017-03-02 10:33:09 -0600199 std::bind(&Lsdb::exprireOrRefreshNameLsa, this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500200}
201
202bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500203Lsdb::installNameLsa(NameLsa& nlsa)
akmhoque53353462014-04-22 08:43:45 -0500204{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700205 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500206 NameLsa* chkNameLsa = findNameLsa(nlsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500207 // Determines if the name LSA is new or not.
akmhoque157b0a42014-05-13 00:26:37 -0500208 if (chkNameLsa == 0) {
akmhoque53353462014-04-22 08:43:45 -0500209 addNameLsa(nlsa);
akmhoque2f423352014-06-03 11:49:35 -0500210 _LOG_DEBUG("New Name LSA");
211 _LOG_DEBUG("Adding Name Lsa");
akmhoque53353462014-04-22 08:43:45 -0500212 nlsa.writeLog();
akmhoque674b0b12014-05-20 14:33:28 -0500213
akmhoque157b0a42014-05-13 00:26:37 -0500214 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500215 // If this name LSA is from another router, add the advertised
216 // prefixes to the NPT.
akmhoque31d1d4b2014-05-05 22:08:14 -0500217 m_nlsr.getNamePrefixTable().addEntry(nlsa.getOrigRouter(),
218 nlsa.getOrigRouter());
219 std::list<ndn::Name> nameList = nlsa.getNpl().getNameList();
220 for (std::list<ndn::Name>::iterator it = nameList.begin(); it != nameList.end();
akmhoque157b0a42014-05-13 00:26:37 -0500221 it++) {
222 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500223 m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500224 }
225 }
226 }
akmhoque157b0a42014-05-13 00:26:37 -0500227 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500228 ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
229 ndn::time::system_clock::now();
230 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500231 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500232 nlsa.setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
akmhoque53353462014-04-22 08:43:45 -0500233 nlsa.getLsSeqNo(),
234 timeToExpire));
235 }
Nick G97e34942016-07-11 14:46:27 -0500236 // Else this is a known name LSA, so we are updating it.
akmhoque157b0a42014-05-13 00:26:37 -0500237 else {
238 if (chkNameLsa->getLsSeqNo() < nlsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500239 _LOG_DEBUG("Updated Name LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500240 _LOG_DEBUG("Deleting Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500241 chkNameLsa->writeLog();
242 chkNameLsa->setLsSeqNo(nlsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500243 chkNameLsa->setExpirationTimePoint(nlsa.getExpirationTimePoint());
akmhoqueb6450b12014-04-24 00:01:03 -0500244 chkNameLsa->getNpl().sort();
akmhoque53353462014-04-22 08:43:45 -0500245 nlsa.getNpl().sort();
Nick G97e34942016-07-11 14:46:27 -0500246 // Obtain the set difference of the current and the incoming
247 // name prefix sets, and add those.
akmhoque31d1d4b2014-05-05 22:08:14 -0500248 std::list<ndn::Name> nameToAdd;
akmhoque53353462014-04-22 08:43:45 -0500249 std::set_difference(nlsa.getNpl().getNameList().begin(),
250 nlsa.getNpl().getNameList().end(),
akmhoqueb6450b12014-04-24 00:01:03 -0500251 chkNameLsa->getNpl().getNameList().begin(),
252 chkNameLsa->getNpl().getNameList().end(),
akmhoque53353462014-04-22 08:43:45 -0500253 std::inserter(nameToAdd, nameToAdd.begin()));
akmhoque31d1d4b2014-05-05 22:08:14 -0500254 for (std::list<ndn::Name>::iterator it = nameToAdd.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500255 it != nameToAdd.end(); ++it) {
akmhoqueb6450b12014-04-24 00:01:03 -0500256 chkNameLsa->addName((*it));
akmhoque157b0a42014-05-13 00:26:37 -0500257 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
258 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500259 m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500260 }
261 }
262 }
Vince Lehmanf1aa5232014-10-06 17:57:35 -0500263
264 chkNameLsa->getNpl().sort();
265
Nick G97e34942016-07-11 14:46:27 -0500266 // Also remove any names that are no longer being advertised.
akmhoque31d1d4b2014-05-05 22:08:14 -0500267 std::list<ndn::Name> nameToRemove;
akmhoqueb6450b12014-04-24 00:01:03 -0500268 std::set_difference(chkNameLsa->getNpl().getNameList().begin(),
269 chkNameLsa->getNpl().getNameList().end(),
akmhoque53353462014-04-22 08:43:45 -0500270 nlsa.getNpl().getNameList().begin(),
271 nlsa.getNpl().getNameList().end(),
272 std::inserter(nameToRemove, nameToRemove.begin()));
akmhoque31d1d4b2014-05-05 22:08:14 -0500273 for (std::list<ndn::Name>::iterator it = nameToRemove.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500274 it != nameToRemove.end(); ++it) {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600275 _LOG_DEBUG("Removing name LSA no longer advertised: " << (*it).toUri());
akmhoqueb6450b12014-04-24 00:01:03 -0500276 chkNameLsa->removeName((*it));
akmhoque157b0a42014-05-13 00:26:37 -0500277 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
278 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500279 m_nlsr.getNamePrefixTable().removeEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500280 }
281 }
282 }
dmcoomes9eaf3f42017-02-21 11:39:01 -0600283
akmhoque157b0a42014-05-13 00:26:37 -0500284 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500285 ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
286 ndn::time::system_clock::now();
287 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500288 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500289 cancelScheduleLsaExpiringEvent(chkNameLsa->getExpiringEventId());
290 chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500291 nlsa.getLsSeqNo(),
292 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500293 _LOG_DEBUG("Adding Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500294 chkNameLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500295 }
296 }
297 return true;
298}
299
300bool
301Lsdb::addNameLsa(NameLsa& nlsa)
302{
303 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
304 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600305 std::bind(nameLsaCompareByKey, _1,
akmhoque53353462014-04-22 08:43:45 -0500306 nlsa.getKey()));
akmhoque157b0a42014-05-13 00:26:37 -0500307 if (it == m_nameLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500308 m_nameLsdb.push_back(nlsa);
309 return true;
310 }
311 return false;
312}
313
314bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500315Lsdb::removeNameLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500316{
317 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
318 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600319 std::bind(nameLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500320 if (it != m_nameLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500321 _LOG_DEBUG("Deleting Name Lsa");
akmhoque53353462014-04-22 08:43:45 -0500322 (*it).writeLog();
Nick G97e34942016-07-11 14:46:27 -0500323 // If the requested name LSA is not ours, we also need to remove
324 // its entries from the NPT.
akmhoque31d1d4b2014-05-05 22:08:14 -0500325 if ((*it).getOrigRouter() !=
akmhoque157b0a42014-05-13 00:26:37 -0500326 m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500327 m_nlsr.getNamePrefixTable().removeEntry((*it).getOrigRouter(),
328 (*it).getOrigRouter());
329 for (std::list<ndn::Name>::iterator nit = (*it).getNpl().getNameList().begin();
akmhoque157b0a42014-05-13 00:26:37 -0500330 nit != (*it).getNpl().getNameList().end(); ++nit) {
331 if ((*nit) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500332 m_nlsr.getNamePrefixTable().removeEntry((*nit), (*it).getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500333 }
334 }
335 }
336 m_nameLsdb.erase(it);
337 return true;
338 }
339 return false;
340}
341
342bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500343Lsdb::doesNameLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500344{
345 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
346 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600347 std::bind(nameLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500348 if (it == m_nameLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500349 return false;
350 }
351 return true;
352}
353
354void
akmhoque2f423352014-06-03 11:49:35 -0500355Lsdb::writeNameLsdbLog()
akmhoque53353462014-04-22 08:43:45 -0500356{
akmhoque2f423352014-06-03 11:49:35 -0500357 _LOG_DEBUG("---------------Name LSDB-------------------");
akmhoque53353462014-04-22 08:43:45 -0500358 for (std::list<NameLsa>::iterator it = m_nameLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500359 it != m_nameLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -0500360 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -0500361 }
362}
363
Jiewen Tana0497d82015-02-02 21:59:18 -0800364const std::list<NameLsa>&
365Lsdb::getNameLsdb()
366{
367 return m_nameLsdb;
368}
369
akmhoque53353462014-04-22 08:43:45 -0500370// Cor LSA and LSDB related Functions start here
371
Nick G97e34942016-07-11 14:46:27 -0500372/*! \brief Compares whether an LSA object is the same as a key.
373 \param clsa The cor. LSA to check the identity of.
374 \param key The key of the publishing router to check against.
375*/
akmhoque53353462014-04-22 08:43:45 -0500376static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500377corLsaCompareByKey(const CoordinateLsa& clsa, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500378{
379 return clsa.getKey() == key;
380}
381
382bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500383Lsdb::buildAndInstallOwnCoordinateLsa()
akmhoque53353462014-04-22 08:43:45 -0500384{
akmhoque31d1d4b2014-05-05 22:08:14 -0500385 CoordinateLsa corLsa(m_nlsr.getConfParameter().getRouterPrefix(),
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500386 m_sequencingManager.getCorLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500387 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500388 m_nlsr.getConfParameter().getCorR(),
389 m_nlsr.getConfParameter().getCorTheta());
Nick Gordon5c467f02016-07-13 13:40:10 -0500390
391 // Sync coordinate LSAs if using HR or HR dry run.
392 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500393 m_sequencingManager.increaseCorLsaSeq();
394 m_sequencingManager.writeSeqNoToFile();
395 m_sync.publishRoutingUpdate(CoordinateLsa::TYPE_STRING, m_sequencingManager.getCorLsaSeq());
Nick Gordon5c467f02016-07-13 13:40:10 -0500396 }
397
akmhoque31d1d4b2014-05-05 22:08:14 -0500398 installCoordinateLsa(corLsa);
Nick Gordon5c467f02016-07-13 13:40:10 -0500399
akmhoque53353462014-04-22 08:43:45 -0500400 return true;
401}
402
akmhoqueb6450b12014-04-24 00:01:03 -0500403CoordinateLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500404Lsdb::findCoordinateLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500405{
akmhoqueb6450b12014-04-24 00:01:03 -0500406 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
407 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600408 std::bind(corLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500409 if (it != m_corLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500410 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500411 }
akmhoqueb6450b12014-04-24 00:01:03 -0500412 return 0;
akmhoque53353462014-04-22 08:43:45 -0500413}
414
415bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500416Lsdb::isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500417{
akmhoqueb6450b12014-04-24 00:01:03 -0500418 CoordinateLsa* clsa = findCoordinateLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500419 // Is the coordinate LSA in the LSDB already
akmhoque157b0a42014-05-13 00:26:37 -0500420 if (clsa != 0) {
Nick G97e34942016-07-11 14:46:27 -0500421 // And the seq no is newer (higher) than the current one
akmhoque157b0a42014-05-13 00:26:37 -0500422 if (clsa->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500423 return true;
424 }
akmhoque157b0a42014-05-13 00:26:37 -0500425 else {
akmhoque53353462014-04-22 08:43:45 -0500426 return false;
427 }
428 }
429 return true;
430}
431
Nick G97e34942016-07-11 14:46:27 -0500432 // Schedules a refresh/expire event in the scheduler.
433 // \param key The name of the router that published the LSA.
434 // \param seqNo the seq. no. associated with the LSA to check.
435 // \param expTime How long to wait before triggering the event.
akmhoque53353462014-04-22 08:43:45 -0500436ndn::EventId
akmhoque31d1d4b2014-05-05 22:08:14 -0500437Lsdb::scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
akmhoquec7a79b22014-05-26 08:06:19 -0500438 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500439{
Vince Lehman7c603292014-09-11 17:48:16 -0500440 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
dmcoomes9f936662017-03-02 10:33:09 -0600441 std::bind(&Lsdb::exprireOrRefreshCoordinateLsa,
Vince Lehman7c603292014-09-11 17:48:16 -0500442 this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500443}
444
445bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500446Lsdb::installCoordinateLsa(CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500447{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700448 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500449 CoordinateLsa* chkCorLsa = findCoordinateLsa(clsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500450 // Checking whether the LSA is new or not.
akmhoque157b0a42014-05-13 00:26:37 -0500451 if (chkCorLsa == 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500452 _LOG_DEBUG("New Coordinate LSA. Adding to LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500453 _LOG_DEBUG("Adding Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500454 clsa.writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500455 addCoordinateLsa(clsa);
akmhoque2f423352014-06-03 11:49:35 -0500456
Nick Gordon5c467f02016-07-13 13:40:10 -0500457 // Register the LSA's origin router prefix
akmhoque157b0a42014-05-13 00:26:37 -0500458 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500459 m_nlsr.getNamePrefixTable().addEntry(clsa.getOrigRouter(),
460 clsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500461 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500462 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500463 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500464 }
Nick G97e34942016-07-11 14:46:27 -0500465 // Set the expiration time for the new LSA.
akmhoque157b0a42014-05-13 00:26:37 -0500466 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500467 ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
468 ndn::time::system_clock::now();
469 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500470 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500471 scheduleCoordinateLsaExpiration(clsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500472 clsa.getLsSeqNo(), timeToExpire);
akmhoque53353462014-04-22 08:43:45 -0500473 }
Nick G97e34942016-07-11 14:46:27 -0500474 // We are just updating this LSA.
akmhoque157b0a42014-05-13 00:26:37 -0500475 else {
476 if (chkCorLsa->getLsSeqNo() < clsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500477 _LOG_DEBUG("Updated Coordinate LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500478 _LOG_DEBUG("Deleting Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500479 chkCorLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500480 chkCorLsa->setLsSeqNo(clsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500481 chkCorLsa->setExpirationTimePoint(clsa.getExpirationTimePoint());
Nick G97e34942016-07-11 14:46:27 -0500482 // If the new LSA contains new routing information, update the LSDB with it.
akmhoque157b0a42014-05-13 00:26:37 -0500483 if (!chkCorLsa->isEqualContent(clsa)) {
akmhoqueb6450b12014-04-24 00:01:03 -0500484 chkCorLsa->setCorRadius(clsa.getCorRadius());
485 chkCorLsa->setCorTheta(clsa.getCorTheta());
akmhoque157b0a42014-05-13 00:26:37 -0500486 if (m_nlsr.getConfParameter().getHyperbolicState() >= HYPERBOLIC_STATE_ON) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500487 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500488 }
489 }
Nick G97e34942016-07-11 14:46:27 -0500490 // If this is an LSA from another router, refresh its expiration time.
akmhoque157b0a42014-05-13 00:26:37 -0500491 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500492 ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
493 ndn::time::system_clock::now();
494 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500495 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500496 cancelScheduleLsaExpiringEvent(chkCorLsa->getExpiringEventId());
497 chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(clsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500498 clsa.getLsSeqNo(),
499 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500500 _LOG_DEBUG("Adding Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500501 chkCorLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500502 }
503 }
504 return true;
505}
506
507bool
akmhoqueb6450b12014-04-24 00:01:03 -0500508Lsdb::addCoordinateLsa(CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500509{
akmhoqueb6450b12014-04-24 00:01:03 -0500510 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
511 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600512 std::bind(corLsaCompareByKey, _1,
akmhoque157b0a42014-05-13 00:26:37 -0500513 clsa.getKey()));
514 if (it == m_corLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500515 m_corLsdb.push_back(clsa);
516 return true;
517 }
518 return false;
519}
520
521bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500522Lsdb::removeCoordinateLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500523{
akmhoqueb6450b12014-04-24 00:01:03 -0500524 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
525 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600526 std::bind(corLsaCompareByKey,
akmhoque157b0a42014-05-13 00:26:37 -0500527 _1, key));
528 if (it != m_corLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500529 _LOG_DEBUG("Deleting Coordinate Lsa");
Nick Gordon5c467f02016-07-13 13:40:10 -0500530 it->writeLog();
531
532 if (it->getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
533 m_nlsr.getNamePrefixTable().removeEntry(it->getOrigRouter(), it->getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500534 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500535
akmhoque53353462014-04-22 08:43:45 -0500536 m_corLsdb.erase(it);
537 return true;
538 }
539 return false;
540}
541
542bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500543Lsdb::doesCoordinateLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500544{
akmhoqueb6450b12014-04-24 00:01:03 -0500545 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
546 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600547 std::bind(corLsaCompareByKey,
akmhoque157b0a42014-05-13 00:26:37 -0500548 _1, key));
549 if (it == m_corLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500550 return false;
551 }
552 return true;
553}
554
555void
akmhoque2f423352014-06-03 11:49:35 -0500556Lsdb::writeCorLsdbLog()
akmhoque53353462014-04-22 08:43:45 -0500557{
akmhoque2f423352014-06-03 11:49:35 -0500558 _LOG_DEBUG("---------------Cor LSDB-------------------");
akmhoqueb6450b12014-04-24 00:01:03 -0500559 for (std::list<CoordinateLsa>::iterator it = m_corLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500560 it != m_corLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -0500561 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -0500562 }
563}
564
Jiewen Tana0497d82015-02-02 21:59:18 -0800565const std::list<CoordinateLsa>&
566Lsdb::getCoordinateLsdb()
567{
568 return m_corLsdb;
569}
570
akmhoque53353462014-04-22 08:43:45 -0500571// Adj LSA and LSDB related function starts here
572
Nick G97e34942016-07-11 14:46:27 -0500573 /*! \brief Returns whether an adj. LSA object is from some router.
574 \param alsa The adj. LSA object.
575 \param key The router name that you want to compare the LSA with.
576 */
akmhoque53353462014-04-22 08:43:45 -0500577static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500578adjLsaCompareByKey(AdjLsa& alsa, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500579{
580 return alsa.getKey() == key;
581}
582
akmhoque53353462014-04-22 08:43:45 -0500583void
Vince Lehman50df6b72015-03-03 12:06:40 -0600584Lsdb::scheduleAdjLsaBuild()
akmhoque53353462014-04-22 08:43:45 -0500585{
Vince Lehman50df6b72015-03-03 12:06:40 -0600586 m_nlsr.incrementAdjBuildCount();
587
Nick Gordon5c467f02016-07-13 13:40:10 -0500588 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
589 // Don't build adjacency LSAs in hyperbolic routing
dmcoomes9eaf3f42017-02-21 11:39:01 -0600590 _LOG_DEBUG("Adjacency LSA not built. Currently in hyperbolic routing state.");
Nick Gordon5c467f02016-07-13 13:40:10 -0500591 return;
592 }
593
Vince Lehman50df6b72015-03-03 12:06:40 -0600594 if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
595 _LOG_DEBUG("Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
596
dmcoomes9f936662017-03-02 10:33:09 -0600597 m_scheduler.scheduleEvent(m_adjLsaBuildInterval, std::bind(&Lsdb::buildAdjLsa, this));
Vince Lehman50df6b72015-03-03 12:06:40 -0600598 m_nlsr.setIsBuildAdjLsaSheduled(true);
599 }
600}
601
602void
603Lsdb::buildAdjLsa()
604{
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500605 _LOG_TRACE("Lsdb::buildAdjLsa called");
Vince Lehman50df6b72015-03-03 12:06:40 -0600606
akmhoque674b0b12014-05-20 14:33:28 -0500607 m_nlsr.setIsBuildAdjLsaSheduled(false);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500608
609 if (m_nlsr.getAdjacencyList().isAdjLsaBuildable(m_nlsr.getConfParameter().getInterestRetryNumber())) {
610
akmhoque31d1d4b2014-05-05 22:08:14 -0500611 int adjBuildCount = m_nlsr.getAdjBuildCount();
Nick G97e34942016-07-11 14:46:27 -0500612 // Only do the adjLsa build if there's one scheduled
akmhoque157b0a42014-05-13 00:26:37 -0500613 if (adjBuildCount > 0) {
Nick G97e34942016-07-11 14:46:27 -0500614 // It only makes sense to do the adjLsa build if we have neighbors
akmhoque157b0a42014-05-13 00:26:37 -0500615 if (m_nlsr.getAdjacencyList().getNumOfActiveNeighbor() > 0) {
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500616 _LOG_DEBUG("Building and installing own Adj LSA");
akmhoque31d1d4b2014-05-05 22:08:14 -0500617 buildAndInstallOwnAdjLsa();
akmhoque53353462014-04-22 08:43:45 -0500618 }
Nick G97e34942016-07-11 14:46:27 -0500619 // We have no active neighbors, meaning no one can route through
620 // us. So delete our entry in the LSDB. This prevents this
621 // router from refreshing the LSA, eventually causing other
622 // routers to delete it, too.
akmhoque157b0a42014-05-13 00:26:37 -0500623 else {
dmcoomes9f936662017-03-02 10:33:09 -0600624 _LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors");
Nick G97e34942016-07-11 14:46:27 -0500625 // Get this router's key
akmhoque31d1d4b2014-05-05 22:08:14 -0500626 ndn::Name key = m_nlsr.getConfParameter().getRouterPrefix();
alvy49b1c0c2014-12-19 13:57:46 -0600627 key.append(AdjLsa::TYPE_STRING);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500628
akmhoque31d1d4b2014-05-05 22:08:14 -0500629 removeAdjLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500630 // Recompute routing table after removal
akmhoque31d1d4b2014-05-05 22:08:14 -0500631 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500632 }
Nick G97e34942016-07-11 14:46:27 -0500633 // In the case that during building the adj LSA, the FIB has to
634 // wait on an Interest response, the number of scheduled adj LSA
635 // builds could change, so we shouldn't just set it to 0.
akmhoque31d1d4b2014-05-05 22:08:14 -0500636 m_nlsr.setAdjBuildCount(m_nlsr.getAdjBuildCount() - adjBuildCount);
akmhoque53353462014-04-22 08:43:45 -0500637 }
638 }
Nick G97e34942016-07-11 14:46:27 -0500639 // We are still waiting to know the adjacency status of some
640 // neighbor, so schedule a build for later (when all that has
641 // hopefully finished)
642 else {
643 m_nlsr.setIsBuildAdjLsaSheduled(true);
644 int schedulingTime = m_nlsr.getConfParameter().getInterestRetryNumber() *
645 m_nlsr.getConfParameter().getInterestResendTime();
646 m_scheduler.scheduleEvent(ndn::time::seconds(schedulingTime),
dmcoomes9f936662017-03-02 10:33:09 -0600647 std::bind(&Lsdb::buildAdjLsa, this));
Nick G97e34942016-07-11 14:46:27 -0500648 }
akmhoque53353462014-04-22 08:43:45 -0500649}
650
akmhoque53353462014-04-22 08:43:45 -0500651bool
652Lsdb::addAdjLsa(AdjLsa& alsa)
653{
654 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
655 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600656 std::bind(adjLsaCompareByKey, _1,
akmhoque53353462014-04-22 08:43:45 -0500657 alsa.getKey()));
akmhoque157b0a42014-05-13 00:26:37 -0500658 if (it == m_adjLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500659 m_adjLsdb.push_back(alsa);
660 return true;
661 }
662 return false;
663}
664
akmhoqueb6450b12014-04-24 00:01:03 -0500665AdjLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500666Lsdb::findAdjLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500667{
668 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
669 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600670 std::bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500671 if (it != m_adjLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500672 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500673 }
akmhoqueb6450b12014-04-24 00:01:03 -0500674 return 0;
akmhoque53353462014-04-22 08:43:45 -0500675}
676
akmhoque53353462014-04-22 08:43:45 -0500677bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500678Lsdb::isAdjLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500679{
akmhoqueb6450b12014-04-24 00:01:03 -0500680 AdjLsa* adjLsaCheck = findAdjLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500681 // If it is in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500682 if (adjLsaCheck != 0) {
Nick G97e34942016-07-11 14:46:27 -0500683 // And the supplied seq no is newer (higher) than the current one.
akmhoque157b0a42014-05-13 00:26:37 -0500684 if (adjLsaCheck->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500685 return true;
686 }
akmhoque157b0a42014-05-13 00:26:37 -0500687 else {
akmhoque53353462014-04-22 08:43:45 -0500688 return false;
689 }
690 }
691 return true;
692}
693
akmhoque53353462014-04-22 08:43:45 -0500694ndn::EventId
akmhoquec7a79b22014-05-26 08:06:19 -0500695Lsdb::scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
696 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500697{
Vince Lehman7c603292014-09-11 17:48:16 -0500698 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
dmcoomes9f936662017-03-02 10:33:09 -0600699 std::bind(&Lsdb::exprireOrRefreshAdjLsa, this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500700}
701
702bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500703Lsdb::installAdjLsa(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500704{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700705 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500706 AdjLsa* chkAdjLsa = findAdjLsa(alsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500707 // If this adj. LSA is not in the LSDB already
akmhoque157b0a42014-05-13 00:26:37 -0500708 if (chkAdjLsa == 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500709 _LOG_DEBUG("New Adj LSA. Adding to LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500710 _LOG_DEBUG("Adding Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500711 alsa.writeLog();
akmhoque53353462014-04-22 08:43:45 -0500712 addAdjLsa(alsa);
Nick G97e34942016-07-11 14:46:27 -0500713 // Add any new name prefixes to the NPT
akmhoque31d1d4b2014-05-05 22:08:14 -0500714 alsa.addNptEntries(m_nlsr);
715 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque157b0a42014-05-13 00:26:37 -0500716 if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500717 ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
718 ndn::time::system_clock::now();
719 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500720 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500721 scheduleAdjLsaExpiration(alsa.getKey(),
akmhoque53353462014-04-22 08:43:45 -0500722 alsa.getLsSeqNo(), timeToExpire);
723 }
akmhoque157b0a42014-05-13 00:26:37 -0500724 else {
725 if (chkAdjLsa->getLsSeqNo() < alsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500726 _LOG_DEBUG("Updated Adj LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500727 _LOG_DEBUG("Deleting Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500728 chkAdjLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500729 chkAdjLsa->setLsSeqNo(alsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500730 chkAdjLsa->setExpirationTimePoint(alsa.getExpirationTimePoint());
Nick G97e34942016-07-11 14:46:27 -0500731 // If the new adj LSA has new content, update the contents of
732 // the LSDB entry. Additionally, since we've changed the
733 // contents of the LSDB, we have to schedule a routing
734 // calculation.
akmhoque157b0a42014-05-13 00:26:37 -0500735 if (!chkAdjLsa->isEqualContent(alsa)) {
akmhoqueb6450b12014-04-24 00:01:03 -0500736 chkAdjLsa->getAdl().reset();
akmhoquefdbddb12014-05-02 18:35:19 -0500737 chkAdjLsa->getAdl().addAdjacents(alsa.getAdl());
akmhoque31d1d4b2014-05-05 22:08:14 -0500738 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500739 }
akmhoque157b0a42014-05-13 00:26:37 -0500740 if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500741 ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
742 ndn::time::system_clock::now();
743 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500744 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500745 cancelScheduleLsaExpiringEvent(chkAdjLsa->getExpiringEventId());
746 chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(alsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500747 alsa.getLsSeqNo(),
748 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500749 _LOG_DEBUG("Adding Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500750 chkAdjLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500751 }
752 }
753 return true;
754}
755
756bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500757Lsdb::buildAndInstallOwnAdjLsa()
akmhoque53353462014-04-22 08:43:45 -0500758{
akmhoque31d1d4b2014-05-05 22:08:14 -0500759 AdjLsa adjLsa(m_nlsr.getConfParameter().getRouterPrefix(),
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500760 m_sequencingManager.getAdjLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500761 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500762 m_nlsr.getAdjacencyList().getNumOfActiveNeighbor(),
763 m_nlsr.getAdjacencyList());
Vince Lehman904c2412014-09-23 19:36:11 -0500764
Nick Gordon5c467f02016-07-13 13:40:10 -0500765 //Sync adjacency LSAs if link-state or dry-run HR is enabled.
766 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_ON) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500767 m_sequencingManager.increaseAdjLsaSeq();
768 m_sequencingManager.writeSeqNoToFile();
769 m_sync.publishRoutingUpdate(AdjLsa::TYPE_STRING, m_sequencingManager.getAdjLsaSeq());
Nick Gordon5c467f02016-07-13 13:40:10 -0500770 }
Vince Lehman904c2412014-09-23 19:36:11 -0500771
Vince Lehman9d097802015-03-16 17:55:59 -0500772 return installAdjLsa(adjLsa);
akmhoque53353462014-04-22 08:43:45 -0500773}
774
775bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500776Lsdb::removeAdjLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500777{
778 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
779 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600780 std::bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500781 if (it != m_adjLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500782 _LOG_DEBUG("Deleting Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500783 (*it).writeLog();
akmhoque31d1d4b2014-05-05 22:08:14 -0500784 (*it).removeNptEntries(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500785 m_adjLsdb.erase(it);
786 return true;
787 }
788 return false;
789}
790
791bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500792Lsdb::doesAdjLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500793{
794 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
795 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600796 std::bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500797 if (it == m_adjLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500798 return false;
799 }
800 return true;
801}
802
Jiewen Tana0497d82015-02-02 21:59:18 -0800803const std::list<AdjLsa>&
akmhoque53353462014-04-22 08:43:45 -0500804Lsdb::getAdjLsdb()
805{
806 return m_adjLsdb;
807}
808
809void
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700810Lsdb::setLsaRefreshTime(const seconds& lsaRefreshTime)
akmhoque53353462014-04-22 08:43:45 -0500811{
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700812 m_lsaRefreshTime = lsaRefreshTime;
akmhoque53353462014-04-22 08:43:45 -0500813}
814
815void
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500816Lsdb::setThisRouterPrefix(std::string trp)
akmhoque53353462014-04-22 08:43:45 -0500817{
818 m_thisRouterPrefix = trp;
819}
820
Nick G97e34942016-07-11 14:46:27 -0500821 // This function determines whether a name LSA should be refreshed
822 // or expired. The conditions for getting refreshed are: it is still
823 // in the LSDB, it hasn't been updated by something else already (as
824 // evidenced by its seq. no.), and this is the originating router for
825 // the LSA. Is it let expire in all other cases.
826 // lsaKey is the key of the LSA's publishing router.
827 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500828void
akmhoque31d1d4b2014-05-05 22:08:14 -0500829Lsdb::exprireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500830{
akmhoque674b0b12014-05-20 14:33:28 -0500831 _LOG_DEBUG("Lsdb::exprireOrRefreshNameLsa Called");
832 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500833 NameLsa* chkNameLsa = findNameLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500834 // If this name LSA exists in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500835 if (chkNameLsa != 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500836 _LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500837 // If its seq no is the one we are expecting.
akmhoque157b0a42014-05-13 00:26:37 -0500838 if (chkNameLsa->getLsSeqNo() == seqNo) {
839 if (chkNameLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500840 _LOG_DEBUG("Own Name LSA, so refreshing it");
841 _LOG_DEBUG("Deleting Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500842 chkNameLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500843 chkNameLsa->setLsSeqNo(chkNameLsa->getLsSeqNo() + 1);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500844 m_sequencingManager.setNameLsaSeq(chkNameLsa->getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500845 chkNameLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500846 _LOG_DEBUG("Adding Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500847 chkNameLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500848 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500849 chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(chkNameLsa->getKey(),
akmhoquefdbddb12014-05-02 18:35:19 -0500850 chkNameLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700851 m_lsaRefreshTime));
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500852 m_sequencingManager.writeSeqNoToFile();
853 m_sync.publishRoutingUpdate(NameLsa::TYPE_STRING, m_sequencingManager.getNameLsaSeq());
akmhoque53353462014-04-22 08:43:45 -0500854 }
Nick G97e34942016-07-11 14:46:27 -0500855 // Since we cannot refresh other router's LSAs, our only choice is to expire.
akmhoque157b0a42014-05-13 00:26:37 -0500856 else {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600857 _LOG_DEBUG("Other's Name LSA, so removing from LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500858 removeNameLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500859 }
860 }
861 }
862}
863
Nick G97e34942016-07-11 14:46:27 -0500864 // This function determines whether an adj. LSA should be refreshed
865 // or expired. The conditions for getting refreshed are: it is still
866 // in the LSDB, it hasn't been updated by something else already (as
867 // evidenced by its seq. no.), and this is the originating router for
868 // the LSA. Is it let expire in all other cases.
869 // lsaKey is the key of the LSA's publishing router.
870 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500871void
akmhoque31d1d4b2014-05-05 22:08:14 -0500872Lsdb::exprireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500873{
akmhoque674b0b12014-05-20 14:33:28 -0500874 _LOG_DEBUG("Lsdb::exprireOrRefreshAdjLsa Called");
dmcoomes9eaf3f42017-02-21 11:39:01 -0600875 _LOG_DEBUG("LSA Key: " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500876 AdjLsa* chkAdjLsa = findAdjLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500877 // If this is a valid LSA
akmhoque157b0a42014-05-13 00:26:37 -0500878 if (chkAdjLsa != 0) {
akmhoque2f423352014-06-03 11:49:35 -0500879 _LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500880 // And if it hasn't been updated for some other reason
akmhoque157b0a42014-05-13 00:26:37 -0500881 if (chkAdjLsa->getLsSeqNo() == seqNo) {
Nick G97e34942016-07-11 14:46:27 -0500882 // If it is our own LSA
akmhoque157b0a42014-05-13 00:26:37 -0500883 if (chkAdjLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500884 _LOG_DEBUG("Own Adj LSA, so refreshing it");
885 _LOG_DEBUG("Deleting Adj Lsa");
886 chkAdjLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500887 chkAdjLsa->setLsSeqNo(chkAdjLsa->getLsSeqNo() + 1);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500888 m_sequencingManager.setAdjLsaSeq(chkAdjLsa->getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500889 chkAdjLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500890 _LOG_DEBUG("Adding Adj Lsa");
891 chkAdjLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500892 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500893 chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(chkAdjLsa->getKey(),
akmhoquefdbddb12014-05-02 18:35:19 -0500894 chkAdjLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700895 m_lsaRefreshTime));
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500896 m_sequencingManager.writeSeqNoToFile();
897 m_sync.publishRoutingUpdate(AdjLsa::TYPE_STRING, m_sequencingManager.getAdjLsaSeq());
akmhoque53353462014-04-22 08:43:45 -0500898 }
Nick G97e34942016-07-11 14:46:27 -0500899 // An LSA from another router is expiring
akmhoque157b0a42014-05-13 00:26:37 -0500900 else {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600901 _LOG_DEBUG("Other's Adj LSA, so removing from LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500902 removeAdjLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500903 }
Nick G97e34942016-07-11 14:46:27 -0500904 // We have changed the contents of the LSDB, so we have to
905 // schedule a routing calculation
akmhoque31d1d4b2014-05-05 22:08:14 -0500906 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500907 }
908 }
909}
910
Nick G97e34942016-07-11 14:46:27 -0500911 // This function determines whether an adj. LSA should be refreshed
912 // or expired. The conditions for getting refreshed are: it is still
913 // in the LSDB, it hasn't been updated by something else already (as
914 // evidenced by its seq. no.), and this is the originating router for
915 // the LSA. It is let expire in all other cases.
916 // lsaKey is the key of the LSA's publishing router.
917 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500918void
akmhoque31d1d4b2014-05-05 22:08:14 -0500919Lsdb::exprireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
akmhoqueb6450b12014-04-24 00:01:03 -0500920 uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500921{
akmhoque674b0b12014-05-20 14:33:28 -0500922 _LOG_DEBUG("Lsdb::exprireOrRefreshCorLsa Called ");
923 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500924 CoordinateLsa* chkCorLsa = findCoordinateLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500925 // Whether the LSA is in the LSDB or not.
akmhoque157b0a42014-05-13 00:26:37 -0500926 if (chkCorLsa != 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500927 _LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500928 // Whether the LSA has been updated without our knowledge.
akmhoque157b0a42014-05-13 00:26:37 -0500929 if (chkCorLsa->getLsSeqNo() == seqNo) {
930 if (chkCorLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500931 _LOG_DEBUG("Own Cor LSA, so refreshing it");
932 _LOG_DEBUG("Deleting Coordinate Lsa");
933 chkCorLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500934 chkCorLsa->setLsSeqNo(chkCorLsa->getLsSeqNo() + 1);
Nick Gordon5c467f02016-07-13 13:40:10 -0500935 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500936 m_sequencingManager.setCorLsaSeq(chkCorLsa->getLsSeqNo());
Nick Gordon5c467f02016-07-13 13:40:10 -0500937 }
938
akmhoquec7a79b22014-05-26 08:06:19 -0500939 chkCorLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500940 _LOG_DEBUG("Adding Coordinate Lsa");
941 chkCorLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500942 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500943 chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(
944 chkCorLsa->getKey(),
945 chkCorLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700946 m_lsaRefreshTime));
Nick Gordon5c467f02016-07-13 13:40:10 -0500947 // Only sync coordinate LSAs if link-state routing is disabled
948 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500949 m_sequencingManager.writeSeqNoToFile();
950 m_sync.publishRoutingUpdate(CoordinateLsa::TYPE_STRING, m_sequencingManager.getCorLsaSeq());
Nick Gordon5c467f02016-07-13 13:40:10 -0500951 }
akmhoque53353462014-04-22 08:43:45 -0500952 }
Nick G97e34942016-07-11 14:46:27 -0500953 // We can't refresh other router's LSAs, so we remove it.
akmhoque157b0a42014-05-13 00:26:37 -0500954 else {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600955 _LOG_DEBUG("Other's Cor LSA, so removing from LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500956 removeCoordinateLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500957 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500958 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500959 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500960 }
961 }
962 }
963}
964
akmhoque53353462014-04-22 08:43:45 -0500965void
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700966Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500967 steady_clock::TimePoint deadline)
akmhoque31d1d4b2014-05-05 22:08:14 -0500968{
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500969 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
970 deadline = steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700971 }
Nick G97e34942016-07-11 14:46:27 -0500972 // The first component of the interest is the name.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500973 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
Nick G97e34942016-07-11 14:46:27 -0500974 // The seq no is the last
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500975 uint64_t seqNo = interestName[-1].toNumber();
976
Nick G97e34942016-07-11 14:46:27 -0500977 // If the LSA is not found in the list currently.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500978 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
979 m_highestSeqNo[lsaName] = seqNo;
980 }
Nick G97e34942016-07-11 14:46:27 -0500981 // If the new seq no is higher, that means the LSA is valid
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500982 else if (seqNo > m_highestSeqNo[lsaName]) {
983 m_highestSeqNo[lsaName] = seqNo;
984 }
Nick G97e34942016-07-11 14:46:27 -0500985 // Otherwise, its an old/invalid LSA
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500986 else if (seqNo < m_highestSeqNo[lsaName]) {
987 return;
988 }
989
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500990 ndn::Interest interest(interestName);
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700991 interest.setInterestLifetime(m_nlsr.getConfParameter().getLsaInterestLifetime());
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500992
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500993 _LOG_DEBUG("Fetching Data for LSA: " << interestName << " Seq number: " << seqNo);
994 ndn::util::SegmentFetcher::fetch(m_nlsr.getNlsrFace(), interest,
995 m_nlsr.getValidator(),
dmcoomes9f936662017-03-02 10:33:09 -0600996 std::bind(&Lsdb::afterFetchLsa, this, _1, interestName),
997 std::bind(&Lsdb::onFetchLsaError, this, _1, _2, interestName,
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500998 timeoutCount, deadline, lsaName, seqNo));
akmhoque31d1d4b2014-05-05 22:08:14 -0500999}
1000
1001void
1002Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
1003{
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001004 const ndn::Name& interestName(interest.getName());
1005 _LOG_DEBUG("Interest received for LSA: " << interestName);
1006
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001007 std::string chkString("LSA");
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001008 int32_t lsaPosition = util::getNameComponentPosition(interest.getName(), chkString);
1009
akmhoque157b0a42014-05-13 00:26:37 -05001010 if (lsaPosition >= 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001011
Nick G97e34942016-07-11 14:46:27 -05001012 // Forms the name of the router that the Interest packet came from.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001013 ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
1014 originRouter.append(interestName.getSubName(lsaPosition + 1,
1015 interest.getName().size() - lsaPosition - 3));
1016
1017 uint64_t seqNo = interestName[-1].toNumber();
1018 _LOG_DEBUG("LSA sequence number from interest: " << seqNo);
1019
1020 std::string interestedLsType = interestName[-2].toUri();
1021
Nick G97e34942016-07-11 14:46:27 -05001022 // Passes the Interest off to the appropriate subprocessor
alvy49b1c0c2014-12-19 13:57:46 -06001023 if (interestedLsType == NameLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001024 processInterestForNameLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001025 }
alvy49b1c0c2014-12-19 13:57:46 -06001026 else if (interestedLsType == AdjLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001027 processInterestForAdjacencyLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001028 }
alvy49b1c0c2014-12-19 13:57:46 -06001029 else if (interestedLsType == CoordinateLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001030 processInterestForCoordinateLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001031 }
akmhoque157b0a42014-05-13 00:26:37 -05001032 else {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001033 _LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
akmhoque31d1d4b2014-05-05 22:08:14 -05001034 }
1035 }
1036}
1037
Nick G97e34942016-07-11 14:46:27 -05001038 // \brief Sends LSA data.
1039 // \param interest The Interest that warranted the data.
1040 // \param content The data that the Interest was seeking.
akmhoque31d1d4b2014-05-05 22:08:14 -05001041void
akmhoque69c9aa92014-07-23 15:15:05 -05001042Lsdb::putLsaData(const ndn::Interest& interest, const std::string& content)
1043{
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001044 LsaContentPublisher publisher(m_nlsr.getNlsrFace(),
1045 m_nlsr.getKeyChain(),
1046 m_lsaRefreshTime,
1047 content);
dmcoomes9eaf3f42017-02-21 11:39:01 -06001048 _LOG_DEBUG("Sending requested data ( " << content << ") for interest (" << interest
1049 << ") to be published and added to face.");
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001050 publisher.publish(interest.getName(),
1051 ndn::security::signingByCertificate(m_nlsr.getDefaultCertName()));
akmhoque69c9aa92014-07-23 15:15:05 -05001052}
1053
Nick G97e34942016-07-11 14:46:27 -05001054 // \brief Finds and sends a requested name LSA.
1055 // \param interest The interest that seeks the name LSA.
1056 // \param lsaKey The LSA that the Interest is seeking.
1057 // \param seqNo A sequence number to ensure that we are sending the
1058 // version that was requested.
akmhoque69c9aa92014-07-23 15:15:05 -05001059void
akmhoque31d1d4b2014-05-05 22:08:14 -05001060Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
1061 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001062 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001063{
dmcoomes9eaf3f42017-02-21 11:39:01 -06001064
1065 _LOG_DEBUG("nameLsa interest " << interest << " received");
akmhoque31d1d4b2014-05-05 22:08:14 -05001066 NameLsa* nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001067 if (nameLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001068 if (nameLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001069 std::string content = nameLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001070 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001071 }
dmcoomes9eaf3f42017-02-21 11:39:01 -06001072 else {
1073 _LOG_TRACE("SeqNo for nameLsa does not match");
1074 }
1075 }
1076 else {
1077 _LOG_TRACE(interest << " was not found in this lsdb");
akmhoque31d1d4b2014-05-05 22:08:14 -05001078 }
1079}
1080
Nick G97e34942016-07-11 14:46:27 -05001081 // \brief Finds and sends a requested adj. LSA.
1082 // \param interest The interest that seeks the adj. LSA.
1083 // \param lsaKey The LSA that the Interest is seeking.
1084 // \param seqNo A sequence number to ensure that we are sending the
1085 // version that was requested.
akmhoque31d1d4b2014-05-05 22:08:14 -05001086void
1087Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
1088 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001089 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001090{
Nick Gordon5c467f02016-07-13 13:40:10 -05001091 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
dmcoomes9eaf3f42017-02-21 11:39:01 -06001092 _LOG_ERROR("Received interest for an adjacency LSA when hyperbolic routing is enabled");
Nick Gordon5c467f02016-07-13 13:40:10 -05001093 }
1094
dmcoomes9eaf3f42017-02-21 11:39:01 -06001095 _LOG_DEBUG("AdjLsa interest " << interest << " received");
akmhoque31d1d4b2014-05-05 22:08:14 -05001096 AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001097 if (adjLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001098 if (adjLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001099 std::string content = adjLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001100 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001101 }
dmcoomes9eaf3f42017-02-21 11:39:01 -06001102 else {
1103 _LOG_TRACE("SeqNo for AdjLsa does not match");
1104 }
1105 }
1106 else {
1107 _LOG_TRACE(interest << " was not found in this lsdb");
akmhoque31d1d4b2014-05-05 22:08:14 -05001108 }
1109}
1110
Nick G97e34942016-07-11 14:46:27 -05001111 // \brief Finds and sends a requested cor. LSA.
1112 // \param interest The interest that seeks the cor. LSA.
1113 // \param lsaKey The LSA that the Interest is seeking.
1114 // \param seqNo A sequence number to ensure that we are sending the
1115 // version that was requested.
akmhoque31d1d4b2014-05-05 22:08:14 -05001116void
1117Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
1118 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001119 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001120{
Nick Gordon5c467f02016-07-13 13:40:10 -05001121 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
dmcoomes9eaf3f42017-02-21 11:39:01 -06001122 _LOG_ERROR("Received Interest for a coordinate LSA when link-state routing is enabled");
Nick Gordon5c467f02016-07-13 13:40:10 -05001123 }
1124
dmcoomes9eaf3f42017-02-21 11:39:01 -06001125 _LOG_DEBUG("CoordinateLsa interest " << interest << " received");
akmhoque31d1d4b2014-05-05 22:08:14 -05001126 CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001127 if (corLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001128 if (corLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001129 std::string content = corLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001130 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001131 }
dmcoomes9eaf3f42017-02-21 11:39:01 -06001132 else {
1133 _LOG_TRACE("SeqNo for CoordinateLsa does not match");
1134 }
1135 }
1136 else {
1137 _LOG_TRACE(interest << " was not found in this lsdb");
akmhoque31d1d4b2014-05-05 22:08:14 -05001138 }
1139}
1140
1141void
dmcoomes9f936662017-03-02 10:33:09 -06001142Lsdb::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
Yingdi Yu20e3a6e2014-05-26 23:16:10 -07001143{
1144 const ndn::Name& dataName = data->getName();
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001145 _LOG_DEBUG("Data validation successful for LSA: " << dataName);
1146
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001147 std::string chkString("LSA");
akmhoque31d1d4b2014-05-05 22:08:14 -05001148 int32_t lsaPosition = util::getNameComponentPosition(dataName, chkString);
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001149
akmhoque157b0a42014-05-13 00:26:37 -05001150 if (lsaPosition >= 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001151
Nick G97e34942016-07-11 14:46:27 -05001152 // Extracts the prefix of the originating router from the data.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001153 ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001154 originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001155
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001156 uint64_t seqNo = dataName[-1].toNumber();
1157 std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()));
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001158
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001159 std::string interestedLsType = dataName[-2].toUri();
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001160
alvy49b1c0c2014-12-19 13:57:46 -06001161 if (interestedLsType == NameLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001162 processContentNameLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001163 }
alvy49b1c0c2014-12-19 13:57:46 -06001164 else if (interestedLsType == AdjLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001165 processContentAdjacencyLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001166 }
alvy49b1c0c2014-12-19 13:57:46 -06001167 else if (interestedLsType == CoordinateLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001168 processContentCoordinateLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001169 }
akmhoque157b0a42014-05-13 00:26:37 -05001170 else {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001171 _LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
akmhoque31d1d4b2014-05-05 22:08:14 -05001172 }
1173 }
1174}
1175
1176void
1177Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001178 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001179{
akmhoque157b0a42014-05-13 00:26:37 -05001180 if (isNameLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001181 NameLsa nameLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001182 if (nameLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001183 installNameLsa(nameLsa);
1184 }
akmhoque157b0a42014-05-13 00:26:37 -05001185 else {
akmhoque2f423352014-06-03 11:49:35 -05001186 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001187 }
1188 }
1189}
1190
1191void
1192Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001193 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001194{
akmhoque157b0a42014-05-13 00:26:37 -05001195 if (isAdjLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001196 AdjLsa adjLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001197 if (adjLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001198 installAdjLsa(adjLsa);
1199 }
akmhoque157b0a42014-05-13 00:26:37 -05001200 else {
akmhoque2f423352014-06-03 11:49:35 -05001201 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001202 }
1203 }
1204}
1205
1206void
1207Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001208 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001209{
akmhoque157b0a42014-05-13 00:26:37 -05001210 if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001211 CoordinateLsa corLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001212 if (corLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001213 installCoordinateLsa(corLsa);
1214 }
akmhoque157b0a42014-05-13 00:26:37 -05001215 else {
akmhoque2f423352014-06-03 11:49:35 -05001216 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001217 }
1218 }
1219}
1220
akmhoquec7a79b22014-05-26 08:06:19 -05001221ndn::time::system_clock::TimePoint
1222Lsdb::getLsaExpirationTimePoint()
1223{
1224 ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
1225 expirationTimePoint = expirationTimePoint +
1226 ndn::time::seconds(m_nlsr.getConfParameter().getRouterDeadInterval());
1227 return expirationTimePoint;
1228}
akmhoque31d1d4b2014-05-05 22:08:14 -05001229
1230void
akmhoque2f423352014-06-03 11:49:35 -05001231Lsdb::writeAdjLsdbLog()
akmhoque53353462014-04-22 08:43:45 -05001232{
akmhoque2f423352014-06-03 11:49:35 -05001233 _LOG_DEBUG("---------------Adj LSDB-------------------");
akmhoque53353462014-04-22 08:43:45 -05001234 for (std::list<AdjLsa>::iterator it = m_adjLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -05001235 it != m_adjLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -05001236 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -05001237 }
1238}
1239
1240//-----utility function -----
1241bool
akmhoque31d1d4b2014-05-05 22:08:14 -05001242Lsdb::doesLsaExist(const ndn::Name& key, const std::string& lsType)
akmhoque53353462014-04-22 08:43:45 -05001243{
alvy49b1c0c2014-12-19 13:57:46 -06001244 if (lsType == NameLsa::TYPE_STRING) {
akmhoque53353462014-04-22 08:43:45 -05001245 return doesNameLsaExist(key);
1246 }
alvy49b1c0c2014-12-19 13:57:46 -06001247 else if (lsType == AdjLsa::TYPE_STRING) {
akmhoque53353462014-04-22 08:43:45 -05001248 return doesAdjLsaExist(key);
1249 }
alvy49b1c0c2014-12-19 13:57:46 -06001250 else if (lsType == CoordinateLsa::TYPE_STRING) {
akmhoqueb6450b12014-04-24 00:01:03 -05001251 return doesCoordinateLsaExist(key);
akmhoque53353462014-04-22 08:43:45 -05001252 }
1253 return false;
1254}
1255
Alexander Afanasyev8388ec62014-08-16 18:38:57 -07001256} // namespace nlsr