blob: c0689056676e6eb055b7ad65d7e28566da2b4bfc [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoaf7a2112019-03-19 14:55:20 -04002/*
Ashlesh Gawande85998a12017-12-07 22:22:13 -06003 * Copyright (c) 2014-2019, The University of Memphis,
Nick Gordonf8b5bcd2016-08-11 15:06:50 -05004 * Regents of the University of California
akmhoque3d06e792014-05-27 16:23:20 -05005 *
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/>.
akmhoque3d06e792014-05-27 16:23:20 -050019 **/
Junxiao Shi63bd0342016-08-17 16:57:14 +000020
Alejandro Gil Torrese0d20482016-03-06 23:56:19 -060021#include "hello-protocol.hpp"
akmhoque31d1d4b2014-05-05 22:08:14 -050022#include "nlsr.hpp"
23#include "lsdb.hpp"
akmhoque31d1d4b2014-05-05 22:08:14 -050024#include "utility/name-helper.hpp"
akmhoque674b0b12014-05-20 14:33:28 -050025#include "logger.hpp"
akmhoque31d1d4b2014-05-05 22:08:14 -050026
27namespace nlsr {
28
dmcoomescf8d0ed2017-02-21 11:39:01 -060029INIT_LOGGER(HelloProtocol);
akmhoque674b0b12014-05-20 14:33:28 -050030
akmhoque93f1a072014-06-19 16:24:28 -050031const std::string HelloProtocol::INFO_COMPONENT = "INFO";
Ashlesh Gawandecba0ae22018-03-27 17:57:56 -050032const std::string HelloProtocol::NLSR_COMPONENT = "nlsr";
akmhoque157b0a42014-05-13 00:26:37 -050033
Ashlesh Gawande85998a12017-12-07 22:22:13 -060034HelloProtocol::HelloProtocol(ndn::Face& face, ndn::KeyChain& keyChain,
35 ndn::security::SigningInfo& signingInfo,
36 ConfParameter& confParam, RoutingTable& routingTable,
37 Lsdb& lsdb)
38 : m_face(face)
39 , m_scheduler(m_face.getIoService())
40 , m_keyChain(keyChain)
41 , m_signingInfo(signingInfo)
42 , m_confParam(confParam)
43 , m_routingTable(routingTable)
44 , m_lsdb(lsdb)
Nick Gordone18296c2017-10-11 16:05:24 -050045{
46}
47
akmhoque31d1d4b2014-05-05 22:08:14 -050048void
49HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
50{
dmcoomes5bcb39e2017-10-31 15:07:55 -050051 NLSR_LOG_DEBUG("Expressing Interest :" << interestName);
Ashlesh Gawande85998a12017-12-07 22:22:13 -060052 ndn::Interest interest(interestName);
53 interest.setInterestLifetime(ndn::time::seconds(seconds));
54 interest.setMustBeFresh(true);
55 interest.setCanBePrefix(true);
56 m_face.expressInterest(interest,
57 std::bind(&HelloProtocol::onContent, this, _1, _2),
58 [this] (const ndn::Interest& interest, const ndn::lp::Nack& nack)
59 {
60 NDN_LOG_TRACE("Received Nack with reason " << nack.getReason());
61 NDN_LOG_TRACE("Treating as timeout");
62 processInterestTimedOut(interest);
63 },
64 std::bind(&HelloProtocol::processInterestTimedOut, this, _1));
Alejandro Gil Torrese0d20482016-03-06 23:56:19 -060065
66 // increment SENT_HELLO_INTEREST
67 hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
akmhoque31d1d4b2014-05-05 22:08:14 -050068}
69
70void
Ashlesh Gawande85998a12017-12-07 22:22:13 -060071HelloProtocol::sendScheduledInterest()
akmhoque31d1d4b2014-05-05 22:08:14 -050072{
Ashlesh Gawande85998a12017-12-07 22:22:13 -060073 for (const auto& adjacent : m_confParam.getAdjacencyList().getAdjList()) {
Nick G97e34942016-07-11 14:46:27 -050074 // If this adjacency has a Face, just proceed as usual.
Ashlesh Gawande85998a12017-12-07 22:22:13 -060075 if(adjacent.getFaceId() != 0) {
dmcoomes9f936662017-03-02 10:33:09 -060076 // interest name: /<neighbor>/NLSR/INFO/<router>
Ashlesh Gawande85998a12017-12-07 22:22:13 -060077 ndn::Name interestName = adjacent.getName() ;
akmhoquec04e7272014-07-02 11:00:14 -050078 interestName.append(NLSR_COMPONENT);
79 interestName.append(INFO_COMPONENT);
Ashlesh Gawande85998a12017-12-07 22:22:13 -060080 interestName.append(m_confParam.getRouterPrefix().wireEncode());
81 expressInterest(interestName, m_confParam.getInterestResendTime());
dmcoomes5bcb39e2017-10-31 15:07:55 -050082 NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
akmhoquec04e7272014-07-02 11:00:14 -050083 }
akmhoque31d1d4b2014-05-05 22:08:14 -050084 }
Ashlesh Gawande85998a12017-12-07 22:22:13 -060085 scheduleInterest(m_confParam.getInfoInterestInterval());
akmhoque31d1d4b2014-05-05 22:08:14 -050086}
87
88void
89HelloProtocol::scheduleInterest(uint32_t seconds)
90{
dmcoomes5bcb39e2017-10-31 15:07:55 -050091 NLSR_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
Vince Lehman50df6b72015-03-03 12:06:40 -060092
Davide Pesaventoaf7a2112019-03-19 14:55:20 -040093 m_scheduler.schedule(ndn::time::seconds(seconds), [this] { sendScheduledInterest(); });
akmhoque31d1d4b2014-05-05 22:08:14 -050094}
95
96void
97HelloProtocol::processInterest(const ndn::Name& name,
98 const ndn::Interest& interest)
99{
dmcoomes9f936662017-03-02 10:33:09 -0600100 // interest name: /<neighbor>/NLSR/INFO/<router>
akmhoque31d1d4b2014-05-05 22:08:14 -0500101 const ndn::Name interestName = interest.getName();
Alejandro Gil Torrese0d20482016-03-06 23:56:19 -0600102
103 // increment RCV_HELLO_INTEREST
104 hpIncrementSignal(Statistics::PacketType::RCV_HELLO_INTEREST);
105
dmcoomes5bcb39e2017-10-31 15:07:55 -0500106 NLSR_LOG_DEBUG("Interest Received for Name: " << interestName);
akmhoque157b0a42014-05-13 00:26:37 -0500107 if (interestName.get(-2).toUri() != INFO_COMPONENT) {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500108 NLSR_LOG_DEBUG("INFO_COMPONENT not found or interestName: " << interestName
dmcoomes9eaf3f42017-02-21 11:39:01 -0600109 << " does not match expression");
akmhoque31d1d4b2014-05-05 22:08:14 -0500110 return;
111 }
Alejandro Gil Torrese0d20482016-03-06 23:56:19 -0600112
akmhoque157b0a42014-05-13 00:26:37 -0500113 ndn::Name neighbor;
114 neighbor.wireDecode(interestName.get(-1).blockFromValue());
dmcoomes5bcb39e2017-10-31 15:07:55 -0500115 NLSR_LOG_DEBUG("Neighbor: " << neighbor);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600116 if (m_confParam.getAdjacencyList().isNeighbor(neighbor)) {
dmcoomes9f936662017-03-02 10:33:09 -0600117 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
akmhoque69c9aa92014-07-23 15:15:05 -0500118 data->setName(ndn::Name(interest.getName()).appendVersion());
119 data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
120 data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600121 INFO_COMPONENT.size());
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500122
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600123 m_keyChain.sign(*data, m_signingInfo);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500124
dmcoomes5bcb39e2017-10-31 15:07:55 -0500125 NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500126
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600127 m_face.put(*data);
Alejandro Gil Torrese0d20482016-03-06 23:56:19 -0600128 // increment SENT_HELLO_DATA
129 hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
Nick Gordonc780a692017-04-27 18:03:02 -0500130
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600131 auto adjacent = m_confParam.getAdjacencyList().findAdjacent(neighbor);
Nick G97e34942016-07-11 14:46:27 -0500132 // If this neighbor was previously inactive, send our own hello interest, too
Vince Lehmancb76ade2014-08-28 21:24:41 -0500133 if (adjacent->getStatus() == Adjacent::STATUS_INACTIVE) {
Nick G97e34942016-07-11 14:46:27 -0500134 // We can only do that if the neighbor currently has a face.
akmhoquec04e7272014-07-02 11:00:14 -0500135 if(adjacent->getFaceId() != 0){
dmcoomes9f936662017-03-02 10:33:09 -0600136 // interest name: /<neighbor>/NLSR/INFO/<router>
akmhoquec04e7272014-07-02 11:00:14 -0500137 ndn::Name interestName(neighbor);
138 interestName.append(NLSR_COMPONENT);
139 interestName.append(INFO_COMPONENT);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600140 interestName.append(m_confParam.getRouterPrefix().wireEncode());
141 expressInterest(interestName, m_confParam.getInterestResendTime());
akmhoquec04e7272014-07-02 11:00:14 -0500142 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500143 }
144 }
145}
146
147void
148HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
149{
dmcoomes9f936662017-03-02 10:33:09 -0600150 // interest name: /<neighbor>/NLSR/INFO/<router>
akmhoque31d1d4b2014-05-05 22:08:14 -0500151 const ndn::Name interestName(interest.getName());
dmcoomes5bcb39e2017-10-31 15:07:55 -0500152 NLSR_LOG_DEBUG("Interest timed out for Name: " << interestName);
akmhoque157b0a42014-05-13 00:26:37 -0500153 if (interestName.get(-2).toUri() != INFO_COMPONENT) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500154 return;
155 }
akmhoque93f1a072014-06-19 16:24:28 -0500156 ndn::Name neighbor = interestName.getPrefix(-3);
dmcoomes5bcb39e2017-10-31 15:07:55 -0500157 NLSR_LOG_DEBUG("Neighbor: " << neighbor);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600158 m_confParam.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
Vince Lehmancb76ade2014-08-28 21:24:41 -0500159
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600160 Adjacent::Status status = m_confParam.getAdjacencyList().getStatusOfNeighbor(neighbor);
Vince Lehmancb76ade2014-08-28 21:24:41 -0500161
akmhoque31d1d4b2014-05-05 22:08:14 -0500162 uint32_t infoIntTimedOutCount =
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600163 m_confParam.getAdjacencyList().getTimedOutInterestCount(neighbor);
dmcoomes5bcb39e2017-10-31 15:07:55 -0500164 NLSR_LOG_DEBUG("Status: " << status);
165 NLSR_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600166 if (infoIntTimedOutCount < m_confParam.getInterestRetryNumber()) {
dmcoomes9f936662017-03-02 10:33:09 -0600167 // interest name: /<neighbor>/NLSR/INFO/<router>
akmhoque31d1d4b2014-05-05 22:08:14 -0500168 ndn::Name interestName(neighbor);
akmhoque93f1a072014-06-19 16:24:28 -0500169 interestName.append(NLSR_COMPONENT);
akmhoque157b0a42014-05-13 00:26:37 -0500170 interestName.append(INFO_COMPONENT);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600171 interestName.append(m_confParam.getRouterPrefix().wireEncode());
dmcoomes5bcb39e2017-10-31 15:07:55 -0500172 NLSR_LOG_DEBUG("Resending interest: " << interestName);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600173 expressInterest(interestName, m_confParam.getInterestResendTime());
akmhoque31d1d4b2014-05-05 22:08:14 -0500174 }
Vince Lehmancb76ade2014-08-28 21:24:41 -0500175 else if ((status == Adjacent::STATUS_ACTIVE) &&
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600176 (infoIntTimedOutCount == m_confParam.getInterestRetryNumber())) {
177 m_confParam.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
Vince Lehman50df6b72015-03-03 12:06:40 -0600178
dmcoomes5bcb39e2017-10-31 15:07:55 -0500179 NLSR_LOG_DEBUG("Neighbor: " << neighbor << " status changed to INACTIVE");
dmcoomes9eaf3f42017-02-21 11:39:01 -0600180
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600181 m_lsdb.scheduleAdjLsaBuild();
akmhoque31d1d4b2014-05-05 22:08:14 -0500182 }
183}
184
Nick G97e34942016-07-11 14:46:27 -0500185 // This is the first function that incoming Hello data will
186 // see. This checks if the data appears to be signed, and passes it
187 // on to validate the content of the data.
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700188void
189HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
190{
dmcoomes5bcb39e2017-10-31 15:07:55 -0500191 NLSR_LOG_DEBUG("Received data for INFO(name): " << data.getName());
akmhoquedfe615f2014-07-27 14:12:21 -0500192 if (data.getSignature().hasKeyLocator()) {
193 if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
dmcoomes5bcb39e2017-10-31 15:07:55 -0500194 NLSR_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
akmhoquedfe615f2014-07-27 14:12:21 -0500195 }
196 }
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600197 m_confParam.getValidator().validate(data,
198 std::bind(&HelloProtocol::onContentValidated, this, _1),
199 std::bind(&HelloProtocol::onContentValidationFailed,
200 this, _1, _2));
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700201}
akmhoque31d1d4b2014-05-05 22:08:14 -0500202
203void
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500204HelloProtocol::onContentValidated(const ndn::Data& data)
akmhoque31d1d4b2014-05-05 22:08:14 -0500205{
dmcoomes9f936662017-03-02 10:33:09 -0600206 // data name: /<neighbor>/NLSR/INFO/<router>/<version>
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500207 ndn::Name dataName = data.getName();
dmcoomes5bcb39e2017-10-31 15:07:55 -0500208 NLSR_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500209
akmhoque157b0a42014-05-13 00:26:37 -0500210 if (dataName.get(-3).toUri() == INFO_COMPONENT) {
akmhoque93f1a072014-06-19 16:24:28 -0500211 ndn::Name neighbor = dataName.getPrefix(-4);
Vince Lehmancb76ade2014-08-28 21:24:41 -0500212
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600213 Adjacent::Status oldStatus = m_confParam.getAdjacencyList().getStatusOfNeighbor(neighbor);
214 m_confParam.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_ACTIVE);
215 m_confParam.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
216 Adjacent::Status newStatus = m_confParam.getAdjacencyList().getStatusOfNeighbor(neighbor);
Vince Lehmancb76ade2014-08-28 21:24:41 -0500217
dmcoomes5bcb39e2017-10-31 15:07:55 -0500218 NLSR_LOG_DEBUG("Neighbor : " << neighbor);
219 NLSR_LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
akmhoque157b0a42014-05-13 00:26:37 -0500220 // change in Adjacency list
221 if ((oldStatus - newStatus) != 0) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600222 if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
223 m_routingTable.scheduleRoutingTableCalculation();
Ashlesh Gawandec5fa3202016-12-05 13:21:51 -0600224 }
225 else {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600226 m_lsdb.scheduleAdjLsaBuild();
Ashlesh Gawandec5fa3202016-12-05 13:21:51 -0600227 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500228 }
229 }
Alejandro Gil Torrese0d20482016-03-06 23:56:19 -0600230 // increment RCV_HELLO_DATA
231 hpIncrementSignal(Statistics::PacketType::RCV_HELLO_DATA);
akmhoque31d1d4b2014-05-05 22:08:14 -0500232}
233
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700234void
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500235HelloProtocol::onContentValidationFailed(const ndn::Data& data,
236 const ndn::security::v2::ValidationError& ve)
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700237{
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500238 NLSR_LOG_DEBUG("Validation Error: " << ve);
Yingdi Yu20e3a6e2014-05-26 23:16:10 -0700239}
240
Nick Gordonfad8e252016-08-11 14:21:38 -0500241} // namespace nlsr