blob: e1b7bd87644ae0432fb06a16e0ea224ce1085b43 [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
Eric Newberryfdc06452020-06-23 22:40:16 -0700138BOOST_AUTO_TEST_CASE(InterestWithoutNonce)
139{
140 auto face1 = addFace();
141 auto face2 = addFace();
142
143 Fib& fib = forwarder.getFib();
144 fib::Entry* entry = fib.insert("/A").first;
145 fib.addOrUpdateNextHop(*entry, *face2, 0);
146
147 auto interest = makeInterest("/A");
148 BOOST_CHECK_EQUAL(interest->hasNonce(), false);
149 face1->receiveInterest(*interest, 0);
150
151 // Ensure Nonce added if incoming packet did not have Nonce
152 BOOST_REQUIRE_EQUAL(face2->getCounters().nOutInterests, 1);
153 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
154 BOOST_CHECK_EQUAL(face2->sentInterests.back().hasNonce(), true);
155}
156
Junxiao Shi891f47b2016-06-20 00:02:11 +0000157BOOST_AUTO_TEST_CASE(OutgoingInterest)
158{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400159 auto face1 = addFace();
160 auto face2 = addFace();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000161
162 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600163 auto interestA1 = makeInterest("/A", false, nullopt, 8378);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000164 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000165 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000166
Junxiao Shi9d727852019-05-14 13:44:22 -0600167 auto interestA2 = makeInterest("/A", false, nullopt, 1698);
ashiqopuc7079482019-02-20 05:34:37 +0000168 forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000169
Alex Lane6bead9b2020-05-12 19:08:20 -0500170 auto outA2 = pitA->getOutRecord(*face2);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000171 BOOST_REQUIRE(outA2 != pitA->out_end());
172 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000173
Junxiao Shi891f47b2016-06-20 00:02:11 +0000174 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000175 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000176}
177
Junxiao Shie342e8d2016-09-18 16:48:00 +0000178BOOST_AUTO_TEST_CASE(NextHopFaceId)
179{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400180 auto face1 = addFace();
181 auto face2 = addFace();
182 auto face3 = addFace();
Junxiao Shie342e8d2016-09-18 16:48:00 +0000183
184 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000185 fib::Entry* entry = fib.insert("/A").first;
186 fib.addOrUpdateNextHop(*entry, *face3, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000187
Junxiao Shi9d727852019-05-14 13:44:22 -0600188 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000189 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
190
ashiqopu075bb7d2019-03-10 01:38:21 +0000191 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400192 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000193 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
194 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
195 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
196}
197
Eric Newberry9d283ad2020-04-12 23:37:17 -0700198BOOST_AUTO_TEST_CASE(HopLimit)
199{
200 auto faceIn = addFace();
201 auto faceRemote = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
202 auto faceLocal = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
203 Fib& fib = forwarder.getFib();
204 fib::Entry* entryRemote = fib.insert("/remote").first;
205 fib.addOrUpdateNextHop(*entryRemote, *faceRemote, 0);
206 fib::Entry* entryLocal = fib.insert("/local").first;
207 fib.addOrUpdateNextHop(*entryLocal, *faceLocal, 0);
208
209 // Incoming interest w/o HopLimit will not be dropped on send or receive paths
210 auto interestNoHopLimit = makeInterest("/remote/abcdefgh");
211 faceIn->receiveInterest(*interestNoHopLimit, 0);
212 this->advanceClocks(100_ms, 1_s);
213 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 1);
214 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
215 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
216 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 1);
217 BOOST_CHECK(!faceRemote->sentInterests.back().getHopLimit());
218
219 // Incoming interest w/ HopLimit > 1 will not be dropped on send/receive
220 auto interestHopLimit2 = makeInterest("/remote/ijklmnop");
221 interestHopLimit2->setHopLimit(2);
222 faceIn->receiveInterest(*interestHopLimit2, 0);
223 this->advanceClocks(100_ms, 1_s);
224 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
225 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
226 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
227 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 2);
228 BOOST_REQUIRE(faceRemote->sentInterests.back().getHopLimit());
229 BOOST_CHECK_EQUAL(*faceRemote->sentInterests.back().getHopLimit(), 1);
230
231 // Incoming interest w/ HopLimit == 1 will be dropped on send path if going out on remote face
232 auto interestHopLimit1Remote = makeInterest("/remote/qrstuvwx");
233 interestHopLimit1Remote->setHopLimit(1);
234 faceIn->receiveInterest(*interestHopLimit1Remote, 0);
235 this->advanceClocks(100_ms, 1_s);
236 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
237 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
238 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
239 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
240
241 // Incoming interest w/ HopLimit == 1 will not be dropped on send path if going out on local face
242 auto interestHopLimit1Local = makeInterest("/local/abcdefgh");
243 interestHopLimit1Local->setHopLimit(1);
244 faceIn->receiveInterest(*interestHopLimit1Local, 0);
245 this->advanceClocks(100_ms, 1_s);
246 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutInterests, 1);
247 BOOST_CHECK_EQUAL(faceLocal->getCounters().nInHopLimitZero, 0);
248 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutHopLimitZero, 0);
249 BOOST_REQUIRE_EQUAL(faceLocal->sentInterests.size(), 1);
250 BOOST_REQUIRE(faceLocal->sentInterests.back().getHopLimit());
251 BOOST_CHECK_EQUAL(*faceLocal->sentInterests.back().getHopLimit(), 0);
252
253 // Interest w/ HopLimit == 0 will be dropped on receive path
254 auto interestHopLimit0 = makeInterest("/remote/yzabcdef");
255 interestHopLimit0->setHopLimit(0);
256 faceIn->receiveInterest(*interestHopLimit0, 0);
257 this->advanceClocks(100_ms, 1_s);
258 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
259 BOOST_CHECK_EQUAL(faceIn->getCounters().nInHopLimitZero, 1);
260 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
261 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
262}
263
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700264class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700265{
266public:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400267 using Forwarder::Forwarder;
268
Junxiao Shi88884492014-02-15 15:57:43 -0700269protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000270 void
Davide Pesaventob31206e2019-04-20 22:34:12 -0400271 dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
Junxiao Shi88884492014-02-15 15:57:43 -0700272 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700273 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700274 }
275
276public:
Davide Pesaventob31206e2019-04-20 22:34:12 -0400277 int dispatchToStrategy_count = 0;
Junxiao Shi88884492014-02-15 15:57:43 -0700278};
279
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400280BOOST_FIXTURE_TEST_CASE(ScopeLocalhostIncoming, GlobalIoTimeFixture)
Junxiao Shi88884492014-02-15 15:57:43 -0700281{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400282 FaceTable faceTable;
283 ScopeLocalhostIncomingTestForwarder forwarder(faceTable);
284
Junxiao Shicde37ad2015-12-24 01:02:05 -0700285 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
286 auto face2 = make_shared<DummyFace>();
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400287 faceTable.add(face1);
288 faceTable.add(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700289
Junxiao Shi88884492014-02-15 15:57:43 -0700290 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700291 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600292 auto i1 = makeInterest("/localhost/A1");
ashiqopuc7079482019-02-20 05:34:37 +0000293 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700294 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700295
Junxiao Shi88884492014-02-15 15:57:43 -0700296 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700297 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600298 auto i2 = makeInterest("/localhost/A2");
ashiqopuc7079482019-02-20 05:34:37 +0000299 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700300 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700301
Junxiao Shi88884492014-02-15 15:57:43 -0700302 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700303 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600304 auto i3 = makeInterest("/A3");
ashiqopuc7079482019-02-20 05:34:37 +0000305 forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700306 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700307
Junxiao Shi88884492014-02-15 15:57:43 -0700308 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700309 forwarder.dispatchToStrategy_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600310 auto i4 = makeInterest("/A4");
ashiqopuc7079482019-02-20 05:34:37 +0000311 forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700312 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700313
Alex Lane6bead9b2020-05-12 19:08:20 -0500314 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
315
Junxiao Shi88884492014-02-15 15:57:43 -0700316 // local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600317 auto d1 = makeData("/localhost/B1");
ashiqopuc7079482019-02-20 05:34:37 +0000318 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500319 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700320
321 // non-local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600322 auto d2 = makeData("/localhost/B2");
ashiqopuc7079482019-02-20 05:34:37 +0000323 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
Alex Lane6bead9b2020-05-12 19:08:20 -0500324 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700325
Junxiao Shi88884492014-02-15 15:57:43 -0700326 // local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600327 auto d3 = makeData("/B3");
ashiqopuc7079482019-02-20 05:34:37 +0000328 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
Alex Lane6bead9b2020-05-12 19:08:20 -0500329 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 2);
Junxiao Shi88884492014-02-15 15:57:43 -0700330
331 // non-local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600332 auto d4 = makeData("/B4");
ashiqopuc7079482019-02-20 05:34:37 +0000333 forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
Alex Lane6bead9b2020-05-12 19:08:20 -0500334 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 3);
Junxiao Shi88884492014-02-15 15:57:43 -0700335}
336
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700337BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700338{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400339 auto face1 = addFace();
340 auto face2 = addFace();
Junxiao Shif3c07812014-03-11 21:48:49 -0700341
Junxiao Shi9d727852019-05-14 13:44:22 -0600342 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
343 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700344
Junxiao Shi9d727852019-05-14 13:44:22 -0600345 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000346 strategyA.afterReceiveInterest_count = 0;
347 strategyA.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000348 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000349 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700350
Junxiao Shi9d727852019-05-14 13:44:22 -0600351 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000352 strategyB.afterReceiveInterest_count = 0;
353 strategyB.interestOutFace = face2;
ashiqopuc7079482019-02-20 05:34:37 +0000354 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000355 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700356
Davide Pesavento14e71f02019-03-28 17:35:25 -0400357 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700358
Junxiao Shi9d727852019-05-14 13:44:22 -0600359 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000360 strategyA.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000361 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000362 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700363
Junxiao Shi9d727852019-05-14 13:44:22 -0600364 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000365 strategyB.beforeSatisfyInterest_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000366 forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000367 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700368
Junxiao Shi9d727852019-05-14 13:44:22 -0600369 auto interest3 = makeInterest("/A/3", false, 30_ms);
ashiqopuc7079482019-02-20 05:34:37 +0000370 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
Junxiao Shi9d727852019-05-14 13:44:22 -0600371 auto interest4 = makeInterest("/B/4", false, 5_s);
ashiqopuc7079482019-02-20 05:34:37 +0000372 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700373}
374
Junxiao Shida006f52014-05-16 11:18:00 -0700375BOOST_AUTO_TEST_CASE(IncomingData)
376{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400377 auto face1 = addFace();
378 auto face2 = addFace();
379 auto face3 = addFace();
380 auto face4 = addFace();
Junxiao Shida006f52014-05-16 11:18:00 -0700381
382 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600383 auto interestD = makeInterest("/A/B/C/D");
384 shared_ptr<pit::Entry> pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000385 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600386 auto interestA = makeInterest("/A", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700387 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000388 pitA->insertOrUpdateInRecord(*face2, *interestA);
389 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600390 auto interestC = makeInterest("/A/B/C", true);
Junxiao Shida006f52014-05-16 11:18:00 -0700391 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000392 pitC->insertOrUpdateInRecord(*face3, *interestC);
393 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700394
Junxiao Shi9d727852019-05-14 13:44:22 -0600395 auto dataD = makeData("/A/B/C/D");
ashiqopuc7079482019-02-20 05:34:37 +0000396 forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400397 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700398
Junxiao Shicde37ad2015-12-24 01:02:05 -0700399 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
400 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
401 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
402 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500403
404 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
405 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 3);
406 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shida006f52014-05-16 11:18:00 -0700407}
408
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700409BOOST_AUTO_TEST_CASE(IncomingNack)
410{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400411 auto face1 = addFace();
412 auto face2 = addFace();
413 auto face3 = addFace("dummy://", "dummy://",
414 ndn::nfd::FACE_SCOPE_NON_LOCAL,
415 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
416 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700417
Junxiao Shi9d727852019-05-14 13:44:22 -0600418 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
419 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700420
421 Pit& pit = forwarder.getPit();
422
423 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600424 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700425 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000426 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600427 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700428 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000429 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700430
Junxiao Shi9d727852019-05-14 13:44:22 -0600431 lp::Nack nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000432 strategyA.afterReceiveNack_count = 0;
433 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000434 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000435 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
436 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700437
Junxiao Shi9d727852019-05-14 13:44:22 -0600438 lp::Nack nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000439 strategyA.afterReceiveNack_count = 0;
440 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000441 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000442 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
443 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700444
445 // record Nack on PIT out-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500446 auto outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700447 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700448 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
449 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
450
451 // drop if no PIT entry
Junxiao Shi9d727852019-05-14 13:44:22 -0600452 lp::Nack nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000453 strategyA.afterReceiveNack_count = 0;
454 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000455 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000456 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
457 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700458
459 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600460 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700461 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000462 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700463
Junxiao Shi9d727852019-05-14 13:44:22 -0600464 lp::Nack nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000465 strategyA.afterReceiveNack_count = 0;
466 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000467 forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000468 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
469 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700470
471 // drop if Nonce does not match out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600472 lp::Nack nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000473 strategyA.afterReceiveNack_count = 0;
474 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000475 forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000476 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
477 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700478
479 // drop if inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000480 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000481 strategyA.afterReceiveNack_count = 0;
482 strategyB.afterReceiveNack_count = 0;
ashiqopuc7079482019-02-20 05:34:37 +0000483 forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000484 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
485 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700486}
487
488BOOST_AUTO_TEST_CASE(OutgoingNack)
489{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400490 auto face1 = addFace();
491 auto face2 = addFace();
492 auto face3 = addFace("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
497 Pit& pit = forwarder.getPit();
498
499 lp::NackHeader nackHeader;
500 nackHeader.setReason(lp::NackReason::CONGESTION);
501
502 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600503 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700504 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000505 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700506
507 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000508 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700509 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
510
511 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600512 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700513 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000514 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600515 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000516 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700517
518 face1->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000519 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700520 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
521 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
522 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
523
524 // erase in-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500525 auto inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700526 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700527
528 // send Nack with correct Nonce
529 face2->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000530 forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700531 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
532 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
533 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
534
535 // erase in-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500536 auto inRecord2b = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700537 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700538
539 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600540 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000541 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700542
543 face3->sentNacks.clear();
ashiqopuc7079482019-02-20 05:34:37 +0000544 forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700545 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
546}
547
548BOOST_AUTO_TEST_CASE(InterestLoopNack)
549{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400550 auto face1 = addFace();
551 auto face2 = addFace();
552 auto face3 = addFace("dummy://", "dummy://",
553 ndn::nfd::FACE_SCOPE_NON_LOCAL,
554 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
555 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
556 auto face4 = addFace();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700557
558 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000559 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
560 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700561
562 // receive Interest on face1
563 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600564 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000565 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700566 BOOST_CHECK(face1->sentNacks.empty());
567
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000568 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700569 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600570 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000571 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000572 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700573
574 // receive Interest with duplicate Nonce on face2
575 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600576 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000577 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700578 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400579 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700580 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
581
582 // receive Interest with new Nonce on face2
583 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600584 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000585 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700586 BOOST_CHECK(face2->sentNacks.empty());
587
588 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
589 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600590 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000591 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700592 BOOST_CHECK(face3->sentNacks.empty());
593}
594
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400595BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700596{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400597 auto face1 = addFace();
598 auto face2 = addFace();
Junxiao Shia110f262014-10-12 12:35:20 -0700599
600 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700601 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
602 if (pktType == tlv::Interest) {
603 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000604 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700605 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700606 });
Junxiao Shia110f262014-10-12 12:35:20 -0700607
608 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000609 fib::Entry* entry = fib.insert("/A").first;
610 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700611
Junxiao Shi455581d2014-11-17 18:38:40 -0700612 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600613 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000614 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700615
Junxiao Shi455581d2014-11-17 18:38:40 -0700616 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400617 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
618 this->advanceClocks(25_ms, 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700619
Junxiao Shicde37ad2015-12-24 01:02:05 -0700620 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700621
622 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
623 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
624 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
625 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
626 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700627}
628
Junxiao Shid41d6072016-06-19 23:35:27 +0000629BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700630{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400631 auto face1 = addFace();
Junxiao Shi9d727852019-05-14 13:44:22 -0600632 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700633
634 DeadNonceList& dnl = forwarder.getDeadNonceList();
635 dnl.add(interest->getName(), interest->getNonce());
636 Pit& pit = forwarder.getPit();
637 BOOST_REQUIRE_EQUAL(pit.size(), 0);
638
ashiqopuc7079482019-02-20 05:34:37 +0000639 forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400640 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700641 BOOST_CHECK_EQUAL(pit.size(), 0);
642}
643
Alex Lane6bead9b2020-05-12 19:08:20 -0500644BOOST_AUTO_TEST_CASE(UnsolicitedData)
645{
646 auto face1 = addFace();
647 auto data = makeData("/A");
648
649 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
650 forwarder.onIncomingData(FaceEndpoint(*face1, 0), *data);
651 this->advanceClocks(1_ms, 10_ms);
652 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
653}
654
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400655BOOST_AUTO_TEST_SUITE_END() // TestForwarder
656BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700657
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700658} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700659} // namespace nfd