blob: b5ddb8a1dfbb661f1bbe9c48a1cad2ddba104705 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi84d62cb2017-07-12 16:15:18 +00002/*
Junxiao Shi38b24c72017-01-05 02:59:31 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Junxiao Shicde37ad2015-12-24 01:02:05 -07004 * 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.
10 *
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/>.
24 */
25
26#include "face/udp-factory.hpp"
27
Eric Newberry42602412016-08-27 09:33:18 -070028#include "factory-test-common.hpp"
Junxiao Shi64d99f22017-01-21 23:06:36 +000029#include "face-system-fixture.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070030#include "tests/limited-io.hpp"
Junxiao Shi84d62cb2017-07-12 16:15:18 +000031#include "test-netif-ip.hpp"
Junxiao Shic31080d2017-01-24 15:10:12 +000032#include <boost/algorithm/string/replace.hpp>
33#include <boost/range/algorithm.hpp>
Junxiao Shicde37ad2015-12-24 01:02:05 -070034
35namespace nfd {
Junxiao Shi64d99f22017-01-21 23:06:36 +000036namespace face {
Junxiao Shicde37ad2015-12-24 01:02:05 -070037namespace tests {
38
39BOOST_AUTO_TEST_SUITE(Face)
40BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, BaseFixture)
41
42using nfd::Face;
43
Junxiao Shi64d99f22017-01-21 23:06:36 +000044BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceSystemFixture)
45
46BOOST_AUTO_TEST_CASE(Channels)
47{
48 const std::string CONFIG = R"CONFIG(
49 face_system
50 {
51 udp
52 {
53 port 7001
54 enable_v4 yes
55 enable_v6 yes
56 idle_timeout 30
57 mcast no
58 }
59 }
60 )CONFIG";
61
62 parseConfig(CONFIG, true);
63 parseConfig(CONFIG, false);
64
65 auto& factory = this->getFactoryById<UdpFactory>("udp");
66 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
67}
68
69BOOST_AUTO_TEST_CASE(ChannelV4)
70{
71 const std::string CONFIG = R"CONFIG(
72 face_system
73 {
74 udp
75 {
76 port 7001
77 enable_v4 yes
78 enable_v6 no
79 mcast no
80 }
81 }
82 )CONFIG";
83
84 parseConfig(CONFIG, true);
85 parseConfig(CONFIG, false);
86
87 auto& factory = this->getFactoryById<UdpFactory>("udp");
88 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
89}
90
91BOOST_AUTO_TEST_CASE(ChannelV6)
92{
93 const std::string CONFIG = R"CONFIG(
94 face_system
95 {
96 udp
97 {
98 port 7001
99 enable_v4 no
100 enable_v6 yes
101 mcast no
102 }
103 }
104 )CONFIG";
105
106 parseConfig(CONFIG, true);
107 parseConfig(CONFIG, false);
108
109 auto& factory = this->getFactoryById<UdpFactory>("udp");
110 checkChannelListEqual(factory, {"udp6://[::]:7001"});
111}
112
113class UdpMcastConfigFixture : public FaceSystemFixture
114{
115protected:
116 UdpMcastConfigFixture()
117 {
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000118 for (const auto& netif : collectNetworkInterfaces()) {
119 if (netif->isUp() && netif->canMulticast() && hasAddressFamily<AddressFamily::V4>(*netif)) {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000120 netifs.push_back(netif);
121 }
122 }
123 }
124
125 std::vector<const Face*>
Teng Liangfe4fce32017-03-29 04:49:38 +0000126 listUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000127 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000128 return this->listFacesByScheme("udp4", linkType);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000129 }
130
131 size_t
Teng Liangfe4fce32017-03-29 04:49:38 +0000132 countUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000133 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000134 return this->listUdpMcastFaces(linkType).size();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000135 }
136
Junxiao Shic31080d2017-01-24 15:10:12 +0000137 /** \brief determine whether a UDP multicast face is created on \p netif
138 */
139 static bool
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000140 isFaceOnNetif(const Face& face, const shared_ptr<const ndn::net::NetworkInterface>& netif)
Junxiao Shic31080d2017-01-24 15:10:12 +0000141 {
142 auto ip = boost::asio::ip::address_v4::from_string(face.getLocalUri().getHost());
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000143 return std::any_of(netif->getNetworkAddresses().begin(), netif->getNetworkAddresses().end(),
144 [ip] (const ndn::net::NetworkAddress& a) { return a.getIp() == ip; });
Junxiao Shic31080d2017-01-24 15:10:12 +0000145 }
146
Junxiao Shi64d99f22017-01-21 23:06:36 +0000147protected:
148 /** \brief MulticastUdpTransport-capable network interfaces
149 */
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000150 std::vector<shared_ptr<const ndn::net::NetworkInterface>> netifs;
Junxiao Shi64d99f22017-01-21 23:06:36 +0000151};
152
153#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
154 do { \
155 if (this->netifs.size() < (n)) { \
156 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
157 " or more MulticastUdpTransport-capable network interfaces"); \
158 return; \
159 } \
160 } while (false)
161
162BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpMcastConfigFixture)
163{
164#ifdef __linux__
165 // need superuser privilege for creating multicast faces on linux
166 SKIP_IF_NOT_SUPERUSER();
167#endif // __linux__
168
169 const std::string CONFIG_WITH_MCAST = R"CONFIG(
170 face_system
171 {
172 udp
173 {
174 mcast yes
175 }
176 }
177 )CONFIG";
178 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
179 face_system
180 {
181 udp
182 {
183 mcast no
184 }
185 }
186 )CONFIG";
187
188 parseConfig(CONFIG_WITHOUT_MCAST, false);
189 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
190
191 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
192
193 parseConfig(CONFIG_WITH_MCAST, false);
194 g_io.poll();
195 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), netifs.size());
196
197 parseConfig(CONFIG_WITHOUT_MCAST, false);
198 g_io.poll();
199 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
200}
201
Teng Liangfe4fce32017-03-29 04:49:38 +0000202BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpMcastConfigFixture)
203{
204#ifdef __linux__
205 // need superuser privilege for creating multicast faces on linux
206 SKIP_IF_NOT_SUPERUSER();
207#endif // __linux__
208 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
209
210 const std::string CONFIG = R"CONFIG(
211 face_system
212 {
213 udp
214 {
215 mcast_ad_hoc yes
216 }
217 }
218 )CONFIG";
219
220 parseConfig(CONFIG, false);
221 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
222}
223
Junxiao Shi64d99f22017-01-21 23:06:36 +0000224BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpoint, UdpMcastConfigFixture)
225{
226#ifdef __linux__
227 // need superuser privilege for creating multicast faces on linux
228 SKIP_IF_NOT_SUPERUSER();
229#endif // __linux__
230 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
231
232 const std::string CONFIG1 = R"CONFIG(
233 face_system
234 {
235 udp
236 {
237 mcast_group 239.66.30.1
238 mcast_port 7011
239 }
240 }
241 )CONFIG";
242 const std::string CONFIG2 = R"CONFIG(
243 face_system
244 {
245 udp
246 {
247 mcast_group 239.66.30.2
248 mcast_port 7012
249 }
250 }
251 )CONFIG";
252
253 parseConfig(CONFIG1, false);
254 auto udpMcastFaces = this->listUdpMcastFaces();
255 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
256 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
257 FaceUri("udp4://239.66.30.1:7011"));
258
259 parseConfig(CONFIG2, false);
260 g_io.poll();
261 udpMcastFaces = this->listUdpMcastFaces();
262 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
263 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
264 FaceUri("udp4://239.66.30.2:7012"));
265}
266
Junxiao Shic31080d2017-01-24 15:10:12 +0000267BOOST_FIXTURE_TEST_CASE(Whitelist, UdpMcastConfigFixture)
268{
269#ifdef __linux__
270 // need superuser privilege for creating multicast faces on linux
271 SKIP_IF_NOT_SUPERUSER();
272#endif // __linux__
273 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
274
275 std::string CONFIG = R"CONFIG(
276 face_system
277 {
278 udp
279 {
280 whitelist
281 {
282 ifname %ifname
283 }
284 }
285 }
286 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000287 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000288
289 parseConfig(CONFIG, false);
290 auto udpMcastFaces = this->listUdpMcastFaces();
291 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
292 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
293}
294
295BOOST_FIXTURE_TEST_CASE(Blacklist, UdpMcastConfigFixture)
296{
297#ifdef __linux__
298 // need superuser privilege for creating multicast faces on linux
299 SKIP_IF_NOT_SUPERUSER();
300#endif // __linux__
301 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
302
303 std::string CONFIG = R"CONFIG(
304 face_system
305 {
306 udp
307 {
308 blacklist
309 {
310 ifname %ifname
311 }
312 }
313 }
314 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000315 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000316
317 parseConfig(CONFIG, false);
318 auto udpMcastFaces = this->listUdpMcastFaces();
319 BOOST_CHECK_EQUAL(udpMcastFaces.size(), netifs.size() - 1);
320 BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [=] (const Face* face) {
321 return isFaceOnNetif(*face, netifs.front());
322 }), 0);
323}
324
325BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpMcastConfigFixture)
326{
327#ifdef __linux__
328 // need superuser privilege for creating multicast faces on linux
329 SKIP_IF_NOT_SUPERUSER();
330#endif // __linux__
331 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
332
333 std::string CONFIG1 = R"CONFIG(
334 face_system
335 {
336 udp
337 {
338 whitelist
339 {
340 ifname %ifname
341 }
342 }
343 }
344 )CONFIG";
345 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000346 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
347 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000348
349 parseConfig(CONFIG1, false);
350 auto udpMcastFaces = this->listUdpMcastFaces();
351 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
352 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
353
354 parseConfig(CONFIG2, false);
355 g_io.poll();
356 udpMcastFaces = this->listUdpMcastFaces();
357 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
358 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.back()));
359}
360
Junxiao Shi64d99f22017-01-21 23:06:36 +0000361BOOST_AUTO_TEST_CASE(Omitted)
362{
363 const std::string CONFIG = R"CONFIG(
364 face_system
365 {
366 }
367 )CONFIG";
368
369 parseConfig(CONFIG, true);
370 parseConfig(CONFIG, false);
371
372 auto& factory = this->getFactoryById<UdpFactory>("udp");
373 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
374 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
375}
376
377BOOST_AUTO_TEST_CASE(BadIdleTimeout)
378{
379 const std::string CONFIG = R"CONFIG(
380 face_system
381 {
382 udp
383 {
384 idle_timeout hello
385 }
386 }
387 )CONFIG";
388
389 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
390 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
391}
392
393BOOST_AUTO_TEST_CASE(BadMcast)
394{
395 const std::string CONFIG = R"CONFIG(
396 face_system
397 {
398 udp
399 {
400 mcast hello
401 }
402 }
403 )CONFIG";
404
405 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
406 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
407}
408
409BOOST_AUTO_TEST_CASE(BadMcastGroup)
410{
411 const std::string CONFIG = R"CONFIG(
412 face_system
413 {
414 udp
415 {
416 mcast_group hello
417 }
418 }
419 )CONFIG";
420
421 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
422 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
423}
424
425BOOST_AUTO_TEST_CASE(BadMcastGroupV4Unicast)
426{
427 const std::string CONFIG = R"CONFIG(
428 face_system
429 {
430 udp
431 {
432 mcast_group 10.0.0.1
433 }
434 }
435 )CONFIG";
436
437 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
438 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
439}
440
441BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
442{
443 const std::string CONFIG = R"CONFIG(
444 face_system
445 {
446 udp
447 {
448 mcast_group ff00::1
449 }
450 }
451 )CONFIG";
452
453 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
454 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
455}
456
457BOOST_AUTO_TEST_CASE(AllDisabled)
458{
459 const std::string CONFIG = R"CONFIG(
460 face_system
461 {
462 udp
463 {
464 enable_v4 no
465 enable_v6 no
466 mcast no
467 }
468 }
469 )CONFIG";
470
471 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
472 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
473}
474
475BOOST_AUTO_TEST_CASE(UnknownOption)
476{
477 const std::string CONFIG = R"CONFIG(
478 face_system
479 {
480 udp
481 {
482 hello
483 }
484 }
485 )CONFIG";
486
487 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
488 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
489}
490
491BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
492
Junxiao Shicde37ad2015-12-24 01:02:05 -0700493BOOST_AUTO_TEST_CASE(GetChannels)
494{
495 UdpFactory factory;
496 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
497
498 std::vector<shared_ptr<const Channel>> expectedChannels;
499 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
500 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
501 expectedChannels.push_back(factory.createChannel("::1", "20071"));
502
503 for (const auto& i : factory.getChannels()) {
504 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
505 BOOST_REQUIRE(pos != expectedChannels.end());
506 expectedChannels.erase(pos);
507 }
508
509 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
510}
511
Weiwei Liu72cee942016-02-04 16:49:19 -0700512BOOST_AUTO_TEST_CASE(CreateChannel)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700513{
Weiwei Liu72cee942016-02-04 16:49:19 -0700514 UdpFactory factory;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700515
Weiwei Liu72cee942016-02-04 16:49:19 -0700516 auto channel1 = factory.createChannel("127.0.0.1", "20070");
517 auto channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700518 BOOST_CHECK_EQUAL(channel1, channel1a);
519 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
520
Weiwei Liu72cee942016-02-04 16:49:19 -0700521 auto channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700522 BOOST_CHECK_NE(channel1, channel2);
523
Weiwei Liu72cee942016-02-04 16:49:19 -0700524 auto channel3 = factory.createChannel("::1", "20071");
525 BOOST_CHECK_NE(channel2, channel3);
526 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700527
Weiwei Liu72cee942016-02-04 16:49:19 -0700528 // createChannel with multicast address
529 BOOST_CHECK_EXCEPTION(factory.createChannel("224.0.0.1", "20070"), UdpFactory::Error,
530 [] (const UdpFactory::Error& e) {
531 return strcmp(e.what(),
532 "createChannel is only for unicast channels. The provided endpoint "
533 "is multicast. Use createMulticastFace to create a multicast face") == 0;
534 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700535
Weiwei Liu72cee942016-02-04 16:49:19 -0700536 // createChannel with a local endpoint that has already been allocated for a UDP multicast face
537 auto multicastFace = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20072");
538 BOOST_CHECK_EXCEPTION(factory.createChannel("127.0.0.1", "20072"), UdpFactory::Error,
539 [] (const UdpFactory::Error& e) {
540 return strcmp(e.what(),
541 "Cannot create the requested UDP unicast channel, local "
542 "endpoint is already allocated for a UDP multicast face") == 0;
543 });
544}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700545
Weiwei Liu72cee942016-02-04 16:49:19 -0700546BOOST_AUTO_TEST_CASE(CreateMulticastFace)
547{
Weiwei Liu72cee942016-02-04 16:49:19 -0700548 UdpFactory factory;
549
550 auto multicastFace1 = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
551 auto multicastFace1a = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700552 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
553
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200554 // createMulticastFace with a local endpoint that is already used by a channel
Weiwei Liu72cee942016-02-04 16:49:19 -0700555 auto channel = factory.createChannel("127.0.0.1", "20071");
556 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20071"), UdpFactory::Error,
557 [] (const UdpFactory::Error& e) {
558 return strcmp(e.what(),
559 "Cannot create the requested UDP multicast face, local "
560 "endpoint is already allocated for a UDP unicast channel") == 0;
561 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700562
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200563 // createMulticastFace with a local endpoint that is already
564 // used by a multicast face on a different multicast group
Weiwei Liu72cee942016-02-04 16:49:19 -0700565 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.42", "20070"), UdpFactory::Error,
566 [] (const UdpFactory::Error& e) {
567 return strcmp(e.what(),
568 "Cannot create the requested UDP multicast face, local "
569 "endpoint is already allocated for a UDP multicast face "
570 "on a different multicast group") == 0;
571 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700572
Weiwei Liu72cee942016-02-04 16:49:19 -0700573 // createMulticastFace with an IPv4 unicast address
574 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "192.168.10.15", "20072"), UdpFactory::Error,
575 [] (const UdpFactory::Error& e) {
576 return strcmp(e.what(),
577 "Cannot create the requested UDP multicast face, "
578 "the multicast group given as input is not a multicast address") == 0;
579 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700580
Weiwei Liu72cee942016-02-04 16:49:19 -0700581 // createMulticastFace with an IPv6 multicast address
582 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("::1", "ff01::114", "20073"), UdpFactory::Error,
583 [] (const UdpFactory::Error& e) {
584 return strcmp(e.what(),
585 "IPv6 multicast is not supported yet. Please provide an IPv4 "
586 "address") == 0;
587 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700588
Weiwei Liu72cee942016-02-04 16:49:19 -0700589 // createMulticastFace with different local and remote port numbers
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200590 udp::Endpoint localEndpoint(boost::asio::ip::address_v4::loopback(), 20074);
591 udp::Endpoint multicastEndpoint(boost::asio::ip::address::from_string("224.0.0.1"), 20075);
Weiwei Liu72cee942016-02-04 16:49:19 -0700592 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(localEndpoint, multicastEndpoint), UdpFactory::Error,
593 [] (const UdpFactory::Error& e) {
594 return strcmp(e.what(),
595 "Cannot create the requested UDP multicast face, "
596 "both endpoints should have the same port number. ") == 0;
597 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700598}
599
Eric Newberry42602412016-08-27 09:33:18 -0700600BOOST_AUTO_TEST_CASE(FaceCreate)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700601{
Junxiao Shi38b24c72017-01-05 02:59:31 +0000602 UdpFactory factory;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700603
Eric Newberry42602412016-08-27 09:33:18 -0700604 createFace(factory,
605 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000606 {},
Eric Newberry42602412016-08-27 09:33:18 -0700607 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700608 false,
Eric Newberry42602412016-08-27 09:33:18 -0700609 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700610
611 factory.createChannel("127.0.0.1", "20071");
612
Eric Newberry42602412016-08-27 09:33:18 -0700613 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400614 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000615 {},
Eric Newberry42602412016-08-27 09:33:18 -0700616 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700617 false,
Eric Newberry42602412016-08-27 09:33:18 -0700618 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +0000619
Eric Newberry42602412016-08-27 09:33:18 -0700620 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400621 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000622 {},
Eric Newberry42602412016-08-27 09:33:18 -0700623 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700624 false,
Eric Newberry42602412016-08-27 09:33:18 -0700625 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700626
Eric Newberry42602412016-08-27 09:33:18 -0700627 createFace(factory,
628 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000629 {},
Eric Newberry42602412016-08-27 09:33:18 -0700630 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700631 false,
Eric Newberry42602412016-08-27 09:33:18 -0700632 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700633}
634
635BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
636{
Junxiao Shi38b24c72017-01-05 02:59:31 +0000637 UdpFactory factory;
Eric Newberry78e32b02017-04-01 14:34:44 +0000638 factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700639
Eric Newberry42602412016-08-27 09:33:18 -0700640 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400641 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400642 FaceUri("udp4://127.0.0.1:20071"),
Davide Pesavento46afec42017-05-28 14:28:47 -0400643 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
644 false,
645 {CreateFaceExpectedResult::FAILURE, 406,
646 "Unicast UDP faces cannot be created with a LocalUri"});
647
648 createFace(factory,
649 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000650 {},
Eric Newberry42602412016-08-27 09:33:18 -0700651 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
Eric Newberryf40551a2016-09-05 15:41:16 -0700652 false,
Eric Newberry42602412016-08-27 09:33:18 -0700653 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400654 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000655
656 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400657 FaceUri("udp4://233.252.0.1:23252"),
658 {},
Eric Newberry78e32b02017-04-01 14:34:44 +0000659 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
660 false,
661 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400662 "Cannot create multicast UDP faces"});
663
664 createFace(factory,
665 FaceUri("udp4://127.0.0.1:20071"),
666 {},
667 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
668 false,
669 {CreateFaceExpectedResult::FAILURE, 406,
670 "Requested endpoint is prohibited"});
671
672 createFace(factory,
673 FaceUri("udp4://127.0.0.1:20072"),
674 {},
675 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
676 true,
677 {CreateFaceExpectedResult::FAILURE, 406,
678 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700679}
680
681class FakeNetworkInterfaceFixture : public BaseFixture
682{
683public:
684 FakeNetworkInterfaceFixture()
685 {
686 using namespace boost::asio::ip;
687
688 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
689
690 fakeInterfaces->push_back(
691 NetworkInterfaceInfo {0, "eth0",
692 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
693 {address_v4::from_string("0.0.0.0")},
694 {address_v6::from_string("::")},
695 address_v4(),
696 IFF_UP});
697 fakeInterfaces->push_back(
698 NetworkInterfaceInfo {1, "eth0",
699 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
700 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
701 {},
702 address_v4::from_string("192.168.2.255"),
703 0});
704 fakeInterfaces->push_back(
705 NetworkInterfaceInfo {2, "eth1",
706 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
707 {address_v4::from_string("198.51.100.1")},
708 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
709 address_v4::from_string("198.51.100.255"),
710 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
711
712 setDebugNetworkInterfaces(fakeInterfaces);
713 }
714
715 ~FakeNetworkInterfaceFixture()
716 {
717 setDebugNetworkInterfaces(nullptr);
718 }
719};
720
721BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
722{
723 using namespace boost::asio::ip;
724
725 UdpFactory factory;
726 factory.prohibitEndpoint(udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
727 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
728 BOOST_CHECK((factory.m_prohibitedEndpoints ==
729 std::set<udp::Endpoint> {
730 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
731 }));
732
733 factory.m_prohibitedEndpoints.clear();
734 factory.prohibitEndpoint(udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
735 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
736 BOOST_CHECK((factory.m_prohibitedEndpoints ==
737 std::set<udp::Endpoint> {
738 udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048),
739 }));
740
741 factory.m_prohibitedEndpoints.clear();
742 factory.prohibitEndpoint(udp::Endpoint(address_v4(), 1024));
743 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 6);
744 BOOST_CHECK((factory.m_prohibitedEndpoints ==
745 std::set<udp::Endpoint> {
746 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
747 udp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
748 udp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
749 udp::Endpoint(address_v4::from_string("198.51.100.255"), 1024),
750 udp::Endpoint(address_v4::from_string("255.255.255.255"), 1024),
751 udp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
752 }));
753
754 factory.m_prohibitedEndpoints.clear();
755 factory.prohibitEndpoint(udp::Endpoint(address_v6(), 2048));
756 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
757 BOOST_CHECK((factory.m_prohibitedEndpoints ==
758 std::set<udp::Endpoint> {
759 udp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
760 udp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
761 udp::Endpoint(address_v6::from_string("::"), 2048),
762 }));
763}
764
765BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
766BOOST_AUTO_TEST_SUITE_END() // Face
767
768} // namespace tests
Junxiao Shi64d99f22017-01-21 23:06:36 +0000769} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700770} // namespace nfd