lsa-segment-storage.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "lsa-segment-storage.hpp"
23 #include "logger.hpp"
24 #include "lsa.hpp"
25 #include "utility/name-helper.hpp"
26 #include "conf-parameter.hpp"
27 
28 namespace nlsr {
29 
30 INIT_LOGGER(LsaSegmentStorage);
31 
32 LsaSegmentStorage::LsaSegmentStorage(ndn::Scheduler& scheduler)
33  : m_scheduler(scheduler)
34 {
35 }
36 
37 void
38 LsaSegmentStorage::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
39 {
40  fetcher.afterSegmentValidated.connect(std::bind(&LsaSegmentStorage::afterFetcherSignalEmitted,
41  this, _1));
42 }
43 
44 const ndn::Data*
45 LsaSegmentStorage::getLsaSegment(const ndn::Interest& interest)
46 {
47  ndn::Name lsaSegmentsKey = interest.getName();
48 
49  // If this is the first interest then it does not contain the segment number,
50  // so need to append zero segment component at the end to match with the data
51  if (lsaSegmentsKey.size() > 0) {
52  if (!lsaSegmentsKey.get(-1).isSegment()) {
53  lsaSegmentsKey.appendSegment(0);
54  }
55 
56  auto it = m_lsaSegments.find(lsaSegmentsKey);
57  if (it == m_lsaSegments.end()) {
58  NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " cannot be found in the lsa storage");
59 
60  return nullptr;
61  }
62  else {
63  NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " is in the storage.");
64  return &(it->second);
65  }
66  }
67  else {
68  NLSR_LOG_ERROR("Received interest has empty name.");
69  return nullptr;
70  }
71 }
72 
73 void
74 LsaSegmentStorage::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
75 {
76  NLSR_LOG_TRACE("Received a LSA segment: " << lsaSegment.getName());
77 
78  // lsaSegmentName is /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
79  auto lsaSegmentName = lsaSegment.getName();
80 
81  if (lsaSegmentName.size() > 0) {
82  // lsaSegmentsKey is /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
83  ndn::Name lsaSegmentsKey(lsaSegmentName.getPrefix(lsaSegmentName.size() - 2));
84  lsaSegmentsKey.append(lsaSegmentName.get(-1));
85 
86  // No need to store same LSA multiple time
87  if (m_lsaSegments.find(lsaSegmentsKey) == m_lsaSegments.end()) {
88  NLSR_LOG_TRACE("Received LSA segment is new. Storing it in the storage.");
89  NLSR_LOG_TRACE("LSA data segment's name: " << lsaSegmentName);
90 
91  // Delete the same LSA with lower sequence number
92  deleteOldLsas(lsaSegmentName);
93 
94  m_lsaSegments[lsaSegmentsKey] = lsaSegment;
95  }
96  else {
97  NLSR_LOG_TRACE("The received segment is already in the storage.");
98  }
99 
100  ndn::time::seconds expirationTime(LSA_REFRESH_TIME_DEFAULT);
101 
102  // schedule the segment deletion
103  scheduleLsaSegmentDeletion(lsaSegmentsKey, expirationTime);
104  }
105  else {
106  NLSR_LOG_ERROR("The received LSA segment has empty name.");
107  }
108 }
109 
110 void
111 LsaSegmentStorage::deleteOldLsas(const ndn::Name& newLsaName)
112 {
113  auto newLsaKey = newLsaName.getPrefix(newLsaName.size() - 3);
114  auto newSeqNo = newLsaName.get(-3).toNumber();
115 
116  std::vector<decltype(m_lsaSegments)::key_type> lsaToDelete;
117 
118  for (const auto& segment : m_lsaSegments) {
119  ndn::Name segmentKey = segment.first;
120  auto oldSeqNo = segmentKey.get(-2).toNumber();
121  auto existingLsaKey = segmentKey.getPrefix(segmentKey.size() - 2);
122 
123  if (newLsaKey == existingLsaKey) {
124  if (newSeqNo > oldSeqNo) { // in the key the second last component is the sequence number
125  NLSR_LOG_TRACE("Outdated LSA: " << segmentKey << " with seq no: " <<
126  oldSeqNo << " is deleted.");
127  lsaToDelete.push_back(segmentKey);
128  }
129  }
130  }
131 
132  for (const auto& segmentKey : lsaToDelete) {
133  m_lsaSegments.erase(segmentKey);
134  }
135 }
136 
137 void
138 LsaSegmentStorage::scheduleLsaSegmentDeletion(const ndn::Name& lsaSegmentsKey,
139  ndn::time::seconds expirationTime)
140 {
141  NLSR_LOG_TRACE("Scheduling LSA segment deletion for "
142  << lsaSegmentsKey << " in: " << expirationTime);
143  m_scheduler.scheduleEvent(expirationTime,
144  [lsaSegmentsKey, this] {
145  m_lsaSegments.erase(lsaSegmentsKey);
146  });
147 }
148 
149 } // namespace nlsr
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define INIT_LOGGER(name)
Definition: logger.hpp:35
void connectToFetcher(ndn::util::SegmentFetcher &fetcher)
Get connected to the signal emitted by SegmentFetcher.
const ndn::Data * getLsaSegment(const ndn::Interest &interest)
Returns an LSA segment for an interest from LsaSegmentStorage.
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
LsaSegmentStorage(ndn::Scheduler &scheduler)
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:37