blob: ea6292249b83b3af13f86bf33e7449a31f28e1b7 [file] [log] [blame]
Giulio Grassi624f6c62014-02-18 19:42:14 +01001/* -*- 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/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Giulio Grassi624f6c62014-02-18 19:42:14 +010025
Davide Pesavento6ad890a2015-03-09 03:43:17 +010026#include "face/udp-channel.hpp"
27#include "face/udp-face.hpp"
Giulio Grassi624f6c62014-02-18 19:42:14 +010028#include "face/udp-factory.hpp"
Junxiao Shi7e2413b2014-03-02 11:15:09 -070029
Davide Pesavento6ad890a2015-03-09 03:43:17 +010030#include "core/network-interface.hpp"
Junxiao Shi7e2413b2014-03-02 11:15:09 -070031#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070032#include "tests/limited-io.hpp"
Chengyu Fan4381fb62015-01-14 11:37:04 -070033#include "face-history.hpp"
Giulio Grassi624f6c62014-02-18 19:42:14 +010034
35namespace nfd {
36namespace tests {
37
38BOOST_FIXTURE_TEST_SUITE(FaceUdp, BaseFixture)
39
Steve DiBenedettoef04f272014-06-04 14:28:31 -060040BOOST_AUTO_TEST_CASE(GetChannels)
41{
42 UdpFactory factory;
43 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
44
45 std::vector<shared_ptr<const Channel> > expectedChannels;
46
47 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
48 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
49 expectedChannels.push_back(factory.createChannel("::1", "20071"));
50
51 std::list<shared_ptr<const Channel> > channels = factory.getChannels();
52 for (std::list<shared_ptr<const Channel> >::const_iterator i = channels.begin();
53 i != channels.end(); ++i)
54 {
55 std::vector<shared_ptr<const Channel> >::iterator pos =
56 std::find(expectedChannels.begin(), expectedChannels.end(), *i);
57
58 BOOST_REQUIRE(pos != expectedChannels.end());
59 expectedChannels.erase(pos);
60 }
61
62 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
63}
64
Giulio Grassi624f6c62014-02-18 19:42:14 +010065class FactoryErrorCheck : protected BaseFixture
66{
67public:
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070068 bool
69 isTheSameMulticastEndpoint(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010070 return strcmp(e.what(),
71 "Cannot create the requested UDP unicast channel, local "
72 "endpoint is already allocated for a UDP multicast face") == 0;
73 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -070074
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070075 bool
76 isNotMulticastAddress(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010077 return strcmp(e.what(),
78 "Cannot create the requested UDP multicast face, "
79 "the multicast group given as input is not a multicast address") == 0;
80 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -070081
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070082 bool
83 isTheSameUnicastEndpoint(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010084 return strcmp(e.what(),
85 "Cannot create the requested UDP multicast face, local "
86 "endpoint is already allocated for a UDP unicast channel") == 0;
87 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -070088
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070089 bool
90 isLocalEndpointOnDifferentGroup(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010091 return strcmp(e.what(),
92 "Cannot create the requested UDP multicast face, local "
93 "endpoint is already allocated for a UDP multicast face "
94 "on a different multicast group") == 0;
95 }
96};
Junxiao Shi7e2413b2014-03-02 11:15:09 -070097
Giulio Grassi624f6c62014-02-18 19:42:14 +010098BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
99{
100 using boost::asio::ip::udp;
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700101
Giulio Grassi624f6c62014-02-18 19:42:14 +0100102 UdpFactory factory = UdpFactory();
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700103
Giulio Grassi624f6c62014-02-18 19:42:14 +0100104 //to instantiate multicast face on a specific ip address, change interfaceIp
105 std::string interfaceIp = "0.0.0.0";
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700106
Giulio Grassi624f6c62014-02-18 19:42:14 +0100107 shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
108 shared_ptr<UdpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
109 BOOST_CHECK_EQUAL(channel1, channel1a);
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700110 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700111
Giulio Grassi624f6c62014-02-18 19:42:14 +0100112 shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
113 BOOST_CHECK_NE(channel1, channel2);
114
115 shared_ptr<UdpChannel> channel3 = factory.createChannel(interfaceIp, "20070");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700116
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700117 shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20071");
118 BOOST_CHECK_NE(channel2, channel4);
119 BOOST_CHECK_EQUAL(channel4->getUri().toString(), "udp6://[::1]:20071");
120
Giulio Grassi624f6c62014-02-18 19:42:14 +0100121 //same endpoint of a unicast channel
Davide Pesavento94279412015-02-27 01:29:32 +0100122 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "224.0.0.1", "20070"),
123 UdpFactory::Error, isTheSameUnicastEndpoint);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700124
Davide Pesavento94279412015-02-27 01:29:32 +0100125 auto multicastFace1 = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
126 auto multicastFace1a = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
Giulio Grassi624f6c62014-02-18 19:42:14 +0100127 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
Davide Pesavento94279412015-02-27 01:29:32 +0100128 BOOST_CHECK_EQUAL(multicastFace1->isLocal(), false);
129 BOOST_CHECK_EQUAL(multicastFace1->isOnDemand(), false);
130 BOOST_CHECK_EQUAL(multicastFace1->isMultiAccess(), true);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700131
Giulio Grassi624f6c62014-02-18 19:42:14 +0100132 //same endpoint of a multicast face
133 BOOST_CHECK_EXCEPTION(factory.createChannel(interfaceIp, "20072"),
Davide Pesavento94279412015-02-27 01:29:32 +0100134 UdpFactory::Error, isTheSameMulticastEndpoint);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700135
Giulio Grassi624f6c62014-02-18 19:42:14 +0100136 //same multicast endpoint, different group
Davide Pesavento94279412015-02-27 01:29:32 +0100137 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "224.0.0.42", "20072"),
138 UdpFactory::Error, isLocalEndpointOnDifferentGroup);
Giulio Grassi624f6c62014-02-18 19:42:14 +0100139
Davide Pesavento94279412015-02-27 01:29:32 +0100140 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "192.168.10.15", "20025"),
141 UdpFactory::Error, isNotMulticastAddress);
Giulio Grassi624f6c62014-02-18 19:42:14 +0100142
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700143
Giulio Grassi624f6c62014-02-18 19:42:14 +0100144// //Test commented because it required to be run in a machine that can resolve ipv6 query
145// shared_ptr<UdpChannel> channel1v6 = factory.createChannel(//"::1",
146// "fe80::5e96:9dff:fe7d:9c8d%en1",
147// //"fe80::aa54:b2ff:fe08:27b8%wlan0",
148// "20070");
149//
150// //the creation of multicastFace2 works properly. It has been disable because it needs an IP address of
151// //an available network interface (different from the first one used)
152// shared_ptr<MulticastUdpFace> multicastFace2 = factory.createMulticastFace("192.168.1.17",
153// "224.0.0.1",
154// "20073");
155// BOOST_CHECK_NE(multicastFace1, multicastFace2);
156//
157//
158// //ipv6 - work in progress
159// shared_ptr<MulticastUdpFace> multicastFace3 = factory.createMulticastFace("fe80::5e96:9dff:fe7d:9c8d%en1",
160// "FF01:0:0:0:0:0:0:2",
161// "20073");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700162//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100163// shared_ptr<MulticastUdpFace> multicastFace4 = factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
164// "FF01:0:0:0:0:0:0:2",
165// "20073");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700166//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100167// BOOST_CHECK_EQUAL(multicastFace3, multicastFace4);
168//
169// shared_ptr<MulticastUdpFace> multicastFace5 = factory.createMulticastFace("::1",
170// "FF01:0:0:0:0:0:0:2",
171// "20073");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700172//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100173// BOOST_CHECK_NE(multicastFace3, multicastFace5);
174//
175// //same local ipv6 endpoint for a different multicast group
176// BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
177// "FE01:0:0:0:0:0:0:2",
178// "20073"),
179// UdpFactory::Error);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700180//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100181// //same local ipv6 (expect for th port number) endpoint for a different multicast group
182// BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
183// "FE01:0:0:0:0:0:0:2",
184// "20075"),
185// UdpFactory::Error);
186//
187// BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
188// "FE12:0:0:0:0:0:0:2",
189// "20075"),
190// UdpFactory::Error);
191//
192// //not a multicast ipv6
193// BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
194// "A112:0:0:0:0:0:0:2",
195// "20075"),
196// UdpFactory::Error);
Giulio Grassi624f6c62014-02-18 19:42:14 +0100197}
198
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -0700199class FaceCreateFixture : protected BaseFixture
200{
201public:
202 void
203 ignore()
204 {
205 }
206
207 void
208 checkError(const std::string& errorActual, const std::string& errorExpected)
209 {
210 BOOST_CHECK_EQUAL(errorActual, errorExpected);
211 }
212
213 void
214 failIfError(const std::string& errorActual)
215 {
216 BOOST_FAIL("No error expected, but got: [" << errorActual << "]");
217 }
218};
219
220BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
221{
222 UdpFactory factory = UdpFactory();
223
Chengyu Fan4381fb62015-01-14 11:37:04 -0700224 factory.createFace(FaceUri("udp4://127.0.0.1:6363"),
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -0700225 bind(&FaceCreateFixture::ignore, this),
Chengyu Fan4381fb62015-01-14 11:37:04 -0700226 bind(&FaceCreateFixture::checkError, this, _1,
227 "No channels available to connect to 127.0.0.1:6363"));
Giulio Grassi624f6c62014-02-18 19:42:14 +0100228
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000229 factory.createChannel("127.0.0.1", "20071");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700230
Giulio Grassi624f6c62014-02-18 19:42:14 +0100231 factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
Chengyu Fan4381fb62015-01-14 11:37:04 -0700232 bind(&FaceCreateFixture::ignore, this),
233 bind(&FaceCreateFixture::failIfError, this, _1));
234}
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700235
Chengyu Fan4381fb62015-01-14 11:37:04 -0700236class EndToEndIpv4
237{
238public:
239 static const std::string
240 getScheme()
241 {
242 return "udp4";
243 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700244
Chengyu Fan4381fb62015-01-14 11:37:04 -0700245 static const std::string
246 getLocalIp()
247 {
248 return "127.0.0.1";
249 }
Giulio Grassi624f6c62014-02-18 19:42:14 +0100250
Chengyu Fan4381fb62015-01-14 11:37:04 -0700251 static const std::string
252 getPort1()
253 {
254 return "20071";
255 }
256
257 static const std::string
258 getPort2()
259 {
260 return "20072";
261 }
262
263 static const std::string
264 getPort3()
265 {
266 return "20073";
267 }
268
269 static const FaceUri
270 getFaceUri1()
271 {
272 return FaceUri("udp4://127.0.0.1:20071");
273 }
274
275 static const FaceUri
276 getFaceUri2()
277 {
278 return FaceUri("udp4://127.0.0.1:20072");
279 }
280
281 static const FaceUri
282 getFaceUri3()
283 {
284 return FaceUri("udp4://127.0.0.1:20073");
285 }
286};
287
288class EndToEndIpv6
289{
290public:
291 static const std::string
292 getScheme()
293 {
294 return "udp6";
295 }
296
297 static const std::string
298 getLocalIp()
299 {
300 return "::1";
301 }
302
303 static const std::string
304 getPort1()
305 {
306 return "20071";
307 }
308
309 static const std::string
310 getPort2()
311 {
312 return "20072";
313 }
314
315 static const std::string
316 getPort3()
317 {
318 return "20073";
319 }
320
321 static const FaceUri
322 getFaceUri1()
323 {
324 return FaceUri("udp6://[::1]:20071");
325 }
326
327 static const FaceUri
328 getFaceUri2()
329 {
330 return FaceUri("udp6://[::1]:20072");
331 }
332
333 static const FaceUri
334 getFaceUri3()
335 {
336 return FaceUri("udp6://[::1]:20073");
337 }
338};
339
340typedef boost::mpl::list<EndToEndIpv4, EndToEndIpv6> EndToEndAddresses;
341
342// end to end communication
343BOOST_AUTO_TEST_CASE_TEMPLATE(EndToEnd, A, EndToEndAddresses)
344{
345 LimitedIo limitedIo;
346 UdpFactory factory;
347
348 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
349
350 // face1 (on channel1) connects to face2 (on channel2, to be created)
351 shared_ptr<Face> face1;
352 unique_ptr<FaceHistory> history1;
353 factory.createFace(A::getFaceUri2(),
354 [&] (shared_ptr<Face> newFace) {
355 face1 = newFace;
356 history1.reset(new FaceHistory(*face1, limitedIo));
357 limitedIo.afterOp();
358 },
359 [] (const std::string& reason) { BOOST_ERROR(reason); });
360
361 limitedIo.run(1, time::seconds(1));
362 BOOST_REQUIRE(face1 != nullptr);
363 BOOST_CHECK_EQUAL(face1->getRemoteUri(), A::getFaceUri2());
364 BOOST_CHECK_EQUAL(face1->getLocalUri(), A::getFaceUri1());
365 BOOST_CHECK_EQUAL(face1->isLocal(), false); // UdpFace is never local
366 BOOST_CHECK_EQUAL(face1->getCounters().getNInBytes(), 0);
367 BOOST_CHECK_EQUAL(face1->getCounters().getNOutBytes(), 0);
368
369 // channel2 creation must be after face1 creation,
370 // otherwise channel2's endpoint would be prohibited
371 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2());
372 shared_ptr<Face> face2;
373 unique_ptr<FaceHistory> history2;
374 channel2->listen([&] (shared_ptr<Face> newFace) {
375 BOOST_CHECK(face2 == nullptr);
376 face2 = newFace;
377 history2.reset(new FaceHistory(*face2, limitedIo));
378 limitedIo.afterOp();
379 },
380 [] (const std::string& reason) { BOOST_ERROR(reason); });
381
382 limitedIo.run(1, time::seconds(1));
383 BOOST_CHECK(face2 == nullptr); // face2 shouldn't be created until face1 sends something
384
385 shared_ptr<Interest> interest1 = makeInterest("/I1");
386 shared_ptr<Interest> interest2 = makeInterest("/I2");
387 shared_ptr<Data> data1 = makeData("/D1");
388 shared_ptr<Data> data2 = makeData("/D2");
389
390 // face1 sends to channel2, creates face2
391 face1->sendInterest(*interest1);
392 face1->sendData(*data1);
393 face1->sendData(*data1);
394 face1->sendData(*data1);
395 size_t nBytesSent1 = interest1->wireEncode().size() + 3 * data1->wireEncode().size();
396
397 limitedIo.run(5, time::seconds(1)); // 1 accept, 4 receives
398
399 BOOST_REQUIRE(face2 != nullptr);
400 BOOST_CHECK_EQUAL(face2->getRemoteUri(), A::getFaceUri1());
401 BOOST_CHECK_EQUAL(face2->getLocalUri(), A::getFaceUri2());
402 BOOST_CHECK_EQUAL(face2->isLocal(), false); // UdpFace is never local
403 BOOST_CHECK_EQUAL(face2->getCounters().getNInBytes(), nBytesSent1);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700404 BOOST_CHECK_EQUAL(face2->getCounters().getNOutBytes(), 0);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700405
Chengyu Fan4381fb62015-01-14 11:37:04 -0700406 BOOST_REQUIRE_EQUAL(history2->receivedInterests.size(), 1);
407 BOOST_CHECK_EQUAL(history2->receivedInterests.front().getName(), interest1->getName());
408 BOOST_REQUIRE_EQUAL(history2->receivedData.size(), 3);
409 BOOST_CHECK_EQUAL(history2->receivedData.front().getName(), data1->getName());
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700410
Chengyu Fan4381fb62015-01-14 11:37:04 -0700411 // face2 sends to face1
412 face2->sendInterest(*interest2);
413 face2->sendInterest(*interest2);
414 face2->sendInterest(*interest2);
415 face2->sendData(*data2);
416 size_t nBytesSent2 = 3 * interest2->wireEncode().size() + data2->wireEncode().size();
Giulio Grassi624f6c62014-02-18 19:42:14 +0100417
Chengyu Fan4381fb62015-01-14 11:37:04 -0700418 limitedIo.run(4, time::seconds(1)); // 4 receives
Giulio Grassi624f6c62014-02-18 19:42:14 +0100419
Chengyu Fan4381fb62015-01-14 11:37:04 -0700420 BOOST_REQUIRE_EQUAL(history1->receivedInterests.size(), 3);
421 BOOST_CHECK_EQUAL(history1->receivedInterests.front().getName(), interest2->getName());
422 BOOST_REQUIRE_EQUAL(history1->receivedData.size(), 1);
423 BOOST_CHECK_EQUAL(history1->receivedData.front().getName(), data2->getName());
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700424
Chengyu Fan4381fb62015-01-14 11:37:04 -0700425 // counters
Junxiao Shi79494162014-04-02 18:25:11 -0700426 const FaceCounters& counters1 = face1->getCounters();
Chengyu Fan4381fb62015-01-14 11:37:04 -0700427 BOOST_CHECK_EQUAL(counters1.getNInInterests(), 3);
428 BOOST_CHECK_EQUAL(counters1.getNInDatas(), 1);
429 BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 1);
430 BOOST_CHECK_EQUAL(counters1.getNOutDatas(), 3);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700431 BOOST_CHECK_EQUAL(counters1.getNInBytes(), nBytesSent2);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700432 BOOST_CHECK_EQUAL(counters1.getNOutBytes(), nBytesSent1);
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000433
Junxiao Shi79494162014-04-02 18:25:11 -0700434 const FaceCounters& counters2 = face2->getCounters();
Chengyu Fan4381fb62015-01-14 11:37:04 -0700435 BOOST_CHECK_EQUAL(counters2.getNInInterests(), 1);
436 BOOST_CHECK_EQUAL(counters2.getNInDatas(), 3);
437 BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 3);
438 BOOST_CHECK_EQUAL(counters2.getNOutDatas(), 1);
439 BOOST_CHECK_EQUAL(counters2.getNInBytes(), nBytesSent1);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700440 BOOST_CHECK_EQUAL(counters2.getNOutBytes(), nBytesSent2);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000441}
Giulio Grassi624f6c62014-02-18 19:42:14 +0100442
Chengyu Fan4381fb62015-01-14 11:37:04 -0700443// channel accepting multiple incoming connections
444BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, EndToEndAddresses)
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000445{
Chengyu Fan4381fb62015-01-14 11:37:04 -0700446 LimitedIo limitedIo;
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000447 UdpFactory factory;
448
Chengyu Fan4381fb62015-01-14 11:37:04 -0700449 // channel1 is listening
450 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
451 std::vector<shared_ptr<Face>> faces1;
452 channel1->listen([&] (shared_ptr<Face> newFace) {
453 faces1.push_back(newFace);
454 limitedIo.afterOp();
455 },
456 [] (const std::string& reason) { BOOST_ERROR(reason); });
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000457
Chengyu Fan4381fb62015-01-14 11:37:04 -0700458 // face2 (on channel2) connects to channel1
459 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2());
460 BOOST_CHECK_NE(channel1, channel2);
461 shared_ptr<Face> face2;
462 boost::asio::ip::address ipAddress2 = boost::asio::ip::address::from_string(A::getLocalIp());
463 udp::Endpoint endpoint2(ipAddress2, boost::lexical_cast<uint16_t>(A::getPort1()));
464 channel2->connect(endpoint2,
465 [&] (shared_ptr<Face> newFace) {
466 face2 = newFace;
467 limitedIo.afterOp();
468 },
469 [] (const std::string& reason) { BOOST_ERROR(reason); });
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000470
Chengyu Fan4381fb62015-01-14 11:37:04 -0700471 limitedIo.run(1, time::seconds(1)); // 1 create (on channel2)
472 BOOST_REQUIRE(face2 != nullptr);
473 BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face2 sends something
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000474
Chengyu Fan4381fb62015-01-14 11:37:04 -0700475 // face3 (on channel3) connects to channel1
476 shared_ptr<UdpChannel> channel3 = factory.createChannel(A::getLocalIp(), A::getPort3());
477 BOOST_CHECK_NE(channel1, channel3);
478 shared_ptr<Face> face3;
479 boost::asio::ip::address ipAddress3 = boost::asio::ip::address::from_string(A::getLocalIp());
480 udp::Endpoint endpoint3(ipAddress3, boost::lexical_cast<uint16_t>(A::getPort1()));
481 channel3->connect(endpoint3,
482 [&] (shared_ptr<Face> newFace) {
483 face3 = newFace;
484 limitedIo.afterOp();
485 },
486 [] (const std::string& reason) { BOOST_ERROR(reason); });
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000487
Chengyu Fan4381fb62015-01-14 11:37:04 -0700488 limitedIo.run(1, time::seconds(1)); // 1 create (on channel3)
489 BOOST_REQUIRE(face3 != nullptr);
490 BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face3 sends something
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000491
Chengyu Fan4381fb62015-01-14 11:37:04 -0700492 // face2 sends to channel1
493 shared_ptr<Interest> interest2 = makeInterest("/I2");
494 face2->sendInterest(*interest2);
495 limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1)
496 BOOST_REQUIRE_EQUAL(faces1.size(), 1);
497 BOOST_CHECK_EQUAL(channel1->size(), 1);
498 BOOST_CHECK_EQUAL(faces1.at(0)->getRemoteUri(), A::getFaceUri2());
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000499
Chengyu Fan4381fb62015-01-14 11:37:04 -0700500 // face3 sends to channel1
501 shared_ptr<Data> data3 = makeData("/D3");
502 face3->sendData(*data3);
503 limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1)
504 BOOST_REQUIRE_EQUAL(faces1.size(), 2);
505 BOOST_CHECK_EQUAL(channel1->size(), 2);
506 BOOST_CHECK_EQUAL(faces1.at(1)->getRemoteUri(), A::getFaceUri3());
Giulio Grassi624f6c62014-02-18 19:42:14 +0100507}
508
Chengyu Fan4381fb62015-01-14 11:37:04 -0700509// manually close a face
510BOOST_AUTO_TEST_CASE_TEMPLATE(ManualClose, A, EndToEndAddresses)
Giulio Grassi624f6c62014-02-18 19:42:14 +0100511{
Chengyu Fan4381fb62015-01-14 11:37:04 -0700512 LimitedIo limitedIo;
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700513 UdpFactory factory;
Giulio Grassi624f6c62014-02-18 19:42:14 +0100514
Chengyu Fan4381fb62015-01-14 11:37:04 -0700515 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
516 shared_ptr<Face> face1;
517 unique_ptr<FaceHistory> history1;
518 factory.createFace(A::getFaceUri2(),
519 [&] (shared_ptr<Face> newFace) {
520 face1 = newFace;
521 history1.reset(new FaceHistory(*face1, limitedIo));
522 limitedIo.afterOp();
523 },
524 [] (const std::string& reason) { BOOST_ERROR(reason); });
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700525
Chengyu Fan4381fb62015-01-14 11:37:04 -0700526 limitedIo.run(1, time::milliseconds(100));
527 BOOST_REQUIRE(face1 != nullptr);
528 BOOST_CHECK_EQUAL(channel1->size(), 1);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700529
Chengyu Fan4381fb62015-01-14 11:37:04 -0700530 face1->close();
531 getGlobalIoService().poll();
532 BOOST_CHECK_EQUAL(history1->failures.size(), 1);
Giulio Grassi69871f02014-03-09 16:14:44 +0100533 BOOST_CHECK_EQUAL(channel1->size(), 0);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700534}
Junxiao Shi79494162014-04-02 18:25:11 -0700535
Chengyu Fan4381fb62015-01-14 11:37:04 -0700536// automatically close an idle incoming face
537BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses)
538{
539 LimitedIo limitedIo;
540 UdpFactory factory;
541
542 // channel1 is listening
543 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1(),
544 time::seconds(2));
545 shared_ptr<Face> face1;
546 unique_ptr<FaceHistory> history1;
547 channel1->listen([&] (shared_ptr<Face> newFace) {
548 BOOST_CHECK(face1 == nullptr);
549 face1 = newFace;
550 history1.reset(new FaceHistory(*face1, limitedIo));
551 limitedIo.afterOp();
552 },
553 [] (const std::string& reason) { BOOST_ERROR(reason); });
554
555 // face2 (on channel2) connects to channel1
556 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2(),
557 time::seconds(2));
558 shared_ptr<Face> face2;
559 unique_ptr<FaceHistory> history2;
560 boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(A::getLocalIp());
561 udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(A::getPort1()));
562 channel2->connect(endpoint,
563 [&] (shared_ptr<Face> newFace) {
564 face2 = newFace;
565 history2.reset(new FaceHistory(*face2, limitedIo));
566 limitedIo.afterOp();
567 },
568 [] (const std::string& reason) { BOOST_ERROR(reason); });
569
570 limitedIo.run(1, time::milliseconds(100)); // 1 create (on channel2)
571 BOOST_REQUIRE(face2 != nullptr);
572 BOOST_CHECK_EQUAL(face2->isOnDemand(), false);
Davide Pesavento94279412015-02-27 01:29:32 +0100573 BOOST_CHECK_EQUAL(face2->isMultiAccess(), false);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700574
575 // face2 sends to channel1, creates face1
576 shared_ptr<Interest> interest2 = makeInterest("/I2");
577 face2->sendInterest(*interest2);
578
579 limitedIo.run(2, time::seconds(1)); // 1 accept (on channel1), 1 receive (on face1)
Giulio Grassi69871f02014-03-09 16:14:44 +0100580 BOOST_CHECK_EQUAL(channel1->size(), 1);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700581 BOOST_REQUIRE(face1 != nullptr);
582 BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
Davide Pesavento94279412015-02-27 01:29:32 +0100583 BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
Junxiao Shi79494162014-04-02 18:25:11 -0700584
Chengyu Fan4381fb62015-01-14 11:37:04 -0700585 limitedIo.defer(time::seconds(1));
586 BOOST_CHECK_EQUAL(history1->failures.size(), 0); // face1 is not idle
587 BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed
Giulio Grassi69871f02014-03-09 16:14:44 +0100588
Chengyu Fan4381fb62015-01-14 11:37:04 -0700589 limitedIo.defer(time::seconds(4));
590 BOOST_CHECK_EQUAL(history1->failures.size(), 1); // face1 is idle and automatically closed
591 BOOST_CHECK_EQUAL(channel1->size(), 0);
592 BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed
Giulio Grassi69871f02014-03-09 16:14:44 +0100593}
594
Alexander Afanasyev70aaf8a2014-12-13 00:44:22 -0800595class FakeNetworkInterfaceFixture : public BaseFixture
596{
597public:
598 FakeNetworkInterfaceFixture()
599 {
600 using namespace boost::asio::ip;
601
602 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
603
604 fakeInterfaces->push_back(
605 NetworkInterfaceInfo {0, "eth0",
606 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
607 {address_v4::from_string("0.0.0.0")},
608 {address_v6::from_string("::")},
609 address_v4(),
610 IFF_UP});
611 fakeInterfaces->push_back(
612 NetworkInterfaceInfo {1, "eth0",
613 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
614 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
615 {},
616 address_v4::from_string("192.168.2.255"),
617 0});
618 fakeInterfaces->push_back(
619 NetworkInterfaceInfo {2, "eth1",
620 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
621 {address_v4::from_string("198.51.100.1")},
622 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
623 address_v4::from_string("198.51.100.255"),
624 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
625
626 setDebugNetworkInterfaces(fakeInterfaces);
627 }
628
629 ~FakeNetworkInterfaceFixture()
630 {
631 setDebugNetworkInterfaces(nullptr);
632 }
633};
634
635BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
636{
637 using namespace boost::asio::ip;
638
639 UdpFactory factory;
640 factory.prohibitEndpoint(udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
641 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
642 BOOST_CHECK((factory.m_prohibitedEndpoints ==
643 std::set<udp::Endpoint> {
644 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
645 }));
646
647 factory.m_prohibitedEndpoints.clear();
648 factory.prohibitEndpoint(udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
649 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
650 BOOST_CHECK((factory.m_prohibitedEndpoints ==
651 std::set<udp::Endpoint> {
652 udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048),
653 }));
654
655 factory.m_prohibitedEndpoints.clear();
656 factory.prohibitEndpoint(udp::Endpoint(address_v4(), 1024));
657 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 6);
658 BOOST_CHECK((factory.m_prohibitedEndpoints ==
659 std::set<udp::Endpoint> {
660 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
661 udp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
662 udp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
663 udp::Endpoint(address_v4::from_string("198.51.100.255"), 1024),
664 udp::Endpoint(address_v4::from_string("255.255.255.255"), 1024),
665 udp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
666 }));
667
668 factory.m_prohibitedEndpoints.clear();
669 factory.prohibitEndpoint(udp::Endpoint(address_v6(), 2048));
670 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
671 BOOST_CHECK((factory.m_prohibitedEndpoints ==
672 std::set<udp::Endpoint> {
673 udp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
674 udp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
675 udp::Endpoint(address_v6::from_string("::"), 2048),
676 }));
677}
678
Giulio Grassi624f6c62014-02-18 19:42:14 +0100679BOOST_AUTO_TEST_SUITE_END()
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700680
Giulio Grassi624f6c62014-02-18 19:42:14 +0100681} // namespace tests
682} // namespace nfd