]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/test/ip/multicast.cpp
09b0a745eecaebc591b05b2ff16ecf4cc32da5be
[ceph.git] / ceph / src / boost / libs / asio / test / ip / multicast.cpp
1 //
2 // multicast.cpp
3 // ~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 // Disable autolinking for unit tests.
12 #if !defined(BOOST_ALL_NO_LIB)
13 #define BOOST_ALL_NO_LIB 1
14 #endif // !defined(BOOST_ALL_NO_LIB)
15
16 // Test that header file is self-contained.
17 #include <boost/asio/ip/multicast.hpp>
18
19 #include <boost/asio/io_context.hpp>
20 #include <boost/asio/ip/udp.hpp>
21 #include "../unit_test.hpp"
22
23 //------------------------------------------------------------------------------
24
25 // ip_multicast_compile test
26 // ~~~~~~~~~~~~~~~~~~~~~~~~~
27 // The following test checks that all nested classes, enums and constants in
28 // ip::multicast compile and link correctly. Runtime failures are ignored.
29
30 namespace ip_multicast_compile {
31
32 void test()
33 {
34 using namespace boost::asio;
35 namespace ip = boost::asio::ip;
36
37 try
38 {
39 io_context ioc;
40 ip::udp::socket sock(ioc);
41 const ip::address address;
42 const ip::address_v4 address_v4;
43 const ip::address_v6 address_v6;
44
45 // join_group class.
46
47 ip::multicast::join_group join_group1;
48 ip::multicast::join_group join_group2(address);
49 ip::multicast::join_group join_group3(address_v4);
50 ip::multicast::join_group join_group4(address_v4, address_v4);
51 ip::multicast::join_group join_group5(address_v6);
52 ip::multicast::join_group join_group6(address_v6, 1);
53 sock.set_option(join_group6);
54
55 // leave_group class.
56
57 ip::multicast::leave_group leave_group1;
58 ip::multicast::leave_group leave_group2(address);
59 ip::multicast::leave_group leave_group3(address_v4);
60 ip::multicast::leave_group leave_group4(address_v4, address_v4);
61 ip::multicast::leave_group leave_group5(address_v6);
62 ip::multicast::leave_group leave_group6(address_v6, 1);
63 sock.set_option(leave_group6);
64
65 // outbound_interface class.
66
67 ip::multicast::outbound_interface outbound_interface1;
68 ip::multicast::outbound_interface outbound_interface2(address_v4);
69 ip::multicast::outbound_interface outbound_interface3(1);
70 sock.set_option(outbound_interface3);
71
72 // hops class.
73
74 ip::multicast::hops hops1(1024);
75 sock.set_option(hops1);
76 ip::multicast::hops hops2;
77 sock.get_option(hops2);
78 hops1 = 1;
79 (void)static_cast<int>(hops1.value());
80
81 // enable_loopback class.
82
83 ip::multicast::enable_loopback enable_loopback1(true);
84 sock.set_option(enable_loopback1);
85 ip::multicast::enable_loopback enable_loopback2;
86 sock.get_option(enable_loopback2);
87 enable_loopback1 = true;
88 (void)static_cast<bool>(enable_loopback1);
89 (void)static_cast<bool>(!enable_loopback1);
90 (void)static_cast<bool>(enable_loopback1.value());
91 }
92 catch (std::exception&)
93 {
94 }
95 }
96
97 } // namespace ip_multicast_compile
98
99 //------------------------------------------------------------------------------
100
101 // ip_multicast_runtime test
102 // ~~~~~~~~~~~~~~~~~~~~~~~~~
103 // The following test checks the runtime operation of the socket options defined
104 // in the ip::multicast namespace.
105
106 namespace ip_multicast_runtime {
107
108 #if defined(__hpux)
109 // HP-UX doesn't declare this function extern "C", so it is declared again here
110 // to avoid a linker error about an undefined symbol.
111 extern "C" unsigned int if_nametoindex(const char*);
112 #endif // defined(__hpux)
113
114 void test()
115 {
116 using namespace boost::asio;
117 namespace ip = boost::asio::ip;
118
119 io_context ioc;
120 boost::system::error_code ec;
121
122 ip::udp::endpoint ep_v4(ip::address_v4::loopback(), 0);
123 ip::udp::socket sock_v4(ioc);
124 sock_v4.open(ep_v4.protocol(), ec);
125 sock_v4.bind(ep_v4, ec);
126 bool have_v4 = !ec;
127
128 ip::udp::endpoint ep_v6(ip::address_v6::loopback(), 0);
129 ip::udp::socket sock_v6(ioc);
130 sock_v6.open(ep_v6.protocol(), ec);
131 sock_v6.bind(ep_v6, ec);
132 bool have_v6 = !ec;
133
134 BOOST_ASIO_CHECK(have_v4 || have_v6);
135
136 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
137 // Windows CE seems to have problems with some multicast group addresses.
138 // The following address works on CE, but as it is not a private multicast
139 // address it will not be used on other platforms.
140 const ip::address multicast_address_v4 = ip::make_address("239.0.0.4", ec);
141 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
142 const ip::address multicast_address_v4 = ip::make_address("239.255.0.1", ec);
143 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
144 BOOST_ASIO_CHECK(!have_v4 || !ec);
145
146 #if (defined(__MACH__) && defined(__APPLE__)) \
147 || defined(__FreeBSD__) \
148 || defined(__NetBSD__) \
149 || defined(__OpenBSD__)
150 const ip::address multicast_address_v6 = ip::make_address("ff02::1%lo0", ec);
151 #else // (defined(__MACH__) && defined(__APPLE__))
152 // || defined(__FreeBSD__)
153 // || defined(__NetBSD__)
154 // || defined(__OpenBSD__)
155 const ip::address multicast_address_v6 = ip::make_address("ff01::1", ec);
156 #endif // (defined(__MACH__) && defined(__APPLE__))
157 // || defined(__FreeBSD__)
158 // || defined(__NetBSD__)
159 // || defined(__OpenBSD__)
160 BOOST_ASIO_CHECK(!have_v6 || !ec);
161
162 // join_group class.
163
164 if (have_v4)
165 {
166 ip::multicast::join_group join_group(multicast_address_v4);
167 sock_v4.set_option(join_group, ec);
168 BOOST_ASIO_CHECK_MESSAGE(!ec || ec == error::no_such_device,
169 ec.value() << ", " << ec.message());
170
171 if (!ec)
172 {
173 // leave_group class.
174
175 ip::multicast::leave_group leave_group(multicast_address_v4);
176 sock_v4.set_option(leave_group, ec);
177 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
178 }
179 }
180
181 if (have_v6)
182 {
183 ip::multicast::join_group join_group(multicast_address_v6);
184 sock_v6.set_option(join_group, ec);
185 BOOST_ASIO_CHECK_MESSAGE(!ec || ec == error::no_such_device,
186 ec.value() << ", " << ec.message());
187
188 if (!ec)
189 {
190 // leave_group class.
191
192 ip::multicast::leave_group leave_group(multicast_address_v6);
193 sock_v6.set_option(leave_group, ec);
194 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
195 }
196 }
197
198 // outbound_interface class.
199
200 if (have_v4)
201 {
202 ip::multicast::outbound_interface outbound_interface(
203 ip::address_v4::loopback());
204 sock_v4.set_option(outbound_interface, ec);
205 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
206 }
207
208 if (have_v6)
209 {
210 #if defined(__hpux)
211 ip::multicast::outbound_interface outbound_interface(if_nametoindex("lo0"));
212 #else
213 ip::multicast::outbound_interface outbound_interface(1);
214 #endif
215 sock_v6.set_option(outbound_interface, ec);
216 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
217 }
218
219 // hops class.
220
221 if (have_v4)
222 {
223 ip::multicast::hops hops1(1);
224 BOOST_ASIO_CHECK(hops1.value() == 1);
225 sock_v4.set_option(hops1, ec);
226 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
227
228 ip::multicast::hops hops2;
229 sock_v4.get_option(hops2, ec);
230 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
231 BOOST_ASIO_CHECK(hops2.value() == 1);
232
233 ip::multicast::hops hops3(0);
234 BOOST_ASIO_CHECK(hops3.value() == 0);
235 sock_v4.set_option(hops3, ec);
236 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
237
238 ip::multicast::hops hops4;
239 sock_v4.get_option(hops4, ec);
240 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
241 BOOST_ASIO_CHECK(hops4.value() == 0);
242 }
243
244 if (have_v6)
245 {
246 ip::multicast::hops hops1(1);
247 BOOST_ASIO_CHECK(hops1.value() == 1);
248 sock_v6.set_option(hops1, ec);
249 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
250
251 ip::multicast::hops hops2;
252 sock_v6.get_option(hops2, ec);
253 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
254 BOOST_ASIO_CHECK(hops2.value() == 1);
255
256 ip::multicast::hops hops3(0);
257 BOOST_ASIO_CHECK(hops3.value() == 0);
258 sock_v6.set_option(hops3, ec);
259 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
260
261 ip::multicast::hops hops4;
262 sock_v6.get_option(hops4, ec);
263 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
264 BOOST_ASIO_CHECK(hops4.value() == 0);
265 }
266
267 // enable_loopback class.
268
269 if (have_v4)
270 {
271 ip::multicast::enable_loopback enable_loopback1(true);
272 BOOST_ASIO_CHECK(enable_loopback1.value());
273 BOOST_ASIO_CHECK(static_cast<bool>(enable_loopback1));
274 BOOST_ASIO_CHECK(!!enable_loopback1);
275 sock_v4.set_option(enable_loopback1, ec);
276 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
277 // Option is not supported under Windows CE.
278 BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
279 ec.value() << ", " << ec.message());
280 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
281 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
282 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
283
284 ip::multicast::enable_loopback enable_loopback2;
285 sock_v4.get_option(enable_loopback2, ec);
286 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
287 // Not supported under Windows CE but can get value.
288 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
289 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
290 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
291 BOOST_ASIO_CHECK(enable_loopback2.value());
292 BOOST_ASIO_CHECK(static_cast<bool>(enable_loopback2));
293 BOOST_ASIO_CHECK(!!enable_loopback2);
294 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
295
296 ip::multicast::enable_loopback enable_loopback3(false);
297 BOOST_ASIO_CHECK(!enable_loopback3.value());
298 BOOST_ASIO_CHECK(!static_cast<bool>(enable_loopback3));
299 BOOST_ASIO_CHECK(!enable_loopback3);
300 sock_v4.set_option(enable_loopback3, ec);
301 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
302 // Option is not supported under Windows CE.
303 BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
304 ec.value() << ", " << ec.message());
305 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
306 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
307 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
308
309 ip::multicast::enable_loopback enable_loopback4;
310 sock_v4.get_option(enable_loopback4, ec);
311 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
312 // Not supported under Windows CE but can get value.
313 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
314 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
315 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
316 BOOST_ASIO_CHECK(!enable_loopback4.value());
317 BOOST_ASIO_CHECK(!static_cast<bool>(enable_loopback4));
318 BOOST_ASIO_CHECK(!enable_loopback4);
319 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
320 }
321
322 if (have_v6)
323 {
324 ip::multicast::enable_loopback enable_loopback1(true);
325 BOOST_ASIO_CHECK(enable_loopback1.value());
326 BOOST_ASIO_CHECK(static_cast<bool>(enable_loopback1));
327 BOOST_ASIO_CHECK(!!enable_loopback1);
328 sock_v6.set_option(enable_loopback1, ec);
329 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
330
331 ip::multicast::enable_loopback enable_loopback2;
332 sock_v6.get_option(enable_loopback2, ec);
333 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
334 BOOST_ASIO_CHECK(enable_loopback2.value());
335 BOOST_ASIO_CHECK(static_cast<bool>(enable_loopback2));
336 BOOST_ASIO_CHECK(!!enable_loopback2);
337
338 ip::multicast::enable_loopback enable_loopback3(false);
339 BOOST_ASIO_CHECK(!enable_loopback3.value());
340 BOOST_ASIO_CHECK(!static_cast<bool>(enable_loopback3));
341 BOOST_ASIO_CHECK(!enable_loopback3);
342 sock_v6.set_option(enable_loopback3, ec);
343 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
344
345 ip::multicast::enable_loopback enable_loopback4;
346 sock_v6.get_option(enable_loopback4, ec);
347 BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
348 BOOST_ASIO_CHECK(!enable_loopback4.value());
349 BOOST_ASIO_CHECK(!static_cast<bool>(enable_loopback4));
350 BOOST_ASIO_CHECK(!enable_loopback4);
351 }
352 }
353
354 } // namespace ip_multicast_runtime
355
356 //------------------------------------------------------------------------------
357
358 BOOST_ASIO_TEST_SUITE
359 (
360 "ip/multicast",
361 BOOST_ASIO_TEST_CASE(ip_multicast_compile::test)
362 BOOST_ASIO_TEST_CASE(ip_multicast_runtime::test)
363 )