blob: 5f2518ea74a08def9eeaf60092f52213b129b341 [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/*
Eric Newberry9d283ad2020-04-12 23:37:17 -07003 * Copyright (c) 2014-2020, 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
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040040class ForwarderFixture : public GlobalIoTimeFixture
41{
42protected:
43 template<typename ...Args>
44 shared_ptr<DummyFace>
45 addFace(Args&&... args)
46 {
47 auto face = make_shared<DummyFace>(std::forward<Args>(args)...);
48 faceTable.add(face);
49 return face;
50 }
51
52protected:
53 FaceTable faceTable;
54 Forwarder forwarder{faceTable};
55};
56
Junxiao Shi0355e9f2015-09-02 07:24:53 -070057BOOST_AUTO_TEST_SUITE(Fw)
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040058BOOST_FIXTURE_TEST_SUITE(TestForwarder, ForwarderFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070059
Junxiao Shi8c8d2182014-01-30 22:33:00 -070060BOOST_AUTO_TEST_CASE(SimpleExchange)
61{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040062 auto face1 = addFace();
63 auto face2 = addFace();
Junxiao Shic041ca32014-02-25 20:01:15 -070064
Junxiao Shi8c8d2182014-01-30 22:33:00 -070065 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +000066 fib::Entry* entry = fib.insert("/A").first;
67 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070068
Junxiao Shida93f1f2015-11-11 06:13:16 -070069 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
70 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000071 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
72 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060073 face1->receiveInterest(*makeInterest("/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(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000076 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070077 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
78 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070079 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
80 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000081 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
82 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Alex Lane6bead9b2020-05-12 19:08:20 -050083 BOOST_CHECK_EQUAL(forwarder.getCounters().nSatisfiedInterests, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070084
Junxiao Shida93f1f2015-11-11 06:13:16 -070085 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
86 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -060087 face2->receiveData(*makeData("/A/B"), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -040088 this->advanceClocks(100_ms, 1_s);
Junxiao Shicde37ad2015-12-24 01:02:05 -070089 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shi9d727852019-05-14 13:44:22 -060090 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070091 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
92 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070093 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
94 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Alex Lane6bead9b2020-05-12 19:08:20 -050095 BOOST_CHECK_EQUAL(forwarder.getCounters().nInNacks, 0);
96 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutNacks, 0);
97 BOOST_CHECK_EQUAL(forwarder.getCounters().nSatisfiedInterests, 1);
98 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070099}
100
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700101BOOST_AUTO_TEST_CASE(CsMatched)
102{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400103 auto face1 = addFace();
104 auto face2 = addFace();
105 auto face3 = addFace();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700106
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700107 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000108 fib::Entry* entry = fib.insert("/A").first;
109 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700110
111 Pit& pit = forwarder.getPit();
112 BOOST_CHECK_EQUAL(pit.size(), 0);
113
Junxiao Shi9d727852019-05-14 13:44:22 -0600114 auto data = makeData("/A/B");
115 data->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
116 forwarder.getCs().insert(*data);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700117
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000118 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
119 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shi9d727852019-05-14 13:44:22 -0600120 face1->receiveInterest(*makeInterest("/A", true), 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400121 this->advanceClocks(1_ms, 5_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700122 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700123 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000124 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
125 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700126
Junxiao Shicde37ad2015-12-24 01:02:05 -0700127 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700128 // IncomingFaceId field should be reset to represent CS
Junxiao Shi9d727852019-05-14 13:44:22 -0600129 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700130 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
131 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700132
Davide Pesavento14e71f02019-03-28 17:35:25 -0400133 this->advanceClocks(100_ms, 500_ms);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700134 // PIT entry should not be left behind
135 BOOST_CHECK_EQUAL(pit.size(), 0);
136}
137
Junxiao Shi891f47b2016-06-20 00:02:11 +0000138BOOST_AUTO_TEST_CASE(OutgoingInterest)
139{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400140 auto face1 = addFace();
141 auto face2 = addFace();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000142
143 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600144 auto interestA1 = makeInterest("/A", false, nullopt, 8378);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000145 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000146 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000147
Junxiao Shi9d727852019-05-14 13:44:22 -0600148 auto interestA2 = makeInterest("/A", false, nullopt, 1698);
ashiqopuc7079482019-02-20 05:34:37 +0000149 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000150
Alex Lane6bead9b2020-05-12 19:08:20 -0500151 auto outA2 = pitA->getOutRecord(*face2);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000152 BOOST_REQUIRE(outA2 != pitA->out_end());
153 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000154
Junxiao Shi891f47b2016-06-20 00:02:11 +0000155 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000156 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000157}
158
Junxiao Shie342e8d2016-09-18 16:48:00 +0000159BOOST_AUTO_TEST_CASE(NextHopFaceId)
160{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400161 auto face1 = addFace();
162 auto face2 = addFace();
163 auto face3 = addFace();
Junxiao Shie342e8d2016-09-18 16:48:00 +0000164
165 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000166 fib::Entry* entry = fib.insert("/A").first;
167 fib.addOrUpdateNextHop(*entry, *face3, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000168
Junxiao Shi9d727852019-05-14 13:44:22 -0600169 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000170 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
171
ashiqopu075bb7d2019-03-10 01:38:21 +0000172 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400173 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000174 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
175 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
176 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
177}
178
Eric Newberry9d283ad2020-04-12 23:37:17 -0700179BOOST_AUTO_TEST_CASE(HopLimit)
180{
181 auto faceIn = addFace();
182 auto faceRemote = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
183 auto faceLocal = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
184 Fib& fib = forwarder.getFib();
185 fib::Entry* entryRemote = fib.insert("/remote").first;
186 fib.addOrUpdateNextHop(*entryRemote, *faceRemote, 0);
187 fib::Entry* entryLocal = fib.insert("/local").first;
188 fib.addOrUpdateNextHop(*entryLocal, *faceLocal, 0);
189
190 // Incoming interest w/o HopLimit will not be dropped on send or receive paths
191 auto interestNoHopLimit = makeInterest("/remote/abcdefgh");
192 faceIn->receiveInterest(*interestNoHopLimit, 0);
193 this->advanceClocks(100_ms, 1_s);
194 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 1);
195 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
196 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
197 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 1);
198 BOOST_CHECK(!faceRemote->sentInterests.back().getHopLimit());
199
200 // Incoming interest w/ HopLimit > 1 will not be dropped on send/receive
201 auto interestHopLimit2 = makeInterest("/remote/ijklmnop");
202 interestHopLimit2->setHopLimit(2);
203 faceIn->receiveInterest(*interestHopLimit2, 0);
204 this->advanceClocks(100_ms, 1_s);
205 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
206 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
207 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
208 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 2);
209 BOOST_REQUIRE(faceRemote->sentInterests.back().getHopLimit());
210 BOOST_CHECK_EQUAL(*faceRemote->sentInterests.back().getHopLimit(), 1);
211
212 // Incoming interest w/ HopLimit == 1 will be dropped on send path if going out on remote face
213 auto interestHopLimit1Remote = makeInterest("/remote/qrstuvwx");
214 interestHopLimit1Remote->setHopLimit(1);
215 faceIn->receiveInterest(*interestHopLimit1Remote, 0);
216 this->advanceClocks(100_ms, 1_s);
217 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
218 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
219 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
220 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
221
222 // Incoming interest w/ HopLimit == 1 will not be dropped on send path if going out on local face
223 auto interestHopLimit1Local = makeInterest("/local/abcdefgh");
224 interestHopLimit1Local->setHopLimit(1);
225 faceIn->receiveInterest(*interestHopLimit1Local, 0);
226 this->advanceClocks(100_ms, 1_s);
227 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutInterests, 1);
228 BOOST_CHECK_EQUAL(faceLocal->getCounters().nInHopLimitZero, 0);
229 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutHopLimitZero, 0);
230 BOOST_REQUIRE_EQUAL(faceLocal->sentInterests.size(), 1);
231 BOOST_REQUIRE(faceLocal->sentInterests.back().getHopLimit());
232 BOOST_CHECK_EQUAL(*faceLocal->sentInterests.back().getHopLimit(), 0);
233
234 // Interest w/ HopLimit == 0 will be dropped on receive path
235 auto interestHopLimit0 = makeInterest("/remote/yzabcdef");
236 interestHopLimit0->setHopLimit(0);
237 faceIn->receiveInterest(*interestHopLimit0, 0);
238 this->advanceClocks(100_ms, 1_s);
239 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
240 BOOST_CHECK_EQUAL(faceIn->getCounters().nInHopLimitZero, 1);
241 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
242 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
243}
244
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700245class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700246{
247public:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400248 using Forwarder::Forwarder;
249
Junxiao Shi88884492014-02-15 15:57:43 -0700250protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000251 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400252 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700253 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700254 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700255 }
256
257public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400258 int dispatchToStrategy_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700259};
260
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400261BOOST_FIXTURE_TEST_CASE(ScopeLocalhostIncoming, GlobalIoTimeFixture)
Junxiao Shi88884492014-02-15 15:57:43 -0700262{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400263 FaceTable faceTable;
264 ScopeLocalhostIncomingTestForwarder forwarder(faceTable);
265
Junxiao Shicde37ad2015-12-24 01:02:05 -0700266 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
267 auto face2 = make_shared<DummyFace>();
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400268 faceTable.add(face1);
269 faceTable.add(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700270
Junxiao Shi88884492014-02-15 15:57:43 -0700271 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700272 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600273 auto i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000274 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700275 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700276
Junxiao Shi88884492014-02-15 15:57:43 -0700277 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700278 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600279 auto i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000280 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700281 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700282
Junxiao Shi88884492014-02-15 15:57:43 -0700283 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700284 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600285 auto i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000286 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700287 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700288
Junxiao Shi88884492014-02-15 15:57:43 -0700289 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700290 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600291 auto i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000292 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700293 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700294
Alex Lane6bead9b2020-05-12 19:08:20 -0500295 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
296
Junxiao Shi88884492014-02-15 15:57:43 -0700297 // local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600298 auto d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000299 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500300 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700301
302 // non-local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600303 auto d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000304 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Alex Lane6bead9b2020-05-12 19:08:20 -0500305 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700306
Junxiao Shi88884492014-02-15 15:57:43 -0700307 // local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600308 auto d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000309 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Alex Lane6bead9b2020-05-12 19:08:20 -0500310 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 2);
Junxiao Shi88884492014-02-15 15:57:43 -0700311
312 // non-local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600313 auto d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000314 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Alex Lane6bead9b2020-05-12 19:08:20 -0500315 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 3);
Junxiao Shi88884492014-02-15 15:57:43 -0700316}
317
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700318BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700319{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400320 auto face1 = addFace();
321 auto face2 = addFace();
Junxiao Shif3c07812014-03-11 21:48:49 -0700322
Junxiao Shi9d727852019-05-14 13:44:22 -0600323 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
324 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700325
Junxiao Shi9d727852019-05-14 13:44:22 -0600326 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000327 strategyA.afterReceiveInterest_count = 0;
328 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000329 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000330 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700331
Junxiao Shi9d727852019-05-14 13:44:22 -0600332 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000333 strategyB.afterReceiveInterest_count = 0;
334 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000335 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000336 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700337
Davide Pesavento14e71f02019-03-28 17:35:25 -0400338 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700339
Junxiao Shi9d727852019-05-14 13:44:22 -0600340 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000341 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000342 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000343 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700344
Junxiao Shi9d727852019-05-14 13:44:22 -0600345 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000346 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000347 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000348 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700349
Junxiao Shi9d727852019-05-14 13:44:22 -0600350 auto interest3 = makeInterest("/A/3", false, 30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000351 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shi9d727852019-05-14 13:44:22 -0600352 auto interest4 = makeInterest("/B/4", false, 5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000353 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700354}
355
Junxiao Shida006f52014-05-16 11:18:00 -0700356BOOST_AUTO_TEST_CASE(IncomingData)
357{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400358 auto face1 = addFace();
359 auto face2 = addFace();
360 auto face3 = addFace();
361 auto face4 = addFace();
Junxiao Shida006f52014-05-16 11:18:00 -0700362
363 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600364 auto interestD = makeInterest("/A/B/C/D");
365 shared_ptr<pit::Entry> pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000366 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600367 auto interestA = makeInterest("/A", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700368 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000369 pitA->insertOrUpdateInRecord(*face2, *interestA);
370 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600371 auto interestC = makeInterest("/A/B/C", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700372 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000373 pitC->insertOrUpdateInRecord(*face3, *interestC);
374 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700375
Junxiao Shi9d727852019-05-14 13:44:22 -0600376 auto dataD = makeData("/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000377 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400378 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700379
Junxiao Shicde37ad2015-12-24 01:02:05 -0700380 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
381 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
382 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
383 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500384
385 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
386 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 3);
387 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shida006f52014-05-16 11:18:00 -0700388}
389
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700390BOOST_AUTO_TEST_CASE(IncomingNack)
391{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400392 auto face1 = addFace();
393 auto face2 = addFace();
394 auto face3 = addFace("dummy://", "dummy://",
395 ndn::nfd::FACE_SCOPE_NON_LOCAL,
396 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
397 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700398
Junxiao Shi9d727852019-05-14 13:44:22 -0600399 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
400 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700401
402 Pit& pit = forwarder.getPit();
403
404 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600405 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700406 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000407 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600408 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700409 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000410 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700411
Junxiao Shi9d727852019-05-14 13:44:22 -0600412 lp::Nack nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000413 strategyA.afterReceiveNack_count = 0;
414 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000415 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000416 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
417 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700418
Junxiao Shi9d727852019-05-14 13:44:22 -0600419 lp::Nack nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000420 strategyA.afterReceiveNack_count = 0;
421 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000422 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000423 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
424 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700425
426 // record Nack on PIT out-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500427 auto outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700428 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700429 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
430 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
431
432 // drop if no PIT entry
Junxiao Shi9d727852019-05-14 13:44:22 -0600433 lp::Nack nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000434 strategyA.afterReceiveNack_count = 0;
435 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000436 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000437 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
438 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700439
440 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600441 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700442 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000443 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700444
Junxiao Shi9d727852019-05-14 13:44:22 -0600445 lp::Nack nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000446 strategyA.afterReceiveNack_count = 0;
447 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000448 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000449 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
450 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700451
452 // drop if Nonce does not match out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600453 lp::Nack nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000454 strategyA.afterReceiveNack_count = 0;
455 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000456 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000457 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
458 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700459
460 // drop if inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000461 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000462 strategyA.afterReceiveNack_count = 0;
463 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000464 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000465 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
466 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700467}
468
469BOOST_AUTO_TEST_CASE(OutgoingNack)
470{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400471 auto face1 = addFace();
472 auto face2 = addFace();
473 auto face3 = addFace("dummy://", "dummy://",
474 ndn::nfd::FACE_SCOPE_NON_LOCAL,
475 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
476 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700477
478 Pit& pit = forwarder.getPit();
479
480 lp::NackHeader nackHeader;
481 nackHeader.setReason(lp::NackReason::CONGESTION);
482
483 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600484 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700485 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000486 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700487
488 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000489 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700490 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
491
492 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600493 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700494 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000495 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600496 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000497 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700498
499 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000500 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700501 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
502 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
503 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
504
505 // erase in-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500506 auto inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700507 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700508
509 // send Nack with correct Nonce
510 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000511 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700512 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
513 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
514 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
515
516 // erase in-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500517 auto inRecord2b = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700518 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700519
520 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600521 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000522 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700523
524 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000525 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700526 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
527}
528
529BOOST_AUTO_TEST_CASE(InterestLoopNack)
530{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400531 auto face1 = addFace();
532 auto face2 = addFace();
533 auto face3 = addFace("dummy://", "dummy://",
534 ndn::nfd::FACE_SCOPE_NON_LOCAL,
535 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
536 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
537 auto face4 = addFace();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700538
539 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000540 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
541 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700542
543 // receive Interest on face1
544 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600545 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000546 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700547 BOOST_CHECK(face1->sentNacks.empty());
548
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000549 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700550 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600551 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000552 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000553 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700554
555 // receive Interest with duplicate Nonce on face2
556 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600557 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000558 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700559 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400560 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700561 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
562
563 // receive Interest with new Nonce on face2
564 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600565 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000566 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700567 BOOST_CHECK(face2->sentNacks.empty());
568
569 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
570 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600571 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000572 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700573 BOOST_CHECK(face3->sentNacks.empty());
574}
575
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400576BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700577{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400578 auto face1 = addFace();
579 auto face2 = addFace();
Junxiao Shia110f262014-10-12 12:35:20 -0700580
581 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700582 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
583 if (pktType == tlv::Interest) {
584 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000585 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700586 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700587 });
Junxiao Shia110f262014-10-12 12:35:20 -0700588
589 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000590 fib::Entry* entry = fib.insert("/A").first;
591 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700592
Junxiao Shi455581d2014-11-17 18:38:40 -0700593 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600594 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000595 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700596
Junxiao Shi455581d2014-11-17 18:38:40 -0700597 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400598 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
599 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700600
Junxiao Shicde37ad2015-12-24 01:02:05 -0700601 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700602
603 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
604 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
605 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
606 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
607 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700608}
609
Junxiao Shid41d6072016-06-19 23:35:27 +0000610BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700611{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400612 auto face1 = addFace();
Junxiao Shi9d727852019-05-14 13:44:22 -0600613 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700614
615 DeadNonceList& dnl = forwarder.getDeadNonceList();
616 dnl.add(interest->getName(), interest->getNonce());
617 Pit& pit = forwarder.getPit();
618 BOOST_REQUIRE_EQUAL(pit.size(), 0);
619
ashiqopuc7079482019-02-20 05:34:37 +0000620 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400621 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700622 BOOST_CHECK_EQUAL(pit.size(), 0);
623}
624
Alex Lane6bead9b2020-05-12 19:08:20 -0500625BOOST_AUTO_TEST_CASE(UnsolicitedData)
626{
627 auto face1 = addFace();
628 auto data = makeData("/A");
629
630 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
631 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *data);
632 this->advanceClocks(1_ms, 10_ms);
633 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
634}
635
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400636BOOST_AUTO_TEST_SUITE_END() // TestForwarder
637BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700638
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700639} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700640} // namespace nfd