blob: c243ddcf4a4e1a97b9b5e8073b3d2b722516a9cc [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/*
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04003 * Copyright (c) 2014-2022, 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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040033namespace nfd::tests {
34
35using face::UdpChannel;
36using face::UdpFactory;
Junxiao Shicde37ad2015-12-24 01:02:05 -070037
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040038class UdpFactoryFixture : public FaceSystemFactoryFixture<UdpFactory>
39{
40protected:
41 shared_ptr<UdpChannel>
Davide Pesaventobb734df2017-10-24 18:05:36 -040042 createChannel(const std::string& localIp, uint16_t localPort)
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040043 {
Davide Pesavento9c33b902018-05-20 01:30:29 -040044 udp::Endpoint endpoint(boost::asio::ip::address::from_string(localIp), localPort);
Davide Pesavento494a9552018-02-04 22:16:05 -050045 return factory.createChannel(endpoint, 5_min);
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040046 }
47};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000048
Davide Pesaventobb734df2017-10-24 18:05:36 -040049class UdpFactoryMcastFixture : public UdpFactoryFixture
50{
51protected:
52 UdpFactoryMcastFixture()
53 {
54 for (const auto& netif : collectNetworkInterfaces()) {
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050055 // same filtering logic as UdpFactory::applyMcastConfigToNetif()
56 if (netif->isUp() && !netif->isLoopback() && netif->canMulticast()) {
57 bool hasValidIpAddress = false;
58 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
59 hasValidIpAddress = true;
60 netifsV4.push_back(netif);
61 }
62 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V6)) {
63 hasValidIpAddress = true;
64 netifsV6.push_back(netif);
65 }
66 if (hasValidIpAddress) {
67 netifs.push_back(netif);
68 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040069 }
70 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040071 this->copyRealNetifsToNetmon();
72 }
73
74 shared_ptr<Face>
75 createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
76 {
Davide Pesavento9c33b902018-05-20 01:30:29 -040077 auto localAddress = boost::asio::ip::address::from_string(localIp);
78 udp::Endpoint mcastEndpoint(boost::asio::ip::address::from_string(mcastIp), mcastPort);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050079
80 if (localAddress.is_v4()) {
81 BOOST_ASSERT(!netifsV4.empty());
82 return factory.createMulticastFace(netifsV4.front(), localAddress, mcastEndpoint);
83 }
84 else {
85 BOOST_ASSERT(!netifsV6.empty());
86 return factory.createMulticastFace(netifsV6.front(), localAddress, mcastEndpoint);
87 }
88 }
89
90 /** \brief returns a non-loopback IP address suitable for the creation of a UDP multicast face
91 */
92 boost::asio::ip::address
93 findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
94 {
95 const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
96 for (const auto& netif : netifList) {
97 for (const auto& a : netif->getNetworkAddresses()) {
98 if (a.getFamily() == af && !a.getIp().is_loopback())
99 return a.getIp();
100 }
101 }
102 return {};
Davide Pesaventobb734df2017-10-24 18:05:36 -0400103 }
104
105 std::vector<const Face*>
106 listUdp4McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
107 {
108 return this->listFacesByScheme("udp4", linkType);
109 }
110
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500111 std::vector<const Face*>
112 listUdp6McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
113 {
114 return this->listFacesByScheme("udp6", linkType);
115 }
116
117 /** \brief determine whether \p netif has at least one IP address of the given family
Davide Pesaventobb734df2017-10-24 18:05:36 -0400118 */
119 static bool
120 hasAddressFamily(const NetworkInterface& netif, ndn::net::AddressFamily af)
121 {
122 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
123 [af] (const NetworkAddress& a) { return a.getFamily() == af; });
124 }
125
126 /** \brief determine whether a UDP multicast face is created on \p netif
127 */
128 static bool
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500129 isFaceOnNetif(const Face& face, const NetworkInterface& netif)
Davide Pesaventobb734df2017-10-24 18:05:36 -0400130 {
Davide Pesavento9c33b902018-05-20 01:30:29 -0400131 auto ip = boost::asio::ip::address::from_string(face.getLocalUri().getHost());
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500132 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
Davide Pesaventobb734df2017-10-24 18:05:36 -0400133 [ip] (const NetworkAddress& a) { return a.getIp() == ip; });
134 }
135
136protected:
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500137 /** \brief MulticastUdpTransport-capable network interfaces (IPv4 + IPv6)
138 *
139 * This should be used in test cases that do not depend on a specific address family
Davide Pesaventobb734df2017-10-24 18:05:36 -0400140 */
141 std::vector<shared_ptr<const NetworkInterface>> netifs;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500142
143 /** \brief MulticastUdpTransport-capable network interfaces (IPv4 only)
144 */
145 std::vector<shared_ptr<const NetworkInterface>> netifsV4;
146
147 /** \brief MulticastUdpTransport-capable network interfaces (IPv6 only)
148 */
149 std::vector<shared_ptr<const NetworkInterface>> netifsV6;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400150};
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
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500161#define SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(n) \
162 do { \
163 if (this->netifsV4.size() < (n)) { \
164 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
165 " or more IPv4 MulticastUdpTransport-capable network interfaces"); \
166 return; \
167 } \
168 } while (false)
169
170#define SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(n) \
171 do { \
172 if (this->netifsV6.size() < (n)) { \
173 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
174 " or more IPv6 MulticastUdpTransport-capable network interfaces"); \
175 return; \
176 } \
177 } while (false)
178
Junxiao Shicde37ad2015-12-24 01:02:05 -0700179BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000180BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700181
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000182BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000183
Davide Pesavento494a9552018-02-04 22:16:05 -0500184using nfd::Face;
185
186BOOST_AUTO_TEST_CASE(Defaults)
187{
188 const std::string CONFIG = R"CONFIG(
189 face_system
190 {
191 udp
192 }
193 )CONFIG";
194
195 parseConfig(CONFIG, true);
196 parseConfig(CONFIG, false);
197
198 checkChannelListEqual(factory, {"udp4://0.0.0.0:6363", "udp6://[::]:6363"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700199 for (const auto& ch : factory.getChannels()) {
200 BOOST_CHECK(ch->isListening());
201 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), ndn::MAX_NDN_PACKET_SIZE);
202 }
Davide Pesavento494a9552018-02-04 22:16:05 -0500203}
204
205BOOST_AUTO_TEST_CASE(DisableListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000206{
207 const std::string CONFIG = R"CONFIG(
208 face_system
209 {
210 udp
211 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500212 listen no
Junxiao Shi64d99f22017-01-21 23:06:36 +0000213 port 7001
Junxiao Shi64d99f22017-01-21 23:06:36 +0000214 mcast no
215 }
216 }
217 )CONFIG";
218
219 parseConfig(CONFIG, true);
220 parseConfig(CONFIG, false);
221
Junxiao Shi64d99f22017-01-21 23:06:36 +0000222 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700223 for (const auto& ch : factory.getChannels()) {
224 BOOST_CHECK(!ch->isListening());
225 }
Junxiao Shi64d99f22017-01-21 23:06:36 +0000226}
227
Davide Pesavento494a9552018-02-04 22:16:05 -0500228BOOST_AUTO_TEST_CASE(DisableV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000229{
230 const std::string CONFIG = R"CONFIG(
231 face_system
232 {
233 udp
234 {
235 port 7001
236 enable_v4 no
237 enable_v6 yes
Junxiao Shia6286a92021-02-23 06:43:52 -0700238 unicast_mtu 1452
Junxiao Shi64d99f22017-01-21 23:06:36 +0000239 mcast no
240 }
241 }
242 )CONFIG";
243
244 parseConfig(CONFIG, true);
245 parseConfig(CONFIG, false);
246
Junxiao Shi64d99f22017-01-21 23:06:36 +0000247 checkChannelListEqual(factory, {"udp6://[::]:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700248 for (const auto& ch : factory.getChannels()) {
249 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
250 }
Junxiao Shi64d99f22017-01-21 23:06:36 +0000251}
252
Davide Pesavento494a9552018-02-04 22:16:05 -0500253BOOST_AUTO_TEST_CASE(DisableV6)
254{
255 const std::string CONFIG = R"CONFIG(
256 face_system
257 {
258 udp
259 {
260 port 7001
261 enable_v4 yes
262 enable_v6 no
Junxiao Shia6286a92021-02-23 06:43:52 -0700263 unicast_mtu 1452
Davide Pesavento494a9552018-02-04 22:16:05 -0500264 mcast no
265 }
266 }
267 )CONFIG";
268
269 parseConfig(CONFIG, true);
270 parseConfig(CONFIG, false);
271
272 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700273 for (const auto& ch : factory.getChannels()) {
274 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
275 }
Davide Pesavento494a9552018-02-04 22:16:05 -0500276}
277
Davide Pesaventobb734df2017-10-24 18:05:36 -0400278BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixture)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000279{
Junxiao Shi64d99f22017-01-21 23:06:36 +0000280 const std::string CONFIG_WITH_MCAST = R"CONFIG(
281 face_system
282 {
283 udp
284 {
285 mcast yes
286 }
287 }
288 )CONFIG";
289 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
290 face_system
291 {
292 udp
293 {
294 mcast no
295 }
296 }
297 )CONFIG";
298
299 parseConfig(CONFIG_WITHOUT_MCAST, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400300 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500301 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000302
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500303#ifdef __linux__
304 // need superuser privileges to create multicast faces on Linux
305 SKIP_IF_NOT_SUPERUSER();
306#endif // __linux__
Junxiao Shi64d99f22017-01-21 23:06:36 +0000307
308 parseConfig(CONFIG_WITH_MCAST, false);
309 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500310 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), netifsV4.size());
311 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), netifsV6.size());
Junxiao Shi64d99f22017-01-21 23:06:36 +0000312
Alexander Afanasyev3a2339a2020-05-27 23:05:06 -0400313 BOOST_REQUIRE_EQUAL(factory.getChannels().size(), 2);
314 for (const auto& face : this->listUdp4McastFaces()) {
315 BOOST_REQUIRE(face->getChannel().lock());
316 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp4");
317 }
318
319 for (const auto& face : this->listUdp6McastFaces()) {
320 BOOST_REQUIRE(face->getChannel().lock());
321 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp6");
322 }
323
Junxiao Shi64d99f22017-01-21 23:06:36 +0000324 parseConfig(CONFIG_WITHOUT_MCAST, false);
325 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400326 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500327 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000328}
329
Davide Pesaventobb734df2017-10-24 18:05:36 -0400330BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixture)
Teng Liangfe4fce32017-03-29 04:49:38 +0000331{
332#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500333 // need superuser privileges to create multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000334 SKIP_IF_NOT_SUPERUSER();
335#endif // __linux__
336 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
337
338 const std::string CONFIG = R"CONFIG(
339 face_system
340 {
341 udp
342 {
343 mcast_ad_hoc yes
344 }
345 }
346 )CONFIG";
347
348 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500349 BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV4.size());
350 BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV6.size());
Teng Liangfe4fce32017-03-29 04:49:38 +0000351}
352
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500353BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixture)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000354{
355#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500356 // need superuser privileges to create multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000357 SKIP_IF_NOT_SUPERUSER();
358#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500359 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000360
361 const std::string CONFIG1 = R"CONFIG(
362 face_system
363 {
364 udp
365 {
366 mcast_group 239.66.30.1
367 mcast_port 7011
368 }
369 }
370 )CONFIG";
371 const std::string CONFIG2 = R"CONFIG(
372 face_system
373 {
374 udp
375 {
376 mcast_group 239.66.30.2
377 mcast_port 7012
378 }
379 }
380 )CONFIG";
381
382 parseConfig(CONFIG1, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400383 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500384 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
385 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.1:7011"));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000386
387 parseConfig(CONFIG2, false);
388 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400389 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500390 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
391 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.2:7012"));
392}
393
394BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixture)
395{
396#ifdef __linux__
397 // need superuser privileges to create multicast faces on Linux
398 SKIP_IF_NOT_SUPERUSER();
399#endif // __linux__
400 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
401
402 const std::string CONFIG1 = R"CONFIG(
403 face_system
404 {
405 udp
406 {
407 mcast_group_v6 ff02::1101
408 mcast_port_v6 7011
409 }
410 }
411 )CONFIG";
412 const std::string CONFIG2 = R"CONFIG(
413 face_system
414 {
415 udp
416 {
417 mcast_group_v6 ff02::1102
418 mcast_port_v6 7012
419 }
420 }
421 )CONFIG";
422
423 parseConfig(CONFIG1, false);
424 auto udpMcastFaces = this->listUdp6McastFaces();
425 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
426 auto expectedAddr = boost::asio::ip::address_v6::from_string("ff02::1101");
427 expectedAddr.scope_id(netifsV6.front()->getIndex());
428 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri(udp::Endpoint(expectedAddr, 7011)));
429
430 parseConfig(CONFIG2, false);
431 g_io.poll();
432 udpMcastFaces = this->listUdp6McastFaces();
433 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
434 expectedAddr = boost::asio::ip::address_v6::from_string("ff02::1102");
435 expectedAddr.scope_id(netifsV6.front()->getIndex());
436 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri(udp::Endpoint(expectedAddr, 7012)));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000437}
438
Davide Pesaventobb734df2017-10-24 18:05:36 -0400439BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000440{
441#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500442 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000443 SKIP_IF_NOT_SUPERUSER();
444#endif // __linux__
445 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
446
447 std::string CONFIG = R"CONFIG(
448 face_system
449 {
450 udp
451 {
452 whitelist
453 {
454 ifname %ifname
455 }
456 }
457 }
458 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000459 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000460
461 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500462
Davide Pesaventobb734df2017-10-24 18:05:36 -0400463 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500464 BOOST_CHECK_LE(udpMcastFaces.size(), 1);
465 auto udpMcastFacesV6 = this->listUdp6McastFaces();
466 BOOST_CHECK_LE(udpMcastFacesV6.size(), 1);
467 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
468 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
469 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
470 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000471}
472
Davide Pesaventobb734df2017-10-24 18:05:36 -0400473BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000474{
475#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500476 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000477 SKIP_IF_NOT_SUPERUSER();
478#endif // __linux__
479 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
480
481 std::string CONFIG = R"CONFIG(
482 face_system
483 {
484 udp
485 {
486 blacklist
487 {
488 ifname %ifname
489 }
490 }
491 }
492 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000493 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000494
495 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500496
Davide Pesaventobb734df2017-10-24 18:05:36 -0400497 auto udpMcastFaces = this->listUdp4McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500498 if (!netifsV4.empty())
499 BOOST_CHECK_GE(udpMcastFaces.size(), netifsV4.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500500 auto udpMcastFacesV6 = this->listUdp6McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500501 if (!netifsV6.empty())
502 BOOST_CHECK_GE(udpMcastFacesV6.size(), netifsV6.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500503 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
504 BOOST_CHECK_LT(udpMcastFaces.size(), netifsV4.size() + netifsV6.size());
505 BOOST_CHECK(std::none_of(udpMcastFaces.begin(), udpMcastFaces.end(),
506 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000507}
508
Davide Pesaventobb734df2017-10-24 18:05:36 -0400509BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000510{
511#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500512 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000513 SKIP_IF_NOT_SUPERUSER();
514#endif // __linux__
515 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
516
517 std::string CONFIG1 = R"CONFIG(
518 face_system
519 {
520 udp
521 {
522 whitelist
523 {
524 ifname %ifname
525 }
526 }
527 }
528 )CONFIG";
529 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000530 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
531 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000532
533 parseConfig(CONFIG1, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500534
Davide Pesaventobb734df2017-10-24 18:05:36 -0400535 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500536 auto 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.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000541
542 parseConfig(CONFIG2, false);
543 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500544
Davide Pesaventobb734df2017-10-24 18:05:36 -0400545 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500546 udpMcastFacesV6 = this->listUdp6McastFaces();
547 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
548 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
549 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
550 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.back()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000551}
552
Junxiao Shi64d99f22017-01-21 23:06:36 +0000553BOOST_AUTO_TEST_CASE(Omitted)
554{
555 const std::string CONFIG = R"CONFIG(
556 face_system
557 {
558 }
559 )CONFIG";
560
561 parseConfig(CONFIG, true);
562 parseConfig(CONFIG, false);
563
Junxiao Shi64d99f22017-01-21 23:06:36 +0000564 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
565 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500566 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp6", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000567}
568
Davide Pesaventobb734df2017-10-24 18:05:36 -0400569BOOST_AUTO_TEST_CASE(AllDisabled)
570{
571 const std::string CONFIG = R"CONFIG(
572 face_system
573 {
574 udp
575 {
576 enable_v4 no
577 enable_v6 no
578 mcast no
579 }
580 }
581 )CONFIG";
582
583 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
584 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
585}
586
Davide Pesavento494a9552018-02-04 22:16:05 -0500587BOOST_AUTO_TEST_CASE(BadListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000588{
589 const std::string CONFIG = R"CONFIG(
590 face_system
591 {
592 udp
593 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500594 listen hello
595 }
596 }
597 )CONFIG";
598
599 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
600 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
601}
602
Davide Pesavento494a9552018-02-04 22:16:05 -0500603BOOST_AUTO_TEST_CASE(BadPort)
604{
605 // not a number
606 const std::string CONFIG1 = R"CONFIG(
607 face_system
608 {
609 udp
610 {
611 port hello
612 }
613 }
614 )CONFIG";
615
616 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
617 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
618
619 // negative number
620 const std::string CONFIG2 = R"CONFIG(
621 face_system
622 {
623 udp
624 {
625 port -1
626 }
627 }
628 )CONFIG";
629
630 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
631 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
632
633 // out of range
634 const std::string CONFIG3 = R"CONFIG(
635 face_system
636 {
637 udp
638 {
639 port 65536
640 }
641 }
642 )CONFIG";
643
644 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
645 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
646}
647
Davide Pesavento494a9552018-02-04 22:16:05 -0500648BOOST_AUTO_TEST_CASE(BadIdleTimeout)
649{
650 // not a number
651 const std::string CONFIG1 = R"CONFIG(
652 face_system
653 {
654 udp
655 {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000656 idle_timeout hello
657 }
658 }
659 )CONFIG";
660
Davide Pesavento494a9552018-02-04 22:16:05 -0500661 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
662 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
663
664 // negative number
665 const std::string CONFIG2 = R"CONFIG(
666 face_system
667 {
668 udp
669 {
670 idle_timeout -15
671 }
672 }
673 )CONFIG";
674
675 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
676 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000677}
678
Junxiao Shia6286a92021-02-23 06:43:52 -0700679BOOST_AUTO_TEST_CASE(BadMtu)
680{
681 // not a number
682 const std::string CONFIG1 = R"CONFIG(
683 face_system
684 {
685 udp
686 {
687 unicast_mtu hello
688 }
689 }
690 )CONFIG";
691
692 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
693 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
694
695 // underflow
696 const std::string CONFIG2 = R"CONFIG(
697 face_system
698 {
699 udp
700 {
701 unicast_mtu 63
702 }
703 }
704 )CONFIG";
705
706 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
707 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
708
709 // underflow
710 const std::string CONFIG3 = R"CONFIG(
711 face_system
712 {
713 udp
714 {
715 unicast_mtu 8801
716 }
717 }
718 )CONFIG";
719
720 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
721 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
722}
723
Junxiao Shi64d99f22017-01-21 23:06:36 +0000724BOOST_AUTO_TEST_CASE(BadMcast)
725{
726 const std::string CONFIG = R"CONFIG(
727 face_system
728 {
729 udp
730 {
731 mcast hello
732 }
733 }
734 )CONFIG";
735
736 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
737 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
738}
739
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500740BOOST_AUTO_TEST_CASE(BadMcastGroupV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000741{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400742 // not an address
743 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000744 face_system
745 {
746 udp
747 {
748 mcast_group hello
749 }
750 }
751 )CONFIG";
752
Davide Pesaventobb734df2017-10-24 18:05:36 -0400753 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
754 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000755
Davide Pesaventobb734df2017-10-24 18:05:36 -0400756 // non-multicast address
757 const std::string CONFIG2 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000758 face_system
759 {
760 udp
761 {
762 mcast_group 10.0.0.1
763 }
764 }
765 )CONFIG";
766
Davide Pesaventobb734df2017-10-24 18:05:36 -0400767 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
768 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000769
Davide Pesaventobb734df2017-10-24 18:05:36 -0400770 // wrong address family
771 const std::string CONFIG3 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000772 face_system
773 {
774 udp
775 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400776 mcast_group ff02::1234
Junxiao Shi64d99f22017-01-21 23:06:36 +0000777 }
778 }
779 )CONFIG";
780
Davide Pesaventobb734df2017-10-24 18:05:36 -0400781 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
782 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000783}
784
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500785BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
786{
787 // not an address
788 const std::string CONFIG1 = R"CONFIG(
789 face_system
790 {
791 udp
792 {
793 mcast_group_v6 foo
794 }
795 }
796 )CONFIG";
797
798 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
799 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
800
801 // non-multicast address
802 const std::string CONFIG2 = R"CONFIG(
803 face_system
804 {
805 udp
806 {
807 mcast_group_v6 fe80::1234
808 }
809 }
810 )CONFIG";
811
812 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
813 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
814
815 // wrong address family
816 const std::string CONFIG3 = R"CONFIG(
817 face_system
818 {
819 udp
820 {
821 mcast_group_v6 224.0.23.170
822 }
823 }
824 )CONFIG";
825
826 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
827 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
828}
829
830BOOST_AUTO_TEST_CASE(BadMcastPortV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000831{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400832 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000833 face_system
834 {
835 udp
836 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400837 mcast_port hey
Junxiao Shi64d99f22017-01-21 23:06:36 +0000838 }
839 }
840 )CONFIG";
841
Davide Pesaventobb734df2017-10-24 18:05:36 -0400842 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
843 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
844
845 const std::string CONFIG2 = R"CONFIG(
846 face_system
847 {
848 udp
849 {
850 mcast_port 99999
851 }
852 }
853 )CONFIG";
854
855 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
856 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000857}
858
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500859BOOST_AUTO_TEST_CASE(BadMcastPortV6)
860{
861 const std::string CONFIG1 = R"CONFIG(
862 face_system
863 {
864 udp
865 {
866 mcast_port_v6 bar
867 }
868 }
869 )CONFIG";
870
871 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
872 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
873
874 const std::string CONFIG2 = R"CONFIG(
875 face_system
876 {
877 udp
878 {
879 mcast_port_v6 99999
880 }
881 }
882 )CONFIG";
883
884 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
885 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
886}
887
Junxiao Shi64d99f22017-01-21 23:06:36 +0000888BOOST_AUTO_TEST_CASE(UnknownOption)
889{
890 const std::string CONFIG = R"CONFIG(
891 face_system
892 {
893 udp
894 {
895 hello
896 }
897 }
898 )CONFIG";
899
900 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
901 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
902}
903
904BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
905
Junxiao Shicde37ad2015-12-24 01:02:05 -0700906BOOST_AUTO_TEST_CASE(GetChannels)
907{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400908 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700909
Davide Pesaventob15276f2017-07-15 16:27:13 -0400910 std::set<std::string> expected;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400911 expected.insert(createChannel("127.0.0.1", 20070)->getUri().toString());
912 expected.insert(createChannel("127.0.0.1", 20071)->getUri().toString());
913 expected.insert(createChannel("::1", 20071)->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400914 checkChannelListEqual(factory, expected);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700915}
916
Davide Pesaventobb734df2017-10-24 18:05:36 -0400917BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700918{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400919 auto channel1 = createChannel("127.0.0.1", 20070);
920 auto channel1a = createChannel("127.0.0.1", 20070);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700921 BOOST_CHECK_EQUAL(channel1, channel1a);
922 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
923
Davide Pesaventobb734df2017-10-24 18:05:36 -0400924 auto channel2 = createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700925 BOOST_CHECK_NE(channel1, channel2);
926
Davide Pesaventobb734df2017-10-24 18:05:36 -0400927 auto channel3 = createChannel("::1", 20071);
Weiwei Liu72cee942016-02-04 16:49:19 -0700928 BOOST_CHECK_NE(channel2, channel3);
929 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700930
Davide Pesaventobb734df2017-10-24 18:05:36 -0400931#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500932 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400933 SKIP_IF_NOT_SUPERUSER();
934#endif // __linux__
Davide Pesaventobb734df2017-10-24 18:05:36 -0400935
Davide Pesavento19779d82019-02-14 13:40:04 -0500936 // createChannel with a local endpoint that has already been allocated to a UDP multicast face
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500937 if (!netifsV4.empty()) {
938 auto mcastFace = createMulticastFace("127.0.0.1", "224.0.0.254", 20072);
939 BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", 20072), UdpFactory::Error,
940 [] (const UdpFactory::Error& e) {
941 return strcmp(e.what(),
942 "Cannot create UDP channel on 127.0.0.1:20072, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500943 "endpoint already allocated to a UDP multicast face") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500944 });
945 }
946 if (!netifsV6.empty()) {
947 auto mcastFace = createMulticastFace("::1", "ff02::114", 20072);
948 BOOST_CHECK_EXCEPTION(createChannel("::1", 20072), UdpFactory::Error,
949 [] (const UdpFactory::Error& e) {
950 return strcmp(e.what(),
951 "Cannot create UDP channel on [::1]:20072, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500952 "endpoint already allocated to a UDP multicast face") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500953 });
954 }
Weiwei Liu72cee942016-02-04 16:49:19 -0700955}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700956
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500957BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixture)
Weiwei Liu72cee942016-02-04 16:49:19 -0700958{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400959#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500960 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400961 SKIP_IF_NOT_SUPERUSER();
962#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500963 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400964
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500965 auto multicastFace1 = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
966 auto multicastFace1a = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
967 auto multicastFace2 = createMulticastFace("127.0.0.1", "224.0.0.254", 20030);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700968 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500969 BOOST_CHECK_NE(multicastFace1, multicastFace2);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700970
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500971 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V4);
972 if (!address.is_unspecified()) {
973 auto multicastFace3 = createMulticastFace(address.to_string(), "224.0.0.254", 20070);
974 BOOST_CHECK_NE(multicastFace1, multicastFace3);
975 BOOST_CHECK_NE(multicastFace2, multicastFace3);
976 }
977
978 // create with a local endpoint already used by a channel
Davide Pesaventobb734df2017-10-24 18:05:36 -0400979 auto channel = createChannel("127.0.0.1", 20071);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500980 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.254", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700981 [] (const UdpFactory::Error& e) {
982 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500983 "Cannot create UDP multicast face on 127.0.0.1:20071, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500984 "endpoint already allocated to a UDP channel") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -0700985 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700986
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500987 // create with a local endpoint already used by a multicast face on a different multicast group
Davide Pesaventobb734df2017-10-24 18:05:36 -0400988 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.42", 20070), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700989 [] (const UdpFactory::Error& e) {
990 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500991 "Cannot create UDP multicast face on 127.0.0.1:20070, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500992 "endpoint already allocated to a different UDP multicast face") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -0700993 });
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500994}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700995
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500996BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixture)
997{
998#ifdef __linux__
999 // need superuser privileges to create multicast faces on Linux
1000 SKIP_IF_NOT_SUPERUSER();
1001#endif // __linux__
1002 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
1003
1004 auto multicastFace1 = createMulticastFace("::1", "ff02::114", 20070);
1005 auto multicastFace1a = createMulticastFace("::1", "ff02::114", 20070);
1006 auto multicastFace2 = createMulticastFace("::1", "ff02::114", 20030);
1007 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
1008 BOOST_CHECK_NE(multicastFace1, multicastFace2);
1009
1010 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V6);
1011 if (!address.is_unspecified()) {
1012 auto multicastFace3 = createMulticastFace(address.to_string(), "ff02::114", 20070);
1013 BOOST_CHECK_NE(multicastFace1, multicastFace3);
1014 BOOST_CHECK_NE(multicastFace2, multicastFace3);
1015 }
1016
1017 // create with a local endpoint already used by a channel
1018 auto channel = createChannel("::1", 20071);
1019 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::114", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -07001020 [] (const UdpFactory::Error& e) {
1021 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001022 "Cannot create UDP multicast face on [::1]:20071, "
Davide Pesavento19779d82019-02-14 13:40:04 -05001023 "endpoint already allocated to a UDP channel") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001024 });
1025
1026 // create with a local endpoint already used by a multicast face on a different multicast group
1027 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::42", 20070), UdpFactory::Error,
1028 [] (const UdpFactory::Error& e) {
1029 return strcmp(e.what(),
1030 "Cannot create UDP multicast face on [::1]:20070, "
Davide Pesavento19779d82019-02-14 13:40:04 -05001031 "endpoint already allocated to a different UDP multicast face") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -07001032 });
Junxiao Shicde37ad2015-12-24 01:02:05 -07001033}
1034
Davide Pesaventob15276f2017-07-15 16:27:13 -04001035BOOST_AUTO_TEST_CASE(CreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001036{
Eric Newberry42602412016-08-27 09:33:18 -07001037 createFace(factory,
1038 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001039 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001040 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001041 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001042
Davide Pesaventobb734df2017-10-24 18:05:36 -04001043 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001044
Eric Newberry42602412016-08-27 09:33:18 -07001045 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001046 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001047 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001048 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001049 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +00001050
Eric Newberry42602412016-08-27 09:33:18 -07001051 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001052 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001053 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001054 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001055 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001056
Eric Newberry42602412016-08-27 09:33:18 -07001057 createFace(factory,
1058 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001059 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001060 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -04001061 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1062
Eric Newberry2642cd22017-07-13 21:34:53 -04001063 createFace(factory,
1064 FaceUri("udp4://127.0.0.1:20073"),
1065 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001066 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, true, false},
Eric Newberry0c3e57b2018-01-25 20:54:46 -07001067 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1068
1069 createFace(factory,
1070 FaceUri("udp4://127.0.0.1:20073"),
1071 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001072 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, true},
1073 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1074
1075 createFace(factory,
1076 FaceUri("udp4://127.0.0.1:20074"),
1077 {},
1078 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, 1000, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001079 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001080}
1081
Davide Pesaventob15276f2017-07-15 16:27:13 -04001082BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001083{
Davide Pesaventobb734df2017-10-24 18:05:36 -04001084 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001085
Eric Newberry42602412016-08-27 09:33:18 -07001086 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001087 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001088 FaceUri("udp4://127.0.0.1:20071"),
Eric Newberry812d6152018-06-06 15:06:01 -07001089 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001090 {CreateFaceExpectedResult::FAILURE, 406,
1091 "Unicast UDP faces cannot be created with a LocalUri"});
1092
1093 createFace(factory,
1094 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001095 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001096 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001097 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001098 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +00001099
1100 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001101 FaceUri("udp4://233.252.0.1:23252"),
1102 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001103 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry78e32b02017-04-01 14:34:44 +00001104 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001105 "Cannot create multicast UDP faces"});
1106
1107 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001108 FaceUri("udp4://127.0.0.1:20072"),
1109 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001110 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001111 {CreateFaceExpectedResult::FAILURE, 406,
1112 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001113}
1114
Junxiao Shicde37ad2015-12-24 01:02:05 -07001115BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
1116BOOST_AUTO_TEST_SUITE_END() // Face
1117
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04001118} // namespace nfd::tests