blob: 59b5ef3c9d49f3e7436708e64bf8c80158e489a0 [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"
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);
Junxiao Shid41d6072016-06-19 23:35:27 +000063 face1->receiveInterest(*interestAB);
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);
Junxiao Shid41d6072016-06-19 23:35:27 +000076 face2->receiveData(*dataABC);
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);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700113 face1->receiveInterest(*interestA);
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
173 face1->receiveInterest(*interest);
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 Shi9b27bd22014-02-26 20:29:58 -0700183 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700184 {
185 }
186
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000187 void
ashiqopuc7079482019-02-20 05:34:37 +0000188 onDataUnsolicited(const FaceEndpoint& ingress, const Data& data) override
Junxiao Shi88884492014-02-15 15:57:43 -0700189 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700190 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700191 }
192
193protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000194 void
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400195 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) override
Junxiao Shi88884492014-02-15 15:57:43 -0700196 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700197 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700198 }
199
200public:
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700201 int dispatchToStrategy_count;
202 int onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700203};
204
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700205BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700206{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700207 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700208 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
209 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700210 forwarder.addFace(face1);
211 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700212
Junxiao Shi88884492014-02-15 15:57:43 -0700213 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700214 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700215 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000216 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700217 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700218
Junxiao Shi88884492014-02-15 15:57:43 -0700219 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700220 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700221 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000222 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700223 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700224
Junxiao Shi88884492014-02-15 15:57:43 -0700225 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700226 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700227 shared_ptr<Interest> i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000228 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700229 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700230
Junxiao Shi88884492014-02-15 15:57:43 -0700231 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700232 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700233 shared_ptr<Interest> i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000234 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700235 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700236
Junxiao Shi88884492014-02-15 15:57:43 -0700237 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700238 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700239 shared_ptr<Data> d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000240 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700241 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700242
243 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700244 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700245 shared_ptr<Data> d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000246 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700247 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700248
Junxiao Shi88884492014-02-15 15:57:43 -0700249 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700250 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700251 shared_ptr<Data> d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000252 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700253 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700254
255 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700256 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700257 shared_ptr<Data> d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000258 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700259 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700260}
261
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700262BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700263{
Junxiao Shif3c07812014-03-11 21:48:49 -0700264 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700265 auto face1 = make_shared<DummyFace>();
266 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700267 forwarder.addFace(face1);
268 forwarder.addFace(face2);
269
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000270 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
271 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700272
273 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000274 strategyA.afterReceiveInterest_count = 0;
275 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000276 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000277 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700278
279 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000280 strategyB.afterReceiveInterest_count = 0;
281 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000282 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000283 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700284
Davide Pesavento14e71f02019-03-28 17:35:25 -0400285 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700286
287 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000288 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000289 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000290 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700291
292 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000293 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000294 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000295 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700296
297 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400298 interest3->setInterestLifetime(30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000299 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700300 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400301 interest4->setInterestLifetime(5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000302 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700303}
304
Junxiao Shida006f52014-05-16 11:18:00 -0700305BOOST_AUTO_TEST_CASE(IncomingData)
306{
Junxiao Shida006f52014-05-16 11:18:00 -0700307 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700308 auto face1 = make_shared<DummyFace>();
309 auto face2 = make_shared<DummyFace>();
310 auto face3 = make_shared<DummyFace>();
311 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700312 forwarder.addFace(face1);
313 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700314 forwarder.addFace(face3);
315 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700316
317 Pit& pit = forwarder.getPit();
318 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
319 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000320 pit0->insertOrUpdateInRecord(*face1, 0, *interest0);
Junxiao Shida006f52014-05-16 11:18:00 -0700321 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
322 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000323 pitA->insertOrUpdateInRecord(*face1, 0, *interestA);
324 pitA->insertOrUpdateInRecord(*face2, 0, *interestA);
Junxiao Shida006f52014-05-16 11:18:00 -0700325 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
326 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000327 pitC->insertOrUpdateInRecord(*face3, 0, *interestC);
328 pitC->insertOrUpdateInRecord(*face4, 0, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700329
330 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000331 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400332 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700333
Junxiao Shicde37ad2015-12-24 01:02:05 -0700334 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
335 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
336 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
337 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700338}
339
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700340BOOST_AUTO_TEST_CASE(IncomingNack)
341{
342 Forwarder forwarder;
343 auto face1 = make_shared<DummyFace>();
344 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700345 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
346 ndn::nfd::FACE_SCOPE_NON_LOCAL,
347 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
348 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700349 forwarder.addFace(face1);
350 forwarder.addFace(face2);
351 forwarder.addFace(face3);
352
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000353 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
354 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700355
356 Pit& pit = forwarder.getPit();
357
358 // dispatch to the correct strategy
359 shared_ptr<Interest> interest1 = makeInterest("/A/AYJqayrzF", 562);
360 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000361 pit1->insertOrUpdateOutRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700362 shared_ptr<Interest> interest2 = makeInterest("/B/EVyP73ru", 221);
363 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000364 pit2->insertOrUpdateOutRecord(*face1, 0, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700365
366 lp::Nack nack1 = makeNack("/A/AYJqayrzF", 562, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000367 strategyA.afterReceiveNack_count = 0;
368 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000369 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000370 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
371 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700372
373 lp::Nack nack2 = makeNack("/B/EVyP73ru", 221, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000374 strategyA.afterReceiveNack_count = 0;
375 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000376 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000377 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
378 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700379
380 // record Nack on PIT out-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000381 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700382 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700383 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
384 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
385
386 // drop if no PIT entry
387 lp::Nack nack3 = makeNack("/yEcw5HhdM", 243, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000388 strategyA.afterReceiveNack_count = 0;
389 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000390 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000391 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
392 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700393
394 // drop if no out-record
395 shared_ptr<Interest> interest4 = makeInterest("/Etab4KpY", 157);
396 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000397 pit4->insertOrUpdateOutRecord(*face1, 0, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700398
399 lp::Nack nack4a = makeNack("/Etab4KpY", 157, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000400 strategyA.afterReceiveNack_count = 0;
401 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000402 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000403 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
404 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700405
406 // drop if Nonce does not match out-record
407 lp::Nack nack4b = makeNack("/Etab4KpY", 294, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000408 strategyA.afterReceiveNack_count = 0;
409 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000410 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000411 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
412 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700413
414 // drop if inFace is multi-access
ashiqopud3ae85d2019-02-17 02:29:55 +0000415 pit4->insertOrUpdateOutRecord(*face3, 0, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000416 strategyA.afterReceiveNack_count = 0;
417 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000418 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000419 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
420 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700421}
422
423BOOST_AUTO_TEST_CASE(OutgoingNack)
424{
425 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700426 auto face1 = make_shared<DummyFace>();
427 auto face2 = make_shared<DummyFace>();
428 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
429 ndn::nfd::FACE_SCOPE_NON_LOCAL,
430 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
431 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
432 forwarder.addFace(face1);
433 forwarder.addFace(face2);
434 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700435
436 Pit& pit = forwarder.getPit();
437
438 lp::NackHeader nackHeader;
439 nackHeader.setReason(lp::NackReason::CONGESTION);
440
441 // don't send Nack if there's no in-record
442 shared_ptr<Interest> interest1 = makeInterest("/fM5IVEtC", 719);
443 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000444 pit1->insertOrUpdateInRecord(*face1, 0, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700445
446 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000447 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700448 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
449
450 // send Nack with correct Nonce
451 shared_ptr<Interest> interest2a = makeInterest("/Vi8tRm9MG3", 152);
452 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
ashiqopud3ae85d2019-02-17 02:29:55 +0000453 pit2->insertOrUpdateInRecord(*face1, 0, *interest2a);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700454 shared_ptr<Interest> interest2b = makeInterest("/Vi8tRm9MG3", 808);
ashiqopud3ae85d2019-02-17 02:29:55 +0000455 pit2->insertOrUpdateInRecord(*face2, 0, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700456
457 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000458 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700459 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
460 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
461 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
462
463 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000464 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700465 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700466
467 // send Nack with correct Nonce
468 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000469 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700470 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
471 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
472 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
473
474 // erase in-record
ashiqopud3ae85d2019-02-17 02:29:55 +0000475 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1, 0);
Junxiao Shi4846f372016-04-05 13:39:30 -0700476 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700477
478 // don't send Nack to multi-access face
479 shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
ashiqopud3ae85d2019-02-17 02:29:55 +0000480 pit2->insertOrUpdateInRecord(*face3, 0, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700481
482 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000483 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700484 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
485}
486
487BOOST_AUTO_TEST_CASE(InterestLoopNack)
488{
489 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700490 auto face1 = make_shared<DummyFace>();
491 auto face2 = make_shared<DummyFace>();
492 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
493 ndn::nfd::FACE_SCOPE_NON_LOCAL,
494 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
495 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700496 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700497 forwarder.addFace(face1);
498 forwarder.addFace(face2);
499 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700500 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700501
502 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000503 fib.insert("/zT4XwK0Hnx").first->addOrUpdateNextHop(*face4, 0, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700504
505 // receive Interest on face1
506 face1->sentNacks.clear();
507 shared_ptr<Interest> interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
508 face1->receiveInterest(*interest1a);
509 BOOST_CHECK(face1->sentNacks.empty());
510
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000511 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700512 face1->sentNacks.clear();
513 shared_ptr<Interest> interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
514 face1->receiveInterest(*interest1b);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000515 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700516
517 // receive Interest with duplicate Nonce on face2
518 face2->sentNacks.clear();
519 shared_ptr<Interest> interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
520 face2->receiveInterest(*interest2a);
521 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
522 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
523 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
524
525 // receive Interest with new Nonce on face2
526 face2->sentNacks.clear();
527 shared_ptr<Interest> interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 944);
528 face2->receiveInterest(*interest2b);
529 BOOST_CHECK(face2->sentNacks.empty());
530
531 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
532 face3->sentNacks.clear();
533 shared_ptr<Interest> interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
534 face3->receiveInterest(*interest3a);
535 BOOST_CHECK(face3->sentNacks.empty());
536}
537
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400538BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700539{
Junxiao Shia110f262014-10-12 12:35:20 -0700540 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700541 auto face1 = make_shared<DummyFace>();
542 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700543 forwarder.addFace(face1);
544 forwarder.addFace(face2);
545
546 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700547 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
548 if (pktType == tlv::Interest) {
549 auto interest = make_shared<Interest>(face2->sentInterests.back());
Davide Pesavento3dade002019-03-19 11:29:56 -0600550 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700551 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700552 });
Junxiao Shia110f262014-10-12 12:35:20 -0700553
554 Fib& fib = forwarder.getFib();
ashiqopu3ad49db2018-10-20 22:38:47 +0000555 fib.insert("/A").first->addOrUpdateNextHop(*face2, 0, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700556
Junxiao Shi455581d2014-11-17 18:38:40 -0700557 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700558 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
559 interest->setNonce(82101183);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400560 interest->setInterestLifetime(50_ms);
Junxiao Shia110f262014-10-12 12:35:20 -0700561 face1->receiveInterest(*interest);
562
Junxiao Shi455581d2014-11-17 18:38:40 -0700563 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400564 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
565 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700566
Junxiao Shicde37ad2015-12-24 01:02:05 -0700567 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700568
569 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
570 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
571 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
572 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
573 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700574}
575
Junxiao Shid41d6072016-06-19 23:35:27 +0000576BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700577{
578 Forwarder forwarder;
579 shared_ptr<Face> face1 = make_shared<DummyFace>();
580 forwarder.addFace(face1);
581
582 shared_ptr<Interest> interest = makeInterest("ndn:/hcLSAsQ9A");
583 interest->setNonce(61883075);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400584 interest->setInterestLifetime(2_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700585
586 DeadNonceList& dnl = forwarder.getDeadNonceList();
587 dnl.add(interest->getName(), interest->getNonce());
588 Pit& pit = forwarder.getPit();
589 BOOST_REQUIRE_EQUAL(pit.size(), 0);
590
ashiqopuc7079482019-02-20 05:34:37 +0000591 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400592 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700593 BOOST_CHECK_EQUAL(pit.size(), 0);
594}
595
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400596BOOST_AUTO_TEST_SUITE_END() // TestForwarder
597BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700598
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700599} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700600} // namespace nfd