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-2023, 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 
121  struct name_hash {
122  int
123  operator()(const ndn::Name& name) const {
124  return std::hash<ndn::Name>{}(name);
125  }
126  };
127 
129  template<typename T>
130  int
131  operator()(T t) const {
132  return static_cast<int>(t);
133  }
134  };
135 
136  struct byName{};
137  struct byType{};
138 
139  using LsaContainer = boost::multi_index_container<
140  std::shared_ptr<Lsa>,
141  bmi::indexed_by<
142  bmi::hashed_unique<
143  bmi::tag<byName>,
144  bmi::composite_key<
145  Lsa,
146  bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
147  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
148  >,
149  bmi::composite_key_hash<name_hash, enum_class_hash>
150  >,
151  bmi::hashed_non_unique<
152  bmi::tag<byType>,
153  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
155  >
156  >
157  >;
158 
159  template<typename T>
160  std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
161  LsaContainer::index<Lsdb::byType>::type::iterator>
163  {
164  return m_lsdb.get<byType>().equal_range(T::type());
165  }
166 
168  std::shared_ptr<Lsa>
169  findLsa(const ndn::Name& router, Lsa::Type lsaType) const
170  {
171  auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
172  return it != m_lsdb.end() ? *it : nullptr;
173  }
174 
175  void
176  incrementDataSentStats(Lsa::Type lsaType)
177  {
178  if (lsaType == Lsa::Type::NAME) {
180  }
181  else if (lsaType == Lsa::Type::ADJACENCY) {
183  }
184  else if (lsaType == Lsa::Type::COORDINATE) {
186  }
187  }
188 
189  void
190  incrementInterestRcvdStats(Lsa::Type lsaType)
191  {
192  if (lsaType == Lsa::Type::NAME) {
194  }
195  else if (lsaType == Lsa::Type::ADJACENCY) {
197  }
198  else if (lsaType == Lsa::Type::COORDINATE) {
200  }
201  }
202 
203  void
204  incrementInterestSentStats(Lsa::Type lsaType)
205  {
206  if (lsaType == Lsa::Type::NAME) {
208  }
209  else if (lsaType == Lsa::Type::ADJACENCY) {
211  }
212  else if (lsaType == Lsa::Type::COORDINATE) {
214  }
215  }
216 
222  bool
223  isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t lsSeqNo) const
224  {
225  // Is the name in the LSDB and the supplied seq no is the highest so far
226  auto lsaPtr = findLsa(originRouter, lsaType);
227  return lsaPtr ? lsaPtr->getSeqNo() < lsSeqNo : true;
228  }
229 
230  void
231  installLsa(std::shared_ptr<Lsa> lsa);
232 
241  void
242  removeLsa(const ndn::Name& router, Lsa::Type lsaType);
243 
244  void
245  removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);
246 
254  void
255  buildAdjLsa();
256 
258  void
259  buildAndInstallOwnAdjLsa();
260 
265  ndn::scheduler::EventId
266  scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime);
267 
271  void
272  expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
273 
274  bool
275  processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
276  Lsa::Type lsaType, uint64_t seqNo);
277 
278  void
279  expressInterest(const ndn::Name& interestName, uint32_t timeoutCount, uint64_t incomingFaceId,
280  ndn::time::steady_clock::time_point deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
281 
296  void
297  onFetchLsaError(uint32_t errorCode, const std::string& msg,
298  const ndn::Name& interestName, uint32_t retransmitNo,
299  const ndn::time::steady_clock::time_point& deadline,
300  ndn::Name lsaName, uint64_t seqNo);
301 
308  void
309  afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
310 
311  void
312  emitSegmentValidatedSignal(const ndn::Data& data)
313  {
315  }
316 
317  ndn::time::system_clock::time_point
318  getLsaExpirationTimePoint() const
319  {
320  return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
321  }
322 
323 public:
324  ndn::util::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
325  ndn::util::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
326  using AfterLsdbModified = ndn::util::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
327  std::list<ndn::Name>, std::list<ndn::Name>>;
329 
331  ndn::Face& m_face;
332  ndn::Scheduler m_scheduler;
333  ConfParameter& m_confParam;
334 
335  SyncLogicHandler m_sync;
336 
337  LsaContainer m_lsdb;
338 
339  ndn::time::seconds m_lsaRefreshTime;
340  ndn::time::seconds m_adjLsaBuildInterval;
341  const ndn::Name& m_thisRouterPrefix;
342 
343  // Maps the name of an LSA to its highest known sequence number from sync;
344  // Used to stop NLSR from trying to fetch outdated LSAs
345  std::map<ndn::Name, uint64_t> m_highestSeqNo;
346 
347  SequencingManager m_sequencingManager;
348 
349  ndn::util::signal::ScopedConnection m_onNewLsaConnection;
350 
351  std::set<std::shared_ptr<ndn::util::SegmentFetcher>> m_fetchers;
352  ndn::util::Segmenter m_segmenter;
353  ndn::InMemoryStorageFifo m_segmentFifo;
354 
355  bool m_isBuildAdjLsaScheduled;
356  int64_t m_adjBuildCount;
357  ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
358 
359  ndn::InMemoryStoragePersistent m_lsaStorage;
360 
361  static inline const ndn::time::steady_clock::time_point DEFAULT_LSA_RETRIEVAL_DEADLINE =
362  ndn::time::steady_clock::time_point::min();
363 };
364 
365 } // namespace nlsr
366 
367 #endif // NLSR_LSDB_HPP
A class to house all the configuration parameters for NLSR.
uint32_t getRouterDeadInterval() const
std::shared_ptr< T > findLsa(const ndn::Name &router) const
Definition: lsdb.hpp:116
ndn::util::Signal< Lsdb, ndn::Data > afterSegmentValidatedSignal
Definition: lsdb.hpp:325
bool doesLsaExist(const ndn::Name &router, Lsa::Type lsaType)
Returns whether the LSDB contains some LSA.
Definition: lsdb.hpp:69
~Lsdb()
Definition: lsdb.cpp:78
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition: lsdb.hpp:162
void buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
Definition: lsdb.cpp:86
ndn::util::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
Definition: lsdb.hpp:324
AfterLsdbModified onLsdbModified
Definition: lsdb.hpp:328
void writeLog() const
Definition: lsdb.cpp:136
boost::multi_index_container< std::shared_ptr< Lsa >, bmi::indexed_by< bmi::hashed_unique< bmi::tag< byName >, bmi::composite_key< Lsa, bmi::const_mem_fun< Lsa, ndn::Name, &Lsa::getOriginRouterCopy >, 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:157
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Definition: lsdb.cpp:156
bool getIsBuildAdjLsaScheduled() const
Definition: lsdb.hpp:103
void scheduleAdjLsaBuild()
Schedules a build of this router's LSA.
Definition: lsdb.cpp:115
Lsdb(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam)
Definition: lsdb.cpp:34
ndn::util::Signal< Lsdb, std::shared_ptr< Lsa >, LsdbUpdate, std::list< ndn::Name >, std::list< ndn::Name > > AfterLsdbModified
Definition: lsdb.hpp:327
SyncLogicHandler & getSync()
Definition: lsdb.hpp:109
NLSR-to-ChronoSync 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
int operator()(T t) const
Definition: lsdb.hpp:131
int operator()(const ndn::Name &name) const
Definition: lsdb.hpp:123
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE