blob: af362e1e147ddeb5a8caf5f9d51bb016314f9b5b [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/*
ashiqopu3ad49db2018-10-20 22:38:47 +00003 * Copyright (c) 2014-2019, 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);
Junxiao Shic041ca32014-02-25 20:01:15 -070083
Junxiao Shida93f1f2015-11-11 06:13:16 -070084 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
85 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060086 face2->receiveData(*makeData("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040087 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070088 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shi9d727852019-05-14 13:44:22 -060089 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070090 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
91 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070092 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
93 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070094}
95
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070096BOOST_AUTO_TEST_CASE(CsMatched)
97{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040098 auto face1 = addFace();
99 auto face2 = addFace();
100 auto face3 = addFace();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700101
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700102 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000103 fib::Entry* entry = fib.insert("/A").first;
104 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700105
106 Pit& pit = forwarder.getPit();
107 BOOST_CHECK_EQUAL(pit.size(), 0);
108
Junxiao Shi9d727852019-05-14 13:44:22 -0600109 auto data = makeData("/A/B");
110 data->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
111 forwarder.getCs().insert(*data);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700112
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000113 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
114 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -0600115 face1->receiveInterest(*makeInterest("/A", true), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400116 this->advanceClocks(1_ms, 5_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700117 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700118 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000119 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
120 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700121
Junxiao Shicde37ad2015-12-24 01:02:05 -0700122 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700123 // IncomingFaceId field should be reset to represent CS
Junxiao Shi9d727852019-05-14 13:44:22 -0600124 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700125 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
126 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700127
Davide Pesavento14e71f02019-03-28 17:35:25 -0400128 this->advanceClocks(100_ms, 500_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700129 // PIT entry should not be left behind
130 BOOST_CHECK_EQUAL(pit.size(), 0);
131}
132
Junxiao Shi891f47b2016-06-20 00:02:11 +0000133BOOST_AUTO_TEST_CASE(OutgoingInterest)
134{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400135 auto face1 = addFace();
136 auto face2 = addFace();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000137
138 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600139 auto interestA1 = makeInterest("/A", false, nullopt, 8378);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000140 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000141 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000142
Junxiao Shi9d727852019-05-14 13:44:22 -0600143 auto interestA2 = makeInterest("/A", false, nullopt, 1698);
ashiqopuc7079482019-02-20 05:34:37 +0000144 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000145
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000146 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000147 BOOST_REQUIRE(outA2 != pitA->out_end());
148 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000149
Junxiao Shi891f47b2016-06-20 00:02:11 +0000150 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000151 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000152}
153
Junxiao Shie342e8d2016-09-18 16:48:00 +0000154BOOST_AUTO_TEST_CASE(NextHopFaceId)
155{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400156 auto face1 = addFace();
157 auto face2 = addFace();
158 auto face3 = addFace();
Junxiao Shie342e8d2016-09-18 16:48:00 +0000159
160 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000161 fib::Entry* entry = fib.insert("/A").first;
162 fib.addOrUpdateNextHop(*entry, *face3, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000163
Junxiao Shi9d727852019-05-14 13:44:22 -0600164 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000165 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
166
ashiqopu075bb7d2019-03-10 01:38:21 +0000167 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400168 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000169 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
170 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
171 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
172}
173
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700174class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700175{
176public:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400177 using Forwarder::Forwarder;
178
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000179 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400180 onDataUnsolicited(const FaceEndpoint&, const Data&) final
Junxiao Shi88884492014-02-15 15:57:43 -0700181 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700182 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700183 }
184
185protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000186 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400187 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700188 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700189 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700190 }
191
192public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400193 int dispatchToStrategy_count = 0;
194 int onDataUnsolicited_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700195};
196
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400197BOOST_FIXTURE_TEST_CASE(ScopeLocalhostIncoming, GlobalIoTimeFixture)
Junxiao Shi88884492014-02-15 15:57:43 -0700198{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400199 FaceTable faceTable;
200 ScopeLocalhostIncomingTestForwarder forwarder(faceTable);
201
Junxiao Shicde37ad2015-12-24 01:02:05 -0700202 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
203 auto face2 = make_shared<DummyFace>();
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400204 faceTable.add(face1);
205 faceTable.add(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700206
Junxiao Shi88884492014-02-15 15:57:43 -0700207 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700208 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600209 auto i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000210 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700211 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700212
Junxiao Shi88884492014-02-15 15:57:43 -0700213 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700214 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600215 auto i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000216 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700217 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700218
Junxiao Shi88884492014-02-15 15:57:43 -0700219 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700220 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600221 auto i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000222 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700223 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700224
Junxiao Shi88884492014-02-15 15:57:43 -0700225 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700226 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600227 auto i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000228 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700229 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700230
Junxiao Shi88884492014-02-15 15:57:43 -0700231 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700232 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600233 auto d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000234 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700235 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700236
237 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700238 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600239 auto d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000240 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700241 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700242
Junxiao Shi88884492014-02-15 15:57:43 -0700243 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700244 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600245 auto d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000246 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700247 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700248
249 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700250 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600251 auto d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000252 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700253 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700254}
255
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700256BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700257{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400258 auto face1 = addFace();
259 auto face2 = addFace();
Junxiao Shif3c07812014-03-11 21:48:49 -0700260
Junxiao Shi9d727852019-05-14 13:44:22 -0600261 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
262 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700263
Junxiao Shi9d727852019-05-14 13:44:22 -0600264 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000265 strategyA.afterReceiveInterest_count = 0;
266 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000267 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000268 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700269
Junxiao Shi9d727852019-05-14 13:44:22 -0600270 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000271 strategyB.afterReceiveInterest_count = 0;
272 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000273 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000274 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700275
Davide Pesavento14e71f02019-03-28 17:35:25 -0400276 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700277
Junxiao Shi9d727852019-05-14 13:44:22 -0600278 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000279 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000280 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000281 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700282
Junxiao Shi9d727852019-05-14 13:44:22 -0600283 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000284 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000285 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000286 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700287
Junxiao Shi9d727852019-05-14 13:44:22 -0600288 auto interest3 = makeInterest("/A/3", false, 30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000289 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shi9d727852019-05-14 13:44:22 -0600290 auto interest4 = makeInterest("/B/4", false, 5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000291 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700292}
293
Junxiao Shida006f52014-05-16 11:18:00 -0700294BOOST_AUTO_TEST_CASE(IncomingData)
295{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400296 auto face1 = addFace();
297 auto face2 = addFace();
298 auto face3 = addFace();
299 auto face4 = addFace();
Junxiao Shida006f52014-05-16 11:18:00 -0700300
301 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600302 auto interestD = makeInterest("/A/B/C/D");
303 shared_ptr<pit::Entry> pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000304 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600305 auto interestA = makeInterest("/A", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700306 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000307 pitA->insertOrUpdateInRecord(*face2, *interestA);
308 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600309 auto interestC = makeInterest("/A/B/C", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700310 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000311 pitC->insertOrUpdateInRecord(*face3, *interestC);
312 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700313
Junxiao Shi9d727852019-05-14 13:44:22 -0600314 auto dataD = makeData("/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000315 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400316 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700317
Junxiao Shicde37ad2015-12-24 01:02:05 -0700318 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
319 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
320 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
321 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700322}
323
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700324BOOST_AUTO_TEST_CASE(IncomingNack)
325{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400326 auto face1 = addFace();
327 auto face2 = addFace();
328 auto face3 = addFace("dummy://", "dummy://",
329 ndn::nfd::FACE_SCOPE_NON_LOCAL,
330 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
331 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700332
Junxiao Shi9d727852019-05-14 13:44:22 -0600333 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
334 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700335
336 Pit& pit = forwarder.getPit();
337
338 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600339 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700340 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000341 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600342 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700343 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000344 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700345
Junxiao Shi9d727852019-05-14 13:44:22 -0600346 lp::Nack nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000347 strategyA.afterReceiveNack_count = 0;
348 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000349 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000350 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
351 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700352
Junxiao Shi9d727852019-05-14 13:44:22 -0600353 lp::Nack nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000354 strategyA.afterReceiveNack_count = 0;
355 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000356 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000357 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
358 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700359
360 // record Nack on PIT out-record
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000361 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700362 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700363 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
364 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
365
366 // drop if no PIT entry
Junxiao Shi9d727852019-05-14 13:44:22 -0600367 lp::Nack nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000368 strategyA.afterReceiveNack_count = 0;
369 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000370 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000371 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
372 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700373
374 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600375 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700376 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000377 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700378
Junxiao Shi9d727852019-05-14 13:44:22 -0600379 lp::Nack nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000380 strategyA.afterReceiveNack_count = 0;
381 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000382 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000383 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
384 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700385
386 // drop if Nonce does not match out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600387 lp::Nack nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000388 strategyA.afterReceiveNack_count = 0;
389 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000390 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000391 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
392 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700393
394 // drop if inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000395 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000396 strategyA.afterReceiveNack_count = 0;
397 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000398 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000399 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
400 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700401}
402
403BOOST_AUTO_TEST_CASE(OutgoingNack)
404{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400405 auto face1 = addFace();
406 auto face2 = addFace();
407 auto face3 = addFace("dummy://", "dummy://",
408 ndn::nfd::FACE_SCOPE_NON_LOCAL,
409 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
410 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700411
412 Pit& pit = forwarder.getPit();
413
414 lp::NackHeader nackHeader;
415 nackHeader.setReason(lp::NackReason::CONGESTION);
416
417 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600418 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700419 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000420 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700421
422 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000423 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700424 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
425
426 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600427 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700428 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000429 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600430 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000431 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700432
433 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000434 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700435 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
436 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
437 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
438
439 // erase in-record
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000440 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700441 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700442
443 // send Nack with correct Nonce
444 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000445 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700446 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
447 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
448 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
449
450 // erase in-record
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000451 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700452 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700453
454 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600455 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000456 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700457
458 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000459 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700460 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
461}
462
463BOOST_AUTO_TEST_CASE(InterestLoopNack)
464{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400465 auto face1 = addFace();
466 auto face2 = addFace();
467 auto face3 = addFace("dummy://", "dummy://",
468 ndn::nfd::FACE_SCOPE_NON_LOCAL,
469 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
470 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
471 auto face4 = addFace();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700472
473 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000474 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
475 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700476
477 // receive Interest on face1
478 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600479 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000480 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700481 BOOST_CHECK(face1->sentNacks.empty());
482
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000483 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700484 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600485 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000486 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000487 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700488
489 // receive Interest with duplicate Nonce on face2
490 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600491 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000492 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700493 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400494 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700495 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
496
497 // receive Interest with new Nonce on face2
498 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600499 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000500 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700501 BOOST_CHECK(face2->sentNacks.empty());
502
503 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
504 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600505 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000506 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700507 BOOST_CHECK(face3->sentNacks.empty());
508}
509
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400510BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700511{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400512 auto face1 = addFace();
513 auto face2 = addFace();
Junxiao Shia110f262014-10-12 12:35:20 -0700514
515 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700516 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
517 if (pktType == tlv::Interest) {
518 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000519 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700520 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700521 });
Junxiao Shia110f262014-10-12 12:35:20 -0700522
523 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000524 fib::Entry* entry = fib.insert("/A").first;
525 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700526
Junxiao Shi455581d2014-11-17 18:38:40 -0700527 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600528 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000529 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700530
Junxiao Shi455581d2014-11-17 18:38:40 -0700531 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400532 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
533 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700534
Junxiao Shicde37ad2015-12-24 01:02:05 -0700535 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700536
537 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
538 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
539 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
540 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
541 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700542}
543
Junxiao Shid41d6072016-06-19 23:35:27 +0000544BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700545{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400546 auto face1 = addFace();
Junxiao Shi330136a2016-03-10 04:53:08 -0700547
Junxiao Shi9d727852019-05-14 13:44:22 -0600548 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700549
550 DeadNonceList& dnl = forwarder.getDeadNonceList();
551 dnl.add(interest->getName(), interest->getNonce());
552 Pit& pit = forwarder.getPit();
553 BOOST_REQUIRE_EQUAL(pit.size(), 0);
554
ashiqopuc7079482019-02-20 05:34:37 +0000555 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400556 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700557 BOOST_CHECK_EQUAL(pit.size(), 0);
558}
559
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400560BOOST_AUTO_TEST_SUITE_END() // TestForwarder
561BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700562
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700563} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700564} // namespace nfd