blob: 12ced1620047a590ffed893dfc7bf1a453f7d5af [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/*
Davide Pesaventob21bed82021-02-13 00:20:06 -05003 * Copyright (c) 2014-2021, 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);
Eric Newberry2377ada2020-09-28 22:40:14 -0700164 auto 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);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400168 auto outA2 = forwarder.onOutgoingInterest(*interestA2, *face2, pitA);
Eric Newberry2377ada2020-09-28 22:40:14 -0700169 BOOST_REQUIRE(outA2 != nullptr);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000170 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000171
Eric Newberry2377ada2020-09-28 22:40:14 -0700172 // This packet will be dropped because HopLimit=0
173 auto interestA3 = makeInterest("/A", false, nullopt, 9876);
174 interestA3->setHopLimit(0);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400175 auto outA3 = forwarder.onOutgoingInterest(*interestA3, *face2, pitA);
Eric Newberry2377ada2020-09-28 22:40:14 -0700176 BOOST_CHECK(outA3 == nullptr);
177
Junxiao Shi891f47b2016-06-20 00:02:11 +0000178 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000179 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000180}
181
Junxiao Shie342e8d2016-09-18 16:48:00 +0000182BOOST_AUTO_TEST_CASE(NextHopFaceId)
183{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400184 auto face1 = addFace();
185 auto face2 = addFace();
186 auto face3 = addFace();
Junxiao Shie342e8d2016-09-18 16:48:00 +0000187
188 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000189 fib::Entry* entry = fib.insert("/A").first;
190 fib.addOrUpdateNextHop(*entry, *face3, 0);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000191
Junxiao Shi9d727852019-05-14 13:44:22 -0600192 auto interest = makeInterest("/A/B");
Junxiao Shie342e8d2016-09-18 16:48:00 +0000193 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
194
ashiqopu075bb7d2019-03-10 01:38:21 +0000195 face1->receiveInterest(*interest, 0);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400196 this->advanceClocks(100_ms, 1_s);
Junxiao Shie342e8d2016-09-18 16:48:00 +0000197 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
198 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
199 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
200}
201
Eric Newberry9d283ad2020-04-12 23:37:17 -0700202BOOST_AUTO_TEST_CASE(HopLimit)
203{
204 auto faceIn = addFace();
205 auto faceRemote = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
206 auto faceLocal = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
207 Fib& fib = forwarder.getFib();
208 fib::Entry* entryRemote = fib.insert("/remote").first;
209 fib.addOrUpdateNextHop(*entryRemote, *faceRemote, 0);
210 fib::Entry* entryLocal = fib.insert("/local").first;
211 fib.addOrUpdateNextHop(*entryLocal, *faceLocal, 0);
212
213 // Incoming interest w/o HopLimit will not be dropped on send or receive paths
214 auto interestNoHopLimit = makeInterest("/remote/abcdefgh");
215 faceIn->receiveInterest(*interestNoHopLimit, 0);
216 this->advanceClocks(100_ms, 1_s);
217 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 1);
218 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
219 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
220 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 1);
221 BOOST_CHECK(!faceRemote->sentInterests.back().getHopLimit());
222
223 // Incoming interest w/ HopLimit > 1 will not be dropped on send/receive
224 auto interestHopLimit2 = makeInterest("/remote/ijklmnop");
225 interestHopLimit2->setHopLimit(2);
226 faceIn->receiveInterest(*interestHopLimit2, 0);
227 this->advanceClocks(100_ms, 1_s);
228 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
229 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
230 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
231 BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 2);
232 BOOST_REQUIRE(faceRemote->sentInterests.back().getHopLimit());
233 BOOST_CHECK_EQUAL(*faceRemote->sentInterests.back().getHopLimit(), 1);
234
235 // Incoming interest w/ HopLimit == 1 will be dropped on send path if going out on remote face
236 auto interestHopLimit1Remote = makeInterest("/remote/qrstuvwx");
237 interestHopLimit1Remote->setHopLimit(1);
238 faceIn->receiveInterest(*interestHopLimit1Remote, 0);
239 this->advanceClocks(100_ms, 1_s);
240 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
241 BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
242 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
243 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
244
245 // Incoming interest w/ HopLimit == 1 will not be dropped on send path if going out on local face
246 auto interestHopLimit1Local = makeInterest("/local/abcdefgh");
247 interestHopLimit1Local->setHopLimit(1);
248 faceIn->receiveInterest(*interestHopLimit1Local, 0);
249 this->advanceClocks(100_ms, 1_s);
250 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutInterests, 1);
251 BOOST_CHECK_EQUAL(faceLocal->getCounters().nInHopLimitZero, 0);
252 BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutHopLimitZero, 0);
253 BOOST_REQUIRE_EQUAL(faceLocal->sentInterests.size(), 1);
254 BOOST_REQUIRE(faceLocal->sentInterests.back().getHopLimit());
255 BOOST_CHECK_EQUAL(*faceLocal->sentInterests.back().getHopLimit(), 0);
256
257 // Interest w/ HopLimit == 0 will be dropped on receive path
258 auto interestHopLimit0 = makeInterest("/remote/yzabcdef");
259 interestHopLimit0->setHopLimit(0);
260 faceIn->receiveInterest(*interestHopLimit0, 0);
261 this->advanceClocks(100_ms, 1_s);
262 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
263 BOOST_CHECK_EQUAL(faceIn->getCounters().nInHopLimitZero, 1);
264 BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
265 BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
266}
267
Davide Pesavento05590472021-02-17 15:53:27 -0500268BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700269{
Davide Pesavento05590472021-02-17 15:53:27 -0500270 auto face1 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
271 auto face2 = addFace(); // default is non-local
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400272
Davide Pesavento05590472021-02-17 15:53:27 -0500273 auto& strategy = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
Junxiao Shic041ca32014-02-25 20:01:15 -0700274
Junxiao Shi88884492014-02-15 15:57:43 -0700275 // local face, /localhost: OK
Davide Pesavento05590472021-02-17 15:53:27 -0500276 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600277 auto i1 = makeInterest("/localhost/A1");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400278 forwarder.onIncomingInterest(*i1, FaceEndpoint(*face1, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500279 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700280
Junxiao Shi88884492014-02-15 15:57:43 -0700281 // non-local face, /localhost: violate
Davide Pesavento05590472021-02-17 15:53:27 -0500282 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600283 auto i2 = makeInterest("/localhost/A2");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400284 forwarder.onIncomingInterest(*i2, FaceEndpoint(*face2, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500285 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700286
Junxiao Shi88884492014-02-15 15:57:43 -0700287 // local face, non-/localhost: OK
Davide Pesavento05590472021-02-17 15:53:27 -0500288 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600289 auto i3 = makeInterest("/A3");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400290 forwarder.onIncomingInterest(*i3, FaceEndpoint(*face1, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500291 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700292
Junxiao Shi88884492014-02-15 15:57:43 -0700293 // non-local face, non-/localhost: OK
Davide Pesavento05590472021-02-17 15:53:27 -0500294 strategy.afterReceiveInterest_count = 0;
Junxiao Shi9d727852019-05-14 13:44:22 -0600295 auto i4 = makeInterest("/A4");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400296 forwarder.onIncomingInterest(*i4, FaceEndpoint(*face2, 0));
Davide Pesavento05590472021-02-17 15:53:27 -0500297 BOOST_CHECK_EQUAL(strategy.afterReceiveInterest_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700298
Alex Lane6bead9b2020-05-12 19:08:20 -0500299 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
300
Junxiao Shi88884492014-02-15 15:57:43 -0700301 // local face, /localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600302 auto d1 = makeData("/localhost/B1");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400303 forwarder.onIncomingData(*d1, FaceEndpoint(*face1, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500304 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700305
Davide Pesavento05590472021-02-17 15:53:27 -0500306 // non-local face, /localhost: violate
Junxiao Shi9d727852019-05-14 13:44:22 -0600307 auto d2 = makeData("/localhost/B2");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400308 forwarder.onIncomingData(*d2, FaceEndpoint(*face2, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500309 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700310
Junxiao Shi88884492014-02-15 15:57:43 -0700311 // local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600312 auto d3 = makeData("/B3");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400313 forwarder.onIncomingData(*d3, FaceEndpoint(*face1, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500314 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 2);
Junxiao Shi88884492014-02-15 15:57:43 -0700315
316 // non-local face, non-/localhost: OK
Junxiao Shi9d727852019-05-14 13:44:22 -0600317 auto d4 = makeData("/B4");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400318 forwarder.onIncomingData(*d4, FaceEndpoint(*face2, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500319 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 3);
Junxiao Shi88884492014-02-15 15:57:43 -0700320}
321
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700322BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700323{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400324 auto face1 = addFace();
325 auto face2 = addFace();
Junxiao Shif3c07812014-03-11 21:48:49 -0700326
Eric Newberry2377ada2020-09-28 22:40:14 -0700327 auto& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
328 auto& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700329
Junxiao Shi9d727852019-05-14 13:44:22 -0600330 auto interest1 = makeInterest("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000331 strategyA.afterReceiveInterest_count = 0;
332 strategyA.interestOutFace = face2;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400333 forwarder.onIncomingInterest(*interest1, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000334 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700335
Junxiao Shi9d727852019-05-14 13:44:22 -0600336 auto interest2 = makeInterest("/B/2", true);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000337 strategyB.afterReceiveInterest_count = 0;
338 strategyB.interestOutFace = face2;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400339 forwarder.onIncomingInterest(*interest2, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000340 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700341
Davide Pesavento14e71f02019-03-28 17:35:25 -0400342 this->advanceClocks(1_ms, 5_ms);
Junxiao Shif3c07812014-03-11 21:48:49 -0700343
Junxiao Shi9d727852019-05-14 13:44:22 -0600344 auto data1 = makeData("/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000345 strategyA.beforeSatisfyInterest_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400346 forwarder.onIncomingData(*data1, FaceEndpoint(*face2, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000347 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700348
Junxiao Shi9d727852019-05-14 13:44:22 -0600349 auto data2 = makeData("/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000350 strategyB.beforeSatisfyInterest_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400351 forwarder.onIncomingData(*data2, FaceEndpoint(*face2, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000352 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700353
Junxiao Shi9d727852019-05-14 13:44:22 -0600354 auto interest3 = makeInterest("/A/3", false, 30_ms);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400355 forwarder.onIncomingInterest(*interest3, FaceEndpoint(*face1, 0));
Junxiao Shi9d727852019-05-14 13:44:22 -0600356 auto interest4 = makeInterest("/B/4", false, 5_s);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400357 forwarder.onIncomingInterest(*interest4, FaceEndpoint(*face1, 0));
Junxiao Shif3c07812014-03-11 21:48:49 -0700358}
359
Junxiao Shida006f52014-05-16 11:18:00 -0700360BOOST_AUTO_TEST_CASE(IncomingData)
361{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400362 auto face1 = addFace();
363 auto face2 = addFace();
364 auto face3 = addFace();
365 auto face4 = addFace();
Junxiao Shida006f52014-05-16 11:18:00 -0700366
367 Pit& pit = forwarder.getPit();
Junxiao Shi9d727852019-05-14 13:44:22 -0600368 auto interestD = makeInterest("/A/B/C/D");
Eric Newberry2377ada2020-09-28 22:40:14 -0700369 auto pitD = pit.insert(*interestD).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000370 pitD->insertOrUpdateInRecord(*face1, *interestD);
Junxiao Shi9d727852019-05-14 13:44:22 -0600371 auto interestA = makeInterest("/A", true);
Eric Newberry2377ada2020-09-28 22:40:14 -0700372 auto pitA = pit.insert(*interestA).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000373 pitA->insertOrUpdateInRecord(*face2, *interestA);
374 pitA->insertOrUpdateInRecord(*face3, *interestA);
Junxiao Shi9d727852019-05-14 13:44:22 -0600375 auto interestC = makeInterest("/A/B/C", true);
Eric Newberry2377ada2020-09-28 22:40:14 -0700376 auto pitC = pit.insert(*interestC).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000377 pitC->insertOrUpdateInRecord(*face3, *interestC);
378 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700379
Junxiao Shi9d727852019-05-14 13:44:22 -0600380 auto dataD = makeData("/A/B/C/D");
Davide Pesavento0498ce82021-06-14 02:02:21 -0400381 forwarder.onIncomingData(*dataD, FaceEndpoint(*face3, 0));
Davide Pesavento14e71f02019-03-28 17:35:25 -0400382 this->advanceClocks(1_ms, 5_ms);
Junxiao Shida006f52014-05-16 11:18:00 -0700383
Junxiao Shicde37ad2015-12-24 01:02:05 -0700384 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
385 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
386 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
387 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Alex Lane6bead9b2020-05-12 19:08:20 -0500388
389 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
390 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 3);
391 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Junxiao Shida006f52014-05-16 11:18:00 -0700392}
393
Eric Newberry2377ada2020-09-28 22:40:14 -0700394BOOST_AUTO_TEST_CASE(OutgoingData)
395{
396 auto face1 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
397 auto face2 = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
398 auto face3 = addFace();
399 face3->setId(face::INVALID_FACEID);
400
401 auto data = makeData("/QkzAWU6K");
402 auto localData = makeData("/localhost/YH8bqnbv");
403
404 face1->sentData.clear();
405 BOOST_CHECK(forwarder.onOutgoingData(*data, *face1));
406 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
407 BOOST_CHECK_EQUAL(face1->sentData.back().getName(), data->getName());
408
409 // scope control
410 face1->sentData.clear();
411 face2->sentData.clear();
412 BOOST_CHECK(!forwarder.onOutgoingData(*localData, *face2));
413 BOOST_CHECK_EQUAL(face2->sentData.size(), 0);
414 BOOST_CHECK(forwarder.onOutgoingData(*localData, *face1));
415 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
416 BOOST_CHECK_EQUAL(face1->sentData.back().getName(), localData->getName());
417
418 // face with invalid ID
419 face3->sentData.clear();
420 BOOST_CHECK(!forwarder.onOutgoingData(*data, *face3));
421 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
422}
423
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700424BOOST_AUTO_TEST_CASE(IncomingNack)
425{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400426 auto face1 = addFace();
427 auto face2 = addFace();
428 auto face3 = addFace("dummy://", "dummy://",
429 ndn::nfd::FACE_SCOPE_NON_LOCAL,
430 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
431 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700432
Eric Newberry2377ada2020-09-28 22:40:14 -0700433 auto& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
434 auto& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700435
436 Pit& pit = forwarder.getPit();
437
438 // dispatch to the correct strategy
Junxiao Shi9d727852019-05-14 13:44:22 -0600439 auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
Eric Newberry2377ada2020-09-28 22:40:14 -0700440 auto pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000441 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi9d727852019-05-14 13:44:22 -0600442 auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
Eric Newberry2377ada2020-09-28 22:40:14 -0700443 auto pit2 = pit.insert(*interest2).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000444 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700445
Eric Newberry2377ada2020-09-28 22:40:14 -0700446 auto nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000447 strategyA.afterReceiveNack_count = 0;
448 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400449 forwarder.onIncomingNack(nack1, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000450 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
451 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700452
Eric Newberry2377ada2020-09-28 22:40:14 -0700453 auto nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000454 strategyA.afterReceiveNack_count = 0;
455 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400456 forwarder.onIncomingNack(nack2, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000457 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
458 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700459
460 // record Nack on PIT out-record
Alex Lane6bead9b2020-05-12 19:08:20 -0500461 auto outRecord1 = pit1->getOutRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700462 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700463 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
464 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
465
466 // drop if no PIT entry
Eric Newberry2377ada2020-09-28 22:40:14 -0700467 auto nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000468 strategyA.afterReceiveNack_count = 0;
469 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400470 forwarder.onIncomingNack(nack3, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000471 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
472 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700473
474 // drop if no out-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600475 auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
Eric Newberry2377ada2020-09-28 22:40:14 -0700476 auto pit4 = pit.insert(*interest4).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000477 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700478
Eric Newberry2377ada2020-09-28 22:40:14 -0700479 auto nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000480 strategyA.afterReceiveNack_count = 0;
481 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400482 forwarder.onIncomingNack(nack4a, FaceEndpoint(*face2, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000483 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
484 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700485
486 // drop if Nonce does not match out-record
Eric Newberry2377ada2020-09-28 22:40:14 -0700487 auto nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000488 strategyA.afterReceiveNack_count = 0;
489 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400490 forwarder.onIncomingNack(nack4b, FaceEndpoint(*face1, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000491 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
492 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700493
494 // drop if inFace is multi-access
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000495 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000496 strategyA.afterReceiveNack_count = 0;
497 strategyB.afterReceiveNack_count = 0;
Davide Pesavento0498ce82021-06-14 02:02:21 -0400498 forwarder.onIncomingNack(nack4a, FaceEndpoint(*face3, 0));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000499 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
500 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700501}
502
503BOOST_AUTO_TEST_CASE(OutgoingNack)
504{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400505 auto face1 = addFace();
506 auto face2 = addFace();
507 auto face3 = addFace("dummy://", "dummy://",
508 ndn::nfd::FACE_SCOPE_NON_LOCAL,
509 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
510 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Eric Newberry2377ada2020-09-28 22:40:14 -0700511 auto face4 = addFace();
512 face4->setId(face::INVALID_FACEID);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700513
514 Pit& pit = forwarder.getPit();
515
516 lp::NackHeader nackHeader;
517 nackHeader.setReason(lp::NackReason::CONGESTION);
518
519 // don't send Nack if there's no in-record
Junxiao Shi9d727852019-05-14 13:44:22 -0600520 auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
Eric Newberry2377ada2020-09-28 22:40:14 -0700521 auto pit1 = pit.insert(*interest1).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000522 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700523
524 face2->sentNacks.clear();
Davide Pesavento0498ce82021-06-14 02:02:21 -0400525 BOOST_CHECK(!forwarder.onOutgoingNack(nackHeader, *face2, pit1));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700526 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
527
528 // send Nack with correct Nonce
Junxiao Shi9d727852019-05-14 13:44:22 -0600529 auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
Eric Newberry2377ada2020-09-28 22:40:14 -0700530 auto pit2 = pit.insert(*interest2a).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000531 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi9d727852019-05-14 13:44:22 -0600532 auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000533 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700534 face1->sentNacks.clear();
Eric Newberry2377ada2020-09-28 22:40:14 -0700535 face2->sentNacks.clear();
536
Davide Pesavento0498ce82021-06-14 02:02:21 -0400537 BOOST_CHECK(forwarder.onOutgoingNack(nackHeader, *face1, pit2));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700538 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
539 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
540 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
Eric Newberry2377ada2020-09-28 22:40:14 -0700541 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700542
Eric Newberry2377ada2020-09-28 22:40:14 -0700543 // in-record is erased
Alex Lane6bead9b2020-05-12 19:08:20 -0500544 auto inRecord2a = pit2->getInRecord(*face1);
Junxiao Shi4846f372016-04-05 13:39:30 -0700545 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700546
547 // send Nack with correct Nonce
Davide Pesavento0498ce82021-06-14 02:02:21 -0400548 BOOST_CHECK(forwarder.onOutgoingNack(nackHeader, *face2, pit2));
Eric Newberry2377ada2020-09-28 22:40:14 -0700549 BOOST_CHECK_EQUAL(face1->sentNacks.size(), 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700550 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
551 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
552 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
553
Eric Newberry2377ada2020-09-28 22:40:14 -0700554 // in-record is erased
555 auto inRecord2b = pit2->getInRecord(*face2);
Junxiao Shi4846f372016-04-05 13:39:30 -0700556 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700557
558 // don't send Nack to multi-access face
Junxiao Shi9d727852019-05-14 13:44:22 -0600559 auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000560 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700561
562 face3->sentNacks.clear();
Davide Pesavento0498ce82021-06-14 02:02:21 -0400563 BOOST_CHECK(!forwarder.onOutgoingNack(nackHeader, *face3, pit2));
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700564 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
Eric Newberry2377ada2020-09-28 22:40:14 -0700565
566 // don't send Nack to face with invalid ID
567 auto interest1b = makeInterest("/fM5IVEtC", false, nullopt, 553);
568 pit1->insertOrUpdateInRecord(*face4, *interest1b);
569
570 face4->sentNacks.clear();
Davide Pesavento0498ce82021-06-14 02:02:21 -0400571 BOOST_CHECK(!forwarder.onOutgoingNack(nackHeader, *face4, pit1));
Eric Newberry2377ada2020-09-28 22:40:14 -0700572 BOOST_CHECK_EQUAL(face4->sentNacks.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700573}
574
575BOOST_AUTO_TEST_CASE(InterestLoopNack)
576{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400577 auto face1 = addFace();
578 auto face2 = addFace();
579 auto face3 = addFace("dummy://", "dummy://",
580 ndn::nfd::FACE_SCOPE_NON_LOCAL,
581 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
582 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
583 auto face4 = addFace();
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700584
585 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000586 fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
587 fib.addOrUpdateNextHop(*entry, *face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700588
589 // receive Interest on face1
590 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600591 auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000592 face1->receiveInterest(*interest1a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700593 BOOST_CHECK(face1->sentNacks.empty());
594
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000595 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700596 face1->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600597 auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000598 face1->receiveInterest(*interest1b, 0);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000599 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700600
601 // receive Interest with duplicate Nonce on face2
602 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600603 auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000604 face2->receiveInterest(*interest2a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700605 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
Davide Pesavento7890a9f2019-08-25 23:11:18 -0400606 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700607 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
608
609 // receive Interest with new Nonce on face2
610 face2->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600611 auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
ashiqopu075bb7d2019-03-10 01:38:21 +0000612 face2->receiveInterest(*interest2b, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700613 BOOST_CHECK(face2->sentNacks.empty());
614
615 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
616 face3->sentNacks.clear();
Junxiao Shi9d727852019-05-14 13:44:22 -0600617 auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
ashiqopu075bb7d2019-03-10 01:38:21 +0000618 face3->receiveInterest(*interest3a, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700619 BOOST_CHECK(face3->sentNacks.empty());
620}
621
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400622BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700623{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400624 auto face1 = addFace();
625 auto face2 = addFace();
Junxiao Shia110f262014-10-12 12:35:20 -0700626
627 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700628 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
629 if (pktType == tlv::Interest) {
630 auto interest = make_shared<Interest>(face2->sentInterests.back());
ashiqopu075bb7d2019-03-10 01:38:21 +0000631 getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700632 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700633 });
Junxiao Shia110f262014-10-12 12:35:20 -0700634
635 Fib& fib = forwarder.getFib();
Ju Pand8315bf2019-07-31 06:59:07 +0000636 fib::Entry* entry = fib.insert("/A").first;
637 fib.addOrUpdateNextHop(*entry, *face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700638
Junxiao Shi455581d2014-11-17 18:38:40 -0700639 // receive an Interest
Junxiao Shi9d727852019-05-14 13:44:22 -0600640 auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
ashiqopu075bb7d2019-03-10 01:38:21 +0000641 face1->receiveInterest(*interest, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700642
Junxiao Shi455581d2014-11-17 18:38:40 -0700643 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
Davide Pesavento14e71f02019-03-28 17:35:25 -0400644 BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
645 this->advanceClocks(25_ms, 40);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700646 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700647
648 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
649 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
650 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
651 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
652 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700653}
654
Junxiao Shid41d6072016-06-19 23:35:27 +0000655BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700656{
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400657 auto face1 = addFace();
Junxiao Shi9d727852019-05-14 13:44:22 -0600658 auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);
Junxiao Shi330136a2016-03-10 04:53:08 -0700659
Davide Pesavento0498ce82021-06-14 02:02:21 -0400660 auto& dnl = forwarder.getDeadNonceList();
Junxiao Shi330136a2016-03-10 04:53:08 -0700661 dnl.add(interest->getName(), interest->getNonce());
Davide Pesavento0498ce82021-06-14 02:02:21 -0400662 auto& pit = forwarder.getPit();
663 BOOST_CHECK_EQUAL(pit.size(), 0);
Junxiao Shi330136a2016-03-10 04:53:08 -0700664
Davide Pesavento0498ce82021-06-14 02:02:21 -0400665 forwarder.onIncomingInterest(*interest, FaceEndpoint(*face1, 0));
Davide Pesavento14e71f02019-03-28 17:35:25 -0400666 this->advanceClocks(100_ms, 20_s);
Junxiao Shi330136a2016-03-10 04:53:08 -0700667 BOOST_CHECK_EQUAL(pit.size(), 0);
668}
669
Alex Lane6bead9b2020-05-12 19:08:20 -0500670BOOST_AUTO_TEST_CASE(UnsolicitedData)
671{
672 auto face1 = addFace();
673 auto data = makeData("/A");
674
675 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
Davide Pesavento0498ce82021-06-14 02:02:21 -0400676 forwarder.onIncomingData(*data, FaceEndpoint(*face1, 0));
Alex Lane6bead9b2020-05-12 19:08:20 -0500677 this->advanceClocks(1_ms, 10_ms);
678 BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
679}
680
Davide Pesaventob21bed82021-02-13 00:20:06 -0500681BOOST_AUTO_TEST_CASE(NewNextHop)
682{
683 auto face1 = addFace();
684 auto face2 = addFace();
685 auto face3 = addFace();
686 auto face4 = addFace();
687
688 auto& strategy = choose<DummyStrategy>(forwarder, "/A", DummyStrategy::getStrategyName());
689
690 Fib& fib = forwarder.getFib();
691 Pit& pit = forwarder.getPit();
692
693 // fib: "/", "/A/B", "/A/B/C/D/E"
694 fib::Entry* entry = fib.insert("/").first;
695 fib.addOrUpdateNextHop(*entry, *face1, 100);
696 entry = fib.insert("/A/B").first;
697 fib.addOrUpdateNextHop(*entry, *face2, 0);
698 entry = fib.insert("/A/B/C/D/E").first;
699 fib.addOrUpdateNextHop(*entry, *face3, 0);
700
701 // pit: "/A", "/A/B/C", "/A/B/Z"
702 auto interest1 = makeInterest("/A");
703 auto pit1 = pit.insert(*interest1).first;
704 pit1->insertOrUpdateInRecord(*face3, *interest1);
705 auto interest2 = makeInterest("/A/B/C");
706 auto pit2 = pit.insert(*interest2).first;
707 pit2->insertOrUpdateInRecord(*face3, *interest2);
708 auto interest3 = makeInterest("/A/B/Z");
709 auto pit3 = pit.insert(*interest3).first;
710 pit3->insertOrUpdateInRecord(*face3, *interest3);
711
712 // new nexthop for "/"
713 entry = fib.insert("/").first;
714 fib.addOrUpdateNextHop(*entry, *face2, 50);
715
716 // /A --> triggered
717 // /A/B/C --> not triggered
718 // /A/B/Z --> not triggered
719 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 1);
720 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
721 strategy.afterNewNextHopCalls.clear();
722
723 // new nexthop for "/A"
724 entry = fib.insert("/A").first;
725 fib.addOrUpdateNextHop(*entry, *face4, 50);
726
727 // /A --> triggered
728 // /A/B/C --> not triggered
729 // /A/B/Z --> not triggered
730 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 1);
731 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
732 strategy.afterNewNextHopCalls.clear();
733
734 // new nexthop for "/A/B"
735 entry = fib.insert("/A/B").first;
736 fib.addOrUpdateNextHop(*entry, *face4, 0);
737
738 // /A --> not triggered
739 // /A/B/C --> triggered
740 // /A/B/Z --> triggered
741 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 2);
742 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A/B/C");
743 BOOST_TEST(strategy.afterNewNextHopCalls[1] == "/A/B/Z");
744 strategy.afterNewNextHopCalls.clear();
745
746 // new nexthop for "/A/B/C/D"
747 entry = fib.insert("/A/B/C/D").first;
748 fib.addOrUpdateNextHop(*entry, *face1, 0);
749
750 // nothing triggered
751 BOOST_TEST(strategy.afterNewNextHopCalls.size() == 0);
752
753 // create a second pit entry for /A
754 auto interest4 = makeInterest("/A");
755 interest4->setMustBeFresh(true);
756 auto pit4 = pit.insert(*interest4).first;
757 pit4->insertOrUpdateInRecord(*face3, *interest4);
758
759 // new nexthop for "/A"
760 entry = fib.insert("/A").first;
761 fib.addOrUpdateNextHop(*entry, *face1, 0);
762
763 // /A --> triggered twice
764 // /A/B/C --> not triggered
765 // /A/B/Z --> not triggered
766 BOOST_TEST_REQUIRE(strategy.afterNewNextHopCalls.size() == 2);
767 BOOST_TEST(strategy.afterNewNextHopCalls[0] == "/A");
768 BOOST_TEST(strategy.afterNewNextHopCalls[1] == "/A");
769}
770
Davide Pesaventocf7db2f2019-03-24 23:17:28 -0400771BOOST_AUTO_TEST_SUITE_END() // TestForwarder
772BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700773
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700774} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700775} // namespace nfd