blob: f3f7c6374578f4e10bceffc31addcd8707dba36b [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);
Eric Newberry2377ada2020-09-28 22:40:14 -0700168 auto outA2 = forwarder.onOutgoingInterest(pitA, *face2, *interestA2);
169 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);
175 auto outA3 = forwarder.onOutgoingInterest(pitA, *face2, *interestA3);
176 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
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700268class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700269{
270public:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400271 using Forwarder::Forwarder;
272
Junxiao Shi88884492014-02-15 15:57:43 -0700273protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000274 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400275 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700276 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700277 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700278 }
279
280public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400281 int dispatchToStrategy_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700282};
283
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400284BOOST_FIXTURE_TEST_CASE(ScopeLocalhostIncoming, GlobalIoTimeFixture)
Junxiao Shi88884492014-02-15 15:57:43 -0700285{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400286 FaceTable faceTable;
287 ScopeLocalhostIncomingTestForwarder forwarder(faceTable);
288
Junxiao Shicde37ad2015-12-24 01:02:05 -0700289 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
290 auto face2 = make_shared<DummyFace>();
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400291 faceTable.add(face1);
292 faceTable.add(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700293
Junxiao Shi88884492014-02-15 15:57:43 -0700294 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700295 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600296 auto i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000297 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700298 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700299
Junxiao Shi88884492014-02-15 15:57:43 -0700300 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700301 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600302 auto i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000303 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700304 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700305
Junxiao Shi88884492014-02-15 15:57:43 -0700306 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700307 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600308 auto i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000309 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700310 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700311
Junxiao Shi88884492014-02-15 15:57:43 -0700312 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700313 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600314 auto i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000315 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700316 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700317
Alex Lane6bead9b2020-05-12 19:08:20 -0500318 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
319
Junxiao Shi88884492014-02-15 15:57:43 -0700320 // local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600321 auto d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000322 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500323 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700324
325 // non-local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600326 auto d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000327 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Alex Lane6bead9b2020-05-12 19:08:20 -0500328 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700329
Junxiao Shi88884492014-02-15 15:57:43 -0700330 // local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600331 auto d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000332 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Alex Lane6bead9b2020-05-12 19:08:20 -0500333 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 2);
Junxiao Shi88884492014-02-15 15:57:43 -0700334
335 // non-local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600336 auto d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000337 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Alex Lane6bead9b2020-05-12 19:08:20 -0500338 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 3);
Junxiao Shi88884492014-02-15 15:57:43 -0700339}
340
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700341BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700342{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400343 auto face1 = addFace();
344 auto face2 = addFace();
Junxiao Shif3c07812014-03-11 21:48:49 -0700345
Eric Newberry2377ada2020-09-28 22:40:14 -0700346 auto& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
347 auto& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700348
Junxiao Shi9d727852019-05-14 13:44:22 -0600349 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000350 strategyA.afterReceiveInterest_count = 0;
351 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000352 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000353 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700354
Junxiao Shi9d727852019-05-14 13:44:22 -0600355 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000356 strategyB.afterReceiveInterest_count = 0;
357 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000358 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000359 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700360
Davide Pesavento14e71f02019-03-28 17:35:25 -0400361 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700362
Junxiao Shi9d727852019-05-14 13:44:22 -0600363 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000364 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000365 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000366 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700367
Junxiao Shi9d727852019-05-14 13:44:22 -0600368 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000369 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000370 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000371 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700372
Junxiao Shi9d727852019-05-14 13:44:22 -0600373 auto interest3 = makeInterest("/A/3", false, 30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000374 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shi9d727852019-05-14 13:44:22 -0600375 auto interest4 = makeInterest("/B/4", false, 5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000376 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700377}
378
Junxiao Shida006f52014-05-16 11:18:00 -0700379BOOST_AUTO_TEST_CASE(IncomingData)
380{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400381 auto face1 = addFace();
382 auto face2 = addFace();
383 auto face3 = addFace();
384 auto face4 = addFace();
Junxiao Shida006f52014-05-16 11:18:00 -0700385
386 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600387 auto interestD = makeInterest("/A/B/C/D");
Eric Newberry2377ada2020-09-28 22:40:14 -0700388 auto pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000389 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600390 auto interestA = makeInterest("/A", true);
Eric Newberry2377ada2020-09-28 22:40:14 -0700391 auto pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000392 pitA->insertOrUpdateInRecord(*face2, *interestA);
393 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600394 auto interestC = makeInterest("/A/B/C", true);
Eric Newberry2377ada2020-09-28 22:40:14 -0700395 auto pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000396 pitC->insertOrUpdateInRecord(*face3, *interestC);
397 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700398
Junxiao Shi9d727852019-05-14 13:44:22 -0600399 auto dataD = makeData("/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000400 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400401 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700402
Junxiao Shicde37ad2015-12-24 01:02:05 -0700403 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
404 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
405 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
406 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500407
408 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
409 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 3);
410 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shida006f52014-05-16 11:18:00 -0700411}
412
Eric Newberry2377ada2020-09-28 22:40:14 -0700413BOOST_AUTO_TEST_CASE(OutgoingData)
414{
415 auto face1 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
416 auto face2 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
417 auto face3 = addFace();
418 face3->setId(face::INVALID_FACEID);
419
420 auto data = makeData("/QkzAWU6K");
421 auto localData = makeData("/localhost/YH8bqnbv");
422
423 face1->sentData.clear();
424 BOOST_CHECK(forwarder.onOutgoingData(*data, *face1));
425 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
426 BOOST_CHECK_EQUAL(face1->sentData.back().getName(), data->getName());
427
428 // scope control
429 face1->sentData.clear();
430 face2->sentData.clear();
431 BOOST_CHECK(!forwarder.onOutgoingData(*localData, *face2));
432 BOOST_CHECK_EQUAL(face2->sentData.size(), 0);
433 BOOST_CHECK(forwarder.onOutgoingData(*localData, *face1));
434 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
435 BOOST_CHECK_EQUAL(face1->sentData.back().getName(), localData->getName());
436
437 // face with invalid ID
438 face3->sentData.clear();
439 BOOST_CHECK(!forwarder.onOutgoingData(*data, *face3));
440 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
441}
442
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700443BOOST_AUTO_TEST_CASE(IncomingNack)
444{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400445 auto face1 = addFace();
446 auto face2 = addFace();
447 auto face3 = addFace("dummy://", "dummy://",
448 ndn::nfd::FACE_SCOPE_NON_LOCAL,
449 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
450 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700451
Eric Newberry2377ada2020-09-28 22:40:14 -0700452 auto& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
453 auto& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700454
455 Pit& pit = forwarder.getPit();
456
457 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600458 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Eric Newberry2377ada2020-09-28 22:40:14 -0700459 auto pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000460 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600461 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Eric Newberry2377ada2020-09-28 22:40:14 -0700462 auto pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000463 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700464
Eric Newberry2377ada2020-09-28 22:40:14 -0700465 auto nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000466 strategyA.afterReceiveNack_count = 0;
467 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000468 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000469 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
470 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700471
Eric Newberry2377ada2020-09-28 22:40:14 -0700472 auto nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000473 strategyA.afterReceiveNack_count = 0;
474 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000475 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000476 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
477 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700478
479 // record Nack on PIT out-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500480 auto outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700481 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700482 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
483 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
484
485 // drop if no PIT entry
Eric Newberry2377ada2020-09-28 22:40:14 -0700486 auto nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000487 strategyA.afterReceiveNack_count = 0;
488 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000489 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000490 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
491 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700492
493 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600494 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Eric Newberry2377ada2020-09-28 22:40:14 -0700495 auto pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000496 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700497
Eric Newberry2377ada2020-09-28 22:40:14 -0700498 auto nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000499 strategyA.afterReceiveNack_count = 0;
500 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000501 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000502 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
503 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700504
505 // drop if Nonce does not match out-record
Eric Newberry2377ada2020-09-28 22:40:14 -0700506 auto nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000507 strategyA.afterReceiveNack_count = 0;
508 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000509 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000510 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
511 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700512
513 // drop if inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000514 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000515 strategyA.afterReceiveNack_count = 0;
516 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000517 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000518 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
519 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700520}
521
522BOOST_AUTO_TEST_CASE(OutgoingNack)
523{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400524 auto face1 = addFace();
525 auto face2 = addFace();
526 auto face3 = addFace("dummy://", "dummy://",
527 ndn::nfd::FACE_SCOPE_NON_LOCAL,
528 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
529 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Eric Newberry2377ada2020-09-28 22:40:14 -0700530 auto face4 = addFace();
531 face4->setId(face::INVALID_FACEID);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700532
533 Pit& pit = forwarder.getPit();
534
535 lp::NackHeader nackHeader;
536 nackHeader.setReason(lp::NackReason::CONGESTION);
537
538 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600539 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Eric Newberry2377ada2020-09-28 22:40:14 -0700540 auto pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000541 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700542
543 face2->sentNacks.clear();
Eric Newberry2377ada2020-09-28 22:40:14 -0700544 BOOST_CHECK(!forwarder.onOutgoingNack(pit1, *face2, nackHeader));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700545 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
546
547 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600548 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Eric Newberry2377ada2020-09-28 22:40:14 -0700549 auto pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000550 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600551 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000552 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700553 face1->sentNacks.clear();
Eric Newberry2377ada2020-09-28 22:40:14 -0700554 face2->sentNacks.clear();
555
556 BOOST_CHECK(forwarder.onOutgoingNack(pit2, *face1, nackHeader));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700557 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
558 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
559 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
Eric Newberry2377ada2020-09-28 22:40:14 -0700560 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700561
Eric Newberry2377ada2020-09-28 22:40:14 -0700562 // in-record is erased
Alex Lane6bead9b2020-05-12 19:08:20 -0500563 auto inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700564 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700565
566 // send Nack with correct Nonce
Eric Newberry2377ada2020-09-28 22:40:14 -0700567 BOOST_CHECK(forwarder.onOutgoingNack(pit2, *face2, nackHeader));
568 BOOST_CHECK_EQUAL(face1->sentNacks.size(), 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700569 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
570 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
571 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
572
Eric Newberry2377ada2020-09-28 22:40:14 -0700573 // in-record is erased
574 auto inRecord2b = pit2->getInRecord(*face2);
Junxiao Shi4846f372016-04-05 13:39:30 -0700575 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700576
577 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600578 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000579 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700580
581 face3->sentNacks.clear();
Eric Newberry2377ada2020-09-28 22:40:14 -0700582 BOOST_CHECK(!forwarder.onOutgoingNack(pit2, *face3, nackHeader));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700583 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
Eric Newberry2377ada2020-09-28 22:40:14 -0700584
585 // don't send Nack to face with invalid ID
586 auto interest1b = makeInterest("/fM5IVEtC", false, nullopt, 553);
587 pit1->insertOrUpdateInRecord(*face4, *interest1b);
588
589 face4->sentNacks.clear();
590 BOOST_CHECK(!forwarder.onOutgoingNack(pit1, *face4, nackHeader));
591 BOOST_CHECK_EQUAL(face4->sentNacks.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700592}
593
594BOOST_AUTO_TEST_CASE(InterestLoopNack)
595{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400596 auto face1 = addFace();
597 auto face2 = addFace();
598 auto face3 = addFace("dummy://", "dummy://",
599 ndn::nfd::FACE_SCOPE_NON_LOCAL,
600 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
601 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
602 auto face4 = addFace();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700603
604 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000605 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
606 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700607
608 // receive Interest on face1
609 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600610 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000611 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700612 BOOST_CHECK(face1->sentNacks.empty());
613
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000614 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700615 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600616 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000617 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000618 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700619
620 // receive Interest with duplicate Nonce on face2
621 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600622 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000623 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700624 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400625 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700626 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
627
628 // receive Interest with new Nonce on face2
629 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600630 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000631 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700632 BOOST_CHECK(face2->sentNacks.empty());
633
634 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
635 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600636 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000637 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700638 BOOST_CHECK(face3->sentNacks.empty());
639}
640
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400641BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700642{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400643 auto face1 = addFace();
644 auto face2 = addFace();
Junxiao Shia110f262014-10-12 12:35:20 -0700645
646 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700647 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
648 if (pktType == tlv::Interest) {
649 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000650 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700651 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700652 });
Junxiao Shia110f262014-10-12 12:35:20 -0700653
654 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000655 fib::Entry* entry = fib.insert("/A").first;
656 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700657
Junxiao Shi455581d2014-11-17 18:38:40 -0700658 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600659 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000660 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700661
Junxiao Shi455581d2014-11-17 18:38:40 -0700662 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400663 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
664 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700665
Junxiao Shicde37ad2015-12-24 01:02:05 -0700666 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700667
668 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
669 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
670 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
671 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
672 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700673}
674
Junxiao Shid41d6072016-06-19 23:35:27 +0000675BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700676{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400677 auto face1 = addFace();
Junxiao Shi9d727852019-05-14 13:44:22 -0600678 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700679
680 DeadNonceList& dnl = forwarder.getDeadNonceList();
681 dnl.add(interest->getName(), interest->getNonce());
682 Pit& pit = forwarder.getPit();
683 BOOST_REQUIRE_EQUAL(pit.size(), 0);
684
ashiqopuc7079482019-02-20 05:34:37 +0000685 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400686 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700687 BOOST_CHECK_EQUAL(pit.size(), 0);
688}
689
Alex Lane6bead9b2020-05-12 19:08:20 -0500690BOOST_AUTO_TEST_CASE(UnsolicitedData)
691{
692 auto face1 = addFace();
693 auto data = makeData("/A");
694
695 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
696 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *data);
697 this->advanceClocks(1_ms, 10_ms);
698 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
699}
700
Davide Pesaventob21bed82021-02-13 00:20:06 -0500701BOOST_AUTO_TEST_CASE(NewNextHop)
702{
703 auto face1 = addFace();
704 auto face2 = addFace();
705 auto face3 = addFace();
706 auto face4 = addFace();
707
708 auto& strategy = choose<DummyStrategy>(forwarder, "/A", DummyStrategy::getStrategyName());
709
710 Fib& fib = forwarder.getFib();
711 Pit& pit = forwarder.getPit();
712
713 // fib: "/", "/A/B", "/A/B/C/D/E"
714 fib::Entry* entry = fib.insert("/").first;
715 fib.addOrUpdateNextHop(*entry, *face1, 100);
716 entry = fib.insert("/A/B").first;
717 fib.addOrUpdateNextHop(*entry, *face2, 0);
718 entry = fib.insert("/A/B/C/D/E").first;
719 fib.addOrUpdateNextHop(*entry, *face3, 0);
720
721 // pit: "/A", "/A/B/C", "/A/B/Z"
722 auto interest1 = makeInterest("/A");
723 auto pit1 = pit.insert(*interest1).first;
724 pit1->insertOrUpdateInRecord(*face3, *interest1);
725 auto interest2 = makeInterest("/A/B/C");
726 auto pit2 = pit.insert(*interest2).first;
727 pit2->insertOrUpdateInRecord(*face3, *interest2);
728 auto interest3 = makeInterest("/A/B/Z");
729 auto pit3 = pit.insert(*interest3).first;
730 pit3->insertOrUpdateInRecord(*face3, *interest3);
731
732 // new nexthop for "/"
733 entry = fib.insert("/").first;
734 fib.addOrUpdateNextHop(*entry, *face2, 50);
735
736 // /A --> triggered
737 // /A/B/C --> not triggered
738 // /A/B/Z --> not triggered
739 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 1);
740 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
741 strategy.afterNewNextHopCalls.clear();
742
743 // new nexthop for "/A"
744 entry = fib.insert("/A").first;
745 fib.addOrUpdateNextHop(*entry, *face4, 50);
746
747 // /A --> triggered
748 // /A/B/C --> not triggered
749 // /A/B/Z --> not triggered
750 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 1);
751 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
752 strategy.afterNewNextHopCalls.clear();
753
754 // new nexthop for "/A/B"
755 entry = fib.insert("/A/B").first;
756 fib.addOrUpdateNextHop(*entry, *face4, 0);
757
758 // /A --> not triggered
759 // /A/B/C --> triggered
760 // /A/B/Z --> triggered
761 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 2);
762 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A/B/C");
763 BOOST_TEST(strategy.afterNewNextHopCalls[1] == "/A/B/Z");
764 strategy.afterNewNextHopCalls.clear();
765
766 // new nexthop for "/A/B/C/D"
767 entry = fib.insert("/A/B/C/D").first;
768 fib.addOrUpdateNextHop(*entry, *face1, 0);
769
770 // nothing triggered
771 BOOST_TEST(strategy.afterNewNextHopCalls.size() == 0);
772
773 // create a second pit entry for /A
774 auto interest4 = makeInterest("/A");
775 interest4->setMustBeFresh(true);
776 auto pit4 = pit.insert(*interest4).first;
777 pit4->insertOrUpdateInRecord(*face3, *interest4);
778
779 // new nexthop for "/A"
780 entry = fib.insert("/A").first;
781 fib.addOrUpdateNextHop(*entry, *face1, 0);
782
783 // /A --> triggered twice
784 // /A/B/C --> not triggered
785 // /A/B/Z --> not triggered
786 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 2);
787 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
788 BOOST_TEST(strategy.afterNewNextHopCalls[1] == "/A");
789}
790
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400791BOOST_AUTO_TEST_SUITE_END() // TestForwarder
792BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700793
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700794} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700795} // namespace nfd