blob: 60c8ea4fae8fda2449e30245cdf3a6acb115ae05 [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 Pesavento3dade002019-03-19 11:29:56 -060027#include "daemon/global.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070028
Junxiao Shid9ee45c2014-02-27 15:38:11 -070029#include "tests/test-common.hpp"
Junxiao Shi06a1eab2017-09-04 13:13:02 +000030#include "tests/daemon/face/dummy-face.hpp"
31#include "choose-strategy.hpp"
32#include "dummy-strategy.hpp"
33
34#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi8c8d2182014-01-30 22:33:00 -070035
36namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070037namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070038
Junxiao Shi0355e9f2015-09-02 07:24:53 -070039BOOST_AUTO_TEST_SUITE(Fw)
Junxiao Shid41d6072016-06-19 23:35:27 +000040BOOST_FIXTURE_TEST_SUITE(TestForwarder, UnitTestTimeFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070041
Junxiao Shi8c8d2182014-01-30 22:33:00 -070042BOOST_AUTO_TEST_CASE(SimpleExchange)
43{
Junxiao Shic041ca32014-02-25 20:01:15 -070044 Forwarder forwarder;
45
Junxiao Shia6de4292016-07-12 02:08:10 +000046 shared_ptr<Interest> interestAB = makeInterest("/A/B");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070047 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shia6de4292016-07-12 02:08:10 +000048 shared_ptr<Data> dataABC = makeData("/A/B/C");
Junxiao Shi8c8d2182014-01-30 22:33:00 -070049
Junxiao Shicde37ad2015-12-24 01:02:05 -070050 auto face1 = make_shared<DummyFace>();
51 auto face2 = make_shared<DummyFace>();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070052 forwarder.addFace(face1);
53 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070054
Junxiao Shi8c8d2182014-01-30 22:33:00 -070055 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +000056 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070057
Junxiao Shida93f1f2015-11-11 06:13:16 -070058 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
59 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000060 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
61 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shid41d6072016-06-19 23:35:27 +000062 face1->receiveInterest(*interestAB);
63 this->advanceClocks(time::milliseconds(100), time::seconds(1));
Junxiao Shicde37ad2015-12-24 01:02:05 -070064 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000065 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070066 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
67 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070068 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
69 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000070 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
71 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070072
Junxiao Shida93f1f2015-11-11 06:13:16 -070073 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
74 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shid41d6072016-06-19 23:35:27 +000075 face2->receiveData(*dataABC);
76 this->advanceClocks(time::milliseconds(100), time::seconds(1));
Junxiao Shicde37ad2015-12-24 01:02:05 -070077 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000078 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B/C");
Junxiao Shicde37ad2015-12-24 01:02:05 -070079 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
80 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070081 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
82 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070083}
84
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070085BOOST_AUTO_TEST_CASE(CsMatched)
86{
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070087 Forwarder forwarder;
88
Junxiao Shicde37ad2015-12-24 01:02:05 -070089 auto face1 = make_shared<DummyFace>();
90 auto face2 = make_shared<DummyFace>();
91 auto face3 = make_shared<DummyFace>();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070092 forwarder.addFace(face1);
93 forwarder.addFace(face2);
94 forwarder.addFace(face3);
95
Junxiao Shia6de4292016-07-12 02:08:10 +000096 shared_ptr<Interest> interestA = makeInterest("/A");
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070097 interestA->setInterestLifetime(time::seconds(4));
Junxiao Shia6de4292016-07-12 02:08:10 +000098 shared_ptr<Data> dataA = makeData("/A");
Junxiao Shi0de23a22015-12-03 20:07:02 +000099 dataA->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700100
101 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000102 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700103
104 Pit& pit = forwarder.getPit();
105 BOOST_CHECK_EQUAL(pit.size(), 0);
106
107 Cs& cs = forwarder.getCs();
Minsheng Zhangffe8bbb2016-03-10 13:40:37 -0700108 cs.insert(*dataA);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700109
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000110 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
111 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700112 face1->receiveInterest(*interestA);
Junxiao Shid41d6072016-06-19 23:35:27 +0000113 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700114 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700115 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000116 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
117 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700118
Junxiao Shicde37ad2015-12-24 01:02:05 -0700119 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700120 // IncomingFaceId field should be reset to represent CS
Junxiao Shicde37ad2015-12-24 01:02:05 -0700121 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
122 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700123
Junxiao Shid41d6072016-06-19 23:35:27 +0000124 this->advanceClocks(time::milliseconds(100), time::milliseconds(500));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700125 // PIT entry should not be left behind
126 BOOST_CHECK_EQUAL(pit.size(), 0);
127}
128
Junxiao Shi891f47b2016-06-20 00:02:11 +0000129BOOST_AUTO_TEST_CASE(OutgoingInterest)
130{
131 Forwarder forwarder;
132 auto face1 = make_shared<DummyFace>();
133 auto face2 = make_shared<DummyFace>();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000134 forwarder.addFace(face1);
135 forwarder.addFace(face2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000136
137 Pit& pit = forwarder.getPit();
Junxiao Shia6de4292016-07-12 02:08:10 +0000138 auto interestA1 = makeInterest("/A");
Junxiao Shi891f47b2016-06-20 00:02:11 +0000139 interestA1->setNonce(8378);
140 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000141 pitA->insertOrUpdateInRecord(*face1, 0, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000142
Junxiao Shia6de4292016-07-12 02:08:10 +0000143 auto interestA2 = makeInterest("/A");
Junxiao Shic5f651f2016-11-17 22:58:12 +0000144 interestA2->setNonce(1698);
ashiqopuc7079482019-02-20 05:34:37 +0000145 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000146
ashiqopud3ae85d2019-02-17 02:29:55 +0000147 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2, 0);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000148 BOOST_REQUIRE(outA2 != pitA->out_end());
149 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000150
Junxiao Shi891f47b2016-06-20 00:02:11 +0000151 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000152 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000153}
154
Junxiao Shie342e8d2016-09-18 16:48:00 +0000155BOOST_AUTO_TEST_CASE(NextHopFaceId)
156{
157 Forwarder forwarder;
158
159 auto face1 = make_shared<DummyFace>();
160 auto face2 = make_shared<DummyFace>();
161 auto face3 = make_shared<DummyFace>();
162 forwarder.addFace(face1);
163 forwarder.addFace(face2);
164 forwarder.addFace(face3);
165
166 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000167 fib.insert("/A").first->addOrUpdateNextHop(*face3, 0, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000168
169 shared_ptr<Interest> interest = makeInterest("/A/B");
170 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
171
172 face1->receiveInterest(*interest);
173 this->advanceClocks(time::milliseconds(100), time::seconds(1));
174 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
175 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
176 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
177}
178
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700179class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700180{
181public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700182 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700183 {
184 }
185
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000186 void
ashiqopuc7079482019-02-20 05:34:37 +0000187 onDataUnsolicited(const FaceEndpoint& ingress, const Data& data) override
Junxiao Shi88884492014-02-15 15:57:43 -0700188 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700189 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700190 }
191
192protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000193 void
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400194 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) override
Junxiao Shi88884492014-02-15 15:57:43 -0700195 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700196 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700197 }
198
199public:
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700200 int dispatchToStrategy_count;
201 int onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700202};
203
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700204BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700205{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700206 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700207 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
208 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700209 forwarder.addFace(face1);
210 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700211
Junxiao Shi88884492014-02-15 15:57:43 -0700212 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700213 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700214 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000215 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700216 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700217
Junxiao Shi88884492014-02-15 15:57:43 -0700218 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700219 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700220 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000221 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700222 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700223
Junxiao Shi88884492014-02-15 15:57:43 -0700224 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700225 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700226 shared_ptr<Interest> i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000227 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700228 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700229
Junxiao Shi88884492014-02-15 15:57:43 -0700230 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700231 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700232 shared_ptr<Interest> i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000233 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700234 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700235
Junxiao Shi88884492014-02-15 15:57:43 -0700236 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700237 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700238 shared_ptr<Data> d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000239 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700240 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700241
242 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700243 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700244 shared_ptr<Data> d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000245 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700246 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700247
Junxiao Shi88884492014-02-15 15:57:43 -0700248 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700249 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700250 shared_ptr<Data> d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000251 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700252 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700253
254 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700255 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700256 shared_ptr<Data> d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000257 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700258 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700259}
260
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700261BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700262{
Junxiao Shif3c07812014-03-11 21:48:49 -0700263 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700264 auto face1 = make_shared<DummyFace>();
265 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700266 forwarder.addFace(face1);
267 forwarder.addFace(face2);
268
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000269 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
270 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700271
272 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000273 strategyA.afterReceiveInterest_count = 0;
274 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000275 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000276 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700277
278 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000279 strategyB.afterReceiveInterest_count = 0;
280 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000281 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000282 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700283
Junxiao Shid41d6072016-06-19 23:35:27 +0000284 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shif3c07812014-03-11 21:48:49 -0700285
286 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000287 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000288 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000289 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700290
291 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000292 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000293 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000294 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700295
296 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700297 interest3->setInterestLifetime(time::milliseconds(30));
ashiqopuc7079482019-02-20 05:34:37 +0000298 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700299 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700300 interest4->setInterestLifetime(time::milliseconds(5000));
ashiqopuc7079482019-02-20 05:34:37 +0000301 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700302}
303
Junxiao Shida006f52014-05-16 11:18:00 -0700304BOOST_AUTO_TEST_CASE(IncomingData)
305{
Junxiao Shida006f52014-05-16 11:18:00 -0700306 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700307 auto face1 = make_shared<DummyFace>();
308 auto face2 = make_shared<DummyFace>();
309 auto face3 = make_shared<DummyFace>();
310 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700311 forwarder.addFace(face1);
312 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700313 forwarder.addFace(face3);
314 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700315
316 Pit& pit = forwarder.getPit();
317 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
318 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000319 pit0->insertOrUpdateInRecord(*face1, 0, *interest0);
Junxiao Shida006f52014-05-16 11:18:00 -0700320 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
321 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000322 pitA->insertOrUpdateInRecord(*face1, 0, *interestA);
323 pitA->insertOrUpdateInRecord(*face2, 0, *interestA);
Junxiao Shida006f52014-05-16 11:18:00 -0700324 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
325 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000326 pitC->insertOrUpdateInRecord(*face3, 0, *interestC);
327 pitC->insertOrUpdateInRecord(*face4, 0, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700328
329 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000330 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Junxiao Shid41d6072016-06-19 23:35:27 +0000331 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shida006f52014-05-16 11:18:00 -0700332
Junxiao Shicde37ad2015-12-24 01:02:05 -0700333 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
334 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
335 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
336 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700337}
338
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700339BOOST_AUTO_TEST_CASE(IncomingNack)
340{
341 Forwarder forwarder;
342 auto face1 = make_shared<DummyFace>();
343 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700344 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
345 ndn::nfd::FACE_SCOPE_NON_LOCAL,
346 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
347 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700348 forwarder.addFace(face1);
349 forwarder.addFace(face2);
350 forwarder.addFace(face3);
351
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000352 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
353 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700354
355 Pit& pit = forwarder.getPit();
356
357 // dispatch to the correct strategy
358 shared_ptr<Interest> interest1 = makeInterest("/A/AYJqayrzF", 562);
359 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000360 pit1->insertOrUpdateOutRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700361 shared_ptr<Interest> interest2 = makeInterest("/B/EVyP73ru", 221);
362 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000363 pit2->insertOrUpdateOutRecord(*face1, 0, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700364
365 lp::Nack nack1 = makeNack("/A/AYJqayrzF", 562, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000366 strategyA.afterReceiveNack_count = 0;
367 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000368 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000369 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
370 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700371
372 lp::Nack nack2 = makeNack("/B/EVyP73ru", 221, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000373 strategyA.afterReceiveNack_count = 0;
374 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000375 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000376 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
377 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700378
379 // record Nack on PIT out-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000380 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700381 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700382 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
383 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
384
385 // drop if no PIT entry
386 lp::Nack nack3 = makeNack("/yEcw5HhdM", 243, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000387 strategyA.afterReceiveNack_count = 0;
388 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000389 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000390 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
391 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700392
393 // drop if no out-record
394 shared_ptr<Interest> interest4 = makeInterest("/Etab4KpY", 157);
395 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000396 pit4->insertOrUpdateOutRecord(*face1, 0, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700397
398 lp::Nack nack4a = makeNack("/Etab4KpY", 157, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000399 strategyA.afterReceiveNack_count = 0;
400 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000401 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000402 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
403 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700404
405 // drop if Nonce does not match out-record
406 lp::Nack nack4b = makeNack("/Etab4KpY", 294, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000407 strategyA.afterReceiveNack_count = 0;
408 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000409 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000410 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
411 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700412
413 // drop if inFace is multi-access
ashiqopud3ae85d2019-02-17 02:29:55 +0000414 pit4->insertOrUpdateOutRecord(*face3, 0, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000415 strategyA.afterReceiveNack_count = 0;
416 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000417 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000418 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
419 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700420}
421
422BOOST_AUTO_TEST_CASE(OutgoingNack)
423{
424 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700425 auto face1 = make_shared<DummyFace>();
426 auto face2 = make_shared<DummyFace>();
427 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
428 ndn::nfd::FACE_SCOPE_NON_LOCAL,
429 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
430 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
431 forwarder.addFace(face1);
432 forwarder.addFace(face2);
433 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700434
435 Pit& pit = forwarder.getPit();
436
437 lp::NackHeader nackHeader;
438 nackHeader.setReason(lp::NackReason::CONGESTION);
439
440 // don't send Nack if there's no in-record
441 shared_ptr<Interest> interest1 = makeInterest("/fM5IVEtC", 719);
442 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000443 pit1->insertOrUpdateInRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700444
445 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000446 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700447 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
448
449 // send Nack with correct Nonce
450 shared_ptr<Interest> interest2a = makeInterest("/Vi8tRm9MG3", 152);
451 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000452 pit2->insertOrUpdateInRecord(*face1, 0, *interest2a);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700453 shared_ptr<Interest> interest2b = makeInterest("/Vi8tRm9MG3", 808);
ashiqopud3ae85d2019-02-17 02:29:55 +0000454 pit2->insertOrUpdateInRecord(*face2, 0, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700455
456 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000457 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700458 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
459 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
460 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
461
462 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000463 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700464 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700465
466 // send Nack with correct Nonce
467 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000468 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700469 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
470 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
471 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
472
473 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000474 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700475 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700476
477 // don't send Nack to multi-access face
478 shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
ashiqopud3ae85d2019-02-17 02:29:55 +0000479 pit2->insertOrUpdateInRecord(*face3, 0, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700480
481 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000482 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700483 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
484}
485
486BOOST_AUTO_TEST_CASE(InterestLoopNack)
487{
488 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700489 auto face1 = make_shared<DummyFace>();
490 auto face2 = make_shared<DummyFace>();
491 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
492 ndn::nfd::FACE_SCOPE_NON_LOCAL,
493 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
494 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700495 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700496 forwarder.addFace(face1);
497 forwarder.addFace(face2);
498 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700499 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700500
501 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000502 fib.insert("/zT4XwK0Hnx").first->addOrUpdateNextHop(*face4, 0, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700503
504 // receive Interest on face1
505 face1->sentNacks.clear();
506 shared_ptr<Interest> interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
507 face1->receiveInterest(*interest1a);
508 BOOST_CHECK(face1->sentNacks.empty());
509
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000510 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700511 face1->sentNacks.clear();
512 shared_ptr<Interest> interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
513 face1->receiveInterest(*interest1b);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000514 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700515
516 // receive Interest with duplicate Nonce on face2
517 face2->sentNacks.clear();
518 shared_ptr<Interest> interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
519 face2->receiveInterest(*interest2a);
520 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
521 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
522 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
523
524 // receive Interest with new Nonce on face2
525 face2->sentNacks.clear();
526 shared_ptr<Interest> interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 944);
527 face2->receiveInterest(*interest2b);
528 BOOST_CHECK(face2->sentNacks.empty());
529
530 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
531 face3->sentNacks.clear();
532 shared_ptr<Interest> interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
533 face3->receiveInterest(*interest3a);
534 BOOST_CHECK(face3->sentNacks.empty());
535}
536
Junxiao Shi455581d2014-11-17 18:38:40 -0700537BOOST_FIXTURE_TEST_CASE(InterestLoopWithShortLifetime, UnitTestTimeFixture) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700538{
Junxiao Shia110f262014-10-12 12:35:20 -0700539 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700540 auto face1 = make_shared<DummyFace>();
541 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700542 forwarder.addFace(face1);
543 forwarder.addFace(face2);
544
545 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700546 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
547 if (pktType == tlv::Interest) {
548 auto interest = make_shared<Interest>(face2->sentInterests.back());
Davide Pesavento3dade002019-03-19 11:29:56 -0600549 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700550 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700551 });
Junxiao Shia110f262014-10-12 12:35:20 -0700552
553 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000554 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700555
Junxiao Shi455581d2014-11-17 18:38:40 -0700556 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700557 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
558 interest->setNonce(82101183);
559 interest->setInterestLifetime(time::milliseconds(50));
560 face1->receiveInterest(*interest);
561
Junxiao Shi455581d2014-11-17 18:38:40 -0700562 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
563 BOOST_ASSERT(time::milliseconds(25) * 40 < forwarder.getDeadNonceList().getLifetime());
564 this->advanceClocks(time::milliseconds(25), 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700565
Junxiao Shicde37ad2015-12-24 01:02:05 -0700566 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700567
568 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
569 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
570 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
571 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
572 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700573}
574
Junxiao Shid41d6072016-06-19 23:35:27 +0000575BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700576{
577 Forwarder forwarder;
578 shared_ptr<Face> face1 = make_shared<DummyFace>();
579 forwarder.addFace(face1);
580
581 shared_ptr<Interest> interest = makeInterest("ndn:/hcLSAsQ9A");
582 interest->setNonce(61883075);
583 interest->setInterestLifetime(time::seconds(2));
584
585 DeadNonceList& dnl = forwarder.getDeadNonceList();
586 dnl.add(interest->getName(), interest->getNonce());
587 Pit& pit = forwarder.getPit();
588 BOOST_REQUIRE_EQUAL(pit.size(), 0);
589
ashiqopuc7079482019-02-20 05:34:37 +0000590 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Junxiao Shi330136a2016-03-10 04:53:08 -0700591 this->advanceClocks(time::milliseconds(100), time::seconds(20));
592 BOOST_CHECK_EQUAL(pit.size(), 0);
593}
594
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700595BOOST_AUTO_TEST_SUITE_END()
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700596BOOST_AUTO_TEST_SUITE_END()
597
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700598} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700599} // namespace nfd