blob: c0dfc471d4340eeb66d47e56056691365610422e [file] [log] [blame]
Vince Lehman09131122014-09-09 17:10:11 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Vince Lehmanc2acdcb2015-04-29 11:14:35 -05003 * Copyright (c) 2014-2015, The University of Memphis,
4 * 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/>.
Vince Lehman09131122014-09-09 17:10:11 -050020 **/
21
Vince Lehman02e32992015-03-11 12:31:20 -050022#include "test-common.hpp"
Vince Lehman199e9cf2015-04-07 13:22:16 -050023#include "control-commands.hpp"
Vince Lehman09131122014-09-09 17:10:11 -050024
Vince Lehman02e32992015-03-11 12:31:20 -050025#include "nlsr.hpp"
26
27#include <ndn-cxx/management/nfd-face-event-notification.hpp>
28#include <ndn-cxx/util/dummy-client-face.hpp>
Vince Lehman09131122014-09-09 17:10:11 -050029
30namespace nlsr {
31namespace test {
32
Vince Lehman09131122014-09-09 17:10:11 -050033using ndn::shared_ptr;
34
35BOOST_FIXTURE_TEST_SUITE(TestNlsr, BaseFixture)
36
37BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
38{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060039 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>();
Vince Lehman09131122014-09-09 17:10:11 -050040 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
41
42 // Simulate loading configuration file
43 AdjacencyList& neighbors = nlsr.getAdjacencyList();
44
45 Adjacent neighborA("/ndn/neighborA", "uri://faceA", 25, Adjacent::STATUS_INACTIVE, 0, 0);
46 neighbors.insert(neighborA);
47
48 Adjacent neighborB("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_INACTIVE, 0, 0);
49 neighbors.insert(neighborB);
50
51 Adjacent neighborC("/ndn/neighborC", "uri://faceC", 17, Adjacent::STATUS_INACTIVE, 0, 0);
52 neighbors.insert(neighborC);
53
54 nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
55
56 nlsr.initialize();
57
58 std::list<Adjacent> neighborList = neighbors.getAdjList();
59 for (std::list<Adjacent>::iterator it = neighborList.begin(); it != neighborList.end(); ++it) {
60 BOOST_CHECK_EQUAL(it->getLinkCost(), 0);
61 }
62}
63
64BOOST_AUTO_TEST_CASE(HyperbolicOff_LinkStateCost)
65{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060066 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>();
Vince Lehman09131122014-09-09 17:10:11 -050067 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
68
69 // Simulate loading configuration file
70 AdjacencyList& neighbors = nlsr.getAdjacencyList();
71
72 Adjacent neighborA("/ndn/neighborA", "uri://faceA", 25, Adjacent::STATUS_INACTIVE, 0, 0);
73 neighbors.insert(neighborA);
74
75 Adjacent neighborB("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_INACTIVE, 0, 0);
76 neighbors.insert(neighborB);
77
78 Adjacent neighborC("/ndn/neighborC", "uri://faceC", 17, Adjacent::STATUS_INACTIVE, 0, 0);
79 neighbors.insert(neighborC);
80
81 nlsr.initialize();
82
83 std::list<Adjacent> neighborList = neighbors.getAdjList();
84 for (std::list<Adjacent>::iterator it = neighborList.begin(); it != neighborList.end(); ++it) {
85 BOOST_CHECK(it->getLinkCost() != 0);
86 }
87}
88
Vince Lehman7b616582014-10-17 16:25:39 -050089BOOST_AUTO_TEST_CASE(SetEventIntervals)
90{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060091 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>();
Vince Lehman7b616582014-10-17 16:25:39 -050092 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
93
94 // Simulate loading configuration file
95 ConfParameter& conf = nlsr.getConfParameter();
96 conf.setAdjLsaBuildInterval(3);
97 conf.setFirstHelloInterval(6);
98 conf.setRoutingCalcInterval(9);
99
100 nlsr.initialize();
101
Vince Lehman50df6b72015-03-03 12:06:40 -0600102 const Lsdb& lsdb = nlsr.getLsdb();
Vince Lehman7b616582014-10-17 16:25:39 -0500103 const RoutingTable& rt = nlsr.getRoutingTable();
104
Vince Lehman50df6b72015-03-03 12:06:40 -0600105 BOOST_CHECK_EQUAL(lsdb.getAdjLsaBuildInterval(), ndn::time::seconds(3));
Vince Lehman7b616582014-10-17 16:25:39 -0500106 BOOST_CHECK_EQUAL(nlsr.getFirstHelloInterval(), 6);
107 BOOST_CHECK_EQUAL(rt.getRoutingCalcInterval(), ndn::time::seconds(9));
108}
109
Vince Lehman02e32992015-03-11 12:31:20 -0500110BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
111{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -0600112 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
Vince Lehman02e32992015-03-11 12:31:20 -0500113 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
Vince Lehman41b173e2015-05-07 14:13:26 -0500114 Lsdb& lsdb = nlsr.getLsdb();
Vince Lehman02e32992015-03-11 12:31:20 -0500115
116 // Simulate loading configuration file
117 ConfParameter& conf = nlsr.getConfParameter();
118 conf.setNetwork("/ndn");
119 conf.setSiteName("/site");
120 conf.setRouterName("/%C1.router/this-router");
121 conf.setAdjLsaBuildInterval(0);
122 conf.setRoutingCalcInterval(0);
123
124 // Add active neighbors
125 AdjacencyList& neighbors = nlsr.getAdjacencyList();
126
127 uint64_t destroyFaceId = 128;
128
129 // Create a neighbor whose Face will be destroyed
130 Adjacent failNeighbor("/ndn/neighborA", "uri://faceA", 10, Adjacent::STATUS_ACTIVE, 0,
131 destroyFaceId);
132 neighbors.insert(failNeighbor);
133
134 // Create an additional neighbor so an adjacency LSA can be built after the face is destroyed
Vince Lehman41b173e2015-05-07 14:13:26 -0500135 Adjacent otherNeighbor("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_ACTIVE, 0, 256);
Vince Lehman02e32992015-03-11 12:31:20 -0500136 neighbors.insert(otherNeighbor);
137
138 nlsr.initialize();
139
140 // Simulate successful HELLO responses
Vince Lehman41b173e2015-05-07 14:13:26 -0500141 lsdb.scheduleAdjLsaBuild();
142
143 // Set up adjacency LSAs
144 // This router
145 Adjacent thisRouter(conf.getRouterPrefix(), "uri://faceB", 10, Adjacent::STATUS_ACTIVE, 0, 256);
146
147 AdjLsa ownAdjLsa(conf.getRouterPrefix(), AdjLsa::TYPE_STRING, 10, ndn::time::system_clock::now(),
148 1, neighbors);
149 lsdb.installAdjLsa(ownAdjLsa);
150
151 // Router that will fail
152 AdjacencyList failAdjacencies;
153 failAdjacencies.insert(thisRouter);
154
155 AdjLsa failAdjLsa("/ndn/neighborA", AdjLsa::TYPE_STRING, 10,
156 ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, failAdjacencies);
157
158 lsdb.installAdjLsa(failAdjLsa);
159
160 // Other router
161 AdjacencyList otherAdjacencies;
162 otherAdjacencies.insert(thisRouter);
163
164 AdjLsa otherAdjLsa("/ndn/neighborB", AdjLsa::TYPE_STRING, 10,
165 ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, otherAdjacencies);
166
167 lsdb.installAdjLsa(otherAdjLsa);
Vince Lehman02e32992015-03-11 12:31:20 -0500168
169 // Run the scheduler to build an adjacency LSA
170 this->advanceClocks(ndn::time::milliseconds(1));
171
172 // Make sure an adjacency LSA was built
173 ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix()).append(AdjLsa::TYPE_STRING);
Vince Lehman41b173e2015-05-07 14:13:26 -0500174 AdjLsa* lsa = lsdb.findAdjLsa(key);
Vince Lehman02e32992015-03-11 12:31:20 -0500175 BOOST_REQUIRE(lsa != nullptr);
176
alvy46ccaae2015-06-25 14:13:39 -0500177 uint32_t lastAdjLsaSeqNo = lsa->getLsSeqNo();
178 nlsr.getSequencingManager().setAdjLsaSeq(lastAdjLsaSeqNo);
Vince Lehman02e32992015-03-11 12:31:20 -0500179
180 // Make sure the routing table was calculated
181 RoutingTableEntry* rtEntry = nlsr.getRoutingTable().findRoutingTableEntry(failNeighbor.getName());
182 BOOST_REQUIRE(rtEntry != nullptr);
183 BOOST_REQUIRE_EQUAL(rtEntry->getNexthopList().getSize(), 1);
184
185 // Receive FaceEventDestroyed notification
186 ndn::nfd::FaceEventNotification event;
187 event.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
188 .setFaceId(destroyFaceId);
189
190 shared_ptr<ndn::Data> data = make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
191 data->setContent(event.wireEncode());
192 nlsr.getKeyChain().sign(*data);
193
194 face->receive(*data);
195
196 // Run the scheduler to build an adjacency LSA
197 this->advanceClocks(ndn::time::milliseconds(1));
198
199 Adjacent updatedNeighbor = neighbors.getAdjacent(failNeighbor.getName());
200
201 BOOST_CHECK_EQUAL(updatedNeighbor.getFaceId(), 0);
202 BOOST_CHECK_EQUAL(updatedNeighbor.getInterestTimedOutNo(),
203 nlsr.getConfParameter().getInterestRetryNumber());
204 BOOST_CHECK_EQUAL(updatedNeighbor.getStatus(), Adjacent::STATUS_INACTIVE);
alvy46ccaae2015-06-25 14:13:39 -0500205
206 lsa = lsdb.findAdjLsa(key);
207 BOOST_REQUIRE(lsa != nullptr);
208
209 BOOST_CHECK_EQUAL(lsa->getLsSeqNo(), lastAdjLsaSeqNo + 1);
Vince Lehman02e32992015-03-11 12:31:20 -0500210
211 // Make sure the routing table was recalculated
212 rtEntry = nlsr.getRoutingTable().findRoutingTableEntry(failNeighbor.getName());
213 BOOST_CHECK(rtEntry == nullptr);
214}
215
Vince Lehman199e9cf2015-04-07 13:22:16 -0500216// Bug #2733
217// This test checks that when a face for an inactive node is destroyed, an
218// Adjacency LSA build does not postpone the LSA refresh and cause RIB
219// entries for other nodes' name prefixes to not be refreshed.
220//
221// This test is invalid when Issue #2732 is implemented since an Adjacency LSA
222// refresh will not cause RIB entries for other nodes' name prefixes to be refreshed.
223BOOST_FIXTURE_TEST_CASE(FaceDestroyEventInactive, UnitTestTimeFixture)
224{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -0600225 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
Vince Lehman199e9cf2015-04-07 13:22:16 -0500226 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
227 Lsdb& lsdb = nlsr.getLsdb();
228
229 // Simulate loading configuration file
230 ConfParameter& conf = nlsr.getConfParameter();
231 conf.setNetwork("/ndn");
232 conf.setSiteName("/site");
233 conf.setRouterName("/%C1.router/this-router");
234 conf.setFirstHelloInterval(0);
235 conf.setAdjLsaBuildInterval(0);
236 conf.setRoutingCalcInterval(0);
237
238 // Add neighbors
239 AdjacencyList& neighbors = nlsr.getAdjacencyList();
240
241 uint64_t destroyFaceId = 128;
242
243 // Create an inactive neighbor whose Face will be destroyed
244 Adjacent failNeighbor("/ndn/neighborA", "uri://faceA", 10, Adjacent::STATUS_INACTIVE, 3,
245 destroyFaceId);
246 neighbors.insert(failNeighbor);
247
248 // Create an additional active neighbor so an adjacency LSA can be built
249 Adjacent otherNeighbor("/ndn/neighborB", "uri://faceB", 25, Adjacent::STATUS_ACTIVE, 0, 256);
250 neighbors.insert(otherNeighbor);
251
252 // Add a name for the neighbor to advertise
253 NamePrefixList nameList;
254 ndn::Name nameToAdvertise("/ndn/neighborB/name");
255 nameList.insert(nameToAdvertise);
256
257 NameLsa nameLsa("/ndn/neighborB", "name", 25, ndn::time::system_clock::now(), nameList);
258 lsdb.installNameLsa(nameLsa);
259
260 nlsr.initialize();
261
262 // Simulate successful HELLO responses from neighbor B
263 lsdb.scheduleAdjLsaBuild();
264
Vince Lehman41b173e2015-05-07 14:13:26 -0500265 // Set up adjacency LSAs
266 // This router
267 Adjacent thisRouter(conf.getRouterPrefix(), "uri://faceB", 25, Adjacent::STATUS_ACTIVE, 0, 256);
268
269 AdjLsa ownAdjLsa(conf.getRouterPrefix(), AdjLsa::TYPE_STRING, 10, ndn::time::system_clock::now(),
270 1, neighbors);
271 lsdb.installAdjLsa(ownAdjLsa);
272
273 // Other ACTIVE router
274 AdjacencyList otherAdjacencies;
275 otherAdjacencies.insert(thisRouter);
276
277 AdjLsa otherAdjLsa("/ndn/neighborB", AdjLsa::TYPE_STRING, 10,
278 ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, otherAdjacencies);
279
280 lsdb.installAdjLsa(otherAdjLsa);
281
Vince Lehman199e9cf2015-04-07 13:22:16 -0500282 // Run the scheduler to build an adjacency LSA
283 this->advanceClocks(ndn::time::milliseconds(1));
284
285 ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix()).append(AdjLsa::TYPE_STRING);
286 AdjLsa* lsa = lsdb.findAdjLsa(key);
287 BOOST_REQUIRE(lsa != nullptr);
288
289 // Cancel previous LSA expiration event
290 g_scheduler.cancelEvent(lsa->getExpiringEventId());
291
292 // Set expiration time for own Adjacency LSA to earlier value for unit-test
293 //
294 // Expiration time is negative to offset the GRACE_PERIOD (10 seconds) automatically applied
295 // to expiration times
296 ndn::EventId id = lsdb.scheduleAdjLsaExpiration(key, lsa->getLsSeqNo(), -ndn::time::seconds(9));
297 lsa->setExpiringEventId(id);
298
299 // Generate a FaceEventDestroyed notification
300 ndn::nfd::FaceEventNotification event;
301 event.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
302 .setFaceId(destroyFaceId);
303
304 shared_ptr<ndn::Data> data = make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
305 data->setContent(event.wireEncode());
306 nlsr.getKeyChain().sign(*data);
307
308 // Receive the FaceEventDestroyed notification
309 face->receive(*data);
310
311 // Run the scheduler to expire the Adjacency LSA. The expiration should refresh the RIB
312 // entries associated with Neighbor B's advertised prefix.
313 face->sentInterests.clear();
314 this->advanceClocks(ndn::time::seconds(1));
315
316 // The Face should have two sent Interests: the face event and a RIB registration
317 BOOST_REQUIRE(face->sentInterests.size() > 0);
318 const ndn::Interest& interest = face->sentInterests.back();
319
320 ndn::nfd::ControlParameters parameters;
321 ndn::Name::Component verb;
322 BOOST_REQUIRE_NO_THROW(extractRibCommandParameters(interest, verb, parameters));
323
324 BOOST_CHECK_EQUAL(verb, ndn::Name::Component("register"));
325 BOOST_CHECK_EQUAL(parameters.getName(), nameToAdvertise);
326}
327
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500328BOOST_FIXTURE_TEST_CASE(GetCertificate, UnitTestTimeFixture)
329{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -0600330 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500331 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
332
333 // Create certificate
334 ndn::Name identity("/TestNLSR/identity");
335 identity.appendVersion();
336
337 ndn::KeyChain keyChain;
338 keyChain.createIdentity(identity);
339 ndn::Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
340 shared_ptr<ndn::IdentityCertificate> certificate = keyChain.getCertificate(certName);
341
342 const ndn::Name certKey = certificate->getName().getPrefix(-1);
343
344 BOOST_CHECK(nlsr.getCertificate(certKey) == nullptr);
345
346 // Certificate should be retrievable from the CertificateStore
347 nlsr.loadCertToPublish(certificate);
348
349 BOOST_CHECK(nlsr.getCertificate(certKey) != nullptr);
350
351 nlsr.getCertificateStore().clear();
352
353 // Certificate should be retrievable from the cache
354 nlsr.addCertificateToCache(certificate);
355 this->advanceClocks(ndn::time::milliseconds(10));
356
357 BOOST_CHECK(nlsr.getCertificate(certKey) != nullptr);
358}
359
Vince Lehman09131122014-09-09 17:10:11 -0500360BOOST_AUTO_TEST_SUITE_END()
361
362} //namespace test
363} //namespace nlsr