1 //
2 // udp.cpp
3 // ~~~~~~~
4 //
5 // Copyright (c) 2003-2019 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/udp.hpp>
18 
19 #include <cstring>
20 #include <boost/asio/io_context.hpp>
21 #include "../unit_test.hpp"
22 #include "../archetypes/async_result.hpp"
23 #include "../archetypes/gettable_socket_option.hpp"
24 #include "../archetypes/io_control_command.hpp"
25 #include "../archetypes/settable_socket_option.hpp"
26 
27 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
28 # include <boost/bind.hpp>
29 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
30 # include <functional>
31 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
32 
33 //------------------------------------------------------------------------------
34 
35 // ip_udp_socket_compile test
36 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
37 // The following test checks that all public member functions on the class
38 // ip::udp::socket compile and link correctly. Runtime failures are ignored.
39 
40 namespace ip_udp_socket_compile {
41 
42 struct connect_handler
43 {
connect_handlerip_udp_socket_compile::connect_handler44   connect_handler() {}
operator ()ip_udp_socket_compile::connect_handler45   void operator()(const boost::system::error_code&) {}
46 #if defined(BOOST_ASIO_HAS_MOVE)
connect_handlerip_udp_socket_compile::connect_handler47   connect_handler(connect_handler&&) {}
48 private:
49   connect_handler(const connect_handler&);
50 #endif // defined(BOOST_ASIO_HAS_MOVE)
51 };
52 
53 struct wait_handler
54 {
wait_handlerip_udp_socket_compile::wait_handler55   wait_handler() {}
operator ()ip_udp_socket_compile::wait_handler56   void operator()(const boost::system::error_code&) {}
57 #if defined(BOOST_ASIO_HAS_MOVE)
wait_handlerip_udp_socket_compile::wait_handler58   wait_handler(wait_handler&&) {}
59 private:
60   wait_handler(const wait_handler&);
61 #endif // defined(BOOST_ASIO_HAS_MOVE)
62 };
63 
64 struct send_handler
65 {
send_handlerip_udp_socket_compile::send_handler66   send_handler() {}
operator ()ip_udp_socket_compile::send_handler67   void operator()(const boost::system::error_code&, std::size_t) {}
68 #if defined(BOOST_ASIO_HAS_MOVE)
send_handlerip_udp_socket_compile::send_handler69   send_handler(send_handler&&) {}
70 private:
71   send_handler(const send_handler&);
72 #endif // defined(BOOST_ASIO_HAS_MOVE)
73 };
74 
75 struct receive_handler
76 {
receive_handlerip_udp_socket_compile::receive_handler77   receive_handler() {}
operator ()ip_udp_socket_compile::receive_handler78   void operator()(const boost::system::error_code&, std::size_t) {}
79 #if defined(BOOST_ASIO_HAS_MOVE)
receive_handlerip_udp_socket_compile::receive_handler80   receive_handler(receive_handler&&) {}
81 private:
82   receive_handler(const receive_handler&);
83 #endif // defined(BOOST_ASIO_HAS_MOVE)
84 };
85 
test()86 void test()
87 {
88   using namespace boost::asio;
89   namespace ip = boost::asio::ip;
90 
91   try
92   {
93     io_context ioc;
94     const io_context::executor_type ioc_ex = ioc.get_executor();
95     char mutable_char_buffer[128] = "";
96     const char const_char_buffer[128] = "";
97     socket_base::message_flags in_flags = 0;
98     archetypes::settable_socket_option<void> settable_socket_option1;
99     archetypes::settable_socket_option<int> settable_socket_option2;
100     archetypes::settable_socket_option<double> settable_socket_option3;
101     archetypes::gettable_socket_option<void> gettable_socket_option1;
102     archetypes::gettable_socket_option<int> gettable_socket_option2;
103     archetypes::gettable_socket_option<double> gettable_socket_option3;
104     archetypes::io_control_command io_control_command;
105     archetypes::lazy_handler lazy;
106     boost::system::error_code ec;
107 
108     // basic_datagram_socket constructors.
109 
110     ip::udp::socket socket1(ioc);
111     ip::udp::socket socket2(ioc, ip::udp::v4());
112     ip::udp::socket socket3(ioc, ip::udp::v6());
113     ip::udp::socket socket4(ioc, ip::udp::endpoint(ip::udp::v4(), 0));
114     ip::udp::socket socket5(ioc, ip::udp::endpoint(ip::udp::v6(), 0));
115 #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
116     ip::udp::socket::native_handle_type native_socket1
117       = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
118     ip::udp::socket socket6(ioc, ip::udp::v4(), native_socket1);
119 #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
120 
121     ip::udp::socket socket7(ioc_ex);
122     ip::udp::socket socket8(ioc_ex, ip::udp::v4());
123     ip::udp::socket socket9(ioc_ex, ip::udp::v6());
124     ip::udp::socket socket10(ioc_ex, ip::udp::endpoint(ip::udp::v4(), 0));
125     ip::udp::socket socket11(ioc_ex, ip::udp::endpoint(ip::udp::v6(), 0));
126 #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
127     ip::udp::socket::native_handle_type native_socket2
128       = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
129     ip::udp::socket socket12(ioc_ex, ip::udp::v4(), native_socket2);
130 #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
131 
132 #if defined(BOOST_ASIO_HAS_MOVE)
133     ip::udp::socket socket13(std::move(socket6));
134 #endif // defined(BOOST_ASIO_HAS_MOVE)
135 
136     // basic_datagram_socket operators.
137 
138 #if defined(BOOST_ASIO_HAS_MOVE)
139     socket1 = ip::udp::socket(ioc);
140     socket1 = std::move(socket2);
141 #endif // defined(BOOST_ASIO_HAS_MOVE)
142 
143     // basic_io_object functions.
144 
145     ip::udp::socket::executor_type ex = socket1.get_executor();
146     (void)ex;
147 
148     // basic_socket functions.
149 
150     ip::udp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
151     (void)lowest_layer;
152 
153     const ip::udp::socket& socket14 = socket1;
154     const ip::udp::socket::lowest_layer_type& lowest_layer2
155       = socket14.lowest_layer();
156     (void)lowest_layer2;
157 
158     socket1.open(ip::udp::v4());
159     socket1.open(ip::udp::v6());
160     socket1.open(ip::udp::v4(), ec);
161     socket1.open(ip::udp::v6(), ec);
162 
163 #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
164     ip::udp::socket::native_handle_type native_socket3
165       = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
166     socket1.assign(ip::udp::v4(), native_socket3);
167     ip::udp::socket::native_handle_type native_socket4
168       = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
169     socket1.assign(ip::udp::v4(), native_socket4, ec);
170 #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
171 
172     bool is_open = socket1.is_open();
173     (void)is_open;
174 
175     socket1.close();
176     socket1.close(ec);
177 
178     socket1.release();
179     socket1.release(ec);
180 
181     ip::udp::socket::native_handle_type native_socket5
182       = socket1.native_handle();
183     (void)native_socket5;
184 
185     socket1.cancel();
186     socket1.cancel(ec);
187 
188     bool at_mark1 = socket1.at_mark();
189     (void)at_mark1;
190     bool at_mark2 = socket1.at_mark(ec);
191     (void)at_mark2;
192 
193     std::size_t available1 = socket1.available();
194     (void)available1;
195     std::size_t available2 = socket1.available(ec);
196     (void)available2;
197 
198     socket1.bind(ip::udp::endpoint(ip::udp::v4(), 0));
199     socket1.bind(ip::udp::endpoint(ip::udp::v6(), 0));
200     socket1.bind(ip::udp::endpoint(ip::udp::v4(), 0), ec);
201     socket1.bind(ip::udp::endpoint(ip::udp::v6(), 0), ec);
202 
203     socket1.connect(ip::udp::endpoint(ip::udp::v4(), 0));
204     socket1.connect(ip::udp::endpoint(ip::udp::v6(), 0));
205     socket1.connect(ip::udp::endpoint(ip::udp::v4(), 0), ec);
206     socket1.connect(ip::udp::endpoint(ip::udp::v6(), 0), ec);
207 
208     socket1.async_connect(ip::udp::endpoint(ip::udp::v4(), 0),
209         connect_handler());
210     socket1.async_connect(ip::udp::endpoint(ip::udp::v6(), 0),
211         connect_handler());
212     int i1 = socket1.async_connect(ip::udp::endpoint(ip::udp::v4(), 0), lazy);
213     (void)i1;
214     int i2 = socket1.async_connect(ip::udp::endpoint(ip::udp::v6(), 0), lazy);
215     (void)i2;
216 
217     socket1.set_option(settable_socket_option1);
218     socket1.set_option(settable_socket_option1, ec);
219     socket1.set_option(settable_socket_option2);
220     socket1.set_option(settable_socket_option2, ec);
221     socket1.set_option(settable_socket_option3);
222     socket1.set_option(settable_socket_option3, ec);
223 
224     socket1.get_option(gettable_socket_option1);
225     socket1.get_option(gettable_socket_option1, ec);
226     socket1.get_option(gettable_socket_option2);
227     socket1.get_option(gettable_socket_option2, ec);
228     socket1.get_option(gettable_socket_option3);
229     socket1.get_option(gettable_socket_option3, ec);
230 
231     socket1.io_control(io_control_command);
232     socket1.io_control(io_control_command, ec);
233 
234     bool non_blocking1 = socket1.non_blocking();
235     (void)non_blocking1;
236     socket1.non_blocking(true);
237     socket1.non_blocking(false, ec);
238 
239     bool non_blocking2 = socket1.native_non_blocking();
240     (void)non_blocking2;
241     socket1.native_non_blocking(true);
242     socket1.native_non_blocking(false, ec);
243 
244     ip::udp::endpoint endpoint1 = socket1.local_endpoint();
245     (void)endpoint1;
246     ip::udp::endpoint endpoint2 = socket1.local_endpoint(ec);
247     (void)endpoint2;
248 
249     ip::udp::endpoint endpoint3 = socket1.remote_endpoint();
250     (void)endpoint3;
251     ip::udp::endpoint endpoint4 = socket1.remote_endpoint(ec);
252     (void)endpoint4;
253 
254     socket1.shutdown(socket_base::shutdown_both);
255     socket1.shutdown(socket_base::shutdown_both, ec);
256 
257     socket1.wait(socket_base::wait_read);
258     socket1.wait(socket_base::wait_write, ec);
259 
260     socket1.async_wait(socket_base::wait_read, wait_handler());
261     int i3 = socket1.async_wait(socket_base::wait_write, lazy);
262     (void)i3;
263 
264     // basic_datagram_socket functions.
265 
266     socket1.send(buffer(mutable_char_buffer));
267     socket1.send(buffer(const_char_buffer));
268     socket1.send(null_buffers());
269     socket1.send(buffer(mutable_char_buffer), in_flags);
270     socket1.send(buffer(const_char_buffer), in_flags);
271     socket1.send(null_buffers(), in_flags);
272     socket1.send(buffer(mutable_char_buffer), in_flags, ec);
273     socket1.send(buffer(const_char_buffer), in_flags, ec);
274     socket1.send(null_buffers(), in_flags, ec);
275 
276     socket1.async_send(buffer(mutable_char_buffer), send_handler());
277     socket1.async_send(buffer(const_char_buffer), send_handler());
278     socket1.async_send(null_buffers(), send_handler());
279     socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler());
280     socket1.async_send(buffer(const_char_buffer), in_flags, send_handler());
281     socket1.async_send(null_buffers(), in_flags, send_handler());
282     int i4 = socket1.async_send(buffer(mutable_char_buffer), lazy);
283     (void)i4;
284     int i5 = socket1.async_send(buffer(const_char_buffer), lazy);
285     (void)i5;
286     int i6 = socket1.async_send(null_buffers(), lazy);
287     (void)i6;
288     int i7 = socket1.async_send(buffer(mutable_char_buffer), in_flags, lazy);
289     (void)i7;
290     int i8 = socket1.async_send(buffer(const_char_buffer), in_flags, lazy);
291     (void)i8;
292     int i9 = socket1.async_send(null_buffers(), in_flags, lazy);
293     (void)i9;
294 
295     socket1.send_to(buffer(mutable_char_buffer),
296         ip::udp::endpoint(ip::udp::v4(), 0));
297     socket1.send_to(buffer(mutable_char_buffer),
298         ip::udp::endpoint(ip::udp::v6(), 0));
299     socket1.send_to(buffer(const_char_buffer),
300         ip::udp::endpoint(ip::udp::v4(), 0));
301     socket1.send_to(buffer(const_char_buffer),
302         ip::udp::endpoint(ip::udp::v6(), 0));
303     socket1.send_to(null_buffers(),
304         ip::udp::endpoint(ip::udp::v4(), 0));
305     socket1.send_to(null_buffers(),
306         ip::udp::endpoint(ip::udp::v6(), 0));
307     socket1.send_to(buffer(mutable_char_buffer),
308         ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
309     socket1.send_to(buffer(mutable_char_buffer),
310         ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
311     socket1.send_to(buffer(const_char_buffer),
312         ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
313     socket1.send_to(buffer(const_char_buffer),
314         ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
315     socket1.send_to(null_buffers(),
316         ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
317     socket1.send_to(null_buffers(),
318         ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
319     socket1.send_to(buffer(mutable_char_buffer),
320         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
321     socket1.send_to(buffer(mutable_char_buffer),
322         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
323     socket1.send_to(buffer(const_char_buffer),
324         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
325     socket1.send_to(buffer(const_char_buffer),
326         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
327     socket1.send_to(null_buffers(),
328         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
329     socket1.send_to(null_buffers(),
330         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
331 
332     socket1.async_send_to(buffer(mutable_char_buffer),
333         ip::udp::endpoint(ip::udp::v4(), 0), send_handler());
334     socket1.async_send_to(buffer(mutable_char_buffer),
335         ip::udp::endpoint(ip::udp::v6(), 0), send_handler());
336     socket1.async_send_to(buffer(const_char_buffer),
337         ip::udp::endpoint(ip::udp::v4(), 0), send_handler());
338     socket1.async_send_to(buffer(const_char_buffer),
339         ip::udp::endpoint(ip::udp::v6(), 0), send_handler());
340     socket1.async_send_to(null_buffers(),
341         ip::udp::endpoint(ip::udp::v4(), 0), send_handler());
342     socket1.async_send_to(null_buffers(),
343         ip::udp::endpoint(ip::udp::v6(), 0), send_handler());
344     socket1.async_send_to(buffer(mutable_char_buffer),
345         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler());
346     socket1.async_send_to(buffer(mutable_char_buffer),
347         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler());
348     socket1.async_send_to(buffer(const_char_buffer),
349         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler());
350     socket1.async_send_to(buffer(const_char_buffer),
351         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler());
352     socket1.async_send_to(null_buffers(),
353         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler());
354     socket1.async_send_to(null_buffers(),
355         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler());
356     int i10 = socket1.async_send_to(buffer(mutable_char_buffer),
357         ip::udp::endpoint(ip::udp::v4(), 0), lazy);
358     (void)i10;
359     int i11 = socket1.async_send_to(buffer(mutable_char_buffer),
360         ip::udp::endpoint(ip::udp::v6(), 0), lazy);
361     (void)i11;
362     int i12 = socket1.async_send_to(buffer(const_char_buffer),
363         ip::udp::endpoint(ip::udp::v4(), 0), lazy);
364     (void)i12;
365     int i13 = socket1.async_send_to(buffer(const_char_buffer),
366         ip::udp::endpoint(ip::udp::v6(), 0), lazy);
367     (void)i13;
368     int i14 = socket1.async_send_to(null_buffers(),
369         ip::udp::endpoint(ip::udp::v4(), 0), lazy);
370     (void)i14;
371     int i15 = socket1.async_send_to(null_buffers(),
372         ip::udp::endpoint(ip::udp::v6(), 0), lazy);
373     (void)i15;
374     int i16 = socket1.async_send_to(buffer(mutable_char_buffer),
375         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, lazy);
376     (void)i16;
377     int i17 = socket1.async_send_to(buffer(mutable_char_buffer),
378         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, lazy);
379     (void)i17;
380     int i18 = socket1.async_send_to(buffer(const_char_buffer),
381         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, lazy);
382     (void)i18;
383     int i19 = socket1.async_send_to(buffer(const_char_buffer),
384         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, lazy);
385     (void)i19;
386     int i20 = socket1.async_send_to(null_buffers(),
387         ip::udp::endpoint(ip::udp::v4(), 0), in_flags, lazy);
388     (void)i20;
389     int i21 = socket1.async_send_to(null_buffers(),
390         ip::udp::endpoint(ip::udp::v6(), 0), in_flags, lazy);
391     (void)i21;
392 
393     socket1.receive(buffer(mutable_char_buffer));
394     socket1.receive(null_buffers());
395     socket1.receive(buffer(mutable_char_buffer), in_flags);
396     socket1.receive(null_buffers(), in_flags);
397     socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
398     socket1.receive(null_buffers(), in_flags, ec);
399 
400     socket1.async_receive(buffer(mutable_char_buffer), receive_handler());
401     socket1.async_receive(null_buffers(), receive_handler());
402     socket1.async_receive(buffer(mutable_char_buffer), in_flags,
403         receive_handler());
404     socket1.async_receive(null_buffers(), in_flags, receive_handler());
405     int i22 = socket1.async_receive(buffer(mutable_char_buffer), lazy);
406     (void)i22;
407     int i23 = socket1.async_receive(null_buffers(), lazy);
408     (void)i23;
409     int i24 = socket1.async_receive(buffer(mutable_char_buffer),
410         in_flags, lazy);
411     (void)i24;
412     int i25 = socket1.async_receive(null_buffers(), in_flags, lazy);
413     (void)i25;
414 
415     ip::udp::endpoint endpoint;
416     socket1.receive_from(buffer(mutable_char_buffer), endpoint);
417     socket1.receive_from(null_buffers(), endpoint);
418     socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
419     socket1.receive_from(null_buffers(), endpoint, in_flags);
420     socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
421     socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
422 
423     socket1.async_receive_from(buffer(mutable_char_buffer),
424         endpoint, receive_handler());
425     socket1.async_receive_from(null_buffers(),
426         endpoint, receive_handler());
427     socket1.async_receive_from(buffer(mutable_char_buffer),
428         endpoint, in_flags, receive_handler());
429     socket1.async_receive_from(null_buffers(),
430         endpoint, in_flags, receive_handler());
431     int i26 = socket1.async_receive_from(buffer(mutable_char_buffer),
432         endpoint, lazy);
433     (void)i26;
434     int i27 = socket1.async_receive_from(null_buffers(),
435         endpoint, lazy);
436     (void)i27;
437     int i28 = socket1.async_receive_from(buffer(mutable_char_buffer),
438         endpoint, in_flags, lazy);
439     (void)i28;
440     int i29 = socket1.async_receive_from(null_buffers(),
441         endpoint, in_flags, lazy);
442     (void)i29;
443   }
444   catch (std::exception&)
445   {
446   }
447 }
448 
449 } // namespace ip_udp_socket_compile
450 
451 //------------------------------------------------------------------------------
452 
453 // ip_udp_socket_runtime test
454 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
455 // The following test checks the runtime operation of the ip::udp::socket class.
456 
457 namespace ip_udp_socket_runtime {
458 
handle_send(size_t expected_bytes_sent,const boost::system::error_code & err,size_t bytes_sent)459 void handle_send(size_t expected_bytes_sent,
460     const boost::system::error_code& err, size_t bytes_sent)
461 {
462   BOOST_ASIO_CHECK(!err);
463   BOOST_ASIO_CHECK(expected_bytes_sent == bytes_sent);
464 }
465 
handle_recv(size_t expected_bytes_recvd,const boost::system::error_code & err,size_t bytes_recvd)466 void handle_recv(size_t expected_bytes_recvd,
467     const boost::system::error_code& err, size_t bytes_recvd)
468 {
469   BOOST_ASIO_CHECK(!err);
470   BOOST_ASIO_CHECK(expected_bytes_recvd == bytes_recvd);
471 }
472 
test()473 void test()
474 {
475   using namespace std; // For memcmp and memset.
476   using namespace boost::asio;
477   namespace ip = boost::asio::ip;
478 
479 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
480   namespace bindns = boost;
481 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
482   namespace bindns = std;
483   using std::placeholders::_1;
484   using std::placeholders::_2;
485 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
486 
487   io_context ioc;
488 
489   ip::udp::socket s1(ioc, ip::udp::endpoint(ip::udp::v4(), 0));
490   ip::udp::endpoint target_endpoint = s1.local_endpoint();
491   target_endpoint.address(ip::address_v4::loopback());
492 
493   ip::udp::socket s2(ioc);
494   s2.open(ip::udp::v4());
495   s2.bind(ip::udp::endpoint(ip::udp::v4(), 0));
496   char send_msg[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
497   s2.send_to(buffer(send_msg, sizeof(send_msg)), target_endpoint);
498 
499   char recv_msg[sizeof(send_msg)];
500   ip::udp::endpoint sender_endpoint;
501   size_t bytes_recvd = s1.receive_from(buffer(recv_msg, sizeof(recv_msg)),
502       sender_endpoint);
503 
504   BOOST_ASIO_CHECK(bytes_recvd == sizeof(send_msg));
505   BOOST_ASIO_CHECK(memcmp(send_msg, recv_msg, sizeof(send_msg)) == 0);
506 
507   memset(recv_msg, 0, sizeof(recv_msg));
508 
509   target_endpoint = sender_endpoint;
510   s1.async_send_to(buffer(send_msg, sizeof(send_msg)), target_endpoint,
511       bindns::bind(handle_send, sizeof(send_msg), _1, _2));
512   s2.async_receive_from(buffer(recv_msg, sizeof(recv_msg)), sender_endpoint,
513       bindns::bind(handle_recv, sizeof(recv_msg), _1, _2));
514 
515   ioc.run();
516 
517   BOOST_ASIO_CHECK(memcmp(send_msg, recv_msg, sizeof(send_msg)) == 0);
518 }
519 
520 } // namespace ip_udp_socket_runtime
521 
522 //------------------------------------------------------------------------------
523 
524 // ip_udp_resolver_compile test
525 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
526 // The following test checks that all public member functions on the class
527 // ip::udp::resolver compile and link correctly. Runtime failures are ignored.
528 
529 namespace ip_udp_resolver_compile {
530 
531 struct resolve_handler
532 {
resolve_handlerip_udp_resolver_compile::resolve_handler533   resolve_handler() {}
operator ()ip_udp_resolver_compile::resolve_handler534   void operator()(const boost::system::error_code&,
535       boost::asio::ip::udp::resolver::results_type) {}
536 #if defined(BOOST_ASIO_HAS_MOVE)
resolve_handlerip_udp_resolver_compile::resolve_handler537   resolve_handler(resolve_handler&&) {}
538 private:
539   resolve_handler(const resolve_handler&);
540 #endif // defined(BOOST_ASIO_HAS_MOVE)
541 };
542 
test()543 void test()
544 {
545   using namespace boost::asio;
546   namespace ip = boost::asio::ip;
547 
548   try
549   {
550     io_context ioc;
551     const io_context::executor_type ioc_ex = ioc.get_executor();
552     archetypes::lazy_handler lazy;
553     boost::system::error_code ec;
554 #if !defined(BOOST_ASIO_NO_DEPRECATED)
555     ip::udp::resolver::query q(ip::udp::v4(), "localhost", "0");
556 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
557     ip::udp::endpoint e(ip::address_v4::loopback(), 0);
558 
559     // basic_resolver constructors.
560 
561     ip::udp::resolver resolver(ioc);
562     ip::udp::resolver resolver2(ioc_ex);
563 
564 #if defined(BOOST_ASIO_HAS_MOVE)
565     ip::udp::resolver resolver3(std::move(resolver));
566 #endif // defined(BOOST_ASIO_HAS_MOVE)
567 
568     // basic_resolver operators.
569 
570 #if defined(BOOST_ASIO_HAS_MOVE)
571     resolver = ip::udp::resolver(ioc);
572     resolver = std::move(resolver3);
573 #endif // defined(BOOST_ASIO_HAS_MOVE)
574 
575     // basic_io_object functions.
576 
577     ip::udp::resolver::executor_type ex = resolver.get_executor();
578     (void)ex;
579 
580     // basic_resolver functions.
581 
582     resolver.cancel();
583 
584 #if !defined(BOOST_ASIO_NO_DEPRECATED)
585     ip::udp::resolver::results_type results1 = resolver.resolve(q);
586     (void)results1;
587 
588     ip::udp::resolver::results_type results2 = resolver.resolve(q, ec);
589     (void)results2;
590 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
591 
592     ip::udp::resolver::results_type results3 = resolver.resolve("", "");
593     (void)results3;
594 
595     ip::udp::resolver::results_type results4 = resolver.resolve("", "", ec);
596     (void)results4;
597 
598     ip::udp::resolver::results_type results5 =
599       resolver.resolve("", "", ip::udp::resolver::flags());
600     (void)results5;
601 
602     ip::udp::resolver::results_type results6 =
603       resolver.resolve("", "", ip::udp::resolver::flags(), ec);
604     (void)results6;
605 
606     ip::udp::resolver::results_type results7 =
607       resolver.resolve(ip::udp::v4(), "", "");
608     (void)results7;
609 
610     ip::udp::resolver::results_type results8 =
611       resolver.resolve(ip::udp::v4(), "", "", ec);
612     (void)results8;
613 
614     ip::udp::resolver::results_type results9 =
615       resolver.resolve(ip::udp::v4(), "", "", ip::udp::resolver::flags());
616     (void)results9;
617 
618     ip::udp::resolver::results_type results10 =
619       resolver.resolve(ip::udp::v4(), "", "", ip::udp::resolver::flags(), ec);
620     (void)results10;
621 
622     ip::udp::resolver::results_type results11 = resolver.resolve(e);
623     (void)results11;
624 
625     ip::udp::resolver::results_type results12 = resolver.resolve(e, ec);
626     (void)results12;
627 
628 #if !defined(BOOST_ASIO_NO_DEPRECATED)
629     resolver.async_resolve(q, resolve_handler());
630     int i1 = resolver.async_resolve(q, lazy);
631     (void)i1;
632 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
633 
634     resolver.async_resolve("", "", resolve_handler());
635     int i2 = resolver.async_resolve("", "", lazy);
636     (void)i2;
637 
638     resolver.async_resolve("", "",
639         ip::udp::resolver::flags(), resolve_handler());
640     int i3 = resolver.async_resolve("", "",
641         ip::udp::resolver::flags(), lazy);
642     (void)i3;
643 
644     resolver.async_resolve(ip::udp::v4(), "", "", resolve_handler());
645     int i4 = resolver.async_resolve(ip::udp::v4(), "", "", lazy);
646     (void)i4;
647 
648     resolver.async_resolve(ip::udp::v4(),
649         "", "", ip::udp::resolver::flags(), resolve_handler());
650     int i5 = resolver.async_resolve(ip::udp::v4(),
651         "", "", ip::udp::resolver::flags(), lazy);
652     (void)i5;
653 
654     resolver.async_resolve(e, resolve_handler());
655     int i6 = resolver.async_resolve(e, lazy);
656     (void)i6;
657   }
658   catch (std::exception&)
659   {
660   }
661 }
662 
663 } // namespace ip_udp_resolver_compile
664 
665 //------------------------------------------------------------------------------
666 
667 BOOST_ASIO_TEST_SUITE
668 (
669   "ip/udp",
670   BOOST_ASIO_TEST_CASE(ip_udp_socket_compile::test)
671   BOOST_ASIO_TEST_CASE(ip_udp_socket_runtime::test)
672   BOOST_ASIO_TEST_CASE(ip_udp_resolver_compile::test)
673 )
674