blob: 162429e6b67ffe612b158f00eb76c41ce0ddab63 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05003 * Copyright (c) 2014-2016, 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
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -050066Lsdb::Lsdb(Nlsr& nlsr, ndn::Scheduler& scheduler, SyncLogicHandler& sync)
67 : m_nlsr(nlsr)
68 , m_scheduler(scheduler)
69 , m_sync(sync)
70 , m_lsaRefreshTime(0)
71 , m_adjLsaBuildInterval(ADJ_LSA_BUILD_INTERVAL_DEFAULT)
72{
73}
74
75void
76Lsdb::onFetchLsaError(uint32_t errorCode,
77 const std::string& msg,
78 ndn::Name& interestName,
79 uint32_t retransmitNo,
80 const ndn::time::steady_clock::TimePoint& deadline,
81 ndn::Name lsaName,
82 uint64_t seqNo)
83{
84 _LOG_DEBUG("Failed to fetch LSA: " << lsaName << ", Error code: " << errorCode
85 << ", Message: " << msg);
86
87 if (ndn::time::steady_clock::now() < deadline) {
88 SequenceNumberMap::const_iterator it = m_highestSeqNo.find(lsaName);
89
90 if (it != m_highestSeqNo.end() && it->second == seqNo) {
91 // If the SegmentFetcher failed due to an Interest timeout, it is safe to re-express
92 // immediately since at the least the LSA Interest lifetime has elapsed.
93 // Otherwise, it is necessary to delay the Interest re-expression to prevent
94 // the potential for constant Interest flooding.
95 ndn::time::seconds delay = m_nlsr.getConfParameter().getLsaInterestLifetime();
96
97 if (errorCode == ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
98 delay = ndn::time::seconds(0);
99 }
100
101 m_scheduler.scheduleEvent(delay, std::bind(&Lsdb::expressInterest, this,
102 interestName, retransmitNo + 1, deadline));
103 }
104 }
105}
106
107void
108Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, ndn::Name& interestName)
109{
110 shared_ptr<ndn::Data> data = make_shared<ndn::Data>(ndn::Name(interestName));
111 data->setContent(bufferPtr);
112
113 _LOG_DEBUG("Received data for LSA(name): " << data->getName());
114
115 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
116 uint64_t seqNo = interestName[-1].toNumber();
117
118 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
119 m_highestSeqNo[lsaName] = seqNo;
120 }
121 else if (seqNo > m_highestSeqNo[lsaName]) {
122 m_highestSeqNo[lsaName] = seqNo;
123 }
124 else if (seqNo < m_highestSeqNo[lsaName]) {
125 return;
126 }
127
128 onContentValidated(data);
129}
akmhoque53353462014-04-22 08:43:45 -0500130
131void
akmhoque31d1d4b2014-05-05 22:08:14 -0500132Lsdb::cancelScheduleLsaExpiringEvent(ndn::EventId eid)
akmhoque53353462014-04-22 08:43:45 -0500133{
Vince Lehman7c603292014-09-11 17:48:16 -0500134 m_scheduler.cancelEvent(eid);
akmhoque53353462014-04-22 08:43:45 -0500135}
136
Nick G97e34942016-07-11 14:46:27 -0500137 /*! \brief Compares if a name LSA is the same as the one specified by key
138
139 \param nlsa1 A name LSA object
140 \param key A key of an originating router to compare to nlsa1
141 */
akmhoque53353462014-04-22 08:43:45 -0500142static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500143nameLsaCompareByKey(const NameLsa& nlsa1, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500144{
145 return nlsa1.getKey() == key;
146}
147
akmhoque53353462014-04-22 08:43:45 -0500148bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500149Lsdb::buildAndInstallOwnNameLsa()
akmhoque53353462014-04-22 08:43:45 -0500150{
akmhoque31d1d4b2014-05-05 22:08:14 -0500151 NameLsa nameLsa(m_nlsr.getConfParameter().getRouterPrefix(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500152 m_nlsr.getSequencingManager().getNameLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500153 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500154 m_nlsr.getNamePrefixList());
155 m_nlsr.getSequencingManager().increaseNameLsaSeq();
156 return installNameLsa(nameLsa);
akmhoque53353462014-04-22 08:43:45 -0500157}
158
akmhoqueb6450b12014-04-24 00:01:03 -0500159NameLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500160Lsdb::findNameLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500161{
162 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
163 m_nameLsdb.end(),
164 bind(nameLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500165 if (it != m_nameLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500166 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500167 }
akmhoqueb6450b12014-04-24 00:01:03 -0500168 return 0;
akmhoque53353462014-04-22 08:43:45 -0500169}
170
171bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500172Lsdb::isNameLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500173{
akmhoqueb6450b12014-04-24 00:01:03 -0500174 NameLsa* nameLsaCheck = findNameLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500175 // Is the name in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500176 if (nameLsaCheck != 0) {
Nick G97e34942016-07-11 14:46:27 -0500177 // And the supplied seq no is the highest so far
akmhoque157b0a42014-05-13 00:26:37 -0500178 if (nameLsaCheck->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500179 return true;
180 }
akmhoque157b0a42014-05-13 00:26:37 -0500181 else {
akmhoque53353462014-04-22 08:43:45 -0500182 return false;
183 }
184 }
185 return true;
186}
187
188ndn::EventId
akmhoquec7a79b22014-05-26 08:06:19 -0500189Lsdb::scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
190 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500191{
Vince Lehman7c603292014-09-11 17:48:16 -0500192 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
193 ndn::bind(&Lsdb::exprireOrRefreshNameLsa, this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500194}
195
196bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500197Lsdb::installNameLsa(NameLsa& nlsa)
akmhoque53353462014-04-22 08:43:45 -0500198{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700199 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500200 NameLsa* chkNameLsa = findNameLsa(nlsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500201 // Determines if the name LSA is new or not.
akmhoque157b0a42014-05-13 00:26:37 -0500202 if (chkNameLsa == 0) {
akmhoque53353462014-04-22 08:43:45 -0500203 addNameLsa(nlsa);
akmhoque2f423352014-06-03 11:49:35 -0500204 _LOG_DEBUG("New Name LSA");
205 _LOG_DEBUG("Adding Name Lsa");
akmhoque53353462014-04-22 08:43:45 -0500206 nlsa.writeLog();
akmhoque674b0b12014-05-20 14:33:28 -0500207
akmhoque157b0a42014-05-13 00:26:37 -0500208 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500209 // If this name LSA is from another router, add the advertised
210 // prefixes to the NPT.
akmhoque31d1d4b2014-05-05 22:08:14 -0500211 m_nlsr.getNamePrefixTable().addEntry(nlsa.getOrigRouter(),
212 nlsa.getOrigRouter());
213 std::list<ndn::Name> nameList = nlsa.getNpl().getNameList();
214 for (std::list<ndn::Name>::iterator it = nameList.begin(); it != nameList.end();
akmhoque157b0a42014-05-13 00:26:37 -0500215 it++) {
216 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500217 m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500218 }
219 }
220 }
akmhoque157b0a42014-05-13 00:26:37 -0500221 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500222 ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
223 ndn::time::system_clock::now();
224 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500225 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500226 nlsa.setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
akmhoque53353462014-04-22 08:43:45 -0500227 nlsa.getLsSeqNo(),
228 timeToExpire));
229 }
Nick G97e34942016-07-11 14:46:27 -0500230 // Else this is a known name LSA, so we are updating it.
akmhoque157b0a42014-05-13 00:26:37 -0500231 else {
232 if (chkNameLsa->getLsSeqNo() < nlsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500233 _LOG_DEBUG("Updated Name LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500234 _LOG_DEBUG("Deleting Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500235 chkNameLsa->writeLog();
236 chkNameLsa->setLsSeqNo(nlsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500237 chkNameLsa->setExpirationTimePoint(nlsa.getExpirationTimePoint());
akmhoqueb6450b12014-04-24 00:01:03 -0500238 chkNameLsa->getNpl().sort();
akmhoque53353462014-04-22 08:43:45 -0500239 nlsa.getNpl().sort();
Nick G97e34942016-07-11 14:46:27 -0500240 // Obtain the set difference of the current and the incoming
241 // name prefix sets, and add those.
akmhoque31d1d4b2014-05-05 22:08:14 -0500242 std::list<ndn::Name> nameToAdd;
akmhoque53353462014-04-22 08:43:45 -0500243 std::set_difference(nlsa.getNpl().getNameList().begin(),
244 nlsa.getNpl().getNameList().end(),
akmhoqueb6450b12014-04-24 00:01:03 -0500245 chkNameLsa->getNpl().getNameList().begin(),
246 chkNameLsa->getNpl().getNameList().end(),
akmhoque53353462014-04-22 08:43:45 -0500247 std::inserter(nameToAdd, nameToAdd.begin()));
akmhoque31d1d4b2014-05-05 22:08:14 -0500248 for (std::list<ndn::Name>::iterator it = nameToAdd.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500249 it != nameToAdd.end(); ++it) {
akmhoqueb6450b12014-04-24 00:01:03 -0500250 chkNameLsa->addName((*it));
akmhoque157b0a42014-05-13 00:26:37 -0500251 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
252 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500253 m_nlsr.getNamePrefixTable().addEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500254 }
255 }
256 }
Vince Lehmanf1aa5232014-10-06 17:57:35 -0500257
258 chkNameLsa->getNpl().sort();
259
Nick G97e34942016-07-11 14:46:27 -0500260 // Also remove any names that are no longer being advertised.
akmhoque31d1d4b2014-05-05 22:08:14 -0500261 std::list<ndn::Name> nameToRemove;
akmhoqueb6450b12014-04-24 00:01:03 -0500262 std::set_difference(chkNameLsa->getNpl().getNameList().begin(),
263 chkNameLsa->getNpl().getNameList().end(),
akmhoque53353462014-04-22 08:43:45 -0500264 nlsa.getNpl().getNameList().begin(),
265 nlsa.getNpl().getNameList().end(),
266 std::inserter(nameToRemove, nameToRemove.begin()));
akmhoque31d1d4b2014-05-05 22:08:14 -0500267 for (std::list<ndn::Name>::iterator it = nameToRemove.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500268 it != nameToRemove.end(); ++it) {
akmhoqueb6450b12014-04-24 00:01:03 -0500269 chkNameLsa->removeName((*it));
akmhoque157b0a42014-05-13 00:26:37 -0500270 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
271 if ((*it) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500272 m_nlsr.getNamePrefixTable().removeEntry((*it), nlsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500273 }
274 }
275 }
akmhoque157b0a42014-05-13 00:26:37 -0500276 if (nlsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500277 ndn::time::system_clock::Duration duration = nlsa.getExpirationTimePoint() -
278 ndn::time::system_clock::now();
279 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500280 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500281 cancelScheduleLsaExpiringEvent(chkNameLsa->getExpiringEventId());
282 chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500283 nlsa.getLsSeqNo(),
284 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500285 _LOG_DEBUG("Adding Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500286 chkNameLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500287 }
288 }
289 return true;
290}
291
292bool
293Lsdb::addNameLsa(NameLsa& nlsa)
294{
295 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
296 m_nameLsdb.end(),
297 bind(nameLsaCompareByKey, _1,
298 nlsa.getKey()));
akmhoque157b0a42014-05-13 00:26:37 -0500299 if (it == m_nameLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500300 m_nameLsdb.push_back(nlsa);
301 return true;
302 }
303 return false;
304}
305
306bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500307Lsdb::removeNameLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500308{
309 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
310 m_nameLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500311 ndn::bind(nameLsaCompareByKey, _1, key));
312 if (it != m_nameLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500313 _LOG_DEBUG("Deleting Name Lsa");
akmhoque53353462014-04-22 08:43:45 -0500314 (*it).writeLog();
Nick G97e34942016-07-11 14:46:27 -0500315 // If the requested name LSA is not ours, we also need to remove
316 // its entries from the NPT.
akmhoque31d1d4b2014-05-05 22:08:14 -0500317 if ((*it).getOrigRouter() !=
akmhoque157b0a42014-05-13 00:26:37 -0500318 m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500319 m_nlsr.getNamePrefixTable().removeEntry((*it).getOrigRouter(),
320 (*it).getOrigRouter());
321 for (std::list<ndn::Name>::iterator nit = (*it).getNpl().getNameList().begin();
akmhoque157b0a42014-05-13 00:26:37 -0500322 nit != (*it).getNpl().getNameList().end(); ++nit) {
323 if ((*nit) != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500324 m_nlsr.getNamePrefixTable().removeEntry((*nit), (*it).getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500325 }
326 }
327 }
328 m_nameLsdb.erase(it);
329 return true;
330 }
331 return false;
332}
333
334bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500335Lsdb::doesNameLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500336{
337 std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
338 m_nameLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500339 ndn::bind(nameLsaCompareByKey, _1, key));
340 if (it == m_nameLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500341 return false;
342 }
343 return true;
344}
345
346void
akmhoque2f423352014-06-03 11:49:35 -0500347Lsdb::writeNameLsdbLog()
akmhoque53353462014-04-22 08:43:45 -0500348{
akmhoque2f423352014-06-03 11:49:35 -0500349 _LOG_DEBUG("---------------Name LSDB-------------------");
akmhoque53353462014-04-22 08:43:45 -0500350 for (std::list<NameLsa>::iterator it = m_nameLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500351 it != m_nameLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -0500352 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -0500353 }
354}
355
Jiewen Tana0497d82015-02-02 21:59:18 -0800356const std::list<NameLsa>&
357Lsdb::getNameLsdb()
358{
359 return m_nameLsdb;
360}
361
akmhoque53353462014-04-22 08:43:45 -0500362// Cor LSA and LSDB related Functions start here
363
Nick G97e34942016-07-11 14:46:27 -0500364/*! \brief Compares whether an LSA object is the same as a key.
365 \param clsa The cor. LSA to check the identity of.
366 \param key The key of the publishing router to check against.
367*/
akmhoque53353462014-04-22 08:43:45 -0500368static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500369corLsaCompareByKey(const CoordinateLsa& clsa, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500370{
371 return clsa.getKey() == key;
372}
373
374bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500375Lsdb::buildAndInstallOwnCoordinateLsa()
akmhoque53353462014-04-22 08:43:45 -0500376{
akmhoque31d1d4b2014-05-05 22:08:14 -0500377 CoordinateLsa corLsa(m_nlsr.getConfParameter().getRouterPrefix(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500378 m_nlsr.getSequencingManager().getCorLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500379 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500380 m_nlsr.getConfParameter().getCorR(),
381 m_nlsr.getConfParameter().getCorTheta());
Nick Gordon5c467f02016-07-13 13:40:10 -0500382
383 // Sync coordinate LSAs if using HR or HR dry run.
384 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
385 m_nlsr.getSequencingManager().increaseCorLsaSeq();
386 m_sync.publishRoutingUpdate();
387 }
388
akmhoque31d1d4b2014-05-05 22:08:14 -0500389 installCoordinateLsa(corLsa);
Nick Gordon5c467f02016-07-13 13:40:10 -0500390
akmhoque53353462014-04-22 08:43:45 -0500391 return true;
392}
393
akmhoqueb6450b12014-04-24 00:01:03 -0500394CoordinateLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500395Lsdb::findCoordinateLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500396{
akmhoqueb6450b12014-04-24 00:01:03 -0500397 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
398 m_corLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500399 ndn::bind(corLsaCompareByKey, _1, key));
400 if (it != m_corLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500401 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500402 }
akmhoqueb6450b12014-04-24 00:01:03 -0500403 return 0;
akmhoque53353462014-04-22 08:43:45 -0500404}
405
406bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500407Lsdb::isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500408{
akmhoqueb6450b12014-04-24 00:01:03 -0500409 CoordinateLsa* clsa = findCoordinateLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500410 // Is the coordinate LSA in the LSDB already
akmhoque157b0a42014-05-13 00:26:37 -0500411 if (clsa != 0) {
Nick G97e34942016-07-11 14:46:27 -0500412 // And the seq no is newer (higher) than the current one
akmhoque157b0a42014-05-13 00:26:37 -0500413 if (clsa->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500414 return true;
415 }
akmhoque157b0a42014-05-13 00:26:37 -0500416 else {
akmhoque53353462014-04-22 08:43:45 -0500417 return false;
418 }
419 }
420 return true;
421}
422
Nick G97e34942016-07-11 14:46:27 -0500423 // Schedules a refresh/expire event in the scheduler.
424 // \param key The name of the router that published the LSA.
425 // \param seqNo the seq. no. associated with the LSA to check.
426 // \param expTime How long to wait before triggering the event.
akmhoque53353462014-04-22 08:43:45 -0500427ndn::EventId
akmhoque31d1d4b2014-05-05 22:08:14 -0500428Lsdb::scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
akmhoquec7a79b22014-05-26 08:06:19 -0500429 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500430{
Vince Lehman7c603292014-09-11 17:48:16 -0500431 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
432 ndn::bind(&Lsdb::exprireOrRefreshCoordinateLsa,
433 this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500434}
435
436bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500437Lsdb::installCoordinateLsa(CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500438{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700439 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500440 CoordinateLsa* chkCorLsa = findCoordinateLsa(clsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500441 // Checking whether the LSA is new or not.
akmhoque157b0a42014-05-13 00:26:37 -0500442 if (chkCorLsa == 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500443 _LOG_DEBUG("New Coordinate LSA. Adding to LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500444 _LOG_DEBUG("Adding Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500445 clsa.writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500446 addCoordinateLsa(clsa);
akmhoque2f423352014-06-03 11:49:35 -0500447
Nick Gordon5c467f02016-07-13 13:40:10 -0500448 // Register the LSA's origin router prefix
akmhoque157b0a42014-05-13 00:26:37 -0500449 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500450 m_nlsr.getNamePrefixTable().addEntry(clsa.getOrigRouter(),
451 clsa.getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500452 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500453 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500454 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500455 }
Nick G97e34942016-07-11 14:46:27 -0500456 // Set the expiration time for the new LSA.
akmhoque157b0a42014-05-13 00:26:37 -0500457 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500458 ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
459 ndn::time::system_clock::now();
460 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500461 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500462 scheduleCoordinateLsaExpiration(clsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500463 clsa.getLsSeqNo(), timeToExpire);
akmhoque53353462014-04-22 08:43:45 -0500464 }
Nick G97e34942016-07-11 14:46:27 -0500465 // We are just updating this LSA.
akmhoque157b0a42014-05-13 00:26:37 -0500466 else {
467 if (chkCorLsa->getLsSeqNo() < clsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500468 _LOG_DEBUG("Updated Coordinate LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500469 _LOG_DEBUG("Deleting Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500470 chkCorLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500471 chkCorLsa->setLsSeqNo(clsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500472 chkCorLsa->setExpirationTimePoint(clsa.getExpirationTimePoint());
Nick G97e34942016-07-11 14:46:27 -0500473 // If the new LSA contains new routing information, update the LSDB with it.
akmhoque157b0a42014-05-13 00:26:37 -0500474 if (!chkCorLsa->isEqualContent(clsa)) {
akmhoqueb6450b12014-04-24 00:01:03 -0500475 chkCorLsa->setCorRadius(clsa.getCorRadius());
476 chkCorLsa->setCorTheta(clsa.getCorTheta());
akmhoque157b0a42014-05-13 00:26:37 -0500477 if (m_nlsr.getConfParameter().getHyperbolicState() >= HYPERBOLIC_STATE_ON) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500478 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500479 }
480 }
Nick G97e34942016-07-11 14:46:27 -0500481 // If this is an LSA from another router, refresh its expiration time.
akmhoque157b0a42014-05-13 00:26:37 -0500482 if (clsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500483 ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
484 ndn::time::system_clock::now();
485 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500486 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500487 cancelScheduleLsaExpiringEvent(chkCorLsa->getExpiringEventId());
488 chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(clsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500489 clsa.getLsSeqNo(),
490 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500491 _LOG_DEBUG("Adding Coordinate Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500492 chkCorLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500493 }
494 }
495 return true;
496}
497
498bool
akmhoqueb6450b12014-04-24 00:01:03 -0500499Lsdb::addCoordinateLsa(CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500500{
akmhoqueb6450b12014-04-24 00:01:03 -0500501 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
502 m_corLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500503 ndn::bind(corLsaCompareByKey, _1,
504 clsa.getKey()));
505 if (it == m_corLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500506 m_corLsdb.push_back(clsa);
507 return true;
508 }
509 return false;
510}
511
512bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500513Lsdb::removeCoordinateLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500514{
akmhoqueb6450b12014-04-24 00:01:03 -0500515 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
516 m_corLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500517 ndn::bind(corLsaCompareByKey,
518 _1, key));
519 if (it != m_corLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500520 _LOG_DEBUG("Deleting Coordinate Lsa");
Nick Gordon5c467f02016-07-13 13:40:10 -0500521 it->writeLog();
522
523 if (it->getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
524 m_nlsr.getNamePrefixTable().removeEntry(it->getOrigRouter(), it->getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500525 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500526
akmhoque53353462014-04-22 08:43:45 -0500527 m_corLsdb.erase(it);
528 return true;
529 }
530 return false;
531}
532
533bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500534Lsdb::doesCoordinateLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500535{
akmhoqueb6450b12014-04-24 00:01:03 -0500536 std::list<CoordinateLsa>::iterator it = std::find_if(m_corLsdb.begin(),
537 m_corLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500538 ndn::bind(corLsaCompareByKey,
539 _1, key));
540 if (it == m_corLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500541 return false;
542 }
543 return true;
544}
545
546void
akmhoque2f423352014-06-03 11:49:35 -0500547Lsdb::writeCorLsdbLog()
akmhoque53353462014-04-22 08:43:45 -0500548{
akmhoque2f423352014-06-03 11:49:35 -0500549 _LOG_DEBUG("---------------Cor LSDB-------------------");
akmhoqueb6450b12014-04-24 00:01:03 -0500550 for (std::list<CoordinateLsa>::iterator it = m_corLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -0500551 it != m_corLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -0500552 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -0500553 }
554}
555
Jiewen Tana0497d82015-02-02 21:59:18 -0800556const std::list<CoordinateLsa>&
557Lsdb::getCoordinateLsdb()
558{
559 return m_corLsdb;
560}
561
akmhoque53353462014-04-22 08:43:45 -0500562// Adj LSA and LSDB related function starts here
563
Nick G97e34942016-07-11 14:46:27 -0500564 /*! \brief Returns whether an adj. LSA object is from some router.
565 \param alsa The adj. LSA object.
566 \param key The router name that you want to compare the LSA with.
567 */
akmhoque53353462014-04-22 08:43:45 -0500568static bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500569adjLsaCompareByKey(AdjLsa& alsa, const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500570{
571 return alsa.getKey() == key;
572}
573
akmhoque53353462014-04-22 08:43:45 -0500574void
Vince Lehman50df6b72015-03-03 12:06:40 -0600575Lsdb::scheduleAdjLsaBuild()
akmhoque53353462014-04-22 08:43:45 -0500576{
Vince Lehman50df6b72015-03-03 12:06:40 -0600577 m_nlsr.incrementAdjBuildCount();
578
Nick Gordon5c467f02016-07-13 13:40:10 -0500579 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
580 // Don't build adjacency LSAs in hyperbolic routing
581 return;
582 }
583
Vince Lehman50df6b72015-03-03 12:06:40 -0600584 if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
585 _LOG_DEBUG("Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
586
587 m_scheduler.scheduleEvent(m_adjLsaBuildInterval, ndn::bind(&Lsdb::buildAdjLsa, this));
588 m_nlsr.setIsBuildAdjLsaSheduled(true);
589 }
590}
591
592void
593Lsdb::buildAdjLsa()
594{
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500595 _LOG_TRACE("Lsdb::buildAdjLsa called");
Vince Lehman50df6b72015-03-03 12:06:40 -0600596
akmhoque674b0b12014-05-20 14:33:28 -0500597 m_nlsr.setIsBuildAdjLsaSheduled(false);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500598
599 if (m_nlsr.getAdjacencyList().isAdjLsaBuildable(m_nlsr.getConfParameter().getInterestRetryNumber())) {
600
akmhoque31d1d4b2014-05-05 22:08:14 -0500601 int adjBuildCount = m_nlsr.getAdjBuildCount();
Nick G97e34942016-07-11 14:46:27 -0500602 // Only do the adjLsa build if there's one scheduled
akmhoque157b0a42014-05-13 00:26:37 -0500603 if (adjBuildCount > 0) {
Nick G97e34942016-07-11 14:46:27 -0500604 // It only makes sense to do the adjLsa build if we have neighbors
akmhoque157b0a42014-05-13 00:26:37 -0500605 if (m_nlsr.getAdjacencyList().getNumOfActiveNeighbor() > 0) {
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500606 _LOG_DEBUG("Building and installing own Adj LSA");
akmhoque31d1d4b2014-05-05 22:08:14 -0500607 buildAndInstallOwnAdjLsa();
akmhoque53353462014-04-22 08:43:45 -0500608 }
Nick G97e34942016-07-11 14:46:27 -0500609 // We have no active neighbors, meaning no one can route through
610 // us. So delete our entry in the LSDB. This prevents this
611 // router from refreshing the LSA, eventually causing other
612 // routers to delete it, too.
akmhoque157b0a42014-05-13 00:26:37 -0500613 else {
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500614 _LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors")
Nick G97e34942016-07-11 14:46:27 -0500615 // Get this router's key
akmhoque31d1d4b2014-05-05 22:08:14 -0500616 ndn::Name key = m_nlsr.getConfParameter().getRouterPrefix();
alvy49b1c0c2014-12-19 13:57:46 -0600617 key.append(AdjLsa::TYPE_STRING);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500618
akmhoque31d1d4b2014-05-05 22:08:14 -0500619 removeAdjLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500620 // Recompute routing table after removal
akmhoque31d1d4b2014-05-05 22:08:14 -0500621 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500622 }
Nick G97e34942016-07-11 14:46:27 -0500623 // In the case that during building the adj LSA, the FIB has to
624 // wait on an Interest response, the number of scheduled adj LSA
625 // builds could change, so we shouldn't just set it to 0.
akmhoque31d1d4b2014-05-05 22:08:14 -0500626 m_nlsr.setAdjBuildCount(m_nlsr.getAdjBuildCount() - adjBuildCount);
akmhoque53353462014-04-22 08:43:45 -0500627 }
628 }
Nick G97e34942016-07-11 14:46:27 -0500629 // We are still waiting to know the adjacency status of some
630 // neighbor, so schedule a build for later (when all that has
631 // hopefully finished)
632 else {
633 m_nlsr.setIsBuildAdjLsaSheduled(true);
634 int schedulingTime = m_nlsr.getConfParameter().getInterestRetryNumber() *
635 m_nlsr.getConfParameter().getInterestResendTime();
636 m_scheduler.scheduleEvent(ndn::time::seconds(schedulingTime),
637 ndn::bind(&Lsdb::buildAdjLsa, this));
638 }
akmhoque53353462014-04-22 08:43:45 -0500639}
640
akmhoque53353462014-04-22 08:43:45 -0500641bool
642Lsdb::addAdjLsa(AdjLsa& alsa)
643{
644 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
645 m_adjLsdb.end(),
646 bind(adjLsaCompareByKey, _1,
647 alsa.getKey()));
akmhoque157b0a42014-05-13 00:26:37 -0500648 if (it == m_adjLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500649 m_adjLsdb.push_back(alsa);
650 return true;
651 }
652 return false;
653}
654
akmhoqueb6450b12014-04-24 00:01:03 -0500655AdjLsa*
akmhoque31d1d4b2014-05-05 22:08:14 -0500656Lsdb::findAdjLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500657{
658 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
659 m_adjLsdb.end(),
660 bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500661 if (it != m_adjLsdb.end()) {
akmhoqueb6450b12014-04-24 00:01:03 -0500662 return &(*it);
akmhoque53353462014-04-22 08:43:45 -0500663 }
akmhoqueb6450b12014-04-24 00:01:03 -0500664 return 0;
akmhoque53353462014-04-22 08:43:45 -0500665}
666
akmhoque53353462014-04-22 08:43:45 -0500667bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500668Lsdb::isAdjLsaNew(const ndn::Name& key, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500669{
akmhoqueb6450b12014-04-24 00:01:03 -0500670 AdjLsa* adjLsaCheck = findAdjLsa(key);
Nick G97e34942016-07-11 14:46:27 -0500671 // If it is in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500672 if (adjLsaCheck != 0) {
Nick G97e34942016-07-11 14:46:27 -0500673 // And the supplied seq no is newer (higher) than the current one.
akmhoque157b0a42014-05-13 00:26:37 -0500674 if (adjLsaCheck->getLsSeqNo() < seqNo) {
akmhoque53353462014-04-22 08:43:45 -0500675 return true;
676 }
akmhoque157b0a42014-05-13 00:26:37 -0500677 else {
akmhoque53353462014-04-22 08:43:45 -0500678 return false;
679 }
680 }
681 return true;
682}
683
akmhoque53353462014-04-22 08:43:45 -0500684ndn::EventId
akmhoquec7a79b22014-05-26 08:06:19 -0500685Lsdb::scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
686 const ndn::time::seconds& expTime)
akmhoque53353462014-04-22 08:43:45 -0500687{
Vince Lehman7c603292014-09-11 17:48:16 -0500688 return m_scheduler.scheduleEvent(expTime + GRACE_PERIOD,
689 ndn::bind(&Lsdb::exprireOrRefreshAdjLsa, this, key, seqNo));
akmhoque53353462014-04-22 08:43:45 -0500690}
691
692bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500693Lsdb::installAdjLsa(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500694{
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700695 ndn::time::seconds timeToExpire = m_lsaRefreshTime;
akmhoqueb6450b12014-04-24 00:01:03 -0500696 AdjLsa* chkAdjLsa = findAdjLsa(alsa.getKey());
Nick G97e34942016-07-11 14:46:27 -0500697 // If this adj. LSA is not in the LSDB already
akmhoque157b0a42014-05-13 00:26:37 -0500698 if (chkAdjLsa == 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500699 _LOG_DEBUG("New Adj LSA. Adding to LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500700 _LOG_DEBUG("Adding Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500701 alsa.writeLog();
akmhoque53353462014-04-22 08:43:45 -0500702 addAdjLsa(alsa);
Nick G97e34942016-07-11 14:46:27 -0500703 // Add any new name prefixes to the NPT
akmhoque31d1d4b2014-05-05 22:08:14 -0500704 alsa.addNptEntries(m_nlsr);
705 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque157b0a42014-05-13 00:26:37 -0500706 if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500707 ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
708 ndn::time::system_clock::now();
709 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500710 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500711 scheduleAdjLsaExpiration(alsa.getKey(),
akmhoque53353462014-04-22 08:43:45 -0500712 alsa.getLsSeqNo(), timeToExpire);
713 }
akmhoque157b0a42014-05-13 00:26:37 -0500714 else {
715 if (chkAdjLsa->getLsSeqNo() < alsa.getLsSeqNo()) {
akmhoque674b0b12014-05-20 14:33:28 -0500716 _LOG_DEBUG("Updated Adj LSA. Updating LSDB");
akmhoque2f423352014-06-03 11:49:35 -0500717 _LOG_DEBUG("Deleting Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500718 chkAdjLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500719 chkAdjLsa->setLsSeqNo(alsa.getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500720 chkAdjLsa->setExpirationTimePoint(alsa.getExpirationTimePoint());
Nick G97e34942016-07-11 14:46:27 -0500721 // If the new adj LSA has new content, update the contents of
722 // the LSDB entry. Additionally, since we've changed the
723 // contents of the LSDB, we have to schedule a routing
724 // calculation.
akmhoque157b0a42014-05-13 00:26:37 -0500725 if (!chkAdjLsa->isEqualContent(alsa)) {
akmhoqueb6450b12014-04-24 00:01:03 -0500726 chkAdjLsa->getAdl().reset();
akmhoquefdbddb12014-05-02 18:35:19 -0500727 chkAdjLsa->getAdl().addAdjacents(alsa.getAdl());
akmhoque31d1d4b2014-05-05 22:08:14 -0500728 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500729 }
akmhoque157b0a42014-05-13 00:26:37 -0500730 if (alsa.getOrigRouter() != m_nlsr.getConfParameter().getRouterPrefix()) {
akmhoquec7a79b22014-05-26 08:06:19 -0500731 ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
732 ndn::time::system_clock::now();
733 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
akmhoque53353462014-04-22 08:43:45 -0500734 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500735 cancelScheduleLsaExpiringEvent(chkAdjLsa->getExpiringEventId());
736 chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(alsa.getKey(),
akmhoqueb6450b12014-04-24 00:01:03 -0500737 alsa.getLsSeqNo(),
738 timeToExpire));
akmhoque2f423352014-06-03 11:49:35 -0500739 _LOG_DEBUG("Adding Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500740 chkAdjLsa->writeLog();
akmhoque53353462014-04-22 08:43:45 -0500741 }
742 }
743 return true;
744}
745
746bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500747Lsdb::buildAndInstallOwnAdjLsa()
akmhoque53353462014-04-22 08:43:45 -0500748{
akmhoque31d1d4b2014-05-05 22:08:14 -0500749 AdjLsa adjLsa(m_nlsr.getConfParameter().getRouterPrefix(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500750 m_nlsr.getSequencingManager().getAdjLsaSeq() + 1,
akmhoquec7a79b22014-05-26 08:06:19 -0500751 getLsaExpirationTimePoint(),
akmhoque31d1d4b2014-05-05 22:08:14 -0500752 m_nlsr.getAdjacencyList().getNumOfActiveNeighbor(),
753 m_nlsr.getAdjacencyList());
Vince Lehman904c2412014-09-23 19:36:11 -0500754
Nick Gordon5c467f02016-07-13 13:40:10 -0500755 //Sync adjacency LSAs if link-state or dry-run HR is enabled.
756 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_ON) {
757 m_nlsr.getSequencingManager().increaseAdjLsaSeq();
758 m_sync.publishRoutingUpdate();
759 }
Vince Lehman904c2412014-09-23 19:36:11 -0500760
Vince Lehman9d097802015-03-16 17:55:59 -0500761 return installAdjLsa(adjLsa);
akmhoque53353462014-04-22 08:43:45 -0500762}
763
764bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500765Lsdb::removeAdjLsa(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500766{
767 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
768 m_adjLsdb.end(),
akmhoque157b0a42014-05-13 00:26:37 -0500769 ndn::bind(adjLsaCompareByKey, _1, key));
770 if (it != m_adjLsdb.end()) {
akmhoque2f423352014-06-03 11:49:35 -0500771 _LOG_DEBUG("Deleting Adj Lsa");
akmhoque674b0b12014-05-20 14:33:28 -0500772 (*it).writeLog();
akmhoque31d1d4b2014-05-05 22:08:14 -0500773 (*it).removeNptEntries(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500774 m_adjLsdb.erase(it);
775 return true;
776 }
777 return false;
778}
779
780bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500781Lsdb::doesAdjLsaExist(const ndn::Name& key)
akmhoque53353462014-04-22 08:43:45 -0500782{
783 std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
784 m_adjLsdb.end(),
785 bind(adjLsaCompareByKey, _1, key));
akmhoque157b0a42014-05-13 00:26:37 -0500786 if (it == m_adjLsdb.end()) {
akmhoque53353462014-04-22 08:43:45 -0500787 return false;
788 }
789 return true;
790}
791
Jiewen Tana0497d82015-02-02 21:59:18 -0800792const std::list<AdjLsa>&
akmhoque53353462014-04-22 08:43:45 -0500793Lsdb::getAdjLsdb()
794{
795 return m_adjLsdb;
796}
797
798void
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700799Lsdb::setLsaRefreshTime(const seconds& lsaRefreshTime)
akmhoque53353462014-04-22 08:43:45 -0500800{
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700801 m_lsaRefreshTime = lsaRefreshTime;
akmhoque53353462014-04-22 08:43:45 -0500802}
803
804void
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500805Lsdb::setThisRouterPrefix(std::string trp)
akmhoque53353462014-04-22 08:43:45 -0500806{
807 m_thisRouterPrefix = trp;
808}
809
Nick G97e34942016-07-11 14:46:27 -0500810 // This function determines whether a name LSA should be refreshed
811 // or expired. The conditions for getting refreshed are: it is still
812 // in the LSDB, it hasn't been updated by something else already (as
813 // evidenced by its seq. no.), and this is the originating router for
814 // the LSA. Is it let expire in all other cases.
815 // lsaKey is the key of the LSA's publishing router.
816 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500817void
akmhoque31d1d4b2014-05-05 22:08:14 -0500818Lsdb::exprireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500819{
akmhoque674b0b12014-05-20 14:33:28 -0500820 _LOG_DEBUG("Lsdb::exprireOrRefreshNameLsa Called");
821 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500822 NameLsa* chkNameLsa = findNameLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500823 // If this name LSA exists in the LSDB
akmhoque157b0a42014-05-13 00:26:37 -0500824 if (chkNameLsa != 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500825 _LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500826 // If its seq no is the one we are expecting.
akmhoque157b0a42014-05-13 00:26:37 -0500827 if (chkNameLsa->getLsSeqNo() == seqNo) {
828 if (chkNameLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500829 _LOG_DEBUG("Own Name LSA, so refreshing it");
830 _LOG_DEBUG("Deleting Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500831 chkNameLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500832 chkNameLsa->setLsSeqNo(chkNameLsa->getLsSeqNo() + 1);
akmhoque31d1d4b2014-05-05 22:08:14 -0500833 m_nlsr.getSequencingManager().setNameLsaSeq(chkNameLsa->getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500834 chkNameLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500835 _LOG_DEBUG("Adding Name Lsa");
akmhoqueb6450b12014-04-24 00:01:03 -0500836 chkNameLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500837 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500838 chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(chkNameLsa->getKey(),
akmhoquefdbddb12014-05-02 18:35:19 -0500839 chkNameLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700840 m_lsaRefreshTime));
Vince Lehman0bcf9a32014-12-10 11:24:45 -0600841 m_sync.publishRoutingUpdate();
akmhoque53353462014-04-22 08:43:45 -0500842 }
Nick G97e34942016-07-11 14:46:27 -0500843 // Since we cannot refresh other router's LSAs, our only choice is to expire.
akmhoque157b0a42014-05-13 00:26:37 -0500844 else {
akmhoque674b0b12014-05-20 14:33:28 -0500845 _LOG_DEBUG("Other's Name LSA, so removing form LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500846 removeNameLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500847 }
848 }
849 }
850}
851
Nick G97e34942016-07-11 14:46:27 -0500852 // This function determines whether an adj. LSA should be refreshed
853 // or expired. The conditions for getting refreshed are: it is still
854 // in the LSDB, it hasn't been updated by something else already (as
855 // evidenced by its seq. no.), and this is the originating router for
856 // the LSA. Is it let expire in all other cases.
857 // lsaKey is the key of the LSA's publishing router.
858 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500859void
akmhoque31d1d4b2014-05-05 22:08:14 -0500860Lsdb::exprireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500861{
akmhoque674b0b12014-05-20 14:33:28 -0500862 _LOG_DEBUG("Lsdb::exprireOrRefreshAdjLsa Called");
863 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500864 AdjLsa* chkAdjLsa = findAdjLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500865 // If this is a valid LSA
akmhoque157b0a42014-05-13 00:26:37 -0500866 if (chkAdjLsa != 0) {
akmhoque2f423352014-06-03 11:49:35 -0500867 _LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500868 // And if it hasn't been updated for some other reason
akmhoque157b0a42014-05-13 00:26:37 -0500869 if (chkAdjLsa->getLsSeqNo() == seqNo) {
Nick G97e34942016-07-11 14:46:27 -0500870 // If it is our own LSA
akmhoque157b0a42014-05-13 00:26:37 -0500871 if (chkAdjLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500872 _LOG_DEBUG("Own Adj LSA, so refreshing it");
873 _LOG_DEBUG("Deleting Adj Lsa");
874 chkAdjLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500875 chkAdjLsa->setLsSeqNo(chkAdjLsa->getLsSeqNo() + 1);
akmhoque31d1d4b2014-05-05 22:08:14 -0500876 m_nlsr.getSequencingManager().setAdjLsaSeq(chkAdjLsa->getLsSeqNo());
akmhoquec7a79b22014-05-26 08:06:19 -0500877 chkAdjLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500878 _LOG_DEBUG("Adding Adj Lsa");
879 chkAdjLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500880 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500881 chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(chkAdjLsa->getKey(),
akmhoquefdbddb12014-05-02 18:35:19 -0500882 chkAdjLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700883 m_lsaRefreshTime));
Vince Lehman0bcf9a32014-12-10 11:24:45 -0600884 m_sync.publishRoutingUpdate();
akmhoque53353462014-04-22 08:43:45 -0500885 }
Nick G97e34942016-07-11 14:46:27 -0500886 // An LSA from another router is expiring
akmhoque157b0a42014-05-13 00:26:37 -0500887 else {
akmhoque674b0b12014-05-20 14:33:28 -0500888 _LOG_DEBUG("Other's Adj LSA, so removing form LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500889 removeAdjLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500890 }
Nick G97e34942016-07-11 14:46:27 -0500891 // We have changed the contents of the LSDB, so we have to
892 // schedule a routing calculation
akmhoque31d1d4b2014-05-05 22:08:14 -0500893 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500894 }
895 }
896}
897
Nick G97e34942016-07-11 14:46:27 -0500898 // This function determines whether an adj. LSA should be refreshed
899 // or expired. The conditions for getting refreshed are: it is still
900 // in the LSDB, it hasn't been updated by something else already (as
901 // evidenced by its seq. no.), and this is the originating router for
902 // the LSA. It is let expire in all other cases.
903 // lsaKey is the key of the LSA's publishing router.
904 // seqNo is the seq. no. of the candidate LSA.
akmhoque53353462014-04-22 08:43:45 -0500905void
akmhoque31d1d4b2014-05-05 22:08:14 -0500906Lsdb::exprireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
akmhoqueb6450b12014-04-24 00:01:03 -0500907 uint64_t seqNo)
akmhoque53353462014-04-22 08:43:45 -0500908{
akmhoque674b0b12014-05-20 14:33:28 -0500909 _LOG_DEBUG("Lsdb::exprireOrRefreshCorLsa Called ");
910 _LOG_DEBUG("LSA Key : " << lsaKey << " Seq No: " << seqNo);
akmhoqueb6450b12014-04-24 00:01:03 -0500911 CoordinateLsa* chkCorLsa = findCoordinateLsa(lsaKey);
Nick G97e34942016-07-11 14:46:27 -0500912 // Whether the LSA is in the LSDB or not.
akmhoque157b0a42014-05-13 00:26:37 -0500913 if (chkCorLsa != 0) {
akmhoque674b0b12014-05-20 14:33:28 -0500914 _LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getLsSeqNo());
Nick G97e34942016-07-11 14:46:27 -0500915 // Whether the LSA has been updated without our knowledge.
akmhoque157b0a42014-05-13 00:26:37 -0500916 if (chkCorLsa->getLsSeqNo() == seqNo) {
917 if (chkCorLsa->getOrigRouter() == m_thisRouterPrefix) {
akmhoque2f423352014-06-03 11:49:35 -0500918 _LOG_DEBUG("Own Cor LSA, so refreshing it");
919 _LOG_DEBUG("Deleting Coordinate Lsa");
920 chkCorLsa->writeLog();
akmhoqueb6450b12014-04-24 00:01:03 -0500921 chkCorLsa->setLsSeqNo(chkCorLsa->getLsSeqNo() + 1);
Nick Gordon5c467f02016-07-13 13:40:10 -0500922 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
923 m_nlsr.getSequencingManager().setCorLsaSeq(chkCorLsa->getLsSeqNo());
924 }
925
akmhoquec7a79b22014-05-26 08:06:19 -0500926 chkCorLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
akmhoque2f423352014-06-03 11:49:35 -0500927 _LOG_DEBUG("Adding Coordinate Lsa");
928 chkCorLsa->writeLog();
akmhoquefdbddb12014-05-02 18:35:19 -0500929 // schedule refreshing event again
akmhoque31d1d4b2014-05-05 22:08:14 -0500930 chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(
931 chkCorLsa->getKey(),
932 chkCorLsa->getLsSeqNo(),
Alexander Afanasyev8388ec62014-08-16 18:38:57 -0700933 m_lsaRefreshTime));
Nick Gordon5c467f02016-07-13 13:40:10 -0500934 // Only sync coordinate LSAs if link-state routing is disabled
935 if (m_nlsr.getConfParameter().getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
936 m_sync.publishRoutingUpdate();
937 }
akmhoque53353462014-04-22 08:43:45 -0500938 }
Nick G97e34942016-07-11 14:46:27 -0500939 // We can't refresh other router's LSAs, so we remove it.
akmhoque157b0a42014-05-13 00:26:37 -0500940 else {
akmhoque674b0b12014-05-20 14:33:28 -0500941 _LOG_DEBUG("Other's Cor LSA, so removing form LSDB");
akmhoque31d1d4b2014-05-05 22:08:14 -0500942 removeCoordinateLsa(lsaKey);
akmhoque53353462014-04-22 08:43:45 -0500943 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500944 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500945 m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
akmhoque53353462014-04-22 08:43:45 -0500946 }
947 }
948 }
949}
950
akmhoque53353462014-04-22 08:43:45 -0500951void
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700952Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500953 steady_clock::TimePoint deadline)
akmhoque31d1d4b2014-05-05 22:08:14 -0500954{
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500955 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
956 deadline = steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700957 }
Nick G97e34942016-07-11 14:46:27 -0500958 // The first component of the interest is the name.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500959 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
Nick G97e34942016-07-11 14:46:27 -0500960 // The seq no is the last
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500961 uint64_t seqNo = interestName[-1].toNumber();
962
Nick G97e34942016-07-11 14:46:27 -0500963 // If the LSA is not found in the list currently.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500964 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
965 m_highestSeqNo[lsaName] = seqNo;
966 }
Nick G97e34942016-07-11 14:46:27 -0500967 // If the new seq no is higher, that means the LSA is valid
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500968 else if (seqNo > m_highestSeqNo[lsaName]) {
969 m_highestSeqNo[lsaName] = seqNo;
970 }
Nick G97e34942016-07-11 14:46:27 -0500971 // Otherwise, its an old/invalid LSA
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500972 else if (seqNo < m_highestSeqNo[lsaName]) {
973 return;
974 }
975
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500976 ndn::Interest interest(interestName);
Alexander Afanasyev411ee4b2014-08-16 23:17:03 -0700977 interest.setInterestLifetime(m_nlsr.getConfParameter().getLsaInterestLifetime());
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500978
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500979 _LOG_DEBUG("Fetching Data for LSA: " << interestName << " Seq number: " << seqNo);
980 ndn::util::SegmentFetcher::fetch(m_nlsr.getNlsrFace(), interest,
981 m_nlsr.getValidator(),
982 ndn::bind(&Lsdb::afterFetchLsa, this, _1, interestName),
983 ndn::bind(&Lsdb::onFetchLsaError, this, _1, _2, interestName,
984 timeoutCount, deadline, lsaName, seqNo));
akmhoque31d1d4b2014-05-05 22:08:14 -0500985}
986
987void
988Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
989{
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500990 const ndn::Name& interestName(interest.getName());
991 _LOG_DEBUG("Interest received for LSA: " << interestName);
992
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -0500993 std::string chkString("LSA");
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500994 int32_t lsaPosition = util::getNameComponentPosition(interest.getName(), chkString);
995
akmhoque157b0a42014-05-13 00:26:37 -0500996 if (lsaPosition >= 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500997
Nick G97e34942016-07-11 14:46:27 -0500998 // Forms the name of the router that the Interest packet came from.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -0500999 ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
1000 originRouter.append(interestName.getSubName(lsaPosition + 1,
1001 interest.getName().size() - lsaPosition - 3));
1002
1003 uint64_t seqNo = interestName[-1].toNumber();
1004 _LOG_DEBUG("LSA sequence number from interest: " << seqNo);
1005
1006 std::string interestedLsType = interestName[-2].toUri();
1007
Nick G97e34942016-07-11 14:46:27 -05001008 // Passes the Interest off to the appropriate subprocessor
alvy49b1c0c2014-12-19 13:57:46 -06001009 if (interestedLsType == NameLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001010 processInterestForNameLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001011 }
alvy49b1c0c2014-12-19 13:57:46 -06001012 else if (interestedLsType == AdjLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001013 processInterestForAdjacencyLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001014 }
alvy49b1c0c2014-12-19 13:57:46 -06001015 else if (interestedLsType == CoordinateLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001016 processInterestForCoordinateLsa(interest, originRouter.append(interestedLsType), seqNo);
akmhoque31d1d4b2014-05-05 22:08:14 -05001017 }
akmhoque157b0a42014-05-13 00:26:37 -05001018 else {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001019 _LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
akmhoque31d1d4b2014-05-05 22:08:14 -05001020 }
1021 }
1022}
1023
Nick G97e34942016-07-11 14:46:27 -05001024 // \brief Sends LSA data.
1025 // \param interest The Interest that warranted the data.
1026 // \param content The data that the Interest was seeking.
akmhoque31d1d4b2014-05-05 22:08:14 -05001027void
akmhoque69c9aa92014-07-23 15:15:05 -05001028Lsdb::putLsaData(const ndn::Interest& interest, const std::string& content)
1029{
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001030 LsaContentPublisher publisher(m_nlsr.getNlsrFace(),
1031 m_nlsr.getKeyChain(),
1032 m_lsaRefreshTime,
1033 content);
1034 publisher.publish(interest.getName(),
1035 ndn::security::signingByCertificate(m_nlsr.getDefaultCertName()));
akmhoque69c9aa92014-07-23 15:15:05 -05001036}
1037
Nick G97e34942016-07-11 14:46:27 -05001038 // \brief Finds and sends a requested name LSA.
1039 // \param interest The interest that seeks the name LSA.
1040 // \param lsaKey The LSA that the Interest is seeking.
1041 // \param seqNo A sequence number to ensure that we are sending the
1042 // version that was requested.
akmhoque69c9aa92014-07-23 15:15:05 -05001043void
akmhoque31d1d4b2014-05-05 22:08:14 -05001044Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
1045 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001046 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001047{
1048 NameLsa* nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001049 if (nameLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001050 if (nameLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001051 std::string content = nameLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001052 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001053 }
1054 }
1055}
1056
Nick G97e34942016-07-11 14:46:27 -05001057 // \brief Finds and sends a requested adj. LSA.
1058 // \param interest The interest that seeks the adj. LSA.
1059 // \param lsaKey The LSA that the Interest is seeking.
1060 // \param seqNo A sequence number to ensure that we are sending the
1061 // version that was requested.
akmhoque31d1d4b2014-05-05 22:08:14 -05001062void
1063Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
1064 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001065 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001066{
Nick Gordon5c467f02016-07-13 13:40:10 -05001067 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
1068 _LOG_ERROR("Received interest for an adjacency LSA when hyperbolic routing is enabled.");
1069 }
1070
akmhoque31d1d4b2014-05-05 22:08:14 -05001071 AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001072 if (adjLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001073 if (adjLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001074 std::string content = adjLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001075 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001076 }
1077 }
1078}
1079
Nick G97e34942016-07-11 14:46:27 -05001080 // \brief Finds and sends a requested cor. LSA.
1081 // \param interest The interest that seeks the cor. LSA.
1082 // \param lsaKey The LSA that the Interest is seeking.
1083 // \param seqNo A sequence number to ensure that we are sending the
1084 // version that was requested.
akmhoque31d1d4b2014-05-05 22:08:14 -05001085void
1086Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
1087 const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001088 uint64_t seqNo)
akmhoque31d1d4b2014-05-05 22:08:14 -05001089{
Nick Gordon5c467f02016-07-13 13:40:10 -05001090 if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
1091 _LOG_ERROR("Received Interest for a coordinate LSA when link-state routing is enabled.");
1092 }
1093
akmhoque31d1d4b2014-05-05 22:08:14 -05001094 CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
akmhoque157b0a42014-05-13 00:26:37 -05001095 if (corLsa != 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001096 if (corLsa->getLsSeqNo() == seqNo) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001097 std::string content = corLsa->getData();
akmhoque69c9aa92014-07-23 15:15:05 -05001098 putLsaData(interest,content);
akmhoque31d1d4b2014-05-05 22:08:14 -05001099 }
1100 }
1101}
1102
1103void
Yingdi Yu20e3a6e2014-05-26 23:16:10 -07001104Lsdb::onContentValidated(const ndn::shared_ptr<const ndn::Data>& data)
1105{
1106 const ndn::Name& dataName = data->getName();
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001107 _LOG_DEBUG("Data validation successful for LSA: " << dataName);
1108
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001109 std::string chkString("LSA");
akmhoque31d1d4b2014-05-05 22:08:14 -05001110 int32_t lsaPosition = util::getNameComponentPosition(dataName, chkString);
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001111
akmhoque157b0a42014-05-13 00:26:37 -05001112 if (lsaPosition >= 0) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001113
Nick G97e34942016-07-11 14:46:27 -05001114 // Extracts the prefix of the originating router from the data.
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001115 ndn::Name originRouter = m_nlsr.getConfParameter().getNetwork();
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001116 originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001117
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001118 uint64_t seqNo = dataName[-1].toNumber();
1119 std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()));
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001120
Muktadir R Chowdhuryaa3b0852015-08-06 13:08:56 -05001121 std::string interestedLsType = dataName[-2].toUri();
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001122
alvy49b1c0c2014-12-19 13:57:46 -06001123 if (interestedLsType == NameLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001124 processContentNameLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001125 }
alvy49b1c0c2014-12-19 13:57:46 -06001126 else if (interestedLsType == AdjLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001127 processContentAdjacencyLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001128 }
alvy49b1c0c2014-12-19 13:57:46 -06001129 else if (interestedLsType == CoordinateLsa::TYPE_STRING) {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001130 processContentCoordinateLsa(originRouter.append(interestedLsType), seqNo, dataContent);
akmhoque31d1d4b2014-05-05 22:08:14 -05001131 }
akmhoque157b0a42014-05-13 00:26:37 -05001132 else {
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001133 _LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
akmhoque31d1d4b2014-05-05 22:08:14 -05001134 }
1135 }
1136}
1137
1138void
1139Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001140 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001141{
akmhoque157b0a42014-05-13 00:26:37 -05001142 if (isNameLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001143 NameLsa nameLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001144 if (nameLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001145 installNameLsa(nameLsa);
1146 }
akmhoque157b0a42014-05-13 00:26:37 -05001147 else {
akmhoque2f423352014-06-03 11:49:35 -05001148 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001149 }
1150 }
1151}
1152
1153void
1154Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001155 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001156{
akmhoque157b0a42014-05-13 00:26:37 -05001157 if (isAdjLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001158 AdjLsa adjLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001159 if (adjLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001160 installAdjLsa(adjLsa);
1161 }
akmhoque157b0a42014-05-13 00:26:37 -05001162 else {
akmhoque2f423352014-06-03 11:49:35 -05001163 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001164 }
1165 }
1166}
1167
1168void
1169Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
Ashlesh Gawande5bf83172014-09-19 12:38:17 -05001170 uint64_t lsSeqNo, std::string& dataContent)
akmhoque31d1d4b2014-05-05 22:08:14 -05001171{
akmhoque157b0a42014-05-13 00:26:37 -05001172 if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001173 CoordinateLsa corLsa;
akmhoque157b0a42014-05-13 00:26:37 -05001174 if (corLsa.initializeFromContent(dataContent)) {
akmhoque31d1d4b2014-05-05 22:08:14 -05001175 installCoordinateLsa(corLsa);
1176 }
akmhoque157b0a42014-05-13 00:26:37 -05001177 else {
akmhoque2f423352014-06-03 11:49:35 -05001178 _LOG_DEBUG("LSA data decoding error :(");
akmhoque31d1d4b2014-05-05 22:08:14 -05001179 }
1180 }
1181}
1182
akmhoquec7a79b22014-05-26 08:06:19 -05001183ndn::time::system_clock::TimePoint
1184Lsdb::getLsaExpirationTimePoint()
1185{
1186 ndn::time::system_clock::TimePoint expirationTimePoint = ndn::time::system_clock::now();
1187 expirationTimePoint = expirationTimePoint +
1188 ndn::time::seconds(m_nlsr.getConfParameter().getRouterDeadInterval());
1189 return expirationTimePoint;
1190}
akmhoque31d1d4b2014-05-05 22:08:14 -05001191
1192void
akmhoque2f423352014-06-03 11:49:35 -05001193Lsdb::writeAdjLsdbLog()
akmhoque53353462014-04-22 08:43:45 -05001194{
akmhoque2f423352014-06-03 11:49:35 -05001195 _LOG_DEBUG("---------------Adj LSDB-------------------");
akmhoque53353462014-04-22 08:43:45 -05001196 for (std::list<AdjLsa>::iterator it = m_adjLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -05001197 it != m_adjLsdb.end() ; it++) {
akmhoque2f423352014-06-03 11:49:35 -05001198 (*it).writeLog();
akmhoque53353462014-04-22 08:43:45 -05001199 }
1200}
1201
1202//-----utility function -----
1203bool
akmhoque31d1d4b2014-05-05 22:08:14 -05001204Lsdb::doesLsaExist(const ndn::Name& key, const std::string& lsType)
akmhoque53353462014-04-22 08:43:45 -05001205{
alvy49b1c0c2014-12-19 13:57:46 -06001206 if (lsType == NameLsa::TYPE_STRING) {
akmhoque53353462014-04-22 08:43:45 -05001207 return doesNameLsaExist(key);
1208 }
alvy49b1c0c2014-12-19 13:57:46 -06001209 else if (lsType == AdjLsa::TYPE_STRING) {
akmhoque53353462014-04-22 08:43:45 -05001210 return doesAdjLsaExist(key);
1211 }
alvy49b1c0c2014-12-19 13:57:46 -06001212 else if (lsType == CoordinateLsa::TYPE_STRING) {
akmhoqueb6450b12014-04-24 00:01:03 -05001213 return doesCoordinateLsaExist(key);
akmhoque53353462014-04-22 08:43:45 -05001214 }
1215 return false;
1216}
1217
Alexander Afanasyev8388ec62014-08-16 18:38:57 -07001218} // namespace nlsr