Loading...
Searching...
No Matches
lsdb.hpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2025, 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#ifndef NLSR_LSDB_HPP
23#define NLSR_LSDB_HPP
24
26#include "conf-parameter.hpp"
27#include "lsa/lsa.hpp"
28#include "lsa/name-lsa.hpp"
30#include "lsa/adj-lsa.hpp"
32#include "statistics.hpp"
34
35#include <ndn-cxx/ims/in-memory-storage-fifo.hpp>
36#include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
37#include <ndn-cxx/security/key-chain.hpp>
38#include <ndn-cxx/util/segmenter.hpp>
39#include <ndn-cxx/util/segment-fetcher.hpp>
40#include <ndn-cxx/util/signal.hpp>
41#include <ndn-cxx/util/time.hpp>
42
43#include <boost/multi_index_container.hpp>
44#include <boost/multi_index/composite_key.hpp>
45#include <boost/multi_index/hashed_index.hpp>
46
47namespace nlsr {
48
49namespace bmi = boost::multi_index;
50
51inline constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
52
53enum class LsdbUpdate {
55 UPDATED,
57};
58
59class Lsdb
60{
61public:
62 Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
63
64 ~Lsdb();
65
68 bool
69 doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
70 {
71 return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
72 }
73
77 void
79
82 void
83 buildAndInstallOwnCoordinateLsa();
84
85public:
87 void
89
90 void
91 writeLog() const;
92
93 /* \brief Process interest which can be either:
94 * 1) Discovery interest from segment fetcher:
95 * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
96 * 2) Interest containing segment number:
97 * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
98 */
99 void
100 processInterest(const ndn::Name& name, const ndn::Interest& interest);
101
102 bool
104 {
105 return m_isBuildAdjLsaScheduled;
106 }
107
110 {
111 return m_sync;
112 }
113
114 template<typename T>
115 std::shared_ptr<T>
116 findLsa(const ndn::Name& router) const
117 {
118 return std::static_pointer_cast<T>(findLsa(router, T::type()));
119 }
120
122 {
123 using result_type = ndn::Name;
124
125 ndn::Name
126 operator()(const Lsa& lsa) const
127 {
128 return lsa.getOriginRouter();
129 }
130 };
131
132 struct name_hash {
133 int
134 operator()(const ndn::Name& name) const {
135 return std::hash<ndn::Name>{}(name);
136 }
137 };
138
140 template<typename T>
141 int
142 operator()(T t) const {
143 return static_cast<int>(t);
144 }
145 };
146
147 struct byName{};
148 struct byType{};
149
150 using LsaContainer = boost::multi_index_container<
151 std::shared_ptr<Lsa>,
152 bmi::indexed_by<
153 bmi::hashed_unique<
154 bmi::tag<byName>,
155 bmi::composite_key<
156 Lsa,
158 bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
159 >,
160 bmi::composite_key_hash<name_hash, enum_class_hash>
161 >,
162 bmi::hashed_non_unique<
163 bmi::tag<byType>,
164 bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
166 >
167 >
168 >;
169
170 template<typename T>
171 std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
172 LsaContainer::index<Lsdb::byType>::type::iterator>
174 {
175 return m_lsdb.get<byType>().equal_range(T::type());
176 }
177
179 std::shared_ptr<Lsa>
180 findLsa(const ndn::Name& router, Lsa::Type lsaType) const
181 {
182 auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
183 return it != m_lsdb.end() ? *it : nullptr;
184 }
185
186 void
187 incrementDataSentStats(Lsa::Type lsaType)
188 {
189 if (lsaType == Lsa::Type::NAME) {
191 }
192 else if (lsaType == Lsa::Type::ADJACENCY) {
194 }
195 else if (lsaType == Lsa::Type::COORDINATE) {
197 }
198 }
199
200 void
201 incrementInterestRcvdStats(Lsa::Type lsaType)
202 {
203 if (lsaType == Lsa::Type::NAME) {
205 }
206 else if (lsaType == Lsa::Type::ADJACENCY) {
208 }
209 else if (lsaType == Lsa::Type::COORDINATE) {
211 }
212 }
213
214 void
215 incrementInterestSentStats(Lsa::Type lsaType)
216 {
217 if (lsaType == Lsa::Type::NAME) {
219 }
220 else if (lsaType == Lsa::Type::ADJACENCY) {
222 }
223 else if (lsaType == Lsa::Type::COORDINATE) {
225 }
226 }
227
233 bool
234 isLsaNew(const ndn::Name& originRouter, Lsa::Type lsaType, uint64_t seqNo) const
235 {
236 // Is the name in the LSDB and the supplied seq no is the highest so far
237 auto lsaPtr = findLsa(originRouter, lsaType);
238 return lsaPtr ? lsaPtr->getSeqNo() < seqNo : true;
239 }
240
241 void
242 installLsa(std::shared_ptr<Lsa> lsa);
243
252 void
253 removeLsa(const ndn::Name& router, Lsa::Type lsaType);
254
255 void
256 removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);
257
265 void
266 buildAdjLsa();
267
269 void
270 buildAndInstallOwnAdjLsa();
271
276 ndn::scheduler::EventId
277 scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime);
278
282 void
283 expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
284
285 bool
286 processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
287 Lsa::Type lsaType, uint64_t seqNo);
288
289 void
290 expressInterest(const ndn::Name& interestName, uint32_t timeoutCount, uint64_t incomingFaceId,
291 ndn::time::steady_clock::time_point deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
292
307 void
308 onFetchLsaError(uint32_t errorCode, const std::string& msg,
309 const ndn::Name& interestName, uint32_t retransmitNo,
310 const ndn::time::steady_clock::time_point& deadline,
311 ndn::Name lsaName, uint64_t seqNo);
312
319 void
320 afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
321
322 void
323 emitSegmentValidatedSignal(const ndn::Data& data)
324 {
326 }
327
328 ndn::time::system_clock::time_point
329 getLsaExpirationTimePoint() const
330 {
331 return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
332 }
333
334public:
335 ndn::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
336 ndn::signal::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
337 using AfterLsdbModified = ndn::signal::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
338 std::list<nlsr::PrefixInfo>, std::list<nlsr::PrefixInfo>>;
340
342 ndn::Face& m_face;
343 ndn::Scheduler m_scheduler;
344 ConfParameter& m_confParam;
345
346 SyncLogicHandler m_sync;
347
348 LsaContainer m_lsdb;
349
350 ndn::time::seconds m_lsaRefreshTime;
351 ndn::time::seconds m_adjLsaBuildInterval;
352 const ndn::Name& m_thisRouterPrefix;
353
354 // Maps the name of an LSA to its highest known sequence number from sync;
355 // Used to stop NLSR from trying to fetch outdated LSAs
356 std::map<ndn::Name, uint64_t> m_highestSeqNo;
357
358 SequencingManager m_sequencingManager;
359
360 ndn::signal::ScopedConnection m_onNewLsaConnection;
361
362 std::set<std::shared_ptr<ndn::SegmentFetcher>> m_fetchers;
363 ndn::Segmenter m_segmenter;
364 ndn::InMemoryStorageFifo m_segmentFifo;
365
366 bool m_isBuildAdjLsaScheduled;
367 int64_t m_adjBuildCount;
368 ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
369
370 ndn::InMemoryStoragePersistent m_lsaStorage;
371
372 static inline const ndn::time::steady_clock::time_point DEFAULT_LSA_RETRIEVAL_DEADLINE =
373 ndn::time::steady_clock::time_point::min();
374};
375
376} // namespace nlsr
377
378#endif // NLSR_LSDB_HPP
A class to house all the configuration parameters for NLSR.
uint32_t getRouterDeadInterval() const
Represents a Link State Announcement (LSA).
Definition lsa.hpp:48
const ndn::Name & getOriginRouter() const
Definition lsa.hpp:93
ndn::signal::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
Definition lsdb.hpp:335
bool doesLsaExist(const ndn::Name &router, Lsa::Type lsaType)
Returns whether the LSDB contains some LSA.
Definition lsdb.hpp:69
ndn::signal::Signal< Lsdb, std::shared_ptr< Lsa >, LsdbUpdate, std::list< nlsr::PrefixInfo >, std::list< nlsr::PrefixInfo > > AfterLsdbModified
Definition lsdb.hpp:338
void buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
Definition lsdb.cpp:93
boost::multi_index_container< std::shared_ptr< Lsa >, bmi::indexed_by< bmi::hashed_unique< bmi::tag< byName >, bmi::composite_key< Lsa, ExtractOriginRouter, bmi::const_mem_fun< Lsa, Lsa::Type, &Lsa::getType > >, bmi::composite_key_hash< name_hash, enum_class_hash > >, bmi::hashed_non_unique< bmi::tag< byType >, bmi::const_mem_fun< Lsa, Lsa::Type, &Lsa::getType >, enum_class_hash > > > LsaContainer
Definition lsdb.hpp:168
std::shared_ptr< T > findLsa(const ndn::Name &router) const
Definition lsdb.hpp:116
AfterLsdbModified onLsdbModified
Definition lsdb.hpp:339
void writeLog() const
Definition lsdb.cpp:143
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition lsdb.hpp:173
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Definition lsdb.cpp:162
SyncLogicHandler & getSync()
Definition lsdb.hpp:109
ndn::signal::Signal< Lsdb, ndn::Data > afterSegmentValidatedSignal
Definition lsdb.hpp:336
bool getIsBuildAdjLsaScheduled() const
Definition lsdb.hpp:103
void scheduleAdjLsaBuild()
Schedules a build of this router's LSA.
Definition lsdb.cpp:122
NLSR-to-sync interaction point.
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
LsdbUpdate
Definition lsdb.hpp:53
constexpr ndn::time::seconds GRACE_PERIOD
Definition lsdb.hpp:51
ndn::Name operator()(const Lsa &lsa) const
Definition lsdb.hpp:126
int operator()(T t) const
Definition lsdb.hpp:142
int operator()(const ndn::Name &name) const
Definition lsdb.hpp:134
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE