hello-protocol.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "hello-protocol.hpp"
21 
22 #include "hello-protocol.hpp"
23 #include "nlsr.hpp"
24 #include "lsdb.hpp"
25 #include "utility/name-helper.hpp"
26 #include "logger.hpp"
27 
28 namespace nlsr {
29 
30 INIT_LOGGER("HelloProtocol");
31 
32 const std::string HelloProtocol::INFO_COMPONENT = "INFO";
33 const std::string HelloProtocol::NLSR_COMPONENT = "NLSR";
34 
35 HelloProtocol::HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler)
36  : m_nlsr(nlsr)
37  , m_scheduler(scheduler)
38 {
39 }
40 
41 void
42 HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
43 {
44  NLSR_LOG_DEBUG("Expressing Interest :" << interestName);
45  ndn::Interest i(interestName);
46  i.setInterestLifetime(ndn::time::seconds(seconds));
47  i.setMustBeFresh(true);
48  m_nlsr.getNlsrFace().expressInterest(i,
49  std::bind(&HelloProtocol::onContent,
50  this,
51  _1, _2),
52  std::bind(&HelloProtocol::processInterestTimedOut, // Nack
53  this, _1),
54  std::bind(&HelloProtocol::processInterestTimedOut,
55  this, _1));
56 
57  // increment SENT_HELLO_INTEREST
59 }
60 
61 void
63 {
64  std::list<Adjacent> adjList = m_nlsr.getAdjacencyList().getAdjList();
65  for (std::list<Adjacent>::iterator it = adjList.begin(); it != adjList.end();
66  ++it) {
67  // If this adjacency has a Face, just proceed as usual.
68  if((*it).getFaceId() != 0) {
69  // interest name: /<neighbor>/NLSR/INFO/<router>
70  ndn::Name interestName = (*it).getName() ;
71  interestName.append(NLSR_COMPONENT);
72  interestName.append(INFO_COMPONENT);
73  interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
74  expressInterest(interestName,
76  NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
77  }
78  }
80 }
81 
82 void
84 {
85  NLSR_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
86 
87  m_scheduler.scheduleEvent(ndn::time::seconds(seconds),
88  std::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
89 }
90 
91 void
92 HelloProtocol::processInterest(const ndn::Name& name,
93  const ndn::Interest& interest)
94 {
95  // interest name: /<neighbor>/NLSR/INFO/<router>
96  const ndn::Name interestName = interest.getName();
97 
98  // increment RCV_HELLO_INTEREST
100 
101  NLSR_LOG_DEBUG("Interest Received for Name: " << interestName);
102  if (interestName.get(-2).toUri() != INFO_COMPONENT) {
103  NLSR_LOG_DEBUG("INFO_COMPONENT not found or interestName: " << interestName
104  << " does not match expression");
105  return;
106  }
107 
108  ndn::Name neighbor;
109  neighbor.wireDecode(interestName.get(-1).blockFromValue());
110  NLSR_LOG_DEBUG("Neighbor: " << neighbor);
111  if (m_nlsr.getAdjacencyList().isNeighbor(neighbor)) {
112  std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
113  data->setName(ndn::Name(interest.getName()).appendVersion());
114  data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
115  data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
116  INFO_COMPONENT.size());
117 
118  m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
119 
120  NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
121 
122  m_nlsr.getNlsrFace().put(*data);
123  // increment SENT_HELLO_DATA
125 
126  auto adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
127  // If this neighbor was previously inactive, send our own hello interest, too
128  if (adjacent->getStatus() == Adjacent::STATUS_INACTIVE) {
129  // We can only do that if the neighbor currently has a face.
130  if(adjacent->getFaceId() != 0){
131  // interest name: /<neighbor>/NLSR/INFO/<router>
132  ndn::Name interestName(neighbor);
133  interestName.append(NLSR_COMPONENT);
134  interestName.append(INFO_COMPONENT);
135  interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
136  expressInterest(interestName,
138  }
139  }
140  }
141 }
142 
143 void
144 HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
145 {
146  // interest name: /<neighbor>/NLSR/INFO/<router>
147  const ndn::Name interestName(interest.getName());
148  NLSR_LOG_DEBUG("Interest timed out for Name: " << interestName);
149  if (interestName.get(-2).toUri() != INFO_COMPONENT) {
150  return;
151  }
152  ndn::Name neighbor = interestName.getPrefix(-3);
153  NLSR_LOG_DEBUG("Neighbor: " << neighbor);
155 
156  Adjacent::Status status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
157 
158  uint32_t infoIntTimedOutCount =
159  m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
160  NLSR_LOG_DEBUG("Status: " << status);
161  NLSR_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
162  if (infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber()) {
163  // interest name: /<neighbor>/NLSR/INFO/<router>
164  ndn::Name interestName(neighbor);
165  interestName.append(NLSR_COMPONENT);
166  interestName.append(INFO_COMPONENT);
167  interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
168  NLSR_LOG_DEBUG("Resending interest: " << interestName);
169  expressInterest(interestName,
171  }
172  else if ((status == Adjacent::STATUS_ACTIVE) &&
173  (infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber())) {
175 
176  NLSR_LOG_DEBUG("Neighbor: " << neighbor << " status changed to INACTIVE");
177 
178  m_nlsr.getLsdb().scheduleAdjLsaBuild();
179  }
180 }
181 
182  // This is the first function that incoming Hello data will
183  // see. This checks if the data appears to be signed, and passes it
184  // on to validate the content of the data.
185 void
186 HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
187 {
188  NLSR_LOG_DEBUG("Received data for INFO(name): " << data.getName());
189  if (data.getSignature().hasKeyLocator()) {
190  if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
191  NLSR_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
192  }
193  }
194  m_nlsr.getValidator().validate(data,
195  std::bind(&HelloProtocol::onContentValidated, this, _1),
196  std::bind(&HelloProtocol::onContentValidationFailed,
197  this, _1, _2));
198 }
199 
200 void
201 HelloProtocol::onContentValidated(const ndn::Data& data)
202 {
203  // data name: /<neighbor>/NLSR/INFO/<router>/<version>
204  ndn::Name dataName = data.getName();
205  NLSR_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
206 
207  if (dataName.get(-3).toUri() == INFO_COMPONENT) {
208  ndn::Name neighbor = dataName.getPrefix(-4);
209 
210  Adjacent::Status oldStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
212  m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
213  Adjacent::Status newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
214 
215  NLSR_LOG_DEBUG("Neighbor : " << neighbor);
216  NLSR_LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
217  // change in Adjacency list
218  if ((oldStatus - newStatus) != 0) {
221  }
222  else {
223  m_nlsr.getLsdb().scheduleAdjLsaBuild();
224  }
225  }
226  }
227  // increment RCV_HELLO_DATA
229 }
230 
231 void
232 HelloProtocol::onContentValidationFailed(const ndn::Data& data,
233  const ndn::security::v2::ValidationError& ve)
234 {
235  NLSR_LOG_DEBUG("Validation Error: " << ve);
236 }
237 
238 } // namespace nlsr
uint32_t getInterestResendTime() const
void setTimedOutInterestCount(const ndn::Name &neighbor, uint32_t count)
void scheduleAdjLsaBuild()
Schedules a build of this router&#39;s LSA.
Definition: lsdb.cpp:589
ConfParameter & getConfParameter()
Definition: nlsr.hpp:133
ndn::util::signal::Signal< HelloProtocol, Statistics::PacketType > hpIncrementSignal
Adjacent::Status getStatusOfNeighbor(const ndn::Name &neighbor)
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:41
uint32_t getInfoInterestInterval() const
const ndn::Name & getRouterPrefix() const
RoutingTable & getRoutingTable()
Definition: nlsr.hpp:163
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California.
void expressInterest(const ndn::Name &interestNamePrefix, uint32_t seconds)
Sends a Hello Interest packet.
void scheduleInterest(uint32_t seconds)
Schedules a Hello Interest event.
#define INIT_LOGGER(name)
Definition: logger.hpp:35
uint32_t getInterestRetryNumber() const
AdjacencyList & getAdjacencyList()
Definition: nlsr.hpp:139
void scheduleRoutingTableCalculation(Nlsr &pnlsr)
Schedules a calculation event in the event scheduler only if one isn&#39;t already scheduled.
ndn::security::v2::KeyChain & getKeyChain()
Definition: nlsr.hpp:329
void processInterest(const ndn::Name &name, const ndn::Interest &interest)
Processes a Hello Interest from a neighbor.
bool isNeighbor(const ndn::Name &adjName)
void sendScheduledInterest(uint32_t seconds)
Sends Hello Interests to all neighbors.
int32_t getTimedOutInterestCount(const ndn::Name &neighbor)
HelloProtocol(Nlsr &nlsr, ndn::Scheduler &scheduler)
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
Lsdb & getLsdb()
Definition: nlsr.hpp:157
AdjacencyList::iterator findAdjacent(const ndn::Name &adjName)
ndn::Face & getNlsrFace()
Definition: nlsr.hpp:151
int32_t getHyperbolicState() const
const ndn::security::SigningInfo & getSigningInfo()
Definition: nlsr.hpp:341
ndn::security::ValidatorConfig & getValidator()
Definition: nlsr.hpp:306
void incrementTimedOutInterestCount(const ndn::Name &neighbor)
std::list< Adjacent > & getAdjList()
void setStatusOfNeighbor(const ndn::Name &neighbor, Adjacent::Status status)