blob: 4fe528cab87bbd1208a5d18aea00d7f29934b90c [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014 University of Memphis,
4 * Regents of the University of California
5 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
21 *
22 **/
akmhoque31d1d4b2014-05-05 22:08:14 -050023#include "nlsr.hpp"
24#include "lsdb.hpp"
25#include "hello-protocol.hpp"
26#include "utility/name-helper.hpp"
akmhoque674b0b12014-05-20 14:33:28 -050027#include "logger.hpp"
akmhoque31d1d4b2014-05-05 22:08:14 -050028
29namespace nlsr {
30
akmhoque674b0b12014-05-20 14:33:28 -050031INIT_LOGGER("HelloProtocol");
32
akmhoque93f1a072014-06-19 16:24:28 -050033const std::string HelloProtocol::INFO_COMPONENT = "INFO";
34const std::string HelloProtocol::NLSR_COMPONENT = "NLSR";
akmhoque157b0a42014-05-13 00:26:37 -050035
akmhoque31d1d4b2014-05-05 22:08:14 -050036void
37HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
38{
akmhoque674b0b12014-05-20 14:33:28 -050039 _LOG_DEBUG("Expressing Interest :" << interestName);
akmhoque31d1d4b2014-05-05 22:08:14 -050040 ndn::Interest i(interestName);
41 i.setInterestLifetime(ndn::time::seconds(seconds));
42 i.setMustBeFresh(true);
43 m_nlsr.getNlsrFace().expressInterest(i,
Yingdi Yu20e3a6e2014-05-26 23:16:10 -070044 ndn::bind(&HelloProtocol::onContent,
akmhoque31d1d4b2014-05-05 22:08:14 -050045 this,
46 _1, _2),
47 ndn::bind(&HelloProtocol::processInterestTimedOut,
48 this, _1));
49}
50
51void
52HelloProtocol::sendScheduledInterest(uint32_t seconds)
53{
54 std::list<Adjacent> adjList = m_nlsr.getAdjacencyList().getAdjList();
55 for (std::list<Adjacent>::iterator it = adjList.begin(); it != adjList.end();
akmhoque157b0a42014-05-13 00:26:37 -050056 ++it) {
akmhoquec04e7272014-07-02 11:00:14 -050057 if((*it).getFaceId() != 0) {
58 /* interest name: /<neighbor>/NLSR/INFO/<router> */
59 ndn::Name interestName = (*it).getName() ;
60 interestName.append(NLSR_COMPONENT);
61 interestName.append(INFO_COMPONENT);
62 interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
63 expressInterest(interestName,
64 m_nlsr.getConfParameter().getInterestResendTime());
65 }
66 else {
67 registerPrefixes((*it).getName(), (*it).getConnectingFaceUri(),
akmhoquebf11c5f2014-07-21 14:49:47 -050068 (*it).getLinkCost(), ndn::time::milliseconds::max());
akmhoquec04e7272014-07-02 11:00:14 -050069 }
akmhoque31d1d4b2014-05-05 22:08:14 -050070 }
71 scheduleInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
72}
73
74void
75HelloProtocol::scheduleInterest(uint32_t seconds)
76{
77 m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
78 ndn::bind(&HelloProtocol::sendScheduledInterest,
79 this, seconds));
80}
81
82void
83HelloProtocol::processInterest(const ndn::Name& name,
84 const ndn::Interest& interest)
85{
akmhoque93f1a072014-06-19 16:24:28 -050086 /* interest name: /<neighbor>/NLSR/INFO/<router> */
akmhoque31d1d4b2014-05-05 22:08:14 -050087 const ndn::Name interestName = interest.getName();
akmhoque674b0b12014-05-20 14:33:28 -050088 _LOG_DEBUG("Interest Received for Name: " << interestName);
akmhoque157b0a42014-05-13 00:26:37 -050089 if (interestName.get(-2).toUri() != INFO_COMPONENT) {
akmhoque31d1d4b2014-05-05 22:08:14 -050090 return;
91 }
akmhoque157b0a42014-05-13 00:26:37 -050092 ndn::Name neighbor;
93 neighbor.wireDecode(interestName.get(-1).blockFromValue());
akmhoque674b0b12014-05-20 14:33:28 -050094 _LOG_DEBUG("Neighbor: " << neighbor);
akmhoque157b0a42014-05-13 00:26:37 -050095 if (m_nlsr.getAdjacencyList().isNeighbor(neighbor)) {
akmhoque69c9aa92014-07-23 15:15:05 -050096 ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data>();
97 data->setName(ndn::Name(interest.getName()).appendVersion());
98 data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
99 data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
akmhoque157b0a42014-05-13 00:26:37 -0500100 INFO_COMPONENT.size());
akmhoque69c9aa92014-07-23 15:15:05 -0500101 m_nlsr.getKeyChain().sign(*data, m_nlsr.getDefaultCertName());
102 _LOG_DEBUG("Sending out data for name: " << interest.getName());
103 m_nlsr.getNlsrFace().put(*data);
akmhoquec04e7272014-07-02 11:00:14 -0500104 Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
105 if (adjacent->getStatus() == 0) {
106 if(adjacent->getFaceId() != 0){
107 /* interest name: /<neighbor>/NLSR/INFO/<router> */
108 ndn::Name interestName(neighbor);
109 interestName.append(NLSR_COMPONENT);
110 interestName.append(INFO_COMPONENT);
111 interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
112 expressInterest(interestName,
113 m_nlsr.getConfParameter().getInterestResendTime());
114 }
115 else {
116 registerPrefixes(adjacent->getName(), adjacent->getConnectingFaceUri(),
akmhoquebf11c5f2014-07-21 14:49:47 -0500117 adjacent->getLinkCost(), ndn::time::milliseconds::max());
akmhoquec04e7272014-07-02 11:00:14 -0500118 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500119 }
120 }
121}
122
123void
124HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
125{
akmhoque93f1a072014-06-19 16:24:28 -0500126 /* interest name: /<neighbor>/NLSR/INFO/<router> */
akmhoque31d1d4b2014-05-05 22:08:14 -0500127 const ndn::Name interestName(interest.getName());
akmhoque674b0b12014-05-20 14:33:28 -0500128 _LOG_DEBUG("Interest timed out for Name: " << interestName);
akmhoque157b0a42014-05-13 00:26:37 -0500129 if (interestName.get(-2).toUri() != INFO_COMPONENT) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500130 return;
131 }
akmhoque93f1a072014-06-19 16:24:28 -0500132 ndn::Name neighbor = interestName.getPrefix(-3);
akmhoque674b0b12014-05-20 14:33:28 -0500133 _LOG_DEBUG("Neighbor: " << neighbor);
akmhoque31d1d4b2014-05-05 22:08:14 -0500134 m_nlsr.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
135 int status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
136 uint32_t infoIntTimedOutCount =
137 m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
akmhoque674b0b12014-05-20 14:33:28 -0500138 _LOG_DEBUG("Status: " << status);
139 _LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
akmhoque157b0a42014-05-13 00:26:37 -0500140 if ((infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber())) {
akmhoque93f1a072014-06-19 16:24:28 -0500141 /* interest name: /<neighbor>/NLSR/INFO/<router> */
akmhoque31d1d4b2014-05-05 22:08:14 -0500142 ndn::Name interestName(neighbor);
akmhoque93f1a072014-06-19 16:24:28 -0500143 interestName.append(NLSR_COMPONENT);
akmhoque157b0a42014-05-13 00:26:37 -0500144 interestName.append(INFO_COMPONENT);
145 interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
akmhoque31d1d4b2014-05-05 22:08:14 -0500146 expressInterest(interestName,
147 m_nlsr.getConfParameter().getInterestResendTime());
148 }
149 else if ((status == 1) &&
akmhoque157b0a42014-05-13 00:26:37 -0500150 (infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber())) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500151 m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, 0);
152 m_nlsr.incrementAdjBuildCount();
akmhoque157b0a42014-05-13 00:26:37 -0500153 if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
akmhoque674b0b12014-05-20 14:33:28 -0500154 _LOG_DEBUG("Scheduling scheduledAdjLsaBuild");
akmhoque157b0a42014-05-13 00:26:37 -0500155 m_nlsr.setIsBuildAdjLsaSheduled(true);
akmhoque31d1d4b2014-05-05 22:08:14 -0500156 // event here
157 m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
158 ndn::bind(&Lsdb::scheduledAdjLsaBuild,
159 &m_nlsr.getLsdb()));
160 }
161 }
162}
163
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700164void
165HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
166{
akmhoquedfe615f2014-07-27 14:12:21 -0500167 _LOG_DEBUG("Received data for INFO(name): " << data.getName());
168 if (data.getSignature().hasKeyLocator()) {
169 if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
170 _LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
171 }
172 }
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700173 m_nlsr.getValidator().validate(data,
174 ndn::bind(&HelloProtocol::onContentValidated, this, _1),
175 ndn::bind(&HelloProtocol::onContentValidationFailed,
176 this, _1, _2));
177}
akmhoque31d1d4b2014-05-05 22:08:14 -0500178
179void
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700180HelloProtocol::onContentValidated(const ndn::shared_ptr<const ndn::Data>& data)
akmhoque31d1d4b2014-05-05 22:08:14 -0500181{
akmhoque93f1a072014-06-19 16:24:28 -0500182 /* data name: /<neighbor>/NLSR/INFO/<router>/<version> */
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700183 ndn::Name dataName = data->getName();
akmhoquedfe615f2014-07-27 14:12:21 -0500184 _LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
akmhoque157b0a42014-05-13 00:26:37 -0500185 if (dataName.get(-3).toUri() == INFO_COMPONENT) {
akmhoque93f1a072014-06-19 16:24:28 -0500186 ndn::Name neighbor = dataName.getPrefix(-4);
akmhoque31d1d4b2014-05-05 22:08:14 -0500187 int oldStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
akmhoque31d1d4b2014-05-05 22:08:14 -0500188 m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, 1);
189 m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
190 int newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
akmhoque2f423352014-06-03 11:49:35 -0500191 _LOG_DEBUG("Neighbor : " << neighbor);
akmhoque674b0b12014-05-20 14:33:28 -0500192 _LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
akmhoque157b0a42014-05-13 00:26:37 -0500193 // change in Adjacency list
194 if ((oldStatus - newStatus) != 0) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500195 m_nlsr.incrementAdjBuildCount();
akmhoque2f423352014-06-03 11:49:35 -0500196 // Need to schedule event for Adjacency LSA building
akmhoque157b0a42014-05-13 00:26:37 -0500197 if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
akmhoque674b0b12014-05-20 14:33:28 -0500198 _LOG_DEBUG("Scheduling scheduledAdjLsaBuild");
akmhoque157b0a42014-05-13 00:26:37 -0500199 m_nlsr.setIsBuildAdjLsaSheduled(true);
akmhoque31d1d4b2014-05-05 22:08:14 -0500200 // event here
201 m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
202 ndn::bind(&Lsdb::scheduledAdjLsaBuild,
akmhoque157b0a42014-05-13 00:26:37 -0500203 ndn::ref(m_nlsr.getLsdb())));
akmhoque31d1d4b2014-05-05 22:08:14 -0500204 }
205 }
206 }
207}
208
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700209void
210HelloProtocol::onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
211 const std::string& msg)
212{
213 _LOG_DEBUG("Validation Error: " << msg);
214}
215
akmhoquec04e7272014-07-02 11:00:14 -0500216void
akmhoque8e0252b2014-07-07 16:04:44 -0500217HelloProtocol::registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
akmhoquebf11c5f2014-07-21 14:49:47 -0500218 double linkCost, const ndn::time::milliseconds& timeout)
akmhoquec04e7272014-07-02 11:00:14 -0500219{
220 ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
221 broadcastKeyPrefix.append("KEYS");
222 m_nlsr.getFib().registerPrefix(adjName, faceUri, linkCost, timeout,
223 ndn::bind(&HelloProtocol::onRegistrationSuccess,
akmhoque8e0252b2014-07-07 16:04:44 -0500224 this, _1, adjName),
akmhoquec04e7272014-07-02 11:00:14 -0500225 ndn::bind(&HelloProtocol::onRegistrationFailure,
akmhoquedfe615f2014-07-27 14:12:21 -0500226 this, _1, _2, adjName));
akmhoquec04e7272014-07-02 11:00:14 -0500227 m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getChronosyncPrefix(),
228 faceUri, linkCost, timeout);
229 m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getLsaPrefix(),
230 faceUri, linkCost, timeout);
231 m_nlsr.getFib().registerPrefix(broadcastKeyPrefix,
232 faceUri, linkCost, timeout);
akmhoque393d4ff2014-07-16 14:27:03 -0500233 m_nlsr.setStrategies();
akmhoquec04e7272014-07-02 11:00:14 -0500234}
235
236void
237HelloProtocol::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
akmhoque8e0252b2014-07-07 16:04:44 -0500238 const ndn::Name& neighbor)
akmhoquec04e7272014-07-02 11:00:14 -0500239{
240 Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
241 if (adjacent != 0) {
242 adjacent->setFaceId(commandSuccessResult.getFaceId());
243 /* interest name: /<neighbor>/NLSR/INFO/<router> */
244 ndn::Name interestName(neighbor);
245 interestName.append(NLSR_COMPONENT);
246 interestName.append(INFO_COMPONENT);
247 interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
248 expressInterest(interestName,
249 m_nlsr.getConfParameter().getInterestResendTime());
250 }
251}
252
253void
akmhoquedfe615f2014-07-27 14:12:21 -0500254HelloProtocol::onRegistrationFailure(uint32_t code, const std::string& error,
255 const ndn::Name& name)
akmhoquec04e7272014-07-02 11:00:14 -0500256{
257 _LOG_DEBUG(error << " (code: " << code << ")");
akmhoquedfe615f2014-07-27 14:12:21 -0500258 /*
259 * If NLSR can not create face for given faceUri then it will treat this
260 * failure as one INFO interest timed out. So that NLSR can move on with
261 * building Adj Lsa and calculate routing table. NLSR does not build Adj
262 * Lsa unless all the neighbors are ACTIVE or DEAD. For considering the
263 * missconfigured(link) neighbour dead this is required.
264 */
265 Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(name);
266 if (adjacent != 0) {
267 adjacent->setInterestTimedOutNo(adjacent->getInterestTimedOutNo() + 1);
268 int status = adjacent->getStatus();
269 uint32_t infoIntTimedOutCount = adjacent->getInterestTimedOutNo();
270
271 if (infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber()) {
272 if ( status == 1) {
273 adjacent->setStatus(0);
274 }
275 m_nlsr.incrementAdjBuildCount();
276 if (m_nlsr.getIsBuildAdjLsaSheduled() == false) {
277 _LOG_DEBUG("Scheduling scheduledAdjLsaBuild");
278 m_nlsr.setIsBuildAdjLsaSheduled(true);
279 // event here
280 m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
281 ndn::bind(&Lsdb::scheduledAdjLsaBuild,
282 &m_nlsr.getLsdb()));
283 }
284 }
285 }
akmhoquec04e7272014-07-02 11:00:14 -0500286}
287
akmhoque31d1d4b2014-05-05 22:08:14 -0500288} //namespace nlsr