blob: 0ad561215e937e1e4a89e621860957e219f33fbd [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
Junxiao Shi0ba6d642017-07-17 00:53:22 +000039using UdpFactoryFixture = FaceSystemFactoryFixture<UdpFactory>;
40
Junxiao Shicde37ad2015-12-24 01:02:05 -070041BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +000042BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -070043
44using nfd::Face;
45
Junxiao Shi0ba6d642017-07-17 00:53:22 +000046BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi64d99f22017-01-21 23:06:36 +000047
48BOOST_AUTO_TEST_CASE(Channels)
49{
50 const std::string CONFIG = R"CONFIG(
51 face_system
52 {
53 udp
54 {
55 port 7001
56 enable_v4 yes
57 enable_v6 yes
58 idle_timeout 30
59 mcast no
60 }
61 }
62 )CONFIG";
63
64 parseConfig(CONFIG, true);
65 parseConfig(CONFIG, false);
66
Junxiao Shi64d99f22017-01-21 23:06:36 +000067 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
68}
69
70BOOST_AUTO_TEST_CASE(ChannelV4)
71{
72 const std::string CONFIG = R"CONFIG(
73 face_system
74 {
75 udp
76 {
77 port 7001
78 enable_v4 yes
79 enable_v6 no
80 mcast no
81 }
82 }
83 )CONFIG";
84
85 parseConfig(CONFIG, true);
86 parseConfig(CONFIG, false);
87
Junxiao Shi64d99f22017-01-21 23:06:36 +000088 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
Junxiao Shi64d99f22017-01-21 23:06:36 +0000109 checkChannelListEqual(factory, {"udp6://[::]:7001"});
110}
111
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000112class UdpMcastConfigFixture : public UdpFactoryFixture
Junxiao Shi64d99f22017-01-21 23:06:36 +0000113{
114protected:
115 UdpMcastConfigFixture()
116 {
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000117 for (const auto& netif : collectNetworkInterfaces()) {
118 if (netif->isUp() && netif->canMulticast() && hasAddressFamily<AddressFamily::V4>(*netif)) {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000119 netifs.push_back(netif);
120 }
121 }
122 }
123
124 std::vector<const Face*>
Teng Liangfe4fce32017-03-29 04:49:38 +0000125 listUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000126 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000127 return this->listFacesByScheme("udp4", linkType);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000128 }
129
130 size_t
Teng Liangfe4fce32017-03-29 04:49:38 +0000131 countUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000132 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000133 return this->listUdpMcastFaces(linkType).size();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000134 }
135
Junxiao Shic31080d2017-01-24 15:10:12 +0000136 /** \brief determine whether a UDP multicast face is created on \p netif
137 */
138 static bool
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000139 isFaceOnNetif(const Face& face, const shared_ptr<const ndn::net::NetworkInterface>& netif)
Junxiao Shic31080d2017-01-24 15:10:12 +0000140 {
141 auto ip = boost::asio::ip::address_v4::from_string(face.getLocalUri().getHost());
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000142 return std::any_of(netif->getNetworkAddresses().begin(), netif->getNetworkAddresses().end(),
143 [ip] (const ndn::net::NetworkAddress& a) { return a.getIp() == ip; });
Junxiao Shic31080d2017-01-24 15:10:12 +0000144 }
145
Junxiao Shi64d99f22017-01-21 23:06:36 +0000146protected:
147 /** \brief MulticastUdpTransport-capable network interfaces
148 */
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000149 std::vector<shared_ptr<const ndn::net::NetworkInterface>> netifs;
Junxiao Shi64d99f22017-01-21 23:06:36 +0000150};
151
152#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
153 do { \
154 if (this->netifs.size() < (n)) { \
155 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
156 " or more MulticastUdpTransport-capable network interfaces"); \
157 return; \
158 } \
159 } while (false)
160
161BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpMcastConfigFixture)
162{
163#ifdef __linux__
164 // need superuser privilege for creating multicast faces on linux
165 SKIP_IF_NOT_SUPERUSER();
166#endif // __linux__
167
168 const std::string CONFIG_WITH_MCAST = R"CONFIG(
169 face_system
170 {
171 udp
172 {
173 mcast yes
174 }
175 }
176 )CONFIG";
177 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
178 face_system
179 {
180 udp
181 {
182 mcast no
183 }
184 }
185 )CONFIG";
186
187 parseConfig(CONFIG_WITHOUT_MCAST, false);
188 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
189
190 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
191
192 parseConfig(CONFIG_WITH_MCAST, false);
193 g_io.poll();
194 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), netifs.size());
195
196 parseConfig(CONFIG_WITHOUT_MCAST, false);
197 g_io.poll();
198 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
199}
200
Teng Liangfe4fce32017-03-29 04:49:38 +0000201BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpMcastConfigFixture)
202{
203#ifdef __linux__
204 // need superuser privilege for creating multicast faces on linux
205 SKIP_IF_NOT_SUPERUSER();
206#endif // __linux__
207 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
208
209 const std::string CONFIG = R"CONFIG(
210 face_system
211 {
212 udp
213 {
214 mcast_ad_hoc yes
215 }
216 }
217 )CONFIG";
218
219 parseConfig(CONFIG, false);
220 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
221}
222
Junxiao Shi64d99f22017-01-21 23:06:36 +0000223BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpoint, UdpMcastConfigFixture)
224{
225#ifdef __linux__
226 // need superuser privilege for creating multicast faces on linux
227 SKIP_IF_NOT_SUPERUSER();
228#endif // __linux__
229 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
230
231 const std::string CONFIG1 = R"CONFIG(
232 face_system
233 {
234 udp
235 {
236 mcast_group 239.66.30.1
237 mcast_port 7011
238 }
239 }
240 )CONFIG";
241 const std::string CONFIG2 = R"CONFIG(
242 face_system
243 {
244 udp
245 {
246 mcast_group 239.66.30.2
247 mcast_port 7012
248 }
249 }
250 )CONFIG";
251
252 parseConfig(CONFIG1, false);
253 auto udpMcastFaces = this->listUdpMcastFaces();
254 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
255 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
256 FaceUri("udp4://239.66.30.1:7011"));
257
258 parseConfig(CONFIG2, false);
259 g_io.poll();
260 udpMcastFaces = this->listUdpMcastFaces();
261 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
262 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
263 FaceUri("udp4://239.66.30.2:7012"));
264}
265
Junxiao Shic31080d2017-01-24 15:10:12 +0000266BOOST_FIXTURE_TEST_CASE(Whitelist, UdpMcastConfigFixture)
267{
268#ifdef __linux__
269 // need superuser privilege for creating multicast faces on linux
270 SKIP_IF_NOT_SUPERUSER();
271#endif // __linux__
272 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
273
274 std::string CONFIG = R"CONFIG(
275 face_system
276 {
277 udp
278 {
279 whitelist
280 {
281 ifname %ifname
282 }
283 }
284 }
285 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000286 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000287
288 parseConfig(CONFIG, false);
289 auto udpMcastFaces = this->listUdpMcastFaces();
290 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
291 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
292}
293
294BOOST_FIXTURE_TEST_CASE(Blacklist, UdpMcastConfigFixture)
295{
296#ifdef __linux__
297 // need superuser privilege for creating multicast faces on linux
298 SKIP_IF_NOT_SUPERUSER();
299#endif // __linux__
300 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
301
302 std::string CONFIG = R"CONFIG(
303 face_system
304 {
305 udp
306 {
307 blacklist
308 {
309 ifname %ifname
310 }
311 }
312 }
313 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000314 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000315
316 parseConfig(CONFIG, false);
317 auto udpMcastFaces = this->listUdpMcastFaces();
318 BOOST_CHECK_EQUAL(udpMcastFaces.size(), netifs.size() - 1);
319 BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [=] (const Face* face) {
320 return isFaceOnNetif(*face, netifs.front());
321 }), 0);
322}
323
324BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpMcastConfigFixture)
325{
326#ifdef __linux__
327 // need superuser privilege for creating multicast faces on linux
328 SKIP_IF_NOT_SUPERUSER();
329#endif // __linux__
330 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
331
332 std::string CONFIG1 = R"CONFIG(
333 face_system
334 {
335 udp
336 {
337 whitelist
338 {
339 ifname %ifname
340 }
341 }
342 }
343 )CONFIG";
344 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000345 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
346 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000347
348 parseConfig(CONFIG1, false);
349 auto udpMcastFaces = this->listUdpMcastFaces();
350 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
351 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
352
353 parseConfig(CONFIG2, false);
354 g_io.poll();
355 udpMcastFaces = this->listUdpMcastFaces();
356 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
357 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.back()));
358}
359
Junxiao Shi64d99f22017-01-21 23:06:36 +0000360BOOST_AUTO_TEST_CASE(Omitted)
361{
362 const std::string CONFIG = R"CONFIG(
363 face_system
364 {
365 }
366 )CONFIG";
367
368 parseConfig(CONFIG, true);
369 parseConfig(CONFIG, false);
370
Junxiao Shi64d99f22017-01-21 23:06:36 +0000371 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
372 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
373}
374
375BOOST_AUTO_TEST_CASE(BadIdleTimeout)
376{
377 const std::string CONFIG = R"CONFIG(
378 face_system
379 {
380 udp
381 {
382 idle_timeout hello
383 }
384 }
385 )CONFIG";
386
387 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
388 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
389}
390
391BOOST_AUTO_TEST_CASE(BadMcast)
392{
393 const std::string CONFIG = R"CONFIG(
394 face_system
395 {
396 udp
397 {
398 mcast hello
399 }
400 }
401 )CONFIG";
402
403 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
404 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
405}
406
407BOOST_AUTO_TEST_CASE(BadMcastGroup)
408{
409 const std::string CONFIG = R"CONFIG(
410 face_system
411 {
412 udp
413 {
414 mcast_group hello
415 }
416 }
417 )CONFIG";
418
419 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
420 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
421}
422
423BOOST_AUTO_TEST_CASE(BadMcastGroupV4Unicast)
424{
425 const std::string CONFIG = R"CONFIG(
426 face_system
427 {
428 udp
429 {
430 mcast_group 10.0.0.1
431 }
432 }
433 )CONFIG";
434
435 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
436 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
437}
438
439BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
440{
441 const std::string CONFIG = R"CONFIG(
442 face_system
443 {
444 udp
445 {
446 mcast_group ff00::1
447 }
448 }
449 )CONFIG";
450
451 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
452 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
453}
454
455BOOST_AUTO_TEST_CASE(AllDisabled)
456{
457 const std::string CONFIG = R"CONFIG(
458 face_system
459 {
460 udp
461 {
462 enable_v4 no
463 enable_v6 no
464 mcast no
465 }
466 }
467 )CONFIG";
468
469 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
470 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
471}
472
473BOOST_AUTO_TEST_CASE(UnknownOption)
474{
475 const std::string CONFIG = R"CONFIG(
476 face_system
477 {
478 udp
479 {
480 hello
481 }
482 }
483 )CONFIG";
484
485 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
486 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
487}
488
489BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
490
Junxiao Shicde37ad2015-12-24 01:02:05 -0700491BOOST_AUTO_TEST_CASE(GetChannels)
492{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700493 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
494
495 std::vector<shared_ptr<const Channel>> expectedChannels;
496 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
497 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
498 expectedChannels.push_back(factory.createChannel("::1", "20071"));
499
500 for (const auto& i : factory.getChannels()) {
501 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
502 BOOST_REQUIRE(pos != expectedChannels.end());
503 expectedChannels.erase(pos);
504 }
505
506 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
507}
508
Weiwei Liu72cee942016-02-04 16:49:19 -0700509BOOST_AUTO_TEST_CASE(CreateChannel)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700510{
Weiwei Liu72cee942016-02-04 16:49:19 -0700511 auto channel1 = factory.createChannel("127.0.0.1", "20070");
512 auto channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700513 BOOST_CHECK_EQUAL(channel1, channel1a);
514 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
515
Weiwei Liu72cee942016-02-04 16:49:19 -0700516 auto channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700517 BOOST_CHECK_NE(channel1, channel2);
518
Weiwei Liu72cee942016-02-04 16:49:19 -0700519 auto channel3 = factory.createChannel("::1", "20071");
520 BOOST_CHECK_NE(channel2, channel3);
521 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700522
Weiwei Liu72cee942016-02-04 16:49:19 -0700523 // createChannel with multicast address
524 BOOST_CHECK_EXCEPTION(factory.createChannel("224.0.0.1", "20070"), UdpFactory::Error,
525 [] (const UdpFactory::Error& e) {
526 return strcmp(e.what(),
527 "createChannel is only for unicast channels. The provided endpoint "
528 "is multicast. Use createMulticastFace to create a multicast face") == 0;
529 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700530
Weiwei Liu72cee942016-02-04 16:49:19 -0700531 // createChannel with a local endpoint that has already been allocated for a UDP multicast face
532 auto multicastFace = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20072");
533 BOOST_CHECK_EXCEPTION(factory.createChannel("127.0.0.1", "20072"), UdpFactory::Error,
534 [] (const UdpFactory::Error& e) {
535 return strcmp(e.what(),
536 "Cannot create the requested UDP unicast channel, local "
537 "endpoint is already allocated for a UDP multicast face") == 0;
538 });
539}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700540
Weiwei Liu72cee942016-02-04 16:49:19 -0700541BOOST_AUTO_TEST_CASE(CreateMulticastFace)
542{
Weiwei Liu72cee942016-02-04 16:49:19 -0700543 auto multicastFace1 = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
544 auto multicastFace1a = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700545 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
546
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200547 // createMulticastFace with a local endpoint that is already used by a channel
Weiwei Liu72cee942016-02-04 16:49:19 -0700548 auto channel = factory.createChannel("127.0.0.1", "20071");
549 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20071"), UdpFactory::Error,
550 [] (const UdpFactory::Error& e) {
551 return strcmp(e.what(),
552 "Cannot create the requested UDP multicast face, local "
553 "endpoint is already allocated for a UDP unicast channel") == 0;
554 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700555
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200556 // createMulticastFace with a local endpoint that is already
557 // used by a multicast face on a different multicast group
Weiwei Liu72cee942016-02-04 16:49:19 -0700558 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.42", "20070"), UdpFactory::Error,
559 [] (const UdpFactory::Error& e) {
560 return strcmp(e.what(),
561 "Cannot create the requested UDP multicast face, local "
562 "endpoint is already allocated for a UDP multicast face "
563 "on a different multicast group") == 0;
564 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700565
Weiwei Liu72cee942016-02-04 16:49:19 -0700566 // createMulticastFace with an IPv4 unicast address
567 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "192.168.10.15", "20072"), UdpFactory::Error,
568 [] (const UdpFactory::Error& e) {
569 return strcmp(e.what(),
570 "Cannot create the requested UDP multicast face, "
571 "the multicast group given as input is not a multicast address") == 0;
572 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700573
Weiwei Liu72cee942016-02-04 16:49:19 -0700574 // createMulticastFace with an IPv6 multicast address
575 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("::1", "ff01::114", "20073"), UdpFactory::Error,
576 [] (const UdpFactory::Error& e) {
577 return strcmp(e.what(),
578 "IPv6 multicast is not supported yet. Please provide an IPv4 "
579 "address") == 0;
580 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700581
Weiwei Liu72cee942016-02-04 16:49:19 -0700582 // createMulticastFace with different local and remote port numbers
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200583 udp::Endpoint localEndpoint(boost::asio::ip::address_v4::loopback(), 20074);
584 udp::Endpoint multicastEndpoint(boost::asio::ip::address::from_string("224.0.0.1"), 20075);
Weiwei Liu72cee942016-02-04 16:49:19 -0700585 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(localEndpoint, multicastEndpoint), UdpFactory::Error,
586 [] (const UdpFactory::Error& e) {
587 return strcmp(e.what(),
588 "Cannot create the requested UDP multicast face, "
589 "both endpoints should have the same port number. ") == 0;
590 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700591}
592
Eric Newberry42602412016-08-27 09:33:18 -0700593BOOST_AUTO_TEST_CASE(FaceCreate)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700594{
Eric Newberry42602412016-08-27 09:33:18 -0700595 createFace(factory,
596 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000597 {},
Eric Newberry42602412016-08-27 09:33:18 -0700598 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700599 false,
Eric Newberry42602412016-08-27 09:33:18 -0700600 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700601
602 factory.createChannel("127.0.0.1", "20071");
603
Eric Newberry42602412016-08-27 09:33:18 -0700604 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400605 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::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +0000610
Eric Newberry42602412016-08-27 09:33:18 -0700611 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400612 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000613 {},
Eric Newberry42602412016-08-27 09:33:18 -0700614 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700615 false,
Eric Newberry42602412016-08-27 09:33:18 -0700616 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700617
Eric Newberry42602412016-08-27 09:33:18 -0700618 createFace(factory,
619 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000620 {},
Eric Newberry42602412016-08-27 09:33:18 -0700621 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700622 false,
Eric Newberry42602412016-08-27 09:33:18 -0700623 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700624}
625
626BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
627{
Eric Newberry78e32b02017-04-01 14:34:44 +0000628 factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700629
Eric Newberry42602412016-08-27 09:33:18 -0700630 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400631 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400632 FaceUri("udp4://127.0.0.1:20071"),
Davide Pesavento46afec42017-05-28 14:28:47 -0400633 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
634 false,
635 {CreateFaceExpectedResult::FAILURE, 406,
636 "Unicast UDP faces cannot be created with a LocalUri"});
637
638 createFace(factory,
639 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000640 {},
Eric Newberry42602412016-08-27 09:33:18 -0700641 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
Eric Newberryf40551a2016-09-05 15:41:16 -0700642 false,
Eric Newberry42602412016-08-27 09:33:18 -0700643 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400644 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000645
646 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400647 FaceUri("udp4://233.252.0.1:23252"),
648 {},
Eric Newberry78e32b02017-04-01 14:34:44 +0000649 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
650 false,
651 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400652 "Cannot create multicast UDP faces"});
653
654 createFace(factory,
655 FaceUri("udp4://127.0.0.1:20071"),
656 {},
657 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
658 false,
659 {CreateFaceExpectedResult::FAILURE, 406,
660 "Requested endpoint is prohibited"});
661
662 createFace(factory,
663 FaceUri("udp4://127.0.0.1:20072"),
664 {},
665 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
666 true,
667 {CreateFaceExpectedResult::FAILURE, 406,
668 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700669}
670
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000671class FakeNetworkInterfaceFixture : public UdpFactoryFixture
Junxiao Shicde37ad2015-12-24 01:02:05 -0700672{
673public:
674 FakeNetworkInterfaceFixture()
675 {
676 using namespace boost::asio::ip;
677
678 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
679
680 fakeInterfaces->push_back(
681 NetworkInterfaceInfo {0, "eth0",
682 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
683 {address_v4::from_string("0.0.0.0")},
684 {address_v6::from_string("::")},
685 address_v4(),
686 IFF_UP});
687 fakeInterfaces->push_back(
688 NetworkInterfaceInfo {1, "eth0",
689 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
690 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
691 {},
692 address_v4::from_string("192.168.2.255"),
693 0});
694 fakeInterfaces->push_back(
695 NetworkInterfaceInfo {2, "eth1",
696 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
697 {address_v4::from_string("198.51.100.1")},
698 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
699 address_v4::from_string("198.51.100.255"),
700 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
701
702 setDebugNetworkInterfaces(fakeInterfaces);
703 }
704
705 ~FakeNetworkInterfaceFixture()
706 {
707 setDebugNetworkInterfaces(nullptr);
708 }
709};
710
711BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
712{
713 using namespace boost::asio::ip;
714
Junxiao Shicde37ad2015-12-24 01:02:05 -0700715 factory.prohibitEndpoint(udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
716 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
717 BOOST_CHECK((factory.m_prohibitedEndpoints ==
718 std::set<udp::Endpoint> {
719 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
720 }));
721
722 factory.m_prohibitedEndpoints.clear();
723 factory.prohibitEndpoint(udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
724 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
725 BOOST_CHECK((factory.m_prohibitedEndpoints ==
726 std::set<udp::Endpoint> {
727 udp::Endpoint(address_v6::from_string("2001:db8::1"), 2048),
728 }));
729
730 factory.m_prohibitedEndpoints.clear();
731 factory.prohibitEndpoint(udp::Endpoint(address_v4(), 1024));
732 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 6);
733 BOOST_CHECK((factory.m_prohibitedEndpoints ==
734 std::set<udp::Endpoint> {
735 udp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
736 udp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
737 udp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
738 udp::Endpoint(address_v4::from_string("198.51.100.255"), 1024),
739 udp::Endpoint(address_v4::from_string("255.255.255.255"), 1024),
740 udp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
741 }));
742
743 factory.m_prohibitedEndpoints.clear();
744 factory.prohibitEndpoint(udp::Endpoint(address_v6(), 2048));
745 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
746 BOOST_CHECK((factory.m_prohibitedEndpoints ==
747 std::set<udp::Endpoint> {
748 udp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
749 udp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
750 udp::Endpoint(address_v6::from_string("::"), 2048),
751 }));
752}
753
754BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
755BOOST_AUTO_TEST_SUITE_END() // Face
756
757} // namespace tests
Junxiao Shi64d99f22017-01-21 23:06:36 +0000758} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700759} // namespace nfd