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-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 #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"
29 #include "lsa/coordinate-lsa.hpp"
30 #include "lsa/adj-lsa.hpp"
31 #include "sequencing-manager.hpp"
32 #include "statistics.hpp"
33 #include "test-access-control.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 
47 namespace nlsr {
48 
49 namespace bmi = boost::multi_index;
50 
51 inline constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
52 
53 enum class LsdbUpdate {
54  INSTALLED,
55  UPDATED,
56  REMOVED
57 };
58 
59 class Lsdb
60 {
61 public:
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 
85 public:
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 
334 public:
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<ndn::Name>, std::list<ndn::Name>>;
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:46
const ndn::Name & getOriginRouter() const
Definition: lsa.hpp:91
std::shared_ptr< T > findLsa(const ndn::Name &router) const
Definition: lsdb.hpp:116
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< ndn::Name >, std::list< ndn::Name > > AfterLsdbModified
Definition: lsdb.hpp:338
~Lsdb()
Definition: lsdb.cpp:85
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition: lsdb.hpp:173
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
AfterLsdbModified onLsdbModified
Definition: lsdb.hpp:339
void writeLog() const
Definition: lsdb.cpp:143
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Definition: lsdb.cpp:162
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
Lsdb(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam)
Definition: lsdb.cpp:34
SyncLogicHandler & getSync()
Definition: lsdb.hpp:109
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