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-2021, 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 
25 #include "conf-parameter.hpp"
26 #include "lsa/lsa.hpp"
27 #include "lsa/name-lsa.hpp"
28 #include "lsa/coordinate-lsa.hpp"
29 #include "lsa/adj-lsa.hpp"
30 #include "sequencing-manager.hpp"
31 #include "test-access-control.hpp"
33 #include "statistics.hpp"
35 
36 #include <ndn-cxx/security/key-chain.hpp>
37 #include <ndn-cxx/util/signal.hpp>
38 #include <ndn-cxx/util/time.hpp>
39 #include <ndn-cxx/util/segment-fetcher.hpp>
40 #include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
41 
42 #include <boost/multi_index_container.hpp>
43 #include <boost/multi_index/hashed_index.hpp>
44 #include <boost/multi_index/composite_key.hpp>
45 
46 #include <PSync/segment-publisher.hpp>
47 
48 namespace nlsr {
49 
50 namespace bmi = boost::multi_index;
51 
52 static constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
53 
54 class Lsdb
55 {
56 public:
57  Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam,
58  NamePrefixTable& namePrefixTable, RoutingTable& routingTable);
59 
61  {
62  for (const auto& sp : m_fetchers) {
63  sp->stop();
64  }
65  }
66 
69  bool
70  doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
71  {
72  return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
73  }
74 
78  void
80 
82  void
84 
86  void
88 
89  template<typename T>
90  void
91  writeLog() const;
92 
93  void
94  writeLog() const;
95 
96  /* \brief Process interest which can be either:
97  * 1) Discovery interest from segment fetcher:
98  * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
99  * 2) Interest containing segment number:
100  * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
101  */
102  void
103  processInterest(const ndn::Name& name, const ndn::Interest& interest);
104 
105  bool
107  {
108  return m_isBuildAdjLsaSheduled;
109  }
110 
113  {
114  return m_sync;
115  }
116 
117  template<typename T>
118  std::shared_ptr<T>
119  findLsa(const ndn::Name& router) const
120  {
121  return std::static_pointer_cast<T>(findLsa(router, T::type()));
122  }
123 
124  struct name_hash {
125  int
126  operator()(const ndn::Name& name) const {
127  return std::hash<ndn::Name>{}(name);
128  }
129  };
130 
132  template<typename T>
133  int
134  operator()(T t) const {
135  return static_cast<int>(t);
136  }
137  };
138 
139  struct byName{};
140  struct byType{};
141 
142  using LsaContainer = boost::multi_index_container<
143  std::shared_ptr<Lsa>,
144  bmi::indexed_by<
145  bmi::hashed_unique<
146  bmi::tag<byName>,
147  bmi::composite_key<
148  Lsa,
149  bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
150  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
151  >,
152  bmi::composite_key_hash<name_hash, enum_class_hash>
153  >,
154  bmi::hashed_non_unique<
155  bmi::tag<byType>,
156  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
158  >
159  >
160  >;
161 
162  template<typename T>
163  std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
164  LsaContainer::index<Lsdb::byType>::type::iterator>
166  {
167  return m_lsdb.get<byType>().equal_range(T::type());
168  }
169 
171  std::shared_ptr<Lsa>
172  findLsa(const ndn::Name& router, Lsa::Type lsaType) const
173  {
174  auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
175  return it != m_lsdb.end() ? *it : nullptr;
176  }
177 
178  void
179  incrementDataSentStats(Lsa::Type lsaType) {
180  if (lsaType == Lsa::Type::NAME) {
182  }
183  else if (lsaType == Lsa::Type::ADJACENCY) {
185  }
186  else if (lsaType == Lsa::Type::COORDINATE) {
188  }
189  }
190 
191  void
192  incrementInterestRcvdStats(Lsa::Type lsaType) {
193  if (lsaType == Lsa::Type::NAME) {
195  }
196  else if (lsaType == Lsa::Type::ADJACENCY) {
198  }
199  else if (lsaType == Lsa::Type::COORDINATE) {
201  }
202  }
203 
204  void
205  incrementInterestSentStats(Lsa::Type lsaType) {
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)
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  bool
242  removeLsa(const ndn::Name& router, Lsa::Type lsaType);
243 
251  void
252  buildAdjLsa();
253 
255  void
256  buildAndInstallOwnAdjLsa();
257 
262  ndn::scheduler::EventId
263  scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime)
264  {
265  return m_scheduler.schedule(expTime + GRACE_PERIOD, [this, lsa] { expireOrRefreshLsa(lsa); });
266  }
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,
280  ndn::time::steady_clock::TimePoint 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::TimePoint& 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::TimePoint
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::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
325  ndn::util::signal::Signal<Lsdb, const ndn::Data&> afterSegmentValidatedSignal;
326 
328  ndn::Face& m_face;
329  ndn::Scheduler m_scheduler;
330 
331  ConfParameter& m_confParam;
332  NamePrefixTable& m_namePrefixTable;
333  RoutingTable& m_routingTable;
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  psync::SegmentPublisher m_segmentPublisher;
353 
354  bool m_isBuildAdjLsaSheduled;
355  int64_t m_adjBuildCount;
356  ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
357 
358  ndn::InMemoryStoragePersistent m_lsaStorage;
359 
360  const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component("lsdb");
361  static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
362 };
363 
364 } // namespace nlsr
365 
366 #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:119
bool doesLsaExist(const ndn::Name &router, Lsa::Type lsaType)
Returns whether the LSDB contains some LSA.
Definition: lsdb.hpp:70
~Lsdb()
Definition: lsdb.hpp:60
bool getIsBuildAdjLsaSheduled() const
Definition: lsdb.hpp:106
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition: lsdb.hpp:165
void buildAndInstallOwnNameLsa()
Builds a name LSA for this router and then installs it into the LSDB.
Definition: lsdb.cpp:65
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:160
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Definition: lsdb.cpp:142
void buildAndInstallOwnCoordinateLsa()
Builds a cor. LSA for this router and installs it into the LSDB.
Definition: lsdb.cpp:77
Lsdb(ndn::Face &face, ndn::KeyChain &keyChain, ConfParameter &confParam, NamePrefixTable &namePrefixTable, RoutingTable &routingTable)
Definition: lsdb.cpp:35
void scheduleAdjLsaBuild()
Schedules a build of this router's LSA.
Definition: lsdb.cpp:94
ndn::util::signal::Signal< Lsdb, const ndn::Data & > afterSegmentValidatedSignal
Definition: lsdb.hpp:325
void writeLog() const
Definition: lsdb.cpp:116
ndn::util::signal::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
Definition: lsdb.hpp:324
SyncLogicHandler & getSync()
Definition: lsdb.hpp:112
NLSR-to-ChronoSync interaction point.
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California,...
static constexpr ndn::time::seconds GRACE_PERIOD
Definition: lsdb.hpp:52
int operator()(T t) const
Definition: lsdb.hpp:134
int operator()(const ndn::Name &name) const
Definition: lsdb.hpp:126
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE