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"
34 
35 #include <ndn-cxx/security/key-chain.hpp>
36 #include <ndn-cxx/util/signal.hpp>
37 #include <ndn-cxx/util/time.hpp>
38 #include <ndn-cxx/util/segment-fetcher.hpp>
39 #include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
40 
41 #include <boost/multi_index_container.hpp>
42 #include <boost/multi_index/hashed_index.hpp>
43 #include <boost/multi_index/composite_key.hpp>
44 
45 #include <PSync/segment-publisher.hpp>
46 
47 namespace nlsr {
48 
49 namespace bmi = boost::multi_index;
50 
51 static 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 
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 
87  void
88  buildAndInstallOwnCoordinateLsa();
89 
90 public:
92  void
93  scheduleAdjLsaBuild();
94 
95  void
96  writeLog() const;
97 
98  /* \brief Process interest which can be either:
99  * 1) Discovery interest from segment fetcher:
100  * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
101  * 2) Interest containing segment number:
102  * /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
103  */
104  void
105  processInterest(const ndn::Name& name, const ndn::Interest& interest);
106 
107  bool
109  {
110  return m_isBuildAdjLsaScheduled;
111  }
112 
115  {
116  return m_sync;
117  }
118 
119  template<typename T>
120  std::shared_ptr<T>
121  findLsa(const ndn::Name& router) const
122  {
123  return std::static_pointer_cast<T>(findLsa(router, T::type()));
124  }
125 
126  struct name_hash {
127  int
128  operator()(const ndn::Name& name) const {
129  return std::hash<ndn::Name>{}(name);
130  }
131  };
132 
134  template<typename T>
135  int
136  operator()(T t) const {
137  return static_cast<int>(t);
138  }
139  };
140 
141  struct byName{};
142  struct byType{};
143 
144  using LsaContainer = boost::multi_index_container<
145  std::shared_ptr<Lsa>,
146  bmi::indexed_by<
147  bmi::hashed_unique<
148  bmi::tag<byName>,
149  bmi::composite_key<
150  Lsa,
151  bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
152  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
153  >,
154  bmi::composite_key_hash<name_hash, enum_class_hash>
155  >,
156  bmi::hashed_non_unique<
157  bmi::tag<byType>,
158  bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
160  >
161  >
162  >;
163 
164  template<typename T>
165  std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
166  LsaContainer::index<Lsdb::byType>::type::iterator>
168  {
169  return m_lsdb.get<byType>().equal_range(T::type());
170  }
171 
173  std::shared_ptr<Lsa>
174  findLsa(const ndn::Name& router, Lsa::Type lsaType) const
175  {
176  auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
177  return it != m_lsdb.end() ? *it : nullptr;
178  }
179 
180  void
181  incrementDataSentStats(Lsa::Type lsaType) {
182  if (lsaType == Lsa::Type::NAME) {
183  lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
184  }
185  else if (lsaType == Lsa::Type::ADJACENCY) {
186  lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
187  }
188  else if (lsaType == Lsa::Type::COORDINATE) {
190  }
191  }
192 
193  void
194  incrementInterestRcvdStats(Lsa::Type lsaType) {
195  if (lsaType == Lsa::Type::NAME) {
197  }
198  else if (lsaType == Lsa::Type::ADJACENCY) {
200  }
201  else if (lsaType == Lsa::Type::COORDINATE) {
203  }
204  }
205 
206  void
207  incrementInterestSentStats(Lsa::Type lsaType) {
208  if (lsaType == Lsa::Type::NAME) {
210  }
211  else if (lsaType == Lsa::Type::ADJACENCY) {
213  }
214  else if (lsaType == Lsa::Type::COORDINATE) {
216  }
217  }
218 
224  bool
225  isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t lsSeqNo)
226  {
227  // Is the name in the LSDB and the supplied seq no is the highest so far
228  auto lsaPtr = findLsa(originRouter, lsaType);
229  return lsaPtr ? lsaPtr->getSeqNo() < lsSeqNo : true;
230  }
231 
232  void
233  installLsa(std::shared_ptr<Lsa> lsa);
234 
243  void
244  removeLsa(const ndn::Name& router, Lsa::Type lsaType);
245 
246  void
247  removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);
248 
256  void
257  buildAdjLsa();
258 
260  void
261  buildAndInstallOwnAdjLsa();
262 
267  ndn::scheduler::EventId
268  scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime);
269 
273  void
274  expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
275 
276  bool
277  processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
278  Lsa::Type lsaType, uint64_t seqNo);
279 
280  void
281  expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
282  ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
283 
298  void
299  onFetchLsaError(uint32_t errorCode, const std::string& msg,
300  const ndn::Name& interestName, uint32_t retransmitNo,
301  const ndn::time::steady_clock::TimePoint& deadline,
302  ndn::Name lsaName, uint64_t seqNo);
303 
310  void
311  afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
312 
313  void
314  emitSegmentValidatedSignal(const ndn::Data& data)
315  {
316  afterSegmentValidatedSignal(data);
317  }
318 
319  ndn::time::system_clock::TimePoint
320  getLsaExpirationTimePoint() const
321  {
322  return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
323  }
324 
325 public:
326  ndn::util::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
327  ndn::util::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
328  using AfterLsdbModified = ndn::util::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
329  std::list<ndn::Name>, std::list<ndn::Name>>;
331 
333  ndn::Face& m_face;
334  ndn::Scheduler m_scheduler;
335 
336  ConfParameter& m_confParam;
337 
338  SyncLogicHandler m_sync;
339 
340  LsaContainer m_lsdb;
341 
342  ndn::time::seconds m_lsaRefreshTime;
343  ndn::time::seconds m_adjLsaBuildInterval;
344  const ndn::Name& m_thisRouterPrefix;
345 
346  // Maps the name of an LSA to its highest known sequence number from sync;
347  // Used to stop NLSR from trying to fetch outdated LSAs
348  std::map<ndn::Name, uint64_t> m_highestSeqNo;
349 
350  SequencingManager m_sequencingManager;
351 
352  ndn::util::signal::ScopedConnection m_onNewLsaConnection;
353 
354  std::set<std::shared_ptr<ndn::util::SegmentFetcher>> m_fetchers;
355  psync::SegmentPublisher m_segmentPublisher;
356 
357  bool m_isBuildAdjLsaScheduled;
358  int64_t m_adjBuildCount;
359  ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
360 
361  ndn::InMemoryStoragePersistent m_lsaStorage;
362 
363  const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component("lsdb");
364  static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
365 };
366 
367 } // namespace nlsr
368 
369 #endif // NLSR_LSDB_HPP
A class to house all the configuration parameters for NLSR.
#define PUBLIC_WITH_TESTS_ELSE_PRIVATE
static constexpr ndn::time::seconds GRACE_PERIOD
Definition: lsdb.hpp:51
ndn::util::Signal< Lsdb, Statistics::PacketType > lsaIncrementSignal
Definition: lsdb.hpp:326
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:162
int operator()(const ndn::Name &name) const
Definition: lsdb.hpp:128
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition: lsdb.hpp:167
ndn::util::Signal< Lsdb, std::shared_ptr< Lsa >, LsdbUpdate, std::list< ndn::Name >, std::list< ndn::Name > > AfterLsdbModified
Definition: lsdb.hpp:329
LsdbUpdate
Definition: lsdb.hpp:53
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
bool getIsBuildAdjLsaScheduled() const
Definition: lsdb.hpp:108
~Lsdb()
Definition: lsdb.hpp:64
AfterLsdbModified onLsdbModified
Definition: lsdb.hpp:330
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
SyncLogicHandler & getSync()
Definition: lsdb.hpp:114
ndn::util::Signal< Lsdb, ndn::Data > afterSegmentValidatedSignal
Definition: lsdb.hpp:327
int operator()(T t) const
Definition: lsdb.hpp:136
std::shared_ptr< T > findLsa(const ndn::Name &router) const
Definition: lsdb.hpp:121