blob: a5118d80d8f40bb87e8ed88dd9d05c6d3b4cc7c7 [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/*
Teng Liang63086442018-02-25 20:39:42 -07003 * Copyright (c) 2014-2018, 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"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070027
Junxiao Shid9ee45c2014-02-27 15:38:11 -070028#include "tests/test-common.hpp"
Junxiao Shi06a1eab2017-09-04 13:13:02 +000029#include "tests/daemon/face/dummy-face.hpp"
30#include "choose-strategy.hpp"
31#include "dummy-strategy.hpp"
32
33#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi8c8d2182014-01-30 22:33:00 -070034
35namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070036namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070037
Junxiao Shi0355e9f2015-09-02 07:24:53 -070038BOOST_AUTO_TEST_SUITE(Fw)
Junxiao Shid41d6072016-06-19 23:35:27 +000039BOOST_FIXTURE_TEST_SUITE(TestForwarder, UnitTestTimeFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070040
Junxiao Shi8c8d2182014-01-30 22:33:00 -070041BOOST_AUTO_TEST_CASE(SimpleExchange)
42{
Junxiao Shic041ca32014-02-25 20:01:15 -070043 Forwarder forwarder;
44
Junxiao Shia6de4292016-07-12 02:08:10 +000045 shared_ptr<Interest> interestAB = makeInterest("/A/B");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070046 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shia6de4292016-07-12 02:08:10 +000047 shared_ptr<Data> dataABC = makeData("/A/B/C");
Junxiao Shi8c8d2182014-01-30 22:33:00 -070048
Junxiao Shicde37ad2015-12-24 01:02:05 -070049 auto face1 = make_shared<DummyFace>();
50 auto face2 = make_shared<DummyFace>();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070051 forwarder.addFace(face1);
52 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070053
Junxiao Shi8c8d2182014-01-30 22:33:00 -070054 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +000055 fib.insert("/A").first->addNextHop(*face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070056
Junxiao Shida93f1f2015-11-11 06:13:16 -070057 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
58 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000059 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
60 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shid41d6072016-06-19 23:35:27 +000061 face1->receiveInterest(*interestAB);
62 this->advanceClocks(time::milliseconds(100), time::seconds(1));
Junxiao Shicde37ad2015-12-24 01:02:05 -070063 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000064 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070065 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
66 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070067 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
68 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shi06a1eab2017-09-04 13:13:02 +000069 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
70 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070071
Junxiao Shida93f1f2015-11-11 06:13:16 -070072 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
73 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shid41d6072016-06-19 23:35:27 +000074 face2->receiveData(*dataABC);
75 this->advanceClocks(time::milliseconds(100), time::seconds(1));
Junxiao Shicde37ad2015-12-24 01:02:05 -070076 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000077 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B/C");
Junxiao Shicde37ad2015-12-24 01:02:05 -070078 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
79 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070080 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
81 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070082}
83
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070084BOOST_AUTO_TEST_CASE(CsMatched)
85{
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070086 Forwarder forwarder;
87
Junxiao Shicde37ad2015-12-24 01:02:05 -070088 auto face1 = make_shared<DummyFace>();
89 auto face2 = make_shared<DummyFace>();
90 auto face3 = make_shared<DummyFace>();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070091 forwarder.addFace(face1);
92 forwarder.addFace(face2);
93 forwarder.addFace(face3);
94
Junxiao Shia6de4292016-07-12 02:08:10 +000095 shared_ptr<Interest> interestA = makeInterest("/A");
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070096 interestA->setInterestLifetime(time::seconds(4));
Junxiao Shia6de4292016-07-12 02:08:10 +000097 shared_ptr<Data> dataA = makeData("/A");
Junxiao Shi0de23a22015-12-03 20:07:02 +000098 dataA->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070099
100 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +0000101 fib.insert("/A").first->addNextHop(*face2, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700102
103 Pit& pit = forwarder.getPit();
104 BOOST_CHECK_EQUAL(pit.size(), 0);
105
106 Cs& cs = forwarder.getCs();
Minsheng Zhangffe8bbb2016-03-10 13:40:37 -0700107 cs.insert(*dataA);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700108
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000109 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
110 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700111 face1->receiveInterest(*interestA);
Junxiao Shid41d6072016-06-19 23:35:27 +0000112 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700113 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700114 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shi06a1eab2017-09-04 13:13:02 +0000115 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
116 BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700117
Junxiao Shicde37ad2015-12-24 01:02:05 -0700118 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700119 // IncomingFaceId field should be reset to represent CS
Junxiao Shicde37ad2015-12-24 01:02:05 -0700120 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
121 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700122
Junxiao Shid41d6072016-06-19 23:35:27 +0000123 this->advanceClocks(time::milliseconds(100), time::milliseconds(500));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700124 // PIT entry should not be left behind
125 BOOST_CHECK_EQUAL(pit.size(), 0);
126}
127
Junxiao Shi891f47b2016-06-20 00:02:11 +0000128BOOST_AUTO_TEST_CASE(OutgoingInterest)
129{
130 Forwarder forwarder;
131 auto face1 = make_shared<DummyFace>();
132 auto face2 = make_shared<DummyFace>();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000133 forwarder.addFace(face1);
134 forwarder.addFace(face2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000135
136 Pit& pit = forwarder.getPit();
Junxiao Shia6de4292016-07-12 02:08:10 +0000137 auto interestA1 = makeInterest("/A");
Junxiao Shi891f47b2016-06-20 00:02:11 +0000138 interestA1->setNonce(8378);
139 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
Junxiao Shic5f651f2016-11-17 22:58:12 +0000140 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000141
Junxiao Shia6de4292016-07-12 02:08:10 +0000142 auto interestA2 = makeInterest("/A");
Junxiao Shic5f651f2016-11-17 22:58:12 +0000143 interestA2->setNonce(1698);
144 forwarder.onOutgoingInterest(pitA, *face2, *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000145
Junxiao Shic5f651f2016-11-17 22:58:12 +0000146 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2);
147 BOOST_REQUIRE(outA2 != pitA->out_end());
148 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000149
Junxiao Shi891f47b2016-06-20 00:02:11 +0000150 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000151 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000152}
153
Junxiao Shie342e8d2016-09-18 16:48:00 +0000154BOOST_AUTO_TEST_CASE(NextHopFaceId)
155{
156 Forwarder forwarder;
157
158 auto face1 = make_shared<DummyFace>();
159 auto face2 = make_shared<DummyFace>();
160 auto face3 = make_shared<DummyFace>();
161 forwarder.addFace(face1);
162 forwarder.addFace(face2);
163 forwarder.addFace(face3);
164
165 Fib& fib = forwarder.getFib();
166 fib.insert("/A").first->addNextHop(*face3, 0);
167
168 shared_ptr<Interest> interest = makeInterest("/A/B");
169 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
170
171 face1->receiveInterest(*interest);
172 this->advanceClocks(time::milliseconds(100), time::seconds(1));
173 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
174 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
175 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
176}
177
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700178class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700179{
180public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700181 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700182 {
183 }
184
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000185 void
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200186 onDataUnsolicited(Face& inFace, const Data& data) override
Junxiao Shi88884492014-02-15 15:57:43 -0700187 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700188 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700189 }
190
191protected:
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000192 void
Junxiao Shib9420cf2016-08-13 04:38:52 +0000193 dispatchToStrategy(pit::Entry& pitEntry, function<void(fw::Strategy&)> trigger) override
Junxiao Shi88884492014-02-15 15:57:43 -0700194 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700195 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700196 }
197
198public:
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700199 int dispatchToStrategy_count;
200 int onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700201};
202
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700203BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700204{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700205 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700206 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
207 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700208 forwarder.addFace(face1);
209 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700210
Junxiao Shi88884492014-02-15 15:57:43 -0700211 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700212 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700213 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800214 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700215 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700216
Junxiao Shi88884492014-02-15 15:57:43 -0700217 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700218 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700219 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800220 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700221 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700222
Junxiao Shi88884492014-02-15 15:57:43 -0700223 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700224 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700225 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800226 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700227 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700228
Junxiao Shi88884492014-02-15 15:57:43 -0700229 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700230 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700231 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800232 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700233 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700234
Junxiao Shi88884492014-02-15 15:57:43 -0700235 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700236 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700237 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800238 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700239 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700240
241 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700242 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700243 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800244 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700245 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700246
Junxiao Shi88884492014-02-15 15:57:43 -0700247 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700248 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700249 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800250 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700251 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700252
253 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700254 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700255 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800256 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700257 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700258}
259
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700260BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700261{
Junxiao Shif3c07812014-03-11 21:48:49 -0700262 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700263 auto face1 = make_shared<DummyFace>();
264 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700265 forwarder.addFace(face1);
266 forwarder.addFace(face2);
267
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000268 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
269 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700270
271 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000272 strategyA.afterReceiveInterest_count = 0;
273 strategyA.interestOutFace = face2;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700274 forwarder.startProcessInterest(*face1, *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000275 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700276
277 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000278 strategyB.afterReceiveInterest_count = 0;
279 strategyB.interestOutFace = face2;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700280 forwarder.startProcessInterest(*face1, *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000281 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700282
Junxiao Shid41d6072016-06-19 23:35:27 +0000283 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shif3c07812014-03-11 21:48:49 -0700284
285 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000286 strategyA.beforeSatisfyInterest_count = 0;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700287 forwarder.startProcessData(*face2, *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000288 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700289
290 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000291 strategyB.beforeSatisfyInterest_count = 0;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700292 forwarder.startProcessData(*face2, *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000293 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700294
295 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700296 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700297 forwarder.startProcessInterest(*face1, *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700298 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700299 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700300 forwarder.startProcessInterest(*face1, *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700301}
302
Junxiao Shida006f52014-05-16 11:18:00 -0700303BOOST_AUTO_TEST_CASE(IncomingData)
304{
Junxiao Shida006f52014-05-16 11:18:00 -0700305 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700306 auto face1 = make_shared<DummyFace>();
307 auto face2 = make_shared<DummyFace>();
308 auto face3 = make_shared<DummyFace>();
309 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700310 forwarder.addFace(face1);
311 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700312 forwarder.addFace(face3);
313 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700314
315 Pit& pit = forwarder.getPit();
316 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
317 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000318 pit0->insertOrUpdateInRecord(*face1, *interest0);
Junxiao Shida006f52014-05-16 11:18:00 -0700319 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
320 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000321 pitA->insertOrUpdateInRecord(*face1, *interestA);
322 pitA->insertOrUpdateInRecord(*face2, *interestA);
Junxiao Shida006f52014-05-16 11:18:00 -0700323 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
324 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000325 pitC->insertOrUpdateInRecord(*face3, *interestC);
326 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700327
328 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
329 forwarder.onIncomingData(*face3, *dataD);
Junxiao Shid41d6072016-06-19 23:35:27 +0000330 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shida006f52014-05-16 11:18:00 -0700331
Junxiao Shicde37ad2015-12-24 01:02:05 -0700332 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
333 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
334 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
335 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700336}
337
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700338BOOST_AUTO_TEST_CASE(IncomingNack)
339{
340 Forwarder forwarder;
341 auto face1 = make_shared<DummyFace>();
342 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700343 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
344 ndn::nfd::FACE_SCOPE_NON_LOCAL,
345 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
346 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700347 forwarder.addFace(face1);
348 forwarder.addFace(face2);
349 forwarder.addFace(face3);
350
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000351 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
352 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700353
354 Pit& pit = forwarder.getPit();
355
356 // dispatch to the correct strategy
357 shared_ptr<Interest> interest1 = makeInterest("/A/AYJqayrzF", 562);
358 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000359 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700360 shared_ptr<Interest> interest2 = makeInterest("/B/EVyP73ru", 221);
361 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000362 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700363
364 lp::Nack nack1 = makeNack("/A/AYJqayrzF", 562, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000365 strategyA.afterReceiveNack_count = 0;
366 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700367 forwarder.onIncomingNack(*face1, nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000368 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
369 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700370
371 lp::Nack nack2 = makeNack("/B/EVyP73ru", 221, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000372 strategyA.afterReceiveNack_count = 0;
373 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700374 forwarder.onIncomingNack(*face1, nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000375 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
376 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700377
378 // record Nack on PIT out-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700379 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1);
380 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700381 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
382 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
383
384 // drop if no PIT entry
385 lp::Nack nack3 = makeNack("/yEcw5HhdM", 243, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000386 strategyA.afterReceiveNack_count = 0;
387 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700388 forwarder.onIncomingNack(*face1, nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000389 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
390 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700391
392 // drop if no out-record
393 shared_ptr<Interest> interest4 = makeInterest("/Etab4KpY", 157);
394 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000395 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700396
397 lp::Nack nack4a = makeNack("/Etab4KpY", 157, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000398 strategyA.afterReceiveNack_count = 0;
399 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700400 forwarder.onIncomingNack(*face2, nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000401 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
402 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700403
404 // drop if Nonce does not match out-record
405 lp::Nack nack4b = makeNack("/Etab4KpY", 294, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000406 strategyA.afterReceiveNack_count = 0;
407 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700408 forwarder.onIncomingNack(*face1, nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000409 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
410 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700411
412 // drop if inFace is multi-access
Junxiao Shi9cff7792016-08-01 21:45:11 +0000413 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000414 strategyA.afterReceiveNack_count = 0;
415 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700416 forwarder.onIncomingNack(*face3, nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000417 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
418 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700419}
420
421BOOST_AUTO_TEST_CASE(OutgoingNack)
422{
423 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700424 auto face1 = make_shared<DummyFace>();
425 auto face2 = make_shared<DummyFace>();
426 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
427 ndn::nfd::FACE_SCOPE_NON_LOCAL,
428 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
429 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
430 forwarder.addFace(face1);
431 forwarder.addFace(face2);
432 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700433
434 Pit& pit = forwarder.getPit();
435
436 lp::NackHeader nackHeader;
437 nackHeader.setReason(lp::NackReason::CONGESTION);
438
439 // don't send Nack if there's no in-record
440 shared_ptr<Interest> interest1 = makeInterest("/fM5IVEtC", 719);
441 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000442 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700443
444 face2->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700445 forwarder.onOutgoingNack(pit1, *face2, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700446 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
447
448 // send Nack with correct Nonce
449 shared_ptr<Interest> interest2a = makeInterest("/Vi8tRm9MG3", 152);
450 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000451 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700452 shared_ptr<Interest> interest2b = makeInterest("/Vi8tRm9MG3", 808);
Junxiao Shi9cff7792016-08-01 21:45:11 +0000453 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700454
455 face1->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700456 forwarder.onOutgoingNack(pit2, *face1, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700457 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
458 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
459 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
460
461 // erase in-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700462 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1);
463 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700464
465 // send Nack with correct Nonce
466 face2->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700467 forwarder.onOutgoingNack(pit2, *face2, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700468 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
469 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
470 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
471
472 // erase in-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700473 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1);
474 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700475
476 // don't send Nack to multi-access face
477 shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
Junxiao Shi9cff7792016-08-01 21:45:11 +0000478 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700479
480 face3->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700481 forwarder.onOutgoingNack(pit1, *face3, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700482 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
483}
484
485BOOST_AUTO_TEST_CASE(InterestLoopNack)
486{
487 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700488 auto face1 = make_shared<DummyFace>();
489 auto face2 = make_shared<DummyFace>();
490 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
491 ndn::nfd::FACE_SCOPE_NON_LOCAL,
492 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
493 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700494 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700495 forwarder.addFace(face1);
496 forwarder.addFace(face2);
497 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700498 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700499
500 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +0000501 fib.insert("/zT4XwK0Hnx").first->addNextHop(*face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700502
503 // receive Interest on face1
504 face1->sentNacks.clear();
505 shared_ptr<Interest> interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
506 face1->receiveInterest(*interest1a);
507 BOOST_CHECK(face1->sentNacks.empty());
508
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000509 // receive Interest with duplicate Nonce on face1: legit retransmission
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700510 face1->sentNacks.clear();
511 shared_ptr<Interest> interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
512 face1->receiveInterest(*interest1b);
Junxiao Shi2fe3af02017-03-04 17:24:19 +0000513 BOOST_CHECK(face1->sentNacks.empty());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700514
515 // receive Interest with duplicate Nonce on face2
516 face2->sentNacks.clear();
517 shared_ptr<Interest> interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
518 face2->receiveInterest(*interest2a);
519 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
520 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
521 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
522
523 // receive Interest with new Nonce on face2
524 face2->sentNacks.clear();
525 shared_ptr<Interest> interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 944);
526 face2->receiveInterest(*interest2b);
527 BOOST_CHECK(face2->sentNacks.empty());
528
529 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
530 face3->sentNacks.clear();
531 shared_ptr<Interest> interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
532 face3->receiveInterest(*interest3a);
533 BOOST_CHECK(face3->sentNacks.empty());
534}
535
Junxiao Shi455581d2014-11-17 18:38:40 -0700536BOOST_FIXTURE_TEST_CASE(InterestLoopWithShortLifetime, UnitTestTimeFixture) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700537{
Junxiao Shia110f262014-10-12 12:35:20 -0700538 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700539 auto face1 = make_shared<DummyFace>();
540 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700541 forwarder.addFace(face1);
542 forwarder.addFace(face2);
543
544 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700545 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
546 if (pktType == tlv::Interest) {
547 auto interest = make_shared<Interest>(face2->sentInterests.back());
548 scheduler::schedule(time::milliseconds(170), [face1, interest] { face1->receiveInterest(*interest); });
549 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700550 });
Junxiao Shia110f262014-10-12 12:35:20 -0700551
552 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +0000553 fib.insert("/A").first->addNextHop(*face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700554
Junxiao Shi455581d2014-11-17 18:38:40 -0700555 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700556 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
557 interest->setNonce(82101183);
558 interest->setInterestLifetime(time::milliseconds(50));
559 face1->receiveInterest(*interest);
560
Junxiao Shi455581d2014-11-17 18:38:40 -0700561 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
562 BOOST_ASSERT(time::milliseconds(25) * 40 < forwarder.getDeadNonceList().getLifetime());
563 this->advanceClocks(time::milliseconds(25), 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700564
Junxiao Shicde37ad2015-12-24 01:02:05 -0700565 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700566
567 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
568 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
569 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
570 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
571 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700572}
573
Junxiao Shid41d6072016-06-19 23:35:27 +0000574BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700575{
576 Forwarder forwarder;
577 shared_ptr<Face> face1 = make_shared<DummyFace>();
578 forwarder.addFace(face1);
579
580 shared_ptr<Interest> interest = makeInterest("ndn:/hcLSAsQ9A");
581 interest->setNonce(61883075);
582 interest->setInterestLifetime(time::seconds(2));
583
584 DeadNonceList& dnl = forwarder.getDeadNonceList();
585 dnl.add(interest->getName(), interest->getNonce());
586 Pit& pit = forwarder.getPit();
587 BOOST_REQUIRE_EQUAL(pit.size(), 0);
588
589 forwarder.startProcessInterest(*face1, *interest);
590 this->advanceClocks(time::milliseconds(100), time::seconds(20));
591 BOOST_CHECK_EQUAL(pit.size(), 0);
592}
593
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700594BOOST_AUTO_TEST_SUITE_END()
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700595BOOST_AUTO_TEST_SUITE_END()
596
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700597} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700598} // namespace nfd