blob: 55d601c4d250061b70512147c19c99622d3b5a2e [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 Pesaventod91fe6d2023-10-04 21:40:02 -04003 * Copyright (c) 2014-2023, 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
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040035namespace ip = boost::asio::ip;
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040036using face::UdpChannel;
37using face::UdpFactory;
Davide Pesavento279af1c2022-08-29 20:18:32 -040038using ndn::net::NetworkInterface;
Junxiao Shicde37ad2015-12-24 01:02:05 -070039
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040040class UdpFactoryFixture : public FaceSystemFactoryFixture<UdpFactory>
41{
42protected:
43 shared_ptr<UdpChannel>
Davide Pesaventobb734df2017-10-24 18:05:36 -040044 createChannel(const std::string& localIp, uint16_t localPort)
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040045 {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040046 udp::Endpoint endpoint(ip::make_address(localIp), localPort);
Davide Pesavento494a9552018-02-04 22:16:05 -050047 return factory.createChannel(endpoint, 5_min);
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040048 }
49};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000050
Davide Pesaventobb734df2017-10-24 18:05:36 -040051class UdpFactoryMcastFixture : public UdpFactoryFixture
52{
53protected:
54 UdpFactoryMcastFixture()
55 {
56 for (const auto& netif : collectNetworkInterfaces()) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040057 // similar filtering logic to UdpFactory::applyMcastConfigToNetif()
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050058 if (netif->isUp() && !netif->isLoopback() && netif->canMulticast()) {
59 bool hasValidIpAddress = false;
60 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
61 hasValidIpAddress = true;
62 netifsV4.push_back(netif);
63 }
64 if (hasAddressFamily(*netif, ndn::net::AddressFamily::V6)) {
65 hasValidIpAddress = true;
66 netifsV6.push_back(netif);
67 }
68 if (hasValidIpAddress) {
69 netifs.push_back(netif);
70 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040071 }
72 }
Davide Pesaventobb734df2017-10-24 18:05:36 -040073 }
74
75 std::vector<const Face*>
76 listUdp4McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
77 {
Davide Pesaventod7083a52023-10-19 17:51:16 -040078 return listFacesByScheme("udp4", linkType);
Davide Pesaventobb734df2017-10-24 18:05:36 -040079 }
80
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050081 std::vector<const Face*>
82 listUdp6McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
83 {
Davide Pesaventod7083a52023-10-19 17:51:16 -040084 return listFacesByScheme("udp6", linkType);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -050085 }
86
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040087 shared_ptr<NetworkInterface>
88 makeFakeNetif(bool addNetworkAddresses = true)
89 {
90 using namespace ndn::net;
91
92 static int counter = 0;
93 ++counter;
94
95 auto netif = netmon->makeNetworkInterface();
96 netif->setIndex(1000 + counter);
97 netif->setName("ethdummy" + std::to_string(counter));
98 netif->setType(InterfaceType::ETHERNET);
99 netif->setFlags(IFF_MULTICAST | IFF_UP);
100 netif->setState(InterfaceState::RUNNING);
101 netif->setMtu(1500);
102 netif->setEthernetAddress(ethernet::Address{0x3e, 0x15, 0xc2, 0x8b, 0x65, 0x00});
103 if (addNetworkAddresses) {
104 netif->addNetworkAddress(NetworkAddress(AddressFamily::V4,
105 ip::make_address_v4("192.168.2.1"),
106 ip::make_address_v4("192.168.2.255"),
107 24, AddressScope::GLOBAL, 0));
108 netif->addNetworkAddress(NetworkAddress(AddressFamily::V6,
109 ip::make_address_v6("2001:db8:2::1"),
110 ip::make_address_v6("2001:db8:2::ffff:ffff:ffff:ffff"),
111 64, AddressScope::GLOBAL, 0));
112 }
113 return netif;
114 }
115
Davide Pesaventod7083a52023-10-19 17:51:16 -0400116 /**
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(),
Davide Pesavento279af1c2022-08-29 20:18:32 -0400123 [af] (const auto& a) { return a.getFamily() == af; });
Davide Pesaventobb734df2017-10-24 18:05:36 -0400124 }
125
Davide Pesaventod7083a52023-10-19 17:51:16 -0400126 /**
127 * \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 Pesaventoa9ec67c2023-10-19 20:04:04 -0400132 auto faceIp = ip::make_address(face.getLocalUri().getHost());
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500133 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400134 [faceIp] (const auto& a) { return a.getIp() == faceIp; });
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
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400153class UdpFactoryMcastFixtureWithRealNetifs : public UdpFactoryMcastFixture
154{
155protected:
156 UdpFactoryMcastFixtureWithRealNetifs()
157 {
158 copyRealNetifsToNetmon();
159 }
160
161 shared_ptr<Face>
162 createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
163 {
164 auto localAddress = ip::make_address(localIp);
165 udp::Endpoint mcastEndpoint(ip::make_address(mcastIp), mcastPort);
166
167 if (localAddress.is_v4()) {
168 BOOST_ASSERT(!netifsV4.empty());
169 return factory.createMulticastFace(*netifsV4.front(), localAddress, mcastEndpoint);
170 }
171 else {
172 BOOST_ASSERT(!netifsV6.empty());
173 return factory.createMulticastFace(*netifsV6.front(), localAddress, mcastEndpoint);
174 }
175 }
176
177 /**
178 * \brief Returns a non-loopback IP address suitable for the creation of a UDP multicast face.
179 */
180 ip::address
181 findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
182 {
183 const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
184 for (const auto& netif : netifList) {
185 for (const auto& a : netif->getNetworkAddresses()) {
186 if (a.getFamily() == af && !a.getIp().is_loopback())
187 return a.getIp();
188 }
189 }
190 return {};
191 }
192};
193
Davide Pesaventobb734df2017-10-24 18:05:36 -0400194#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
195 do { \
196 if (this->netifs.size() < (n)) { \
197 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
198 " or more MulticastUdpTransport-capable network interfaces"); \
199 return; \
200 } \
201 } while (false)
202
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500203#define SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(n) \
204 do { \
205 if (this->netifsV4.size() < (n)) { \
206 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
207 " or more IPv4 MulticastUdpTransport-capable network interfaces"); \
208 return; \
209 } \
210 } while (false)
211
212#define SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(n) \
213 do { \
214 if (this->netifsV6.size() < (n)) { \
215 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
216 " or more IPv6 MulticastUdpTransport-capable network interfaces"); \
217 return; \
218 } \
219 } while (false)
220
Junxiao Shicde37ad2015-12-24 01:02:05 -0700221BOOST_AUTO_TEST_SUITE(Face)
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400222BOOST_AUTO_TEST_SUITE(TestUdpFactory)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700223
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400224BOOST_FIXTURE_TEST_SUITE(ProcessConfig, UdpFactoryFixture)
Davide Pesavento494a9552018-02-04 22:16:05 -0500225
226BOOST_AUTO_TEST_CASE(Defaults)
227{
228 const std::string CONFIG = R"CONFIG(
229 face_system
230 {
231 udp
232 }
233 )CONFIG";
234
235 parseConfig(CONFIG, true);
236 parseConfig(CONFIG, false);
237
238 checkChannelListEqual(factory, {"udp4://0.0.0.0:6363", "udp6://[::]:6363"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700239 for (const auto& ch : factory.getChannels()) {
240 BOOST_CHECK(ch->isListening());
241 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), ndn::MAX_NDN_PACKET_SIZE);
242 }
Davide Pesavento494a9552018-02-04 22:16:05 -0500243}
244
245BOOST_AUTO_TEST_CASE(DisableListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000246{
247 const std::string CONFIG = R"CONFIG(
248 face_system
249 {
250 udp
251 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500252 listen no
Junxiao Shi64d99f22017-01-21 23:06:36 +0000253 port 7001
Junxiao Shi64d99f22017-01-21 23:06:36 +0000254 mcast no
255 }
256 }
257 )CONFIG";
258
259 parseConfig(CONFIG, true);
260 parseConfig(CONFIG, false);
261
Junxiao Shi64d99f22017-01-21 23:06:36 +0000262 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700263 for (const auto& ch : factory.getChannels()) {
264 BOOST_CHECK(!ch->isListening());
265 }
Junxiao Shi64d99f22017-01-21 23:06:36 +0000266}
267
Davide Pesavento494a9552018-02-04 22:16:05 -0500268BOOST_AUTO_TEST_CASE(DisableV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000269{
270 const std::string CONFIG = R"CONFIG(
271 face_system
272 {
273 udp
274 {
275 port 7001
276 enable_v4 no
277 enable_v6 yes
Junxiao Shia6286a92021-02-23 06:43:52 -0700278 unicast_mtu 1452
Junxiao Shi64d99f22017-01-21 23:06:36 +0000279 mcast no
280 }
281 }
282 )CONFIG";
283
284 parseConfig(CONFIG, true);
285 parseConfig(CONFIG, false);
286
Junxiao Shi64d99f22017-01-21 23:06:36 +0000287 checkChannelListEqual(factory, {"udp6://[::]:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700288 for (const auto& ch : factory.getChannels()) {
289 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
290 }
Junxiao Shi64d99f22017-01-21 23:06:36 +0000291}
292
Davide Pesavento494a9552018-02-04 22:16:05 -0500293BOOST_AUTO_TEST_CASE(DisableV6)
294{
295 const std::string CONFIG = R"CONFIG(
296 face_system
297 {
298 udp
299 {
300 port 7001
301 enable_v4 yes
302 enable_v6 no
Junxiao Shia6286a92021-02-23 06:43:52 -0700303 unicast_mtu 1452
Davide Pesavento494a9552018-02-04 22:16:05 -0500304 mcast no
305 }
306 }
307 )CONFIG";
308
309 parseConfig(CONFIG, true);
310 parseConfig(CONFIG, false);
311
312 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
Junxiao Shia6286a92021-02-23 06:43:52 -0700313 for (const auto& ch : factory.getChannels()) {
314 BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
315 }
Davide Pesavento494a9552018-02-04 22:16:05 -0500316}
317
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400318BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixtureWithRealNetifs)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000319{
Junxiao Shi64d99f22017-01-21 23:06:36 +0000320 const std::string CONFIG_WITH_MCAST = R"CONFIG(
321 face_system
322 {
323 udp
324 {
325 mcast yes
326 }
327 }
328 )CONFIG";
329 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
330 face_system
331 {
332 udp
333 {
334 mcast no
335 }
336 }
337 )CONFIG";
338
339 parseConfig(CONFIG_WITHOUT_MCAST, false);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400340 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500341 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000342
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500343#ifdef __linux__
344 // need superuser privileges to create multicast faces on Linux
345 SKIP_IF_NOT_SUPERUSER();
346#endif // __linux__
Junxiao Shi64d99f22017-01-21 23:06:36 +0000347
348 parseConfig(CONFIG_WITH_MCAST, false);
349 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500350 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), netifsV4.size());
351 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), netifsV6.size());
Junxiao Shi64d99f22017-01-21 23:06:36 +0000352
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400353 BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
354 for (const auto* face : this->listUdp4McastFaces()) {
Alexander Afanasyev3a2339a2020-05-27 23:05:06 -0400355 BOOST_REQUIRE(face->getChannel().lock());
356 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp4");
357 }
358
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400359 for (const auto* face : this->listUdp6McastFaces()) {
Alexander Afanasyev3a2339a2020-05-27 23:05:06 -0400360 BOOST_REQUIRE(face->getChannel().lock());
361 BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp6");
362 }
363
Junxiao Shi64d99f22017-01-21 23:06:36 +0000364 parseConfig(CONFIG_WITHOUT_MCAST, false);
365 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400366 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500367 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000368}
369
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400370BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixtureWithRealNetifs)
Teng Liangfe4fce32017-03-29 04:49:38 +0000371{
372#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500373 // need superuser privileges to create multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000374 SKIP_IF_NOT_SUPERUSER();
375#endif // __linux__
376 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
377
378 const std::string CONFIG = R"CONFIG(
379 face_system
380 {
381 udp
382 {
383 mcast_ad_hoc yes
384 }
385 }
386 )CONFIG";
387
388 parseConfig(CONFIG, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400389 BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
390 BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500391 BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV4.size());
392 BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV6.size());
Teng Liangfe4fce32017-03-29 04:49:38 +0000393}
394
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400395BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixtureWithRealNetifs)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000396{
397#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500398 // need superuser privileges to create multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000399 SKIP_IF_NOT_SUPERUSER();
400#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500401 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000402
403 const std::string CONFIG1 = R"CONFIG(
404 face_system
405 {
406 udp
407 {
408 mcast_group 239.66.30.1
409 mcast_port 7011
410 }
411 }
412 )CONFIG";
413 const std::string CONFIG2 = R"CONFIG(
414 face_system
415 {
416 udp
417 {
418 mcast_group 239.66.30.2
419 mcast_port 7012
420 }
421 }
422 )CONFIG";
423
424 parseConfig(CONFIG1, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400425 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400426 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500427 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
428 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.1:7011"));
Junxiao Shi64d99f22017-01-21 23:06:36 +0000429
430 parseConfig(CONFIG2, false);
431 g_io.poll();
Davide Pesaventobb734df2017-10-24 18:05:36 -0400432 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500433 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
434 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.2:7012"));
435}
436
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400437BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixtureWithRealNetifs)
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500438{
439#ifdef __linux__
440 // need superuser privileges to create multicast faces on Linux
441 SKIP_IF_NOT_SUPERUSER();
442#endif // __linux__
443 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
444
445 const std::string CONFIG1 = R"CONFIG(
446 face_system
447 {
448 udp
449 {
450 mcast_group_v6 ff02::1101
451 mcast_port_v6 7011
452 }
453 }
454 )CONFIG";
455 const std::string CONFIG2 = R"CONFIG(
456 face_system
457 {
458 udp
459 {
460 mcast_group_v6 ff02::1102
461 mcast_port_v6 7012
462 }
463 }
464 )CONFIG";
465
466 parseConfig(CONFIG1, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400467 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500468 auto udpMcastFaces = this->listUdp6McastFaces();
469 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400470 auto uri = udpMcastFaces.front()->getRemoteUri();
471 BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
472 // check the address ignoring the scope id
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400473 auto addr = ip::make_address_v6(uri.getHost());
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400474 addr.scope_id(0);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400475 BOOST_CHECK_EQUAL(addr, ip::make_address_v6("ff02::1101"));
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400476 BOOST_CHECK_EQUAL(uri.getPort(), "7011");
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500477
478 parseConfig(CONFIG2, false);
479 g_io.poll();
480 udpMcastFaces = this->listUdp6McastFaces();
481 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400482 uri = udpMcastFaces.front()->getRemoteUri();
483 BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
484 // check the address ignoring the scope id
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400485 addr = ip::make_address_v6(uri.getHost());
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400486 addr.scope_id(0);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400487 BOOST_CHECK_EQUAL(addr, ip::make_address_v6("ff02::1102"));
Davide Pesaventoe541d1b2022-08-17 15:10:32 -0400488 BOOST_CHECK_EQUAL(uri.getPort(), "7012");
Junxiao Shi64d99f22017-01-21 23:06:36 +0000489}
490
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400491BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixtureWithRealNetifs)
Junxiao Shic31080d2017-01-24 15:10:12 +0000492{
493#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500494 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000495 SKIP_IF_NOT_SUPERUSER();
496#endif // __linux__
497 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
498
499 std::string CONFIG = R"CONFIG(
500 face_system
501 {
502 udp
503 {
504 whitelist
505 {
506 ifname %ifname
507 }
508 }
509 }
510 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000511 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000512
513 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500514
Davide Pesaventobb734df2017-10-24 18:05:36 -0400515 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500516 BOOST_CHECK_LE(udpMcastFaces.size(), 1);
517 auto udpMcastFacesV6 = this->listUdp6McastFaces();
518 BOOST_CHECK_LE(udpMcastFacesV6.size(), 1);
519 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
520 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
521 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400522 [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000523}
524
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400525BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixtureWithRealNetifs)
Junxiao Shic31080d2017-01-24 15:10:12 +0000526{
527#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500528 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000529 SKIP_IF_NOT_SUPERUSER();
530#endif // __linux__
531 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
532
533 std::string CONFIG = R"CONFIG(
534 face_system
535 {
536 udp
537 {
538 blacklist
539 {
540 ifname %ifname
541 }
542 }
543 }
544 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000545 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000546
547 parseConfig(CONFIG, false);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500548
Davide Pesaventobb734df2017-10-24 18:05:36 -0400549 auto udpMcastFaces = this->listUdp4McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500550 if (!netifsV4.empty())
551 BOOST_CHECK_GE(udpMcastFaces.size(), netifsV4.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500552 auto udpMcastFacesV6 = this->listUdp6McastFaces();
Davide Pesavento97a01012018-01-22 19:36:28 -0500553 if (!netifsV6.empty())
554 BOOST_CHECK_GE(udpMcastFacesV6.size(), netifsV6.size() - 1);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500555 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
556 BOOST_CHECK_LT(udpMcastFaces.size(), netifsV4.size() + netifsV6.size());
557 BOOST_CHECK(std::none_of(udpMcastFaces.begin(), udpMcastFaces.end(),
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400558 [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000559}
560
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400561BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixtureWithRealNetifs)
Junxiao Shic31080d2017-01-24 15:10:12 +0000562{
563#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500564 // need superuser privileges to create multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000565 SKIP_IF_NOT_SUPERUSER();
566#endif // __linux__
567 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
568
569 std::string CONFIG1 = R"CONFIG(
570 face_system
571 {
572 udp
573 {
574 whitelist
575 {
576 ifname %ifname
577 }
578 }
579 }
580 )CONFIG";
581 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000582 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
583 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000584
585 parseConfig(CONFIG1, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400586 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500587
Davide Pesaventobb734df2017-10-24 18:05:36 -0400588 auto udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500589 auto udpMcastFacesV6 = this->listUdp6McastFaces();
590 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
591 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
592 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400593 [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000594
595 parseConfig(CONFIG2, false);
596 g_io.poll();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500597
Davide Pesaventobb734df2017-10-24 18:05:36 -0400598 udpMcastFaces = this->listUdp4McastFaces();
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500599 udpMcastFacesV6 = this->listUdp6McastFaces();
600 udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
601 BOOST_CHECK_GE(udpMcastFaces.size(), 1);
602 BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400603 [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.back()); }));
Junxiao Shic31080d2017-01-24 15:10:12 +0000604}
605
Junxiao Shi64d99f22017-01-21 23:06:36 +0000606BOOST_AUTO_TEST_CASE(Omitted)
607{
608 const std::string CONFIG = R"CONFIG(
609 face_system
610 {
611 }
612 )CONFIG";
613
614 parseConfig(CONFIG, true);
615 parseConfig(CONFIG, false);
616
Junxiao Shi64d99f22017-01-21 23:06:36 +0000617 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
618 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500619 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp6", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000620}
621
Davide Pesaventobb734df2017-10-24 18:05:36 -0400622BOOST_AUTO_TEST_CASE(AllDisabled)
623{
624 const std::string CONFIG = R"CONFIG(
625 face_system
626 {
627 udp
628 {
629 enable_v4 no
630 enable_v6 no
631 mcast no
632 }
633 }
634 )CONFIG";
635
636 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
637 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
638}
639
Davide Pesavento494a9552018-02-04 22:16:05 -0500640BOOST_AUTO_TEST_CASE(BadListen)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000641{
642 const std::string CONFIG = R"CONFIG(
643 face_system
644 {
645 udp
646 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500647 listen hello
648 }
649 }
650 )CONFIG";
651
652 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
653 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
654}
655
Davide Pesavento494a9552018-02-04 22:16:05 -0500656BOOST_AUTO_TEST_CASE(BadPort)
657{
658 // not a number
659 const std::string CONFIG1 = R"CONFIG(
660 face_system
661 {
662 udp
663 {
664 port hello
665 }
666 }
667 )CONFIG";
668
669 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
670 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
671
672 // negative number
673 const std::string CONFIG2 = R"CONFIG(
674 face_system
675 {
676 udp
677 {
678 port -1
679 }
680 }
681 )CONFIG";
682
683 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
684 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
685
686 // out of range
687 const std::string CONFIG3 = R"CONFIG(
688 face_system
689 {
690 udp
691 {
692 port 65536
693 }
694 }
695 )CONFIG";
696
697 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
698 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
699}
700
Davide Pesavento494a9552018-02-04 22:16:05 -0500701BOOST_AUTO_TEST_CASE(BadIdleTimeout)
702{
703 // not a number
704 const std::string CONFIG1 = R"CONFIG(
705 face_system
706 {
707 udp
708 {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000709 idle_timeout hello
710 }
711 }
712 )CONFIG";
713
Davide Pesavento494a9552018-02-04 22:16:05 -0500714 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
715 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
716
717 // negative number
718 const std::string CONFIG2 = R"CONFIG(
719 face_system
720 {
721 udp
722 {
723 idle_timeout -15
724 }
725 }
726 )CONFIG";
727
728 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
729 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000730}
731
Junxiao Shia6286a92021-02-23 06:43:52 -0700732BOOST_AUTO_TEST_CASE(BadMtu)
733{
734 // not a number
735 const std::string CONFIG1 = R"CONFIG(
736 face_system
737 {
738 udp
739 {
740 unicast_mtu hello
741 }
742 }
743 )CONFIG";
744
745 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
746 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
747
748 // underflow
749 const std::string CONFIG2 = R"CONFIG(
750 face_system
751 {
752 udp
753 {
754 unicast_mtu 63
755 }
756 }
757 )CONFIG";
758
759 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
760 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
761
762 // underflow
763 const std::string CONFIG3 = R"CONFIG(
764 face_system
765 {
766 udp
767 {
768 unicast_mtu 8801
769 }
770 }
771 )CONFIG";
772
773 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
774 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
775}
776
Junxiao Shi64d99f22017-01-21 23:06:36 +0000777BOOST_AUTO_TEST_CASE(BadMcast)
778{
779 const std::string CONFIG = R"CONFIG(
780 face_system
781 {
782 udp
783 {
784 mcast hello
785 }
786 }
787 )CONFIG";
788
789 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
790 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
791}
792
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500793BOOST_AUTO_TEST_CASE(BadMcastGroupV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000794{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400795 // not an address
796 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000797 face_system
798 {
799 udp
800 {
801 mcast_group hello
802 }
803 }
804 )CONFIG";
805
Davide Pesaventobb734df2017-10-24 18:05:36 -0400806 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
807 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000808
Davide Pesaventobb734df2017-10-24 18:05:36 -0400809 // non-multicast address
810 const std::string CONFIG2 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000811 face_system
812 {
813 udp
814 {
815 mcast_group 10.0.0.1
816 }
817 }
818 )CONFIG";
819
Davide Pesaventobb734df2017-10-24 18:05:36 -0400820 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
821 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000822
Davide Pesaventobb734df2017-10-24 18:05:36 -0400823 // wrong address family
824 const std::string CONFIG3 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000825 face_system
826 {
827 udp
828 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400829 mcast_group ff02::1234
Junxiao Shi64d99f22017-01-21 23:06:36 +0000830 }
831 }
832 )CONFIG";
833
Davide Pesaventobb734df2017-10-24 18:05:36 -0400834 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
835 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000836}
837
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500838BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
839{
840 // not an address
841 const std::string CONFIG1 = R"CONFIG(
842 face_system
843 {
844 udp
845 {
846 mcast_group_v6 foo
847 }
848 }
849 )CONFIG";
850
851 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
852 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
853
854 // non-multicast address
855 const std::string CONFIG2 = R"CONFIG(
856 face_system
857 {
858 udp
859 {
860 mcast_group_v6 fe80::1234
861 }
862 }
863 )CONFIG";
864
865 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
866 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
867
868 // wrong address family
869 const std::string CONFIG3 = R"CONFIG(
870 face_system
871 {
872 udp
873 {
874 mcast_group_v6 224.0.23.170
875 }
876 }
877 )CONFIG";
878
879 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
880 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
881}
882
883BOOST_AUTO_TEST_CASE(BadMcastPortV4)
Junxiao Shi64d99f22017-01-21 23:06:36 +0000884{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400885 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi64d99f22017-01-21 23:06:36 +0000886 face_system
887 {
888 udp
889 {
Davide Pesaventobb734df2017-10-24 18:05:36 -0400890 mcast_port hey
Junxiao Shi64d99f22017-01-21 23:06:36 +0000891 }
892 }
893 )CONFIG";
894
Davide Pesaventobb734df2017-10-24 18:05:36 -0400895 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
896 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
897
898 const std::string CONFIG2 = R"CONFIG(
899 face_system
900 {
901 udp
902 {
903 mcast_port 99999
904 }
905 }
906 )CONFIG";
907
908 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
909 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000910}
911
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500912BOOST_AUTO_TEST_CASE(BadMcastPortV6)
913{
914 const std::string CONFIG1 = R"CONFIG(
915 face_system
916 {
917 udp
918 {
919 mcast_port_v6 bar
920 }
921 }
922 )CONFIG";
923
924 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
925 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
926
927 const std::string CONFIG2 = R"CONFIG(
928 face_system
929 {
930 udp
931 {
932 mcast_port_v6 99999
933 }
934 }
935 )CONFIG";
936
937 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
938 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
939}
940
Junxiao Shi64d99f22017-01-21 23:06:36 +0000941BOOST_AUTO_TEST_CASE(UnknownOption)
942{
943 const std::string CONFIG = R"CONFIG(
944 face_system
945 {
946 udp
947 {
948 hello
949 }
950 }
951 )CONFIG";
952
953 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
954 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
955}
956
957BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
958
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400959BOOST_FIXTURE_TEST_CASE(GetChannels, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700960{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400961 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700962
Davide Pesaventob15276f2017-07-15 16:27:13 -0400963 std::set<std::string> expected;
Davide Pesaventobb734df2017-10-24 18:05:36 -0400964 expected.insert(createChannel("127.0.0.1", 20070)->getUri().toString());
965 expected.insert(createChannel("127.0.0.1", 20071)->getUri().toString());
966 expected.insert(createChannel("::1", 20071)->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400967 checkChannelListEqual(factory, expected);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700968}
969
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400970BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixtureWithRealNetifs)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700971{
Davide Pesaventobb734df2017-10-24 18:05:36 -0400972 auto channel1 = createChannel("127.0.0.1", 20070);
973 auto channel1a = createChannel("127.0.0.1", 20070);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700974 BOOST_CHECK_EQUAL(channel1, channel1a);
975 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400976 BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700977
Davide Pesaventobb734df2017-10-24 18:05:36 -0400978 auto channel2 = createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700979 BOOST_CHECK_NE(channel1, channel2);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400980 BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700981
Davide Pesaventobb734df2017-10-24 18:05:36 -0400982 auto channel3 = createChannel("::1", 20071);
Weiwei Liu72cee942016-02-04 16:49:19 -0700983 BOOST_CHECK_NE(channel2, channel3);
984 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400985 BOOST_CHECK_EQUAL(factory.getChannels().size(), 3);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700986
Davide Pesaventobb734df2017-10-24 18:05:36 -0400987#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500988 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -0400989 SKIP_IF_NOT_SUPERUSER();
990#endif // __linux__
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400991 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
Davide Pesaventobb734df2017-10-24 18:05:36 -0400992
Davide Pesavento19779d82019-02-14 13:40:04 -0500993 // createChannel with a local endpoint that has already been allocated to a UDP multicast face
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -0500994 if (!netifsV4.empty()) {
995 auto mcastFace = createMulticastFace("127.0.0.1", "224.0.0.254", 20072);
996 BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", 20072), UdpFactory::Error,
997 [] (const UdpFactory::Error& e) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400998 return e.what() == "Cannot create UDP channel on 127.0.0.1:20072, "
999 "endpoint already allocated to a UDP multicast face"s;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001000 });
1001 }
1002 if (!netifsV6.empty()) {
1003 auto mcastFace = createMulticastFace("::1", "ff02::114", 20072);
1004 BOOST_CHECK_EXCEPTION(createChannel("::1", 20072), UdpFactory::Error,
1005 [] (const UdpFactory::Error& e) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001006 return e.what() == "Cannot create UDP channel on [::1]:20072, "
1007 "endpoint already allocated to a UDP multicast face"s;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001008 });
1009 }
Weiwei Liu72cee942016-02-04 16:49:19 -07001010}
Junxiao Shicde37ad2015-12-24 01:02:05 -07001011
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001012BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixtureWithRealNetifs)
Weiwei Liu72cee942016-02-04 16:49:19 -07001013{
Davide Pesaventobb734df2017-10-24 18:05:36 -04001014#ifdef __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001015 // need superuser privileges to create multicast faces on Linux
Davide Pesaventobb734df2017-10-24 18:05:36 -04001016 SKIP_IF_NOT_SUPERUSER();
1017#endif // __linux__
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001018 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
Davide Pesaventobb734df2017-10-24 18:05:36 -04001019
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001020 auto multicastFace1 = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
1021 auto multicastFace1a = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
1022 auto multicastFace2 = createMulticastFace("127.0.0.1", "224.0.0.254", 20030);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001023 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001024 BOOST_CHECK_NE(multicastFace1, multicastFace2);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001025
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001026 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V4);
1027 if (!address.is_unspecified()) {
1028 auto multicastFace3 = createMulticastFace(address.to_string(), "224.0.0.254", 20070);
1029 BOOST_CHECK_NE(multicastFace1, multicastFace3);
1030 BOOST_CHECK_NE(multicastFace2, multicastFace3);
1031 }
1032
1033 // create with a local endpoint already used by a channel
Davide Pesaventobb734df2017-10-24 18:05:36 -04001034 auto channel = createChannel("127.0.0.1", 20071);
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001035 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.254", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -07001036 [] (const UdpFactory::Error& e) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001037 return e.what() == "Cannot create UDP multicast face on 127.0.0.1:20071, "
1038 "endpoint already allocated to a UDP channel"s;
Weiwei Liu72cee942016-02-04 16:49:19 -07001039 });
Junxiao Shicde37ad2015-12-24 01:02:05 -07001040
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001041 // create with a local endpoint already used by a multicast face on a different multicast group
Davide Pesaventobb734df2017-10-24 18:05:36 -04001042 BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.42", 20070), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -07001043 [] (const UdpFactory::Error& e) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001044 return e.what() == "Cannot create UDP multicast face on 127.0.0.1:20070, "
1045 "endpoint already allocated to a different UDP multicast face"s;
Weiwei Liu72cee942016-02-04 16:49:19 -07001046 });
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001047}
Junxiao Shicde37ad2015-12-24 01:02:05 -07001048
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001049BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixtureWithRealNetifs)
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001050{
1051#ifdef __linux__
1052 // need superuser privileges to create multicast faces on Linux
1053 SKIP_IF_NOT_SUPERUSER();
1054#endif // __linux__
1055 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
1056
1057 auto multicastFace1 = createMulticastFace("::1", "ff02::114", 20070);
1058 auto multicastFace1a = createMulticastFace("::1", "ff02::114", 20070);
1059 auto multicastFace2 = createMulticastFace("::1", "ff02::114", 20030);
1060 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
1061 BOOST_CHECK_NE(multicastFace1, multicastFace2);
1062
1063 auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V6);
1064 if (!address.is_unspecified()) {
1065 auto multicastFace3 = createMulticastFace(address.to_string(), "ff02::114", 20070);
1066 BOOST_CHECK_NE(multicastFace1, multicastFace3);
1067 BOOST_CHECK_NE(multicastFace2, multicastFace3);
1068 }
1069
1070 // create with a local endpoint already used by a channel
1071 auto channel = createChannel("::1", 20071);
1072 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::114", 20071), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -07001073 [] (const UdpFactory::Error& e) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001074 return e.what() == "Cannot create UDP multicast face on [::1]:20071, "
1075 "endpoint already allocated to a UDP channel"s;
Md Ashiqur Rahman8ce09032018-01-14 22:43:13 -05001076 });
1077
1078 // create with a local endpoint already used by a multicast face on a different multicast group
1079 BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::42", 20070), UdpFactory::Error,
1080 [] (const UdpFactory::Error& e) {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001081 return e.what() == "Cannot create UDP multicast face on [::1]:20070, "
1082 "endpoint already allocated to a different UDP multicast face"s;
Weiwei Liu72cee942016-02-04 16:49:19 -07001083 });
Junxiao Shicde37ad2015-12-24 01:02:05 -07001084}
1085
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001086BOOST_FIXTURE_TEST_CASE(CreateFace, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001087{
Eric Newberry42602412016-08-27 09:33:18 -07001088 createFace(factory,
1089 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001090 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001091 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001092 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001093
Davide Pesaventobb734df2017-10-24 18:05:36 -04001094 createChannel("127.0.0.1", 20071);
Junxiao Shicde37ad2015-12-24 01:02:05 -07001095
Eric Newberry42602412016-08-27 09:33:18 -07001096 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001097 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001098 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001099 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001100 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +00001101
Eric Newberry42602412016-08-27 09:33:18 -07001102 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001103 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001104 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001105 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001106 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001107
Eric Newberry42602412016-08-27 09:33:18 -07001108 createFace(factory,
1109 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001110 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001111 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -04001112 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1113
Eric Newberry2642cd22017-07-13 21:34:53 -04001114 createFace(factory,
1115 FaceUri("udp4://127.0.0.1:20073"),
1116 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001117 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, true, false},
Eric Newberry0c3e57b2018-01-25 20:54:46 -07001118 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1119
1120 createFace(factory,
1121 FaceUri("udp4://127.0.0.1:20073"),
1122 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001123 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, true},
1124 {CreateFaceExpectedResult::SUCCESS, 0, ""});
1125
1126 createFace(factory,
1127 FaceUri("udp4://127.0.0.1:20074"),
1128 {},
1129 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, 1000, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001130 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001131}
1132
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001133BOOST_FIXTURE_TEST_CASE(CreateFaceInvalidRequest, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -07001134{
Eric Newberry42602412016-08-27 09:33:18 -07001135 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001136 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -04001137 FaceUri("udp4://127.0.0.1:20071"),
Eric Newberry812d6152018-06-06 15:06:01 -07001138 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001139 {CreateFaceExpectedResult::FAILURE, 406,
1140 "Unicast UDP faces cannot be created with a LocalUri"});
1141
1142 createFace(factory,
1143 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +00001144 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001145 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -07001146 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001147 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +00001148
1149 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001150 FaceUri("udp4://233.252.0.1:23252"),
1151 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001152 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Eric Newberry78e32b02017-04-01 14:34:44 +00001153 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -04001154 "Cannot create multicast UDP faces"});
1155
1156 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -04001157 FaceUri("udp4://127.0.0.1:20072"),
1158 {},
Eric Newberry812d6152018-06-06 15:06:01 -07001159 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -04001160 {CreateFaceExpectedResult::FAILURE, 406,
1161 "Local fields can only be enabled on faces with local scope"});
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001162
1163 createFace(factory,
1164 FaceUri("udp4://127.0.0.1:20072"),
1165 {},
1166 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, 42, false, false, false},
1167 {CreateFaceExpectedResult::FAILURE, 406,
1168 "Override MTU cannot be less than 64"});
Junxiao Shicde37ad2015-12-24 01:02:05 -07001169}
1170
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -04001171BOOST_FIXTURE_TEST_SUITE(OnInterfaceAdded, UdpFactoryMcastFixture)
1172
1173BOOST_AUTO_TEST_CASE(EligibleV4)
1174{
1175#ifdef __linux__
1176 // need superuser privileges to create multicast faces on Linux
1177 SKIP_IF_NOT_SUPERUSER();
1178#endif // __linux__
1179 SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
1180
1181 parseConfig(R"CONFIG(
1182 face_system
1183 {
1184 udp
1185 }
1186 )CONFIG", false);
1187 g_io.poll();
1188 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1189 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1190
1191 netmon->addInterface(const_pointer_cast<NetworkInterface>(netifsV4.front()));
1192 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 1);
1193 BOOST_CHECK_LE(this->listUdp6McastFaces().size(), 1);
1194}
1195
1196BOOST_AUTO_TEST_CASE(EligibleV6)
1197{
1198#ifdef __linux__
1199 // need superuser privileges to create multicast faces on Linux
1200 SKIP_IF_NOT_SUPERUSER();
1201#endif // __linux__
1202 SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
1203
1204 parseConfig(R"CONFIG(
1205 face_system
1206 {
1207 udp
1208 }
1209 )CONFIG", false);
1210 g_io.poll();
1211 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1212 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1213
1214 netmon->addInterface(const_pointer_cast<NetworkInterface>(netifsV6.front()));
1215 BOOST_CHECK_LE(this->listUdp4McastFaces().size(), 1);
1216 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 1);
1217}
1218
1219BOOST_AUTO_TEST_CASE(EligibleFailure)
1220{
1221 parseConfig(R"CONFIG(
1222 face_system
1223 {
1224 udp
1225 }
1226 )CONFIG", false);
1227 g_io.poll();
1228
1229 // Add a fake interface that satisfies the multicast criteria.
1230 netmon->addInterface(this->makeFakeNetif());
1231 // Creation of multicast faces fails because the interface does not actually exist.
1232 // This test is to ensure that the factory handles failures gracefully.
1233 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1234 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1235}
1236
1237BOOST_AUTO_TEST_CASE(Ineligible)
1238{
1239 parseConfig(R"CONFIG(
1240 face_system
1241 {
1242 udp
1243 }
1244 )CONFIG", false);
1245 g_io.poll();
1246
1247 // netif is down
1248 auto netif = this->makeFakeNetif();
1249 netif->setFlags(netif->getFlags() & ~IFF_UP);
1250 netmon->addInterface(netif);
1251 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1252 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1253
1254 // netif is loopback
1255 netif = this->makeFakeNetif();
1256 netif->setFlags(netif->getFlags() | IFF_LOOPBACK);
1257 netmon->addInterface(netif);
1258 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1259 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1260
1261 // netif cannot multicast
1262 netif = this->makeFakeNetif();
1263 netif->setFlags(netif->getFlags() & ~IFF_MULTICAST);
1264 netmon->addInterface(netif);
1265 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1266 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1267
1268 // no viable IP address
1269 netmon->addInterface(this->makeFakeNetif(false));
1270 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1271 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1272}
1273
1274BOOST_AUTO_TEST_CASE(Disabled)
1275{
1276 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
1277
1278 parseConfig("", false);
1279 g_io.poll();
1280
1281 netmon->addInterface(const_pointer_cast<NetworkInterface>(netifs.front()));
1282 BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
1283 BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
1284}
1285
1286BOOST_AUTO_TEST_SUITE_END() // OnInterfaceAdded
1287
Junxiao Shicde37ad2015-12-24 01:02:05 -07001288BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
1289BOOST_AUTO_TEST_SUITE_END() // Face
1290
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04001291} // namespace nfd::tests