• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // socket_base.cpp
3 // ~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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/socket_base.hpp>
18 
19 #include <boost/asio/io_context.hpp>
20 #include <boost/asio/ip/tcp.hpp>
21 #include <boost/asio/ip/udp.hpp>
22 #include "unit_test.hpp"
23 
24 //------------------------------------------------------------------------------
25 
26 // socket_base_compile test
27 // ~~~~~~~~~~~~~~~~~~~~~~~~
28 // The following test checks that all nested classes, enums and constants in
29 // socket_base compile and link correctly. Runtime failures are ignored.
30 
31 namespace socket_base_compile {
32 
test()33 void test()
34 {
35   using namespace boost::asio;
36   namespace ip = boost::asio::ip;
37 
38   try
39   {
40     io_context ioc;
41     ip::tcp::socket sock(ioc);
42     char buf[1024];
43 
44     // shutdown_type enumeration.
45 
46     sock.shutdown(socket_base::shutdown_receive);
47     sock.shutdown(socket_base::shutdown_send);
48     sock.shutdown(socket_base::shutdown_both);
49 
50     // message_flags constants.
51 
52     sock.receive(buffer(buf), socket_base::message_peek);
53     sock.receive(buffer(buf), socket_base::message_out_of_band);
54     sock.send(buffer(buf), socket_base::message_do_not_route);
55 
56     // broadcast class.
57 
58     socket_base::broadcast broadcast1(true);
59     sock.set_option(broadcast1);
60     socket_base::broadcast broadcast2;
61     sock.get_option(broadcast2);
62     broadcast1 = true;
63     (void)static_cast<bool>(broadcast1);
64     (void)static_cast<bool>(!broadcast1);
65     (void)static_cast<bool>(broadcast1.value());
66 
67     // debug class.
68 
69     socket_base::debug debug1(true);
70     sock.set_option(debug1);
71     socket_base::debug debug2;
72     sock.get_option(debug2);
73     debug1 = true;
74     (void)static_cast<bool>(debug1);
75     (void)static_cast<bool>(!debug1);
76     (void)static_cast<bool>(debug1.value());
77 
78     // do_not_route class.
79 
80     socket_base::do_not_route do_not_route1(true);
81     sock.set_option(do_not_route1);
82     socket_base::do_not_route do_not_route2;
83     sock.get_option(do_not_route2);
84     do_not_route1 = true;
85     (void)static_cast<bool>(do_not_route1);
86     (void)static_cast<bool>(!do_not_route1);
87     (void)static_cast<bool>(do_not_route1.value());
88 
89     // keep_alive class.
90 
91     socket_base::keep_alive keep_alive1(true);
92     sock.set_option(keep_alive1);
93     socket_base::keep_alive keep_alive2;
94     sock.get_option(keep_alive2);
95     keep_alive1 = true;
96     (void)static_cast<bool>(keep_alive1);
97     (void)static_cast<bool>(!keep_alive1);
98     (void)static_cast<bool>(keep_alive1.value());
99 
100     // send_buffer_size class.
101 
102     socket_base::send_buffer_size send_buffer_size1(1024);
103     sock.set_option(send_buffer_size1);
104     socket_base::send_buffer_size send_buffer_size2;
105     sock.get_option(send_buffer_size2);
106     send_buffer_size1 = 1;
107     (void)static_cast<int>(send_buffer_size1.value());
108 
109     // send_low_watermark class.
110 
111     socket_base::send_low_watermark send_low_watermark1(128);
112     sock.set_option(send_low_watermark1);
113     socket_base::send_low_watermark send_low_watermark2;
114     sock.get_option(send_low_watermark2);
115     send_low_watermark1 = 1;
116     (void)static_cast<int>(send_low_watermark1.value());
117 
118     // receive_buffer_size class.
119 
120     socket_base::receive_buffer_size receive_buffer_size1(1024);
121     sock.set_option(receive_buffer_size1);
122     socket_base::receive_buffer_size receive_buffer_size2;
123     sock.get_option(receive_buffer_size2);
124     receive_buffer_size1 = 1;
125     (void)static_cast<int>(receive_buffer_size1.value());
126 
127     // receive_low_watermark class.
128 
129     socket_base::receive_low_watermark receive_low_watermark1(128);
130     sock.set_option(receive_low_watermark1);
131     socket_base::receive_low_watermark receive_low_watermark2;
132     sock.get_option(receive_low_watermark2);
133     receive_low_watermark1 = 1;
134     (void)static_cast<int>(receive_low_watermark1.value());
135 
136     // reuse_address class.
137 
138     socket_base::reuse_address reuse_address1(true);
139     sock.set_option(reuse_address1);
140     socket_base::reuse_address reuse_address2;
141     sock.get_option(reuse_address2);
142     reuse_address1 = true;
143     (void)static_cast<bool>(reuse_address1);
144     (void)static_cast<bool>(!reuse_address1);
145     (void)static_cast<bool>(reuse_address1.value());
146 
147     // linger class.
148 
149     socket_base::linger linger1(true, 30);
150     sock.set_option(linger1);
151     socket_base::linger linger2;
152     sock.get_option(linger2);
153     linger1.enabled(true);
154     (void)static_cast<bool>(linger1.enabled());
155     linger1.timeout(1);
156     (void)static_cast<int>(linger1.timeout());
157 
158     // out_of_band_inline class.
159 
160     socket_base::out_of_band_inline out_of_band_inline1(true);
161     sock.set_option(out_of_band_inline1);
162     socket_base::out_of_band_inline out_of_band_inline2;
163     sock.get_option(out_of_band_inline2);
164     out_of_band_inline1 = true;
165     (void)static_cast<bool>(out_of_band_inline1);
166     (void)static_cast<bool>(!out_of_band_inline1);
167     (void)static_cast<bool>(out_of_band_inline1.value());
168 
169     // enable_connection_aborted class.
170 
171     socket_base::enable_connection_aborted enable_connection_aborted1(true);
172     sock.set_option(enable_connection_aborted1);
173     socket_base::enable_connection_aborted enable_connection_aborted2;
174     sock.get_option(enable_connection_aborted2);
175     enable_connection_aborted1 = true;
176     (void)static_cast<bool>(enable_connection_aborted1);
177     (void)static_cast<bool>(!enable_connection_aborted1);
178     (void)static_cast<bool>(enable_connection_aborted1.value());
179 
180     // bytes_readable class.
181 
182     socket_base::bytes_readable bytes_readable;
183     sock.io_control(bytes_readable);
184     std::size_t bytes = bytes_readable.get();
185     (void)bytes;
186   }
187   catch (std::exception&)
188   {
189   }
190 }
191 
192 } // namespace socket_base_compile
193 
194 //------------------------------------------------------------------------------
195 
196 // socket_base_runtime test
197 // ~~~~~~~~~~~~~~~~~~~~~~~~
198 // The following test checks the runtime operation of the socket options and I/O
199 // control commands defined in socket_base.
200 
201 namespace socket_base_runtime {
202 
test()203 void test()
204 {
205   using namespace boost::asio;
206   namespace ip = boost::asio::ip;
207 
208   io_context ioc;
209   ip::udp::socket udp_sock(ioc, ip::udp::v4());
210   ip::tcp::socket tcp_sock(ioc, ip::tcp::v4());
211   ip::tcp::acceptor tcp_acceptor(ioc, ip::tcp::v4());
212   boost::system::error_code ec;
213 
214   // broadcast class.
215 
216   socket_base::broadcast broadcast1(true);
217   BOOST_ASIO_CHECK(broadcast1.value());
218   BOOST_ASIO_CHECK(static_cast<bool>(broadcast1));
219   BOOST_ASIO_CHECK(!!broadcast1);
220   udp_sock.set_option(broadcast1, ec);
221   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
222 
223   socket_base::broadcast broadcast2;
224   udp_sock.get_option(broadcast2, ec);
225   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
226   BOOST_ASIO_CHECK(broadcast2.value());
227   BOOST_ASIO_CHECK(static_cast<bool>(broadcast2));
228   BOOST_ASIO_CHECK(!!broadcast2);
229 
230   socket_base::broadcast broadcast3(false);
231   BOOST_ASIO_CHECK(!broadcast3.value());
232   BOOST_ASIO_CHECK(!static_cast<bool>(broadcast3));
233   BOOST_ASIO_CHECK(!broadcast3);
234   udp_sock.set_option(broadcast3, ec);
235   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
236 
237   socket_base::broadcast broadcast4;
238   udp_sock.get_option(broadcast4, ec);
239   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
240   BOOST_ASIO_CHECK(!broadcast4.value());
241   BOOST_ASIO_CHECK(!static_cast<bool>(broadcast4));
242   BOOST_ASIO_CHECK(!broadcast4);
243 
244   // debug class.
245 
246   socket_base::debug debug1(true);
247   BOOST_ASIO_CHECK(debug1.value());
248   BOOST_ASIO_CHECK(static_cast<bool>(debug1));
249   BOOST_ASIO_CHECK(!!debug1);
250   udp_sock.set_option(debug1, ec);
251 #if defined(__linux__)
252   // On Linux, only root can set SO_DEBUG.
253   bool not_root = (ec == boost::asio::error::access_denied);
254   BOOST_ASIO_CHECK(!ec || not_root);
255   BOOST_ASIO_WARN_MESSAGE(!ec, "Must be root to set debug socket option");
256 #else // defined(__linux__)
257 # if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
258   // Option is not supported under Windows CE.
259   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
260       ec.value() << ", " << ec.message());
261 # else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
262   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
263 # endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
264 #endif // defined(__linux__)
265 
266   socket_base::debug debug2;
267   udp_sock.get_option(debug2, ec);
268 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
269   // Option is not supported under Windows CE.
270   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
271       ec.value() << ", " << ec.message());
272 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
273   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
274 # if defined(__linux__)
275   BOOST_ASIO_CHECK(debug2.value() || not_root);
276   BOOST_ASIO_CHECK(static_cast<bool>(debug2) || not_root);
277   BOOST_ASIO_CHECK(!!debug2 || not_root);
278 # else // defined(__linux__)
279   BOOST_ASIO_CHECK(debug2.value());
280   BOOST_ASIO_CHECK(static_cast<bool>(debug2));
281   BOOST_ASIO_CHECK(!!debug2);
282 # endif // defined(__linux__)
283 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
284 
285   socket_base::debug debug3(false);
286   BOOST_ASIO_CHECK(!debug3.value());
287   BOOST_ASIO_CHECK(!static_cast<bool>(debug3));
288   BOOST_ASIO_CHECK(!debug3);
289   udp_sock.set_option(debug3, ec);
290 #if defined(__linux__)
291   BOOST_ASIO_CHECK(!ec || not_root);
292 #else // defined(__linux__)
293 # if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
294   // Option is not supported under Windows CE.
295   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
296       ec.value() << ", " << ec.message());
297 # else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
298   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
299 # endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
300 #endif // defined(__linux__)
301 
302   socket_base::debug debug4;
303   udp_sock.get_option(debug4, ec);
304 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
305   // Option is not supported under Windows CE.
306   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
307       ec.value() << ", " << ec.message());
308 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
309   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
310 # if defined(__linux__)
311   BOOST_ASIO_CHECK(!debug4.value() || not_root);
312   BOOST_ASIO_CHECK(!static_cast<bool>(debug4) || not_root);
313   BOOST_ASIO_CHECK(!debug4 || not_root);
314 # else // defined(__linux__)
315   BOOST_ASIO_CHECK(!debug4.value());
316   BOOST_ASIO_CHECK(!static_cast<bool>(debug4));
317   BOOST_ASIO_CHECK(!debug4);
318 # endif // defined(__linux__)
319 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
320 
321   // do_not_route class.
322 
323   socket_base::do_not_route do_not_route1(true);
324   BOOST_ASIO_CHECK(do_not_route1.value());
325   BOOST_ASIO_CHECK(static_cast<bool>(do_not_route1));
326   BOOST_ASIO_CHECK(!!do_not_route1);
327   udp_sock.set_option(do_not_route1, ec);
328 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
329   // Option is not supported under Windows CE.
330   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
331       ec.value() << ", " << ec.message());
332 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
333   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
334 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
335 
336   socket_base::do_not_route do_not_route2;
337   udp_sock.get_option(do_not_route2, ec);
338 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
339   // Option is not supported under Windows CE.
340   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
341       ec.value() << ", " << ec.message());
342 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
343   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
344   BOOST_ASIO_CHECK(do_not_route2.value());
345   BOOST_ASIO_CHECK(static_cast<bool>(do_not_route2));
346   BOOST_ASIO_CHECK(!!do_not_route2);
347 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
348 
349   socket_base::do_not_route do_not_route3(false);
350   BOOST_ASIO_CHECK(!do_not_route3.value());
351   BOOST_ASIO_CHECK(!static_cast<bool>(do_not_route3));
352   BOOST_ASIO_CHECK(!do_not_route3);
353   udp_sock.set_option(do_not_route3, ec);
354 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
355   // Option is not supported under Windows CE.
356   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
357       ec.value() << ", " << ec.message());
358 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
359   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
360 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
361 
362   socket_base::do_not_route do_not_route4;
363   udp_sock.get_option(do_not_route4, ec);
364 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
365   // Option is not supported under Windows CE.
366   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
367       ec.value() << ", " << ec.message());
368 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
369   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
370   BOOST_ASIO_CHECK(!do_not_route4.value());
371   BOOST_ASIO_CHECK(!static_cast<bool>(do_not_route4));
372   BOOST_ASIO_CHECK(!do_not_route4);
373 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
374 
375   // keep_alive class.
376 
377   socket_base::keep_alive keep_alive1(true);
378   BOOST_ASIO_CHECK(keep_alive1.value());
379   BOOST_ASIO_CHECK(static_cast<bool>(keep_alive1));
380   BOOST_ASIO_CHECK(!!keep_alive1);
381   tcp_sock.set_option(keep_alive1, ec);
382   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
383 
384   socket_base::keep_alive keep_alive2;
385   tcp_sock.get_option(keep_alive2, ec);
386   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
387   BOOST_ASIO_CHECK(keep_alive2.value());
388   BOOST_ASIO_CHECK(static_cast<bool>(keep_alive2));
389   BOOST_ASIO_CHECK(!!keep_alive2);
390 
391   socket_base::keep_alive keep_alive3(false);
392   BOOST_ASIO_CHECK(!keep_alive3.value());
393   BOOST_ASIO_CHECK(!static_cast<bool>(keep_alive3));
394   BOOST_ASIO_CHECK(!keep_alive3);
395   tcp_sock.set_option(keep_alive3, ec);
396   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
397 
398   socket_base::keep_alive keep_alive4;
399   tcp_sock.get_option(keep_alive4, ec);
400   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
401   BOOST_ASIO_CHECK(!keep_alive4.value());
402   BOOST_ASIO_CHECK(!static_cast<bool>(keep_alive4));
403   BOOST_ASIO_CHECK(!keep_alive4);
404 
405   // send_buffer_size class.
406 
407   socket_base::send_buffer_size send_buffer_size1(4096);
408   BOOST_ASIO_CHECK(send_buffer_size1.value() == 4096);
409   tcp_sock.set_option(send_buffer_size1, ec);
410   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
411 
412   socket_base::send_buffer_size send_buffer_size2;
413   tcp_sock.get_option(send_buffer_size2, ec);
414   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
415   BOOST_ASIO_CHECK(send_buffer_size2.value() == 4096);
416 
417   socket_base::send_buffer_size send_buffer_size3(16384);
418   BOOST_ASIO_CHECK(send_buffer_size3.value() == 16384);
419   tcp_sock.set_option(send_buffer_size3, ec);
420   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
421 
422   socket_base::send_buffer_size send_buffer_size4;
423   tcp_sock.get_option(send_buffer_size4, ec);
424   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
425   BOOST_ASIO_CHECK(send_buffer_size4.value() == 16384);
426 
427   // send_low_watermark class.
428 
429   socket_base::send_low_watermark send_low_watermark1(4096);
430   BOOST_ASIO_CHECK(send_low_watermark1.value() == 4096);
431   tcp_sock.set_option(send_low_watermark1, ec);
432 #if defined(WIN32) || defined(__linux__) || defined(__sun)
433   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows, Linux or Solaris.
434 #else
435   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
436 #endif
437 
438   socket_base::send_low_watermark send_low_watermark2;
439   tcp_sock.get_option(send_low_watermark2, ec);
440 #if defined(WIN32) || defined(__sun)
441   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
442 #elif defined(__linux__)
443   BOOST_ASIO_CHECK(!ec); // Not supported on Linux but can get value.
444 #else
445   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
446   BOOST_ASIO_CHECK(send_low_watermark2.value() == 4096);
447 #endif
448 
449   socket_base::send_low_watermark send_low_watermark3(8192);
450   BOOST_ASIO_CHECK(send_low_watermark3.value() == 8192);
451   tcp_sock.set_option(send_low_watermark3, ec);
452 #if defined(WIN32) || defined(__linux__) || defined(__sun)
453   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows, Linux or Solaris.
454 #else
455   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
456 #endif
457 
458   socket_base::send_low_watermark send_low_watermark4;
459   tcp_sock.get_option(send_low_watermark4, ec);
460 #if defined(WIN32) || defined(__sun)
461   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
462 #elif defined(__linux__)
463   BOOST_ASIO_CHECK(!ec); // Not supported on Linux but can get value.
464 #else
465   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
466   BOOST_ASIO_CHECK(send_low_watermark4.value() == 8192);
467 #endif
468 
469   // receive_buffer_size class.
470 
471   socket_base::receive_buffer_size receive_buffer_size1(4096);
472   BOOST_ASIO_CHECK(receive_buffer_size1.value() == 4096);
473   tcp_sock.set_option(receive_buffer_size1, ec);
474 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
475   // Option is not supported under Windows CE.
476   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
477       ec.value() << ", " << ec.message());
478 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
479   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
480 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
481 
482   socket_base::receive_buffer_size receive_buffer_size2;
483   tcp_sock.get_option(receive_buffer_size2, ec);
484 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
485   BOOST_ASIO_CHECK(!ec); // Not supported under Windows CE but can get value.
486 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
487   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
488   BOOST_ASIO_CHECK(receive_buffer_size2.value() == 4096);
489 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
490 
491   socket_base::receive_buffer_size receive_buffer_size3(16384);
492   BOOST_ASIO_CHECK(receive_buffer_size3.value() == 16384);
493   tcp_sock.set_option(receive_buffer_size3, ec);
494 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
495   // Option is not supported under Windows CE.
496   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
497       ec.value() << ", " << ec.message());
498 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
499   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
500 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
501 
502   socket_base::receive_buffer_size receive_buffer_size4;
503   tcp_sock.get_option(receive_buffer_size4, ec);
504 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
505   BOOST_ASIO_CHECK(!ec); // Not supported under Windows CE but can get value.
506 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
507   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
508   BOOST_ASIO_CHECK(receive_buffer_size4.value() == 16384);
509 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
510 
511   // receive_low_watermark class.
512 
513   socket_base::receive_low_watermark receive_low_watermark1(4096);
514   BOOST_ASIO_CHECK(receive_low_watermark1.value() == 4096);
515   tcp_sock.set_option(receive_low_watermark1, ec);
516 #if defined(WIN32) || defined(__sun)
517   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
518 #else
519   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
520 #endif
521 
522   socket_base::receive_low_watermark receive_low_watermark2;
523   tcp_sock.get_option(receive_low_watermark2, ec);
524 #if defined(WIN32) || defined(__sun)
525   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
526 #else
527   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
528   BOOST_ASIO_CHECK(receive_low_watermark2.value() == 4096);
529 #endif
530 
531   socket_base::receive_low_watermark receive_low_watermark3(8192);
532   BOOST_ASIO_CHECK(receive_low_watermark3.value() == 8192);
533   tcp_sock.set_option(receive_low_watermark3, ec);
534 #if defined(WIN32) || defined(__sun)
535   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
536 #else
537   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
538 #endif
539 
540   socket_base::receive_low_watermark receive_low_watermark4;
541   tcp_sock.get_option(receive_low_watermark4, ec);
542 #if defined(WIN32) || defined(__sun)
543   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
544 #else
545   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
546   BOOST_ASIO_CHECK(receive_low_watermark4.value() == 8192);
547 #endif
548 
549   // reuse_address class.
550 
551   socket_base::reuse_address reuse_address1(true);
552   BOOST_ASIO_CHECK(reuse_address1.value());
553   BOOST_ASIO_CHECK(static_cast<bool>(reuse_address1));
554   BOOST_ASIO_CHECK(!!reuse_address1);
555   udp_sock.set_option(reuse_address1, ec);
556   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
557 
558   socket_base::reuse_address reuse_address2;
559   udp_sock.get_option(reuse_address2, ec);
560   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
561   BOOST_ASIO_CHECK(reuse_address2.value());
562   BOOST_ASIO_CHECK(static_cast<bool>(reuse_address2));
563   BOOST_ASIO_CHECK(!!reuse_address2);
564 
565   socket_base::reuse_address reuse_address3(false);
566   BOOST_ASIO_CHECK(!reuse_address3.value());
567   BOOST_ASIO_CHECK(!static_cast<bool>(reuse_address3));
568   BOOST_ASIO_CHECK(!reuse_address3);
569   udp_sock.set_option(reuse_address3, ec);
570   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
571 
572   socket_base::reuse_address reuse_address4;
573   udp_sock.get_option(reuse_address4, ec);
574   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
575   BOOST_ASIO_CHECK(!reuse_address4.value());
576   BOOST_ASIO_CHECK(!static_cast<bool>(reuse_address4));
577   BOOST_ASIO_CHECK(!reuse_address4);
578 
579   // linger class.
580 
581   socket_base::linger linger1(true, 60);
582   BOOST_ASIO_CHECK(linger1.enabled());
583   BOOST_ASIO_CHECK(linger1.timeout() == 60);
584   tcp_sock.set_option(linger1, ec);
585   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
586 
587   socket_base::linger linger2;
588   tcp_sock.get_option(linger2, ec);
589   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
590   BOOST_ASIO_CHECK(linger2.enabled());
591   BOOST_ASIO_CHECK(linger2.timeout() == 60);
592 
593   socket_base::linger linger3(false, 0);
594   BOOST_ASIO_CHECK(!linger3.enabled());
595   BOOST_ASIO_CHECK(linger3.timeout() == 0);
596   tcp_sock.set_option(linger3, ec);
597   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
598 
599   socket_base::linger linger4;
600   tcp_sock.get_option(linger4, ec);
601   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
602   BOOST_ASIO_CHECK(!linger4.enabled());
603 
604   // enable_connection_aborted class.
605 
606   socket_base::enable_connection_aborted enable_connection_aborted1(true);
607   BOOST_ASIO_CHECK(enable_connection_aborted1.value());
608   BOOST_ASIO_CHECK(static_cast<bool>(enable_connection_aborted1));
609   BOOST_ASIO_CHECK(!!enable_connection_aborted1);
610   tcp_acceptor.set_option(enable_connection_aborted1, ec);
611   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
612 
613   socket_base::enable_connection_aborted enable_connection_aborted2;
614   tcp_acceptor.get_option(enable_connection_aborted2, ec);
615   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
616   BOOST_ASIO_CHECK(enable_connection_aborted2.value());
617   BOOST_ASIO_CHECK(static_cast<bool>(enable_connection_aborted2));
618   BOOST_ASIO_CHECK(!!enable_connection_aborted2);
619 
620   socket_base::enable_connection_aborted enable_connection_aborted3(false);
621   BOOST_ASIO_CHECK(!enable_connection_aborted3.value());
622   BOOST_ASIO_CHECK(!static_cast<bool>(enable_connection_aborted3));
623   BOOST_ASIO_CHECK(!enable_connection_aborted3);
624   tcp_acceptor.set_option(enable_connection_aborted3, ec);
625   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
626 
627   socket_base::enable_connection_aborted enable_connection_aborted4;
628   tcp_acceptor.get_option(enable_connection_aborted4, ec);
629   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
630   BOOST_ASIO_CHECK(!enable_connection_aborted4.value());
631   BOOST_ASIO_CHECK(!static_cast<bool>(enable_connection_aborted4));
632   BOOST_ASIO_CHECK(!enable_connection_aborted4);
633 
634   // bytes_readable class.
635 
636   socket_base::bytes_readable bytes_readable;
637   udp_sock.io_control(bytes_readable, ec);
638   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
639 }
640 
641 } // namespace socket_base_runtime
642 
643 //------------------------------------------------------------------------------
644 
645 BOOST_ASIO_TEST_SUITE
646 (
647   "socket_base",
648   BOOST_ASIO_TEST_CASE(socket_base_compile::test)
649   BOOST_ASIO_TEST_CASE(socket_base_runtime::test)
650 )
651