Loading...
Searching...
No Matches
lsdb.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2024, The University of Memphis,
4 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
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/>.
20 */
21
22#include "lsdb.hpp"
23
24#include "logger.hpp"
25#include "nlsr.hpp"
27
28#include <ndn-cxx/lp/tags.hpp>
29
30namespace nlsr {
31
32INIT_LOGGER(Lsdb);
33
34Lsdb::Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam)
35 : m_face(face)
36 , m_scheduler(face.getIoContext())
37 , m_confParam(confParam)
38 , m_sync(m_face, keyChain,
39 [this] (const auto& routerName, Lsa::Type lsaType, uint64_t seqNo, uint64_t) {
40 return isLsaNew(routerName, lsaType, seqNo);
41 },
43 confParam.getSyncProtocol(),
44 confParam.getSyncPrefix(),
45 confParam.getSyncUserPrefix(),
46 confParam.getSyncInterestLifetime(),
47 confParam.getRouterPrefix(),
48 confParam.getHyperbolicState()
49 })
50 , m_lsaRefreshTime(ndn::time::seconds(m_confParam.getLsaRefreshTime()))
51 , m_adjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval())
52 , m_thisRouterPrefix(m_confParam.getRouterPrefix())
53 , m_sequencingManager(m_confParam.getStateFileDir(), m_confParam.getHyperbolicState())
54 , m_onNewLsaConnection(m_sync.onNewLsa.connect(
55 [this] (const ndn::Name& updateName, uint64_t sequenceNumber,
56 const ndn::Name& originRouter, uint64_t incomingFaceId) {
57 ndn::Name lsaInterest{updateName};
58 lsaInterest.appendNumber(sequenceNumber);
59 expressInterest(lsaInterest, 0, incomingFaceId);
60 }))
61 , m_segmenter(keyChain, m_confParam.getSigningInfo())
62 , m_segmentFifo(100)
63 , m_isBuildAdjLsaScheduled(false)
64 , m_adjBuildCount(0)
65{
66 ndn::Name name = m_confParam.getLsaPrefix();
67 NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
68
69 m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
70 [this] (const auto& name, const auto& interest) { processInterest(name, interest); },
71 [] (const auto& name) { NLSR_LOG_DEBUG("Successfully registered prefix: " << name); },
72 [] (const auto& name, const auto& reason) {
73 NLSR_LOG_ERROR("Failed to register prefix " << name);
74 NDN_THROW(std::runtime_error("Register prefix failed: " + reason));
75 },
76 m_confParam.getSigningInfo(), ndn::nfd::ROUTE_FLAG_CAPTURE);
77
78 buildAndInstallOwnNameLsa();
79 // Install coordinate LSAs if using HR or dry-run HR.
80 if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
81 buildAndInstallOwnCoordinateLsa();
82 }
83}
84
85Lsdb::~Lsdb()
86{
87 for (const auto& fetcher : m_fetchers) {
88 fetcher->stop();
89 }
90}
91
92void
93Lsdb::buildAndInstallOwnNameLsa()
94{
95 NameLsa nameLsa(m_thisRouterPrefix, m_sequencingManager.getNameLsaSeq() + 1,
96 getLsaExpirationTimePoint(), m_confParam.getNamePrefixList());
97 m_sequencingManager.increaseNameLsaSeq();
98 m_sequencingManager.writeSeqNoToFile();
99 m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
100
101 installLsa(std::make_shared<NameLsa>(nameLsa));
102}
103
104void
105Lsdb::buildAndInstallOwnCoordinateLsa()
106{
107 CoordinateLsa corLsa(m_thisRouterPrefix, m_sequencingManager.getCorLsaSeq() + 1,
108 getLsaExpirationTimePoint(), m_confParam.getCorR(),
109 m_confParam.getCorTheta());
110 m_sequencingManager.increaseCorLsaSeq();
111 m_sequencingManager.writeSeqNoToFile();
112
113 // Sync coordinate LSAs if using HR or HR dry run.
114 if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
115 m_sync.publishRoutingUpdate(Lsa::Type::COORDINATE, m_sequencingManager.getCorLsaSeq());
116 }
117
118 installLsa(std::make_shared<CoordinateLsa>(corLsa));
119}
120
121void
122Lsdb::scheduleAdjLsaBuild()
123{
124 m_adjBuildCount++;
125
126 if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
127 // Don't build adjacency LSAs in hyperbolic routing
128 NLSR_LOG_DEBUG("Adjacency LSA not built while in hyperbolic routing state");
129 return;
130 }
131
132 if (m_isBuildAdjLsaScheduled) {
133 NLSR_LOG_DEBUG("Rescheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
134 }
135 else {
136 NLSR_LOG_DEBUG("Scheduling Adjacency LSA build in " << m_adjLsaBuildInterval);
137 m_isBuildAdjLsaScheduled = true;
138 }
139 m_scheduledAdjLsaBuild = m_scheduler.schedule(m_adjLsaBuildInterval, [this] { buildAdjLsa(); });
140}
141
142void
143Lsdb::writeLog() const
144{
145 for (auto type : {Lsa::Type::COORDINATE, Lsa::Type::NAME, Lsa::Type::ADJACENCY}) {
146 if ((type == Lsa::Type::COORDINATE &&
147 m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) ||
148 (type == Lsa::Type::ADJACENCY &&
149 m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON)) {
150 continue;
151 }
152
153 NLSR_LOG_DEBUG("---------------" << type << " LSDB-------------------");
154 auto lsaRange = m_lsdb.get<byType>().equal_range(type);
155 for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
156 NLSR_LOG_DEBUG(**lsaIt);
157 }
158 }
159}
160
161void
162Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
163{
164 ndn::Name interestName(interest.getName());
165 NLSR_LOG_DEBUG("Interest received for LSA: " << interestName);
166
167 if (interestName[-2].isVersion()) {
168 // Interest for particular segment
169 auto data = m_segmentFifo.find(interestName);
170 if (data) {
171 NLSR_LOG_TRACE("Replying from FIFO buffer");
172 m_face.put(*data);
173 return;
174 }
175
176 // Remove version and segment
177 interestName = interestName.getPrefix(-2);
178 NLSR_LOG_TRACE("Interest w/o segment and version: " << interestName);
179 }
180
181 // increment RCV_LSA_INTEREST
182 lsaIncrementSignal(Statistics::PacketType::RCV_LSA_INTEREST);
183
184 std::string chkString("LSA");
185 int32_t lsaPosition = util::getNameComponentPosition(interestName, chkString);
186
187 // Forms the name of the router that the Interest packet came from.
188 ndn::Name originRouter = m_confParam.getNetwork();
189 originRouter.append(interestName.getSubName(lsaPosition + 1,
190 interestName.size() - lsaPosition - 3));
191
192 // if the interest is for this router's LSA
193 if (originRouter == m_thisRouterPrefix && lsaPosition >= 0) {
194 uint64_t seqNo = interestName[-1].toNumber();
195 NLSR_LOG_DEBUG("LSA sequence number from interest: " << seqNo);
196
197 std::string lsaType = interestName[-2].toUri();
198 Lsa::Type interestedLsType;
199 std::istringstream(lsaType) >> interestedLsType;
200 if (interestedLsType == Lsa::Type::BASE) {
201 NLSR_LOG_WARN("Received unrecognized LSA type: " << lsaType);
202 return;
203 }
204
205 incrementInterestRcvdStats(interestedLsType);
206 if (processInterestForLsa(interest, originRouter, interestedLsType, seqNo)) {
207 lsaIncrementSignal(Statistics::PacketType::SENT_LSA_DATA);
208 }
209 }
210 // else the interest is for other router's LSA, serve signed data from LsaSegmentStorage
211 else if (auto lsaSegment = m_lsaStorage.find(interest); lsaSegment) {
212 NLSR_LOG_TRACE("Found data in LSA storage. Sending data for " << interest.getName());
213 m_face.put(*lsaSegment);
214 }
215}
216
217bool
218Lsdb::processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
219 Lsa::Type lsaType, uint64_t seqNo)
220{
221 NLSR_LOG_DEBUG(interest << " received for " << lsaType);
222
223 if (auto lsaPtr = findLsa(originRouter, lsaType); lsaPtr) {
224 NLSR_LOG_TRACE("Verifying SeqNo for " << lsaType << " is same as requested");
225 if (lsaPtr->getSeqNo() == seqNo) {
226 auto segments = m_segmenter.segment(lsaPtr->wireEncode(),
227 ndn::Name(interest.getName()).appendVersion(),
228 ndn::MAX_NDN_PACKET_SIZE / 2, m_lsaRefreshTime);
229 for (const auto& data : segments) {
230 m_segmentFifo.insert(*data, m_lsaRefreshTime);
231 m_scheduler.schedule(m_lsaRefreshTime,
232 [this, name = data->getName()] { m_segmentFifo.erase(name); });
233 }
234
235 uint64_t segNum = 0;
236 if (interest.getName()[-1].isSegment()) {
237 segNum = interest.getName()[-1].toSegment();
238 }
239 if (segNum < segments.size()) {
240 m_face.put(*segments[segNum]);
241 }
242 incrementDataSentStats(lsaType);
243 return true;
244 }
245 }
246 else {
247 NLSR_LOG_TRACE(interest << " was not found in our LSDB");
248 }
249 return false;
250}
251
252void
253Lsdb::installLsa(std::shared_ptr<Lsa> lsa)
254{
255 auto timeToExpire = m_lsaRefreshTime;
256 if (lsa->getOriginRouter() != m_thisRouterPrefix) {
257 auto duration = lsa->getExpirationTimePoint() - ndn::time::system_clock::now();
258 if (duration > ndn::time::seconds(0)) {
259 timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
260 }
261 }
262
263 auto chkLsa = findLsa(lsa->getOriginRouter(), lsa->getType());
264 if (chkLsa == nullptr) {
265 NLSR_LOG_DEBUG("Adding LSA:\n" << *lsa);
266
267 m_lsdb.emplace(lsa);
268 onLsdbModified(lsa, LsdbUpdate::INSTALLED, {}, {});
269
270 lsa->setExpiringEventId(scheduleLsaExpiration(lsa, timeToExpire));
271 }
272 // Else this is a known name LSA, so we are updating it.
273 else if (chkLsa->getSeqNo() < lsa->getSeqNo()) {
274 NLSR_LOG_DEBUG("Updating LSA:\n" << *chkLsa);
275 chkLsa->setSeqNo(lsa->getSeqNo());
276 chkLsa->setExpirationTimePoint(lsa->getExpirationTimePoint());
277
278 auto [updated, namesToAdd, namesToRemove] = chkLsa->update(lsa);
279 if (updated) {
280 onLsdbModified(lsa, LsdbUpdate::UPDATED, namesToAdd, namesToRemove);
281 }
282
283 chkLsa->setExpiringEventId(scheduleLsaExpiration(chkLsa, timeToExpire));
284 NLSR_LOG_DEBUG("Updated LSA:\n" << *chkLsa);
285 }
286}
287
288void
289Lsdb::removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt)
290{
291 if (lsaIt != m_lsdb.end()) {
292 auto lsaPtr = *lsaIt;
293 NLSR_LOG_DEBUG("Removing LSA:\n" << *lsaPtr);
294 m_lsdb.erase(lsaIt);
295 onLsdbModified(lsaPtr, LsdbUpdate::REMOVED, {}, {});
296 }
297}
298
299void
300Lsdb::removeLsa(const ndn::Name& router, Lsa::Type lsaType)
301{
302 removeLsa(m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)));
303}
304
305void
306Lsdb::buildAdjLsa()
307{
308 NLSR_LOG_TRACE("buildAdjLsa called");
309
310 m_isBuildAdjLsaScheduled = false;
311
312 if (m_confParam.getAdjacencyList().isAdjLsaBuildable(m_confParam.getInterestRetryNumber())) {
313
314 int adjBuildCount = m_adjBuildCount;
315 // Only do the adjLsa build if there's one scheduled
316 if (adjBuildCount > 0) {
317 // It only makes sense to do the adjLsa build if we have neighbors
318 if (m_confParam.getAdjacencyList().getNumOfActiveNeighbor() > 0) {
319 NLSR_LOG_DEBUG("Building and installing own Adj LSA");
320 buildAndInstallOwnAdjLsa();
321 }
322 // We have no active neighbors, meaning no one can route through
323 // us. So delete our entry in the LSDB. This prevents this
324 // router from refreshing the LSA, eventually causing other
325 // routers to delete it, too.
326 else {
327 NLSR_LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors");
328 removeLsa(m_thisRouterPrefix, Lsa::Type::ADJACENCY);
329 }
330 // In the case that during building the adj LSA, the FIB has to
331 // wait on an Interest response, the number of scheduled adj LSA
332 // builds could change, so we shouldn't just set it to 0.
333 m_adjBuildCount = m_adjBuildCount - adjBuildCount;
334 }
335 }
336 // We are still waiting to know the adjacency status of some
337 // neighbor, so schedule a build for later (when all that has
338 // hopefully finished)
339 else {
340 m_isBuildAdjLsaScheduled = true;
341 auto schedulingTime = ndn::time::seconds(m_confParam.getInterestRetryNumber() *
342 m_confParam.getInterestResendTime());
343 m_scheduledAdjLsaBuild = m_scheduler.schedule(schedulingTime, [this] { buildAdjLsa(); });
344 }
345}
346
347void
348Lsdb::buildAndInstallOwnAdjLsa()
349{
350 AdjLsa adjLsa(m_thisRouterPrefix, m_sequencingManager.getAdjLsaSeq() + 1,
351 getLsaExpirationTimePoint(),
352 m_confParam.getAdjacencyList());
353 m_sequencingManager.increaseAdjLsaSeq();
354 m_sequencingManager.writeSeqNoToFile();
355
356 //Sync adjacency LSAs if link-state or dry-run HR is enabled.
357 if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_ON) {
358 m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
359 }
360
361 installLsa(std::make_shared<AdjLsa>(adjLsa));
362}
363
364ndn::scheduler::EventId
365Lsdb::scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime)
366{
367 NLSR_LOG_DEBUG("Scheduling expiration in: " << expTime + GRACE_PERIOD << " for " << lsa->getOriginRouter());
368 return m_scheduler.schedule(expTime + GRACE_PERIOD, [this, lsa] { expireOrRefreshLsa(lsa); });
369}
370
371void
372Lsdb::expireOrRefreshLsa(std::shared_ptr<Lsa> lsa)
373{
374 NLSR_LOG_DEBUG("ExpireOrRefreshLsa called for " << lsa->getType());
375 NLSR_LOG_DEBUG("OriginRouter: " << lsa->getOriginRouter() << " Seq No: " << lsa->getSeqNo());
376
377 auto lsaIt = m_lsdb.get<byName>().find(std::make_tuple(lsa->getOriginRouter(), lsa->getType()));
378
379 // If this name LSA exists in the LSDB
380 if (lsaIt != m_lsdb.end()) {
381 auto lsaPtr = *lsaIt;
382 NLSR_LOG_DEBUG(*lsaPtr);
383 NLSR_LOG_DEBUG("LSA Exists with seq no: " << lsaPtr->getSeqNo());
384 // If its seq no is the one we are expecting.
385 if (lsaPtr->getSeqNo() == lsa->getSeqNo()) {
386 if (lsaPtr->getOriginRouter() == m_thisRouterPrefix) {
387 NLSR_LOG_DEBUG("Own " << lsaPtr->getType() << " LSA, so refreshing it");
388 NLSR_LOG_DEBUG("Current LSA:\n" << *lsaPtr);
389 lsaPtr->setSeqNo(lsaPtr->getSeqNo() + 1);
390 m_sequencingManager.setLsaSeq(lsaPtr->getSeqNo(), lsaPtr->getType());
391 lsaPtr->setExpirationTimePoint(getLsaExpirationTimePoint());
392 NLSR_LOG_DEBUG("Updated LSA:\n" << *lsaPtr);
393 // schedule refreshing event again
394 lsaPtr->setExpiringEventId(scheduleLsaExpiration(lsaPtr, m_lsaRefreshTime));
395 m_sequencingManager.writeSeqNoToFile();
396 m_sync.publishRoutingUpdate(lsaPtr->getType(), m_sequencingManager.getLsaSeq(lsaPtr->getType()));
397 }
398 // Since we cannot refresh other router's LSAs, our only choice is to expire.
399 else {
400 NLSR_LOG_DEBUG("Other's " << lsaPtr->getType() << " LSA, so removing from LSDB");
401 removeLsa(lsaIt);
402 }
403 }
404 }
405}
406
407void
408Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount, uint64_t incomingFaceId,
409 ndn::time::steady_clock::time_point deadline)
410{
411 // increment SENT_LSA_INTEREST
412 lsaIncrementSignal(Statistics::PacketType::SENT_LSA_INTEREST);
413
414 if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
415 deadline = ndn::time::steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
416 }
417 // The first component of the interest is the name.
418 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
419 // The seq no is the last
420 uint64_t seqNo = interestName[-1].toNumber();
421
422 // If the LSA is not found in the list currently.
423 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
424 m_highestSeqNo[lsaName] = seqNo;
425 }
426 // If the new seq no is higher, that means the LSA is valid
427 else if (seqNo > m_highestSeqNo[lsaName]) {
428 m_highestSeqNo[lsaName] = seqNo;
429 }
430 // Otherwise, its an old/invalid LSA
431 else if (seqNo < m_highestSeqNo[lsaName]) {
432 return;
433 }
434
435 ndn::Interest interest(interestName);
436 if (incomingFaceId != 0) {
437 interest.setTag(std::make_shared<ndn::lp::NextHopFaceIdTag>(incomingFaceId));
438 }
439 ndn::SegmentFetcher::Options options;
440 options.interestLifetime = m_confParam.getLsaInterestLifetime();
441 options.maxTimeout = m_confParam.getLsaInterestLifetime();
442
443 NLSR_LOG_DEBUG("Fetching Data for LSA: " << interestName << " Seq number: " << seqNo);
444 auto fetcher = ndn::SegmentFetcher::start(m_face, interest, m_confParam.getValidator(), options);
445
446 auto it = m_fetchers.insert(fetcher).first;
447
448 fetcher->afterSegmentValidated.connect([this] (const ndn::Data& data) {
449 // Nlsr class subscribes to this to fetch certificates
450 afterSegmentValidatedSignal(data);
451
452 // If we don't do this IMS throws: std::bad_weak_ptr: bad_weak_ptr
453 auto lsaSegment = std::make_shared<const ndn::Data>(data);
454 m_lsaStorage.insert(*lsaSegment);
455 // Schedule deletion of the segment
456 m_scheduler.schedule(ndn::time::seconds(LSA_REFRESH_TIME_DEFAULT),
457 [this, name = lsaSegment->getName()] { m_lsaStorage.erase(name); });
458 });
459
460 fetcher->onComplete.connect([=] (const ndn::ConstBufferPtr& bufferPtr) {
461 m_lsaStorage.erase(ndn::Name(lsaName).appendNumber(seqNo - 1));
462 afterFetchLsa(bufferPtr, interestName);
463 m_fetchers.erase(it);
464 });
465
466 fetcher->onError.connect([=] (uint32_t errorCode, const std::string& msg) {
467 onFetchLsaError(errorCode, msg, interestName, timeoutCount, deadline, lsaName, seqNo);
468 m_fetchers.erase(it);
469 });
470
471 Lsa::Type lsaType;
472 std::istringstream(interestName[-2].toUri()) >> lsaType;
473 incrementInterestSentStats(lsaType);
474}
475
476void
477Lsdb::onFetchLsaError(uint32_t errorCode, const std::string& msg, const ndn::Name& interestName,
478 uint32_t retransmitNo, const ndn::time::steady_clock::time_point& deadline,
479 ndn::Name lsaName, uint64_t seqNo)
480{
481 NLSR_LOG_DEBUG("Failed to fetch LSA: " << lsaName << ", Error code: " << errorCode
482 << ", Message: " << msg);
483
484 if (ndn::time::steady_clock::now() < deadline) {
485 auto it = m_highestSeqNo.find(lsaName);
486 if (it != m_highestSeqNo.end() && it->second == seqNo) {
487 // If the SegmentFetcher failed due to an Interest timeout, it is safe to re-express
488 // immediately since at the least the LSA Interest lifetime has elapsed.
489 // Otherwise, it is necessary to delay the Interest re-expression to prevent
490 // the potential for constant Interest flooding.
491 auto delay = m_confParam.getLsaInterestLifetime();
492 if (errorCode == ndn::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
493 delay = 0_s;
494 }
495 m_scheduler.schedule(delay, std::bind(&Lsdb::expressInterest, this, interestName,
496 retransmitNo + 1, /*Multicast FaceID*/0, deadline));
497 }
498 }
499}
500
501void
502Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName)
503{
504 NLSR_LOG_DEBUG("Received data for LSA interest: " << interestName);
505 lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
506
507 ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
508 uint64_t seqNo = interestName[-1].toNumber();
509
510 if (m_highestSeqNo.find(lsaName) == m_highestSeqNo.end()) {
511 m_highestSeqNo[lsaName] = seqNo;
512 }
513 else if (seqNo > m_highestSeqNo[lsaName]) {
514 m_highestSeqNo[lsaName] = seqNo;
515 NLSR_LOG_TRACE("SeqNo for LSA(name): " << interestName << " updated");
516 }
517 else if (seqNo < m_highestSeqNo[lsaName]) {
518 return;
519 }
520
521 std::string chkString("LSA");
522 int32_t lsaPosition = util::getNameComponentPosition(interestName, chkString);
523
524 if (lsaPosition >= 0) {
525 // Extracts the prefix of the originating router from the data.
526 ndn::Name originRouter = m_confParam.getNetwork();
527 originRouter.append(interestName.getSubName(lsaPosition + 1,
528 interestName.size() - lsaPosition - 3));
529 try {
530 Lsa::Type interestedLsType;
531 std::istringstream(interestName[-2].toUri()) >> interestedLsType;
532
533 if (interestedLsType == Lsa::Type::BASE) {
534 NLSR_LOG_WARN("Received unrecognized LSA Type: " << interestName[-2].toUri());
535 return;
536 }
537
538 ndn::Block block(bufferPtr);
539 if (interestedLsType == Lsa::Type::NAME) {
540 lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_DATA);
541 if (isLsaNew(originRouter, interestedLsType, seqNo)) {
542 installLsa(std::make_shared<NameLsa>(block));
543 }
544 }
545 else if (interestedLsType == Lsa::Type::ADJACENCY) {
546 lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_DATA);
547 if (isLsaNew(originRouter, interestedLsType, seqNo)) {
548 installLsa(std::make_shared<AdjLsa>(block));
549 }
550 }
551 else if (interestedLsType == Lsa::Type::COORDINATE) {
552 lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_DATA);
553 if (isLsaNew(originRouter, interestedLsType, seqNo)) {
554 installLsa(std::make_shared<CoordinateLsa>(block));
555 }
556 }
557 }
558 catch (const std::exception& e) {
559 NLSR_LOG_TRACE("LSA data decoding error: " << e.what());
560 }
561 }
562}
563
564} // namespace nlsr
A class to house all the configuration parameters for NLSR.
Represents an LSA of hyperbolic coordinates of the origin router.
Represents a Link State Announcement (LSA).
Definition lsa.hpp:48
Lsdb(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam)
Definition lsdb.cpp:34
Represents an LSA of name prefixes announced by the origin router.
Definition name-lsa.hpp:43
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
Definition logger.hpp:38
#define INIT_LOGGER(name)
Definition logger.hpp:35
#define NLSR_LOG_WARN(x)
Definition logger.hpp:40
#define NLSR_LOG_ERROR(x)
Definition logger.hpp:41
#define NLSR_LOG_TRACE(x)
Definition logger.hpp:37
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
@ HYPERBOLIC_STATE_ON
@ HYPERBOLIC_STATE_OFF