LCOV - code coverage report
Current view: top level - corosio - socket_option.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 95.9 % 74 71 3
Test Date: 2026-08-21 20:48:07 Functions: 100.0 % 36 36

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Steve Gerbino
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/cppalliance/corosio
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_COROSIO_SOCKET_OPTION_HPP
      11                 : #define BOOST_COROSIO_SOCKET_OPTION_HPP
      12                 : 
      13                 : #include <boost/corosio/detail/config.hpp>
      14                 : #include <boost/corosio/ipv4_address.hpp>
      15                 : #include <boost/corosio/ipv6_address.hpp>
      16                 : 
      17                 : #include <cstddef>
      18                 : 
      19                 : /** @file socket_option.hpp
      20                 : 
      21                 :     Type-erased socket option types that avoid platform-specific
      22                 :     headers. The protocol level and option name for each type are
      23                 :     resolved at link time via the compiled library.
      24                 : 
      25                 :     For an inline (zero-overhead) alternative that includes platform
      26                 :     headers, use `<boost/corosio/native/native_socket_option.hpp>`
      27                 :     (`boost::corosio::native_socket_option`).
      28                 : 
      29                 :     Both variants satisfy the same option-type interface and work
      30                 :     interchangeably with `tcp_socket::set_option` /
      31                 :     `tcp_socket::get_option` and the corresponding acceptor methods.
      32                 : 
      33                 :     @see native_socket_option
      34                 : */
      35                 : 
      36                 : namespace boost::corosio::socket_option {
      37                 : 
      38                 : /** Base class for concrete boolean socket options.
      39                 : 
      40                 :     Stores a boolean as an `int` suitable for `setsockopt`/`getsockopt`.
      41                 :     Derived types provide `level()` and `name()` for the specific option.
      42                 : */
      43                 : class BOOST_COROSIO_DECL boolean_option
      44                 : {
      45                 :     int value_ = 0;
      46                 : 
      47                 : public:
      48                 :     /// Construct with default value (disabled).
      49                 :     boolean_option() = default;
      50                 : 
      51                 :     /** Construct with an explicit value.
      52                 : 
      53                 :         @param v `true` to enable the option, `false` to disable.
      54                 :     */
      55 HIT         469 :     explicit boolean_option(bool v) noexcept : value_(v ? 1 : 0) {}
      56                 : 
      57                 :     /// Assign a new value.
      58               4 :     boolean_option& operator=(bool v) noexcept
      59                 :     {
      60               4 :         value_ = v ? 1 : 0;
      61               4 :         return *this;
      62                 :     }
      63                 : 
      64                 :     /// Return the option value.
      65              62 :     bool value() const noexcept
      66                 :     {
      67              62 :         return value_ != 0;
      68                 :     }
      69                 : 
      70                 :     /// Return the option value.
      71               4 :     explicit operator bool() const noexcept
      72                 :     {
      73               4 :         return value_ != 0;
      74                 :     }
      75                 : 
      76                 :     /// Return the negated option value.
      77               4 :     bool operator!() const noexcept
      78                 :     {
      79               4 :         return value_ == 0;
      80                 :     }
      81                 : 
      82                 :     /// Return a pointer to the underlying storage.
      83              78 :     void* data() noexcept
      84                 :     {
      85              78 :         return &value_;
      86                 :     }
      87                 : 
      88                 :     /// Return a pointer to the underlying storage.
      89             463 :     void const* data() const noexcept
      90                 :     {
      91             463 :         return &value_;
      92                 :     }
      93                 : 
      94                 :     /// Return the size of the underlying storage.
      95             541 :     std::size_t size() const noexcept
      96                 :     {
      97             541 :         return sizeof(value_);
      98                 :     }
      99                 : 
     100                 :     /** Normalize after `getsockopt` returns fewer bytes than expected.
     101                 : 
     102                 :         Windows Vista+ may write only 1 byte for boolean options.
     103                 : 
     104                 :         @param s The number of bytes actually written by `getsockopt`.
     105                 :     */
     106              66 :     void resize(std::size_t s) noexcept
     107                 :     {
     108              66 :         if (s == sizeof(char))
     109 MIS           0 :             value_ = *reinterpret_cast<unsigned char*>(&value_) ? 1 : 0;
     110 HIT          66 :     }
     111                 : };
     112                 : 
     113                 : /** Base class for concrete integer socket options.
     114                 : 
     115                 :     Stores an integer suitable for `setsockopt`/`getsockopt`.
     116                 :     Derived types provide `level()` and `name()` for the specific option.
     117                 : */
     118                 : class BOOST_COROSIO_DECL integer_option
     119                 : {
     120                 :     int value_ = 0;
     121                 : 
     122                 : public:
     123                 :     /// Construct with default value (zero).
     124                 :     integer_option() = default;
     125                 : 
     126                 :     /** Construct with an explicit value.
     127                 : 
     128                 :         @param v The option value.
     129                 :     */
     130              65 :     explicit integer_option(int v) noexcept : value_(v) {}
     131                 : 
     132                 :     /// Assign a new value.
     133               2 :     integer_option& operator=(int v) noexcept
     134                 :     {
     135               2 :         value_ = v;
     136               2 :         return *this;
     137                 :     }
     138                 : 
     139                 :     /// Return the option value.
     140              46 :     int value() const noexcept
     141                 :     {
     142              46 :         return value_;
     143                 :     }
     144                 : 
     145                 :     /// Return a pointer to the underlying storage.
     146              44 :     void* data() noexcept
     147                 :     {
     148              44 :         return &value_;
     149                 :     }
     150                 : 
     151                 :     /// Return a pointer to the underlying storage.
     152              61 :     void const* data() const noexcept
     153                 :     {
     154              61 :         return &value_;
     155                 :     }
     156                 : 
     157                 :     /// Return the size of the underlying storage.
     158             105 :     std::size_t size() const noexcept
     159                 :     {
     160             105 :         return sizeof(value_);
     161                 :     }
     162                 : 
     163                 :     /** Normalize after `getsockopt` returns fewer bytes than expected.
     164                 : 
     165                 :         @param s The number of bytes actually written by `getsockopt`.
     166                 :     */
     167              44 :     void resize(std::size_t s) noexcept
     168                 :     {
     169              44 :         if (s == sizeof(char))
     170 MIS           0 :             value_ =
     171               0 :                 static_cast<int>(*reinterpret_cast<unsigned char*>(&value_));
     172 HIT          44 :     }
     173                 : };
     174                 : 
     175                 : /** Base class for concrete boolean socket options with single-byte storage.
     176                 : 
     177                 :     Some BSD-derived kernels (macOS, FreeBSD) require certain IPv4 multicast
     178                 :     options (`IP_MULTICAST_LOOP`) to be set with a one-byte value and return
     179                 :     `EINVAL` for the four-byte form that Linux accepts. This base provides
     180                 :     `unsigned char` storage so the same options work on every platform.
     181                 : */
     182                 : class BOOST_COROSIO_DECL byte_boolean_option
     183                 : {
     184                 :     unsigned char value_ = 0;
     185                 : 
     186                 : public:
     187                 :     /// Construct with default value (disabled).
     188                 :     byte_boolean_option() = default;
     189                 : 
     190                 :     /** Construct with an explicit value.
     191                 : 
     192                 :         @param v `true` to enable the option, `false` to disable.
     193                 :     */
     194              10 :     explicit byte_boolean_option(bool v) noexcept : value_(v ? 1 : 0) {}
     195                 : 
     196                 :     /// Assign a new value.
     197                 :     byte_boolean_option& operator=(bool v) noexcept
     198                 :     {
     199                 :         value_ = v ? 1 : 0;
     200                 :         return *this;
     201                 :     }
     202                 : 
     203                 :     /// Return the option value.
     204               8 :     bool value() const noexcept
     205                 :     {
     206               8 :         return value_ != 0;
     207                 :     }
     208                 : 
     209                 :     /// Return the option value.
     210                 :     explicit operator bool() const noexcept
     211                 :     {
     212                 :         return value_ != 0;
     213                 :     }
     214                 : 
     215                 :     /// Return the negated option value.
     216                 :     bool operator!() const noexcept
     217                 :     {
     218                 :         return value_ == 0;
     219                 :     }
     220                 : 
     221                 :     /// Return a pointer to the underlying storage.
     222               8 :     void* data() noexcept
     223                 :     {
     224               8 :         return &value_;
     225                 :     }
     226                 : 
     227                 :     /// Return a pointer to the underlying storage.
     228              10 :     void const* data() const noexcept
     229                 :     {
     230              10 :         return &value_;
     231                 :     }
     232                 : 
     233                 :     /// Return the size of the underlying storage.
     234              18 :     std::size_t size() const noexcept
     235                 :     {
     236              18 :         return sizeof(value_);
     237                 :     }
     238                 : 
     239                 :     /// Storage is already one byte; no normalization needed.
     240               8 :     void resize(std::size_t) noexcept {}
     241                 : };
     242                 : 
     243                 : /** Base class for concrete integer socket options with single-byte storage.
     244                 : 
     245                 :     Same rationale as `byte_boolean_option`: BSD-derived kernels require
     246                 :     `IP_MULTICAST_TTL` to be set with a one-byte value. Linux accepts
     247                 :     one-byte too, so single-byte storage is portable.
     248                 : */
     249                 : class BOOST_COROSIO_DECL byte_integer_option
     250                 : {
     251                 :     unsigned char value_ = 0;
     252                 : 
     253                 : public:
     254                 :     /// Construct with default value (zero).
     255                 :     byte_integer_option() = default;
     256                 : 
     257                 :     /** Construct with an explicit value.
     258                 : 
     259                 :         @param v The option value; truncated to one byte.
     260                 :     */
     261               4 :     explicit byte_integer_option(int v) noexcept
     262               4 :         : value_(static_cast<unsigned char>(v))
     263               4 :     {}
     264                 : 
     265                 :     /// Assign a new value; truncated to one byte.
     266                 :     byte_integer_option& operator=(int v) noexcept
     267                 :     {
     268                 :         value_ = static_cast<unsigned char>(v);
     269                 :         return *this;
     270                 :     }
     271                 : 
     272                 :     /// Return the option value.
     273               4 :     int value() const noexcept
     274                 :     {
     275               4 :         return value_;
     276                 :     }
     277                 : 
     278                 :     /// Return a pointer to the underlying storage.
     279               4 :     void* data() noexcept
     280                 :     {
     281               4 :         return &value_;
     282                 :     }
     283                 : 
     284                 :     /// Return a pointer to the underlying storage.
     285               4 :     void const* data() const noexcept
     286                 :     {
     287               4 :         return &value_;
     288                 :     }
     289                 : 
     290                 :     /// Return the size of the underlying storage.
     291               8 :     std::size_t size() const noexcept
     292                 :     {
     293               8 :         return sizeof(value_);
     294                 :     }
     295                 : 
     296                 :     /// Storage is already one byte; no normalization needed.
     297               4 :     void resize(std::size_t) noexcept {}
     298                 : };
     299                 : 
     300                 : /** Disable Nagle's algorithm (TCP_NODELAY).
     301                 : 
     302                 :     @par Example
     303                 :     @code
     304                 :     sock.set_option( socket_option::no_delay( true ) );
     305                 :     auto nd = sock.get_option<socket_option::no_delay>();
     306                 :     bool disabled = nd.value();  // true: Nagle's algorithm is off
     307                 :     @endcode
     308                 : */
     309                 : class BOOST_COROSIO_DECL no_delay : public boolean_option
     310                 : {
     311                 : public:
     312                 :     using boolean_option::boolean_option;
     313                 :     using boolean_option::operator=;
     314                 : 
     315                 :     /// Return the protocol level.
     316                 :     static int level() noexcept;
     317                 : 
     318                 :     /// Return the option name.
     319                 :     static int name() noexcept;
     320                 : };
     321                 : 
     322                 : /** Enable periodic keepalive probes (SO_KEEPALIVE).
     323                 : 
     324                 :     @par Example
     325                 :     @code
     326                 :     sock.set_option( socket_option::keep_alive( true ) );
     327                 :     @endcode
     328                 : */
     329                 : class BOOST_COROSIO_DECL keep_alive : public boolean_option
     330                 : {
     331                 : public:
     332                 :     using boolean_option::boolean_option;
     333                 :     using boolean_option::operator=;
     334                 : 
     335                 :     /// Return the protocol level.
     336                 :     static int level() noexcept;
     337                 : 
     338                 :     /// Return the option name.
     339                 :     static int name() noexcept;
     340                 : };
     341                 : 
     342                 : /** Restrict an IPv6 socket to IPv6 only (IPV6_V6ONLY).
     343                 : 
     344                 :     When enabled, the socket only accepts IPv6 connections.
     345                 :     When disabled, the socket accepts both IPv4 and IPv6
     346                 :     connections (dual-stack mode).
     347                 : 
     348                 :     @par Example
     349                 :     @code
     350                 :     sock.set_option( socket_option::v6_only( true ) );
     351                 :     @endcode
     352                 : */
     353                 : class BOOST_COROSIO_DECL v6_only : public boolean_option
     354                 : {
     355                 : public:
     356                 :     using boolean_option::boolean_option;
     357                 :     using boolean_option::operator=;
     358                 : 
     359                 :     /// Return the protocol level.
     360                 :     static int level() noexcept;
     361                 : 
     362                 :     /// Return the option name.
     363                 :     static int name() noexcept;
     364                 : };
     365                 : 
     366                 : /** Allow local address reuse (SO_REUSEADDR).
     367                 : 
     368                 :     @par Example
     369                 :     @code
     370                 :     acc.set_option( socket_option::reuse_address( true ) );
     371                 :     @endcode
     372                 : */
     373                 : class BOOST_COROSIO_DECL reuse_address : public boolean_option
     374                 : {
     375                 : public:
     376                 :     using boolean_option::boolean_option;
     377                 :     using boolean_option::operator=;
     378                 : 
     379                 :     /// Return the protocol level.
     380                 :     static int level() noexcept;
     381                 : 
     382                 :     /// Return the option name.
     383                 :     static int name() noexcept;
     384                 : };
     385                 : 
     386                 : /** Allow sending to broadcast addresses (SO_BROADCAST).
     387                 : 
     388                 :     Required for UDP sockets that send to broadcast addresses
     389                 :     such as 255.255.255.255. Without this option, `send_to`
     390                 :     returns an error.
     391                 : 
     392                 :     @par Example
     393                 :     @code
     394                 :     udp_socket sock( ioc );
     395                 :     if ( auto ec = sock.open() )
     396                 :         return;
     397                 :     sock.set_option( socket_option::broadcast( true ) );
     398                 :     @endcode
     399                 : */
     400                 : class BOOST_COROSIO_DECL broadcast : public boolean_option
     401                 : {
     402                 : public:
     403                 :     using boolean_option::boolean_option;
     404                 :     using boolean_option::operator=;
     405                 : 
     406                 :     /// Return the protocol level.
     407                 :     static int level() noexcept;
     408                 : 
     409                 :     /// Return the option name.
     410                 :     static int name() noexcept;
     411                 : };
     412                 : 
     413                 : /** Allow multiple sockets to bind to the same port (SO_REUSEPORT).
     414                 : 
     415                 :     Not available on all platforms. On unsupported platforms,
     416                 :     `set_option` throws `std::system_error`.
     417                 : 
     418                 :     @par Example
     419                 :     @code
     420                 :     if ( auto ec = acc.open( tcp::v6() ) )
     421                 :         return;
     422                 :     acc.set_option( socket_option::reuse_port( true ) );
     423                 :     if ( auto ec = acc.bind( endpoint( ipv6_address::any(), 8080 ) ) )
     424                 :         return;
     425                 :     if ( auto ec = acc.listen() )
     426                 :         return;
     427                 :     @endcode
     428                 : */
     429                 : class BOOST_COROSIO_DECL reuse_port : public boolean_option
     430                 : {
     431                 : public:
     432                 :     using boolean_option::boolean_option;
     433                 :     using boolean_option::operator=;
     434                 : 
     435                 :     /// Return the protocol level.
     436                 :     static int level() noexcept;
     437                 : 
     438                 :     /// Return the option name.
     439                 :     static int name() noexcept;
     440                 : };
     441                 : 
     442                 : /** Set the receive buffer size (SO_RCVBUF).
     443                 : 
     444                 :     @par Example
     445                 :     @code
     446                 :     sock.set_option( socket_option::receive_buffer_size( 65536 ) );
     447                 :     auto opt = sock.get_option<socket_option::receive_buffer_size>();
     448                 :     int sz = opt.value();
     449                 :     @endcode
     450                 : */
     451                 : class BOOST_COROSIO_DECL receive_buffer_size : public integer_option
     452                 : {
     453                 : public:
     454                 :     using integer_option::integer_option;
     455                 :     using integer_option::operator=;
     456                 : 
     457                 :     /// Return the protocol level.
     458                 :     static int level() noexcept;
     459                 : 
     460                 :     /// Return the option name.
     461                 :     static int name() noexcept;
     462                 : };
     463                 : 
     464                 : /** Set the send buffer size (SO_SNDBUF).
     465                 : 
     466                 :     @par Example
     467                 :     @code
     468                 :     sock.set_option( socket_option::send_buffer_size( 65536 ) );
     469                 :     @endcode
     470                 : */
     471                 : class BOOST_COROSIO_DECL send_buffer_size : public integer_option
     472                 : {
     473                 : public:
     474                 :     using integer_option::integer_option;
     475                 :     using integer_option::operator=;
     476                 : 
     477                 :     /// Return the protocol level.
     478                 :     static int level() noexcept;
     479                 : 
     480                 :     /// Return the option name.
     481                 :     static int name() noexcept;
     482                 : };
     483                 : 
     484                 : /** The SO_LINGER socket option.
     485                 : 
     486                 :     Controls behavior when closing a socket with unsent data.
     487                 :     When enabled, `close()` blocks until pending data is sent
     488                 :     or the timeout expires.
     489                 : 
     490                 :     @par Example
     491                 :     @code
     492                 :     sock.set_option( socket_option::linger( true, 5 ) );
     493                 :     auto opt = sock.get_option<socket_option::linger>();
     494                 :     if ( opt.enabled() )
     495                 :         std::cout << "linger timeout: " << opt.timeout() << "s\n";
     496                 :     @endcode
     497                 : */
     498                 : class BOOST_COROSIO_DECL linger
     499                 : {
     500                 :     // Opaque storage for the platform's struct linger.
     501                 :     // POSIX: { int, int } = 8 bytes.
     502                 :     // Windows: { u_short, u_short } = 4 bytes.
     503                 :     static constexpr std::size_t max_storage_ = 8;
     504                 :     alignas(4) unsigned char storage_[max_storage_]{};
     505                 : 
     506                 : public:
     507                 :     /// Construct with default values (disabled, zero timeout).
     508                 :     linger() noexcept = default;
     509                 : 
     510                 :     /** Construct with explicit values.
     511                 : 
     512                 :         @param enabled `true` to enable linger behavior on close.
     513                 :         @param timeout The linger timeout in seconds.
     514                 :     */
     515                 :     linger(bool enabled, int timeout) noexcept;
     516                 : 
     517                 :     /// Return whether linger is enabled.
     518                 :     bool enabled() const noexcept;
     519                 : 
     520                 :     /// Set whether linger is enabled.
     521                 :     void enabled(bool v) noexcept;
     522                 : 
     523                 :     /// Return the linger timeout in seconds.
     524                 :     int timeout() const noexcept;
     525                 : 
     526                 :     /// Set the linger timeout in seconds.
     527                 :     void timeout(int v) noexcept;
     528                 : 
     529                 :     /// Return the protocol level.
     530                 :     static int level() noexcept;
     531                 : 
     532                 :     /// Return the option name.
     533                 :     static int name() noexcept;
     534                 : 
     535                 :     /// Return a pointer to the underlying storage.
     536              12 :     void* data() noexcept
     537                 :     {
     538              12 :         return storage_;
     539                 :     }
     540                 : 
     541                 :     /// Return a pointer to the underlying storage.
     542             152 :     void const* data() const noexcept
     543                 :     {
     544             152 :         return storage_;
     545                 :     }
     546                 : 
     547                 :     /// Return the size of the underlying storage.
     548                 :     std::size_t size() const noexcept;
     549                 : 
     550                 :     /** Normalize after `getsockopt`.
     551                 : 
     552                 :         No-op — `struct linger` is always returned at full size.
     553                 : 
     554                 :         @param s The number of bytes actually written by `getsockopt`.
     555                 :     */
     556              12 :     void resize(std::size_t) noexcept {}
     557                 : };
     558                 : 
     559                 : /** Enable loopback of outgoing multicast on IPv4 (IP_MULTICAST_LOOP).
     560                 : 
     561                 :     Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
     562                 :     reject the four-byte form with `EINVAL`. Linux accepts either size.
     563                 : 
     564                 :     @par Example
     565                 :     @code
     566                 :     sock.set_option( socket_option::multicast_loop_v4( true ) );
     567                 :     @endcode
     568                 : */
     569                 : class BOOST_COROSIO_DECL multicast_loop_v4 : public byte_boolean_option
     570                 : {
     571                 : public:
     572                 :     using byte_boolean_option::byte_boolean_option;
     573                 :     using byte_boolean_option::operator=;
     574                 : 
     575                 :     /// Return the protocol level.
     576                 :     static int level() noexcept;
     577                 : 
     578                 :     /// Return the option name.
     579                 :     static int name() noexcept;
     580                 : };
     581                 : 
     582                 : /** Enable loopback of outgoing multicast on IPv6 (IPV6_MULTICAST_LOOP).
     583                 : 
     584                 :     @par Example
     585                 :     @code
     586                 :     sock.set_option( socket_option::multicast_loop_v6( true ) );
     587                 :     @endcode
     588                 : */
     589                 : class BOOST_COROSIO_DECL multicast_loop_v6 : public boolean_option
     590                 : {
     591                 : public:
     592                 :     using boolean_option::boolean_option;
     593                 :     using boolean_option::operator=;
     594                 : 
     595                 :     /// Return the protocol level.
     596                 :     static int level() noexcept;
     597                 : 
     598                 :     /// Return the option name.
     599                 :     static int name() noexcept;
     600                 : };
     601                 : 
     602                 : /** Set the multicast TTL for IPv4 (IP_MULTICAST_TTL).
     603                 : 
     604                 :     Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
     605                 :     reject the four-byte form with `EINVAL`. Linux accepts either size.
     606                 :     Values are truncated to the 0–255 range.
     607                 : 
     608                 :     @par Example
     609                 :     @code
     610                 :     sock.set_option( socket_option::multicast_hops_v4( 4 ) );
     611                 :     @endcode
     612                 : */
     613                 : class BOOST_COROSIO_DECL multicast_hops_v4 : public byte_integer_option
     614                 : {
     615                 : public:
     616                 :     using byte_integer_option::byte_integer_option;
     617                 :     using byte_integer_option::operator=;
     618                 : 
     619                 :     /// Return the protocol level.
     620                 :     static int level() noexcept;
     621                 : 
     622                 :     /// Return the option name.
     623                 :     static int name() noexcept;
     624                 : };
     625                 : 
     626                 : /** Set the multicast hop limit for IPv6 (IPV6_MULTICAST_HOPS).
     627                 : 
     628                 :     @par Example
     629                 :     @code
     630                 :     sock.set_option( socket_option::multicast_hops_v6( 4 ) );
     631                 :     @endcode
     632                 : */
     633                 : class BOOST_COROSIO_DECL multicast_hops_v6 : public integer_option
     634                 : {
     635                 : public:
     636                 :     using integer_option::integer_option;
     637                 :     using integer_option::operator=;
     638                 : 
     639                 :     /// Return the protocol level.
     640                 :     static int level() noexcept;
     641                 : 
     642                 :     /// Return the option name.
     643                 :     static int name() noexcept;
     644                 : };
     645                 : 
     646                 : /** Set the outgoing interface for IPv6 multicast (IPV6_MULTICAST_IF).
     647                 : 
     648                 :     @par Example
     649                 :     @code
     650                 :     sock.set_option( socket_option::multicast_interface_v6( 1 ) );
     651                 :     @endcode
     652                 : */
     653                 : class BOOST_COROSIO_DECL multicast_interface_v6 : public integer_option
     654                 : {
     655                 : public:
     656                 :     using integer_option::integer_option;
     657                 :     using integer_option::operator=;
     658                 : 
     659                 :     /// Return the protocol level.
     660                 :     static int level() noexcept;
     661                 : 
     662                 :     /// Return the option name.
     663                 :     static int name() noexcept;
     664                 : };
     665                 : 
     666                 : /** Join an IPv4 multicast group (IP_ADD_MEMBERSHIP).
     667                 : 
     668                 :     @par Example
     669                 :     @code
     670                 :     sock.set_option( socket_option::join_group_v4(
     671                 :         ipv4_address( "239.255.0.1" ) ) );
     672                 :     @endcode
     673                 : */
     674                 : class BOOST_COROSIO_DECL join_group_v4
     675                 : {
     676                 :     static constexpr std::size_t max_storage_ = 8;
     677                 :     alignas(4) unsigned char storage_[max_storage_]{};
     678                 : 
     679                 : public:
     680                 :     /// Construct with default values.
     681                 :     join_group_v4() noexcept = default;
     682                 : 
     683                 :     /** Construct with a group and optional interface address.
     684                 : 
     685                 :         @param group The multicast group address to join.
     686                 :         @param iface The local interface to use (default: any).
     687                 :     */
     688                 :     join_group_v4(
     689                 :         ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
     690                 : 
     691                 :     /// Return the protocol level.
     692                 :     static int level() noexcept;
     693                 : 
     694                 :     /// Return the option name.
     695                 :     static int name() noexcept;
     696                 : 
     697                 :     /// Return a pointer to the underlying storage.
     698                 :     void* data() noexcept
     699                 :     {
     700                 :         return storage_;
     701                 :     }
     702                 : 
     703                 :     /// Return a pointer to the underlying storage.
     704               4 :     void const* data() const noexcept
     705                 :     {
     706               4 :         return storage_;
     707                 :     }
     708                 : 
     709                 :     /// Return the size of the underlying storage.
     710                 :     std::size_t size() const noexcept;
     711                 : 
     712                 :     /// No-op resize.
     713                 :     void resize(std::size_t) noexcept {}
     714                 : };
     715                 : 
     716                 : /** Leave an IPv4 multicast group (IP_DROP_MEMBERSHIP).
     717                 : 
     718                 :     @par Example
     719                 :     @code
     720                 :     sock.set_option( socket_option::leave_group_v4(
     721                 :         ipv4_address( "239.255.0.1" ) ) );
     722                 :     @endcode
     723                 : */
     724                 : class BOOST_COROSIO_DECL leave_group_v4
     725                 : {
     726                 :     static constexpr std::size_t max_storage_ = 8;
     727                 :     alignas(4) unsigned char storage_[max_storage_]{};
     728                 : 
     729                 : public:
     730                 :     /// Construct with default values.
     731                 :     leave_group_v4() noexcept = default;
     732                 : 
     733                 :     /** Construct with a group and optional interface address.
     734                 : 
     735                 :         @param group The multicast group address to leave.
     736                 :         @param iface The local interface (default: any).
     737                 :     */
     738                 :     leave_group_v4(
     739                 :         ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
     740                 : 
     741                 :     /// Return the protocol level.
     742                 :     static int level() noexcept;
     743                 : 
     744                 :     /// Return the option name.
     745                 :     static int name() noexcept;
     746                 : 
     747                 :     /// Return a pointer to the underlying storage.
     748                 :     void* data() noexcept
     749                 :     {
     750                 :         return storage_;
     751                 :     }
     752                 : 
     753                 :     /// Return a pointer to the underlying storage.
     754               2 :     void const* data() const noexcept
     755                 :     {
     756               2 :         return storage_;
     757                 :     }
     758                 : 
     759                 :     /// Return the size of the underlying storage.
     760                 :     std::size_t size() const noexcept;
     761                 : 
     762                 :     /// No-op resize.
     763                 :     void resize(std::size_t) noexcept {}
     764                 : };
     765                 : 
     766                 : /** Join an IPv6 multicast group (IPV6_JOIN_GROUP).
     767                 : 
     768                 :     @par Example
     769                 :     @code
     770                 :     sock.set_option( socket_option::join_group_v6(
     771                 :         ipv6_address( "ff02::1" ), 0 ) );
     772                 :     @endcode
     773                 : */
     774                 : class BOOST_COROSIO_DECL join_group_v6
     775                 : {
     776                 :     static constexpr std::size_t max_storage_ = 20;
     777                 :     alignas(4) unsigned char storage_[max_storage_]{};
     778                 : 
     779                 : public:
     780                 :     /// Construct with default values.
     781                 :     join_group_v6() noexcept = default;
     782                 : 
     783                 :     /** Construct with a group and optional interface index.
     784                 : 
     785                 :         @param group The multicast group address to join.
     786                 :         @param if_index The interface index (0 = kernel chooses).
     787                 :     */
     788                 :     join_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
     789                 : 
     790                 :     /// Return the protocol level.
     791                 :     static int level() noexcept;
     792                 : 
     793                 :     /// Return the option name.
     794                 :     static int name() noexcept;
     795                 : 
     796                 :     /// Return a pointer to the underlying storage.
     797                 :     void* data() noexcept
     798                 :     {
     799                 :         return storage_;
     800                 :     }
     801                 : 
     802                 :     /// Return a pointer to the underlying storage.
     803               2 :     void const* data() const noexcept
     804                 :     {
     805               2 :         return storage_;
     806                 :     }
     807                 : 
     808                 :     /// Return the size of the underlying storage.
     809                 :     std::size_t size() const noexcept;
     810                 : 
     811                 :     /// No-op resize.
     812                 :     void resize(std::size_t) noexcept {}
     813                 : };
     814                 : 
     815                 : /** Leave an IPv6 multicast group (IPV6_LEAVE_GROUP).
     816                 : 
     817                 :     @par Example
     818                 :     @code
     819                 :     sock.set_option( socket_option::leave_group_v6(
     820                 :         ipv6_address( "ff02::1" ), 0 ) );
     821                 :     @endcode
     822                 : */
     823                 : class BOOST_COROSIO_DECL leave_group_v6
     824                 : {
     825                 :     static constexpr std::size_t max_storage_ = 20;
     826                 :     alignas(4) unsigned char storage_[max_storage_]{};
     827                 : 
     828                 : public:
     829                 :     /// Construct with default values.
     830                 :     leave_group_v6() noexcept = default;
     831                 : 
     832                 :     /** Construct with a group and optional interface index.
     833                 : 
     834                 :         @param group The multicast group address to leave.
     835                 :         @param if_index The interface index (0 = kernel chooses).
     836                 :     */
     837                 :     leave_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
     838                 : 
     839                 :     /// Return the protocol level.
     840                 :     static int level() noexcept;
     841                 : 
     842                 :     /// Return the option name.
     843                 :     static int name() noexcept;
     844                 : 
     845                 :     /// Return a pointer to the underlying storage.
     846                 :     void* data() noexcept
     847                 :     {
     848                 :         return storage_;
     849                 :     }
     850                 : 
     851                 :     /// Return a pointer to the underlying storage.
     852               2 :     void const* data() const noexcept
     853                 :     {
     854               2 :         return storage_;
     855                 :     }
     856                 : 
     857                 :     /// Return the size of the underlying storage.
     858                 :     std::size_t size() const noexcept;
     859                 : 
     860                 :     /// No-op resize.
     861                 :     void resize(std::size_t) noexcept {}
     862                 : };
     863                 : 
     864                 : /** Set the outgoing interface for IPv4 multicast (IP_MULTICAST_IF).
     865                 : 
     866                 :     Unlike the integer-based `multicast_interface_v6`, this option
     867                 :     takes an `ipv4_address` identifying the local interface.
     868                 : 
     869                 :     @par Example
     870                 :     @code
     871                 :     sock.set_option( socket_option::multicast_interface_v4(
     872                 :         ipv4_address( "192.168.1.1" ) ) );
     873                 :     @endcode
     874                 : */
     875                 : class BOOST_COROSIO_DECL multicast_interface_v4
     876                 : {
     877                 :     static constexpr std::size_t max_storage_ = 4;
     878                 :     alignas(4) unsigned char storage_[max_storage_]{};
     879                 : 
     880                 : public:
     881                 :     /// Construct with default values (INADDR_ANY).
     882                 :     multicast_interface_v4() noexcept = default;
     883                 : 
     884                 :     /** Construct with an interface address.
     885                 : 
     886                 :         @param iface The local interface address.
     887                 :     */
     888                 :     explicit multicast_interface_v4(ipv4_address iface) noexcept;
     889                 : 
     890                 :     /// Return the protocol level.
     891                 :     static int level() noexcept;
     892                 : 
     893                 :     /// Return the option name.
     894                 :     static int name() noexcept;
     895                 : 
     896                 :     /// Return a pointer to the underlying storage.
     897                 :     void* data() noexcept
     898                 :     {
     899                 :         return storage_;
     900                 :     }
     901                 : 
     902                 :     /// Return a pointer to the underlying storage.
     903               2 :     void const* data() const noexcept
     904                 :     {
     905               2 :         return storage_;
     906                 :     }
     907                 : 
     908                 :     /// Return the size of the underlying storage.
     909                 :     std::size_t size() const noexcept;
     910                 : 
     911                 :     /// No-op resize.
     912                 :     void resize(std::size_t) noexcept {}
     913                 : };
     914                 : 
     915                 : } // namespace boost::corosio::socket_option
     916                 : 
     917                 : #endif // BOOST_COROSIO_SOCKET_OPTION_HPP
        

Generated by: LCOV version 2.3