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-2020, 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 #include <utility>
49 #include <boost/cstdint.hpp>
50 
51 namespace nlsr {
52 
53 namespace bmi = boost::multi_index;
54 using namespace ndn::literals::time_literals;
55 
56 static constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
57 
58 class Lsdb
59 {
60 public:
61  Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam,
62  NamePrefixTable& namePrefixTable, RoutingTable& routingTable);
63 
65  {
66  for (const auto& sp : m_fetchers) {
67  sp->stop();
68  }
69  }
70 
73  bool
74  doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
75  {
76  return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
77  }
78 
82  void
83  buildAndInstallOwnNameLsa();
84 
86  void
87  buildAndInstallOwnCoordinateLsa();
88 
90  void
91  scheduleAdjLsaBuild();
92 
93  template<typename T>
94  void
95  writeLog() const;
96 
97  void
98  writeLog() const;
99 
100  /* \brief Process interest which can be either:
101  * 1) Discovery interest from segment fetcher:
102  * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
103  * 2) Interest containing segment number:
104  * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
105  */
106  void
107  processInterest(const ndn::Name& name, const ndn::Interest& interest);
108 
109  bool
111  {
112  return m_isBuildAdjLsaSheduled;
113  }
114 
117  {
118  return m_sync;
119  }
120 
121  template<typename T>
122  std::shared_ptr<T>
123  findLsa(const ndn::Name& router) const
124  {
125  return std::static_pointer_cast<T>(findLsa(router, T::type()));
126  }
127 
128  struct name_hash {
129  int
130  operator()(const ndn::Name& name) const {
131  return std::hash<ndn::Name>{}(name);
132  }
133  };
134 
136  template<typename T>
137  int
138  operator()(T t) const {
139  return static_cast<int>(t);
140  }
141  };
142 
143  struct byName{};
144  struct byType{};
145 
146  using LsaContainer = boost::multi_index_container<
147  std::shared_ptr<Lsa>,
148  bmi::indexed_by<
149  bmi::hashed_unique<
150  bmi::tag<byName>,
151  bmi::composite_key<
152  Lsa,
153  bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
154  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
155  >,
156  bmi::composite_key_hash<name_hash, enum_class_hash>
157  >,
158  bmi::hashed_non_unique<
159  bmi::tag<byType>,
160  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
162  >
163  >
164  >;
165 
166  template<typename T>
167  std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
168  LsaContainer::index<Lsdb::byType>::type::iterator>
170  {
171  return m_lsdb.get<byType>().equal_range(T::type());
172  }
173 
175  std::shared_ptr<Lsa>
176  findLsa(const ndn::Name& router, Lsa::Type lsaType) const
177  {
178  auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
179  return it != m_lsdb.end() ? *it : nullptr;
180  }
181 
182  void
183  incrementDataSentStats(Lsa::Type lsaType) {
184  if (lsaType == Lsa::Type::NAME) {
185  lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
186  }
187  else if (lsaType == Lsa::Type::ADJACENCY) {
188  lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
189  }
190  else if (lsaType == Lsa::Type::COORDINATE) {
192  }
193  }
194 
195  void
196  incrementInterestRcvdStats(Lsa::Type lsaType) {
197  if (lsaType == Lsa::Type::NAME) {
199  }
200  else if (lsaType == Lsa::Type::ADJACENCY) {
202  }
203  else if (lsaType == Lsa::Type::COORDINATE) {
205  }
206  }
207 
208  void
209  incrementInterestSentStats(Lsa::Type lsaType) {
210  if (lsaType == Lsa::Type::NAME) {
212  }
213  else if (lsaType == Lsa::Type::ADJACENCY) {
215  }
216  else if (lsaType == Lsa::Type::COORDINATE) {
218  }
219  }
220 
226  bool
227  isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t lsSeqNo)
228  {
229  // Is the name in the LSDB and the supplied seq no is the highest so far
230  auto lsaPtr = findLsa(originRouter, lsaType);
231  return lsaPtr ? lsaPtr->getSeqNo() < lsSeqNo : true;
232  }
233 
234  void
235  installLsa(shared_ptr<Lsa> lsa);
236 
245  bool
246  removeLsa(const ndn::Name& router, Lsa::Type lsaType);
247 
255  void
256  buildAdjLsa();
257 
259  void
260  buildAndInstallOwnAdjLsa();
261 
266  ndn::scheduler::EventId
267  scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime)
268  {
269  return m_scheduler.schedule(expTime + GRACE_PERIOD, [this, lsa] { expireOrRefreshLsa(lsa); });
270  }
271 
275  void
276  expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
277 
278  bool
279  processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
280  Lsa::Type lsaType, uint64_t seqNo);
281 
282  void
283  expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
284  ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
285 
300  void
301  onFetchLsaError(uint32_t errorCode, const std::string& msg,
302  const ndn::Name& interestName, uint32_t retransmitNo,
303  const ndn::time::steady_clock::TimePoint& deadline,
304  ndn::Name lsaName, uint64_t seqNo);
305 
312  void
313  afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
314 
315  void
316  emitSegmentValidatedSignal(const ndn::Data& data)
317  {
318  afterSegmentValidatedSignal(data);
319  }
320 
321  ndn::time::system_clock::TimePoint
322  getLsaExpirationTimePoint() const
323  {
324  return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
325  }
326 
327 public:
328  ndn::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
329  ndn::util::signal::Signal<Lsdb, const ndn::Data&> afterSegmentValidatedSignal;
330 
332  ndn::Face& m_face;
333  ndn::Scheduler m_scheduler;
334 
335  ConfParameter& m_confParam;
336  NamePrefixTable& m_namePrefixTable;
337  RoutingTable& m_routingTable;
338 
339  SyncLogicHandler m_sync;
340 
341  LsaContainer m_lsdb;
342 
343  ndn::time::seconds m_lsaRefreshTime;
344  ndn::time::seconds m_adjLsaBuildInterval;
345  const ndn::Name& m_thisRouterPrefix;
346 
347  // Maps the name of an LSA to its highest known sequence number from sync;
348  // Used to stop NLSR from trying to fetch outdated LSAs
349  std::map<ndn::Name, uint64_t> m_highestSeqNo;
350 
351  SequencingManager m_sequencingManager;
352 
353  ndn::util::signal::ScopedConnection m_onNewLsaConnection;
354 
355  std::set<std::shared_ptr<ndn::util::SegmentFetcher>> m_fetchers;
356  psync::SegmentPublisher m_segmentPublisher;
357 
358  bool m_isBuildAdjLsaSheduled;
359  int64_t m_adjBuildCount;
360  ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
361 
362  ndn::InMemoryStoragePersistent m_lsaStorage;
363 
364  const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component("lsdb");
365  static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
366 };
367 
368 } // namespace nlsr
369 
370 #endif // NLSR_LSDB_HPP
A class to house all the configuration parameters for NLSR.
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE
bool getIsBuildAdjLsaSheduled() const
Definition: lsdb.hpp:110
static constexpr ndn::time::seconds GRACE_PERIOD
Definition: lsdb.hpp:56
const ndn::Name::Component NAME_COMPONENT
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:164
int operator()(const ndn::Name &name) const
Definition: lsdb.hpp:130
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition: lsdb.hpp:169
ndn::util::signal::Signal< Lsdb, const ndn::Data & > afterSegmentValidatedSignal
Definition: lsdb.hpp:329
NLSR-to-ChronoSync interaction point.
bool doesLsaExist(const ndn::Name &router, Lsa::Type lsaType)
Returns whether the LSDB contains some LSA.
Definition: lsdb.hpp:74
~Lsdb()
Definition: lsdb.hpp:64
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
ndn::util::signal::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
Definition: lsdb.hpp:328
SyncLogicHandler & getSync()
Definition: lsdb.hpp:116
int operator()(T t) const
Definition: lsdb.hpp:138
std::shared_ptr< T > findLsa(const ndn::Name &router) const
Definition: lsdb.hpp:123