blob: d9d50d620c47f3dd6eed2642aed3ee81279735fc [file] [log] [blame]
Junxiao Shi8c8d2182014-01-30 22:33:00 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070027#include "tests/daemon/face/dummy-face.hpp"
Junxiao Shif3c07812014-03-11 21:48:49 -070028#include "dummy-strategy.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070029
Junxiao Shid9ee45c2014-02-27 15:38:11 -070030#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070031#include "tests/limited-io.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070032
33namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070034namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070035
Junxiao Shi0355e9f2015-09-02 07:24:53 -070036BOOST_AUTO_TEST_SUITE(Fw)
37BOOST_FIXTURE_TEST_SUITE(TestForwarder, BaseFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070038
Junxiao Shi8c8d2182014-01-30 22:33:00 -070039BOOST_AUTO_TEST_CASE(SimpleExchange)
40{
Junxiao Shi75ab6b72014-11-30 01:01:05 -070041 LimitedIo limitedIo;
42 auto afterOp = bind(&LimitedIo::afterOp, &limitedIo);;
Junxiao Shic041ca32014-02-25 20:01:15 -070043 Forwarder forwarder;
44
Junxiao Shi8c8d2182014-01-30 22:33:00 -070045 Name nameA ("ndn:/A");
46 Name nameAB ("ndn:/A/B");
47 Name nameABC("ndn:/A/B/C");
Junxiao Shif3c07812014-03-11 21:48:49 -070048 shared_ptr<Interest> interestAB = makeInterest(nameAB);
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070049 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shif3c07812014-03-11 21:48:49 -070050 shared_ptr<Data> dataABC = makeData(nameABC);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070051
Junxiao Shid9ee45c2014-02-27 15:38:11 -070052 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
53 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
Junxiao Shic099ddb2014-12-25 20:53:20 -070054 face1->afterSend.connect(afterOp);
55 face2->afterSend.connect(afterOp);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070056 forwarder.addFace(face1);
57 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070058
Junxiao Shi8c8d2182014-01-30 22:33:00 -070059 Fib& fib = forwarder.getFib();
Junxiao Shi6e694322014-04-03 10:27:13 -070060 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
Junxiao Shi8c8d2182014-01-30 22:33:00 -070061 fibEntry->addNextHop(face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070062
Junxiao Shi6e694322014-04-03 10:27:13 -070063 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 0);
64 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 0);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070065 g_io.post([&] { face1->receiveInterest(*interestAB); });
66 BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070067 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070068 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getName(), nameAB);
Junxiao Shi06887ac2014-02-13 20:15:42 -070069 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070070 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 1);
71 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070072
Junxiao Shi6e694322014-04-03 10:27:13 -070073 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 0);
74 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 0);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070075 g_io.post([&] { face2->receiveData(*dataABC); });
76 BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070077 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070078 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getName(), nameABC);
Junxiao Shi06887ac2014-02-13 20:15:42 -070079 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070080 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 1);
81 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070082}
83
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070084BOOST_AUTO_TEST_CASE(CsMatched)
85{
86 LimitedIo limitedIo;
87 Forwarder forwarder;
88
89 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
90 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
91 shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
92 forwarder.addFace(face1);
93 forwarder.addFace(face2);
94 forwarder.addFace(face3);
95
96 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
97 interestA->setInterestLifetime(time::seconds(4));
98 shared_ptr<Data> dataA = makeData("ndn:/A");
99 dataA->setIncomingFaceId(face3->getId());
100
101 Fib& fib = forwarder.getFib();
102 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
103 fibEntry->addNextHop(face2, 0);
104
105 Pit& pit = forwarder.getPit();
106 BOOST_CHECK_EQUAL(pit.size(), 0);
107
108 Cs& cs = forwarder.getCs();
109 BOOST_REQUIRE(cs.insert(*dataA));
110
111 face1->receiveInterest(*interestA);
112 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
113 // Interest matching ContentStore should not be forwarded
114 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 0);
115
116 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
117 // IncomingFaceId field should be reset to represent CS
118 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), FACEID_CONTENT_STORE);
119
120 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(500));
121 // PIT entry should not be left behind
122 BOOST_CHECK_EQUAL(pit.size(), 0);
123}
124
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700125class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700126{
127public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700128 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700129 {
130 }
131
132 virtual void
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700133 onDataUnsolicited(Face& inFace, const Data& data) DECL_OVERRIDE
Junxiao Shi88884492014-02-15 15:57:43 -0700134 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700135 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700136 }
137
138protected:
139 virtual void
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700140 dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> f) DECL_OVERRIDE
Junxiao Shi88884492014-02-15 15:57:43 -0700141 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700142 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700143 }
144
145public:
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700146 int dispatchToStrategy_count;
147 int onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700148};
149
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700150BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700151{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700152 ScopeLocalhostIncomingTestForwarder forwarder;
153 shared_ptr<Face> face1 = make_shared<DummyLocalFace>();
154 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700155 forwarder.addFace(face1);
156 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700157
Junxiao Shi88884492014-02-15 15:57:43 -0700158 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700159 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700160 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800161 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700162 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700163
Junxiao Shi88884492014-02-15 15:57:43 -0700164 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700165 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700166 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800167 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700168 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700169
Junxiao Shi88884492014-02-15 15:57:43 -0700170 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700171 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700172 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800173 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700174 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700175
Junxiao Shi88884492014-02-15 15:57:43 -0700176 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700177 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700178 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800179 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700180 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700181
Junxiao Shi88884492014-02-15 15:57:43 -0700182 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700183 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700184 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800185 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700186 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700187
188 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700189 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700190 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800191 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700192 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700193
Junxiao Shi88884492014-02-15 15:57:43 -0700194 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700195 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700196 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800197 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700198 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700199
200 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700201 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700202 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800203 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700204 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700205}
206
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700207BOOST_AUTO_TEST_CASE(ScopeLocalhostOutgoing)
208{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700209 Forwarder forwarder;
210 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
211 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
212 shared_ptr<Face> face3 = make_shared<DummyLocalFace>();
213 forwarder.addFace(face1);
214 forwarder.addFace(face2);
215 forwarder.addFace(face3);
216 Pit& pit = forwarder.getPit();
217
218 // local face, /localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700219 shared_ptr<Interest> interestA1 = makeInterest("/localhost/A1");
220 shared_ptr<pit::Entry> pitA1 = pit.insert(*interestA1).first;
221 pitA1->insertOrUpdateInRecord(face3, *interestA1);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700222 face1->m_sentInterests.clear();
223 forwarder.onOutgoingInterest(pitA1, *face1);
224 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
225
226 // non-local face, /localhost: violate
Junxiao Shif3c07812014-03-11 21:48:49 -0700227 shared_ptr<Interest> interestA2 = makeInterest("/localhost/A2");
228 shared_ptr<pit::Entry> pitA2 = pit.insert(*interestA2).first;
229 pitA2->insertOrUpdateInRecord(face3, *interestA2);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700230 face2->m_sentInterests.clear();
231 forwarder.onOutgoingInterest(pitA2, *face2);
232 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 0);
233
234 // local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700235 shared_ptr<Interest> interestA3 = makeInterest("/A3");
236 shared_ptr<pit::Entry> pitA3 = pit.insert(*interestA3).first;
237 pitA3->insertOrUpdateInRecord(face3, *interestA3);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700238 face1->m_sentInterests.clear();
239 forwarder.onOutgoingInterest(pitA3, *face1);
240 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
241
242 // non-local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700243 shared_ptr<Interest> interestA4 = makeInterest("/A4");
244 shared_ptr<pit::Entry> pitA4 = pit.insert(*interestA4).first;
245 pitA4->insertOrUpdateInRecord(face3, *interestA4);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700246 face2->m_sentInterests.clear();
247 forwarder.onOutgoingInterest(pitA4, *face2);
248 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
249
250 // local face, /localhost: OK
251 face1->m_sentDatas.clear();
252 forwarder.onOutgoingData(Data("/localhost/B1"), *face1);
253 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
254
255 // non-local face, /localhost: OK
256 face2->m_sentDatas.clear();
257 forwarder.onOutgoingData(Data("/localhost/B2"), *face2);
258 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 0);
259
260 // local face, non-/localhost: OK
261 face1->m_sentDatas.clear();
262 forwarder.onOutgoingData(Data("/B3"), *face1);
263 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
264
265 // non-local face, non-/localhost: OK
266 face2->m_sentDatas.clear();
267 forwarder.onOutgoingData(Data("/B4"), *face2);
268 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
269}
270
Junxiao Shi11bd9c22014-03-13 20:44:13 -0700271BOOST_AUTO_TEST_CASE(ScopeLocalhopOutgoing)
272{
273 Forwarder forwarder;
274 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
275 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
276 shared_ptr<DummyLocalFace> face3 = make_shared<DummyLocalFace>();
277 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
278 forwarder.addFace(face1);
279 forwarder.addFace(face2);
280 forwarder.addFace(face3);
281 forwarder.addFace(face4);
282 Pit& pit = forwarder.getPit();
283
284 // from local face, to local face: OK
285 shared_ptr<Interest> interest1 = makeInterest("/localhop/1");
286 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
287 pit1->insertOrUpdateInRecord(face1, *interest1);
288 face3->m_sentInterests.clear();
289 forwarder.onOutgoingInterest(pit1, *face3);
290 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
291
292 // from non-local face, to local face: OK
293 shared_ptr<Interest> interest2 = makeInterest("/localhop/2");
294 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
295 pit2->insertOrUpdateInRecord(face2, *interest2);
296 face3->m_sentInterests.clear();
297 forwarder.onOutgoingInterest(pit2, *face3);
298 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
299
300 // from local face, to non-local face: OK
301 shared_ptr<Interest> interest3 = makeInterest("/localhop/3");
302 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
303 pit3->insertOrUpdateInRecord(face1, *interest3);
304 face4->m_sentInterests.clear();
305 forwarder.onOutgoingInterest(pit3, *face4);
306 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
307
308 // from non-local face, to non-local face: violate
309 shared_ptr<Interest> interest4 = makeInterest("/localhop/4");
310 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
311 pit4->insertOrUpdateInRecord(face2, *interest4);
312 face4->m_sentInterests.clear();
313 forwarder.onOutgoingInterest(pit4, *face4);
314 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 0);
315
316 // from local face and non-local face, to local face: OK
317 shared_ptr<Interest> interest5 = makeInterest("/localhop/5");
318 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
319 pit5->insertOrUpdateInRecord(face1, *interest5);
320 pit5->insertOrUpdateInRecord(face2, *interest5);
321 face3->m_sentInterests.clear();
322 forwarder.onOutgoingInterest(pit5, *face3);
323 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
324
325 // from local face and non-local face, to non-local face: OK
326 shared_ptr<Interest> interest6 = makeInterest("/localhop/6");
327 shared_ptr<pit::Entry> pit6 = pit.insert(*interest6).first;
328 pit6->insertOrUpdateInRecord(face1, *interest6);
329 pit6->insertOrUpdateInRecord(face2, *interest6);
330 face4->m_sentInterests.clear();
331 forwarder.onOutgoingInterest(pit6, *face4);
332 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
333}
334
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700335BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700336{
337 LimitedIo limitedIo;
338 Forwarder forwarder;
339 shared_ptr<Face> face1 = make_shared<DummyFace>();
340 shared_ptr<Face> face2 = make_shared<DummyFace>();
341 forwarder.addFace(face1);
342 forwarder.addFace(face2);
343
344 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
345 shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700346 ref(forwarder), "ndn:/strategyP");
Junxiao Shif3c07812014-03-11 21:48:49 -0700347 shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700348 ref(forwarder), "ndn:/strategyQ");
Junxiao Shif3c07812014-03-11 21:48:49 -0700349 strategyChoice.install(strategyP);
350 strategyChoice.install(strategyQ);
351 strategyChoice.insert("ndn:/" , strategyP->getName());
352 strategyChoice.insert("ndn:/B", strategyQ->getName());
353
354 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700355 strategyP->afterReceiveInterest_count = 0;
356 strategyP->interestOutFace = face2;
357 forwarder.startProcessInterest(*face1, *interest1);
358 BOOST_CHECK_EQUAL(strategyP->afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700359
360 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700361 strategyQ->afterReceiveInterest_count = 0;
362 strategyQ->interestOutFace = face2;
363 forwarder.startProcessInterest(*face1, *interest2);
364 BOOST_CHECK_EQUAL(strategyQ->afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700365
366 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
367
368 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700369 strategyP->beforeSatisfyInterest_count = 0;
370 forwarder.startProcessData(*face2, *data1);
371 BOOST_CHECK_EQUAL(strategyP->beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700372
373 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700374 strategyQ->beforeSatisfyInterest_count = 0;
375 forwarder.startProcessData(*face2, *data2);
376 BOOST_CHECK_EQUAL(strategyQ->beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700377
378 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700379 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700380 forwarder.startProcessInterest(*face1, *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700381 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700382 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700383 forwarder.startProcessInterest(*face1, *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700384
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700385 strategyP->beforeExpirePendingInterest_count = 0;
386 strategyQ->beforeExpirePendingInterest_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700387 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(100));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700388 BOOST_CHECK_EQUAL(strategyP->beforeExpirePendingInterest_count, 1);
389 BOOST_CHECK_EQUAL(strategyQ->beforeExpirePendingInterest_count, 0);
Junxiao Shif3c07812014-03-11 21:48:49 -0700390}
391
Junxiao Shida006f52014-05-16 11:18:00 -0700392BOOST_AUTO_TEST_CASE(IncomingData)
393{
394 LimitedIo limitedIo;
395 Forwarder forwarder;
396 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
397 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
398 shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
399 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
400 forwarder.addFace(face1);
401 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700402 forwarder.addFace(face3);
403 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700404
405 Pit& pit = forwarder.getPit();
406 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
407 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
408 pit0->insertOrUpdateInRecord(face1, *interest0);
409 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
410 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
411 pitA->insertOrUpdateInRecord(face1, *interestA);
412 pitA->insertOrUpdateInRecord(face2, *interestA);
413 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
414 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
415 pitC->insertOrUpdateInRecord(face3, *interestC);
416 pitC->insertOrUpdateInRecord(face4, *interestC);
417
418 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
419 forwarder.onIncomingData(*face3, *dataD);
420 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
421
422 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
423 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
424 BOOST_CHECK_EQUAL(face3->m_sentDatas.size(), 0);
425 BOOST_CHECK_EQUAL(face4->m_sentDatas.size(), 1);
426}
427
Junxiao Shi455581d2014-11-17 18:38:40 -0700428BOOST_FIXTURE_TEST_CASE(InterestLoopWithShortLifetime, UnitTestTimeFixture) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700429{
Junxiao Shia110f262014-10-12 12:35:20 -0700430 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700431 auto face1 = make_shared<DummyFace>();
432 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700433 forwarder.addFace(face1);
434 forwarder.addFace(face2);
435
436 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shic099ddb2014-12-25 20:53:20 -0700437 face2->onSendInterest.connect([&face1] (const Interest& interest) {
Junxiao Shi455581d2014-11-17 18:38:40 -0700438 scheduler::schedule(time::milliseconds(170), [&] { face1->receiveInterest(interest); });
Junxiao Shic099ddb2014-12-25 20:53:20 -0700439 });
Junxiao Shia110f262014-10-12 12:35:20 -0700440
441 Fib& fib = forwarder.getFib();
442 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
443 fibEntry->addNextHop(face2, 0);
444
Junxiao Shi455581d2014-11-17 18:38:40 -0700445 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700446 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
447 interest->setNonce(82101183);
448 interest->setInterestLifetime(time::milliseconds(50));
449 face1->receiveInterest(*interest);
450
Junxiao Shi455581d2014-11-17 18:38:40 -0700451 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
452 BOOST_ASSERT(time::milliseconds(25) * 40 < forwarder.getDeadNonceList().getLifetime());
453 this->advanceClocks(time::milliseconds(25), 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700454
455 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700456
457 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
458 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
459 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
460 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
461 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700462}
463
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700464BOOST_AUTO_TEST_CASE(LinkDelegation)
465{
466 Forwarder forwarder;
467 shared_ptr<Face> face1 = make_shared<DummyFace>();
468 shared_ptr<Face> face2 = make_shared<DummyFace>();
469 forwarder.addFace(face1);
470 forwarder.addFace(face2);
471
472 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
473 auto strategyP = make_shared<DummyStrategy>(ref(forwarder), "ndn:/strategyP");
474 strategyP->wantAfterReceiveInterestCalls = true;
475 strategyChoice.install(strategyP);
476 strategyChoice.insert("ndn:/" , strategyP->getName());
477
478 Fib& fib = forwarder.getFib();
479 Pit& pit = forwarder.getPit();
480 NetworkRegionTable& nrt = forwarder.getNetworkRegionTable();
481
482 // returns prefix of FIB entry during last afterReceiveInterest trigger
483 auto getLastFibPrefix = [strategyP] () -> Name {
484 BOOST_REQUIRE(!strategyP->afterReceiveInterestCalls.empty());
485 return std::get<2>(strategyP->afterReceiveInterestCalls.back())->getPrefix();
486 };
487
488 shared_ptr<Link> link = makeLink("/net/ndnsim", {{10, "/telia/terabits"}, {20, "/ucla/cs"}});
489
490 // consumer region
491 nrt.clear();
492 nrt.insert("/arizona/cs/avenir");
493 shared_ptr<fib::Entry> fibRoot = fib.insert("/").first;
494 fibRoot->addNextHop(face2, 10);
495
496 auto interest1 = makeInterest("/net/ndnsim/www/1.html");
497 interest1->setLink(link->wireEncode());
498 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
499 pit1->insertOrUpdateInRecord(face1, *interest1);
500
501 forwarder.onContentStoreMiss(*face1, pit1, *interest1);
502 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/");
503 BOOST_CHECK_EQUAL(interest1->hasSelectedDelegation(), false);
504
505 fibRoot->removeNextHop(face2);
506
507 // first default-free router, both delegations are available
508 nrt.clear();
509 nrt.insert("/arizona/cs/hobo");
510 shared_ptr<fib::Entry> fibTelia = fib.insert("/telia").first;
511 fibTelia->addNextHop(face2, 10);
512 shared_ptr<fib::Entry> fibUcla = fib.insert("/ucla").first;
513 fibUcla->addNextHop(face2, 10);
514
515 auto interest2 = makeInterest("/net/ndnsim/www/2.html");
516 interest2->setLink(link->wireEncode());
517 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
518 pit2->insertOrUpdateInRecord(face1, *interest2);
519
520 forwarder.onContentStoreMiss(*face1, pit2, *interest2);
521 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/telia");
522 BOOST_REQUIRE_EQUAL(interest2->hasSelectedDelegation(), true);
523 BOOST_CHECK_EQUAL(interest2->getSelectedDelegation(), "/telia/terabits");
524
525 fib.erase(*fibTelia);
526 fib.erase(*fibUcla);
527
528 // first default-free router, only second delegation is available
529 nrt.clear();
530 nrt.insert("/arizona/cs/hobo");
531 fibUcla = fib.insert("/ucla").first;
532 fibUcla->addNextHop(face2, 10);
533
534 auto interest3 = makeInterest("/net/ndnsim/www/3.html");
535 interest3->setLink(link->wireEncode());
536 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
537 pit3->insertOrUpdateInRecord(face1, *interest3);
538
539 forwarder.onContentStoreMiss(*face1, pit3, *interest3);
540 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/ucla");
541 BOOST_REQUIRE_EQUAL(interest3->hasSelectedDelegation(), true);
542 BOOST_CHECK_EQUAL(interest3->getSelectedDelegation(), "/ucla/cs");
543
544 fib.erase(*fibUcla);
545
546 // default-free router, chosen SelectedDelegation
547 nrt.clear();
548 nrt.insert("/ucsd/caida/click");
549 fibTelia = fib.insert("/telia").first;
550 fibTelia->addNextHop(face2, 10);
551 fibUcla = fib.insert("/ucla").first;
552 fibUcla->addNextHop(face2, 10);
553
554 auto interest4 = makeInterest("/net/ndnsim/www/4.html");
555 interest4->setLink(link->wireEncode());
556 interest4->setSelectedDelegation("/ucla/cs");
557 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
558 pit4->insertOrUpdateInRecord(face1, *interest4);
559
560 forwarder.onContentStoreMiss(*face1, pit4, *interest4);
561 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/ucla");
562 BOOST_REQUIRE_EQUAL(interest4->hasSelectedDelegation(), true);
563 BOOST_CHECK_EQUAL(interest4->getSelectedDelegation(), "/ucla/cs");
564
565 fib.erase(*fibTelia);
566 fib.erase(*fibUcla);
567
568 // producer region
569 nrt.clear();
570 nrt.insert("/ucla/cs/spurs");
571 fibRoot->addNextHop(face2, 10);
572 fibUcla = fib.insert("/ucla").first;
573 fibUcla->addNextHop(face2, 10);
574 shared_ptr<fib::Entry> fibNdnsim = fib.insert("/net/ndnsim").first;
575 fibNdnsim->addNextHop(face2, 10);
576
577 auto interest5 = makeInterest("/net/ndnsim/www/5.html");
578 interest5->setLink(link->wireEncode());
579 interest5->setSelectedDelegation("/ucla/cs");
580 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
581 pit5->insertOrUpdateInRecord(face1, *interest5);
582
583 forwarder.onContentStoreMiss(*face1, pit5, *interest5);
584 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/net/ndnsim");
585 BOOST_REQUIRE_EQUAL(interest5->hasSelectedDelegation(), true);
586 BOOST_CHECK_EQUAL(interest5->getSelectedDelegation(), "/ucla/cs");
587
588 fibRoot->removeNextHop(face2);
589 fib.erase(*fibUcla);
590 fib.erase(*fibNdnsim);
591}
592
593
594class MalformedPacketFixture : public UnitTestTimeFixture
595{
596protected:
597 MalformedPacketFixture()
598 : face1(make_shared<DummyFace>())
599 , face2(make_shared<DummyFace>())
600 {
601 forwarder.addFace(face1);
602 forwarder.addFace(face2);
603 }
604
605 void
606 processInterest(shared_ptr<Interest> badInterest)
607 {
608 forwarder.startProcessInterest(*face1, *badInterest);
609 this->continueProcessPacket();
610 }
611
612 // processData
613
614 // processNack
615
616private:
617 void
618 continueProcessPacket()
619 {
620 this->advanceClocks(time::milliseconds(10), time::seconds(6));
621 }
622
623protected:
624 Forwarder forwarder;
625 shared_ptr<DummyFace> face1; // face of incoming bad packet
626 shared_ptr<DummyFace> face2; // another face for setting up states
627};
628
629BOOST_FIXTURE_TEST_SUITE(MalformedPacket, MalformedPacketFixture)
630
631BOOST_AUTO_TEST_CASE(BadLink)
632{
633 shared_ptr<Interest> goodInterest = makeInterest("ndn:/");
634 Block wire = goodInterest->wireEncode();
635 wire.push_back(ndn::encoding::makeEmptyBlock(tlv::Data)); // bad Link
636 wire.encode();
637
638 auto badInterest = make_shared<Interest>();
639 BOOST_REQUIRE_NO_THROW(badInterest->wireDecode(wire));
640 BOOST_REQUIRE(badInterest->hasLink());
641 BOOST_REQUIRE_THROW(badInterest->getLink(), tlv::Error);
642
643 BOOST_CHECK_NO_THROW(this->processInterest(badInterest));
644}
645
646BOOST_AUTO_TEST_SUITE_END() // MalformedPacket
647
648BOOST_AUTO_TEST_SUITE_END()
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700649BOOST_AUTO_TEST_SUITE_END()
650
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700651} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700652} // namespace nfd