1 //
2 // socket_base.hpp
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 #ifndef BOOST_ASIO_SOCKET_BASE_HPP
12 #define BOOST_ASIO_SOCKET_BASE_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/detail/io_control.hpp>
20 #include <boost/asio/detail/socket_option.hpp>
21 #include <boost/asio/detail/socket_types.hpp>
22 
23 #include <boost/asio/detail/push_options.hpp>
24 
25 namespace boost {
26 namespace asio {
27 
28 /// The socket_base class is used as a base for the basic_stream_socket and
29 /// basic_datagram_socket class templates so that we have a common place to
30 /// define the shutdown_type and enum.
31 class socket_base
32 {
33 public:
34   /// Different ways a socket may be shutdown.
35   enum shutdown_type
36   {
37 #if defined(GENERATING_DOCUMENTATION)
38     /// Shutdown the receive side of the socket.
39     shutdown_receive = implementation_defined,
40 
41     /// Shutdown the send side of the socket.
42     shutdown_send = implementation_defined,
43 
44     /// Shutdown both send and receive on the socket.
45     shutdown_both = implementation_defined
46 #else
47     shutdown_receive = BOOST_ASIO_OS_DEF(SHUT_RD),
48     shutdown_send = BOOST_ASIO_OS_DEF(SHUT_WR),
49     shutdown_both = BOOST_ASIO_OS_DEF(SHUT_RDWR)
50 #endif
51   };
52 
53   /// Bitmask type for flags that can be passed to send and receive operations.
54   typedef int message_flags;
55 
56 #if defined(GENERATING_DOCUMENTATION)
57   /// Peek at incoming data without removing it from the input queue.
58   static const int message_peek = implementation_defined;
59 
60   /// Process out-of-band data.
61   static const int message_out_of_band = implementation_defined;
62 
63   /// Specify that the data should not be subject to routing.
64   static const int message_do_not_route = implementation_defined;
65 
66   /// Specifies that the data marks the end of a record.
67   static const int message_end_of_record = implementation_defined;
68 #else
69   BOOST_ASIO_STATIC_CONSTANT(int,
70       message_peek = BOOST_ASIO_OS_DEF(MSG_PEEK));
71   BOOST_ASIO_STATIC_CONSTANT(int,
72       message_out_of_band = BOOST_ASIO_OS_DEF(MSG_OOB));
73   BOOST_ASIO_STATIC_CONSTANT(int,
74       message_do_not_route = BOOST_ASIO_OS_DEF(MSG_DONTROUTE));
75   BOOST_ASIO_STATIC_CONSTANT(int,
76       message_end_of_record = BOOST_ASIO_OS_DEF(MSG_EOR));
77 #endif
78 
79   /// Wait types.
80   /**
81    * For use with basic_socket::wait() and basic_socket::async_wait().
82    */
83   enum wait_type
84   {
85     /// Wait for a socket to become ready to read.
86     wait_read,
87 
88     /// Wait for a socket to become ready to write.
89     wait_write,
90 
91     /// Wait for a socket to have error conditions pending.
92     wait_error
93   };
94 
95   /// Socket option to permit sending of broadcast messages.
96   /**
97    * Implements the SOL_SOCKET/SO_BROADCAST socket option.
98    *
99    * @par Examples
100    * Setting the option:
101    * @code
102    * boost::asio::ip::udp::socket socket(my_context);
103    * ...
104    * boost::asio::socket_base::broadcast option(true);
105    * socket.set_option(option);
106    * @endcode
107    *
108    * @par
109    * Getting the current option value:
110    * @code
111    * boost::asio::ip::udp::socket socket(my_context);
112    * ...
113    * boost::asio::socket_base::broadcast option;
114    * socket.get_option(option);
115    * bool is_set = option.value();
116    * @endcode
117    *
118    * @par Concepts:
119    * Socket_Option, Boolean_Socket_Option.
120    */
121 #if defined(GENERATING_DOCUMENTATION)
122   typedef implementation_defined broadcast;
123 #else
124   typedef boost::asio::detail::socket_option::boolean<
125     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_BROADCAST)>
126       broadcast;
127 #endif
128 
129   /// Socket option to enable socket-level debugging.
130   /**
131    * Implements the SOL_SOCKET/SO_DEBUG socket option.
132    *
133    * @par Examples
134    * Setting the option:
135    * @code
136    * boost::asio::ip::tcp::socket socket(my_context);
137    * ...
138    * boost::asio::socket_base::debug option(true);
139    * socket.set_option(option);
140    * @endcode
141    *
142    * @par
143    * Getting the current option value:
144    * @code
145    * boost::asio::ip::tcp::socket socket(my_context);
146    * ...
147    * boost::asio::socket_base::debug option;
148    * socket.get_option(option);
149    * bool is_set = option.value();
150    * @endcode
151    *
152    * @par Concepts:
153    * Socket_Option, Boolean_Socket_Option.
154    */
155 #if defined(GENERATING_DOCUMENTATION)
156   typedef implementation_defined debug;
157 #else
158   typedef boost::asio::detail::socket_option::boolean<
159     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_DEBUG)> debug;
160 #endif
161 
162   /// Socket option to prevent routing, use local interfaces only.
163   /**
164    * Implements the SOL_SOCKET/SO_DONTROUTE socket option.
165    *
166    * @par Examples
167    * Setting the option:
168    * @code
169    * boost::asio::ip::udp::socket socket(my_context);
170    * ...
171    * boost::asio::socket_base::do_not_route option(true);
172    * socket.set_option(option);
173    * @endcode
174    *
175    * @par
176    * Getting the current option value:
177    * @code
178    * boost::asio::ip::udp::socket socket(my_context);
179    * ...
180    * boost::asio::socket_base::do_not_route option;
181    * socket.get_option(option);
182    * bool is_set = option.value();
183    * @endcode
184    *
185    * @par Concepts:
186    * Socket_Option, Boolean_Socket_Option.
187    */
188 #if defined(GENERATING_DOCUMENTATION)
189   typedef implementation_defined do_not_route;
190 #else
191   typedef boost::asio::detail::socket_option::boolean<
192     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_DONTROUTE)>
193       do_not_route;
194 #endif
195 
196   /// Socket option to send keep-alives.
197   /**
198    * Implements the SOL_SOCKET/SO_KEEPALIVE socket option.
199    *
200    * @par Examples
201    * Setting the option:
202    * @code
203    * boost::asio::ip::tcp::socket socket(my_context);
204    * ...
205    * boost::asio::socket_base::keep_alive option(true);
206    * socket.set_option(option);
207    * @endcode
208    *
209    * @par
210    * Getting the current option value:
211    * @code
212    * boost::asio::ip::tcp::socket socket(my_context);
213    * ...
214    * boost::asio::socket_base::keep_alive option;
215    * socket.get_option(option);
216    * bool is_set = option.value();
217    * @endcode
218    *
219    * @par Concepts:
220    * Socket_Option, Boolean_Socket_Option.
221    */
222 #if defined(GENERATING_DOCUMENTATION)
223   typedef implementation_defined keep_alive;
224 #else
225   typedef boost::asio::detail::socket_option::boolean<
226     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_KEEPALIVE)> keep_alive;
227 #endif
228 
229   /// Socket option for the send buffer size of a socket.
230   /**
231    * Implements the SOL_SOCKET/SO_SNDBUF socket option.
232    *
233    * @par Examples
234    * Setting the option:
235    * @code
236    * boost::asio::ip::tcp::socket socket(my_context);
237    * ...
238    * boost::asio::socket_base::send_buffer_size option(8192);
239    * socket.set_option(option);
240    * @endcode
241    *
242    * @par
243    * Getting the current option value:
244    * @code
245    * boost::asio::ip::tcp::socket socket(my_context);
246    * ...
247    * boost::asio::socket_base::send_buffer_size option;
248    * socket.get_option(option);
249    * int size = option.value();
250    * @endcode
251    *
252    * @par Concepts:
253    * Socket_Option, Integer_Socket_Option.
254    */
255 #if defined(GENERATING_DOCUMENTATION)
256   typedef implementation_defined send_buffer_size;
257 #else
258   typedef boost::asio::detail::socket_option::integer<
259     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_SNDBUF)>
260       send_buffer_size;
261 #endif
262 
263   /// Socket option for the send low watermark.
264   /**
265    * Implements the SOL_SOCKET/SO_SNDLOWAT socket option.
266    *
267    * @par Examples
268    * Setting the option:
269    * @code
270    * boost::asio::ip::tcp::socket socket(my_context);
271    * ...
272    * boost::asio::socket_base::send_low_watermark option(1024);
273    * socket.set_option(option);
274    * @endcode
275    *
276    * @par
277    * Getting the current option value:
278    * @code
279    * boost::asio::ip::tcp::socket socket(my_context);
280    * ...
281    * boost::asio::socket_base::send_low_watermark option;
282    * socket.get_option(option);
283    * int size = option.value();
284    * @endcode
285    *
286    * @par Concepts:
287    * Socket_Option, Integer_Socket_Option.
288    */
289 #if defined(GENERATING_DOCUMENTATION)
290   typedef implementation_defined send_low_watermark;
291 #else
292   typedef boost::asio::detail::socket_option::integer<
293     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_SNDLOWAT)>
294       send_low_watermark;
295 #endif
296 
297   /// Socket option for the receive buffer size of a socket.
298   /**
299    * Implements the SOL_SOCKET/SO_RCVBUF socket option.
300    *
301    * @par Examples
302    * Setting the option:
303    * @code
304    * boost::asio::ip::tcp::socket socket(my_context);
305    * ...
306    * boost::asio::socket_base::receive_buffer_size option(8192);
307    * socket.set_option(option);
308    * @endcode
309    *
310    * @par
311    * Getting the current option value:
312    * @code
313    * boost::asio::ip::tcp::socket socket(my_context);
314    * ...
315    * boost::asio::socket_base::receive_buffer_size option;
316    * socket.get_option(option);
317    * int size = option.value();
318    * @endcode
319    *
320    * @par Concepts:
321    * Socket_Option, Integer_Socket_Option.
322    */
323 #if defined(GENERATING_DOCUMENTATION)
324   typedef implementation_defined receive_buffer_size;
325 #else
326   typedef boost::asio::detail::socket_option::integer<
327     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_RCVBUF)>
328       receive_buffer_size;
329 #endif
330 
331   /// Socket option for the receive low watermark.
332   /**
333    * Implements the SOL_SOCKET/SO_RCVLOWAT socket option.
334    *
335    * @par Examples
336    * Setting the option:
337    * @code
338    * boost::asio::ip::tcp::socket socket(my_context);
339    * ...
340    * boost::asio::socket_base::receive_low_watermark option(1024);
341    * socket.set_option(option);
342    * @endcode
343    *
344    * @par
345    * Getting the current option value:
346    * @code
347    * boost::asio::ip::tcp::socket socket(my_context);
348    * ...
349    * boost::asio::socket_base::receive_low_watermark option;
350    * socket.get_option(option);
351    * int size = option.value();
352    * @endcode
353    *
354    * @par Concepts:
355    * Socket_Option, Integer_Socket_Option.
356    */
357 #if defined(GENERATING_DOCUMENTATION)
358   typedef implementation_defined receive_low_watermark;
359 #else
360   typedef boost::asio::detail::socket_option::integer<
361     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_RCVLOWAT)>
362       receive_low_watermark;
363 #endif
364 
365   /// Socket option to allow the socket to be bound to an address that is
366   /// already in use.
367   /**
368    * Implements the SOL_SOCKET/SO_REUSEADDR socket option.
369    *
370    * @par Examples
371    * Setting the option:
372    * @code
373    * boost::asio::ip::tcp::acceptor acceptor(my_context);
374    * ...
375    * boost::asio::socket_base::reuse_address option(true);
376    * acceptor.set_option(option);
377    * @endcode
378    *
379    * @par
380    * Getting the current option value:
381    * @code
382    * boost::asio::ip::tcp::acceptor acceptor(my_context);
383    * ...
384    * boost::asio::socket_base::reuse_address option;
385    * acceptor.get_option(option);
386    * bool is_set = option.value();
387    * @endcode
388    *
389    * @par Concepts:
390    * Socket_Option, Boolean_Socket_Option.
391    */
392 #if defined(GENERATING_DOCUMENTATION)
393   typedef implementation_defined reuse_address;
394 #else
395   typedef boost::asio::detail::socket_option::boolean<
396     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_REUSEADDR)>
397       reuse_address;
398 #endif
399 
400   /// Socket option to specify whether the socket lingers on close if unsent
401   /// data is present.
402   /**
403    * Implements the SOL_SOCKET/SO_LINGER socket option.
404    *
405    * @par Examples
406    * Setting the option:
407    * @code
408    * boost::asio::ip::tcp::socket socket(my_context);
409    * ...
410    * boost::asio::socket_base::linger option(true, 30);
411    * socket.set_option(option);
412    * @endcode
413    *
414    * @par
415    * Getting the current option value:
416    * @code
417    * boost::asio::ip::tcp::socket socket(my_context);
418    * ...
419    * boost::asio::socket_base::linger option;
420    * socket.get_option(option);
421    * bool is_set = option.enabled();
422    * unsigned short timeout = option.timeout();
423    * @endcode
424    *
425    * @par Concepts:
426    * Socket_Option, Linger_Socket_Option.
427    */
428 #if defined(GENERATING_DOCUMENTATION)
429   typedef implementation_defined linger;
430 #else
431   typedef boost::asio::detail::socket_option::linger<
432     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_LINGER)>
433       linger;
434 #endif
435 
436   /// Socket option for putting received out-of-band data inline.
437   /**
438    * Implements the SOL_SOCKET/SO_OOBINLINE socket option.
439    *
440    * @par Examples
441    * Setting the option:
442    * @code
443    * boost::asio::ip::tcp::socket socket(my_context);
444    * ...
445    * boost::asio::socket_base::out_of_band_inline option(true);
446    * socket.set_option(option);
447    * @endcode
448    *
449    * @par
450    * Getting the current option value:
451    * @code
452    * boost::asio::ip::tcp::socket socket(my_context);
453    * ...
454    * boost::asio::socket_base::out_of_band_inline option;
455    * socket.get_option(option);
456    * bool value = option.value();
457    * @endcode
458    *
459    * @par Concepts:
460    * Socket_Option, Boolean_Socket_Option.
461    */
462 #if defined(GENERATING_DOCUMENTATION)
463   typedef implementation_defined out_of_band_inline;
464 #else
465   typedef boost::asio::detail::socket_option::boolean<
466     BOOST_ASIO_OS_DEF(SOL_SOCKET), BOOST_ASIO_OS_DEF(SO_OOBINLINE)>
467       out_of_band_inline;
468 #endif
469 
470   /// Socket option to report aborted connections on accept.
471   /**
472    * Implements a custom socket option that determines whether or not an accept
473    * operation is permitted to fail with boost::asio::error::connection_aborted.
474    * By default the option is false.
475    *
476    * @par Examples
477    * Setting the option:
478    * @code
479    * boost::asio::ip::tcp::acceptor acceptor(my_context);
480    * ...
481    * boost::asio::socket_base::enable_connection_aborted option(true);
482    * acceptor.set_option(option);
483    * @endcode
484    *
485    * @par
486    * Getting the current option value:
487    * @code
488    * boost::asio::ip::tcp::acceptor acceptor(my_context);
489    * ...
490    * boost::asio::socket_base::enable_connection_aborted option;
491    * acceptor.get_option(option);
492    * bool is_set = option.value();
493    * @endcode
494    *
495    * @par Concepts:
496    * Socket_Option, Boolean_Socket_Option.
497    */
498 #if defined(GENERATING_DOCUMENTATION)
499   typedef implementation_defined enable_connection_aborted;
500 #else
501   typedef boost::asio::detail::socket_option::boolean<
502     boost::asio::detail::custom_socket_option_level,
503     boost::asio::detail::enable_connection_aborted_option>
504     enable_connection_aborted;
505 #endif
506 
507   /// IO control command to get the amount of data that can be read without
508   /// blocking.
509   /**
510    * Implements the FIONREAD IO control command.
511    *
512    * @par Example
513    * @code
514    * boost::asio::ip::tcp::socket socket(my_context);
515    * ...
516    * boost::asio::socket_base::bytes_readable command(true);
517    * socket.io_control(command);
518    * std::size_t bytes_readable = command.get();
519    * @endcode
520    *
521    * @par Concepts:
522    * IO_Control_Command, Size_IO_Control_Command.
523    */
524 #if defined(GENERATING_DOCUMENTATION)
525   typedef implementation_defined bytes_readable;
526 #else
527   typedef boost::asio::detail::io_control::bytes_readable bytes_readable;
528 #endif
529 
530   /// The maximum length of the queue of pending incoming connections.
531 #if defined(GENERATING_DOCUMENTATION)
532   static const int max_listen_connections = implementation_defined;
533 #else
534   BOOST_ASIO_STATIC_CONSTANT(int, max_listen_connections
535       = BOOST_ASIO_OS_DEF(SOMAXCONN));
536 #endif
537 
538 #if !defined(BOOST_ASIO_NO_DEPRECATED)
539   /// (Deprecated: Use max_listen_connections.) The maximum length of the queue
540   /// of pending incoming connections.
541 #if defined(GENERATING_DOCUMENTATION)
542   static const int max_connections = implementation_defined;
543 #else
544   BOOST_ASIO_STATIC_CONSTANT(int, max_connections
545       = BOOST_ASIO_OS_DEF(SOMAXCONN));
546 #endif
547 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
548 
549 protected:
550   /// Protected destructor to prevent deletion through this type.
~socket_base()551   ~socket_base()
552   {
553   }
554 };
555 
556 } // namespace asio
557 } // namespace boost
558 
559 #include <boost/asio/detail/pop_options.hpp>
560 
561 #endif // BOOST_ASIO_SOCKET_BASE_HPP
562