blob: b71b48e61e3fa02e16d94d924e523a1f71704e69 [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,
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500199 std::bind(&Lsdb::expireOrRefreshNameLsa, 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());
Nick Gordonf14ec352017-07-24 16:09:58 -0500219 std::list<ndn::Name> nameList = nlsa.getNpl().getNames();
akmhoque31d1d4b2014-05-05 22:08:14 -0500220 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.
Nick Gordonf14ec352017-07-24 16:09:58 -0500248 std::list<ndn::Name> newNames = nlsa.getNpl().getNames();
249 std::list<ndn::Name> oldNames = chkNameLsa->getNpl().getNames();
250 std::list<ndn::Name> namesToAdd;
251 std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
252 std::inserter(namesToAdd, namesToAdd.begin()));
253 for (std::list<ndn::Name>::iterator it = namesToAdd.begin();
254 it != namesToAdd.end(); ++it) {
akmhoqueb6450b12014-04-24 00:01:03 -0500255 chkNameLsa->addName((*it));
akmhoque157b0a42014-05-13 00:26:37 -0500256 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
257 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500258 m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500259 }
260 }
261 }
Vince Lehmanf1aa5232014-10-06 17:57:35 -0500262
263 chkNameLsa->getNpl().sort();
264
Nick G97e34942016-07-11 14:46:27 -0500265 // Also remove any names that are no longer being advertised.
Nick Gordonf14ec352017-07-24 16:09:58 -0500266 std::list<ndn::Name> namesToRemove;
267 std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
268 std::inserter(namesToRemove, namesToRemove.begin()));
269 for (std::list<ndn::Name>::iterator it = namesToRemove.begin();
270 it != namesToRemove.end(); ++it) {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600271 _LOG_DEBUG("Removing name LSA no longer advertised: " << (*it).toUri());
akmhoqueb6450b12014-04-24 00:01:03 -0500272 chkNameLsa->removeName((*it));
akmhoque157b0a42014-05-13 00:26:37 -0500273 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
274 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500275 m_nlsr.getNamePrefixTable().removeEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500276 }
277 }
278 }
dmcoomes9eaf3f42017-02-21 11:39:01 -0600279
akmhoque157b0a42014-05-13 00:26:37 -0500280 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500281 ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
282 ndn::time::system_clock::now();
283 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500284 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500285 cancelScheduleLsaExpiringEvent(chkNameLsa->getExpiringEventId());
286 chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500287 nlsa.getLsSeqNo(),
288 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500289 _LOG_DEBUG("Adding Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500290 chkNameLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500291 }
292 }
293 return true;
294}
295
296bool
297Lsdb::addNameLsa(NameLsa& nlsa)
298{
299 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
300 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600301 std::bind(nameLsaCompareByKey, _1,
akmhoque53353462014-04-22 08:43:45 -0500302 nlsa.getKey()));
akmhoque157b0a42014-05-13 00:26:37 -0500303 if (it == m_nameLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500304 m_nameLsdb.push_back(nlsa);
305 return true;
306 }
307 return false;
308}
309
310bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500311Lsdb::removeNameLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500312{
313 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
314 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600315 std::bind(nameLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500316 if (it != m_nameLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500317 _LOG_DEBUG("Deleting Name Lsa");
akmhoque53353462014-04-22 08:43:45 -0500318 (*it).writeLog();
Nick G97e34942016-07-11 14:46:27 -0500319 // If the requested name LSA is not ours, we also need to remove
320 // its entries from the NPT.
akmhoque31d1d4b2014-05-05 22:08:14 -0500321 if ((*it).getOrigRouter() !=
akmhoque157b0a42014-05-13 00:26:37 -0500322 m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500323 m_nlsr.getNamePrefixTable().removeEntry((*it).getOrigRouter(),
324 (*it).getOrigRouter());
Nick Gordonf14ec352017-07-24 16:09:58 -0500325 for (const auto& name : it->getNpl().getNames()) {
326 if (name != m_nlsr.getConfParameter().getRouterPrefix()) {
327 m_nlsr.getNamePrefixTable().removeEntry(name, it->getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500328 }
329 }
330 }
331 m_nameLsdb.erase(it);
332 return true;
333 }
334 return false;
335}
336
337bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500338Lsdb::doesNameLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500339{
340 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
341 m_nameLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600342 std::bind(nameLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500343 if (it == m_nameLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500344 return false;
345 }
346 return true;
347}
348
349void
akmhoque2f423352014-06-03 11:49:35 -0500350Lsdb::writeNameLsdbLog()
akmhoque53353462014-04-22 08:43:45 -0500351{
akmhoque2f423352014-06-03 11:49:35 -0500352 _LOG_DEBUG("---------------Name LSDB-------------------");
akmhoque53353462014-04-22 08:43:45 -0500353 for (std::list<NameLsa>::iterator it = m_nameLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500354 it != m_nameLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -0500355 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -0500356 }
357}
358
Jiewen Tana0497d82015-02-02 21:59:18 -0800359const std::list<NameLsa>&
360Lsdb::getNameLsdb()
361{
362 return m_nameLsdb;
363}
364
akmhoque53353462014-04-22 08:43:45 -0500365// Cor LSA and LSDB related Functions start here
366
Nick G97e34942016-07-11 14:46:27 -0500367/*! \brief Compares whether an LSA object is the same as a key.
368 \param clsa The cor. LSA to check the identity of.
369 \param key The key of the publishing router to check against.
370*/
akmhoque53353462014-04-22 08:43:45 -0500371static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500372corLsaCompareByKey(const CoordinateLsa& clsa, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500373{
374 return clsa.getKey() == key;
375}
376
377bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500378Lsdb::buildAndInstallOwnCoordinateLsa()
akmhoque53353462014-04-22 08:43:45 -0500379{
akmhoque31d1d4b2014-05-05 22:08:14 -0500380 CoordinateLsa corLsa(m_nlsr.getConfParameter().getRouterPrefix(),
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500381 m_sequencingManager.getCorLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500382 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500383 m_nlsr.getConfParameter().getCorR(),
384 m_nlsr.getConfParameter().getCorTheta());
Nick Gordon5c467f02016-07-13 13:40:10 -0500385
386 // Sync coordinate LSAs if using HR or HR dry run.
387 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500388 m_sequencingManager.increaseCorLsaSeq();
389 m_sequencingManager.writeSeqNoToFile();
390 m_sync.publishRoutingUpdate(CoordinateLsa::TYPE_STRING, m_sequencingManager.getCorLsaSeq());
Nick Gordon5c467f02016-07-13 13:40:10 -0500391 }
392
akmhoque31d1d4b2014-05-05 22:08:14 -0500393 installCoordinateLsa(corLsa);
Nick Gordon5c467f02016-07-13 13:40:10 -0500394
akmhoque53353462014-04-22 08:43:45 -0500395 return true;
396}
397
akmhoqueb6450b12014-04-24 00:01:03 -0500398CoordinateLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500399Lsdb::findCoordinateLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500400{
akmhoqueb6450b12014-04-24 00:01:03 -0500401 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
402 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600403 std::bind(corLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500404 if (it != m_corLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500405 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500406 }
akmhoqueb6450b12014-04-24 00:01:03 -0500407 return 0;
akmhoque53353462014-04-22 08:43:45 -0500408}
409
410bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500411Lsdb::isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500412{
akmhoqueb6450b12014-04-24 00:01:03 -0500413 CoordinateLsa* clsa = findCoordinateLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500414 // Is the coordinate LSA in the LSDB already
akmhoque157b0a42014-05-13 00:26:37 -0500415 if (clsa != 0) {
Nick G97e34942016-07-11 14:46:27 -0500416 // And the seq no is newer (higher) than the current one
akmhoque157b0a42014-05-13 00:26:37 -0500417 if (clsa->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500418 return true;
419 }
akmhoque157b0a42014-05-13 00:26:37 -0500420 else {
akmhoque53353462014-04-22 08:43:45 -0500421 return false;
422 }
423 }
424 return true;
425}
426
Nick G97e34942016-07-11 14:46:27 -0500427 // Schedules a refresh/expire event in the scheduler.
428 // \param key The name of the router that published the LSA.
429 // \param seqNo the seq. no. associated with the LSA to check.
430 // \param expTime How long to wait before triggering the event.
akmhoque53353462014-04-22 08:43:45 -0500431ndn::EventId
akmhoque31d1d4b2014-05-05 22:08:14 -0500432Lsdb::scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
akmhoquec7a79b22014-05-26 08:06:19 -0500433 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500434{
Vince Lehman7c603292014-09-11 17:48:16 -0500435 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500436 std::bind(&Lsdb::expireOrRefreshCoordinateLsa,
Vince Lehman7c603292014-09-11 17:48:16 -0500437 this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500438}
439
440bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500441Lsdb::installCoordinateLsa(CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500442{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700443 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500444 CoordinateLsa* chkCorLsa = findCoordinateLsa(clsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500445 // Checking whether the LSA is new or not.
akmhoque157b0a42014-05-13 00:26:37 -0500446 if (chkCorLsa == 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500447 _LOG_DEBUG("New Coordinate LSA. Adding to LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500448 _LOG_DEBUG("Adding Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500449 clsa.writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500450 addCoordinateLsa(clsa);
akmhoque2f423352014-06-03 11:49:35 -0500451
Nick Gordon5c467f02016-07-13 13:40:10 -0500452 // Register the LSA's origin router prefix
akmhoque157b0a42014-05-13 00:26:37 -0500453 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500454 m_nlsr.getNamePrefixTable().addEntry(clsa.getOrigRouter(),
455 clsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500456 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500457 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500458 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500459 }
Nick G97e34942016-07-11 14:46:27 -0500460 // Set the expiration time for the new LSA.
akmhoque157b0a42014-05-13 00:26:37 -0500461 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500462 ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
463 ndn::time::system_clock::now();
464 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500465 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500466 scheduleCoordinateLsaExpiration(clsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500467 clsa.getLsSeqNo(), timeToExpire);
akmhoque53353462014-04-22 08:43:45 -0500468 }
Nick G97e34942016-07-11 14:46:27 -0500469 // We are just updating this LSA.
akmhoque157b0a42014-05-13 00:26:37 -0500470 else {
471 if (chkCorLsa->getLsSeqNo() < clsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500472 _LOG_DEBUG("Updated Coordinate LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500473 _LOG_DEBUG("Deleting Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500474 chkCorLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500475 chkCorLsa->setLsSeqNo(clsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500476 chkCorLsa->setExpirationTimePoint(clsa.getExpirationTimePoint());
Nick G97e34942016-07-11 14:46:27 -0500477 // If the new LSA contains new routing information, update the LSDB with it.
akmhoque157b0a42014-05-13 00:26:37 -0500478 if (!chkCorLsa->isEqualContent(clsa)) {
akmhoqueb6450b12014-04-24 00:01:03 -0500479 chkCorLsa->setCorRadius(clsa.getCorRadius());
480 chkCorLsa->setCorTheta(clsa.getCorTheta());
akmhoque157b0a42014-05-13 00:26:37 -0500481 if (m_nlsr.getConfParameter().getHyperbolicState() >= HYPERBOLIC_STATE_ON) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500482 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500483 }
484 }
Nick G97e34942016-07-11 14:46:27 -0500485 // If this is an LSA from another router, refresh its expiration time.
akmhoque157b0a42014-05-13 00:26:37 -0500486 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500487 ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
488 ndn::time::system_clock::now();
489 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500490 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500491 cancelScheduleLsaExpiringEvent(chkCorLsa->getExpiringEventId());
492 chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(clsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500493 clsa.getLsSeqNo(),
494 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500495 _LOG_DEBUG("Adding Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500496 chkCorLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500497 }
498 }
499 return true;
500}
501
502bool
akmhoqueb6450b12014-04-24 00:01:03 -0500503Lsdb::addCoordinateLsa(CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500504{
akmhoqueb6450b12014-04-24 00:01:03 -0500505 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
506 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600507 std::bind(corLsaCompareByKey, _1,
akmhoque157b0a42014-05-13 00:26:37 -0500508 clsa.getKey()));
509 if (it == m_corLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500510 m_corLsdb.push_back(clsa);
511 return true;
512 }
513 return false;
514}
515
516bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500517Lsdb::removeCoordinateLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500518{
akmhoqueb6450b12014-04-24 00:01:03 -0500519 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
520 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600521 std::bind(corLsaCompareByKey,
akmhoque157b0a42014-05-13 00:26:37 -0500522 _1, key));
523 if (it != m_corLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500524 _LOG_DEBUG("Deleting Coordinate Lsa");
Nick Gordon5c467f02016-07-13 13:40:10 -0500525 it->writeLog();
526
527 if (it->getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
528 m_nlsr.getNamePrefixTable().removeEntry(it->getOrigRouter(), it->getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500529 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500530
akmhoque53353462014-04-22 08:43:45 -0500531 m_corLsdb.erase(it);
532 return true;
533 }
534 return false;
535}
536
537bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500538Lsdb::doesCoordinateLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500539{
akmhoqueb6450b12014-04-24 00:01:03 -0500540 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
541 m_corLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600542 std::bind(corLsaCompareByKey,
akmhoque157b0a42014-05-13 00:26:37 -0500543 _1, key));
544 if (it == m_corLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500545 return false;
546 }
547 return true;
548}
549
550void
akmhoque2f423352014-06-03 11:49:35 -0500551Lsdb::writeCorLsdbLog()
akmhoque53353462014-04-22 08:43:45 -0500552{
akmhoque2f423352014-06-03 11:49:35 -0500553 _LOG_DEBUG("---------------Cor LSDB-------------------");
akmhoqueb6450b12014-04-24 00:01:03 -0500554 for (std::list<CoordinateLsa>::iterator it = m_corLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500555 it != m_corLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -0500556 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -0500557 }
558}
559
Jiewen Tana0497d82015-02-02 21:59:18 -0800560const std::list<CoordinateLsa>&
561Lsdb::getCoordinateLsdb()
562{
563 return m_corLsdb;
564}
565
akmhoque53353462014-04-22 08:43:45 -0500566// Adj LSA and LSDB related function starts here
567
Nick G97e34942016-07-11 14:46:27 -0500568 /*! \brief Returns whether an adj. LSA object is from some router.
569 \param alsa The adj. LSA object.
570 \param key The router name that you want to compare the LSA with.
571 */
akmhoque53353462014-04-22 08:43:45 -0500572static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500573adjLsaCompareByKey(AdjLsa& alsa, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500574{
575 return alsa.getKey() == key;
576}
577
akmhoque53353462014-04-22 08:43:45 -0500578void
Vince Lehman50df6b72015-03-03 12:06:40 -0600579Lsdb::scheduleAdjLsaBuild()
akmhoque53353462014-04-22 08:43:45 -0500580{
Vince Lehman50df6b72015-03-03 12:06:40 -0600581 m_nlsr.incrementAdjBuildCount();
582
Nick Gordon5c467f02016-07-13 13:40:10 -0500583 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
584 // Don't build adjacency LSAs in hyperbolic routing
dmcoomes9eaf3f42017-02-21 11:39:01 -0600585 _LOG_DEBUG("Adjacency LSA not built. Currently in hyperbolic routing state.");
Nick Gordon5c467f02016-07-13 13:40:10 -0500586 return;
587 }
588
Vince Lehman50df6b72015-03-03 12:06:40 -0600589 if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
590 _LOG_DEBUG("Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
591
dmcoomes9f936662017-03-02 10:33:09 -0600592 m_scheduler.scheduleEvent(m_adjLsaBuildInterval, std::bind(&Lsdb::buildAdjLsa, this));
Vince Lehman50df6b72015-03-03 12:06:40 -0600593 m_nlsr.setIsBuildAdjLsaSheduled(true);
594 }
595}
596
597void
598Lsdb::buildAdjLsa()
599{
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500600 _LOG_TRACE("Lsdb::buildAdjLsa called");
Vince Lehman50df6b72015-03-03 12:06:40 -0600601
akmhoque674b0b12014-05-20 14:33:28 -0500602 m_nlsr.setIsBuildAdjLsaSheduled(false);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500603
604 if (m_nlsr.getAdjacencyList().isAdjLsaBuildable(m_nlsr.getConfParameter().getInterestRetryNumber())) {
605
akmhoque31d1d4b2014-05-05 22:08:14 -0500606 int adjBuildCount = m_nlsr.getAdjBuildCount();
Nick G97e34942016-07-11 14:46:27 -0500607 // Only do the adjLsa build if there's one scheduled
akmhoque157b0a42014-05-13 00:26:37 -0500608 if (adjBuildCount > 0) {
Nick G97e34942016-07-11 14:46:27 -0500609 // It only makes sense to do the adjLsa build if we have neighbors
akmhoque157b0a42014-05-13 00:26:37 -0500610 if (m_nlsr.getAdjacencyList().getNumOfActiveNeighbor() > 0) {
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500611 _LOG_DEBUG("Building and installing own Adj LSA");
akmhoque31d1d4b2014-05-05 22:08:14 -0500612 buildAndInstallOwnAdjLsa();
akmhoque53353462014-04-22 08:43:45 -0500613 }
Nick G97e34942016-07-11 14:46:27 -0500614 // We have no active neighbors, meaning no one can route through
615 // us. So delete our entry in the LSDB. This prevents this
616 // router from refreshing the LSA, eventually causing other
617 // routers to delete it, too.
akmhoque157b0a42014-05-13 00:26:37 -0500618 else {
dmcoomes9f936662017-03-02 10:33:09 -0600619 _LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors");
Nick G97e34942016-07-11 14:46:27 -0500620 // Get this router's key
akmhoque31d1d4b2014-05-05 22:08:14 -0500621 ndn::Name key = m_nlsr.getConfParameter().getRouterPrefix();
alvy49b1c0c2014-12-19 13:57:46 -0600622 key.append(AdjLsa::TYPE_STRING);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500623
akmhoque31d1d4b2014-05-05 22:08:14 -0500624 removeAdjLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500625 // Recompute routing table after removal
akmhoque31d1d4b2014-05-05 22:08:14 -0500626 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500627 }
Nick G97e34942016-07-11 14:46:27 -0500628 // In the case that during building the adj LSA, the FIB has to
629 // wait on an Interest response, the number of scheduled adj LSA
630 // builds could change, so we shouldn't just set it to 0.
akmhoque31d1d4b2014-05-05 22:08:14 -0500631 m_nlsr.setAdjBuildCount(m_nlsr.getAdjBuildCount() - adjBuildCount);
akmhoque53353462014-04-22 08:43:45 -0500632 }
633 }
Nick G97e34942016-07-11 14:46:27 -0500634 // We are still waiting to know the adjacency status of some
635 // neighbor, so schedule a build for later (when all that has
636 // hopefully finished)
637 else {
638 m_nlsr.setIsBuildAdjLsaSheduled(true);
639 int schedulingTime = m_nlsr.getConfParameter().getInterestRetryNumber() *
640 m_nlsr.getConfParameter().getInterestResendTime();
641 m_scheduler.scheduleEvent(ndn::time::seconds(schedulingTime),
dmcoomes9f936662017-03-02 10:33:09 -0600642 std::bind(&Lsdb::buildAdjLsa, this));
Nick G97e34942016-07-11 14:46:27 -0500643 }
akmhoque53353462014-04-22 08:43:45 -0500644}
645
akmhoque53353462014-04-22 08:43:45 -0500646bool
647Lsdb::addAdjLsa(AdjLsa& alsa)
648{
649 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
650 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600651 std::bind(adjLsaCompareByKey, _1,
akmhoque53353462014-04-22 08:43:45 -0500652 alsa.getKey()));
akmhoque157b0a42014-05-13 00:26:37 -0500653 if (it == m_adjLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500654 m_adjLsdb.push_back(alsa);
655 return true;
656 }
657 return false;
658}
659
akmhoqueb6450b12014-04-24 00:01:03 -0500660AdjLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500661Lsdb::findAdjLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500662{
663 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
664 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600665 std::bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500666 if (it != m_adjLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500667 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500668 }
akmhoqueb6450b12014-04-24 00:01:03 -0500669 return 0;
akmhoque53353462014-04-22 08:43:45 -0500670}
671
akmhoque53353462014-04-22 08:43:45 -0500672bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500673Lsdb::isAdjLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500674{
akmhoqueb6450b12014-04-24 00:01:03 -0500675 AdjLsa* adjLsaCheck = findAdjLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500676 // If it is in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500677 if (adjLsaCheck != 0) {
Nick G97e34942016-07-11 14:46:27 -0500678 // And the supplied seq no is newer (higher) than the current one.
akmhoque157b0a42014-05-13 00:26:37 -0500679 if (adjLsaCheck->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500680 return true;
681 }
akmhoque157b0a42014-05-13 00:26:37 -0500682 else {
akmhoque53353462014-04-22 08:43:45 -0500683 return false;
684 }
685 }
686 return true;
687}
688
akmhoque53353462014-04-22 08:43:45 -0500689ndn::EventId
akmhoquec7a79b22014-05-26 08:06:19 -0500690Lsdb::scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
691 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500692{
Vince Lehman7c603292014-09-11 17:48:16 -0500693 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500694 std::bind(&Lsdb::expireOrRefreshAdjLsa, this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500695}
696
697bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500698Lsdb::installAdjLsa(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500699{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700700 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500701 AdjLsa* chkAdjLsa = findAdjLsa(alsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500702 // If this adj. LSA is not in the LSDB already
akmhoque157b0a42014-05-13 00:26:37 -0500703 if (chkAdjLsa == 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500704 _LOG_DEBUG("New Adj LSA. Adding to LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500705 _LOG_DEBUG("Adding Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500706 alsa.writeLog();
akmhoque53353462014-04-22 08:43:45 -0500707 addAdjLsa(alsa);
Nick G97e34942016-07-11 14:46:27 -0500708 // Add any new name prefixes to the NPT
akmhoque31d1d4b2014-05-05 22:08:14 -0500709 alsa.addNptEntries(m_nlsr);
710 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque157b0a42014-05-13 00:26:37 -0500711 if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500712 ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
713 ndn::time::system_clock::now();
714 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500715 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500716 scheduleAdjLsaExpiration(alsa.getKey(),
akmhoque53353462014-04-22 08:43:45 -0500717 alsa.getLsSeqNo(), timeToExpire);
718 }
akmhoque157b0a42014-05-13 00:26:37 -0500719 else {
720 if (chkAdjLsa->getLsSeqNo() < alsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500721 _LOG_DEBUG("Updated Adj LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500722 _LOG_DEBUG("Deleting Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500723 chkAdjLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500724 chkAdjLsa->setLsSeqNo(alsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500725 chkAdjLsa->setExpirationTimePoint(alsa.getExpirationTimePoint());
Nick G97e34942016-07-11 14:46:27 -0500726 // If the new adj LSA has new content, update the contents of
727 // the LSDB entry. Additionally, since we've changed the
728 // contents of the LSDB, we have to schedule a routing
729 // calculation.
akmhoque157b0a42014-05-13 00:26:37 -0500730 if (!chkAdjLsa->isEqualContent(alsa)) {
akmhoqueb6450b12014-04-24 00:01:03 -0500731 chkAdjLsa->getAdl().reset();
akmhoquefdbddb12014-05-02 18:35:19 -0500732 chkAdjLsa->getAdl().addAdjacents(alsa.getAdl());
akmhoque31d1d4b2014-05-05 22:08:14 -0500733 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500734 }
akmhoque157b0a42014-05-13 00:26:37 -0500735 if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500736 ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
737 ndn::time::system_clock::now();
738 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500739 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500740 cancelScheduleLsaExpiringEvent(chkAdjLsa->getExpiringEventId());
741 chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(alsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500742 alsa.getLsSeqNo(),
743 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500744 _LOG_DEBUG("Adding Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500745 chkAdjLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500746 }
747 }
748 return true;
749}
750
751bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500752Lsdb::buildAndInstallOwnAdjLsa()
akmhoque53353462014-04-22 08:43:45 -0500753{
akmhoque31d1d4b2014-05-05 22:08:14 -0500754 AdjLsa adjLsa(m_nlsr.getConfParameter().getRouterPrefix(),
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500755 m_sequencingManager.getAdjLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500756 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500757 m_nlsr.getAdjacencyList().getNumOfActiveNeighbor(),
758 m_nlsr.getAdjacencyList());
Vince Lehman904c2412014-09-23 19:36:11 -0500759
Nick Gordon5c467f02016-07-13 13:40:10 -0500760 //Sync adjacency LSAs if link-state or dry-run HR is enabled.
761 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_ON) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500762 m_sequencingManager.increaseAdjLsaSeq();
763 m_sequencingManager.writeSeqNoToFile();
764 m_sync.publishRoutingUpdate(AdjLsa::TYPE_STRING, m_sequencingManager.getAdjLsaSeq());
Nick Gordon5c467f02016-07-13 13:40:10 -0500765 }
Vince Lehman904c2412014-09-23 19:36:11 -0500766
Vince Lehman9d097802015-03-16 17:55:59 -0500767 return installAdjLsa(adjLsa);
akmhoque53353462014-04-22 08:43:45 -0500768}
769
770bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500771Lsdb::removeAdjLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500772{
773 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
774 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600775 std::bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500776 if (it != m_adjLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500777 _LOG_DEBUG("Deleting Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500778 (*it).writeLog();
akmhoque31d1d4b2014-05-05 22:08:14 -0500779 (*it).removeNptEntries(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500780 m_adjLsdb.erase(it);
781 return true;
782 }
783 return false;
784}
785
786bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500787Lsdb::doesAdjLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500788{
789 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
790 m_adjLsdb.end(),
dmcoomes9f936662017-03-02 10:33:09 -0600791 std::bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500792 if (it == m_adjLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500793 return false;
794 }
795 return true;
796}
797
Jiewen Tana0497d82015-02-02 21:59:18 -0800798const std::list<AdjLsa>&
akmhoque53353462014-04-22 08:43:45 -0500799Lsdb::getAdjLsdb()
800{
801 return m_adjLsdb;
802}
803
804void
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700805Lsdb::setLsaRefreshTime(const seconds& lsaRefreshTime)
akmhoque53353462014-04-22 08:43:45 -0500806{
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700807 m_lsaRefreshTime = lsaRefreshTime;
akmhoque53353462014-04-22 08:43:45 -0500808}
809
810void
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500811Lsdb::setThisRouterPrefix(std::string trp)
akmhoque53353462014-04-22 08:43:45 -0500812{
813 m_thisRouterPrefix = trp;
814}
815
Nick G97e34942016-07-11 14:46:27 -0500816 // This function determines whether a name LSA should be refreshed
817 // or expired. The conditions for getting refreshed are: it is still
818 // in the LSDB, it hasn't been updated by something else already (as
819 // evidenced by its seq. no.), and this is the originating router for
820 // the LSA. Is it let expire in all other cases.
821 // lsaKey is the key of the LSA's publishing router.
822 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500823void
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500824Lsdb::expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500825{
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500826 _LOG_DEBUG("Lsdb::expireOrRefreshNameLsa Called");
akmhoque674b0b12014-05-20 14:33:28 -0500827 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500828 NameLsa* chkNameLsa = findNameLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500829 // If this name LSA exists in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500830 if (chkNameLsa != 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500831 _LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500832 // If its seq no is the one we are expecting.
akmhoque157b0a42014-05-13 00:26:37 -0500833 if (chkNameLsa->getLsSeqNo() == seqNo) {
834 if (chkNameLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500835 _LOG_DEBUG("Own Name LSA, so refreshing it");
836 _LOG_DEBUG("Deleting Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500837 chkNameLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500838 chkNameLsa->setLsSeqNo(chkNameLsa->getLsSeqNo() + 1);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500839 m_sequencingManager.setNameLsaSeq(chkNameLsa->getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500840 chkNameLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500841 _LOG_DEBUG("Adding Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500842 chkNameLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500843 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500844 chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(chkNameLsa->getKey(),
akmhoquefdbddb12014-05-02 18:35:19 -0500845 chkNameLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700846 m_lsaRefreshTime));
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500847 m_sequencingManager.writeSeqNoToFile();
848 m_sync.publishRoutingUpdate(NameLsa::TYPE_STRING, m_sequencingManager.getNameLsaSeq());
akmhoque53353462014-04-22 08:43:45 -0500849 }
Nick G97e34942016-07-11 14:46:27 -0500850 // Since we cannot refresh other router's LSAs, our only choice is to expire.
akmhoque157b0a42014-05-13 00:26:37 -0500851 else {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600852 _LOG_DEBUG("Other's Name LSA, so removing from LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500853 removeNameLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500854 }
855 }
856 }
857}
858
Nick G97e34942016-07-11 14:46:27 -0500859 // This function determines whether an adj. LSA should be refreshed
860 // or expired. The conditions for getting refreshed are: it is still
861 // in the LSDB, it hasn't been updated by something else already (as
862 // evidenced by its seq. no.), and this is the originating router for
863 // the LSA. Is it let expire in all other cases.
864 // lsaKey is the key of the LSA's publishing router.
865 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500866void
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500867Lsdb::expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500868{
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500869 _LOG_DEBUG("Lsdb::expireOrRefreshAdjLsa Called");
dmcoomes9eaf3f42017-02-21 11:39:01 -0600870 _LOG_DEBUG("LSA Key: " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500871 AdjLsa* chkAdjLsa = findAdjLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500872 // If this is a valid LSA
akmhoque157b0a42014-05-13 00:26:37 -0500873 if (chkAdjLsa != 0) {
akmhoque2f423352014-06-03 11:49:35 -0500874 _LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500875 // And if it hasn't been updated for some other reason
akmhoque157b0a42014-05-13 00:26:37 -0500876 if (chkAdjLsa->getLsSeqNo() == seqNo) {
Nick G97e34942016-07-11 14:46:27 -0500877 // If it is our own LSA
akmhoque157b0a42014-05-13 00:26:37 -0500878 if (chkAdjLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500879 _LOG_DEBUG("Own Adj LSA, so refreshing it");
880 _LOG_DEBUG("Deleting Adj Lsa");
881 chkAdjLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500882 chkAdjLsa->setLsSeqNo(chkAdjLsa->getLsSeqNo() + 1);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500883 m_sequencingManager.setAdjLsaSeq(chkAdjLsa->getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500884 chkAdjLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500885 _LOG_DEBUG("Adding Adj Lsa");
886 chkAdjLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500887 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500888 chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(chkAdjLsa->getKey(),
akmhoquefdbddb12014-05-02 18:35:19 -0500889 chkAdjLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700890 m_lsaRefreshTime));
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500891 m_sequencingManager.writeSeqNoToFile();
892 m_sync.publishRoutingUpdate(AdjLsa::TYPE_STRING, m_sequencingManager.getAdjLsaSeq());
akmhoque53353462014-04-22 08:43:45 -0500893 }
Nick G97e34942016-07-11 14:46:27 -0500894 // An LSA from another router is expiring
akmhoque157b0a42014-05-13 00:26:37 -0500895 else {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600896 _LOG_DEBUG("Other's Adj LSA, so removing from LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500897 removeAdjLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500898 }
Nick G97e34942016-07-11 14:46:27 -0500899 // We have changed the contents of the LSDB, so we have to
900 // schedule a routing calculation
akmhoque31d1d4b2014-05-05 22:08:14 -0500901 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500902 }
903 }
904}
905
Nick G97e34942016-07-11 14:46:27 -0500906 // This function determines whether an adj. LSA should be refreshed
907 // or expired. The conditions for getting refreshed are: it is still
908 // in the LSDB, it hasn't been updated by something else already (as
909 // evidenced by its seq. no.), and this is the originating router for
910 // the LSA. It is let expire in all other cases.
911 // lsaKey is the key of the LSA's publishing router.
912 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500913void
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500914Lsdb::expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
akmhoqueb6450b12014-04-24 00:01:03 -0500915 uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500916{
Ashlesh Gawande90173ad2017-08-09 15:19:50 -0500917 _LOG_DEBUG("Lsdb::expireOrRefreshCorLsa Called ");
akmhoque674b0b12014-05-20 14:33:28 -0500918 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500919 CoordinateLsa* chkCorLsa = findCoordinateLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500920 // Whether the LSA is in the LSDB or not.
akmhoque157b0a42014-05-13 00:26:37 -0500921 if (chkCorLsa != 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500922 _LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500923 // Whether the LSA has been updated without our knowledge.
akmhoque157b0a42014-05-13 00:26:37 -0500924 if (chkCorLsa->getLsSeqNo() == seqNo) {
925 if (chkCorLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500926 _LOG_DEBUG("Own Cor LSA, so refreshing it");
927 _LOG_DEBUG("Deleting Coordinate Lsa");
928 chkCorLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500929 chkCorLsa->setLsSeqNo(chkCorLsa->getLsSeqNo() + 1);
Nick Gordon5c467f02016-07-13 13:40:10 -0500930 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500931 m_sequencingManager.setCorLsaSeq(chkCorLsa->getLsSeqNo());
Nick Gordon5c467f02016-07-13 13:40:10 -0500932 }
933
akmhoquec7a79b22014-05-26 08:06:19 -0500934 chkCorLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500935 _LOG_DEBUG("Adding Coordinate Lsa");
936 chkCorLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500937 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500938 chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(
939 chkCorLsa->getKey(),
940 chkCorLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700941 m_lsaRefreshTime));
Nick Gordon5c467f02016-07-13 13:40:10 -0500942 // Only sync coordinate LSAs if link-state routing is disabled
943 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500944 m_sequencingManager.writeSeqNoToFile();
945 m_sync.publishRoutingUpdate(CoordinateLsa::TYPE_STRING, m_sequencingManager.getCorLsaSeq());
Nick Gordon5c467f02016-07-13 13:40:10 -0500946 }
akmhoque53353462014-04-22 08:43:45 -0500947 }
Nick G97e34942016-07-11 14:46:27 -0500948 // We can't refresh other router's LSAs, so we remove it.
akmhoque157b0a42014-05-13 00:26:37 -0500949 else {
dmcoomes9eaf3f42017-02-21 11:39:01 -0600950 _LOG_DEBUG("Other's Cor LSA, so removing from LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500951 removeCoordinateLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500952 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500953 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500954 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500955 }
956 }
957 }
958}
959
akmhoque53353462014-04-22 08:43:45 -0500960void
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700961Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500962 steady_clock::TimePoint deadline)
akmhoque31d1d4b2014-05-05 22:08:14 -0500963{
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500964 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
965 deadline = steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700966 }
Nick G97e34942016-07-11 14:46:27 -0500967 // The first component of the interest is the name.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500968 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
Nick G97e34942016-07-11 14:46:27 -0500969 // The seq no is the last
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500970 uint64_t seqNo = interestName[-1].toNumber();
971
Nick G97e34942016-07-11 14:46:27 -0500972 // If the LSA is not found in the list currently.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500973 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
974 m_highestSeqNo[lsaName] = seqNo;
975 }
Nick G97e34942016-07-11 14:46:27 -0500976 // If the new seq no is higher, that means the LSA is valid
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500977 else if (seqNo > m_highestSeqNo[lsaName]) {
978 m_highestSeqNo[lsaName] = seqNo;
979 }
Nick G97e34942016-07-11 14:46:27 -0500980 // Otherwise, its an old/invalid LSA
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500981 else if (seqNo < m_highestSeqNo[lsaName]) {
982 return;
983 }
984
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500985 ndn::Interest interest(interestName);
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700986 interest.setInterestLifetime(m_nlsr.getConfParameter().getLsaInterestLifetime());
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500987
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500988 _LOG_DEBUG("Fetching Data for LSA: " << interestName << " Seq number: " << seqNo);
989 ndn::util::SegmentFetcher::fetch(m_nlsr.getNlsrFace(), interest,
990 m_nlsr.getValidator(),
dmcoomes9f936662017-03-02 10:33:09 -0600991 std::bind(&Lsdb::afterFetchLsa, this, _1, interestName),
992 std::bind(&Lsdb::onFetchLsaError, this, _1, _2, interestName,
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500993 timeoutCount, deadline, lsaName, seqNo));
akmhoque31d1d4b2014-05-05 22:08:14 -0500994}
995
996void
997Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
998{
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500999 const ndn::Name& interestName(interest.getName());
1000 _LOG_DEBUG("Interest received for LSA: " << interestName);
1001
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001002 std::string chkString("LSA");
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001003 int32_t lsaPosition = util::getNameComponentPosition(interest.getName(), chkString);
1004
akmhoque157b0a42014-05-13 00:26:37 -05001005 if (lsaPosition >= 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001006
Nick G97e34942016-07-11 14:46:27 -05001007 // Forms the name of the router that the Interest packet came from.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001008 ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
1009 originRouter.append(interestName.getSubName(lsaPosition + 1,
1010 interest.getName().size() - lsaPosition - 3));
1011
1012 uint64_t seqNo = interestName[-1].toNumber();
1013 _LOG_DEBUG("LSA sequence number from interest: " << seqNo);
1014
1015 std::string interestedLsType = interestName[-2].toUri();
1016
Nick G97e34942016-07-11 14:46:27 -05001017 // Passes the Interest off to the appropriate subprocessor
alvy49b1c0c2014-12-19 13:57:46 -06001018 if (interestedLsType == NameLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001019 processInterestForNameLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001020 }
alvy49b1c0c2014-12-19 13:57:46 -06001021 else if (interestedLsType == AdjLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001022 processInterestForAdjacencyLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001023 }
alvy49b1c0c2014-12-19 13:57:46 -06001024 else if (interestedLsType == CoordinateLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001025 processInterestForCoordinateLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001026 }
akmhoque157b0a42014-05-13 00:26:37 -05001027 else {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001028 _LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
akmhoque31d1d4b2014-05-05 22:08:14 -05001029 }
1030 }
1031}
1032
Nick G97e34942016-07-11 14:46:27 -05001033 // \brief Sends LSA data.
1034 // \param interest The Interest that warranted the data.
1035 // \param content The data that the Interest was seeking.
akmhoque31d1d4b2014-05-05 22:08:14 -05001036void
akmhoque69c9aa92014-07-23 15:15:05 -05001037Lsdb::putLsaData(const ndn::Interest& interest, const std::string& content)
1038{
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001039 LsaContentPublisher publisher(m_nlsr.getNlsrFace(),
1040 m_nlsr.getKeyChain(),
1041 m_lsaRefreshTime,
1042 content);
dmcoomes9eaf3f42017-02-21 11:39:01 -06001043 _LOG_DEBUG("Sending requested data ( " << content << ") for interest (" << interest
1044 << ") to be published and added to face.");
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001045 publisher.publish(interest.getName(),
1046 ndn::security::signingByCertificate(m_nlsr.getDefaultCertName()));
akmhoque69c9aa92014-07-23 15:15:05 -05001047}
1048
Nick G97e34942016-07-11 14:46:27 -05001049 // \brief Finds and sends a requested name LSA.
1050 // \param interest The interest that seeks the name LSA.
1051 // \param lsaKey The LSA that the Interest is seeking.
1052 // \param seqNo A sequence number to ensure that we are sending the
1053 // version that was requested.
akmhoque69c9aa92014-07-23 15:15:05 -05001054void
akmhoque31d1d4b2014-05-05 22:08:14 -05001055Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
1056 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001057 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001058{
dmcoomes9eaf3f42017-02-21 11:39:01 -06001059
1060 _LOG_DEBUG("nameLsa interest " << interest << " received");
akmhoque31d1d4b2014-05-05 22:08:14 -05001061 NameLsa* nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001062 if (nameLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001063 if (nameLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001064 std::string content = nameLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001065 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001066 }
dmcoomes9eaf3f42017-02-21 11:39:01 -06001067 else {
1068 _LOG_TRACE("SeqNo for nameLsa does not match");
1069 }
1070 }
1071 else {
1072 _LOG_TRACE(interest << " was not found in this lsdb");
akmhoque31d1d4b2014-05-05 22:08:14 -05001073 }
1074}
1075
Nick G97e34942016-07-11 14:46:27 -05001076 // \brief Finds and sends a requested adj. LSA.
1077 // \param interest The interest that seeks the adj. LSA.
1078 // \param lsaKey The LSA that the Interest is seeking.
1079 // \param seqNo A sequence number to ensure that we are sending the
1080 // version that was requested.
akmhoque31d1d4b2014-05-05 22:08:14 -05001081void
1082Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
1083 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001084 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001085{
Nick Gordon5c467f02016-07-13 13:40:10 -05001086 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
dmcoomes9eaf3f42017-02-21 11:39:01 -06001087 _LOG_ERROR("Received interest for an adjacency LSA when hyperbolic routing is enabled");
Nick Gordon5c467f02016-07-13 13:40:10 -05001088 }
1089
dmcoomes9eaf3f42017-02-21 11:39:01 -06001090 _LOG_DEBUG("AdjLsa interest " << interest << " received");
akmhoque31d1d4b2014-05-05 22:08:14 -05001091 AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001092 if (adjLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001093 if (adjLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001094 std::string content = adjLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001095 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001096 }
dmcoomes9eaf3f42017-02-21 11:39:01 -06001097 else {
1098 _LOG_TRACE("SeqNo for AdjLsa does not match");
1099 }
1100 }
1101 else {
1102 _LOG_TRACE(interest << " was not found in this lsdb");
akmhoque31d1d4b2014-05-05 22:08:14 -05001103 }
1104}
1105
Nick G97e34942016-07-11 14:46:27 -05001106 // \brief Finds and sends a requested cor. LSA.
1107 // \param interest The interest that seeks the cor. LSA.
1108 // \param lsaKey The LSA that the Interest is seeking.
1109 // \param seqNo A sequence number to ensure that we are sending the
1110 // version that was requested.
akmhoque31d1d4b2014-05-05 22:08:14 -05001111void
1112Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
1113 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001114 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001115{
Nick Gordon5c467f02016-07-13 13:40:10 -05001116 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
dmcoomes9eaf3f42017-02-21 11:39:01 -06001117 _LOG_ERROR("Received Interest for a coordinate LSA when link-state routing is enabled");
Nick Gordon5c467f02016-07-13 13:40:10 -05001118 }
1119
dmcoomes9eaf3f42017-02-21 11:39:01 -06001120 _LOG_DEBUG("CoordinateLsa interest " << interest << " received");
akmhoque31d1d4b2014-05-05 22:08:14 -05001121 CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001122 if (corLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001123 if (corLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001124 std::string content = corLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001125 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001126 }
dmcoomes9eaf3f42017-02-21 11:39:01 -06001127 else {
1128 _LOG_TRACE("SeqNo for CoordinateLsa does not match");
1129 }
1130 }
1131 else {
1132 _LOG_TRACE(interest << " was not found in this lsdb");
akmhoque31d1d4b2014-05-05 22:08:14 -05001133 }
1134}
1135
1136void
dmcoomes9f936662017-03-02 10:33:09 -06001137Lsdb::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
Yingdi Yu20e3a6e2014-05-26 23:16:10 -07001138{
1139 const ndn::Name& dataName = data->getName();
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001140 _LOG_DEBUG("Data validation successful for LSA: " << dataName);
1141
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001142 std::string chkString("LSA");
akmhoque31d1d4b2014-05-05 22:08:14 -05001143 int32_t lsaPosition = util::getNameComponentPosition(dataName, chkString);
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001144
akmhoque157b0a42014-05-13 00:26:37 -05001145 if (lsaPosition >= 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001146
Nick G97e34942016-07-11 14:46:27 -05001147 // Extracts the prefix of the originating router from the data.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001148 ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001149 originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001150
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001151 uint64_t seqNo = dataName[-1].toNumber();
Ashlesh Gawande820bb662017-08-03 16:12:07 -05001152 std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()),
1153 data->getContent().value_size());
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001154
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001155 std::string interestedLsType = dataName[-2].toUri();
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001156
alvy49b1c0c2014-12-19 13:57:46 -06001157 if (interestedLsType == NameLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001158 processContentNameLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001159 }
alvy49b1c0c2014-12-19 13:57:46 -06001160 else if (interestedLsType == AdjLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001161 processContentAdjacencyLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001162 }
alvy49b1c0c2014-12-19 13:57:46 -06001163 else if (interestedLsType == CoordinateLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001164 processContentCoordinateLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001165 }
akmhoque157b0a42014-05-13 00:26:37 -05001166 else {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001167 _LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
akmhoque31d1d4b2014-05-05 22:08:14 -05001168 }
1169 }
1170}
1171
1172void
1173Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001174 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001175{
akmhoque157b0a42014-05-13 00:26:37 -05001176 if (isNameLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001177 NameLsa nameLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001178 if (nameLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001179 installNameLsa(nameLsa);
1180 }
akmhoque157b0a42014-05-13 00:26:37 -05001181 else {
akmhoque2f423352014-06-03 11:49:35 -05001182 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001183 }
1184 }
1185}
1186
1187void
1188Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001189 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001190{
akmhoque157b0a42014-05-13 00:26:37 -05001191 if (isAdjLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001192 AdjLsa adjLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001193 if (adjLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001194 installAdjLsa(adjLsa);
1195 }
akmhoque157b0a42014-05-13 00:26:37 -05001196 else {
akmhoque2f423352014-06-03 11:49:35 -05001197 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001198 }
1199 }
1200}
1201
1202void
1203Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001204 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001205{
akmhoque157b0a42014-05-13 00:26:37 -05001206 if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001207 CoordinateLsa corLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001208 if (corLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001209 installCoordinateLsa(corLsa);
1210 }
akmhoque157b0a42014-05-13 00:26:37 -05001211 else {
akmhoque2f423352014-06-03 11:49:35 -05001212 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001213 }
1214 }
1215}
1216
akmhoquec7a79b22014-05-26 08:06:19 -05001217ndn::time::system_clock::TimePoint
1218Lsdb::getLsaExpirationTimePoint()
1219{
1220 ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
1221 expirationTimePoint = expirationTimePoint +
1222 ndn::time::seconds(m_nlsr.getConfParameter().getRouterDeadInterval());
1223 return expirationTimePoint;
1224}
akmhoque31d1d4b2014-05-05 22:08:14 -05001225
1226void
akmhoque2f423352014-06-03 11:49:35 -05001227Lsdb::writeAdjLsdbLog()
akmhoque53353462014-04-22 08:43:45 -05001228{
akmhoque2f423352014-06-03 11:49:35 -05001229 _LOG_DEBUG("---------------Adj LSDB-------------------");
akmhoque53353462014-04-22 08:43:45 -05001230 for (std::list<AdjLsa>::iterator it = m_adjLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -05001231 it != m_adjLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -05001232 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -05001233 }
1234}
1235
1236//-----utility function -----
1237bool
akmhoque31d1d4b2014-05-05 22:08:14 -05001238Lsdb::doesLsaExist(const ndn::Name& key, const std::string& lsType)
akmhoque53353462014-04-22 08:43:45 -05001239{
alvy49b1c0c2014-12-19 13:57:46 -06001240 if (lsType == NameLsa::TYPE_STRING) {
akmhoque53353462014-04-22 08:43:45 -05001241 return doesNameLsaExist(key);
1242 }
alvy49b1c0c2014-12-19 13:57:46 -06001243 else if (lsType == AdjLsa::TYPE_STRING) {
akmhoque53353462014-04-22 08:43:45 -05001244 return doesAdjLsaExist(key);
1245 }
alvy49b1c0c2014-12-19 13:57:46 -06001246 else if (lsType == CoordinateLsa::TYPE_STRING) {
akmhoqueb6450b12014-04-24 00:01:03 -05001247 return doesCoordinateLsaExist(key);
akmhoque53353462014-04-22 08:43:45 -05001248 }
1249 return false;
1250}
1251
Alexander Afanasyev8388ec62014-08-16 18:38:57 -07001252} // namespace nlsr