blob: 307a3a3ed27f91939e77d28853314a333d61a8c1 [file] [log] [blame]
Vince Lehman09131122014-09-09 17:10:11 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi0b1b7d92019-05-22 15:37:18 +00002/*
Saurab Dulal427e0122019-11-28 11:58:02 -06003 * Copyright (c) 2014-2020, The University of Memphis,
Vince Lehmanc2acdcb2015-04-29 11:14:35 -05004 * Regents of the University of California,
5 * Arizona Board of Regents.
Vince Lehman09131122014-09-09 17:10:11 -05006 *
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/>.
Junxiao Shi0b1b7d92019-05-22 15:37:18 +000020 */
Vince Lehman09131122014-09-09 17:10:11 -050021
Ashlesh Gawande3909aa12017-07-28 16:01:35 -050022#include "nlsr.hpp"
Vince Lehman02e32992015-03-11 12:31:20 -050023#include "test-common.hpp"
Vince Lehman199e9cf2015-04-07 13:22:16 -050024#include "control-commands.hpp"
Nick Gordonc0c6bcf2017-08-15 18:11:21 -050025#include "logger.hpp"
Vince Lehman09131122014-09-09 17:10:11 -050026
Junxiao Shi3e5120c2016-09-10 16:58:34 +000027#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
Vince Lehman09131122014-09-09 17:10:11 -050028
29namespace nlsr {
30namespace test {
31
Ashlesh Gawande85998a12017-12-07 22:22:13 -060032using namespace ndn::time_literals;
Vince Lehman09131122014-09-09 17:10:11 -050033
Nick Gordond5c1a372016-10-31 13:56:23 -050034class NlsrFixture : public MockNfdMgmtFixture
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050035{
36public:
37 NlsrFixture()
Saurab Dulal427e0122019-11-28 11:58:02 -060038 : conf(m_face, m_keyChain)
Ashlesh Gawande85998a12017-12-07 22:22:13 -060039 , confProcessor(conf)
40 , nlsr(m_face, m_keyChain, conf)
41 , lsdb(nlsr.m_lsdb)
42 , neighbors(conf.getAdjacencyList())
Nick Gordond5c1a372016-10-31 13:56:23 -050043 , nSuccessCallbacks(0)
44 , nFailureCallbacks(0)
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050045 {
Ashlesh Gawande85998a12017-12-07 22:22:13 -060046 addIdentity(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050047 }
48
49 void
50 receiveHelloData(const ndn::Name& sender, const ndn::Name& receiver)
51 {
52 ndn::Name dataName(sender);
53 dataName.append("NLSR").append("INFO").append(receiver.wireEncode()).appendVersion();
54
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050055 ndn::Data data(dataName);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050056
57 nlsr.m_helloProtocol.onContentValidated(data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050058 }
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050059
60public:
Ashlesh Gawande85998a12017-12-07 22:22:13 -060061 ConfParameter conf;
62 DummyConfFileProcessor confProcessor;
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050063 Nlsr nlsr;
64 Lsdb& lsdb;
65 AdjacencyList& neighbors;
Nick Gordond5c1a372016-10-31 13:56:23 -050066 uint32_t nSuccessCallbacks;
67 uint32_t nFailureCallbacks;
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -050068 ndn::util::signal::ScopedConnection connection;
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050069};
70
71BOOST_FIXTURE_TEST_SUITE(TestNlsr, NlsrFixture)
Vince Lehman09131122014-09-09 17:10:11 -050072
73BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
74{
Vince Lehman09131122014-09-09 17:10:11 -050075 // Simulate loading configuration file
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050076 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"), 25,
Nick Gordon727d4832017-10-13 18:04:25 -050077 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -050078 neighbors.insert(neighborA);
79
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050080 Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"), 10,
Nick Gordon727d4832017-10-13 18:04:25 -050081 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -050082 neighbors.insert(neighborB);
83
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050084 Adjacent neighborC("/ndn/neighborC", ndn::FaceUri("udp4://10.0.0.3"), 17,
Nick Gordon727d4832017-10-13 18:04:25 -050085 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -050086 neighbors.insert(neighborC);
87
Ashlesh Gawande85998a12017-12-07 22:22:13 -060088 conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
Vince Lehman09131122014-09-09 17:10:11 -050089
90 nlsr.initialize();
91
Ashlesh Gawande57a87172020-05-09 19:47:06 -070092 for (const auto neighbor : neighbors.getAdjList()) {
93 BOOST_CHECK_EQUAL(neighbor.getLinkCost(), 0);
Vince Lehman09131122014-09-09 17:10:11 -050094 }
95}
96
97BOOST_AUTO_TEST_CASE(HyperbolicOff_LinkStateCost)
98{
Vince Lehman09131122014-09-09 17:10:11 -050099 // Simulate loading configuration file
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500100 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"), 25,
Nick Gordon727d4832017-10-13 18:04:25 -0500101 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -0500102 neighbors.insert(neighborA);
103
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500104 Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"), 10,
Nick Gordon727d4832017-10-13 18:04:25 -0500105 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -0500106 neighbors.insert(neighborB);
107
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500108 Adjacent neighborC("/ndn/neighborC", ndn::FaceUri("udp4://10.0.0.3"), 17,
Nick Gordon727d4832017-10-13 18:04:25 -0500109 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -0500110 neighbors.insert(neighborC);
111
112 nlsr.initialize();
113
114 std::list<Adjacent> neighborList = neighbors.getAdjList();
115 for (std::list<Adjacent>::iterator it = neighborList.begin(); it != neighborList.end(); ++it) {
116 BOOST_CHECK(it->getLinkCost() != 0);
117 }
118}
119
Vince Lehman7b616582014-10-17 16:25:39 -0500120BOOST_AUTO_TEST_CASE(SetEventIntervals)
121{
Vince Lehman7b616582014-10-17 16:25:39 -0500122 // Simulate loading configuration file
Vince Lehman7b616582014-10-17 16:25:39 -0500123 conf.setAdjLsaBuildInterval(3);
Vince Lehman7b616582014-10-17 16:25:39 -0500124 conf.setRoutingCalcInterval(9);
125
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600126 Nlsr nlsr2(m_face, m_keyChain, conf);
Vince Lehman7b616582014-10-17 16:25:39 -0500127
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600128 const Lsdb& lsdb = nlsr2.m_lsdb;
129 const RoutingTable& rt = nlsr2.m_routingTable;
Vince Lehman7b616582014-10-17 16:25:39 -0500130
Ashlesh Gawande15052402018-12-12 20:20:00 -0600131 BOOST_CHECK_EQUAL(lsdb.m_adjLsaBuildInterval, ndn::time::seconds(3));
Vince Lehman7b616582014-10-17 16:25:39 -0500132 BOOST_CHECK_EQUAL(rt.getRoutingCalcInterval(), ndn::time::seconds(9));
133}
134
Nick Gordond5c1a372016-10-31 13:56:23 -0500135BOOST_AUTO_TEST_CASE(FaceCreateEvent)
136{
137 // Setting constants for the unit test
138 const uint32_t faceId = 1;
139 const std::string faceUri = "udp4://10.0.0.1:6363";
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500140
141 Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
Nick Gordon727d4832017-10-13 18:04:25 -0500142 Adjacent::STATUS_INACTIVE, 0, 0);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500143
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800144 BOOST_REQUIRE_EQUAL(conf.getAdjacencyList().insert(neighbor), true);
Nick Gordond5c1a372016-10-31 13:56:23 -0500145
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600146 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500147
148 // Build, sign, and send the Face Event
149 ndn::nfd::FaceEventNotification event;
150 event.setKind(ndn::nfd::FACE_EVENT_CREATED)
151 .setRemoteUri(faceUri)
152 .setFaceId(faceId);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600153 auto data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000154 data->setFreshnessPeriod(1_s);
Nick Gordond5c1a372016-10-31 13:56:23 -0500155 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600156 m_keyChain.sign(*data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500157 m_face.receive(*data);
Nick Gordond5c1a372016-10-31 13:56:23 -0500158
159 // Move the clocks forward so that the Face processes the event.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600160 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500161
162 // Need to explicitly provide a FaceUri object, because the
163 // conversion will attempt to create Name objects.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600164 auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
165 BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
Nick Gordond5c1a372016-10-31 13:56:23 -0500166 BOOST_CHECK_EQUAL(iterator->getFaceId(), faceId);
167}
168
169BOOST_AUTO_TEST_CASE(FaceCreateEventNoMatch)
170{
171 // Setting constants for the unit test
172 const uint32_t faceId = 1;
173 const std::string eventUri = "udp4://10.0.0.1:6363";
174 const std::string neighborUri = "udp4://10.0.0.2:6363";
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500175
176 Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(neighborUri), 10,
Nick Gordon727d4832017-10-13 18:04:25 -0500177 Adjacent::STATUS_INACTIVE, 0, 0);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500178
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600179 conf.getAdjacencyList().insert(neighbor);
Nick Gordond5c1a372016-10-31 13:56:23 -0500180
181 // Build, sign, and send the Face Event
182 ndn::nfd::FaceEventNotification event;
183 event.setKind(ndn::nfd::FACE_EVENT_CREATED)
184 .setRemoteUri(eventUri)
185 .setFaceId(faceId);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600186 auto data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000187 data->setFreshnessPeriod(1_s);
Nick Gordond5c1a372016-10-31 13:56:23 -0500188 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600189 m_keyChain.sign(*data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500190 m_face.receive(*data);
Nick Gordond5c1a372016-10-31 13:56:23 -0500191
192 // Move the clocks forward so that the Face processes the event.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600193 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500194
195 // The Face URIs did not match, so this neighbor should be unconfigured.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600196 auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(neighborUri));
197 BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
Nick Gordond5c1a372016-10-31 13:56:23 -0500198 BOOST_CHECK_EQUAL(iterator->getFaceId(), 0);
199}
200
201BOOST_AUTO_TEST_CASE(FaceCreateEventAlreadyConfigured)
202{
Ashlesh Gawande41878572019-09-29 00:16:02 -0500203 // So if NLSR gets the notification and registers prefixes it
204 // will change the Id to 1 and our tests will fail
205 // Need to disable registrationReply in dummy face and have own registration reply in the future
206 const uint32_t neighborFaceId = 1;
Nick Gordond5c1a372016-10-31 13:56:23 -0500207 const std::string faceUri = "udp4://10.0.0.1:6363";
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500208
209 Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
Ashlesh Gawande41878572019-09-29 00:16:02 -0500210 Adjacent::STATUS_ACTIVE, 0, 0);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600211 conf.getAdjacencyList().insert(neighbor);
Nick Gordond5c1a372016-10-31 13:56:23 -0500212
Ashlesh Gawande41878572019-09-29 00:16:02 -0500213 // Let NLSR start the face monitor
214 this->advanceClocks(10_ms);
215
Nick Gordond5c1a372016-10-31 13:56:23 -0500216 // Build, sign, and send the Face Event
217 ndn::nfd::FaceEventNotification event;
218 event.setKind(ndn::nfd::FACE_EVENT_CREATED)
219 .setRemoteUri(faceUri)
Ashlesh Gawande41878572019-09-29 00:16:02 -0500220 .setFaceId(neighborFaceId); // Does not matter what we set here, dummy face always returns 1
Nick Gordond5c1a372016-10-31 13:56:23 -0500221 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000222 data->setFreshnessPeriod(1_s);
Nick Gordond5c1a372016-10-31 13:56:23 -0500223 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600224 m_keyChain.sign(*data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500225 m_face.receive(*data);
Nick Gordond5c1a372016-10-31 13:56:23 -0500226
227 // Move the clocks forward so that the Face processes the event.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600228 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500229
Ashlesh Gawande41878572019-09-29 00:16:02 -0500230 // Check that the neighbor is configured with the face id of 1
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600231 auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
232 BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
Nick Gordond5c1a372016-10-31 13:56:23 -0500233 BOOST_CHECK_EQUAL(iterator->getFaceId(), neighborFaceId);
Ashlesh Gawande41878572019-09-29 00:16:02 -0500234
235 // Resend same event notification again
236 m_face.sentInterests.clear();
237 data->setName("/localhost/nfd/faces/events/%FE%01");
238 m_keyChain.sign(*data);
239 m_face.receive(*data);
240 this->advanceClocks(10_ms);
241
242 for (const auto& interest : m_face.sentInterests) {
243 // Should not re-register prefix since this is the same event notification
244 if (ndn::Name("/localhost/nfd/rib/register").isPrefixOf(interest.getName())) {
245 BOOST_CHECK(false);
246 }
247 }
Nick Gordond5c1a372016-10-31 13:56:23 -0500248}
249
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500250BOOST_AUTO_TEST_CASE(FaceDestroyEvent)
Vince Lehman02e32992015-03-11 12:31:20 -0500251{
Vince Lehman02e32992015-03-11 12:31:20 -0500252 // Add active neighbors
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600253 AdjacencyList& neighbors = conf.getAdjacencyList();
Vince Lehman02e32992015-03-11 12:31:20 -0500254 uint64_t destroyFaceId = 128;
255
256 // Create a neighbor whose Face will be destroyed
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500257 Adjacent failNeighbor("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"),
258 10, Adjacent::STATUS_ACTIVE, 0, destroyFaceId);
Vince Lehman02e32992015-03-11 12:31:20 -0500259 neighbors.insert(failNeighbor);
260
261 // Create an additional neighbor so an adjacency LSA can be built after the face is destroyed
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500262 Adjacent otherNeighbor("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"),
263 10, Adjacent::STATUS_ACTIVE, 0, 256);
Vince Lehman02e32992015-03-11 12:31:20 -0500264 neighbors.insert(otherNeighbor);
265
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -0500266 // Set HelloInterest lifetime as 10 seconds so that neighbors are not marked INACTIVE
267 // upon timeout before this test ends
268 conf.setInterestResendTime(10);
Vince Lehman02e32992015-03-11 12:31:20 -0500269 nlsr.initialize();
270
271 // Simulate successful HELLO responses
Vince Lehman41b173e2015-05-07 14:13:26 -0500272 lsdb.scheduleAdjLsaBuild();
273
274 // Set up adjacency LSAs
275 // This router
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500276 Adjacent thisRouter(conf.getRouterPrefix(), ndn::FaceUri("udp4://10.0.0.3"),
277 10, Adjacent::STATUS_ACTIVE, 0, 256);
Vince Lehman41b173e2015-05-07 14:13:26 -0500278
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500279 AdjLsa ownAdjLsa(conf.getRouterPrefix(), 10,
280 ndn::time::system_clock::now(), 1, neighbors);
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700281 lsdb.installLsa(std::make_shared<AdjLsa>(ownAdjLsa));
Vince Lehman41b173e2015-05-07 14:13:26 -0500282
283 // Router that will fail
284 AdjacencyList failAdjacencies;
285 failAdjacencies.insert(thisRouter);
286
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600287 AdjLsa failAdjLsa("/ndn/neighborA", 10,
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500288 ndn::time::system_clock::now() + ndn::time::seconds(3600),
289 1, failAdjacencies);
Vince Lehman41b173e2015-05-07 14:13:26 -0500290
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700291 lsdb.installLsa(std::make_shared<AdjLsa>(failAdjLsa));
Vince Lehman41b173e2015-05-07 14:13:26 -0500292
293 // Other router
294 AdjacencyList otherAdjacencies;
295 otherAdjacencies.insert(thisRouter);
296
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600297 AdjLsa otherAdjLsa("/ndn/neighborB", 10,
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500298 ndn::time::system_clock::now() + ndn::time::seconds(3600),
299 1, otherAdjacencies);
Vince Lehman41b173e2015-05-07 14:13:26 -0500300
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700301 lsdb.installLsa(std::make_shared<AdjLsa>(otherAdjLsa));
Vince Lehman02e32992015-03-11 12:31:20 -0500302
303 // Run the scheduler to build an adjacency LSA
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600304 this->advanceClocks(10_ms);
Vince Lehman02e32992015-03-11 12:31:20 -0500305
306 // Make sure an adjacency LSA was built
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700307 auto lsa = lsdb.findLsa(conf.getRouterPrefix(), Lsa::Type::ADJACENCY);
Vince Lehman02e32992015-03-11 12:31:20 -0500308 BOOST_REQUIRE(lsa != nullptr);
309
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800310 uint32_t lastAdjLsaSeqNo = lsa->getSeqNo();
Ashlesh Gawande15052402018-12-12 20:20:00 -0600311 nlsr.m_lsdb.m_sequencingManager.setAdjLsaSeq(lastAdjLsaSeqNo);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600312
313 this->advanceClocks(1500_ms, 10);
Vince Lehman02e32992015-03-11 12:31:20 -0500314
315 // Make sure the routing table was calculated
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600316 RoutingTableEntry* rtEntry = nlsr.m_routingTable.findRoutingTableEntry(failNeighbor.getName());
Vince Lehman02e32992015-03-11 12:31:20 -0500317 BOOST_REQUIRE(rtEntry != nullptr);
Nick Gordonff9a6272017-10-12 13:38:29 -0500318 BOOST_REQUIRE_EQUAL(rtEntry->getNexthopList().size(), 1);
Vince Lehman02e32992015-03-11 12:31:20 -0500319
320 // Receive FaceEventDestroyed notification
321 ndn::nfd::FaceEventNotification event;
322 event.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
323 .setFaceId(destroyFaceId);
324
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700325 auto data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000326 data->setFreshnessPeriod(1_s);
Vince Lehman02e32992015-03-11 12:31:20 -0500327 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600328 m_keyChain.sign(*data);
Vince Lehman02e32992015-03-11 12:31:20 -0500329
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500330 m_face.receive(*data);
Vince Lehman02e32992015-03-11 12:31:20 -0500331
332 // Run the scheduler to build an adjacency LSA
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600333 this->advanceClocks(10_ms);
Vince Lehman02e32992015-03-11 12:31:20 -0500334
335 Adjacent updatedNeighbor = neighbors.getAdjacent(failNeighbor.getName());
336
337 BOOST_CHECK_EQUAL(updatedNeighbor.getFaceId(), 0);
338 BOOST_CHECK_EQUAL(updatedNeighbor.getInterestTimedOutNo(),
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600339 conf.getInterestRetryNumber());
Vince Lehman02e32992015-03-11 12:31:20 -0500340 BOOST_CHECK_EQUAL(updatedNeighbor.getStatus(), Adjacent::STATUS_INACTIVE);
alvy46ccaae2015-06-25 14:13:39 -0500341
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700342 lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
alvy46ccaae2015-06-25 14:13:39 -0500343 BOOST_REQUIRE(lsa != nullptr);
344
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800345 BOOST_CHECK_EQUAL(lsa->getSeqNo(), lastAdjLsaSeqNo + 1);
Vince Lehman02e32992015-03-11 12:31:20 -0500346
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600347 this->advanceClocks(15_s, 10);
348
Vince Lehman02e32992015-03-11 12:31:20 -0500349 // Make sure the routing table was recalculated
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600350 rtEntry = nlsr.m_routingTable.findRoutingTableEntry(failNeighbor.getName());
Vince Lehman02e32992015-03-11 12:31:20 -0500351 BOOST_CHECK(rtEntry == nullptr);
352}
353
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500354BOOST_AUTO_TEST_CASE(BuildAdjLsaAfterHelloResponse)
355{
356 // Configure NLSR
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500357 conf.setAdjLsaBuildInterval(1);
358
359 // Add neighbors
360 // Router A
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500361 ndn::Name neighborAName("/ndn/site/%C1.Router/routerA");
362 Adjacent neighborA(neighborAName, ndn::FaceUri("udp4://10.0.0.1"),
363 0, Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500364 neighbors.insert(neighborA);
365
366 // Router B
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500367 ndn::Name neighborBName("/ndn/site/%C1.Router/routerB");
368 Adjacent neighborB(neighborBName, ndn::FaceUri("udp4://10.0.0.1"),
369 0, Adjacent::STATUS_INACTIVE, 0, 0);
370
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500371 neighbors.insert(neighborB);
372
373 nlsr.initialize();
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500374
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600375 this->advanceClocks(10_ms);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500376
377 // Receive HELLO response from Router A
378 receiveHelloData(neighborAName, conf.getRouterPrefix());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600379 this->advanceClocks(1_s, 10);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500380
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500381 // Adjacency LSA should be built even though other router is INACTIVE
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700382 auto lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500383 BOOST_REQUIRE(lsa != nullptr);
Nick Gordonff9a6272017-10-12 13:38:29 -0500384 BOOST_CHECK_EQUAL(lsa->getAdl().size(), 1);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500385
386 // Receive HELLO response from Router B
387 receiveHelloData(neighborBName, conf.getRouterPrefix());
388
389 // Both routers become INACTIVE and HELLO Interests have timed out
390 for (Adjacent& adjacency : neighbors.getAdjList()) {
391 adjacency.setStatus(Adjacent::STATUS_INACTIVE);
392 adjacency.setInterestTimedOutNo(HELLO_RETRIES_DEFAULT);
393 }
394
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600395 this->advanceClocks(1_s, 10);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500396
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500397 // Adjacency LSA should have been removed since this router's adjacencies are
398 // INACTIVE and have timed out
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700399 lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500400 BOOST_CHECK(lsa == nullptr);
401
402 // Receive HELLO response from Router A and B
403 receiveHelloData(neighborAName, conf.getRouterPrefix());
404 receiveHelloData(neighborBName, conf.getRouterPrefix());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600405 this->advanceClocks(1_s, 10);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500406
407 // Adjacency LSA should be built
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700408 lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500409 BOOST_REQUIRE(lsa != nullptr);
Nick Gordonff9a6272017-10-12 13:38:29 -0500410 BOOST_CHECK_EQUAL(lsa->getAdl().size(), 2);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500411}
412
Nick Gordond5c1a372016-10-31 13:56:23 -0500413BOOST_AUTO_TEST_CASE(FaceDatasetFetchSuccess)
414{
415 bool hasResult = false;
Nick Gordond5c1a372016-10-31 13:56:23 -0500416
417 nlsr.initializeFaces([&hasResult] (const std::vector<ndn::nfd::FaceStatus>& faces) {
418 hasResult = true;
419 BOOST_CHECK_EQUAL(faces.size(), 2);
420 BOOST_CHECK_EQUAL(faces.front().getFaceId(), 25401);
421 BOOST_CHECK_EQUAL(faces.back().getFaceId(), 25402);
422 },
423 [] (uint32_t code, const std::string& reason) {});
424
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600425 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500426
427 ndn::nfd::FaceStatus payload1;
428 payload1.setFaceId(25401);
429 ndn::nfd::FaceStatus payload2;
430 payload2.setFaceId(25402);
431 this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
432
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600433 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500434 BOOST_CHECK(hasResult);
435}
436
437BOOST_AUTO_TEST_CASE(FaceDatasetFetchFailure)
438{
Nick Gordond5c1a372016-10-31 13:56:23 -0500439 nlsr.initializeFaces([](const std::vector<ndn::nfd::FaceStatus>& faces) {},
440 [this](uint32_t code, const std::string& reason){
441 this->nFailureCallbacks++;
442 });
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600443 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500444
445 ndn::Name payload;
446 this->sendDataset("/localhost/nfd/faces/list", payload);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600447 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500448
449 BOOST_CHECK_EQUAL(nFailureCallbacks, 1);
450 BOOST_CHECK_EQUAL(nSuccessCallbacks, 0);
451}
452
453BOOST_AUTO_TEST_CASE(FaceDatasetProcess)
454{
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500455 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://192.168.0.100:6363"),
456 25, Adjacent::STATUS_INACTIVE, 0, 0);
Nick Gordond5c1a372016-10-31 13:56:23 -0500457 neighbors.insert(neighborA);
458
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500459 Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://192.168.0.101:6363"),
460 10, Adjacent::STATUS_INACTIVE, 0, 0);
Nick Gordond5c1a372016-10-31 13:56:23 -0500461 neighbors.insert(neighborB);
462
463 ndn::nfd::FaceStatus payload1;
464 payload1.setFaceId(1)
465 .setRemoteUri("udp4://192.168.0.100:6363");
466 ndn::nfd::FaceStatus payload2;
467 payload2.setFaceId(2)
468 .setRemoteUri("udp4://192.168.0.101:6363");
469 std::vector<ndn::nfd::FaceStatus> faceStatuses = {payload1, payload2};
470
471 nlsr.processFaceDataset(faceStatuses);
Nick Gordond5c1a372016-10-31 13:56:23 -0500472
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600473 AdjacencyList adjList = conf.getAdjacencyList();
Nick Gordond5c1a372016-10-31 13:56:23 -0500474
475 BOOST_CHECK_EQUAL(adjList.getAdjacent("/ndn/neighborA").getFaceId(), payload1.getFaceId());
476 BOOST_CHECK_EQUAL(adjList.getAdjacent("/ndn/neighborB").getFaceId(), payload2.getFaceId());
477}
478
479BOOST_AUTO_TEST_CASE(UnconfiguredNeighbor)
480{
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500481 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://192.168.0.100:6363"), 25, Adjacent::STATUS_INACTIVE, 0, 0);
Nick Gordond5c1a372016-10-31 13:56:23 -0500482 neighbors.insert(neighborA);
483
484 ndn::nfd::FaceStatus payload;
485 payload.setFaceId(1)
486 .setRemoteUri("udp4://192.168.0.101:6363"); // Note dissimilar Face URI.
487 std::vector<ndn::nfd::FaceStatus> faceStatuses = {payload};
488
489 nlsr.processFaceDataset(faceStatuses);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600490 this->advanceClocks(20_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500491
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600492 AdjacencyList adjList = conf.getAdjacencyList();
Nick Gordond5c1a372016-10-31 13:56:23 -0500493
494 BOOST_CHECK_EQUAL(adjList.getAdjacent("/ndn/neighborA").getFaceId(), 0);
495}
496
497BOOST_AUTO_TEST_CASE(FaceDatasetPeriodicFetch)
498{
499 int nNameMatches = 0;
500 ndn::Name datasetPrefix("/localhost/nfd/faces/list");
501 ndn::nfd::CommandOptions options;
502 ndn::time::milliseconds defaultTimeout = options.getTimeout();
503
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500504 int fetchInterval(1);
Nick Gordond5c1a372016-10-31 13:56:23 -0500505 conf.setFaceDatasetFetchInterval(fetchInterval);
506 conf.setFaceDatasetFetchTries(0);
507
Nick Gordond5c1a372016-10-31 13:56:23 -0500508 // Elapse the default timeout time of the interest.
509 this->advanceClocks(defaultTimeout);
510
511 // Check that we have one interest for face list in the sent interests.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600512 for (const auto& interest : m_face.sentInterests) {
Nick Gordond5c1a372016-10-31 13:56:23 -0500513 if (datasetPrefix.isPrefixOf(interest.getName())) {
514 nNameMatches++;
515 }
516 }
517 BOOST_CHECK_EQUAL(nNameMatches, 1);
518
519 // Elapse the clock by the reschedule time (that we set)
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500520 this->advanceClocks(ndn::time::seconds(fetchInterval));
Nick Gordond5c1a372016-10-31 13:56:23 -0500521 // Elapse the default timeout on the interest.
522 this->advanceClocks(defaultTimeout);
Nick Gordond5c1a372016-10-31 13:56:23 -0500523
524 // Check that we now have two interests
525 nNameMatches = 0;
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600526 for (const auto& interest : m_face.sentInterests) {
Nick Gordond5c1a372016-10-31 13:56:23 -0500527 if (datasetPrefix.isPrefixOf(interest.getName())) {
528 nNameMatches++;
529 }
530 }
531 BOOST_CHECK_EQUAL(nNameMatches, 2);
532}
533
Vince Lehman09131122014-09-09 17:10:11 -0500534BOOST_AUTO_TEST_SUITE_END()
535
Nick Gordonfad8e252016-08-11 14:21:38 -0500536} // namespace test
537} // namespace nlsr