blob: a6d562ad4890e69bfab63614e7bbcfaa9d452796 [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
Junxiao Shi0355e9f2015-09-02 07:24:53 -070040BOOST_AUTO_TEST_SUITE(Fw)
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040041BOOST_FIXTURE_TEST_SUITE(TestForwarder, GlobalIoTimeFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070042
Junxiao Shi8c8d2182014-01-30 22:33:00 -070043BOOST_AUTO_TEST_CASE(SimpleExchange)
44{
Junxiao Shic041ca32014-02-25 20:01:15 -070045 Forwarder forwarder;
46
Junxiao Shicde37ad2015-12-24 01:02:05 -070047 auto face1 = make_shared<DummyFace>();
48 auto face2 = make_shared<DummyFace>();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070049 forwarder.addFace(face1);
50 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070051
Junxiao Shi8c8d2182014-01-30 22:33:00 -070052 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +000053 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070054
Junxiao Shida93f1f2015-11-11 06:13:16 -070055 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
56 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000057 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
58 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060059 face1->receiveInterest(*makeInterest("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040060 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070061 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000062 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070063 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
64 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070065 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
66 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000067 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
68 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070069
Junxiao Shida93f1f2015-11-11 06:13:16 -070070 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
71 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060072 face2->receiveData(*makeData("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040073 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070074 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shi9d727852019-05-14 13:44:22 -060075 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070076 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
77 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070078 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
79 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070080}
81
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070082BOOST_AUTO_TEST_CASE(CsMatched)
83{
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070084 Forwarder forwarder;
85
Junxiao Shicde37ad2015-12-24 01:02:05 -070086 auto face1 = make_shared<DummyFace>();
87 auto face2 = make_shared<DummyFace>();
88 auto face3 = make_shared<DummyFace>();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070089 forwarder.addFace(face1);
90 forwarder.addFace(face2);
91 forwarder.addFace(face3);
92
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070093 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +000094 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070095
96 Pit& pit = forwarder.getPit();
97 BOOST_CHECK_EQUAL(pit.size(), 0);
98
Junxiao Shi9d727852019-05-14 13:44:22 -060099 auto data = makeData("/A/B");
100 data->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
101 forwarder.getCs().insert(*data);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700102
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000103 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
104 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -0600105 face1->receiveInterest(*makeInterest("/A", true), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400106 this->advanceClocks(1_ms, 5_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700107 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700108 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000109 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
110 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700111
Junxiao Shicde37ad2015-12-24 01:02:05 -0700112 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700113 // IncomingFaceId field should be reset to represent CS
Junxiao Shi9d727852019-05-14 13:44:22 -0600114 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700115 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
116 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700117
Davide Pesavento14e71f02019-03-28 17:35:25 -0400118 this->advanceClocks(100_ms, 500_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700119 // PIT entry should not be left behind
120 BOOST_CHECK_EQUAL(pit.size(), 0);
121}
122
Junxiao Shi891f47b2016-06-20 00:02:11 +0000123BOOST_AUTO_TEST_CASE(OutgoingInterest)
124{
125 Forwarder forwarder;
126 auto face1 = make_shared<DummyFace>();
127 auto face2 = make_shared<DummyFace>();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000128 forwarder.addFace(face1);
129 forwarder.addFace(face2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000130
131 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600132 auto interestA1 = makeInterest("/A", false, nullopt, 8378);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000133 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000134 pitA->insertOrUpdateInRecord(*face1, 0, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000135
Junxiao Shi9d727852019-05-14 13:44:22 -0600136 auto interestA2 = makeInterest("/A", false, nullopt, 1698);
ashiqopuc7079482019-02-20 05:34:37 +0000137 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000138
ashiqopud3ae85d2019-02-17 02:29:55 +0000139 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2, 0);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000140 BOOST_REQUIRE(outA2 != pitA->out_end());
141 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000142
Junxiao Shi891f47b2016-06-20 00:02:11 +0000143 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000144 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000145}
146
Junxiao Shie342e8d2016-09-18 16:48:00 +0000147BOOST_AUTO_TEST_CASE(NextHopFaceId)
148{
149 Forwarder forwarder;
150
151 auto face1 = make_shared<DummyFace>();
152 auto face2 = make_shared<DummyFace>();
153 auto face3 = make_shared<DummyFace>();
154 forwarder.addFace(face1);
155 forwarder.addFace(face2);
156 forwarder.addFace(face3);
157
158 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000159 fib.insert("/A").first->addOrUpdateNextHop(*face3, 0, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000160
Junxiao Shi9d727852019-05-14 13:44:22 -0600161 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000162 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
163
ashiqopu075bb7d2019-03-10 01:38:21 +0000164 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400165 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000166 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
167 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
168 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
169}
170
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700171class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700172{
173public:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000174 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400175 onDataUnsolicited(const FaceEndpoint&, const Data&) final
Junxiao Shi88884492014-02-15 15:57:43 -0700176 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700177 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700178 }
179
180protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000181 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400182 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700183 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700184 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700185 }
186
187public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400188 int dispatchToStrategy_count = 0;
189 int onDataUnsolicited_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700190};
191
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700192BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700193{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700194 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700195 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
196 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700197 forwarder.addFace(face1);
198 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700199
Junxiao Shi88884492014-02-15 15:57:43 -0700200 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700201 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600202 auto i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000203 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700204 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700205
Junxiao Shi88884492014-02-15 15:57:43 -0700206 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700207 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600208 auto i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000209 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700210 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700211
Junxiao Shi88884492014-02-15 15:57:43 -0700212 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700213 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600214 auto i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000215 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
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, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700219 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600220 auto i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000221 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700222 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700223
Junxiao Shi88884492014-02-15 15:57:43 -0700224 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700225 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600226 auto d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000227 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700228 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700229
230 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700231 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600232 auto d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000233 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700234 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700235
Junxiao Shi88884492014-02-15 15:57:43 -0700236 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700237 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600238 auto d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000239 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
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, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700243 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600244 auto d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000245 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700246 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700247}
248
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700249BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700250{
Junxiao Shif3c07812014-03-11 21:48:49 -0700251 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700252 auto face1 = make_shared<DummyFace>();
253 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700254 forwarder.addFace(face1);
255 forwarder.addFace(face2);
256
Junxiao Shi9d727852019-05-14 13:44:22 -0600257 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
258 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700259
Junxiao Shi9d727852019-05-14 13:44:22 -0600260 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000261 strategyA.afterReceiveInterest_count = 0;
262 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000263 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000264 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700265
Junxiao Shi9d727852019-05-14 13:44:22 -0600266 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000267 strategyB.afterReceiveInterest_count = 0;
268 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000269 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000270 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700271
Davide Pesavento14e71f02019-03-28 17:35:25 -0400272 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700273
Junxiao Shi9d727852019-05-14 13:44:22 -0600274 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000275 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000276 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000277 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700278
Junxiao Shi9d727852019-05-14 13:44:22 -0600279 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000280 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000281 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000282 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700283
Junxiao Shi9d727852019-05-14 13:44:22 -0600284 auto interest3 = makeInterest("/A/3", false, 30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000285 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shi9d727852019-05-14 13:44:22 -0600286 auto interest4 = makeInterest("/B/4", false, 5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000287 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700288}
289
Junxiao Shida006f52014-05-16 11:18:00 -0700290BOOST_AUTO_TEST_CASE(IncomingData)
291{
Junxiao Shida006f52014-05-16 11:18:00 -0700292 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700293 auto face1 = make_shared<DummyFace>();
294 auto face2 = make_shared<DummyFace>();
295 auto face3 = make_shared<DummyFace>();
296 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700297 forwarder.addFace(face1);
298 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700299 forwarder.addFace(face3);
300 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700301
302 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600303 auto interestD = makeInterest("/A/B/C/D");
304 shared_ptr<pit::Entry> pitD = pit.insert(*interestD).first;
305 pitD->insertOrUpdateInRecord(*face1, 0, *interestD);
306 auto interestA = makeInterest("/A", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700307 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000308 pitA->insertOrUpdateInRecord(*face2, 0, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600309 pitA->insertOrUpdateInRecord(*face3, 0, *interestA);
310 auto interestC = makeInterest("/A/B/C", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700311 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000312 pitC->insertOrUpdateInRecord(*face3, 0, *interestC);
313 pitC->insertOrUpdateInRecord(*face4, 0, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700314
Junxiao Shi9d727852019-05-14 13:44:22 -0600315 auto dataD = makeData("/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000316 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400317 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700318
Junxiao Shicde37ad2015-12-24 01:02:05 -0700319 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
320 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
321 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
322 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700323}
324
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700325BOOST_AUTO_TEST_CASE(IncomingNack)
326{
327 Forwarder forwarder;
328 auto face1 = make_shared<DummyFace>();
329 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700330 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
331 ndn::nfd::FACE_SCOPE_NON_LOCAL,
332 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
333 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700334 forwarder.addFace(face1);
335 forwarder.addFace(face2);
336 forwarder.addFace(face3);
337
Junxiao Shi9d727852019-05-14 13:44:22 -0600338 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
339 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700340
341 Pit& pit = forwarder.getPit();
342
343 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600344 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700345 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000346 pit1->insertOrUpdateOutRecord(*face1, 0, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600347 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700348 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000349 pit2->insertOrUpdateOutRecord(*face1, 0, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700350
Junxiao Shi9d727852019-05-14 13:44:22 -0600351 lp::Nack nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000352 strategyA.afterReceiveNack_count = 0;
353 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000354 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000355 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
356 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700357
Junxiao Shi9d727852019-05-14 13:44:22 -0600358 lp::Nack nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000359 strategyA.afterReceiveNack_count = 0;
360 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000361 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000362 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
363 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700364
365 // record Nack on PIT out-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000366 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700367 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700368 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
369 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
370
371 // drop if no PIT entry
Junxiao Shi9d727852019-05-14 13:44:22 -0600372 lp::Nack nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), 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), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000376 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
377 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700378
379 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600380 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700381 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000382 pit4->insertOrUpdateOutRecord(*face1, 0, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700383
Junxiao Shi9d727852019-05-14 13:44:22 -0600384 lp::Nack nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000385 strategyA.afterReceiveNack_count = 0;
386 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000387 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000388 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
389 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700390
391 // drop if Nonce does not match out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600392 lp::Nack nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000393 strategyA.afterReceiveNack_count = 0;
394 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000395 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000396 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
397 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700398
399 // drop if inFace is multi-access
ashiqopud3ae85d2019-02-17 02:29:55 +0000400 pit4->insertOrUpdateOutRecord(*face3, 0, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000401 strategyA.afterReceiveNack_count = 0;
402 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000403 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000404 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
405 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700406}
407
408BOOST_AUTO_TEST_CASE(OutgoingNack)
409{
410 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700411 auto face1 = make_shared<DummyFace>();
412 auto face2 = make_shared<DummyFace>();
413 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
414 ndn::nfd::FACE_SCOPE_NON_LOCAL,
415 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
416 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
417 forwarder.addFace(face1);
418 forwarder.addFace(face2);
419 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700420
421 Pit& pit = forwarder.getPit();
422
423 lp::NackHeader nackHeader;
424 nackHeader.setReason(lp::NackReason::CONGESTION);
425
426 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600427 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700428 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000429 pit1->insertOrUpdateInRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700430
431 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000432 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700433 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
434
435 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600436 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700437 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000438 pit2->insertOrUpdateInRecord(*face1, 0, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600439 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
ashiqopud3ae85d2019-02-17 02:29:55 +0000440 pit2->insertOrUpdateInRecord(*face2, 0, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700441
442 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000443 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700444 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
445 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
446 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
447
448 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000449 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700450 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700451
452 // send Nack with correct Nonce
453 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000454 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700455 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
456 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
457 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
458
459 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000460 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700461 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700462
463 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600464 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
ashiqopud3ae85d2019-02-17 02:29:55 +0000465 pit2->insertOrUpdateInRecord(*face3, 0, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700466
467 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000468 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700469 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
470}
471
472BOOST_AUTO_TEST_CASE(InterestLoopNack)
473{
474 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700475 auto face1 = make_shared<DummyFace>();
476 auto face2 = make_shared<DummyFace>();
477 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
478 ndn::nfd::FACE_SCOPE_NON_LOCAL,
479 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
480 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700481 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700482 forwarder.addFace(face1);
483 forwarder.addFace(face2);
484 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700485 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700486
487 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000488 fib.insert("/zT4XwK0Hnx").first->addOrUpdateNextHop(*face4, 0, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700489
490 // receive Interest on face1
491 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600492 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000493 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700494 BOOST_CHECK(face1->sentNacks.empty());
495
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000496 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700497 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600498 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000499 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000500 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700501
502 // receive Interest with duplicate Nonce on face2
503 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600504 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000505 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700506 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
507 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
508 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
509
510 // receive Interest with new Nonce on face2
511 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600512 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000513 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700514 BOOST_CHECK(face2->sentNacks.empty());
515
516 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
517 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600518 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000519 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700520 BOOST_CHECK(face3->sentNacks.empty());
521}
522
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400523BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700524{
Junxiao Shia110f262014-10-12 12:35:20 -0700525 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700526 auto face1 = make_shared<DummyFace>();
527 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700528 forwarder.addFace(face1);
529 forwarder.addFace(face2);
530
531 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700532 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
533 if (pktType == tlv::Interest) {
534 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000535 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700536 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700537 });
Junxiao Shia110f262014-10-12 12:35:20 -0700538
539 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000540 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700541
Junxiao Shi455581d2014-11-17 18:38:40 -0700542 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600543 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000544 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700545
Junxiao Shi455581d2014-11-17 18:38:40 -0700546 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400547 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
548 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700549
Junxiao Shicde37ad2015-12-24 01:02:05 -0700550 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700551
552 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
553 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
554 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
555 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
556 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700557}
558
Junxiao Shid41d6072016-06-19 23:35:27 +0000559BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700560{
561 Forwarder forwarder;
562 shared_ptr<Face> face1 = make_shared<DummyFace>();
563 forwarder.addFace(face1);
564
Junxiao Shi9d727852019-05-14 13:44:22 -0600565 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700566
567 DeadNonceList& dnl = forwarder.getDeadNonceList();
568 dnl.add(interest->getName(), interest->getNonce());
569 Pit& pit = forwarder.getPit();
570 BOOST_REQUIRE_EQUAL(pit.size(), 0);
571
ashiqopuc7079482019-02-20 05:34:37 +0000572 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400573 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700574 BOOST_CHECK_EQUAL(pit.size(), 0);
575}
576
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400577BOOST_AUTO_TEST_SUITE_END() // TestForwarder
578BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700579
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700580} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700581} // namespace nfd