blob: 7325f2486be90e10cc61dca231479e16eb668196 [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 Shia6de4292016-07-12 02:08:10 +000047 shared_ptr<Interest> interestAB = makeInterest("/A/B");
Davide Pesavento14e71f02019-03-28 17:35:25 -040048 interestAB->setInterestLifetime(4_s);
Junxiao Shia6de4292016-07-12 02:08:10 +000049 shared_ptr<Data> dataABC = makeData("/A/B/C");
Junxiao Shi8c8d2182014-01-30 22:33:00 -070050
Junxiao Shicde37ad2015-12-24 01:02:05 -070051 auto face1 = make_shared<DummyFace>();
52 auto face2 = make_shared<DummyFace>();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070053 forwarder.addFace(face1);
54 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070055
Junxiao Shi8c8d2182014-01-30 22:33:00 -070056 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +000057 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070058
Junxiao Shida93f1f2015-11-11 06:13:16 -070059 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
60 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000061 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
62 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
ashiqopu075bb7d2019-03-10 01:38:21 +000063 face1->receiveInterest(*interestAB, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040064 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070065 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000066 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070067 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
68 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070069 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
70 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000071 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
72 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070073
Junxiao Shida93f1f2015-11-11 06:13:16 -070074 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
75 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
ashiqopu075bb7d2019-03-10 01:38:21 +000076 face2->receiveData(*dataABC, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040077 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070078 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000079 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B/C");
Junxiao Shicde37ad2015-12-24 01:02:05 -070080 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
81 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070082 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
83 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070084}
85
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070086BOOST_AUTO_TEST_CASE(CsMatched)
87{
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070088 Forwarder forwarder;
89
Junxiao Shicde37ad2015-12-24 01:02:05 -070090 auto face1 = make_shared<DummyFace>();
91 auto face2 = make_shared<DummyFace>();
92 auto face3 = make_shared<DummyFace>();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070093 forwarder.addFace(face1);
94 forwarder.addFace(face2);
95 forwarder.addFace(face3);
96
Junxiao Shia6de4292016-07-12 02:08:10 +000097 shared_ptr<Interest> interestA = makeInterest("/A");
Davide Pesavento14e71f02019-03-28 17:35:25 -040098 interestA->setInterestLifetime(4_s);
Junxiao Shia6de4292016-07-12 02:08:10 +000099 shared_ptr<Data> dataA = makeData("/A");
Junxiao Shi0de23a22015-12-03 20:07:02 +0000100 dataA->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700101
102 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000103 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700104
105 Pit& pit = forwarder.getPit();
106 BOOST_CHECK_EQUAL(pit.size(), 0);
107
108 Cs& cs = forwarder.getCs();
Minsheng Zhangffe8bbb2016-03-10 13:40:37 -0700109 cs.insert(*dataA);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700110
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000111 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
112 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
ashiqopu075bb7d2019-03-10 01:38:21 +0000113 face1->receiveInterest(*interestA, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400114 this->advanceClocks(1_ms, 5_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700115 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700116 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000117 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
118 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700119
Junxiao Shicde37ad2015-12-24 01:02:05 -0700120 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700121 // IncomingFaceId field should be reset to represent CS
Junxiao Shicde37ad2015-12-24 01:02:05 -0700122 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
123 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700124
Davide Pesavento14e71f02019-03-28 17:35:25 -0400125 this->advanceClocks(100_ms, 500_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700126 // PIT entry should not be left behind
127 BOOST_CHECK_EQUAL(pit.size(), 0);
128}
129
Junxiao Shi891f47b2016-06-20 00:02:11 +0000130BOOST_AUTO_TEST_CASE(OutgoingInterest)
131{
132 Forwarder forwarder;
133 auto face1 = make_shared<DummyFace>();
134 auto face2 = make_shared<DummyFace>();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000135 forwarder.addFace(face1);
136 forwarder.addFace(face2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000137
138 Pit& pit = forwarder.getPit();
Junxiao Shia6de4292016-07-12 02:08:10 +0000139 auto interestA1 = makeInterest("/A");
Junxiao Shi891f47b2016-06-20 00:02:11 +0000140 interestA1->setNonce(8378);
141 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000142 pitA->insertOrUpdateInRecord(*face1, 0, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000143
Junxiao Shia6de4292016-07-12 02:08:10 +0000144 auto interestA2 = makeInterest("/A");
Junxiao Shic5f651f2016-11-17 22:58:12 +0000145 interestA2->setNonce(1698);
ashiqopuc7079482019-02-20 05:34:37 +0000146 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000147
ashiqopud3ae85d2019-02-17 02:29:55 +0000148 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2, 0);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000149 BOOST_REQUIRE(outA2 != pitA->out_end());
150 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000151
Junxiao Shi891f47b2016-06-20 00:02:11 +0000152 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000153 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000154}
155
Junxiao Shie342e8d2016-09-18 16:48:00 +0000156BOOST_AUTO_TEST_CASE(NextHopFaceId)
157{
158 Forwarder forwarder;
159
160 auto face1 = make_shared<DummyFace>();
161 auto face2 = make_shared<DummyFace>();
162 auto face3 = make_shared<DummyFace>();
163 forwarder.addFace(face1);
164 forwarder.addFace(face2);
165 forwarder.addFace(face3);
166
167 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000168 fib.insert("/A").first->addOrUpdateNextHop(*face3, 0, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000169
170 shared_ptr<Interest> interest = makeInterest("/A/B");
171 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
172
ashiqopu075bb7d2019-03-10 01:38:21 +0000173 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400174 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000175 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
176 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
177 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
178}
179
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700180class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700181{
182public:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000183 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400184 onDataUnsolicited(const FaceEndpoint&, const Data&) final
Junxiao Shi88884492014-02-15 15:57:43 -0700185 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700186 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700187 }
188
189protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000190 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400191 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700192 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700193 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700194 }
195
196public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400197 int dispatchToStrategy_count = 0;
198 int onDataUnsolicited_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700199};
200
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700201BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700202{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700203 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700204 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
205 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700206 forwarder.addFace(face1);
207 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700208
Junxiao Shi88884492014-02-15 15:57:43 -0700209 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700210 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700211 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000212 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700213 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700214
Junxiao Shi88884492014-02-15 15:57:43 -0700215 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700216 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700217 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000218 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700219 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700220
Junxiao Shi88884492014-02-15 15:57:43 -0700221 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700222 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700223 shared_ptr<Interest> i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000224 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700225 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700226
Junxiao Shi88884492014-02-15 15:57:43 -0700227 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700228 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700229 shared_ptr<Interest> i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000230 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700231 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700232
Junxiao Shi88884492014-02-15 15:57:43 -0700233 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700234 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700235 shared_ptr<Data> d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000236 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700237 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700238
239 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700240 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700241 shared_ptr<Data> d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000242 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700243 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700244
Junxiao Shi88884492014-02-15 15:57:43 -0700245 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700246 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700247 shared_ptr<Data> d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000248 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700249 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700250
251 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700252 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700253 shared_ptr<Data> d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000254 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700255 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700256}
257
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700258BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700259{
Junxiao Shif3c07812014-03-11 21:48:49 -0700260 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700261 auto face1 = make_shared<DummyFace>();
262 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700263 forwarder.addFace(face1);
264 forwarder.addFace(face2);
265
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000266 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
267 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700268
269 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000270 strategyA.afterReceiveInterest_count = 0;
271 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000272 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000273 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700274
275 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000276 strategyB.afterReceiveInterest_count = 0;
277 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000278 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000279 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700280
Davide Pesavento14e71f02019-03-28 17:35:25 -0400281 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700282
283 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000284 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000285 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000286 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700287
288 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000289 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000290 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000291 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700292
293 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400294 interest3->setInterestLifetime(30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000295 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700296 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400297 interest4->setInterestLifetime(5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000298 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700299}
300
Junxiao Shida006f52014-05-16 11:18:00 -0700301BOOST_AUTO_TEST_CASE(IncomingData)
302{
Junxiao Shida006f52014-05-16 11:18:00 -0700303 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700304 auto face1 = make_shared<DummyFace>();
305 auto face2 = make_shared<DummyFace>();
306 auto face3 = make_shared<DummyFace>();
307 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700308 forwarder.addFace(face1);
309 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700310 forwarder.addFace(face3);
311 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700312
313 Pit& pit = forwarder.getPit();
314 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
315 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000316 pit0->insertOrUpdateInRecord(*face1, 0, *interest0);
Junxiao Shida006f52014-05-16 11:18:00 -0700317 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
318 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000319 pitA->insertOrUpdateInRecord(*face1, 0, *interestA);
320 pitA->insertOrUpdateInRecord(*face2, 0, *interestA);
Junxiao Shida006f52014-05-16 11:18:00 -0700321 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
322 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000323 pitC->insertOrUpdateInRecord(*face3, 0, *interestC);
324 pitC->insertOrUpdateInRecord(*face4, 0, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700325
326 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000327 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400328 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700329
Junxiao Shicde37ad2015-12-24 01:02:05 -0700330 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
331 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
332 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
333 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700334}
335
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700336BOOST_AUTO_TEST_CASE(IncomingNack)
337{
338 Forwarder forwarder;
339 auto face1 = make_shared<DummyFace>();
340 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700341 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
342 ndn::nfd::FACE_SCOPE_NON_LOCAL,
343 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
344 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700345 forwarder.addFace(face1);
346 forwarder.addFace(face2);
347 forwarder.addFace(face3);
348
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000349 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
350 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700351
352 Pit& pit = forwarder.getPit();
353
354 // dispatch to the correct strategy
355 shared_ptr<Interest> interest1 = makeInterest("/A/AYJqayrzF", 562);
356 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000357 pit1->insertOrUpdateOutRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700358 shared_ptr<Interest> interest2 = makeInterest("/B/EVyP73ru", 221);
359 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000360 pit2->insertOrUpdateOutRecord(*face1, 0, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700361
362 lp::Nack nack1 = makeNack("/A/AYJqayrzF", 562, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000363 strategyA.afterReceiveNack_count = 0;
364 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000365 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000366 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
367 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700368
369 lp::Nack nack2 = makeNack("/B/EVyP73ru", 221, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000370 strategyA.afterReceiveNack_count = 0;
371 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000372 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000373 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
374 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700375
376 // record Nack on PIT out-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000377 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700378 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700379 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
380 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
381
382 // drop if no PIT entry
383 lp::Nack nack3 = makeNack("/yEcw5HhdM", 243, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000384 strategyA.afterReceiveNack_count = 0;
385 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000386 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000387 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
388 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700389
390 // drop if no out-record
391 shared_ptr<Interest> interest4 = makeInterest("/Etab4KpY", 157);
392 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000393 pit4->insertOrUpdateOutRecord(*face1, 0, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700394
395 lp::Nack nack4a = makeNack("/Etab4KpY", 157, lp::NackReason::CONGESTION);
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(*face2, 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 // drop if Nonce does not match out-record
403 lp::Nack nack4b = makeNack("/Etab4KpY", 294, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000404 strategyA.afterReceiveNack_count = 0;
405 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000406 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000407 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
408 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700409
410 // drop if inFace is multi-access
ashiqopud3ae85d2019-02-17 02:29:55 +0000411 pit4->insertOrUpdateOutRecord(*face3, 0, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000412 strategyA.afterReceiveNack_count = 0;
413 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000414 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000415 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
416 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700417}
418
419BOOST_AUTO_TEST_CASE(OutgoingNack)
420{
421 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700422 auto face1 = make_shared<DummyFace>();
423 auto face2 = make_shared<DummyFace>();
424 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
425 ndn::nfd::FACE_SCOPE_NON_LOCAL,
426 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
427 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
428 forwarder.addFace(face1);
429 forwarder.addFace(face2);
430 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700431
432 Pit& pit = forwarder.getPit();
433
434 lp::NackHeader nackHeader;
435 nackHeader.setReason(lp::NackReason::CONGESTION);
436
437 // don't send Nack if there's no in-record
438 shared_ptr<Interest> interest1 = makeInterest("/fM5IVEtC", 719);
439 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000440 pit1->insertOrUpdateInRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700441
442 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000443 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700444 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
445
446 // send Nack with correct Nonce
447 shared_ptr<Interest> interest2a = makeInterest("/Vi8tRm9MG3", 152);
448 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000449 pit2->insertOrUpdateInRecord(*face1, 0, *interest2a);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700450 shared_ptr<Interest> interest2b = makeInterest("/Vi8tRm9MG3", 808);
ashiqopud3ae85d2019-02-17 02:29:55 +0000451 pit2->insertOrUpdateInRecord(*face2, 0, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700452
453 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000454 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700455 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
456 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
457 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
458
459 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000460 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700461 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700462
463 // send Nack with correct Nonce
464 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000465 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700466 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
467 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
468 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
469
470 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000471 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700472 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700473
474 // don't send Nack to multi-access face
475 shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
ashiqopud3ae85d2019-02-17 02:29:55 +0000476 pit2->insertOrUpdateInRecord(*face3, 0, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700477
478 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000479 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700480 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
481}
482
483BOOST_AUTO_TEST_CASE(InterestLoopNack)
484{
485 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700486 auto face1 = make_shared<DummyFace>();
487 auto face2 = make_shared<DummyFace>();
488 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
489 ndn::nfd::FACE_SCOPE_NON_LOCAL,
490 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
491 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700492 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700493 forwarder.addFace(face1);
494 forwarder.addFace(face2);
495 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700496 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700497
498 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000499 fib.insert("/zT4XwK0Hnx").first->addOrUpdateNextHop(*face4, 0, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700500
501 // receive Interest on face1
502 face1->sentNacks.clear();
503 shared_ptr<Interest> interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000504 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700505 BOOST_CHECK(face1->sentNacks.empty());
506
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000507 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700508 face1->sentNacks.clear();
509 shared_ptr<Interest> interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000510 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000511 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700512
513 // receive Interest with duplicate Nonce on face2
514 face2->sentNacks.clear();
515 shared_ptr<Interest> interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000516 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700517 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
518 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
519 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
520
521 // receive Interest with new Nonce on face2
522 face2->sentNacks.clear();
523 shared_ptr<Interest> interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000524 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700525 BOOST_CHECK(face2->sentNacks.empty());
526
527 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
528 face3->sentNacks.clear();
529 shared_ptr<Interest> interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000530 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700531 BOOST_CHECK(face3->sentNacks.empty());
532}
533
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400534BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700535{
Junxiao Shia110f262014-10-12 12:35:20 -0700536 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700537 auto face1 = make_shared<DummyFace>();
538 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700539 forwarder.addFace(face1);
540 forwarder.addFace(face2);
541
542 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700543 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
544 if (pktType == tlv::Interest) {
545 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000546 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700547 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700548 });
Junxiao Shia110f262014-10-12 12:35:20 -0700549
550 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000551 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700552
Junxiao Shi455581d2014-11-17 18:38:40 -0700553 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700554 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
555 interest->setNonce(82101183);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400556 interest->setInterestLifetime(50_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000557 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700558
Junxiao Shi455581d2014-11-17 18:38:40 -0700559 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400560 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
561 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700562
Junxiao Shicde37ad2015-12-24 01:02:05 -0700563 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700564
565 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
566 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
567 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
568 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
569 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700570}
571
Junxiao Shid41d6072016-06-19 23:35:27 +0000572BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700573{
574 Forwarder forwarder;
575 shared_ptr<Face> face1 = make_shared<DummyFace>();
576 forwarder.addFace(face1);
577
578 shared_ptr<Interest> interest = makeInterest("ndn:/hcLSAsQ9A");
579 interest->setNonce(61883075);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400580 interest->setInterestLifetime(2_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700581
582 DeadNonceList& dnl = forwarder.getDeadNonceList();
583 dnl.add(interest->getName(), interest->getNonce());
584 Pit& pit = forwarder.getPit();
585 BOOST_REQUIRE_EQUAL(pit.size(), 0);
586
ashiqopuc7079482019-02-20 05:34:37 +0000587 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400588 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700589 BOOST_CHECK_EQUAL(pit.size(), 0);
590}
591
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400592BOOST_AUTO_TEST_SUITE_END() // TestForwarder
593BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700594
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700595} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700596} // namespace nfd