blob: d38c908ba544f6d6ed5d0a21f0dfd450add55610 [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"
Giulio Grassi624f6c62014-02-18 19:42:14 +010027#include "face/udp-factory.hpp"
Junxiao Shi7e2413b2014-03-02 11:15:09 -070028
Davide Pesavento6ad890a2015-03-09 03:43:17 +010029#include "core/network-interface.hpp"
Junxiao Shi7e2413b2014-03-02 11:15:09 -070030#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070031#include "tests/limited-io.hpp"
Chengyu Fan4381fb62015-01-14 11:37:04 -070032#include "face-history.hpp"
Giulio Grassi624f6c62014-02-18 19:42:14 +010033
34namespace nfd {
35namespace tests {
36
Yukai Tu0a49d342015-09-13 12:54:22 +080037BOOST_AUTO_TEST_SUITE(Face)
38BOOST_FIXTURE_TEST_SUITE(TestUdp, BaseFixture)
39
40using nfd::Face;
Giulio Grassi624f6c62014-02-18 19:42:14 +010041
Steve DiBenedettoef04f272014-06-04 14:28:31 -060042BOOST_AUTO_TEST_CASE(GetChannels)
43{
44 UdpFactory factory;
45 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
46
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020047 std::vector<shared_ptr<const Channel>> expectedChannels;
Steve DiBenedettoef04f272014-06-04 14:28:31 -060048 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
49 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
50 expectedChannels.push_back(factory.createChannel("::1", "20071"));
51
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020052 for (const auto& i : factory.getChannels()) {
53 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
54 BOOST_REQUIRE(pos != expectedChannels.end());
55 expectedChannels.erase(pos);
56 }
Steve DiBenedettoef04f272014-06-04 14:28:31 -060057
58 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
59}
60
Giulio Grassi624f6c62014-02-18 19:42:14 +010061class FactoryErrorCheck : protected BaseFixture
62{
63public:
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070064 bool
65 isTheSameMulticastEndpoint(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010066 return strcmp(e.what(),
67 "Cannot create the requested UDP unicast channel, local "
68 "endpoint is already allocated for a UDP multicast face") == 0;
69 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -070070
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070071 bool
72 isNotMulticastAddress(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010073 return strcmp(e.what(),
74 "Cannot create the requested UDP multicast face, "
75 "the multicast group given as input is not a multicast address") == 0;
76 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -070077
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070078 bool
79 isTheSameUnicastEndpoint(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010080 return strcmp(e.what(),
81 "Cannot create the requested UDP multicast face, local "
82 "endpoint is already allocated for a UDP unicast channel") == 0;
83 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -070084
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070085 bool
86 isLocalEndpointOnDifferentGroup(const UdpFactory::Error& e) {
Giulio Grassi624f6c62014-02-18 19:42:14 +010087 return strcmp(e.what(),
88 "Cannot create the requested UDP multicast face, local "
89 "endpoint is already allocated for a UDP multicast face "
90 "on a different multicast group") == 0;
91 }
92};
Junxiao Shi7e2413b2014-03-02 11:15:09 -070093
Giulio Grassi624f6c62014-02-18 19:42:14 +010094BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
95{
96 using boost::asio::ip::udp;
Junxiao Shi7e2413b2014-03-02 11:15:09 -070097
Giulio Grassi624f6c62014-02-18 19:42:14 +010098 UdpFactory factory = UdpFactory();
Junxiao Shi7e2413b2014-03-02 11:15:09 -070099
Giulio Grassi624f6c62014-02-18 19:42:14 +0100100 //to instantiate multicast face on a specific ip address, change interfaceIp
101 std::string interfaceIp = "0.0.0.0";
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700102
Giulio Grassi624f6c62014-02-18 19:42:14 +0100103 shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
104 shared_ptr<UdpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
105 BOOST_CHECK_EQUAL(channel1, channel1a);
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700106 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700107
Giulio Grassi624f6c62014-02-18 19:42:14 +0100108 shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
109 BOOST_CHECK_NE(channel1, channel2);
110
111 shared_ptr<UdpChannel> channel3 = factory.createChannel(interfaceIp, "20070");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700112
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700113 shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20071");
114 BOOST_CHECK_NE(channel2, channel4);
115 BOOST_CHECK_EQUAL(channel4->getUri().toString(), "udp6://[::1]:20071");
116
Giulio Grassi624f6c62014-02-18 19:42:14 +0100117 //same endpoint of a unicast channel
Davide Pesavento94279412015-02-27 01:29:32 +0100118 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "224.0.0.1", "20070"),
119 UdpFactory::Error, isTheSameUnicastEndpoint);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700120
Davide Pesavento94279412015-02-27 01:29:32 +0100121 auto multicastFace1 = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
122 auto multicastFace1a = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
Giulio Grassi624f6c62014-02-18 19:42:14 +0100123 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
Davide Pesavento94279412015-02-27 01:29:32 +0100124 BOOST_CHECK_EQUAL(multicastFace1->isLocal(), false);
Yukai Tu0a49d342015-09-13 12:54:22 +0800125 BOOST_CHECK_EQUAL(multicastFace1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
Davide Pesavento94279412015-02-27 01:29:32 +0100126 BOOST_CHECK_EQUAL(multicastFace1->isMultiAccess(), true);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700127
Giulio Grassi624f6c62014-02-18 19:42:14 +0100128 //same endpoint of a multicast face
129 BOOST_CHECK_EXCEPTION(factory.createChannel(interfaceIp, "20072"),
Davide Pesavento94279412015-02-27 01:29:32 +0100130 UdpFactory::Error, isTheSameMulticastEndpoint);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700131
Giulio Grassi624f6c62014-02-18 19:42:14 +0100132 //same multicast endpoint, different group
Davide Pesavento94279412015-02-27 01:29:32 +0100133 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "224.0.0.42", "20072"),
134 UdpFactory::Error, isLocalEndpointOnDifferentGroup);
Giulio Grassi624f6c62014-02-18 19:42:14 +0100135
Davide Pesavento94279412015-02-27 01:29:32 +0100136 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp, "192.168.10.15", "20025"),
137 UdpFactory::Error, isNotMulticastAddress);
Giulio Grassi624f6c62014-02-18 19:42:14 +0100138
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700139
Giulio Grassi624f6c62014-02-18 19:42:14 +0100140// //Test commented because it required to be run in a machine that can resolve ipv6 query
141// shared_ptr<UdpChannel> channel1v6 = factory.createChannel(//"::1",
142// "fe80::5e96:9dff:fe7d:9c8d%en1",
143// //"fe80::aa54:b2ff:fe08:27b8%wlan0",
144// "20070");
145//
146// //the creation of multicastFace2 works properly. It has been disable because it needs an IP address of
147// //an available network interface (different from the first one used)
148// shared_ptr<MulticastUdpFace> multicastFace2 = factory.createMulticastFace("192.168.1.17",
149// "224.0.0.1",
150// "20073");
151// BOOST_CHECK_NE(multicastFace1, multicastFace2);
152//
153//
154// //ipv6 - work in progress
155// shared_ptr<MulticastUdpFace> multicastFace3 = factory.createMulticastFace("fe80::5e96:9dff:fe7d:9c8d%en1",
156// "FF01:0:0:0:0:0:0:2",
157// "20073");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700158//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100159// shared_ptr<MulticastUdpFace> multicastFace4 = factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
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// BOOST_CHECK_EQUAL(multicastFace3, multicastFace4);
164//
165// shared_ptr<MulticastUdpFace> multicastFace5 = factory.createMulticastFace("::1",
166// "FF01:0:0:0:0:0:0:2",
167// "20073");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700168//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100169// BOOST_CHECK_NE(multicastFace3, multicastFace5);
170//
171// //same local ipv6 endpoint for a different multicast group
172// BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
173// "FE01:0:0:0:0:0:0:2",
174// "20073"),
175// UdpFactory::Error);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700176//
Giulio Grassi624f6c62014-02-18 19:42:14 +0100177// //same local ipv6 (expect for th port number) endpoint for a different multicast group
178// BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
179// "FE01:0:0:0:0:0:0:2",
180// "20075"),
181// UdpFactory::Error);
182//
183// BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
184// "FE12:0:0:0:0:0:0:2",
185// "20075"),
186// UdpFactory::Error);
187//
188// //not a multicast ipv6
189// BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
190// "A112:0:0:0:0:0:0:2",
191// "20075"),
192// UdpFactory::Error);
Giulio Grassi624f6c62014-02-18 19:42:14 +0100193}
194
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -0700195class FaceCreateFixture : protected BaseFixture
196{
197public:
198 void
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -0700199 checkError(const std::string& errorActual, const std::string& errorExpected)
200 {
201 BOOST_CHECK_EQUAL(errorActual, errorExpected);
202 }
203
204 void
205 failIfError(const std::string& errorActual)
206 {
207 BOOST_FAIL("No error expected, but got: [" << errorActual << "]");
208 }
209};
210
211BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
212{
213 UdpFactory factory = UdpFactory();
214
Chengyu Fan4381fb62015-01-14 11:37:04 -0700215 factory.createFace(FaceUri("udp4://127.0.0.1:6363"),
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800216 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
217 bind([]{}),
Chengyu Fan4381fb62015-01-14 11:37:04 -0700218 bind(&FaceCreateFixture::checkError, this, _1,
219 "No channels available to connect to 127.0.0.1:6363"));
Giulio Grassi624f6c62014-02-18 19:42:14 +0100220
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000221 factory.createChannel("127.0.0.1", "20071");
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700222
Giulio Grassi624f6c62014-02-18 19:42:14 +0100223 factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800224 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
225 bind([]{}),
Chengyu Fan4381fb62015-01-14 11:37:04 -0700226 bind(&FaceCreateFixture::failIfError, this, _1));
Yukai Tu375dcb02015-08-01 13:04:43 +0800227 //test the upgrade
228 factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
229 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
230 bind([]{}),
231 bind(&FaceCreateFixture::failIfError, this, _1));
232
233 factory.createFace(FaceUri("udp4://127.0.0.1:20072"),
234 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
235 bind([]{}),
236 bind(&FaceCreateFixture::failIfError, this, _1));
Chengyu Fan4381fb62015-01-14 11:37:04 -0700237}
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700238
Yukai Tu375dcb02015-08-01 13:04:43 +0800239BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800240{
241 UdpFactory factory;
242
243 factory.createChannel("127.0.0.1", "20070");
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800244
245 BOOST_CHECK_THROW(factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800246 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
247 bind([]{}),
248 bind([]{})),
249 ProtocolFactory::Error);
250}
251
Chengyu Fan4381fb62015-01-14 11:37:04 -0700252class EndToEndIpv4
253{
254public:
255 static const std::string
256 getScheme()
257 {
258 return "udp4";
259 }
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700260
Chengyu Fan4381fb62015-01-14 11:37:04 -0700261 static const std::string
262 getLocalIp()
263 {
264 return "127.0.0.1";
265 }
Giulio Grassi624f6c62014-02-18 19:42:14 +0100266
Chengyu Fan4381fb62015-01-14 11:37:04 -0700267 static const std::string
268 getPort1()
269 {
270 return "20071";
271 }
272
273 static const std::string
274 getPort2()
275 {
276 return "20072";
277 }
278
279 static const std::string
280 getPort3()
281 {
282 return "20073";
283 }
284
285 static const FaceUri
286 getFaceUri1()
287 {
288 return FaceUri("udp4://127.0.0.1:20071");
289 }
290
291 static const FaceUri
292 getFaceUri2()
293 {
294 return FaceUri("udp4://127.0.0.1:20072");
295 }
296
297 static const FaceUri
298 getFaceUri3()
299 {
300 return FaceUri("udp4://127.0.0.1:20073");
301 }
302};
303
304class EndToEndIpv6
305{
306public:
307 static const std::string
308 getScheme()
309 {
310 return "udp6";
311 }
312
313 static const std::string
314 getLocalIp()
315 {
316 return "::1";
317 }
318
319 static const std::string
320 getPort1()
321 {
322 return "20071";
323 }
324
325 static const std::string
326 getPort2()
327 {
328 return "20072";
329 }
330
331 static const std::string
332 getPort3()
333 {
334 return "20073";
335 }
336
337 static const FaceUri
338 getFaceUri1()
339 {
340 return FaceUri("udp6://[::1]:20071");
341 }
342
343 static const FaceUri
344 getFaceUri2()
345 {
346 return FaceUri("udp6://[::1]:20072");
347 }
348
349 static const FaceUri
350 getFaceUri3()
351 {
352 return FaceUri("udp6://[::1]:20073");
353 }
354};
355
356typedef boost::mpl::list<EndToEndIpv4, EndToEndIpv6> EndToEndAddresses;
357
358// end to end communication
359BOOST_AUTO_TEST_CASE_TEMPLATE(EndToEnd, A, EndToEndAddresses)
360{
361 LimitedIo limitedIo;
362 UdpFactory factory;
363
364 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
365
366 // face1 (on channel1) connects to face2 (on channel2, to be created)
367 shared_ptr<Face> face1;
368 unique_ptr<FaceHistory> history1;
369 factory.createFace(A::getFaceUri2(),
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800370 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Chengyu Fan4381fb62015-01-14 11:37:04 -0700371 [&] (shared_ptr<Face> newFace) {
372 face1 = newFace;
373 history1.reset(new FaceHistory(*face1, limitedIo));
374 limitedIo.afterOp();
375 },
376 [] (const std::string& reason) { BOOST_ERROR(reason); });
377
378 limitedIo.run(1, time::seconds(1));
379 BOOST_REQUIRE(face1 != nullptr);
380 BOOST_CHECK_EQUAL(face1->getRemoteUri(), A::getFaceUri2());
381 BOOST_CHECK_EQUAL(face1->getLocalUri(), A::getFaceUri1());
382 BOOST_CHECK_EQUAL(face1->isLocal(), false); // UdpFace is never local
Junxiao Shida93f1f2015-11-11 06:13:16 -0700383 BOOST_CHECK_EQUAL(face1->getCounters().nInBytes, 0);
384 BOOST_CHECK_EQUAL(face1->getCounters().nOutBytes, 0);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700385
386 // channel2 creation must be after face1 creation,
387 // otherwise channel2's endpoint would be prohibited
388 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2());
389 shared_ptr<Face> face2;
390 unique_ptr<FaceHistory> history2;
391 channel2->listen([&] (shared_ptr<Face> newFace) {
392 BOOST_CHECK(face2 == nullptr);
393 face2 = newFace;
394 history2.reset(new FaceHistory(*face2, limitedIo));
395 limitedIo.afterOp();
396 },
397 [] (const std::string& reason) { BOOST_ERROR(reason); });
398
399 limitedIo.run(1, time::seconds(1));
400 BOOST_CHECK(face2 == nullptr); // face2 shouldn't be created until face1 sends something
401
402 shared_ptr<Interest> interest1 = makeInterest("/I1");
403 shared_ptr<Interest> interest2 = makeInterest("/I2");
404 shared_ptr<Data> data1 = makeData("/D1");
405 shared_ptr<Data> data2 = makeData("/D2");
406
407 // face1 sends to channel2, creates face2
408 face1->sendInterest(*interest1);
409 face1->sendData(*data1);
410 face1->sendData(*data1);
411 face1->sendData(*data1);
412 size_t nBytesSent1 = interest1->wireEncode().size() + 3 * data1->wireEncode().size();
413
414 limitedIo.run(5, time::seconds(1)); // 1 accept, 4 receives
415
416 BOOST_REQUIRE(face2 != nullptr);
417 BOOST_CHECK_EQUAL(face2->getRemoteUri(), A::getFaceUri1());
418 BOOST_CHECK_EQUAL(face2->getLocalUri(), A::getFaceUri2());
419 BOOST_CHECK_EQUAL(face2->isLocal(), false); // UdpFace is never local
Junxiao Shida93f1f2015-11-11 06:13:16 -0700420 BOOST_CHECK_EQUAL(face2->getCounters().nInBytes, nBytesSent1);
421 BOOST_CHECK_EQUAL(face2->getCounters().nOutBytes, 0);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700422
Chengyu Fan4381fb62015-01-14 11:37:04 -0700423 BOOST_REQUIRE_EQUAL(history2->receivedInterests.size(), 1);
424 BOOST_CHECK_EQUAL(history2->receivedInterests.front().getName(), interest1->getName());
425 BOOST_REQUIRE_EQUAL(history2->receivedData.size(), 3);
426 BOOST_CHECK_EQUAL(history2->receivedData.front().getName(), data1->getName());
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700427
Chengyu Fan4381fb62015-01-14 11:37:04 -0700428 // face2 sends to face1
429 face2->sendInterest(*interest2);
430 face2->sendInterest(*interest2);
431 face2->sendInterest(*interest2);
432 face2->sendData(*data2);
433 size_t nBytesSent2 = 3 * interest2->wireEncode().size() + data2->wireEncode().size();
Giulio Grassi624f6c62014-02-18 19:42:14 +0100434
Chengyu Fan4381fb62015-01-14 11:37:04 -0700435 limitedIo.run(4, time::seconds(1)); // 4 receives
Giulio Grassi624f6c62014-02-18 19:42:14 +0100436
Chengyu Fan4381fb62015-01-14 11:37:04 -0700437 BOOST_REQUIRE_EQUAL(history1->receivedInterests.size(), 3);
438 BOOST_CHECK_EQUAL(history1->receivedInterests.front().getName(), interest2->getName());
439 BOOST_REQUIRE_EQUAL(history1->receivedData.size(), 1);
440 BOOST_CHECK_EQUAL(history1->receivedData.front().getName(), data2->getName());
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700441
Chengyu Fan4381fb62015-01-14 11:37:04 -0700442 // counters
Junxiao Shida93f1f2015-11-11 06:13:16 -0700443 const face::FaceCounters& counters1 = face1->getCounters();
444 BOOST_CHECK_EQUAL(counters1.nInInterests, 3);
445 BOOST_CHECK_EQUAL(counters1.nInData, 1);
446 BOOST_CHECK_EQUAL(counters1.nOutInterests, 1);
447 BOOST_CHECK_EQUAL(counters1.nOutData, 3);
448 BOOST_CHECK_EQUAL(counters1.nInBytes, nBytesSent2);
449 BOOST_CHECK_EQUAL(counters1.nOutBytes, nBytesSent1);
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000450
Junxiao Shida93f1f2015-11-11 06:13:16 -0700451 const face::FaceCounters& counters2 = face2->getCounters();
452 BOOST_CHECK_EQUAL(counters2.nInInterests, 1);
453 BOOST_CHECK_EQUAL(counters2.nInData, 3);
454 BOOST_CHECK_EQUAL(counters2.nOutInterests, 3);
455 BOOST_CHECK_EQUAL(counters2.nOutData, 1);
456 BOOST_CHECK_EQUAL(counters2.nInBytes, nBytesSent1);
457 BOOST_CHECK_EQUAL(counters2.nOutBytes, nBytesSent2);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000458}
Giulio Grassi624f6c62014-02-18 19:42:14 +0100459
Chengyu Fan4381fb62015-01-14 11:37:04 -0700460// channel accepting multiple incoming connections
461BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, EndToEndAddresses)
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000462{
Chengyu Fan4381fb62015-01-14 11:37:04 -0700463 LimitedIo limitedIo;
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000464 UdpFactory factory;
465
Chengyu Fan4381fb62015-01-14 11:37:04 -0700466 // channel1 is listening
467 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
468 std::vector<shared_ptr<Face>> faces1;
469 channel1->listen([&] (shared_ptr<Face> newFace) {
470 faces1.push_back(newFace);
471 limitedIo.afterOp();
472 },
473 [] (const std::string& reason) { BOOST_ERROR(reason); });
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000474
Chengyu Fan4381fb62015-01-14 11:37:04 -0700475 // face2 (on channel2) connects to channel1
476 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2());
477 BOOST_CHECK_NE(channel1, channel2);
478 shared_ptr<Face> face2;
479 boost::asio::ip::address ipAddress2 = boost::asio::ip::address::from_string(A::getLocalIp());
480 udp::Endpoint endpoint2(ipAddress2, boost::lexical_cast<uint16_t>(A::getPort1()));
481 channel2->connect(endpoint2,
Yukai Tu375dcb02015-08-01 13:04:43 +0800482 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Chengyu Fan4381fb62015-01-14 11:37:04 -0700483 [&] (shared_ptr<Face> newFace) {
484 face2 = newFace;
485 limitedIo.afterOp();
486 },
487 [] (const std::string& reason) { BOOST_ERROR(reason); });
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000488
Chengyu Fan4381fb62015-01-14 11:37:04 -0700489 limitedIo.run(1, time::seconds(1)); // 1 create (on channel2)
490 BOOST_REQUIRE(face2 != nullptr);
491 BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face2 sends something
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000492
Chengyu Fan4381fb62015-01-14 11:37:04 -0700493 // face3 (on channel3) connects to channel1
494 shared_ptr<UdpChannel> channel3 = factory.createChannel(A::getLocalIp(), A::getPort3());
495 BOOST_CHECK_NE(channel1, channel3);
496 shared_ptr<Face> face3;
497 boost::asio::ip::address ipAddress3 = boost::asio::ip::address::from_string(A::getLocalIp());
498 udp::Endpoint endpoint3(ipAddress3, boost::lexical_cast<uint16_t>(A::getPort1()));
499 channel3->connect(endpoint3,
Yukai Tu375dcb02015-08-01 13:04:43 +0800500 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Chengyu Fan4381fb62015-01-14 11:37:04 -0700501 [&] (shared_ptr<Face> newFace) {
502 face3 = newFace;
503 limitedIo.afterOp();
504 },
505 [] (const std::string& reason) { BOOST_ERROR(reason); });
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000506
Chengyu Fan4381fb62015-01-14 11:37:04 -0700507 limitedIo.run(1, time::seconds(1)); // 1 create (on channel3)
508 BOOST_REQUIRE(face3 != nullptr);
509 BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face3 sends something
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000510
Chengyu Fan4381fb62015-01-14 11:37:04 -0700511 // face2 sends to channel1
512 shared_ptr<Interest> interest2 = makeInterest("/I2");
513 face2->sendInterest(*interest2);
514 limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1)
515 BOOST_REQUIRE_EQUAL(faces1.size(), 1);
516 BOOST_CHECK_EQUAL(channel1->size(), 1);
517 BOOST_CHECK_EQUAL(faces1.at(0)->getRemoteUri(), A::getFaceUri2());
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000518
Chengyu Fan4381fb62015-01-14 11:37:04 -0700519 // face3 sends to channel1
520 shared_ptr<Data> data3 = makeData("/D3");
521 face3->sendData(*data3);
522 limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1)
523 BOOST_REQUIRE_EQUAL(faces1.size(), 2);
524 BOOST_CHECK_EQUAL(channel1->size(), 2);
525 BOOST_CHECK_EQUAL(faces1.at(1)->getRemoteUri(), A::getFaceUri3());
Giulio Grassi624f6c62014-02-18 19:42:14 +0100526}
527
Chengyu Fan4381fb62015-01-14 11:37:04 -0700528// manually close a face
529BOOST_AUTO_TEST_CASE_TEMPLATE(ManualClose, A, EndToEndAddresses)
Giulio Grassi624f6c62014-02-18 19:42:14 +0100530{
Chengyu Fan4381fb62015-01-14 11:37:04 -0700531 LimitedIo limitedIo;
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700532 UdpFactory factory;
Giulio Grassi624f6c62014-02-18 19:42:14 +0100533
Chengyu Fan4381fb62015-01-14 11:37:04 -0700534 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1());
535 shared_ptr<Face> face1;
536 unique_ptr<FaceHistory> history1;
537 factory.createFace(A::getFaceUri2(),
Yukai Tu7c90e6d2015-07-11 12:21:46 +0800538 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Chengyu Fan4381fb62015-01-14 11:37:04 -0700539 [&] (shared_ptr<Face> newFace) {
540 face1 = newFace;
541 history1.reset(new FaceHistory(*face1, limitedIo));
542 limitedIo.afterOp();
543 },
544 [] (const std::string& reason) { BOOST_ERROR(reason); });
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700545
Chengyu Fan4381fb62015-01-14 11:37:04 -0700546 limitedIo.run(1, time::milliseconds(100));
547 BOOST_REQUIRE(face1 != nullptr);
548 BOOST_CHECK_EQUAL(channel1->size(), 1);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700549
Chengyu Fan4381fb62015-01-14 11:37:04 -0700550 face1->close();
551 getGlobalIoService().poll();
552 BOOST_CHECK_EQUAL(history1->failures.size(), 1);
Giulio Grassi69871f02014-03-09 16:14:44 +0100553 BOOST_CHECK_EQUAL(channel1->size(), 0);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700554}
Junxiao Shi79494162014-04-02 18:25:11 -0700555
Chengyu Fan4381fb62015-01-14 11:37:04 -0700556// automatically close an idle incoming face
557BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses)
558{
559 LimitedIo limitedIo;
560 UdpFactory factory;
561
562 // channel1 is listening
563 shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1(),
564 time::seconds(2));
565 shared_ptr<Face> face1;
566 unique_ptr<FaceHistory> history1;
567 channel1->listen([&] (shared_ptr<Face> newFace) {
568 BOOST_CHECK(face1 == nullptr);
569 face1 = newFace;
570 history1.reset(new FaceHistory(*face1, limitedIo));
571 limitedIo.afterOp();
572 },
573 [] (const std::string& reason) { BOOST_ERROR(reason); });
574
575 // face2 (on channel2) connects to channel1
576 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2(),
577 time::seconds(2));
578 shared_ptr<Face> face2;
579 unique_ptr<FaceHistory> history2;
580 boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(A::getLocalIp());
581 udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(A::getPort1()));
582 channel2->connect(endpoint,
Yukai Tu375dcb02015-08-01 13:04:43 +0800583 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Chengyu Fan4381fb62015-01-14 11:37:04 -0700584 [&] (shared_ptr<Face> newFace) {
585 face2 = newFace;
586 history2.reset(new FaceHistory(*face2, limitedIo));
587 limitedIo.afterOp();
588 },
589 [] (const std::string& reason) { BOOST_ERROR(reason); });
590
591 limitedIo.run(1, time::milliseconds(100)); // 1 create (on channel2)
592 BOOST_REQUIRE(face2 != nullptr);
Yukai Tu731f0d72015-07-04 11:14:44 +0800593 BOOST_CHECK_EQUAL(face2->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
Davide Pesavento94279412015-02-27 01:29:32 +0100594 BOOST_CHECK_EQUAL(face2->isMultiAccess(), false);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700595
596 // face2 sends to channel1, creates face1
597 shared_ptr<Interest> interest2 = makeInterest("/I2");
598 face2->sendInterest(*interest2);
599
600 limitedIo.run(2, time::seconds(1)); // 1 accept (on channel1), 1 receive (on face1)
Giulio Grassi69871f02014-03-09 16:14:44 +0100601 BOOST_CHECK_EQUAL(channel1->size(), 1);
Chengyu Fan4381fb62015-01-14 11:37:04 -0700602 BOOST_REQUIRE(face1 != nullptr);
Yukai Tu731f0d72015-07-04 11:14:44 +0800603 BOOST_CHECK_EQUAL(face1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
Davide Pesavento94279412015-02-27 01:29:32 +0100604 BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
Junxiao Shi79494162014-04-02 18:25:11 -0700605
Chengyu Fan4381fb62015-01-14 11:37:04 -0700606 limitedIo.defer(time::seconds(1));
607 BOOST_CHECK_EQUAL(history1->failures.size(), 0); // face1 is not idle
608 BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed
Giulio Grassi69871f02014-03-09 16:14:44 +0100609
Chengyu Fan4381fb62015-01-14 11:37:04 -0700610 limitedIo.defer(time::seconds(4));
611 BOOST_CHECK_EQUAL(history1->failures.size(), 1); // face1 is idle and automatically closed
612 BOOST_CHECK_EQUAL(channel1->size(), 0);
613 BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed
Giulio Grassi69871f02014-03-09 16:14:44 +0100614}
615
Alexander Afanasyev70aaf8a2014-12-13 00:44:22 -0800616class FakeNetworkInterfaceFixture : public BaseFixture
617{
618public:
619 FakeNetworkInterfaceFixture()
620 {
621 using namespace boost::asio::ip;
622
623 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
624
625 fakeInterfaces->push_back(
626 NetworkInterfaceInfo {0, "eth0",
627 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
628 {address_v4::from_string("0.0.0.0")},
629 {address_v6::from_string("::")},
630 address_v4(),
631 IFF_UP});
632 fakeInterfaces->push_back(
633 NetworkInterfaceInfo {1, "eth0",
634 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
635 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
636 {},
637 address_v4::from_string("192.168.2.255"),
638 0});
639 fakeInterfaces->push_back(
640 NetworkInterfaceInfo {2, "eth1",
641 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
642 {address_v4::from_string("198.51.100.1")},
643 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
644 address_v4::from_string("198.51.100.255"),
645 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
646
647 setDebugNetworkInterfaces(fakeInterfaces);
648 }
649
650 ~FakeNetworkInterfaceFixture()
651 {
652 setDebugNetworkInterfaces(nullptr);
653 }
654};
655
656BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
657{
658 using namespace boost::asio::ip;
659
660 UdpFactory factory;
661 factory.prohibitEndpoint(udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
662 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
663 BOOST_CHECK((factory.m_prohibitedEndpoints ==
664 std::set<udp::Endpoint> {
665 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
666 }));
667
668 factory.m_prohibitedEndpoints.clear();
669 factory.prohibitEndpoint(udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
670 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
671 BOOST_CHECK((factory.m_prohibitedEndpoints ==
672 std::set<udp::Endpoint> {
673 udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048),
674 }));
675
676 factory.m_prohibitedEndpoints.clear();
677 factory.prohibitEndpoint(udp::Endpoint(address_v4(), 1024));
678 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 6);
679 BOOST_CHECK((factory.m_prohibitedEndpoints ==
680 std::set<udp::Endpoint> {
681 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
682 udp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
683 udp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
684 udp::Endpoint(address_v4::from_string("198.51.100.255"), 1024),
685 udp::Endpoint(address_v4::from_string("255.255.255.255"), 1024),
686 udp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
687 }));
688
689 factory.m_prohibitedEndpoints.clear();
690 factory.prohibitEndpoint(udp::Endpoint(address_v6(), 2048));
691 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
692 BOOST_CHECK((factory.m_prohibitedEndpoints ==
693 std::set<udp::Endpoint> {
694 udp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
695 udp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
696 udp::Endpoint(address_v6::from_string("::"), 2048),
697 }));
698}
699
Yukai Tu0a49d342015-09-13 12:54:22 +0800700BOOST_AUTO_TEST_SUITE_END() // TestUdp
701BOOST_AUTO_TEST_SUITE_END() // Face
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700702
Giulio Grassi624f6c62014-02-18 19:42:14 +0100703} // namespace tests
704} // namespace nfd