1 //
2 // socket_base.cpp
3 // ~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 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_service.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_service ios;
41     ip::tcp::socket sock(ios);
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     // enable_connection_aborted class.
159 
160     socket_base::enable_connection_aborted enable_connection_aborted1(true);
161     sock.set_option(enable_connection_aborted1);
162     socket_base::enable_connection_aborted enable_connection_aborted2;
163     sock.get_option(enable_connection_aborted2);
164     enable_connection_aborted1 = true;
165     (void)static_cast<bool>(enable_connection_aborted1);
166     (void)static_cast<bool>(!enable_connection_aborted1);
167     (void)static_cast<bool>(enable_connection_aborted1.value());
168 
169     // non_blocking_io class.
170 
171     socket_base::non_blocking_io non_blocking_io(true);
172     sock.io_control(non_blocking_io);
173 
174     // bytes_readable class.
175 
176     socket_base::bytes_readable bytes_readable;
177     sock.io_control(bytes_readable);
178     std::size_t bytes = bytes_readable.get();
179     (void)bytes;
180   }
181   catch (std::exception&)
182   {
183   }
184 }
185 
186 } // namespace socket_base_compile
187 
188 //------------------------------------------------------------------------------
189 
190 // socket_base_runtime test
191 // ~~~~~~~~~~~~~~~~~~~~~~~~
192 // The following test checks the runtime operation of the socket options and I/O
193 // control commands defined in socket_base.
194 
195 namespace socket_base_runtime {
196 
test()197 void test()
198 {
199   using namespace boost::asio;
200   namespace ip = boost::asio::ip;
201 
202   io_service ios;
203   ip::udp::socket udp_sock(ios, ip::udp::v4());
204   ip::tcp::socket tcp_sock(ios, ip::tcp::v4());
205   ip::tcp::acceptor tcp_acceptor(ios, ip::tcp::v4());
206   boost::system::error_code ec;
207 
208   // broadcast class.
209 
210   socket_base::broadcast broadcast1(true);
211   BOOST_ASIO_CHECK(broadcast1.value());
212   BOOST_ASIO_CHECK(static_cast<bool>(broadcast1));
213   BOOST_ASIO_CHECK(!!broadcast1);
214   udp_sock.set_option(broadcast1, ec);
215   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
216 
217   socket_base::broadcast broadcast2;
218   udp_sock.get_option(broadcast2, ec);
219   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
220   BOOST_ASIO_CHECK(broadcast2.value());
221   BOOST_ASIO_CHECK(static_cast<bool>(broadcast2));
222   BOOST_ASIO_CHECK(!!broadcast2);
223 
224   socket_base::broadcast broadcast3(false);
225   BOOST_ASIO_CHECK(!broadcast3.value());
226   BOOST_ASIO_CHECK(!static_cast<bool>(broadcast3));
227   BOOST_ASIO_CHECK(!broadcast3);
228   udp_sock.set_option(broadcast3, ec);
229   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
230 
231   socket_base::broadcast broadcast4;
232   udp_sock.get_option(broadcast4, ec);
233   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
234   BOOST_ASIO_CHECK(!broadcast4.value());
235   BOOST_ASIO_CHECK(!static_cast<bool>(broadcast4));
236   BOOST_ASIO_CHECK(!broadcast4);
237 
238   // debug class.
239 
240   socket_base::debug debug1(true);
241   BOOST_ASIO_CHECK(debug1.value());
242   BOOST_ASIO_CHECK(static_cast<bool>(debug1));
243   BOOST_ASIO_CHECK(!!debug1);
244   udp_sock.set_option(debug1, ec);
245 #if defined(__linux__)
246   // On Linux, only root can set SO_DEBUG.
247   bool not_root = (ec == boost::asio::error::access_denied);
248   BOOST_ASIO_CHECK(!ec || not_root);
249   BOOST_ASIO_WARN_MESSAGE(!ec, "Must be root to set debug socket option");
250 #else // defined(__linux__)
251 # if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
252   // Option is not supported under Windows CE.
253   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
254       ec.value() << ", " << ec.message());
255 # else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
256   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
257 # endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
258 #endif // defined(__linux__)
259 
260   socket_base::debug debug2;
261   udp_sock.get_option(debug2, ec);
262 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
263   // Option is not supported under Windows CE.
264   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
265       ec.value() << ", " << ec.message());
266 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
267   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
268 # if defined(__linux__)
269   BOOST_ASIO_CHECK(debug2.value() || not_root);
270   BOOST_ASIO_CHECK(static_cast<bool>(debug2) || not_root);
271   BOOST_ASIO_CHECK(!!debug2 || not_root);
272 # else // defined(__linux__)
273   BOOST_ASIO_CHECK(debug2.value());
274   BOOST_ASIO_CHECK(static_cast<bool>(debug2));
275   BOOST_ASIO_CHECK(!!debug2);
276 # endif // defined(__linux__)
277 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
278 
279   socket_base::debug debug3(false);
280   BOOST_ASIO_CHECK(!debug3.value());
281   BOOST_ASIO_CHECK(!static_cast<bool>(debug3));
282   BOOST_ASIO_CHECK(!debug3);
283   udp_sock.set_option(debug3, ec);
284 #if defined(__linux__)
285   BOOST_ASIO_CHECK(!ec || not_root);
286 #else // defined(__linux__)
287 # if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
288   // Option is not supported under Windows CE.
289   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
290       ec.value() << ", " << ec.message());
291 # else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
292   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
293 # endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
294 #endif // defined(__linux__)
295 
296   socket_base::debug debug4;
297   udp_sock.get_option(debug4, ec);
298 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
299   // Option is not supported under Windows CE.
300   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
301       ec.value() << ", " << ec.message());
302 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
303   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
304 # if defined(__linux__)
305   BOOST_ASIO_CHECK(!debug4.value() || not_root);
306   BOOST_ASIO_CHECK(!static_cast<bool>(debug4) || not_root);
307   BOOST_ASIO_CHECK(!debug4 || not_root);
308 # else // defined(__linux__)
309   BOOST_ASIO_CHECK(!debug4.value());
310   BOOST_ASIO_CHECK(!static_cast<bool>(debug4));
311   BOOST_ASIO_CHECK(!debug4);
312 # endif // defined(__linux__)
313 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
314 
315   // do_not_route class.
316 
317   socket_base::do_not_route do_not_route1(true);
318   BOOST_ASIO_CHECK(do_not_route1.value());
319   BOOST_ASIO_CHECK(static_cast<bool>(do_not_route1));
320   BOOST_ASIO_CHECK(!!do_not_route1);
321   udp_sock.set_option(do_not_route1, ec);
322 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
323   // Option is not supported under Windows CE.
324   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
325       ec.value() << ", " << ec.message());
326 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
327   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
328 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
329 
330   socket_base::do_not_route do_not_route2;
331   udp_sock.get_option(do_not_route2, ec);
332 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
333   // Option is not supported under Windows CE.
334   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
335       ec.value() << ", " << ec.message());
336 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
337   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
338   BOOST_ASIO_CHECK(do_not_route2.value());
339   BOOST_ASIO_CHECK(static_cast<bool>(do_not_route2));
340   BOOST_ASIO_CHECK(!!do_not_route2);
341 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
342 
343   socket_base::do_not_route do_not_route3(false);
344   BOOST_ASIO_CHECK(!do_not_route3.value());
345   BOOST_ASIO_CHECK(!static_cast<bool>(do_not_route3));
346   BOOST_ASIO_CHECK(!do_not_route3);
347   udp_sock.set_option(do_not_route3, ec);
348 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
349   // Option is not supported under Windows CE.
350   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
351       ec.value() << ", " << ec.message());
352 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
353   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
354 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
355 
356   socket_base::do_not_route do_not_route4;
357   udp_sock.get_option(do_not_route4, ec);
358 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
359   // Option is not supported under Windows CE.
360   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
361       ec.value() << ", " << ec.message());
362 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
363   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
364   BOOST_ASIO_CHECK(!do_not_route4.value());
365   BOOST_ASIO_CHECK(!static_cast<bool>(do_not_route4));
366   BOOST_ASIO_CHECK(!do_not_route4);
367 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
368 
369   // keep_alive class.
370 
371   socket_base::keep_alive keep_alive1(true);
372   BOOST_ASIO_CHECK(keep_alive1.value());
373   BOOST_ASIO_CHECK(static_cast<bool>(keep_alive1));
374   BOOST_ASIO_CHECK(!!keep_alive1);
375   tcp_sock.set_option(keep_alive1, ec);
376   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
377 
378   socket_base::keep_alive keep_alive2;
379   tcp_sock.get_option(keep_alive2, ec);
380   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
381   BOOST_ASIO_CHECK(keep_alive2.value());
382   BOOST_ASIO_CHECK(static_cast<bool>(keep_alive2));
383   BOOST_ASIO_CHECK(!!keep_alive2);
384 
385   socket_base::keep_alive keep_alive3(false);
386   BOOST_ASIO_CHECK(!keep_alive3.value());
387   BOOST_ASIO_CHECK(!static_cast<bool>(keep_alive3));
388   BOOST_ASIO_CHECK(!keep_alive3);
389   tcp_sock.set_option(keep_alive3, ec);
390   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
391 
392   socket_base::keep_alive keep_alive4;
393   tcp_sock.get_option(keep_alive4, ec);
394   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
395   BOOST_ASIO_CHECK(!keep_alive4.value());
396   BOOST_ASIO_CHECK(!static_cast<bool>(keep_alive4));
397   BOOST_ASIO_CHECK(!keep_alive4);
398 
399   // send_buffer_size class.
400 
401   socket_base::send_buffer_size send_buffer_size1(4096);
402   BOOST_ASIO_CHECK(send_buffer_size1.value() == 4096);
403   tcp_sock.set_option(send_buffer_size1, ec);
404   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
405 
406   socket_base::send_buffer_size send_buffer_size2;
407   tcp_sock.get_option(send_buffer_size2, ec);
408   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
409   BOOST_ASIO_CHECK(send_buffer_size2.value() == 4096);
410 
411   socket_base::send_buffer_size send_buffer_size3(16384);
412   BOOST_ASIO_CHECK(send_buffer_size3.value() == 16384);
413   tcp_sock.set_option(send_buffer_size3, ec);
414   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
415 
416   socket_base::send_buffer_size send_buffer_size4;
417   tcp_sock.get_option(send_buffer_size4, ec);
418   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
419   BOOST_ASIO_CHECK(send_buffer_size4.value() == 16384);
420 
421   // send_low_watermark class.
422 
423   socket_base::send_low_watermark send_low_watermark1(4096);
424   BOOST_ASIO_CHECK(send_low_watermark1.value() == 4096);
425   tcp_sock.set_option(send_low_watermark1, ec);
426 #if defined(WIN32) || defined(__linux__) || defined(__sun)
427   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows, Linux or Solaris.
428 #else
429   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
430 #endif
431 
432   socket_base::send_low_watermark send_low_watermark2;
433   tcp_sock.get_option(send_low_watermark2, ec);
434 #if defined(WIN32) || defined(__sun)
435   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
436 #elif defined(__linux__)
437   BOOST_ASIO_CHECK(!ec); // Not supported on Linux but can get value.
438 #else
439   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
440   BOOST_ASIO_CHECK(send_low_watermark2.value() == 4096);
441 #endif
442 
443   socket_base::send_low_watermark send_low_watermark3(8192);
444   BOOST_ASIO_CHECK(send_low_watermark3.value() == 8192);
445   tcp_sock.set_option(send_low_watermark3, ec);
446 #if defined(WIN32) || defined(__linux__) || defined(__sun)
447   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows, Linux or Solaris.
448 #else
449   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
450 #endif
451 
452   socket_base::send_low_watermark send_low_watermark4;
453   tcp_sock.get_option(send_low_watermark4, ec);
454 #if defined(WIN32) || defined(__sun)
455   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
456 #elif defined(__linux__)
457   BOOST_ASIO_CHECK(!ec); // Not supported on Linux but can get value.
458 #else
459   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
460   BOOST_ASIO_CHECK(send_low_watermark4.value() == 8192);
461 #endif
462 
463   // receive_buffer_size class.
464 
465   socket_base::receive_buffer_size receive_buffer_size1(4096);
466   BOOST_ASIO_CHECK(receive_buffer_size1.value() == 4096);
467   tcp_sock.set_option(receive_buffer_size1, ec);
468 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
469   // Option is not supported under Windows CE.
470   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
471       ec.value() << ", " << ec.message());
472 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
473   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
474 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
475 
476   socket_base::receive_buffer_size receive_buffer_size2;
477   tcp_sock.get_option(receive_buffer_size2, ec);
478 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
479   BOOST_ASIO_CHECK(!ec); // Not supported under Windows CE but can get value.
480 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
481   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
482   BOOST_ASIO_CHECK(receive_buffer_size2.value() == 4096);
483 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
484 
485   socket_base::receive_buffer_size receive_buffer_size3(16384);
486   BOOST_ASIO_CHECK(receive_buffer_size3.value() == 16384);
487   tcp_sock.set_option(receive_buffer_size3, ec);
488 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
489   // Option is not supported under Windows CE.
490   BOOST_ASIO_CHECK_MESSAGE(ec == boost::asio::error::no_protocol_option,
491       ec.value() << ", " << ec.message());
492 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
493   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
494 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
495 
496   socket_base::receive_buffer_size receive_buffer_size4;
497   tcp_sock.get_option(receive_buffer_size4, ec);
498 #if defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
499   BOOST_ASIO_CHECK(!ec); // Not supported under Windows CE but can get value.
500 #else // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
501   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
502   BOOST_ASIO_CHECK(receive_buffer_size4.value() == 16384);
503 #endif // defined(BOOST_ASIO_WINDOWS) && defined(UNDER_CE)
504 
505   // receive_low_watermark class.
506 
507   socket_base::receive_low_watermark receive_low_watermark1(4096);
508   BOOST_ASIO_CHECK(receive_low_watermark1.value() == 4096);
509   tcp_sock.set_option(receive_low_watermark1, ec);
510 #if defined(WIN32) || defined(__sun)
511   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
512 #else
513   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
514 #endif
515 
516   socket_base::receive_low_watermark receive_low_watermark2;
517   tcp_sock.get_option(receive_low_watermark2, ec);
518 #if defined(WIN32) || defined(__sun)
519   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
520 #else
521   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
522   BOOST_ASIO_CHECK(receive_low_watermark2.value() == 4096);
523 #endif
524 
525   socket_base::receive_low_watermark receive_low_watermark3(8192);
526   BOOST_ASIO_CHECK(receive_low_watermark3.value() == 8192);
527   tcp_sock.set_option(receive_low_watermark3, ec);
528 #if defined(WIN32) || defined(__sun)
529   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
530 #else
531   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
532 #endif
533 
534   socket_base::receive_low_watermark receive_low_watermark4;
535   tcp_sock.get_option(receive_low_watermark4, ec);
536 #if defined(WIN32) || defined(__sun)
537   BOOST_ASIO_CHECK(!!ec); // Not supported on Windows or Solaris.
538 #else
539   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
540   BOOST_ASIO_CHECK(receive_low_watermark4.value() == 8192);
541 #endif
542 
543   // reuse_address class.
544 
545   socket_base::reuse_address reuse_address1(true);
546   BOOST_ASIO_CHECK(reuse_address1.value());
547   BOOST_ASIO_CHECK(static_cast<bool>(reuse_address1));
548   BOOST_ASIO_CHECK(!!reuse_address1);
549   udp_sock.set_option(reuse_address1, ec);
550   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
551 
552   socket_base::reuse_address reuse_address2;
553   udp_sock.get_option(reuse_address2, ec);
554   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
555   BOOST_ASIO_CHECK(reuse_address2.value());
556   BOOST_ASIO_CHECK(static_cast<bool>(reuse_address2));
557   BOOST_ASIO_CHECK(!!reuse_address2);
558 
559   socket_base::reuse_address reuse_address3(false);
560   BOOST_ASIO_CHECK(!reuse_address3.value());
561   BOOST_ASIO_CHECK(!static_cast<bool>(reuse_address3));
562   BOOST_ASIO_CHECK(!reuse_address3);
563   udp_sock.set_option(reuse_address3, ec);
564   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
565 
566   socket_base::reuse_address reuse_address4;
567   udp_sock.get_option(reuse_address4, ec);
568   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
569   BOOST_ASIO_CHECK(!reuse_address4.value());
570   BOOST_ASIO_CHECK(!static_cast<bool>(reuse_address4));
571   BOOST_ASIO_CHECK(!reuse_address4);
572 
573   // linger class.
574 
575   socket_base::linger linger1(true, 60);
576   BOOST_ASIO_CHECK(linger1.enabled());
577   BOOST_ASIO_CHECK(linger1.timeout() == 60);
578   tcp_sock.set_option(linger1, ec);
579   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
580 
581   socket_base::linger linger2;
582   tcp_sock.get_option(linger2, ec);
583   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
584   BOOST_ASIO_CHECK(linger2.enabled());
585   BOOST_ASIO_CHECK(linger2.timeout() == 60);
586 
587   socket_base::linger linger3(false, 0);
588   BOOST_ASIO_CHECK(!linger3.enabled());
589   BOOST_ASIO_CHECK(linger3.timeout() == 0);
590   tcp_sock.set_option(linger3, ec);
591   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
592 
593   socket_base::linger linger4;
594   tcp_sock.get_option(linger4, ec);
595   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
596   BOOST_ASIO_CHECK(!linger4.enabled());
597 
598   // enable_connection_aborted class.
599 
600   socket_base::enable_connection_aborted enable_connection_aborted1(true);
601   BOOST_ASIO_CHECK(enable_connection_aborted1.value());
602   BOOST_ASIO_CHECK(static_cast<bool>(enable_connection_aborted1));
603   BOOST_ASIO_CHECK(!!enable_connection_aborted1);
604   tcp_acceptor.set_option(enable_connection_aborted1, ec);
605   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
606 
607   socket_base::enable_connection_aborted enable_connection_aborted2;
608   tcp_acceptor.get_option(enable_connection_aborted2, ec);
609   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
610   BOOST_ASIO_CHECK(enable_connection_aborted2.value());
611   BOOST_ASIO_CHECK(static_cast<bool>(enable_connection_aborted2));
612   BOOST_ASIO_CHECK(!!enable_connection_aborted2);
613 
614   socket_base::enable_connection_aborted enable_connection_aborted3(false);
615   BOOST_ASIO_CHECK(!enable_connection_aborted3.value());
616   BOOST_ASIO_CHECK(!static_cast<bool>(enable_connection_aborted3));
617   BOOST_ASIO_CHECK(!enable_connection_aborted3);
618   tcp_acceptor.set_option(enable_connection_aborted3, ec);
619   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
620 
621   socket_base::enable_connection_aborted enable_connection_aborted4;
622   tcp_acceptor.get_option(enable_connection_aborted4, ec);
623   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
624   BOOST_ASIO_CHECK(!enable_connection_aborted4.value());
625   BOOST_ASIO_CHECK(!static_cast<bool>(enable_connection_aborted4));
626   BOOST_ASIO_CHECK(!enable_connection_aborted4);
627 
628   // non_blocking_io class.
629 
630   socket_base::non_blocking_io non_blocking_io1(true);
631   tcp_sock.io_control(non_blocking_io1, ec);
632   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
633 
634   socket_base::non_blocking_io non_blocking_io2(false);
635   tcp_sock.io_control(non_blocking_io2, ec);
636   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
637 
638   // bytes_readable class.
639 
640   socket_base::bytes_readable bytes_readable;
641   udp_sock.io_control(bytes_readable, ec);
642   BOOST_ASIO_CHECK_MESSAGE(!ec, ec.value() << ", " << ec.message());
643 }
644 
645 } // namespace socket_base_runtime
646 
647 //------------------------------------------------------------------------------
648 
649 BOOST_ASIO_TEST_SUITE
650 (
651   "socket_base",
652   BOOST_ASIO_TEST_CASE(socket_base_compile::test)
653   BOOST_ASIO_TEST_CASE(socket_base_runtime::test)
654 )
655