blob: 0bf7e03b38102f6062caba957112e3465fe4af23 [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/*
Eric Newberrycb27d912020-04-08 19:38:18 -07003 * Copyright (c) 2014-2020, 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
Junxiao Shi64d99f22017-01-21 23:06:36 +000028#include "face-system-fixture.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040029#include "factory-test-common.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040030
Junxiao Shic31080d2017-01-24 15:10:12 +000031#include <boost/algorithm/string/replace.hpp>
Junxiao Shicde37ad2015-12-24 01:02:05 -070032
33namespace nfd {
Junxiao Shi64d99f22017-01-21 23:06:36 +000034namespace face {
Junxiao Shicde37ad2015-12-24 01:02:05 -070035namespace tests {
36
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040037class UdpFactoryFixture : public FaceSystemFactoryFixture<UdpFactory>
38{
39protected:
40 shared_ptr<UdpChannel>
Davide Pesaventobb734df2017-10-24 18:05:36 -040041 createChannel(const std::string& localIp, uint16_t localPort)
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040042 {
Davide Pesavento9c33b902018-05-20 01:30:29 -040043 udp::Endpoint endpoint(boost::asio::ip::address::from_string(localIp), localPort);
Davide Pesavento494a9552018-02-04 22:16:05 -050044 return factory.createChannel(endpoint, 5_min);
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040045 }
46};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000047
Davide Pesaventobb734df2017-10-24 18:05:36 -040048class UdpFactoryMcastFixture : public UdpFactoryFixture
49{
50protected:
51 UdpFactoryMcastFixture()
52 {
53 for (const auto& netif : collectNetworkInterfaces()) {
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050054 // same filtering logic as UdpFactory::applyMcastConfigToNetif()
55 if (netif->isUp() && !netif->isLoopback() && netif->canMulticast()) {
56 bool hasValidIpAddress = false;
57 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
58 hasValidIpAddress = true;
59 netifsV4.push_back(netif);
60 }
61 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V6)) {
62 hasValidIpAddress = true;
63 netifsV6.push_back(netif);
64 }
65 if (hasValidIpAddress) {
66 netifs.push_back(netif);
67 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040068 }
69 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040070 this->copyRealNetifsToNetmon();
71 }
72
73 shared_ptr<Face>
74 createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
75 {
Davide Pesavento9c33b902018-05-20 01:30:29 -040076 auto localAddress = boost::asio::ip::address::from_string(localIp);
77 udp::Endpoint mcastEndpoint(boost::asio::ip::address::from_string(mcastIp), mcastPort);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050078
79 if (localAddress.is_v4()) {
80 BOOST_ASSERT(!netifsV4.empty());
81 return factory.createMulticastFace(netifsV4.front(), localAddress, mcastEndpoint);
82 }
83 else {
84 BOOST_ASSERT(!netifsV6.empty());
85 return factory.createMulticastFace(netifsV6.front(), localAddress, mcastEndpoint);
86 }
87 }
88
89 /** \brief returns a non-loopback IP address suitable for the creation of a UDP multicast face
90 */
91 boost::asio::ip::address
92 findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
93 {
94 const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
95 for (const auto& netif : netifList) {
96 for (const auto& a : netif->getNetworkAddresses()) {
97 if (a.getFamily() == af && !a.getIp().is_loopback())
98 return a.getIp();
99 }
100 }
101 return {};
Davide Pesaventobb734df2017-10-24 18:05:36 -0400102 }
103
104 std::vector<const Face*>
105 listUdp4McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
106 {
107 return this->listFacesByScheme("udp4", linkType);
108 }
109
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500110 std::vector<const Face*>
111 listUdp6McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
112 {
113 return this->listFacesByScheme("udp6", linkType);
114 }
115
116 /** \brief determine whether \p netif has at least one IP address of the given family
Davide Pesaventobb734df2017-10-24 18:05:36 -0400117 */
118 static bool
119 hasAddressFamily(const NetworkInterface& netif, ndn::net::AddressFamily af)
120 {
121 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
122 [af] (const NetworkAddress& a) { return a.getFamily() == af; });
123 }
124
125 /** \brief determine whether a UDP multicast face is created on \p netif
126 */
127 static bool
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500128 isFaceOnNetif(const Face& face, const NetworkInterface& netif)
Davide Pesaventobb734df2017-10-24 18:05:36 -0400129 {
Davide Pesavento9c33b902018-05-20 01:30:29 -0400130 auto ip = boost::asio::ip::address::from_string(face.getLocalUri().getHost());
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500131 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
Davide Pesaventobb734df2017-10-24 18:05:36 -0400132 [ip] (const NetworkAddress& a) { return a.getIp() == ip; });
133 }
134
135protected:
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500136 /** \brief MulticastUdpTransport-capable network interfaces (IPv4 + IPv6)
137 *
138 * This should be used in test cases that do not depend on a specific address family
Davide Pesaventobb734df2017-10-24 18:05:36 -0400139 */
140 std::vector<shared_ptr<const NetworkInterface>> netifs;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500141
142 /** \brief MulticastUdpTransport-capable network interfaces (IPv4 only)
143 */
144 std::vector<shared_ptr<const NetworkInterface>> netifsV4;
145
146 /** \brief MulticastUdpTransport-capable network interfaces (IPv6 only)
147 */
148 std::vector<shared_ptr<const NetworkInterface>> netifsV6;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400149};
150
151#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
152 do { \
153 if (this->netifs.size() < (n)) { \
154 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
155 " or more MulticastUdpTransport-capable network interfaces"); \
156 return; \
157 } \
158 } while (false)
159
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500160#define SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(n) \
161 do { \
162 if (this->netifsV4.size() < (n)) { \
163 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
164 " or more IPv4 MulticastUdpTransport-capable network interfaces"); \
165 return; \
166 } \
167 } while (false)
168
169#define SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(n) \
170 do { \
171 if (this->netifsV6.size() < (n)) { \
172 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
173 " or more IPv6 MulticastUdpTransport-capable network interfaces"); \
174 return; \
175 } \
176 } while (false)
177
Junxiao Shicde37ad2015-12-24 01:02:05 -0700178BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000179BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700180
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000181BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000182
Davide Pesavento494a9552018-02-04 22:16:05 -0500183using nfd::Face;
184
185BOOST_AUTO_TEST_CASE(Defaults)
186{
187 const std::string CONFIG = R"CONFIG(
188 face_system
189 {
190 udp
191 }
192 )CONFIG";
193
194 parseConfig(CONFIG, true);
195 parseConfig(CONFIG, false);
196
197 checkChannelListEqual(factory, {"udp4://0.0.0.0:6363", "udp6://[::]:6363"});
198 auto channels = factory.getChannels();
199 BOOST_CHECK(std::all_of(channels.begin(), channels.end(),
Davide Pesaventod27841b2018-11-13 00:22:24 -0500200 [] (const auto& ch) { return ch->isListening(); }));
Davide Pesavento494a9552018-02-04 22:16:05 -0500201}
202
203BOOST_AUTO_TEST_CASE(DisableListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000204{
205 const std::string CONFIG = R"CONFIG(
206 face_system
207 {
208 udp
209 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500210 listen no
Junxiao Shi64d99f22017-01-21 23:06:36 +0000211 port 7001
Junxiao Shi64d99f22017-01-21 23:06:36 +0000212 mcast no
213 }
214 }
215 )CONFIG";
216
217 parseConfig(CONFIG, true);
218 parseConfig(CONFIG, false);
219
Junxiao Shi64d99f22017-01-21 23:06:36 +0000220 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
Davide Pesavento494a9552018-02-04 22:16:05 -0500221 auto channels = factory.getChannels();
222 BOOST_CHECK(std::none_of(channels.begin(), channels.end(),
Davide Pesaventod27841b2018-11-13 00:22:24 -0500223 [] (const auto& ch) { return ch->isListening(); }));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000224}
225
Davide Pesavento494a9552018-02-04 22:16:05 -0500226BOOST_AUTO_TEST_CASE(DisableV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000227{
228 const std::string CONFIG = R"CONFIG(
229 face_system
230 {
231 udp
232 {
233 port 7001
234 enable_v4 no
235 enable_v6 yes
236 mcast no
237 }
238 }
239 )CONFIG";
240
241 parseConfig(CONFIG, true);
242 parseConfig(CONFIG, false);
243
Junxiao Shi64d99f22017-01-21 23:06:36 +0000244 checkChannelListEqual(factory, {"udp6://[::]:7001"});
245}
246
Davide Pesavento494a9552018-02-04 22:16:05 -0500247BOOST_AUTO_TEST_CASE(DisableV6)
248{
249 const std::string CONFIG = R"CONFIG(
250 face_system
251 {
252 udp
253 {
254 port 7001
255 enable_v4 yes
256 enable_v6 no
257 mcast no
258 }
259 }
260 )CONFIG";
261
262 parseConfig(CONFIG, true);
263 parseConfig(CONFIG, false);
264
265 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
266}
267
Davide Pesaventobb734df2017-10-24 18:05:36 -0400268BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixture)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000269{
Junxiao Shi64d99f22017-01-21 23:06:36 +0000270 const std::string CONFIG_WITH_MCAST = R"CONFIG(
271 face_system
272 {
273 udp
274 {
275 mcast yes
276 }
277 }
278 )CONFIG";
279 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
280 face_system
281 {
282 udp
283 {
284 mcast no
285 }
286 }
287 )CONFIG";
288
289 parseConfig(CONFIG_WITHOUT_MCAST, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400290 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500291 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000292
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500293#ifdef __linux__
294 // need superuser privileges to create multicast faces on Linux
295 SKIP_IF_NOT_SUPERUSER();
296#endif // __linux__
Junxiao Shi64d99f22017-01-21 23:06:36 +0000297
298 parseConfig(CONFIG_WITH_MCAST, false);
299 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500300 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), netifsV4.size());
301 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), netifsV6.size());
Junxiao Shi64d99f22017-01-21 23:06:36 +0000302
Alexander Afanasyev3a2339a2020-05-27 23:05:06 -0400303 BOOST_REQUIRE_EQUAL(factory.getChannels().size(), 2);
304 for (const auto& face : this->listUdp4McastFaces()) {
305 BOOST_REQUIRE(face->getChannel().lock());
306 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp4");
307 }
308
309 for (const auto& face : this->listUdp6McastFaces()) {
310 BOOST_REQUIRE(face->getChannel().lock());
311 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp6");
312 }
313
Junxiao Shi64d99f22017-01-21 23:06:36 +0000314 parseConfig(CONFIG_WITHOUT_MCAST, false);
315 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400316 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500317 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000318}
319
Davide Pesaventobb734df2017-10-24 18:05:36 -0400320BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixture)
Teng Liangfe4fce32017-03-29 04:49:38 +0000321{
322#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500323 // need superuser privileges to create multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000324 SKIP_IF_NOT_SUPERUSER();
325#endif // __linux__
326 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
327
328 const std::string CONFIG = R"CONFIG(
329 face_system
330 {
331 udp
332 {
333 mcast_ad_hoc yes
334 }
335 }
336 )CONFIG";
337
338 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500339 BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV4.size());
340 BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV6.size());
Teng Liangfe4fce32017-03-29 04:49:38 +0000341}
342
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500343BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixture)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000344{
345#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500346 // need superuser privileges to create multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000347 SKIP_IF_NOT_SUPERUSER();
348#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500349 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000350
351 const std::string CONFIG1 = R"CONFIG(
352 face_system
353 {
354 udp
355 {
356 mcast_group 239.66.30.1
357 mcast_port 7011
358 }
359 }
360 )CONFIG";
361 const std::string CONFIG2 = R"CONFIG(
362 face_system
363 {
364 udp
365 {
366 mcast_group 239.66.30.2
367 mcast_port 7012
368 }
369 }
370 )CONFIG";
371
372 parseConfig(CONFIG1, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400373 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500374 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
375 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.1:7011"));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000376
377 parseConfig(CONFIG2, false);
378 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400379 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500380 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
381 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.2:7012"));
382}
383
384BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixture)
385{
386#ifdef __linux__
387 // need superuser privileges to create multicast faces on Linux
388 SKIP_IF_NOT_SUPERUSER();
389#endif // __linux__
390 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
391
392 const std::string CONFIG1 = R"CONFIG(
393 face_system
394 {
395 udp
396 {
397 mcast_group_v6 ff02::1101
398 mcast_port_v6 7011
399 }
400 }
401 )CONFIG";
402 const std::string CONFIG2 = R"CONFIG(
403 face_system
404 {
405 udp
406 {
407 mcast_group_v6 ff02::1102
408 mcast_port_v6 7012
409 }
410 }
411 )CONFIG";
412
413 parseConfig(CONFIG1, false);
414 auto udpMcastFaces = this->listUdp6McastFaces();
415 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
416 auto expectedAddr = boost::asio::ip::address_v6::from_string("ff02::1101");
417 expectedAddr.scope_id(netifsV6.front()->getIndex());
418 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri(udp::Endpoint(expectedAddr, 7011)));
419
420 parseConfig(CONFIG2, false);
421 g_io.poll();
422 udpMcastFaces = this->listUdp6McastFaces();
423 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
424 expectedAddr = boost::asio::ip::address_v6::from_string("ff02::1102");
425 expectedAddr.scope_id(netifsV6.front()->getIndex());
426 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri(udp::Endpoint(expectedAddr, 7012)));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000427}
428
Davide Pesaventobb734df2017-10-24 18:05:36 -0400429BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000430{
431#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500432 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000433 SKIP_IF_NOT_SUPERUSER();
434#endif // __linux__
435 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
436
437 std::string CONFIG = R"CONFIG(
438 face_system
439 {
440 udp
441 {
442 whitelist
443 {
444 ifname %ifname
445 }
446 }
447 }
448 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000449 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000450
451 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500452
Davide Pesaventobb734df2017-10-24 18:05:36 -0400453 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500454 BOOST_CHECK_LE(udpMcastFaces.size(), 1);
455 auto udpMcastFacesV6 = this->listUdp6McastFaces();
456 BOOST_CHECK_LE(udpMcastFacesV6.size(), 1);
457 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
458 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
459 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
460 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000461}
462
Davide Pesaventobb734df2017-10-24 18:05:36 -0400463BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000464{
465#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500466 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000467 SKIP_IF_NOT_SUPERUSER();
468#endif // __linux__
469 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
470
471 std::string CONFIG = R"CONFIG(
472 face_system
473 {
474 udp
475 {
476 blacklist
477 {
478 ifname %ifname
479 }
480 }
481 }
482 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000483 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000484
485 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500486
Davide Pesaventobb734df2017-10-24 18:05:36 -0400487 auto udpMcastFaces = this->listUdp4McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500488 if (!netifsV4.empty())
489 BOOST_CHECK_GE(udpMcastFaces.size(), netifsV4.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500490 auto udpMcastFacesV6 = this->listUdp6McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500491 if (!netifsV6.empty())
492 BOOST_CHECK_GE(udpMcastFacesV6.size(), netifsV6.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500493 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
494 BOOST_CHECK_LT(udpMcastFaces.size(), netifsV4.size() + netifsV6.size());
495 BOOST_CHECK(std::none_of(udpMcastFaces.begin(), udpMcastFaces.end(),
496 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000497}
498
Davide Pesaventobb734df2017-10-24 18:05:36 -0400499BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000500{
501#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500502 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000503 SKIP_IF_NOT_SUPERUSER();
504#endif // __linux__
505 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
506
507 std::string CONFIG1 = R"CONFIG(
508 face_system
509 {
510 udp
511 {
512 whitelist
513 {
514 ifname %ifname
515 }
516 }
517 }
518 )CONFIG";
519 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000520 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
521 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000522
523 parseConfig(CONFIG1, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500524
Davide Pesaventobb734df2017-10-24 18:05:36 -0400525 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500526 auto udpMcastFacesV6 = this->listUdp6McastFaces();
527 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
528 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
529 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
530 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000531
532 parseConfig(CONFIG2, false);
533 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500534
Davide Pesaventobb734df2017-10-24 18:05:36 -0400535 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500536 udpMcastFacesV6 = this->listUdp6McastFaces();
537 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
538 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
539 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
540 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.back()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000541}
542
Junxiao Shi64d99f22017-01-21 23:06:36 +0000543BOOST_AUTO_TEST_CASE(Omitted)
544{
545 const std::string CONFIG = R"CONFIG(
546 face_system
547 {
548 }
549 )CONFIG";
550
551 parseConfig(CONFIG, true);
552 parseConfig(CONFIG, false);
553
Junxiao Shi64d99f22017-01-21 23:06:36 +0000554 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
555 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500556 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp6", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000557}
558
Davide Pesaventobb734df2017-10-24 18:05:36 -0400559BOOST_AUTO_TEST_CASE(AllDisabled)
560{
561 const std::string CONFIG = R"CONFIG(
562 face_system
563 {
564 udp
565 {
566 enable_v4 no
567 enable_v6 no
568 mcast no
569 }
570 }
571 )CONFIG";
572
573 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
574 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
575}
576
Davide Pesavento494a9552018-02-04 22:16:05 -0500577BOOST_AUTO_TEST_CASE(BadListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000578{
579 const std::string CONFIG = R"CONFIG(
580 face_system
581 {
582 udp
583 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500584 listen hello
585 }
586 }
587 )CONFIG";
588
589 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
590 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
591}
592
Davide Pesavento494a9552018-02-04 22:16:05 -0500593BOOST_AUTO_TEST_CASE(BadPort)
594{
595 // not a number
596 const std::string CONFIG1 = R"CONFIG(
597 face_system
598 {
599 udp
600 {
601 port hello
602 }
603 }
604 )CONFIG";
605
606 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
607 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
608
609 // negative number
610 const std::string CONFIG2 = R"CONFIG(
611 face_system
612 {
613 udp
614 {
615 port -1
616 }
617 }
618 )CONFIG";
619
620 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
621 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
622
623 // out of range
624 const std::string CONFIG3 = R"CONFIG(
625 face_system
626 {
627 udp
628 {
629 port 65536
630 }
631 }
632 )CONFIG";
633
634 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
635 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
636}
637
Davide Pesavento494a9552018-02-04 22:16:05 -0500638BOOST_AUTO_TEST_CASE(BadIdleTimeout)
639{
640 // not a number
641 const std::string CONFIG1 = R"CONFIG(
642 face_system
643 {
644 udp
645 {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000646 idle_timeout hello
647 }
648 }
649 )CONFIG";
650
Davide Pesavento494a9552018-02-04 22:16:05 -0500651 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
652 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
653
654 // negative number
655 const std::string CONFIG2 = R"CONFIG(
656 face_system
657 {
658 udp
659 {
660 idle_timeout -15
661 }
662 }
663 )CONFIG";
664
665 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
666 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000667}
668
669BOOST_AUTO_TEST_CASE(BadMcast)
670{
671 const std::string CONFIG = R"CONFIG(
672 face_system
673 {
674 udp
675 {
676 mcast hello
677 }
678 }
679 )CONFIG";
680
681 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
682 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
683}
684
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500685BOOST_AUTO_TEST_CASE(BadMcastGroupV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000686{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400687 // not an address
688 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000689 face_system
690 {
691 udp
692 {
693 mcast_group hello
694 }
695 }
696 )CONFIG";
697
Davide Pesaventobb734df2017-10-24 18:05:36 -0400698 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
699 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000700
Davide Pesaventobb734df2017-10-24 18:05:36 -0400701 // non-multicast address
702 const std::string CONFIG2 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000703 face_system
704 {
705 udp
706 {
707 mcast_group 10.0.0.1
708 }
709 }
710 )CONFIG";
711
Davide Pesaventobb734df2017-10-24 18:05:36 -0400712 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
713 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000714
Davide Pesaventobb734df2017-10-24 18:05:36 -0400715 // wrong address family
716 const std::string CONFIG3 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000717 face_system
718 {
719 udp
720 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400721 mcast_group ff02::1234
Junxiao Shi64d99f22017-01-21 23:06:36 +0000722 }
723 }
724 )CONFIG";
725
Davide Pesaventobb734df2017-10-24 18:05:36 -0400726 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
727 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000728}
729
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500730BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
731{
732 // not an address
733 const std::string CONFIG1 = R"CONFIG(
734 face_system
735 {
736 udp
737 {
738 mcast_group_v6 foo
739 }
740 }
741 )CONFIG";
742
743 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
744 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
745
746 // non-multicast address
747 const std::string CONFIG2 = R"CONFIG(
748 face_system
749 {
750 udp
751 {
752 mcast_group_v6 fe80::1234
753 }
754 }
755 )CONFIG";
756
757 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
758 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
759
760 // wrong address family
761 const std::string CONFIG3 = R"CONFIG(
762 face_system
763 {
764 udp
765 {
766 mcast_group_v6 224.0.23.170
767 }
768 }
769 )CONFIG";
770
771 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
772 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
773}
774
775BOOST_AUTO_TEST_CASE(BadMcastPortV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000776{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400777 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000778 face_system
779 {
780 udp
781 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400782 mcast_port hey
Junxiao Shi64d99f22017-01-21 23:06:36 +0000783 }
784 }
785 )CONFIG";
786
Davide Pesaventobb734df2017-10-24 18:05:36 -0400787 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
788 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
789
790 const std::string CONFIG2 = R"CONFIG(
791 face_system
792 {
793 udp
794 {
795 mcast_port 99999
796 }
797 }
798 )CONFIG";
799
800 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
801 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000802}
803
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500804BOOST_AUTO_TEST_CASE(BadMcastPortV6)
805{
806 const std::string CONFIG1 = R"CONFIG(
807 face_system
808 {
809 udp
810 {
811 mcast_port_v6 bar
812 }
813 }
814 )CONFIG";
815
816 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
817 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
818
819 const std::string CONFIG2 = R"CONFIG(
820 face_system
821 {
822 udp
823 {
824 mcast_port_v6 99999
825 }
826 }
827 )CONFIG";
828
829 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
830 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
831}
832
Junxiao Shi64d99f22017-01-21 23:06:36 +0000833BOOST_AUTO_TEST_CASE(UnknownOption)
834{
835 const std::string CONFIG = R"CONFIG(
836 face_system
837 {
838 udp
839 {
840 hello
841 }
842 }
843 )CONFIG";
844
845 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
846 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
847}
848
849BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
850
Junxiao Shicde37ad2015-12-24 01:02:05 -0700851BOOST_AUTO_TEST_CASE(GetChannels)
852{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400853 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700854
Davide Pesaventob15276f2017-07-15 16:27:13 -0400855 std::set<std::string> expected;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400856 expected.insert(createChannel("127.0.0.1", 20070)->getUri().toString());
857 expected.insert(createChannel("127.0.0.1", 20071)->getUri().toString());
858 expected.insert(createChannel("::1", 20071)->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400859 checkChannelListEqual(factory, expected);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700860}
861
Davide Pesaventobb734df2017-10-24 18:05:36 -0400862BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700863{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400864 auto channel1 = createChannel("127.0.0.1", 20070);
865 auto channel1a = createChannel("127.0.0.1", 20070);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700866 BOOST_CHECK_EQUAL(channel1, channel1a);
867 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
868
Davide Pesaventobb734df2017-10-24 18:05:36 -0400869 auto channel2 = createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700870 BOOST_CHECK_NE(channel1, channel2);
871
Davide Pesaventobb734df2017-10-24 18:05:36 -0400872 auto channel3 = createChannel("::1", 20071);
Weiwei Liu72cee942016-02-04 16:49:19 -0700873 BOOST_CHECK_NE(channel2, channel3);
874 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700875
Davide Pesaventobb734df2017-10-24 18:05:36 -0400876#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500877 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400878 SKIP_IF_NOT_SUPERUSER();
879#endif // __linux__
Davide Pesaventobb734df2017-10-24 18:05:36 -0400880
Davide Pesavento19779d82019-02-14 13:40:04 -0500881 // createChannel with a local endpoint that has already been allocated to a UDP multicast face
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500882 if (!netifsV4.empty()) {
883 auto mcastFace = createMulticastFace("127.0.0.1", "224.0.0.254", 20072);
884 BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", 20072), UdpFactory::Error,
885 [] (const UdpFactory::Error& e) {
886 return strcmp(e.what(),
887 "Cannot create UDP channel on 127.0.0.1:20072, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500888 "endpoint already allocated to a UDP multicast face") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500889 });
890 }
891 if (!netifsV6.empty()) {
892 auto mcastFace = createMulticastFace("::1", "ff02::114", 20072);
893 BOOST_CHECK_EXCEPTION(createChannel("::1", 20072), UdpFactory::Error,
894 [] (const UdpFactory::Error& e) {
895 return strcmp(e.what(),
896 "Cannot create UDP channel on [::1]:20072, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500897 "endpoint already allocated to a UDP multicast face") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500898 });
899 }
Weiwei Liu72cee942016-02-04 16:49:19 -0700900}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700901
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500902BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixture)
Weiwei Liu72cee942016-02-04 16:49:19 -0700903{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400904#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500905 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400906 SKIP_IF_NOT_SUPERUSER();
907#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500908 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400909
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500910 auto multicastFace1 = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
911 auto multicastFace1a = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
912 auto multicastFace2 = createMulticastFace("127.0.0.1", "224.0.0.254", 20030);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700913 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500914 BOOST_CHECK_NE(multicastFace1, multicastFace2);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700915
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500916 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V4);
917 if (!address.is_unspecified()) {
918 auto multicastFace3 = createMulticastFace(address.to_string(), "224.0.0.254", 20070);
919 BOOST_CHECK_NE(multicastFace1, multicastFace3);
920 BOOST_CHECK_NE(multicastFace2, multicastFace3);
921 }
922
923 // create with a local endpoint already used by a channel
Davide Pesaventobb734df2017-10-24 18:05:36 -0400924 auto channel = createChannel("127.0.0.1", 20071);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500925 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.254", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700926 [] (const UdpFactory::Error& e) {
927 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500928 "Cannot create UDP multicast face on 127.0.0.1:20071, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500929 "endpoint already allocated to a UDP channel") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -0700930 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700931
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500932 // create with a local endpoint already used by a multicast face on a different multicast group
Davide Pesaventobb734df2017-10-24 18:05:36 -0400933 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.42", 20070), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700934 [] (const UdpFactory::Error& e) {
935 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500936 "Cannot create UDP multicast face on 127.0.0.1:20070, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500937 "endpoint already allocated to a different UDP multicast face") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -0700938 });
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500939}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700940
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500941BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixture)
942{
943#ifdef __linux__
944 // need superuser privileges to create multicast faces on Linux
945 SKIP_IF_NOT_SUPERUSER();
946#endif // __linux__
947 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
948
949 auto multicastFace1 = createMulticastFace("::1", "ff02::114", 20070);
950 auto multicastFace1a = createMulticastFace("::1", "ff02::114", 20070);
951 auto multicastFace2 = createMulticastFace("::1", "ff02::114", 20030);
952 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
953 BOOST_CHECK_NE(multicastFace1, multicastFace2);
954
955 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V6);
956 if (!address.is_unspecified()) {
957 auto multicastFace3 = createMulticastFace(address.to_string(), "ff02::114", 20070);
958 BOOST_CHECK_NE(multicastFace1, multicastFace3);
959 BOOST_CHECK_NE(multicastFace2, multicastFace3);
960 }
961
962 // create with a local endpoint already used by a channel
963 auto channel = createChannel("::1", 20071);
964 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::114", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700965 [] (const UdpFactory::Error& e) {
966 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500967 "Cannot create UDP multicast face on [::1]:20071, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500968 "endpoint already allocated to a UDP channel") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500969 });
970
971 // create with a local endpoint already used by a multicast face on a different multicast group
972 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::42", 20070), UdpFactory::Error,
973 [] (const UdpFactory::Error& e) {
974 return strcmp(e.what(),
975 "Cannot create UDP multicast face on [::1]:20070, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500976 "endpoint already allocated to a different UDP multicast face") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -0700977 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700978}
979
Davide Pesaventob15276f2017-07-15 16:27:13 -0400980BOOST_AUTO_TEST_CASE(CreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700981{
Eric Newberry42602412016-08-27 09:33:18 -0700982 createFace(factory,
983 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000984 {},
Eric Newberry812d6152018-06-06 15:06:01 -0700985 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700986 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700987
Davide Pesaventobb734df2017-10-24 18:05:36 -0400988 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700989
Eric Newberry42602412016-08-27 09:33:18 -0700990 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400991 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000992 {},
Eric Newberry812d6152018-06-06 15:06:01 -0700993 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700994 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +0000995
Eric Newberry42602412016-08-27 09:33:18 -0700996 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400997 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000998 {},
Eric Newberry812d6152018-06-06 15:06:01 -0700999 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001000 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001001
Eric Newberry42602412016-08-27 09:33:18 -07001002 createFace(factory,
1003 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001004 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001005 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -04001006 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1007
Eric Newberry2642cd22017-07-13 21:34:53 -04001008 createFace(factory,
1009 FaceUri("udp4://127.0.0.1:20073"),
1010 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001011 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, true, false},
Eric Newberry0c3e57b2018-01-25 20:54:46 -07001012 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1013
1014 createFace(factory,
1015 FaceUri("udp4://127.0.0.1:20073"),
1016 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001017 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, true},
1018 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1019
1020 createFace(factory,
1021 FaceUri("udp4://127.0.0.1:20074"),
1022 {},
1023 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, 1000, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001024 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001025}
1026
Davide Pesaventob15276f2017-07-15 16:27:13 -04001027BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001028{
Davide Pesaventobb734df2017-10-24 18:05:36 -04001029 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001030
Eric Newberry42602412016-08-27 09:33:18 -07001031 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001032 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001033 FaceUri("udp4://127.0.0.1:20071"),
Eric Newberry812d6152018-06-06 15:06:01 -07001034 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001035 {CreateFaceExpectedResult::FAILURE, 406,
1036 "Unicast UDP faces cannot be created with a LocalUri"});
1037
1038 createFace(factory,
1039 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001040 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001041 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001042 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001043 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +00001044
1045 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001046 FaceUri("udp4://233.252.0.1:23252"),
1047 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001048 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry78e32b02017-04-01 14:34:44 +00001049 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001050 "Cannot create multicast UDP faces"});
1051
1052 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001053 FaceUri("udp4://127.0.0.1:20072"),
1054 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001055 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001056 {CreateFaceExpectedResult::FAILURE, 406,
1057 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001058}
1059
Junxiao Shicde37ad2015-12-24 01:02:05 -07001060BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
1061BOOST_AUTO_TEST_SUITE_END() // Face
1062
1063} // namespace tests
Junxiao Shi64d99f22017-01-21 23:06:36 +00001064} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -07001065} // namespace nfd