blob: c2e646ea4d858d46567b84f984ee31c4c46109c3 [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();
Ju Pand8315bf2019-07-31 06:59:07 +000053 fib::Entry* entry = fib.insert("/A").first;
54 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070055
Junxiao Shida93f1f2015-11-11 06:13:16 -070056 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
57 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000058 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
59 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060060 face1->receiveInterest(*makeInterest("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040061 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070062 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000063 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070064 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
65 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070066 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
67 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000068 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
69 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070070
Junxiao Shida93f1f2015-11-11 06:13:16 -070071 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
72 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060073 face2->receiveData(*makeData("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040074 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070075 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shi9d727852019-05-14 13:44:22 -060076 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070077 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
78 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070079 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
80 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070081}
82
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070083BOOST_AUTO_TEST_CASE(CsMatched)
84{
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070085 Forwarder forwarder;
86
Junxiao Shicde37ad2015-12-24 01:02:05 -070087 auto face1 = make_shared<DummyFace>();
88 auto face2 = make_shared<DummyFace>();
89 auto face3 = make_shared<DummyFace>();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070090 forwarder.addFace(face1);
91 forwarder.addFace(face2);
92 forwarder.addFace(face3);
93
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070094 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +000095 fib::Entry* entry = fib.insert("/A").first;
96 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070097
98 Pit& pit = forwarder.getPit();
99 BOOST_CHECK_EQUAL(pit.size(), 0);
100
Junxiao Shi9d727852019-05-14 13:44:22 -0600101 auto data = makeData("/A/B");
102 data->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
103 forwarder.getCs().insert(*data);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700104
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000105 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
106 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -0600107 face1->receiveInterest(*makeInterest("/A", true), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400108 this->advanceClocks(1_ms, 5_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700109 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700110 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000111 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
112 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700113
Junxiao Shicde37ad2015-12-24 01:02:05 -0700114 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700115 // IncomingFaceId field should be reset to represent CS
Junxiao Shi9d727852019-05-14 13:44:22 -0600116 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700117 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
118 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700119
Davide Pesavento14e71f02019-03-28 17:35:25 -0400120 this->advanceClocks(100_ms, 500_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700121 // PIT entry should not be left behind
122 BOOST_CHECK_EQUAL(pit.size(), 0);
123}
124
Junxiao Shi891f47b2016-06-20 00:02:11 +0000125BOOST_AUTO_TEST_CASE(OutgoingInterest)
126{
127 Forwarder forwarder;
128 auto face1 = make_shared<DummyFace>();
129 auto face2 = make_shared<DummyFace>();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000130 forwarder.addFace(face1);
131 forwarder.addFace(face2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000132
133 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600134 auto interestA1 = makeInterest("/A", false, nullopt, 8378);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000135 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000136 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000137
Junxiao Shi9d727852019-05-14 13:44:22 -0600138 auto interestA2 = makeInterest("/A", false, nullopt, 1698);
ashiqopuc7079482019-02-20 05:34:37 +0000139 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000140
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000141 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000142 BOOST_REQUIRE(outA2 != pitA->out_end());
143 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000144
Junxiao Shi891f47b2016-06-20 00:02:11 +0000145 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000146 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000147}
148
Junxiao Shie342e8d2016-09-18 16:48:00 +0000149BOOST_AUTO_TEST_CASE(NextHopFaceId)
150{
151 Forwarder forwarder;
152
153 auto face1 = make_shared<DummyFace>();
154 auto face2 = make_shared<DummyFace>();
155 auto face3 = make_shared<DummyFace>();
156 forwarder.addFace(face1);
157 forwarder.addFace(face2);
158 forwarder.addFace(face3);
159
160 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000161 fib::Entry* entry = fib.insert("/A").first;
162 fib.addOrUpdateNextHop(*entry, *face3, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000163
Junxiao Shi9d727852019-05-14 13:44:22 -0600164 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000165 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
166
ashiqopu075bb7d2019-03-10 01:38:21 +0000167 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400168 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000169 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
170 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
171 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
172}
173
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700174class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700175{
176public:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000177 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400178 onDataUnsolicited(const FaceEndpoint&, const Data&) final
Junxiao Shi88884492014-02-15 15:57:43 -0700179 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700180 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700181 }
182
183protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000184 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400185 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700186 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700187 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700188 }
189
190public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400191 int dispatchToStrategy_count = 0;
192 int onDataUnsolicited_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700193};
194
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700195BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700196{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700197 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700198 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
199 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700200 forwarder.addFace(face1);
201 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700202
Junxiao Shi88884492014-02-15 15:57:43 -0700203 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700204 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600205 auto i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000206 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700207 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700208
Junxiao Shi88884492014-02-15 15:57:43 -0700209 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700210 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600211 auto i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000212 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700213 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700214
Junxiao Shi88884492014-02-15 15:57:43 -0700215 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700216 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600217 auto i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000218 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700219 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700220
Junxiao Shi88884492014-02-15 15:57:43 -0700221 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700222 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600223 auto i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000224 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
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 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700228 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600229 auto d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000230 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700231 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700232
233 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700234 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600235 auto d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000236 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700237 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700238
Junxiao Shi88884492014-02-15 15:57:43 -0700239 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700240 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600241 auto d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000242 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700243 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700244
245 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700246 forwarder.onDataUnsolicited_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600247 auto d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000248 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700249 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700250}
251
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700252BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700253{
Junxiao Shif3c07812014-03-11 21:48:49 -0700254 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700255 auto face1 = make_shared<DummyFace>();
256 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700257 forwarder.addFace(face1);
258 forwarder.addFace(face2);
259
Junxiao Shi9d727852019-05-14 13:44:22 -0600260 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
261 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700262
Junxiao Shi9d727852019-05-14 13:44:22 -0600263 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000264 strategyA.afterReceiveInterest_count = 0;
265 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000266 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000267 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700268
Junxiao Shi9d727852019-05-14 13:44:22 -0600269 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000270 strategyB.afterReceiveInterest_count = 0;
271 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000272 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000273 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700274
Davide Pesavento14e71f02019-03-28 17:35:25 -0400275 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700276
Junxiao Shi9d727852019-05-14 13:44:22 -0600277 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000278 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000279 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000280 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700281
Junxiao Shi9d727852019-05-14 13:44:22 -0600282 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000283 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000284 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000285 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700286
Junxiao Shi9d727852019-05-14 13:44:22 -0600287 auto interest3 = makeInterest("/A/3", false, 30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000288 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shi9d727852019-05-14 13:44:22 -0600289 auto interest4 = makeInterest("/B/4", false, 5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000290 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700291}
292
Junxiao Shida006f52014-05-16 11:18:00 -0700293BOOST_AUTO_TEST_CASE(IncomingData)
294{
Junxiao Shida006f52014-05-16 11:18:00 -0700295 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700296 auto face1 = make_shared<DummyFace>();
297 auto face2 = make_shared<DummyFace>();
298 auto face3 = make_shared<DummyFace>();
299 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700300 forwarder.addFace(face1);
301 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700302 forwarder.addFace(face3);
303 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700304
305 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600306 auto interestD = makeInterest("/A/B/C/D");
307 shared_ptr<pit::Entry> pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000308 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600309 auto interestA = makeInterest("/A", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700310 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000311 pitA->insertOrUpdateInRecord(*face2, *interestA);
312 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600313 auto interestC = makeInterest("/A/B/C", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700314 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000315 pitC->insertOrUpdateInRecord(*face3, *interestC);
316 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700317
Junxiao Shi9d727852019-05-14 13:44:22 -0600318 auto dataD = makeData("/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000319 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400320 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700321
Junxiao Shicde37ad2015-12-24 01:02:05 -0700322 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
323 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
324 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
325 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700326}
327
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700328BOOST_AUTO_TEST_CASE(IncomingNack)
329{
330 Forwarder forwarder;
331 auto face1 = make_shared<DummyFace>();
332 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700333 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
334 ndn::nfd::FACE_SCOPE_NON_LOCAL,
335 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
336 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700337 forwarder.addFace(face1);
338 forwarder.addFace(face2);
339 forwarder.addFace(face3);
340
Junxiao Shi9d727852019-05-14 13:44:22 -0600341 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
342 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700343
344 Pit& pit = forwarder.getPit();
345
346 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600347 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700348 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000349 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600350 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700351 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000352 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700353
Junxiao Shi9d727852019-05-14 13:44:22 -0600354 lp::Nack nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000355 strategyA.afterReceiveNack_count = 0;
356 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000357 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000358 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
359 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700360
Junxiao Shi9d727852019-05-14 13:44:22 -0600361 lp::Nack nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000362 strategyA.afterReceiveNack_count = 0;
363 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000364 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000365 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
366 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700367
368 // record Nack on PIT out-record
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000369 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700370 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700371 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
372 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
373
374 // drop if no PIT entry
Junxiao Shi9d727852019-05-14 13:44:22 -0600375 lp::Nack nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000376 strategyA.afterReceiveNack_count = 0;
377 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000378 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000379 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
380 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700381
382 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600383 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700384 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000385 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700386
Junxiao Shi9d727852019-05-14 13:44:22 -0600387 lp::Nack nack4a = makeNack(*interest4, 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(*face2, 0), nack4a);
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 Nonce does not match out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600395 lp::Nack nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), 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(*face1, 0), nack4b);
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 inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000403 pit4->insertOrUpdateOutRecord(*face3, *interest4);
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(*face3, 0), nack4a);
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
411BOOST_AUTO_TEST_CASE(OutgoingNack)
412{
413 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700414 auto face1 = make_shared<DummyFace>();
415 auto face2 = make_shared<DummyFace>();
416 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
417 ndn::nfd::FACE_SCOPE_NON_LOCAL,
418 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
419 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
420 forwarder.addFace(face1);
421 forwarder.addFace(face2);
422 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700423
424 Pit& pit = forwarder.getPit();
425
426 lp::NackHeader nackHeader;
427 nackHeader.setReason(lp::NackReason::CONGESTION);
428
429 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600430 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700431 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000432 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700433
434 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000435 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700436 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
437
438 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600439 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700440 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000441 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600442 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000443 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700444
445 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000446 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700447 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
448 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
449 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
450
451 // erase in-record
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000452 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700453 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700454
455 // send Nack with correct Nonce
456 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000457 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700458 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
459 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
460 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
461
462 // erase in-record
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000463 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700464 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700465
466 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600467 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000468 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700469
470 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000471 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700472 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
473}
474
475BOOST_AUTO_TEST_CASE(InterestLoopNack)
476{
477 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700478 auto face1 = make_shared<DummyFace>();
479 auto face2 = make_shared<DummyFace>();
480 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
481 ndn::nfd::FACE_SCOPE_NON_LOCAL,
482 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
483 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700484 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700485 forwarder.addFace(face1);
486 forwarder.addFace(face2);
487 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700488 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700489
490 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000491 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
492 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700493
494 // receive Interest on face1
495 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600496 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000497 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700498 BOOST_CHECK(face1->sentNacks.empty());
499
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000500 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700501 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600502 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000503 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000504 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700505
506 // receive Interest with duplicate Nonce on face2
507 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600508 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000509 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700510 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400511 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700512 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
513
514 // receive Interest with new Nonce on face2
515 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600516 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000517 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700518 BOOST_CHECK(face2->sentNacks.empty());
519
520 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
521 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600522 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000523 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700524 BOOST_CHECK(face3->sentNacks.empty());
525}
526
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400527BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700528{
Junxiao Shia110f262014-10-12 12:35:20 -0700529 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700530 auto face1 = make_shared<DummyFace>();
531 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700532 forwarder.addFace(face1);
533 forwarder.addFace(face2);
534
535 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700536 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
537 if (pktType == tlv::Interest) {
538 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000539 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700540 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700541 });
Junxiao Shia110f262014-10-12 12:35:20 -0700542
543 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000544 fib::Entry* entry = fib.insert("/A").first;
545 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700546
Junxiao Shi455581d2014-11-17 18:38:40 -0700547 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600548 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000549 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700550
Junxiao Shi455581d2014-11-17 18:38:40 -0700551 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400552 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
553 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700554
Junxiao Shicde37ad2015-12-24 01:02:05 -0700555 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700556
557 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
558 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
559 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
560 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
561 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700562}
563
Junxiao Shid41d6072016-06-19 23:35:27 +0000564BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700565{
566 Forwarder forwarder;
567 shared_ptr<Face> face1 = make_shared<DummyFace>();
568 forwarder.addFace(face1);
569
Junxiao Shi9d727852019-05-14 13:44:22 -0600570 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700571
572 DeadNonceList& dnl = forwarder.getDeadNonceList();
573 dnl.add(interest->getName(), interest->getNonce());
574 Pit& pit = forwarder.getPit();
575 BOOST_REQUIRE_EQUAL(pit.size(), 0);
576
ashiqopuc7079482019-02-20 05:34:37 +0000577 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400578 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700579 BOOST_CHECK_EQUAL(pit.size(), 0);
580}
581
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400582BOOST_AUTO_TEST_SUITE_END() // TestForwarder
583BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700584
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700585} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700586} // namespace nfd