blob: 259dbb35fe4af762e2e406398a85dad7f344a522 [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;
Davide Pesavento279af1c2022-08-29 20:18:32 -040037using ndn::net::NetworkInterface;
Junxiao Shicde37ad2015-12-24 01:02:05 -070038
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040039class UdpFactoryFixture : public FaceSystemFactoryFixture<UdpFactory>
40{
41protected:
42 shared_ptr<UdpChannel>
Davide Pesaventobb734df2017-10-24 18:05:36 -040043 createChannel(const std::string& localIp, uint16_t localPort)
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040044 {
Davide Pesavento9c33b902018-05-20 01:30:29 -040045 udp::Endpoint endpoint(boost::asio::ip::address::from_string(localIp), localPort);
Davide Pesavento494a9552018-02-04 22:16:05 -050046 return factory.createChannel(endpoint, 5_min);
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040047 }
48};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000049
Davide Pesaventobb734df2017-10-24 18:05:36 -040050class UdpFactoryMcastFixture : public UdpFactoryFixture
51{
52protected:
53 UdpFactoryMcastFixture()
54 {
55 for (const auto& netif : collectNetworkInterfaces()) {
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050056 // same filtering logic as UdpFactory::applyMcastConfigToNetif()
57 if (netif->isUp() && !netif->isLoopback() && netif->canMulticast()) {
58 bool hasValidIpAddress = false;
59 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
60 hasValidIpAddress = true;
61 netifsV4.push_back(netif);
62 }
63 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V6)) {
64 hasValidIpAddress = true;
65 netifsV6.push_back(netif);
66 }
67 if (hasValidIpAddress) {
68 netifs.push_back(netif);
69 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040070 }
71 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040072 this->copyRealNetifsToNetmon();
73 }
74
75 shared_ptr<Face>
76 createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
77 {
Davide Pesavento9c33b902018-05-20 01:30:29 -040078 auto localAddress = boost::asio::ip::address::from_string(localIp);
79 udp::Endpoint mcastEndpoint(boost::asio::ip::address::from_string(mcastIp), mcastPort);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050080
81 if (localAddress.is_v4()) {
82 BOOST_ASSERT(!netifsV4.empty());
Davide Pesavento279af1c2022-08-29 20:18:32 -040083 return factory.createMulticastFace(*netifsV4.front(), localAddress, mcastEndpoint);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050084 }
85 else {
86 BOOST_ASSERT(!netifsV6.empty());
Davide Pesavento279af1c2022-08-29 20:18:32 -040087 return factory.createMulticastFace(*netifsV6.front(), localAddress, mcastEndpoint);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050088 }
89 }
90
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040091 /** \brief Returns a non-loopback IP address suitable for the creation of a UDP multicast face.
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050092 */
93 boost::asio::ip::address
94 findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
95 {
96 const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
97 for (const auto& netif : netifList) {
98 for (const auto& a : netif->getNetworkAddresses()) {
99 if (a.getFamily() == af && !a.getIp().is_loopback())
100 return a.getIp();
101 }
102 }
103 return {};
Davide Pesaventobb734df2017-10-24 18:05:36 -0400104 }
105
106 std::vector<const Face*>
107 listUdp4McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
108 {
109 return this->listFacesByScheme("udp4", linkType);
110 }
111
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500112 std::vector<const Face*>
113 listUdp6McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
114 {
115 return this->listFacesByScheme("udp6", linkType);
116 }
117
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400118 /** \brief Determine whether \p netif has at least one IP address of the given family.
Davide Pesaventobb734df2017-10-24 18:05:36 -0400119 */
120 static bool
121 hasAddressFamily(const NetworkInterface& netif, ndn::net::AddressFamily af)
122 {
123 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
Davide Pesavento279af1c2022-08-29 20:18:32 -0400124 [af] (const auto& a) { return a.getFamily() == af; });
Davide Pesaventobb734df2017-10-24 18:05:36 -0400125 }
126
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400127 /** \brief Determine whether a UDP multicast face is created on \p netif.
Davide Pesaventobb734df2017-10-24 18:05:36 -0400128 */
129 static bool
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500130 isFaceOnNetif(const Face& face, const NetworkInterface& netif)
Davide Pesaventobb734df2017-10-24 18:05:36 -0400131 {
Davide Pesavento9c33b902018-05-20 01:30:29 -0400132 auto ip = boost::asio::ip::address::from_string(face.getLocalUri().getHost());
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500133 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
Davide Pesavento279af1c2022-08-29 20:18:32 -0400134 [ip] (const auto& a) { return a.getIp() == ip; });
Davide Pesaventobb734df2017-10-24 18:05:36 -0400135 }
136
137protected:
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400138 /** \brief MulticastUdpTransport-capable network interfaces (IPv4 + IPv6).
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500139 *
140 * This should be used in test cases that do not depend on a specific address family
Davide Pesaventobb734df2017-10-24 18:05:36 -0400141 */
142 std::vector<shared_ptr<const NetworkInterface>> netifs;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500143
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400144 /** \brief MulticastUdpTransport-capable network interfaces (IPv4 only).
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500145 */
146 std::vector<shared_ptr<const NetworkInterface>> netifsV4;
147
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400148 /** \brief MulticastUdpTransport-capable network interfaces (IPv6 only).
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500149 */
150 std::vector<shared_ptr<const NetworkInterface>> netifsV6;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400151};
152
153#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
154 do { \
155 if (this->netifs.size() < (n)) { \
156 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
157 " or more MulticastUdpTransport-capable network interfaces"); \
158 return; \
159 } \
160 } while (false)
161
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500162#define SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(n) \
163 do { \
164 if (this->netifsV4.size() < (n)) { \
165 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
166 " or more IPv4 MulticastUdpTransport-capable network interfaces"); \
167 return; \
168 } \
169 } while (false)
170
171#define SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(n) \
172 do { \
173 if (this->netifsV6.size() < (n)) { \
174 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
175 " or more IPv6 MulticastUdpTransport-capable network interfaces"); \
176 return; \
177 } \
178 } while (false)
179
Junxiao Shicde37ad2015-12-24 01:02:05 -0700180BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000181BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700182
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000183BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000184
Davide Pesavento494a9552018-02-04 22:16:05 -0500185using nfd::Face;
186
187BOOST_AUTO_TEST_CASE(Defaults)
188{
189 const std::string CONFIG = R"CONFIG(
190 face_system
191 {
192 udp
193 }
194 )CONFIG";
195
196 parseConfig(CONFIG, true);
197 parseConfig(CONFIG, false);
198
199 checkChannelListEqual(factory, {"udp4://0.0.0.0:6363", "udp6://[::]:6363"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700200 for (const auto& ch : factory.getChannels()) {
201 BOOST_CHECK(ch->isListening());
202 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), ndn::MAX_NDN_PACKET_SIZE);
203 }
Davide Pesavento494a9552018-02-04 22:16:05 -0500204}
205
206BOOST_AUTO_TEST_CASE(DisableListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000207{
208 const std::string CONFIG = R"CONFIG(
209 face_system
210 {
211 udp
212 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500213 listen no
Junxiao Shi64d99f22017-01-21 23:06:36 +0000214 port 7001
Junxiao Shi64d99f22017-01-21 23:06:36 +0000215 mcast no
216 }
217 }
218 )CONFIG";
219
220 parseConfig(CONFIG, true);
221 parseConfig(CONFIG, false);
222
Junxiao Shi64d99f22017-01-21 23:06:36 +0000223 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700224 for (const auto& ch : factory.getChannels()) {
225 BOOST_CHECK(!ch->isListening());
226 }
Junxiao Shi64d99f22017-01-21 23:06:36 +0000227}
228
Davide Pesavento494a9552018-02-04 22:16:05 -0500229BOOST_AUTO_TEST_CASE(DisableV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000230{
231 const std::string CONFIG = R"CONFIG(
232 face_system
233 {
234 udp
235 {
236 port 7001
237 enable_v4 no
238 enable_v6 yes
Junxiao Shia6286a92021-02-23 06:43:52 -0700239 unicast_mtu 1452
Junxiao Shi64d99f22017-01-21 23:06:36 +0000240 mcast no
241 }
242 }
243 )CONFIG";
244
245 parseConfig(CONFIG, true);
246 parseConfig(CONFIG, false);
247
Junxiao Shi64d99f22017-01-21 23:06:36 +0000248 checkChannelListEqual(factory, {"udp6://[::]:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700249 for (const auto& ch : factory.getChannels()) {
250 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
251 }
Junxiao Shi64d99f22017-01-21 23:06:36 +0000252}
253
Davide Pesavento494a9552018-02-04 22:16:05 -0500254BOOST_AUTO_TEST_CASE(DisableV6)
255{
256 const std::string CONFIG = R"CONFIG(
257 face_system
258 {
259 udp
260 {
261 port 7001
262 enable_v4 yes
263 enable_v6 no
Junxiao Shia6286a92021-02-23 06:43:52 -0700264 unicast_mtu 1452
Davide Pesavento494a9552018-02-04 22:16:05 -0500265 mcast no
266 }
267 }
268 )CONFIG";
269
270 parseConfig(CONFIG, true);
271 parseConfig(CONFIG, false);
272
273 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700274 for (const auto& ch : factory.getChannels()) {
275 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
276 }
Davide Pesavento494a9552018-02-04 22:16:05 -0500277}
278
Davide Pesaventobb734df2017-10-24 18:05:36 -0400279BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixture)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000280{
Junxiao Shi64d99f22017-01-21 23:06:36 +0000281 const std::string CONFIG_WITH_MCAST = R"CONFIG(
282 face_system
283 {
284 udp
285 {
286 mcast yes
287 }
288 }
289 )CONFIG";
290 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
291 face_system
292 {
293 udp
294 {
295 mcast no
296 }
297 }
298 )CONFIG";
299
300 parseConfig(CONFIG_WITHOUT_MCAST, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400301 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500302 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000303
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500304#ifdef __linux__
305 // need superuser privileges to create multicast faces on Linux
306 SKIP_IF_NOT_SUPERUSER();
307#endif // __linux__
Junxiao Shi64d99f22017-01-21 23:06:36 +0000308
309 parseConfig(CONFIG_WITH_MCAST, false);
310 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500311 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), netifsV4.size());
312 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), netifsV6.size());
Junxiao Shi64d99f22017-01-21 23:06:36 +0000313
Alexander Afanasyev3a2339a2020-05-27 23:05:06 -0400314 BOOST_REQUIRE_EQUAL(factory.getChannels().size(), 2);
315 for (const auto& face : this->listUdp4McastFaces()) {
316 BOOST_REQUIRE(face->getChannel().lock());
317 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp4");
318 }
319
320 for (const auto& face : this->listUdp6McastFaces()) {
321 BOOST_REQUIRE(face->getChannel().lock());
322 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp6");
323 }
324
Junxiao Shi64d99f22017-01-21 23:06:36 +0000325 parseConfig(CONFIG_WITHOUT_MCAST, false);
326 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400327 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500328 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000329}
330
Davide Pesaventobb734df2017-10-24 18:05:36 -0400331BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixture)
Teng Liangfe4fce32017-03-29 04:49:38 +0000332{
333#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500334 // need superuser privileges to create multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000335 SKIP_IF_NOT_SUPERUSER();
336#endif // __linux__
337 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
338
339 const std::string CONFIG = R"CONFIG(
340 face_system
341 {
342 udp
343 {
344 mcast_ad_hoc yes
345 }
346 }
347 )CONFIG";
348
349 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500350 BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV4.size());
351 BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV6.size());
Teng Liangfe4fce32017-03-29 04:49:38 +0000352}
353
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500354BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixture)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000355{
356#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500357 // need superuser privileges to create multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000358 SKIP_IF_NOT_SUPERUSER();
359#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500360 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000361
362 const std::string CONFIG1 = R"CONFIG(
363 face_system
364 {
365 udp
366 {
367 mcast_group 239.66.30.1
368 mcast_port 7011
369 }
370 }
371 )CONFIG";
372 const std::string CONFIG2 = R"CONFIG(
373 face_system
374 {
375 udp
376 {
377 mcast_group 239.66.30.2
378 mcast_port 7012
379 }
380 }
381 )CONFIG";
382
383 parseConfig(CONFIG1, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400384 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500385 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
386 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.1:7011"));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000387
388 parseConfig(CONFIG2, false);
389 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400390 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500391 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
392 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.2:7012"));
393}
394
395BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixture)
396{
397#ifdef __linux__
398 // need superuser privileges to create multicast faces on Linux
399 SKIP_IF_NOT_SUPERUSER();
400#endif // __linux__
401 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
402
403 const std::string CONFIG1 = R"CONFIG(
404 face_system
405 {
406 udp
407 {
408 mcast_group_v6 ff02::1101
409 mcast_port_v6 7011
410 }
411 }
412 )CONFIG";
413 const std::string CONFIG2 = R"CONFIG(
414 face_system
415 {
416 udp
417 {
418 mcast_group_v6 ff02::1102
419 mcast_port_v6 7012
420 }
421 }
422 )CONFIG";
423
424 parseConfig(CONFIG1, false);
425 auto udpMcastFaces = this->listUdp6McastFaces();
426 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400427 auto uri = udpMcastFaces.front()->getRemoteUri();
428 BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
429 // check the address ignoring the scope id
430 auto addr = boost::asio::ip::address_v6::from_string(uri.getHost());
431 addr.scope_id(0);
432 BOOST_CHECK_EQUAL(addr, boost::asio::ip::address_v6::from_string("ff02::1101"));
433 BOOST_CHECK_EQUAL(uri.getPort(), "7011");
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500434
435 parseConfig(CONFIG2, false);
436 g_io.poll();
437 udpMcastFaces = this->listUdp6McastFaces();
438 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400439 uri = udpMcastFaces.front()->getRemoteUri();
440 BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
441 // check the address ignoring the scope id
442 addr = boost::asio::ip::address_v6::from_string(uri.getHost());
443 addr.scope_id(0);
444 BOOST_CHECK_EQUAL(addr, boost::asio::ip::address_v6::from_string("ff02::1102"));
445 BOOST_CHECK_EQUAL(uri.getPort(), "7012");
Junxiao Shi64d99f22017-01-21 23:06:36 +0000446}
447
Davide Pesaventobb734df2017-10-24 18:05:36 -0400448BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000449{
450#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500451 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000452 SKIP_IF_NOT_SUPERUSER();
453#endif // __linux__
454 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
455
456 std::string CONFIG = R"CONFIG(
457 face_system
458 {
459 udp
460 {
461 whitelist
462 {
463 ifname %ifname
464 }
465 }
466 }
467 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000468 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000469
470 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500471
Davide Pesaventobb734df2017-10-24 18:05:36 -0400472 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500473 BOOST_CHECK_LE(udpMcastFaces.size(), 1);
474 auto udpMcastFacesV6 = this->listUdp6McastFaces();
475 BOOST_CHECK_LE(udpMcastFacesV6.size(), 1);
476 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
477 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
478 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
479 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000480}
481
Davide Pesaventobb734df2017-10-24 18:05:36 -0400482BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000483{
484#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500485 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000486 SKIP_IF_NOT_SUPERUSER();
487#endif // __linux__
488 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
489
490 std::string CONFIG = R"CONFIG(
491 face_system
492 {
493 udp
494 {
495 blacklist
496 {
497 ifname %ifname
498 }
499 }
500 }
501 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000502 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000503
504 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500505
Davide Pesaventobb734df2017-10-24 18:05:36 -0400506 auto udpMcastFaces = this->listUdp4McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500507 if (!netifsV4.empty())
508 BOOST_CHECK_GE(udpMcastFaces.size(), netifsV4.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500509 auto udpMcastFacesV6 = this->listUdp6McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500510 if (!netifsV6.empty())
511 BOOST_CHECK_GE(udpMcastFacesV6.size(), netifsV6.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500512 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
513 BOOST_CHECK_LT(udpMcastFaces.size(), netifsV4.size() + netifsV6.size());
514 BOOST_CHECK(std::none_of(udpMcastFaces.begin(), udpMcastFaces.end(),
515 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000516}
517
Davide Pesaventobb734df2017-10-24 18:05:36 -0400518BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixture)
Junxiao Shic31080d2017-01-24 15:10:12 +0000519{
520#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500521 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000522 SKIP_IF_NOT_SUPERUSER();
523#endif // __linux__
524 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
525
526 std::string CONFIG1 = R"CONFIG(
527 face_system
528 {
529 udp
530 {
531 whitelist
532 {
533 ifname %ifname
534 }
535 }
536 }
537 )CONFIG";
538 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000539 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
540 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000541
542 parseConfig(CONFIG1, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500543
Davide Pesaventobb734df2017-10-24 18:05:36 -0400544 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500545 auto udpMcastFacesV6 = this->listUdp6McastFaces();
546 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
547 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
548 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
549 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000550
551 parseConfig(CONFIG2, false);
552 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500553
Davide Pesaventobb734df2017-10-24 18:05:36 -0400554 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500555 udpMcastFacesV6 = this->listUdp6McastFaces();
556 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
557 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
558 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
559 [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.back()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000560}
561
Junxiao Shi64d99f22017-01-21 23:06:36 +0000562BOOST_AUTO_TEST_CASE(Omitted)
563{
564 const std::string CONFIG = R"CONFIG(
565 face_system
566 {
567 }
568 )CONFIG";
569
570 parseConfig(CONFIG, true);
571 parseConfig(CONFIG, false);
572
Junxiao Shi64d99f22017-01-21 23:06:36 +0000573 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
574 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500575 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp6", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000576}
577
Davide Pesaventobb734df2017-10-24 18:05:36 -0400578BOOST_AUTO_TEST_CASE(AllDisabled)
579{
580 const std::string CONFIG = R"CONFIG(
581 face_system
582 {
583 udp
584 {
585 enable_v4 no
586 enable_v6 no
587 mcast no
588 }
589 }
590 )CONFIG";
591
592 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
593 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
594}
595
Davide Pesavento494a9552018-02-04 22:16:05 -0500596BOOST_AUTO_TEST_CASE(BadListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000597{
598 const std::string CONFIG = R"CONFIG(
599 face_system
600 {
601 udp
602 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500603 listen hello
604 }
605 }
606 )CONFIG";
607
608 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
609 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
610}
611
Davide Pesavento494a9552018-02-04 22:16:05 -0500612BOOST_AUTO_TEST_CASE(BadPort)
613{
614 // not a number
615 const std::string CONFIG1 = R"CONFIG(
616 face_system
617 {
618 udp
619 {
620 port hello
621 }
622 }
623 )CONFIG";
624
625 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
626 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
627
628 // negative number
629 const std::string CONFIG2 = R"CONFIG(
630 face_system
631 {
632 udp
633 {
634 port -1
635 }
636 }
637 )CONFIG";
638
639 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
640 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
641
642 // out of range
643 const std::string CONFIG3 = R"CONFIG(
644 face_system
645 {
646 udp
647 {
648 port 65536
649 }
650 }
651 )CONFIG";
652
653 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
654 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
655}
656
Davide Pesavento494a9552018-02-04 22:16:05 -0500657BOOST_AUTO_TEST_CASE(BadIdleTimeout)
658{
659 // not a number
660 const std::string CONFIG1 = R"CONFIG(
661 face_system
662 {
663 udp
664 {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000665 idle_timeout hello
666 }
667 }
668 )CONFIG";
669
Davide Pesavento494a9552018-02-04 22:16:05 -0500670 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
671 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
672
673 // negative number
674 const std::string CONFIG2 = R"CONFIG(
675 face_system
676 {
677 udp
678 {
679 idle_timeout -15
680 }
681 }
682 )CONFIG";
683
684 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
685 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000686}
687
Junxiao Shia6286a92021-02-23 06:43:52 -0700688BOOST_AUTO_TEST_CASE(BadMtu)
689{
690 // not a number
691 const std::string CONFIG1 = R"CONFIG(
692 face_system
693 {
694 udp
695 {
696 unicast_mtu hello
697 }
698 }
699 )CONFIG";
700
701 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
702 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
703
704 // underflow
705 const std::string CONFIG2 = R"CONFIG(
706 face_system
707 {
708 udp
709 {
710 unicast_mtu 63
711 }
712 }
713 )CONFIG";
714
715 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
716 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
717
718 // underflow
719 const std::string CONFIG3 = R"CONFIG(
720 face_system
721 {
722 udp
723 {
724 unicast_mtu 8801
725 }
726 }
727 )CONFIG";
728
729 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
730 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
731}
732
Junxiao Shi64d99f22017-01-21 23:06:36 +0000733BOOST_AUTO_TEST_CASE(BadMcast)
734{
735 const std::string CONFIG = R"CONFIG(
736 face_system
737 {
738 udp
739 {
740 mcast hello
741 }
742 }
743 )CONFIG";
744
745 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
746 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
747}
748
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500749BOOST_AUTO_TEST_CASE(BadMcastGroupV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000750{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400751 // not an address
752 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000753 face_system
754 {
755 udp
756 {
757 mcast_group hello
758 }
759 }
760 )CONFIG";
761
Davide Pesaventobb734df2017-10-24 18:05:36 -0400762 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
763 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000764
Davide Pesaventobb734df2017-10-24 18:05:36 -0400765 // non-multicast address
766 const std::string CONFIG2 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000767 face_system
768 {
769 udp
770 {
771 mcast_group 10.0.0.1
772 }
773 }
774 )CONFIG";
775
Davide Pesaventobb734df2017-10-24 18:05:36 -0400776 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
777 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000778
Davide Pesaventobb734df2017-10-24 18:05:36 -0400779 // wrong address family
780 const std::string CONFIG3 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000781 face_system
782 {
783 udp
784 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400785 mcast_group ff02::1234
Junxiao Shi64d99f22017-01-21 23:06:36 +0000786 }
787 }
788 )CONFIG";
789
Davide Pesaventobb734df2017-10-24 18:05:36 -0400790 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
791 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000792}
793
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500794BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
795{
796 // not an address
797 const std::string CONFIG1 = R"CONFIG(
798 face_system
799 {
800 udp
801 {
802 mcast_group_v6 foo
803 }
804 }
805 )CONFIG";
806
807 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
808 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
809
810 // non-multicast address
811 const std::string CONFIG2 = R"CONFIG(
812 face_system
813 {
814 udp
815 {
816 mcast_group_v6 fe80::1234
817 }
818 }
819 )CONFIG";
820
821 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
822 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
823
824 // wrong address family
825 const std::string CONFIG3 = R"CONFIG(
826 face_system
827 {
828 udp
829 {
830 mcast_group_v6 224.0.23.170
831 }
832 }
833 )CONFIG";
834
835 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
836 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
837}
838
839BOOST_AUTO_TEST_CASE(BadMcastPortV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000840{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400841 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000842 face_system
843 {
844 udp
845 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400846 mcast_port hey
Junxiao Shi64d99f22017-01-21 23:06:36 +0000847 }
848 }
849 )CONFIG";
850
Davide Pesaventobb734df2017-10-24 18:05:36 -0400851 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
852 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
853
854 const std::string CONFIG2 = R"CONFIG(
855 face_system
856 {
857 udp
858 {
859 mcast_port 99999
860 }
861 }
862 )CONFIG";
863
864 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
865 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000866}
867
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500868BOOST_AUTO_TEST_CASE(BadMcastPortV6)
869{
870 const std::string CONFIG1 = R"CONFIG(
871 face_system
872 {
873 udp
874 {
875 mcast_port_v6 bar
876 }
877 }
878 )CONFIG";
879
880 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
881 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
882
883 const std::string CONFIG2 = R"CONFIG(
884 face_system
885 {
886 udp
887 {
888 mcast_port_v6 99999
889 }
890 }
891 )CONFIG";
892
893 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
894 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
895}
896
Junxiao Shi64d99f22017-01-21 23:06:36 +0000897BOOST_AUTO_TEST_CASE(UnknownOption)
898{
899 const std::string CONFIG = R"CONFIG(
900 face_system
901 {
902 udp
903 {
904 hello
905 }
906 }
907 )CONFIG";
908
909 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
910 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
911}
912
913BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
914
Junxiao Shicde37ad2015-12-24 01:02:05 -0700915BOOST_AUTO_TEST_CASE(GetChannels)
916{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400917 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700918
Davide Pesaventob15276f2017-07-15 16:27:13 -0400919 std::set<std::string> expected;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400920 expected.insert(createChannel("127.0.0.1", 20070)->getUri().toString());
921 expected.insert(createChannel("127.0.0.1", 20071)->getUri().toString());
922 expected.insert(createChannel("::1", 20071)->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400923 checkChannelListEqual(factory, expected);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700924}
925
Davide Pesaventobb734df2017-10-24 18:05:36 -0400926BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700927{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400928 auto channel1 = createChannel("127.0.0.1", 20070);
929 auto channel1a = createChannel("127.0.0.1", 20070);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700930 BOOST_CHECK_EQUAL(channel1, channel1a);
931 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
932
Davide Pesaventobb734df2017-10-24 18:05:36 -0400933 auto channel2 = createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700934 BOOST_CHECK_NE(channel1, channel2);
935
Davide Pesaventobb734df2017-10-24 18:05:36 -0400936 auto channel3 = createChannel("::1", 20071);
Weiwei Liu72cee942016-02-04 16:49:19 -0700937 BOOST_CHECK_NE(channel2, channel3);
938 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700939
Davide Pesaventobb734df2017-10-24 18:05:36 -0400940#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500941 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400942 SKIP_IF_NOT_SUPERUSER();
943#endif // __linux__
Davide Pesaventobb734df2017-10-24 18:05:36 -0400944
Davide Pesavento19779d82019-02-14 13:40:04 -0500945 // createChannel with a local endpoint that has already been allocated to a UDP multicast face
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500946 if (!netifsV4.empty()) {
947 auto mcastFace = createMulticastFace("127.0.0.1", "224.0.0.254", 20072);
948 BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", 20072), UdpFactory::Error,
949 [] (const UdpFactory::Error& e) {
950 return strcmp(e.what(),
951 "Cannot create UDP channel on 127.0.0.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 }
955 if (!netifsV6.empty()) {
956 auto mcastFace = createMulticastFace("::1", "ff02::114", 20072);
957 BOOST_CHECK_EXCEPTION(createChannel("::1", 20072), UdpFactory::Error,
958 [] (const UdpFactory::Error& e) {
959 return strcmp(e.what(),
960 "Cannot create UDP channel on [::1]:20072, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500961 "endpoint already allocated to a UDP multicast face") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500962 });
963 }
Weiwei Liu72cee942016-02-04 16:49:19 -0700964}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700965
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500966BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixture)
Weiwei Liu72cee942016-02-04 16:49:19 -0700967{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400968#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500969 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400970 SKIP_IF_NOT_SUPERUSER();
971#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500972 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400973
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500974 auto multicastFace1 = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
975 auto multicastFace1a = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
976 auto multicastFace2 = createMulticastFace("127.0.0.1", "224.0.0.254", 20030);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700977 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500978 BOOST_CHECK_NE(multicastFace1, multicastFace2);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700979
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500980 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V4);
981 if (!address.is_unspecified()) {
982 auto multicastFace3 = createMulticastFace(address.to_string(), "224.0.0.254", 20070);
983 BOOST_CHECK_NE(multicastFace1, multicastFace3);
984 BOOST_CHECK_NE(multicastFace2, multicastFace3);
985 }
986
987 // create with a local endpoint already used by a channel
Davide Pesaventobb734df2017-10-24 18:05:36 -0400988 auto channel = createChannel("127.0.0.1", 20071);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500989 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.254", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700990 [] (const UdpFactory::Error& e) {
991 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500992 "Cannot create UDP multicast face on 127.0.0.1:20071, "
Davide Pesavento19779d82019-02-14 13:40:04 -0500993 "endpoint already allocated to a UDP channel") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -0700994 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700995
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500996 // create with a local endpoint already used by a multicast face on a different multicast group
Davide Pesaventobb734df2017-10-24 18:05:36 -0400997 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.42", 20070), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700998 [] (const UdpFactory::Error& e) {
999 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001000 "Cannot create UDP multicast face on 127.0.0.1:20070, "
Davide Pesavento19779d82019-02-14 13:40:04 -05001001 "endpoint already allocated to a different UDP multicast face") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -07001002 });
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001003}
Junxiao Shicde37ad2015-12-24 01:02:05 -07001004
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001005BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixture)
1006{
1007#ifdef __linux__
1008 // need superuser privileges to create multicast faces on Linux
1009 SKIP_IF_NOT_SUPERUSER();
1010#endif // __linux__
1011 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
1012
1013 auto multicastFace1 = createMulticastFace("::1", "ff02::114", 20070);
1014 auto multicastFace1a = createMulticastFace("::1", "ff02::114", 20070);
1015 auto multicastFace2 = createMulticastFace("::1", "ff02::114", 20030);
1016 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
1017 BOOST_CHECK_NE(multicastFace1, multicastFace2);
1018
1019 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V6);
1020 if (!address.is_unspecified()) {
1021 auto multicastFace3 = createMulticastFace(address.to_string(), "ff02::114", 20070);
1022 BOOST_CHECK_NE(multicastFace1, multicastFace3);
1023 BOOST_CHECK_NE(multicastFace2, multicastFace3);
1024 }
1025
1026 // create with a local endpoint already used by a channel
1027 auto channel = createChannel("::1", 20071);
1028 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::114", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -07001029 [] (const UdpFactory::Error& e) {
1030 return strcmp(e.what(),
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001031 "Cannot create UDP multicast face on [::1]:20071, "
Davide Pesavento19779d82019-02-14 13:40:04 -05001032 "endpoint already allocated to a UDP channel") == 0;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001033 });
1034
1035 // create with a local endpoint already used by a multicast face on a different multicast group
1036 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::42", 20070), UdpFactory::Error,
1037 [] (const UdpFactory::Error& e) {
1038 return strcmp(e.what(),
1039 "Cannot create UDP multicast face on [::1]:20070, "
Davide Pesavento19779d82019-02-14 13:40:04 -05001040 "endpoint already allocated to a different UDP multicast face") == 0;
Weiwei Liu72cee942016-02-04 16:49:19 -07001041 });
Junxiao Shicde37ad2015-12-24 01:02:05 -07001042}
1043
Davide Pesaventob15276f2017-07-15 16:27:13 -04001044BOOST_AUTO_TEST_CASE(CreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001045{
Eric Newberry42602412016-08-27 09:33:18 -07001046 createFace(factory,
1047 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001048 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001049 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001050 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001051
Davide Pesaventobb734df2017-10-24 18:05:36 -04001052 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001053
Eric Newberry42602412016-08-27 09:33:18 -07001054 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001055 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001056 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001057 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001058 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +00001059
Eric Newberry42602412016-08-27 09:33:18 -07001060 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001061 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001062 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001063 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001064 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001065
Eric Newberry42602412016-08-27 09:33:18 -07001066 createFace(factory,
1067 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001068 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001069 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -04001070 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1071
Eric Newberry2642cd22017-07-13 21:34:53 -04001072 createFace(factory,
1073 FaceUri("udp4://127.0.0.1:20073"),
1074 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001075 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, true, false},
Eric Newberry0c3e57b2018-01-25 20:54:46 -07001076 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1077
1078 createFace(factory,
1079 FaceUri("udp4://127.0.0.1:20073"),
1080 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001081 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, true},
1082 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1083
1084 createFace(factory,
1085 FaceUri("udp4://127.0.0.1:20074"),
1086 {},
1087 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, 1000, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001088 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001089}
1090
Davide Pesaventob15276f2017-07-15 16:27:13 -04001091BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001092{
Davide Pesaventobb734df2017-10-24 18:05:36 -04001093 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001094
Eric Newberry42602412016-08-27 09:33:18 -07001095 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001096 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001097 FaceUri("udp4://127.0.0.1:20071"),
Eric Newberry812d6152018-06-06 15:06:01 -07001098 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001099 {CreateFaceExpectedResult::FAILURE, 406,
1100 "Unicast UDP faces cannot be created with a LocalUri"});
1101
1102 createFace(factory,
1103 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001104 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001105 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001106 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001107 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +00001108
1109 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001110 FaceUri("udp4://233.252.0.1:23252"),
1111 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001112 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry78e32b02017-04-01 14:34:44 +00001113 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001114 "Cannot create multicast UDP faces"});
1115
1116 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001117 FaceUri("udp4://127.0.0.1:20072"),
1118 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001119 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001120 {CreateFaceExpectedResult::FAILURE, 406,
1121 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001122}
1123
Junxiao Shicde37ad2015-12-24 01:02:05 -07001124BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
1125BOOST_AUTO_TEST_SUITE_END() // Face
1126
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04001127} // namespace nfd::tests