blob: 5fb277687a5e3a5d7d0ace4fc585e09ad3868264 [file] [log] [blame]
Junxiao Shi8c8d2182014-01-30 22:33:00 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shifc2e13d2017-07-25 02:08:48 +00002/*
Davide Pesaventob21bed82021-02-13 00:20:06 -05003 * Copyright (c) 2014-2021, Regents of the University of California,
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08004 * 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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Junxiao Shi82e7f582014-09-07 15:15:40 -070024 */
Junxiao Shi8c8d2182014-01-30 22:33:00 -070025
26#include "fw/forwarder.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040027#include "common/global.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070028
Junxiao Shid9ee45c2014-02-27 15:38:11 -070029#include "tests/test-common.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040030#include "tests/daemon/global-io-fixture.hpp"
Junxiao Shi06a1eab2017-09-04 13:13:02 +000031#include "tests/daemon/face/dummy-face.hpp"
32#include "choose-strategy.hpp"
33#include "dummy-strategy.hpp"
34
35#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi8c8d2182014-01-30 22:33:00 -070036
37namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070038namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070039
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040040class ForwarderFixture : public GlobalIoTimeFixture
41{
42protected:
43 template<typename ...Args>
44 shared_ptr<DummyFace>
45 addFace(Args&&... args)
46 {
47 auto face = make_shared<DummyFace>(std::forward<Args>(args)...);
48 faceTable.add(face);
49 return face;
50 }
51
52protected:
53 FaceTable faceTable;
54 Forwarder forwarder{faceTable};
55};
56
Junxiao Shi0355e9f2015-09-02 07:24:53 -070057BOOST_AUTO_TEST_SUITE(Fw)
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040058BOOST_FIXTURE_TEST_SUITE(TestForwarder, ForwarderFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070059
Junxiao Shi8c8d2182014-01-30 22:33:00 -070060BOOST_AUTO_TEST_CASE(SimpleExchange)
61{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040062 auto face1 = addFace();
63 auto face2 = addFace();
Junxiao Shic041ca32014-02-25 20:01:15 -070064
Junxiao Shi8c8d2182014-01-30 22:33:00 -070065 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +000066 fib::Entry* entry = fib.insert("/A").first;
67 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070068
Junxiao Shida93f1f2015-11-11 06:13:16 -070069 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
70 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000071 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
72 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060073 face1->receiveInterest(*makeInterest("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040074 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070075 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000076 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070077 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
78 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070079 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
80 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000081 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
82 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Alex Lane6bead9b2020-05-12 19:08:20 -050083 BOOST_CHECK_EQUAL(forwarder.getCounters().nSatisfiedInterests, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070084
Junxiao Shida93f1f2015-11-11 06:13:16 -070085 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
86 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060087 face2->receiveData(*makeData("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040088 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070089 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shi9d727852019-05-14 13:44:22 -060090 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070091 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
92 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070093 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
94 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Alex Lane6bead9b2020-05-12 19:08:20 -050095 BOOST_CHECK_EQUAL(forwarder.getCounters().nInNacks, 0);
96 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutNacks, 0);
97 BOOST_CHECK_EQUAL(forwarder.getCounters().nSatisfiedInterests, 1);
98 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070099}
100
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700101BOOST_AUTO_TEST_CASE(CsMatched)
102{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400103 auto face1 = addFace();
104 auto face2 = addFace();
105 auto face3 = addFace();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700106
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700107 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000108 fib::Entry* entry = fib.insert("/A").first;
109 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700110
111 Pit& pit = forwarder.getPit();
112 BOOST_CHECK_EQUAL(pit.size(), 0);
113
Junxiao Shi9d727852019-05-14 13:44:22 -0600114 auto data = makeData("/A/B");
115 data->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
116 forwarder.getCs().insert(*data);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700117
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000118 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
119 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -0600120 face1->receiveInterest(*makeInterest("/A", true), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400121 this->advanceClocks(1_ms, 5_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700122 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700123 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000124 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
125 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700126
Junxiao Shicde37ad2015-12-24 01:02:05 -0700127 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700128 // IncomingFaceId field should be reset to represent CS
Junxiao Shi9d727852019-05-14 13:44:22 -0600129 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700130 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
131 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700132
Davide Pesavento14e71f02019-03-28 17:35:25 -0400133 this->advanceClocks(100_ms, 500_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700134 // PIT entry should not be left behind
135 BOOST_CHECK_EQUAL(pit.size(), 0);
136}
137
Eric Newberryfdc06452020-06-23 22:40:16 -0700138BOOST_AUTO_TEST_CASE(InterestWithoutNonce)
139{
140 auto face1 = addFace();
141 auto face2 = addFace();
142
143 Fib& fib = forwarder.getFib();
144 fib::Entry* entry = fib.insert("/A").first;
145 fib.addOrUpdateNextHop(*entry, *face2, 0);
146
147 auto interest = makeInterest("/A");
148 BOOST_CHECK_EQUAL(interest->hasNonce(), false);
149 face1->receiveInterest(*interest, 0);
150
151 // Ensure Nonce added if incoming packet did not have Nonce
152 BOOST_REQUIRE_EQUAL(face2->getCounters().nOutInterests, 1);
153 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
154 BOOST_CHECK_EQUAL(face2->sentInterests.back().hasNonce(), true);
155}
156
Junxiao Shi891f47b2016-06-20 00:02:11 +0000157BOOST_AUTO_TEST_CASE(OutgoingInterest)
158{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400159 auto face1 = addFace();
160 auto face2 = addFace();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000161
162 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600163 auto interestA1 = makeInterest("/A", false, nullopt, 8378);
Eric Newberry2377ada2020-09-28 22:40:14 -0700164 auto pitA = pit.insert(*interestA1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000165 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000166
Junxiao Shi9d727852019-05-14 13:44:22 -0600167 auto interestA2 = makeInterest("/A", false, nullopt, 1698);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400168 auto outA2 = forwarder.onOutgoingInterest(*interestA2, *face2, pitA);
Eric Newberry2377ada2020-09-28 22:40:14 -0700169 BOOST_REQUIRE(outA2 != nullptr);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000170 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000171
Eric Newberry2377ada2020-09-28 22:40:14 -0700172 // This packet will be dropped because HopLimit=0
173 auto interestA3 = makeInterest("/A", false, nullopt, 9876);
174 interestA3->setHopLimit(0);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400175 auto outA3 = forwarder.onOutgoingInterest(*interestA3, *face2, pitA);
Eric Newberry2377ada2020-09-28 22:40:14 -0700176 BOOST_CHECK(outA3 == nullptr);
177
Junxiao Shi891f47b2016-06-20 00:02:11 +0000178 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000179 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000180}
181
Junxiao Shie342e8d2016-09-18 16:48:00 +0000182BOOST_AUTO_TEST_CASE(NextHopFaceId)
183{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400184 auto face1 = addFace();
185 auto face2 = addFace();
186 auto face3 = addFace();
Junxiao Shie342e8d2016-09-18 16:48:00 +0000187
188 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000189 fib::Entry* entry = fib.insert("/A").first;
190 fib.addOrUpdateNextHop(*entry, *face3, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000191
Junxiao Shi9d727852019-05-14 13:44:22 -0600192 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000193 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
194
ashiqopu075bb7d2019-03-10 01:38:21 +0000195 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400196 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000197 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
198 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
199 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
200}
201
Eric Newberry9d283ad2020-04-12 23:37:17 -0700202BOOST_AUTO_TEST_CASE(HopLimit)
203{
204 auto faceIn = addFace();
205 auto faceRemote = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
206 auto faceLocal = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
207 Fib& fib = forwarder.getFib();
208 fib::Entry* entryRemote = fib.insert("/remote").first;
209 fib.addOrUpdateNextHop(*entryRemote, *faceRemote, 0);
210 fib::Entry* entryLocal = fib.insert("/local").first;
211 fib.addOrUpdateNextHop(*entryLocal, *faceLocal, 0);
212
213 // Incoming interest w/o HopLimit will not be dropped on send or receive paths
214 auto interestNoHopLimit = makeInterest("/remote/abcdefgh");
215 faceIn->receiveInterest(*interestNoHopLimit, 0);
216 this->advanceClocks(100_ms, 1_s);
217 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 1);
218 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
219 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
220 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 1);
221 BOOST_CHECK(!faceRemote->sentInterests.back().getHopLimit());
222
223 // Incoming interest w/ HopLimit > 1 will not be dropped on send/receive
224 auto interestHopLimit2 = makeInterest("/remote/ijklmnop");
225 interestHopLimit2->setHopLimit(2);
226 faceIn->receiveInterest(*interestHopLimit2, 0);
227 this->advanceClocks(100_ms, 1_s);
228 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
229 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
230 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
231 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 2);
232 BOOST_REQUIRE(faceRemote->sentInterests.back().getHopLimit());
233 BOOST_CHECK_EQUAL(*faceRemote->sentInterests.back().getHopLimit(), 1);
234
235 // Incoming interest w/ HopLimit == 1 will be dropped on send path if going out on remote face
236 auto interestHopLimit1Remote = makeInterest("/remote/qrstuvwx");
237 interestHopLimit1Remote->setHopLimit(1);
238 faceIn->receiveInterest(*interestHopLimit1Remote, 0);
239 this->advanceClocks(100_ms, 1_s);
240 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
241 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
242 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
243 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
244
245 // Incoming interest w/ HopLimit == 1 will not be dropped on send path if going out on local face
246 auto interestHopLimit1Local = makeInterest("/local/abcdefgh");
247 interestHopLimit1Local->setHopLimit(1);
248 faceIn->receiveInterest(*interestHopLimit1Local, 0);
249 this->advanceClocks(100_ms, 1_s);
250 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutInterests, 1);
251 BOOST_CHECK_EQUAL(faceLocal->getCounters().nInHopLimitZero, 0);
252 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutHopLimitZero, 0);
253 BOOST_REQUIRE_EQUAL(faceLocal->sentInterests.size(), 1);
254 BOOST_REQUIRE(faceLocal->sentInterests.back().getHopLimit());
255 BOOST_CHECK_EQUAL(*faceLocal->sentInterests.back().getHopLimit(), 0);
256
257 // Interest w/ HopLimit == 0 will be dropped on receive path
258 auto interestHopLimit0 = makeInterest("/remote/yzabcdef");
259 interestHopLimit0->setHopLimit(0);
260 faceIn->receiveInterest(*interestHopLimit0, 0);
261 this->advanceClocks(100_ms, 1_s);
262 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
263 BOOST_CHECK_EQUAL(faceIn->getCounters().nInHopLimitZero, 1);
264 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
265 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
266}
267
Philipp Molla1033342021-06-14 09:34:21 +0200268BOOST_AUTO_TEST_CASE(AddDefaultHopLimit)
269{
270 auto face = addFace();
271 auto faceEndpoint = FaceEndpoint(*face, 0);
272 Pit& pit = forwarder.getPit();
273 auto i1 = makeInterest("/A");
274 auto pitA = pit.insert(*i1).first;
275
276 // By default, no HopLimit should be added
277 auto i2 = makeInterest("/A");
278 BOOST_TEST(!i2->getHopLimit().has_value());
279 forwarder.onContentStoreMiss(*i2, faceEndpoint, pitA);
280 BOOST_TEST(!i2->getHopLimit().has_value());
281
282 // Change config value to 10
283 forwarder.m_config.defaultHopLimit = 10;
284
285 // HopLimit should be set to 10 now
286 auto i3 = makeInterest("/A");
287 BOOST_TEST(!i3->getHopLimit().has_value());
288 forwarder.onContentStoreMiss(*i3, faceEndpoint, pitA);
289 BOOST_REQUIRE(i3->getHopLimit().has_value());
290 BOOST_TEST(*i3->getHopLimit() == 10);
291
292 // An existing HopLimit should be preserved
293 auto i4 = makeInterest("/A");
294 i4->setHopLimit(50);
295 forwarder.onContentStoreMiss(*i4, faceEndpoint, pitA);
296 BOOST_REQUIRE(i4->getHopLimit().has_value());
297 BOOST_TEST(*i4->getHopLimit() == 50);
298}
299
Davide Pesavento05590472021-02-17 15:53:27 -0500300BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700301{
Davide Pesavento05590472021-02-17 15:53:27 -0500302 auto face1 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
303 auto face2 = addFace(); // default is non-local
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400304
Davide Pesavento05590472021-02-17 15:53:27 -0500305 auto& strategy = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
Junxiao Shic041ca32014-02-25 20:01:15 -0700306
Junxiao Shi88884492014-02-15 15:57:43 -0700307 // local face, /localhost: OK
Davide Pesavento05590472021-02-17 15:53:27 -0500308 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600309 auto i1 = makeInterest("/localhost/A1");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400310 forwarder.onIncomingInterest(*i1, FaceEndpoint(*face1, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500311 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700312
Junxiao Shi88884492014-02-15 15:57:43 -0700313 // non-local face, /localhost: violate
Davide Pesavento05590472021-02-17 15:53:27 -0500314 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600315 auto i2 = makeInterest("/localhost/A2");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400316 forwarder.onIncomingInterest(*i2, FaceEndpoint(*face2, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500317 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700318
Junxiao Shi88884492014-02-15 15:57:43 -0700319 // local face, non-/localhost: OK
Davide Pesavento05590472021-02-17 15:53:27 -0500320 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600321 auto i3 = makeInterest("/A3");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400322 forwarder.onIncomingInterest(*i3, FaceEndpoint(*face1, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500323 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700324
Junxiao Shi88884492014-02-15 15:57:43 -0700325 // non-local face, non-/localhost: OK
Davide Pesavento05590472021-02-17 15:53:27 -0500326 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600327 auto i4 = makeInterest("/A4");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400328 forwarder.onIncomingInterest(*i4, FaceEndpoint(*face2, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500329 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700330
Alex Lane6bead9b2020-05-12 19:08:20 -0500331 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
332
Junxiao Shi88884492014-02-15 15:57:43 -0700333 // local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600334 auto d1 = makeData("/localhost/B1");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400335 forwarder.onIncomingData(*d1, FaceEndpoint(*face1, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500336 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700337
Davide Pesavento05590472021-02-17 15:53:27 -0500338 // non-local face, /localhost: violate
Junxiao Shi9d727852019-05-14 13:44:22 -0600339 auto d2 = makeData("/localhost/B2");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400340 forwarder.onIncomingData(*d2, FaceEndpoint(*face2, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500341 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700342
Junxiao Shi88884492014-02-15 15:57:43 -0700343 // local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600344 auto d3 = makeData("/B3");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400345 forwarder.onIncomingData(*d3, FaceEndpoint(*face1, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500346 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 2);
Junxiao Shi88884492014-02-15 15:57:43 -0700347
348 // non-local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600349 auto d4 = makeData("/B4");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400350 forwarder.onIncomingData(*d4, FaceEndpoint(*face2, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500351 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 3);
Junxiao Shi88884492014-02-15 15:57:43 -0700352}
353
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700354BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700355{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400356 auto face1 = addFace();
357 auto face2 = addFace();
Junxiao Shif3c07812014-03-11 21:48:49 -0700358
Eric Newberry2377ada2020-09-28 22:40:14 -0700359 auto& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
360 auto& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700361
Junxiao Shi9d727852019-05-14 13:44:22 -0600362 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000363 strategyA.afterReceiveInterest_count = 0;
364 strategyA.interestOutFace = face2;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400365 forwarder.onIncomingInterest(*interest1, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000366 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700367
Junxiao Shi9d727852019-05-14 13:44:22 -0600368 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000369 strategyB.afterReceiveInterest_count = 0;
370 strategyB.interestOutFace = face2;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400371 forwarder.onIncomingInterest(*interest2, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000372 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700373
Davide Pesavento14e71f02019-03-28 17:35:25 -0400374 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700375
Junxiao Shi9d727852019-05-14 13:44:22 -0600376 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000377 strategyA.beforeSatisfyInterest_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400378 forwarder.onIncomingData(*data1, FaceEndpoint(*face2, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000379 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700380
Junxiao Shi9d727852019-05-14 13:44:22 -0600381 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000382 strategyB.beforeSatisfyInterest_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400383 forwarder.onIncomingData(*data2, FaceEndpoint(*face2, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000384 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700385
Junxiao Shi9d727852019-05-14 13:44:22 -0600386 auto interest3 = makeInterest("/A/3", false, 30_ms);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400387 forwarder.onIncomingInterest(*interest3, FaceEndpoint(*face1, 0));
Junxiao Shi9d727852019-05-14 13:44:22 -0600388 auto interest4 = makeInterest("/B/4", false, 5_s);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400389 forwarder.onIncomingInterest(*interest4, FaceEndpoint(*face1, 0));
Junxiao Shif3c07812014-03-11 21:48:49 -0700390}
391
Junxiao Shida006f52014-05-16 11:18:00 -0700392BOOST_AUTO_TEST_CASE(IncomingData)
393{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400394 auto face1 = addFace();
395 auto face2 = addFace();
396 auto face3 = addFace();
397 auto face4 = addFace();
Junxiao Shida006f52014-05-16 11:18:00 -0700398
399 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600400 auto interestD = makeInterest("/A/B/C/D");
Eric Newberry2377ada2020-09-28 22:40:14 -0700401 auto pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000402 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600403 auto interestA = makeInterest("/A", true);
Eric Newberry2377ada2020-09-28 22:40:14 -0700404 auto pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000405 pitA->insertOrUpdateInRecord(*face2, *interestA);
406 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600407 auto interestC = makeInterest("/A/B/C", true);
Eric Newberry2377ada2020-09-28 22:40:14 -0700408 auto pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000409 pitC->insertOrUpdateInRecord(*face3, *interestC);
410 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700411
Junxiao Shi9d727852019-05-14 13:44:22 -0600412 auto dataD = makeData("/A/B/C/D");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400413 forwarder.onIncomingData(*dataD, FaceEndpoint(*face3, 0));
Davide Pesavento14e71f02019-03-28 17:35:25 -0400414 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700415
Junxiao Shicde37ad2015-12-24 01:02:05 -0700416 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
417 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
418 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
419 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500420
421 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
422 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 3);
423 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shida006f52014-05-16 11:18:00 -0700424}
425
Eric Newberry2377ada2020-09-28 22:40:14 -0700426BOOST_AUTO_TEST_CASE(OutgoingData)
427{
428 auto face1 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
429 auto face2 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
430 auto face3 = addFace();
431 face3->setId(face::INVALID_FACEID);
432
433 auto data = makeData("/QkzAWU6K");
434 auto localData = makeData("/localhost/YH8bqnbv");
435
436 face1->sentData.clear();
437 BOOST_CHECK(forwarder.onOutgoingData(*data, *face1));
438 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
439 BOOST_CHECK_EQUAL(face1->sentData.back().getName(), data->getName());
440
441 // scope control
442 face1->sentData.clear();
443 face2->sentData.clear();
444 BOOST_CHECK(!forwarder.onOutgoingData(*localData, *face2));
445 BOOST_CHECK_EQUAL(face2->sentData.size(), 0);
446 BOOST_CHECK(forwarder.onOutgoingData(*localData, *face1));
447 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
448 BOOST_CHECK_EQUAL(face1->sentData.back().getName(), localData->getName());
449
450 // face with invalid ID
451 face3->sentData.clear();
452 BOOST_CHECK(!forwarder.onOutgoingData(*data, *face3));
453 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
454}
455
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700456BOOST_AUTO_TEST_CASE(IncomingNack)
457{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400458 auto face1 = addFace();
459 auto face2 = addFace();
460 auto face3 = addFace("dummy://", "dummy://",
461 ndn::nfd::FACE_SCOPE_NON_LOCAL,
462 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
463 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700464
Eric Newberry2377ada2020-09-28 22:40:14 -0700465 auto& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
466 auto& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700467
468 Pit& pit = forwarder.getPit();
469
470 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600471 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Eric Newberry2377ada2020-09-28 22:40:14 -0700472 auto pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000473 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600474 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Eric Newberry2377ada2020-09-28 22:40:14 -0700475 auto pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000476 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700477
Eric Newberry2377ada2020-09-28 22:40:14 -0700478 auto nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000479 strategyA.afterReceiveNack_count = 0;
480 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400481 forwarder.onIncomingNack(nack1, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000482 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
483 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700484
Eric Newberry2377ada2020-09-28 22:40:14 -0700485 auto nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000486 strategyA.afterReceiveNack_count = 0;
487 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400488 forwarder.onIncomingNack(nack2, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000489 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
490 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700491
492 // record Nack on PIT out-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500493 auto outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700494 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700495 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
496 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
497
498 // drop if no PIT entry
Eric Newberry2377ada2020-09-28 22:40:14 -0700499 auto nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000500 strategyA.afterReceiveNack_count = 0;
501 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400502 forwarder.onIncomingNack(nack3, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000503 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
504 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700505
506 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600507 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Eric Newberry2377ada2020-09-28 22:40:14 -0700508 auto pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000509 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700510
Eric Newberry2377ada2020-09-28 22:40:14 -0700511 auto nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000512 strategyA.afterReceiveNack_count = 0;
513 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400514 forwarder.onIncomingNack(nack4a, FaceEndpoint(*face2, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000515 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
516 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700517
518 // drop if Nonce does not match out-record
Eric Newberry2377ada2020-09-28 22:40:14 -0700519 auto nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000520 strategyA.afterReceiveNack_count = 0;
521 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400522 forwarder.onIncomingNack(nack4b, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000523 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
524 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700525
526 // drop if inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000527 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000528 strategyA.afterReceiveNack_count = 0;
529 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400530 forwarder.onIncomingNack(nack4a, FaceEndpoint(*face3, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000531 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
532 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700533}
534
535BOOST_AUTO_TEST_CASE(OutgoingNack)
536{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400537 auto face1 = addFace();
538 auto face2 = addFace();
539 auto face3 = addFace("dummy://", "dummy://",
540 ndn::nfd::FACE_SCOPE_NON_LOCAL,
541 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
542 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Eric Newberry2377ada2020-09-28 22:40:14 -0700543 auto face4 = addFace();
544 face4->setId(face::INVALID_FACEID);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700545
546 Pit& pit = forwarder.getPit();
547
548 lp::NackHeader nackHeader;
549 nackHeader.setReason(lp::NackReason::CONGESTION);
550
551 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600552 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Eric Newberry2377ada2020-09-28 22:40:14 -0700553 auto pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000554 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700555
556 face2->sentNacks.clear();
Davide Pesavento0498ce82021-06-14 02:02:21 -0400557 BOOST_CHECK(!forwarder.onOutgoingNack(nackHeader, *face2, pit1));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700558 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
559
560 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600561 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Eric Newberry2377ada2020-09-28 22:40:14 -0700562 auto pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000563 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600564 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000565 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700566 face1->sentNacks.clear();
Eric Newberry2377ada2020-09-28 22:40:14 -0700567 face2->sentNacks.clear();
568
Davide Pesavento0498ce82021-06-14 02:02:21 -0400569 BOOST_CHECK(forwarder.onOutgoingNack(nackHeader, *face1, pit2));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700570 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
571 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
572 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
Eric Newberry2377ada2020-09-28 22:40:14 -0700573 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700574
Eric Newberry2377ada2020-09-28 22:40:14 -0700575 // in-record is erased
Alex Lane6bead9b2020-05-12 19:08:20 -0500576 auto inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700577 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700578
579 // send Nack with correct Nonce
Davide Pesavento0498ce82021-06-14 02:02:21 -0400580 BOOST_CHECK(forwarder.onOutgoingNack(nackHeader, *face2, pit2));
Eric Newberry2377ada2020-09-28 22:40:14 -0700581 BOOST_CHECK_EQUAL(face1->sentNacks.size(), 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700582 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
583 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
584 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
585
Eric Newberry2377ada2020-09-28 22:40:14 -0700586 // in-record is erased
587 auto inRecord2b = pit2->getInRecord(*face2);
Junxiao Shi4846f372016-04-05 13:39:30 -0700588 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700589
590 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600591 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000592 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700593
594 face3->sentNacks.clear();
Davide Pesavento0498ce82021-06-14 02:02:21 -0400595 BOOST_CHECK(!forwarder.onOutgoingNack(nackHeader, *face3, pit2));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700596 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
Eric Newberry2377ada2020-09-28 22:40:14 -0700597
598 // don't send Nack to face with invalid ID
599 auto interest1b = makeInterest("/fM5IVEtC", false, nullopt, 553);
600 pit1->insertOrUpdateInRecord(*face4, *interest1b);
601
602 face4->sentNacks.clear();
Davide Pesavento0498ce82021-06-14 02:02:21 -0400603 BOOST_CHECK(!forwarder.onOutgoingNack(nackHeader, *face4, pit1));
Eric Newberry2377ada2020-09-28 22:40:14 -0700604 BOOST_CHECK_EQUAL(face4->sentNacks.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700605}
606
607BOOST_AUTO_TEST_CASE(InterestLoopNack)
608{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400609 auto face1 = addFace();
610 auto face2 = addFace();
611 auto face3 = addFace("dummy://", "dummy://",
612 ndn::nfd::FACE_SCOPE_NON_LOCAL,
613 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
614 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
615 auto face4 = addFace();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700616
617 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000618 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
619 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700620
621 // receive Interest on face1
622 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600623 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000624 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700625 BOOST_CHECK(face1->sentNacks.empty());
626
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000627 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700628 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600629 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000630 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000631 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700632
633 // receive Interest with duplicate Nonce on face2
634 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600635 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000636 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700637 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400638 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700639 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
640
641 // receive Interest with new Nonce on face2
642 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600643 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000644 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700645 BOOST_CHECK(face2->sentNacks.empty());
646
647 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
648 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600649 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000650 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700651 BOOST_CHECK(face3->sentNacks.empty());
652}
653
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400654BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700655{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400656 auto face1 = addFace();
657 auto face2 = addFace();
Junxiao Shia110f262014-10-12 12:35:20 -0700658
659 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700660 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
661 if (pktType == tlv::Interest) {
662 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000663 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700664 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700665 });
Junxiao Shia110f262014-10-12 12:35:20 -0700666
667 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000668 fib::Entry* entry = fib.insert("/A").first;
669 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700670
Junxiao Shi455581d2014-11-17 18:38:40 -0700671 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600672 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000673 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700674
Junxiao Shi455581d2014-11-17 18:38:40 -0700675 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400676 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
677 this->advanceClocks(25_ms, 40);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700678 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700679
680 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
681 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
682 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
683 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
684 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700685}
686
Junxiao Shid41d6072016-06-19 23:35:27 +0000687BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700688{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400689 auto face1 = addFace();
Junxiao Shi9d727852019-05-14 13:44:22 -0600690 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700691
Davide Pesavento0498ce82021-06-14 02:02:21 -0400692 auto& dnl = forwarder.getDeadNonceList();
Junxiao Shi330136a2016-03-10 04:53:08 -0700693 dnl.add(interest->getName(), interest->getNonce());
Davide Pesavento0498ce82021-06-14 02:02:21 -0400694 auto& pit = forwarder.getPit();
695 BOOST_CHECK_EQUAL(pit.size(), 0);
Junxiao Shi330136a2016-03-10 04:53:08 -0700696
Davide Pesavento0498ce82021-06-14 02:02:21 -0400697 forwarder.onIncomingInterest(*interest, FaceEndpoint(*face1, 0));
Davide Pesavento14e71f02019-03-28 17:35:25 -0400698 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700699 BOOST_CHECK_EQUAL(pit.size(), 0);
700}
701
Alex Lane6bead9b2020-05-12 19:08:20 -0500702BOOST_AUTO_TEST_CASE(UnsolicitedData)
703{
704 auto face1 = addFace();
705 auto data = makeData("/A");
706
707 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400708 forwarder.onIncomingData(*data, FaceEndpoint(*face1, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500709 this->advanceClocks(1_ms, 10_ms);
710 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
711}
712
Davide Pesaventob21bed82021-02-13 00:20:06 -0500713BOOST_AUTO_TEST_CASE(NewNextHop)
714{
715 auto face1 = addFace();
716 auto face2 = addFace();
717 auto face3 = addFace();
718 auto face4 = addFace();
719
720 auto& strategy = choose<DummyStrategy>(forwarder, "/A", DummyStrategy::getStrategyName());
721
722 Fib& fib = forwarder.getFib();
723 Pit& pit = forwarder.getPit();
724
725 // fib: "/", "/A/B", "/A/B/C/D/E"
726 fib::Entry* entry = fib.insert("/").first;
727 fib.addOrUpdateNextHop(*entry, *face1, 100);
728 entry = fib.insert("/A/B").first;
729 fib.addOrUpdateNextHop(*entry, *face2, 0);
730 entry = fib.insert("/A/B/C/D/E").first;
731 fib.addOrUpdateNextHop(*entry, *face3, 0);
732
733 // pit: "/A", "/A/B/C", "/A/B/Z"
734 auto interest1 = makeInterest("/A");
735 auto pit1 = pit.insert(*interest1).first;
736 pit1->insertOrUpdateInRecord(*face3, *interest1);
737 auto interest2 = makeInterest("/A/B/C");
738 auto pit2 = pit.insert(*interest2).first;
739 pit2->insertOrUpdateInRecord(*face3, *interest2);
740 auto interest3 = makeInterest("/A/B/Z");
741 auto pit3 = pit.insert(*interest3).first;
742 pit3->insertOrUpdateInRecord(*face3, *interest3);
743
744 // new nexthop for "/"
745 entry = fib.insert("/").first;
746 fib.addOrUpdateNextHop(*entry, *face2, 50);
747
748 // /A --> triggered
749 // /A/B/C --> not triggered
750 // /A/B/Z --> not triggered
751 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 1);
752 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
753 strategy.afterNewNextHopCalls.clear();
754
755 // new nexthop for "/A"
756 entry = fib.insert("/A").first;
757 fib.addOrUpdateNextHop(*entry, *face4, 50);
758
759 // /A --> triggered
760 // /A/B/C --> not triggered
761 // /A/B/Z --> not triggered
762 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 1);
763 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
764 strategy.afterNewNextHopCalls.clear();
765
766 // new nexthop for "/A/B"
767 entry = fib.insert("/A/B").first;
768 fib.addOrUpdateNextHop(*entry, *face4, 0);
769
770 // /A --> not triggered
771 // /A/B/C --> triggered
772 // /A/B/Z --> triggered
773 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 2);
774 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A/B/C");
775 BOOST_TEST(strategy.afterNewNextHopCalls[1] == "/A/B/Z");
776 strategy.afterNewNextHopCalls.clear();
777
778 // new nexthop for "/A/B/C/D"
779 entry = fib.insert("/A/B/C/D").first;
780 fib.addOrUpdateNextHop(*entry, *face1, 0);
781
782 // nothing triggered
783 BOOST_TEST(strategy.afterNewNextHopCalls.size() == 0);
784
785 // create a second pit entry for /A
786 auto interest4 = makeInterest("/A");
787 interest4->setMustBeFresh(true);
788 auto pit4 = pit.insert(*interest4).first;
789 pit4->insertOrUpdateInRecord(*face3, *interest4);
790
791 // new nexthop for "/A"
792 entry = fib.insert("/A").first;
793 fib.addOrUpdateNextHop(*entry, *face1, 0);
794
795 // /A --> triggered twice
796 // /A/B/C --> not triggered
797 // /A/B/Z --> not triggered
798 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 2);
799 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
800 BOOST_TEST(strategy.afterNewNextHopCalls[1] == "/A");
801}
802
Philipp Molla1033342021-06-14 09:34:21 +0200803BOOST_AUTO_TEST_SUITE(ProcessConfig)
804
805BOOST_AUTO_TEST_CASE(DefaultHopLimit)
806{
807 ConfigFile cf;
808 forwarder.setConfigFile(cf);
809
810 std::string config = R"CONFIG(
811 forwarder
812 {
813 default_hop_limit 10
814 }
815 )CONFIG";
816
817 // The default value is 0
818 BOOST_TEST(forwarder.m_config.defaultHopLimit == 0);
819
820 // Dry run parsing should not change the default config
821 cf.parse(config, true, "dummy-config");
822 BOOST_TEST(forwarder.m_config.defaultHopLimit == 0);
823
824 // Check if the actual parsing works
825 cf.parse(config, false, "dummy-config");
826 BOOST_TEST(forwarder.m_config.defaultHopLimit == 10);
827
828 // After removing default_hop_limit from the config file,
829 // the default value of zero should be restored
830 config = R"CONFIG(
831 forwarder
832 {
833 }
834 )CONFIG";
835
836 cf.parse(config, false, "dummy-config");
837 BOOST_TEST(forwarder.m_config.defaultHopLimit == 0);
838}
839
840BOOST_AUTO_TEST_CASE(BadDefaultHopLimit)
841{
842 ConfigFile cf;
843 forwarder.setConfigFile(cf);
844
845 // not a number
846 std::string config = R"CONFIG(
847 forwarder
848 {
849 default_hop_limit hello
850 }
851 )CONFIG";
852
853 BOOST_CHECK_THROW(cf.parse(config, true, "dummy-config"), ConfigFile::Error);
854 BOOST_CHECK_THROW(cf.parse(config, false, "dummy-config"), ConfigFile::Error);
855
856 // negative number
857 config = R"CONFIG(
858 forwarder
859 {
860 default_hop_limit -1
861 }
862 )CONFIG";
863
864 BOOST_CHECK_THROW(cf.parse(config, true, "dummy-config"), ConfigFile::Error);
865 BOOST_CHECK_THROW(cf.parse(config, false, "dummy-config"), ConfigFile::Error);
866
867 // out of range
868 config = R"CONFIG(
869 forwarder
870 {
871 default_hop_limit 256
872 }
873 )CONFIG";
874
875 BOOST_CHECK_THROW(cf.parse(config, true, "dummy-config"), ConfigFile::Error);
876 BOOST_CHECK_THROW(cf.parse(config, false, "dummy-config"), ConfigFile::Error);
877}
878
879BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
880
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400881BOOST_AUTO_TEST_SUITE_END() // TestForwarder
882BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700883
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700884} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700885} // namespace nfd