blob: 9c8b87a4e17bc11d5066c1046880a8c5abac63ed [file] [log] [blame]
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento8a05c7f2019-02-28 02:26:19 -05003 * Copyright (c) 2014-2019, Regents of the University of California,
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050026#include "mgmt/rib-manager.hpp"
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000027
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040028#include "tests/test-common.hpp"
Davide Pesavento1d12d2f2019-03-22 12:44:14 -040029#include "tests/key-chain-fixture.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040030#include "tests/daemon/global-io-fixture.hpp"
Junxiao Shidf1dc652019-08-30 19:03:19 +000031#include "tests/daemon/rib/fib-updates-common.hpp"
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040032
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000033#include <ndn-cxx/util/dummy-client-face.hpp>
34
Teng Liang18c2b292019-10-18 14:31:04 -070035#include <boost/property_tree/info_parser.hpp>
36
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000037namespace nfd {
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000038namespace tests {
39
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050040using rib::Route;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000041
Teng Liang18c2b292019-10-18 14:31:04 -070042static ConfigSection
43makeSection(const std::string& config)
44{
45 std::istringstream inputStream(config);
46 ConfigSection section;
47 boost::property_tree::read_info(inputStream, section);
48 return section;
49}
50
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040051class RibManagerSlAnnounceFixture : public GlobalIoTimeFixture, public KeyChainFixture
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000052{
53public:
54 using SlAnnounceResult = RibManager::SlAnnounceResult;
55
56 RibManagerSlAnnounceFixture()
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040057 : m_face(g_io, m_keyChain)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000058 , m_nfdController(m_face, m_keyChain)
59 , m_dispatcher(m_face, m_keyChain)
60 , m_fibUpdater(rib, m_nfdController)
61 , m_trustedSigner(m_keyChain.createIdentity("/trusted", ndn::RsaKeyParams()))
62 , m_untrustedSigner(m_keyChain.createIdentity("/untrusted", ndn::RsaKeyParams()))
63 {
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000064 // Face, Controller, Dispatcher are irrelevant to SlAnnounce functions but required by
65 // RibManager construction, so they are private. RibManager is a pointer to avoid code style
66 // rule 1.4 violation.
Davide Pesavento0a71dd32019-03-17 20:36:18 -040067 manager = make_unique<RibManager>(rib, m_face, m_keyChain, m_nfdController, m_dispatcher);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000068
Teng Liang18c2b292019-10-18 14:31:04 -070069 loadDefaultPaConfig();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000070 }
71
72 template<typename ...T>
73 ndn::PrefixAnnouncement
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050074 makeTrustedAnn(T&&... args)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000075 {
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050076 return signPrefixAnn(makePrefixAnn(std::forward<T>(args)...), m_keyChain, m_trustedSigner);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000077 }
78
79 template<typename ...T>
80 ndn::PrefixAnnouncement
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050081 makeUntrustedAnn(T&&... args)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000082 {
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050083 return signPrefixAnn(makePrefixAnn(std::forward<T>(args)...), m_keyChain, m_untrustedSigner);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000084 }
85
86 /** \brief Invoke manager->slAnnounce and wait for result.
87 */
88 SlAnnounceResult
89 slAnnounceSync(const ndn::PrefixAnnouncement& pa, uint64_t faceId, time::milliseconds maxLifetime)
90 {
91 optional<SlAnnounceResult> result;
92 manager->slAnnounce(pa, faceId, maxLifetime,
93 [&] (RibManager::SlAnnounceResult res) {
94 BOOST_CHECK(!result);
95 result = res;
96 });
97
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040098 g_io.poll();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000099 BOOST_CHECK(result);
100 return result.value_or(SlAnnounceResult::ERROR);
101 }
102
103 /** \brief Invoke manager->slRenew and wait for result.
104 */
105 SlAnnounceResult
106 slRenewSync(const Name& name, uint64_t faceId, time::milliseconds maxLifetime)
107 {
108 optional<SlAnnounceResult> result;
109 manager->slRenew(name, faceId, maxLifetime,
110 [&] (RibManager::SlAnnounceResult res) {
111 BOOST_CHECK(!result);
112 result = res;
113 });
114
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400115 g_io.poll();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000116 BOOST_CHECK(result);
117 return result.value_or(SlAnnounceResult::ERROR);
118 }
119
120 /** \brief Invoke manager->slFindAnn and wait for result.
121 */
122 optional<ndn::PrefixAnnouncement>
123 slFindAnnSync(const Name& name)
124 {
125 optional<optional<ndn::PrefixAnnouncement>> result;
126 manager->slFindAnn(name,
127 [&] (optional<ndn::PrefixAnnouncement> found) {
128 BOOST_CHECK(!result);
129 result = found;
130 });
131
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400132 g_io.poll();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000133 BOOST_CHECK(result);
134 return result.value_or(nullopt);
135 }
136
137 /** \brief Lookup a route with PREFIXANN origin.
138 */
139 Route*
140 findAnnRoute(const Name& name, uint64_t faceId)
141 {
142 Route routeQuery;
143 routeQuery.faceId = faceId;
144 routeQuery.origin = ndn::nfd::ROUTE_ORIGIN_PREFIXANN;
145 return rib.find(name, routeQuery);
146 }
147
148private:
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000149 void
Teng Liang18c2b292019-10-18 14:31:04 -0700150 loadDefaultPaConfig()
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000151 {
Teng Liang18c2b292019-10-18 14:31:04 -0700152 const std::string CONFIG = R"CONFIG(
153 trust-anchor
154 {
155 type any
156 }
157 )CONFIG";
158 manager->applyPaConfig(makeSection(CONFIG), "default");
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000159 }
160
161public:
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500162 rib::Rib rib;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000163 unique_ptr<RibManager> manager;
164
165private:
166 ndn::util::DummyClientFace m_face;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000167 ndn::nfd::Controller m_nfdController;
Davide Pesavento78ddcab2019-02-28 22:00:03 -0500168 Dispatcher m_dispatcher;
Junxiao Shidf1dc652019-08-30 19:03:19 +0000169 rib::tests::MockFibUpdater m_fibUpdater;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000170
171 ndn::security::SigningInfo m_trustedSigner;
172 ndn::security::SigningInfo m_untrustedSigner;
173};
174
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500175BOOST_AUTO_TEST_SUITE(Mgmt)
176BOOST_AUTO_TEST_SUITE(TestRibManager)
177BOOST_FIXTURE_TEST_SUITE(SlAnnounce, RibManagerSlAnnounceFixture)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000178
Teng Liang18c2b292019-10-18 14:31:04 -0700179BOOST_AUTO_TEST_CASE(AnnounceWithDefaultConfig)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000180{
Teng Liang18c2b292019-10-18 14:31:04 -0700181 auto pa = makeTrustedAnn("/fMXN7UeB", 1_h);
182 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 3275, 1_h), SlAnnounceResult::OK);
183 BOOST_CHECK(findAnnRoute("/fMXN7UeB", 3275) != nullptr);
184
185 auto pa2 = makeUntrustedAnn("/1nzAe0Y4", 1_h);
186 BOOST_CHECK_EQUAL(slAnnounceSync(pa2, 2959, 1_h), SlAnnounceResult::OK);
187 BOOST_CHECK(findAnnRoute("/1nzAe0Y4", 2959) != nullptr);
188}
189
190BOOST_AUTO_TEST_CASE(AnnounceWithEmptyConfig)
191{
192 manager->applyPaConfig(makeSection(""), "empty");
193
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000194 auto pa = makeTrustedAnn("/fMXN7UeB", 1_h);
195 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 3275, 1_h), SlAnnounceResult::VALIDATION_FAILURE);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000196 BOOST_CHECK(findAnnRoute("/fMXN7UeB", 3275) == nullptr);
Teng Liang18c2b292019-10-18 14:31:04 -0700197
198 auto pa2 = makeUntrustedAnn("/1nzAe0Y4", 1_h);
199 BOOST_CHECK_EQUAL(slAnnounceSync(pa2, 2959, 1_h), SlAnnounceResult::VALIDATION_FAILURE);
200 BOOST_CHECK(findAnnRoute("/1nzAe0Y4", 2959) == nullptr);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000201}
202
203BOOST_AUTO_TEST_CASE(AnnounceValidationError)
204{
Teng Liang18c2b292019-10-18 14:31:04 -0700205 ConfigSection section;
206 section.put("rule.id", "PA");
207 section.put("rule.for", "data");
208 section.put("rule.checker.type", "customized");
209 section.put("rule.checker.sig-type", "rsa-sha256");
210 section.put("rule.checker.key-locator.type", "name");
211 section.put("rule.checker.key-locator.name", "/trusted");
212 section.put("rule.checker.key-locator.relation", "is-prefix-of");
213 section.put("trust-anchor.type", "base64");
214 section.put("trust-anchor.base64-string", getIdentityCertificateBase64("/trusted"));
215 manager->applyPaConfig(section, "trust-schema.section");
216
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000217 auto pa = makeUntrustedAnn("/1nzAe0Y4", 1_h);
218 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2959, 1_h), SlAnnounceResult::VALIDATION_FAILURE);
219
220 BOOST_CHECK(findAnnRoute("/1nzAe0Y4", 2959) == nullptr);
221}
222
223BOOST_AUTO_TEST_CASE(AnnounceInsert_AnnLifetime)
224{
225 auto pa = makeTrustedAnn("/EHJYmJz9", 1_h);
226 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 1641, 2_h), SlAnnounceResult::OK);
227
228 Route* route = findAnnRoute("/EHJYmJz9", 1641);
229 BOOST_REQUIRE(route != nullptr);
230 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 1_h);
231 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 1_h);
232}
233
234BOOST_AUTO_TEST_CASE(AnnounceInsert_ArgLifetime)
235{
236 auto pa = makeTrustedAnn("/BU9Fec9E", 2_h);
237 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 1282, 1_h), SlAnnounceResult::OK);
238
239 Route* route = findAnnRoute("/BU9Fec9E", 1282);
240 BOOST_REQUIRE(route != nullptr);
241 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 2_h);
242 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 1_h);
243}
244
245BOOST_AUTO_TEST_CASE(AnnounceReplace)
246{
247 auto pa = makeTrustedAnn("/HsBFGvL3", 1_h);
248 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2813, 1_h), SlAnnounceResult::OK);
249
250 pa = makeTrustedAnn("/HsBFGvL3", 2_h);
251 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2813, 2_h), SlAnnounceResult::OK);
252
253 Route* route = findAnnRoute("/HsBFGvL3", 2813);
254 BOOST_REQUIRE(route != nullptr);
255 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 2_h);
256 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 2_h);
257}
258
259BOOST_AUTO_TEST_CASE(AnnounceExpired)
260{
261 auto pa = makeTrustedAnn("/awrVv6V7", 1_h, std::make_pair(-3_h, -1_h));
262 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 9087, 1_h), SlAnnounceResult::EXPIRED);
263
264 BOOST_CHECK(findAnnRoute("/awrVv6V7", 9087) == nullptr);
265}
266
267BOOST_AUTO_TEST_CASE(RenewNotFound)
268{
269 BOOST_CHECK_EQUAL(slRenewSync("IAYigN73", 1070, 1_h), SlAnnounceResult::NOT_FOUND);
270
271 BOOST_CHECK(findAnnRoute("/IAYigN73", 1070) == nullptr);
272}
273
274BOOST_AUTO_TEST_CASE(RenewProlong_ArgLifetime)
275{
276 auto pa = makeTrustedAnn("/P2IYFqtr", 4_h);
277 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 4506, 2_h), SlAnnounceResult::OK);
278 advanceClocks(1_h); // Route has 1_h remaining lifetime
279
Teng Lianga4e6ec32018-10-21 09:25:00 -0700280 BOOST_CHECK_EQUAL(slRenewSync("/P2IYFqtr/2321", 4506, 2_h), SlAnnounceResult::OK);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000281
282 Route* route = findAnnRoute("/P2IYFqtr", 4506);
283 BOOST_REQUIRE(route != nullptr);
284 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 3_h);
285 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 2_h); // set by slRenew
286}
287
288BOOST_AUTO_TEST_CASE(RenewProlong_AnnLifetime)
289{
290 auto pa = makeTrustedAnn("/be01Yiba", 4_h);
291 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 1589, 2_h), SlAnnounceResult::OK);
292 advanceClocks(1_h); // Route has 1_h remaining lifetime
293
Teng Lianga4e6ec32018-10-21 09:25:00 -0700294 BOOST_CHECK_EQUAL(slRenewSync("/be01Yiba/4324", 1589, 5_h), SlAnnounceResult::OK);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000295
296 Route* route = findAnnRoute("/be01Yiba", 1589);
297 BOOST_REQUIRE(route != nullptr);
298 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 3_h);
299 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 3_h); // capped by annExpires
300}
301
302BOOST_AUTO_TEST_CASE(RenewShorten)
303{
304 auto pa = makeTrustedAnn("/5XCHYCAd", 4_h);
305 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 3851, 4_h), SlAnnounceResult::OK);
306 advanceClocks(1_h); // Route has 3_h remaining lifetime
307
Teng Lianga4e6ec32018-10-21 09:25:00 -0700308 BOOST_CHECK_EQUAL(slRenewSync("/5XCHYCAd/98934", 3851, 1_h), SlAnnounceResult::OK);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000309
310 Route* route = findAnnRoute("/5XCHYCAd", 3851);
311 BOOST_REQUIRE(route != nullptr);
312 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 3_h);
313 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 1_h); // set by slRenew
314}
315
316BOOST_AUTO_TEST_CASE(RenewShorten_Zero)
317{
318 auto pa = makeTrustedAnn("/cdQ7KPNw", 4_h);
319 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 8031, 4_h), SlAnnounceResult::OK);
320 advanceClocks(1_h); // Route has 3_h remaining lifetime
321
Teng Lianga4e6ec32018-10-21 09:25:00 -0700322 BOOST_CHECK_EQUAL(slRenewSync("/cdQ7KPNw/8023", 8031, 0_s), SlAnnounceResult::EXPIRED);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000323
324 BOOST_CHECK(findAnnRoute("/cdQ7KPNw", 8031) == nullptr);
325}
326
327BOOST_AUTO_TEST_CASE(FindExisting)
328{
329 auto pa = makeTrustedAnn("/JHugsjjr", 1_h);
330 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2363, 1_h), SlAnnounceResult::OK);
331
332 auto found = slFindAnnSync("/JHugsjjr");
333 BOOST_REQUIRE(found);
334 BOOST_CHECK_EQUAL(found->getAnnouncedName(), "/JHugsjjr");
335 BOOST_CHECK(found->getData());
336
337 auto found2 = slFindAnnSync("/JHugsjjr/StvXhKR5");
338 BOOST_CHECK(found == found2);
339}
340
341BOOST_AUTO_TEST_CASE(FindNew)
342{
343 Route route;
344 route.faceId = 1367;
345 route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
346 rib.insert("/dLY1pRhR", route);
347
348 auto pa = slFindAnnSync("/dLY1pRhR/3qNK9Ngn");
349 BOOST_REQUIRE(pa);
350 BOOST_CHECK_EQUAL(pa->getAnnouncedName(), "/dLY1pRhR");
351}
352
353BOOST_AUTO_TEST_CASE(FindNone)
354{
355 auto pa = slFindAnnSync("/2YNeYuV2");
356 BOOST_CHECK(!pa);
357}
358
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500359BOOST_AUTO_TEST_SUITE_END() // SlAnnounce
360BOOST_AUTO_TEST_SUITE_END() // TestRibManager
361BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000362
363} // namespace tests
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000364} // namespace nfd