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-05-29 17:59:39 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 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         261 :     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              42 :     bool value() const noexcept
      66                 :     {
      67              42 :         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              44 :     void* data() noexcept
      84                 :     {
      85              44 :         return &value_;
      86                 :     }
      87                 : 
      88                 :     /// Return a pointer to the underlying storage.
      89             261 :     void const* data() const noexcept
      90                 :     {
      91             261 :         return &value_;
      92                 :     }
      93                 : 
      94                 :     /// Return the size of the underlying storage.
      95             305 :     std::size_t size() const noexcept
      96                 :     {
      97             305 :         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              44 :     void resize(std::size_t s) noexcept
     107                 :     {
     108              44 :         if (s == sizeof(char))
     109 MIS           0 :             value_ = *reinterpret_cast<unsigned char*>(&value_) ? 1 : 0;
     110 HIT          44 :     }
     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 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              24 :     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              30 :     int value() const noexcept
     141                 :     {
     142              30 :         return value_;
     143                 :     }
     144                 : 
     145                 :     /// Return a pointer to the underlying storage.
     146              28 :     void* data() noexcept
     147                 :     {
     148              28 :         return &value_;
     149                 :     }
     150                 : 
     151                 :     /// Return a pointer to the underlying storage.
     152              24 :     void const* data() const noexcept
     153                 :     {
     154              24 :         return &value_;
     155                 :     }
     156                 : 
     157                 :     /// Return the size of the underlying storage.
     158              52 :     std::size_t size() const noexcept
     159                 :     {
     160              52 :         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              28 :     void resize(std::size_t s) noexcept
     168                 :     {
     169              28 :         if (s == sizeof(char))
     170 MIS           0 :             value_ =
     171               0 :                 static_cast<int>(*reinterpret_cast<unsigned char*>(&value_));
     172 HIT          28 :     }
     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 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               6 :     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               4 :     bool value() const noexcept
     205                 :     {
     206               4 :         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               4 :     void* data() noexcept
     223                 :     {
     224               4 :         return &value_;
     225                 :     }
     226                 : 
     227                 :     /// Return a pointer to the underlying storage.
     228               6 :     void const* data() const noexcept
     229                 :     {
     230               6 :         return &value_;
     231                 :     }
     232                 : 
     233                 :     /// Return the size of the underlying storage.
     234              10 :     std::size_t size() const noexcept
     235                 :     {
     236              10 :         return sizeof(value_);
     237                 :     }
     238                 : 
     239                 :     /// Storage is already one byte; no normalization needed.
     240               4 :     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 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               2 :     explicit byte_integer_option(int v) noexcept
     262               2 :         : value_(static_cast<unsigned char>(v))
     263               2 :     {}
     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               2 :     int value() const noexcept
     274                 :     {
     275               2 :         return value_;
     276                 :     }
     277                 : 
     278                 :     /// Return a pointer to the underlying storage.
     279               2 :     void* data() noexcept
     280                 :     {
     281               2 :         return &value_;
     282                 :     }
     283                 : 
     284                 :     /// Return a pointer to the underlying storage.
     285               2 :     void const* data() const noexcept
     286                 :     {
     287               2 :         return &value_;
     288                 :     }
     289                 : 
     290                 :     /// Return the size of the underlying storage.
     291               4 :     std::size_t size() const noexcept
     292                 :     {
     293               4 :         return sizeof(value_);
     294                 :     }
     295                 : 
     296                 :     /// Storage is already one byte; no normalization needed.
     297               2 :     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                 :     if ( nd.value() )
     307                 :         // Nagle's algorithm is disabled
     308                 :     @endcode
     309                 : */
     310                 : class BOOST_COROSIO_DECL no_delay : public boolean_option
     311                 : {
     312                 : public:
     313                 :     using boolean_option::boolean_option;
     314                 :     using boolean_option::operator=;
     315                 : 
     316                 :     /// Return the protocol level.
     317                 :     static int level() noexcept;
     318                 : 
     319                 :     /// Return the option name.
     320                 :     static int name() noexcept;
     321                 : };
     322                 : 
     323                 : /** Enable periodic keepalive probes (SO_KEEPALIVE).
     324                 : 
     325                 :     @par Example
     326                 :     @code
     327                 :     sock.set_option( socket_option::keep_alive( true ) );
     328                 :     @endcode
     329                 : */
     330                 : class BOOST_COROSIO_DECL keep_alive : public boolean_option
     331                 : {
     332                 : public:
     333                 :     using boolean_option::boolean_option;
     334                 :     using boolean_option::operator=;
     335                 : 
     336                 :     /// Return the protocol level.
     337                 :     static int level() noexcept;
     338                 : 
     339                 :     /// Return the option name.
     340                 :     static int name() noexcept;
     341                 : };
     342                 : 
     343                 : /** Restrict an IPv6 socket to IPv6 only (IPV6_V6ONLY).
     344                 : 
     345                 :     When enabled, the socket only accepts IPv6 connections.
     346                 :     When disabled, the socket accepts both IPv4 and IPv6
     347                 :     connections (dual-stack mode).
     348                 : 
     349                 :     @par Example
     350                 :     @code
     351                 :     sock.set_option( socket_option::v6_only( true ) );
     352                 :     @endcode
     353                 : */
     354                 : class BOOST_COROSIO_DECL v6_only : public boolean_option
     355                 : {
     356                 : public:
     357                 :     using boolean_option::boolean_option;
     358                 :     using boolean_option::operator=;
     359                 : 
     360                 :     /// Return the protocol level.
     361                 :     static int level() noexcept;
     362                 : 
     363                 :     /// Return the option name.
     364                 :     static int name() noexcept;
     365                 : };
     366                 : 
     367                 : /** Allow local address reuse (SO_REUSEADDR).
     368                 : 
     369                 :     @par Example
     370                 :     @code
     371                 :     acc.set_option( socket_option::reuse_address( true ) );
     372                 :     @endcode
     373                 : */
     374                 : class BOOST_COROSIO_DECL reuse_address : public boolean_option
     375                 : {
     376                 : public:
     377                 :     using boolean_option::boolean_option;
     378                 :     using boolean_option::operator=;
     379                 : 
     380                 :     /// Return the protocol level.
     381                 :     static int level() noexcept;
     382                 : 
     383                 :     /// Return the option name.
     384                 :     static int name() noexcept;
     385                 : };
     386                 : 
     387                 : /** Allow sending to broadcast addresses (SO_BROADCAST).
     388                 : 
     389                 :     Required for UDP sockets that send to broadcast addresses
     390                 :     such as 255.255.255.255. Without this option, `send_to`
     391                 :     returns an error.
     392                 : 
     393                 :     @par Example
     394                 :     @code
     395                 :     udp_socket sock( ioc );
     396                 :     sock.open();
     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` will return an error.
     417                 : 
     418                 :     @par Example
     419                 :     @code
     420                 :     acc.open( tcp::v6() );
     421                 :     acc.set_option( socket_option::reuse_port( true ) );
     422                 :     acc.bind( endpoint( ipv6_address::any(), 8080 ) );
     423                 :     acc.listen();
     424                 :     @endcode
     425                 : */
     426                 : class BOOST_COROSIO_DECL reuse_port : public boolean_option
     427                 : {
     428                 : public:
     429                 :     using boolean_option::boolean_option;
     430                 :     using boolean_option::operator=;
     431                 : 
     432                 :     /// Return the protocol level.
     433                 :     static int level() noexcept;
     434                 : 
     435                 :     /// Return the option name.
     436                 :     static int name() noexcept;
     437                 : };
     438                 : 
     439                 : /** Set the receive buffer size (SO_RCVBUF).
     440                 : 
     441                 :     @par Example
     442                 :     @code
     443                 :     sock.set_option( socket_option::receive_buffer_size( 65536 ) );
     444                 :     auto opt = sock.get_option<socket_option::receive_buffer_size>();
     445                 :     int sz = opt.value();
     446                 :     @endcode
     447                 : */
     448                 : class BOOST_COROSIO_DECL receive_buffer_size : public integer_option
     449                 : {
     450                 : public:
     451                 :     using integer_option::integer_option;
     452                 :     using integer_option::operator=;
     453                 : 
     454                 :     /// Return the protocol level.
     455                 :     static int level() noexcept;
     456                 : 
     457                 :     /// Return the option name.
     458                 :     static int name() noexcept;
     459                 : };
     460                 : 
     461                 : /** Set the send buffer size (SO_SNDBUF).
     462                 : 
     463                 :     @par Example
     464                 :     @code
     465                 :     sock.set_option( socket_option::send_buffer_size( 65536 ) );
     466                 :     @endcode
     467                 : */
     468                 : class BOOST_COROSIO_DECL send_buffer_size : public integer_option
     469                 : {
     470                 : public:
     471                 :     using integer_option::integer_option;
     472                 :     using integer_option::operator=;
     473                 : 
     474                 :     /// Return the protocol level.
     475                 :     static int level() noexcept;
     476                 : 
     477                 :     /// Return the option name.
     478                 :     static int name() noexcept;
     479                 : };
     480                 : 
     481                 : /** The SO_LINGER socket option.
     482                 : 
     483                 :     Controls behavior when closing a socket with unsent data.
     484                 :     When enabled, `close()` blocks until pending data is sent
     485                 :     or the timeout expires.
     486                 : 
     487                 :     @par Example
     488                 :     @code
     489                 :     sock.set_option( socket_option::linger( true, 5 ) );
     490                 :     auto opt = sock.get_option<socket_option::linger>();
     491                 :     if ( opt.enabled() )
     492                 :         std::cout << "linger timeout: " << opt.timeout() << "s\n";
     493                 :     @endcode
     494                 : */
     495                 : class BOOST_COROSIO_DECL linger
     496                 : {
     497                 :     // Opaque storage for the platform's struct linger.
     498                 :     // POSIX: { int, int } = 8 bytes.
     499                 :     // Windows: { u_short, u_short } = 4 bytes.
     500                 :     static constexpr std::size_t max_storage_ = 8;
     501                 :     alignas(4) unsigned char storage_[max_storage_]{};
     502                 : 
     503                 : public:
     504                 :     /// Construct with default values (disabled, zero timeout).
     505                 :     linger() noexcept = default;
     506                 : 
     507                 :     /** Construct with explicit values.
     508                 : 
     509                 :         @param enabled `true` to enable linger behavior on close.
     510                 :         @param timeout The linger timeout in seconds.
     511                 :     */
     512                 :     linger(bool enabled, int timeout) noexcept;
     513                 : 
     514                 :     /// Return whether linger is enabled.
     515                 :     bool enabled() const noexcept;
     516                 : 
     517                 :     /// Set whether linger is enabled.
     518                 :     void enabled(bool v) noexcept;
     519                 : 
     520                 :     /// Return the linger timeout in seconds.
     521                 :     int timeout() const noexcept;
     522                 : 
     523                 :     /// Set the linger timeout in seconds.
     524                 :     void timeout(int v) noexcept;
     525                 : 
     526                 :     /// Return the protocol level.
     527                 :     static int level() noexcept;
     528                 : 
     529                 :     /// Return the option name.
     530                 :     static int name() noexcept;
     531                 : 
     532                 :     /// Return a pointer to the underlying storage.
     533              10 :     void* data() noexcept
     534                 :     {
     535              10 :         return storage_;
     536                 :     }
     537                 : 
     538                 :     /// Return a pointer to the underlying storage.
     539              34 :     void const* data() const noexcept
     540                 :     {
     541              34 :         return storage_;
     542                 :     }
     543                 : 
     544                 :     /// Return the size of the underlying storage.
     545                 :     std::size_t size() const noexcept;
     546                 : 
     547                 :     /** Normalize after `getsockopt`.
     548                 : 
     549                 :         No-op — `struct linger` is always returned at full size.
     550                 : 
     551                 :         @param s The number of bytes actually written by `getsockopt`.
     552                 :     */
     553              10 :     void resize(std::size_t) noexcept {}
     554                 : };
     555                 : 
     556                 : /** Enable loopback of outgoing multicast on IPv4 (IP_MULTICAST_LOOP).
     557                 : 
     558                 :     Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
     559                 :     reject the four-byte form with `EINVAL`. Linux accepts either size.
     560                 : 
     561                 :     @par Example
     562                 :     @code
     563                 :     sock.set_option( socket_option::multicast_loop_v4( true ) );
     564                 :     @endcode
     565                 : */
     566                 : class BOOST_COROSIO_DECL multicast_loop_v4 : public byte_boolean_option
     567                 : {
     568                 : public:
     569                 :     using byte_boolean_option::byte_boolean_option;
     570                 :     using byte_boolean_option::operator=;
     571                 : 
     572                 :     /// Return the protocol level.
     573                 :     static int level() noexcept;
     574                 : 
     575                 :     /// Return the option name.
     576                 :     static int name() noexcept;
     577                 : };
     578                 : 
     579                 : /** Enable loopback of outgoing multicast on IPv6 (IPV6_MULTICAST_LOOP).
     580                 : 
     581                 :     @par Example
     582                 :     @code
     583                 :     sock.set_option( socket_option::multicast_loop_v6( true ) );
     584                 :     @endcode
     585                 : */
     586                 : class BOOST_COROSIO_DECL multicast_loop_v6 : public boolean_option
     587                 : {
     588                 : public:
     589                 :     using boolean_option::boolean_option;
     590                 :     using boolean_option::operator=;
     591                 : 
     592                 :     /// Return the protocol level.
     593                 :     static int level() noexcept;
     594                 : 
     595                 :     /// Return the option name.
     596                 :     static int name() noexcept;
     597                 : };
     598                 : 
     599                 : /** Set the multicast TTL for IPv4 (IP_MULTICAST_TTL).
     600                 : 
     601                 :     Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
     602                 :     reject the four-byte form with `EINVAL`. Linux accepts either size.
     603                 :     Values are truncated to the 0–255 range.
     604                 : 
     605                 :     @par Example
     606                 :     @code
     607                 :     sock.set_option( socket_option::multicast_hops_v4( 4 ) );
     608                 :     @endcode
     609                 : */
     610                 : class BOOST_COROSIO_DECL multicast_hops_v4 : public byte_integer_option
     611                 : {
     612                 : public:
     613                 :     using byte_integer_option::byte_integer_option;
     614                 :     using byte_integer_option::operator=;
     615                 : 
     616                 :     /// Return the protocol level.
     617                 :     static int level() noexcept;
     618                 : 
     619                 :     /// Return the option name.
     620                 :     static int name() noexcept;
     621                 : };
     622                 : 
     623                 : /** Set the multicast hop limit for IPv6 (IPV6_MULTICAST_HOPS).
     624                 : 
     625                 :     @par Example
     626                 :     @code
     627                 :     sock.set_option( socket_option::multicast_hops_v6( 4 ) );
     628                 :     @endcode
     629                 : */
     630                 : class BOOST_COROSIO_DECL multicast_hops_v6 : public integer_option
     631                 : {
     632                 : public:
     633                 :     using integer_option::integer_option;
     634                 :     using integer_option::operator=;
     635                 : 
     636                 :     /// Return the protocol level.
     637                 :     static int level() noexcept;
     638                 : 
     639                 :     /// Return the option name.
     640                 :     static int name() noexcept;
     641                 : };
     642                 : 
     643                 : /** Set the outgoing interface for IPv6 multicast (IPV6_MULTICAST_IF).
     644                 : 
     645                 :     @par Example
     646                 :     @code
     647                 :     sock.set_option( socket_option::multicast_interface_v6( 1 ) );
     648                 :     @endcode
     649                 : */
     650                 : class BOOST_COROSIO_DECL multicast_interface_v6 : public integer_option
     651                 : {
     652                 : public:
     653                 :     using integer_option::integer_option;
     654                 :     using integer_option::operator=;
     655                 : 
     656                 :     /// Return the protocol level.
     657                 :     static int level() noexcept;
     658                 : 
     659                 :     /// Return the option name.
     660                 :     static int name() noexcept;
     661                 : };
     662                 : 
     663                 : /** Join an IPv4 multicast group (IP_ADD_MEMBERSHIP).
     664                 : 
     665                 :     @par Example
     666                 :     @code
     667                 :     sock.set_option( socket_option::join_group_v4(
     668                 :         ipv4_address( "239.255.0.1" ) ) );
     669                 :     @endcode
     670                 : */
     671                 : class BOOST_COROSIO_DECL join_group_v4
     672                 : {
     673                 :     static constexpr std::size_t max_storage_ = 8;
     674                 :     alignas(4) unsigned char storage_[max_storage_]{};
     675                 : 
     676                 : public:
     677                 :     /// Construct with default values.
     678                 :     join_group_v4() noexcept = default;
     679                 : 
     680                 :     /** Construct with a group and optional interface address.
     681                 : 
     682                 :         @param group The multicast group address to join.
     683                 :         @param iface The local interface to use (default: any).
     684                 :     */
     685                 :     join_group_v4(
     686                 :         ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
     687                 : 
     688                 :     /// Return the protocol level.
     689                 :     static int level() noexcept;
     690                 : 
     691                 :     /// Return the option name.
     692                 :     static int name() noexcept;
     693                 : 
     694                 :     /// Return a pointer to the underlying storage.
     695                 :     void* data() noexcept
     696                 :     {
     697                 :         return storage_;
     698                 :     }
     699                 : 
     700                 :     /// Return a pointer to the underlying storage.
     701               4 :     void const* data() const noexcept
     702                 :     {
     703               4 :         return storage_;
     704                 :     }
     705                 : 
     706                 :     /// Return the size of the underlying storage.
     707                 :     std::size_t size() const noexcept;
     708                 : 
     709                 :     /// No-op resize.
     710                 :     void resize(std::size_t) noexcept {}
     711                 : };
     712                 : 
     713                 : /** Leave an IPv4 multicast group (IP_DROP_MEMBERSHIP).
     714                 : 
     715                 :     @par Example
     716                 :     @code
     717                 :     sock.set_option( socket_option::leave_group_v4(
     718                 :         ipv4_address( "239.255.0.1" ) ) );
     719                 :     @endcode
     720                 : */
     721                 : class BOOST_COROSIO_DECL leave_group_v4
     722                 : {
     723                 :     static constexpr std::size_t max_storage_ = 8;
     724                 :     alignas(4) unsigned char storage_[max_storage_]{};
     725                 : 
     726                 : public:
     727                 :     /// Construct with default values.
     728                 :     leave_group_v4() noexcept = default;
     729                 : 
     730                 :     /** Construct with a group and optional interface address.
     731                 : 
     732                 :         @param group The multicast group address to leave.
     733                 :         @param iface The local interface (default: any).
     734                 :     */
     735                 :     leave_group_v4(
     736                 :         ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
     737                 : 
     738                 :     /// Return the protocol level.
     739                 :     static int level() noexcept;
     740                 : 
     741                 :     /// Return the option name.
     742                 :     static int name() noexcept;
     743                 : 
     744                 :     /// Return a pointer to the underlying storage.
     745                 :     void* data() noexcept
     746                 :     {
     747                 :         return storage_;
     748                 :     }
     749                 : 
     750                 :     /// Return a pointer to the underlying storage.
     751               2 :     void const* data() const noexcept
     752                 :     {
     753               2 :         return storage_;
     754                 :     }
     755                 : 
     756                 :     /// Return the size of the underlying storage.
     757                 :     std::size_t size() const noexcept;
     758                 : 
     759                 :     /// No-op resize.
     760                 :     void resize(std::size_t) noexcept {}
     761                 : };
     762                 : 
     763                 : /** Join an IPv6 multicast group (IPV6_JOIN_GROUP).
     764                 : 
     765                 :     @par Example
     766                 :     @code
     767                 :     sock.set_option( socket_option::join_group_v6(
     768                 :         ipv6_address( "ff02::1" ), 0 ) );
     769                 :     @endcode
     770                 : */
     771                 : class BOOST_COROSIO_DECL join_group_v6
     772                 : {
     773                 :     static constexpr std::size_t max_storage_ = 20;
     774                 :     alignas(4) unsigned char storage_[max_storage_]{};
     775                 : 
     776                 : public:
     777                 :     /// Construct with default values.
     778                 :     join_group_v6() noexcept = default;
     779                 : 
     780                 :     /** Construct with a group and optional interface index.
     781                 : 
     782                 :         @param group The multicast group address to join.
     783                 :         @param if_index The interface index (0 = kernel chooses).
     784                 :     */
     785                 :     join_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
     786                 : 
     787                 :     /// Return the protocol level.
     788                 :     static int level() noexcept;
     789                 : 
     790                 :     /// Return the option name.
     791                 :     static int name() noexcept;
     792                 : 
     793                 :     /// Return a pointer to the underlying storage.
     794                 :     void* data() noexcept
     795                 :     {
     796                 :         return storage_;
     797                 :     }
     798                 : 
     799                 :     /// Return a pointer to the underlying storage.
     800               2 :     void const* data() const noexcept
     801                 :     {
     802               2 :         return storage_;
     803                 :     }
     804                 : 
     805                 :     /// Return the size of the underlying storage.
     806                 :     std::size_t size() const noexcept;
     807                 : 
     808                 :     /// No-op resize.
     809                 :     void resize(std::size_t) noexcept {}
     810                 : };
     811                 : 
     812                 : /** Leave an IPv6 multicast group (IPV6_LEAVE_GROUP).
     813                 : 
     814                 :     @par Example
     815                 :     @code
     816                 :     sock.set_option( socket_option::leave_group_v6(
     817                 :         ipv6_address( "ff02::1" ), 0 ) );
     818                 :     @endcode
     819                 : */
     820                 : class BOOST_COROSIO_DECL leave_group_v6
     821                 : {
     822                 :     static constexpr std::size_t max_storage_ = 20;
     823                 :     alignas(4) unsigned char storage_[max_storage_]{};
     824                 : 
     825                 : public:
     826                 :     /// Construct with default values.
     827                 :     leave_group_v6() noexcept = default;
     828                 : 
     829                 :     /** Construct with a group and optional interface index.
     830                 : 
     831                 :         @param group The multicast group address to leave.
     832                 :         @param if_index The interface index (0 = kernel chooses).
     833                 :     */
     834                 :     leave_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
     835                 : 
     836                 :     /// Return the protocol level.
     837                 :     static int level() noexcept;
     838                 : 
     839                 :     /// Return the option name.
     840                 :     static int name() noexcept;
     841                 : 
     842                 :     /// Return a pointer to the underlying storage.
     843                 :     void* data() noexcept
     844                 :     {
     845                 :         return storage_;
     846                 :     }
     847                 : 
     848                 :     /// Return a pointer to the underlying storage.
     849               2 :     void const* data() const noexcept
     850                 :     {
     851               2 :         return storage_;
     852                 :     }
     853                 : 
     854                 :     /// Return the size of the underlying storage.
     855                 :     std::size_t size() const noexcept;
     856                 : 
     857                 :     /// No-op resize.
     858                 :     void resize(std::size_t) noexcept {}
     859                 : };
     860                 : 
     861                 : /** Set the outgoing interface for IPv4 multicast (IP_MULTICAST_IF).
     862                 : 
     863                 :     Unlike the integer-based `multicast_interface_v6`, this option
     864                 :     takes an `ipv4_address` identifying the local interface.
     865                 : 
     866                 :     @par Example
     867                 :     @code
     868                 :     sock.set_option( socket_option::multicast_interface_v4(
     869                 :         ipv4_address( "192.168.1.1" ) ) );
     870                 :     @endcode
     871                 : */
     872                 : class BOOST_COROSIO_DECL multicast_interface_v4
     873                 : {
     874                 :     static constexpr std::size_t max_storage_ = 4;
     875                 :     alignas(4) unsigned char storage_[max_storage_]{};
     876                 : 
     877                 : public:
     878                 :     /// Construct with default values (INADDR_ANY).
     879                 :     multicast_interface_v4() noexcept = default;
     880                 : 
     881                 :     /** Construct with an interface address.
     882                 : 
     883                 :         @param iface The local interface address.
     884                 :     */
     885                 :     explicit multicast_interface_v4(ipv4_address iface) noexcept;
     886                 : 
     887                 :     /// Return the protocol level.
     888                 :     static int level() noexcept;
     889                 : 
     890                 :     /// Return the option name.
     891                 :     static int name() noexcept;
     892                 : 
     893                 :     /// Return a pointer to the underlying storage.
     894                 :     void* data() noexcept
     895                 :     {
     896                 :         return storage_;
     897                 :     }
     898                 : 
     899                 :     /// Return a pointer to the underlying storage.
     900               2 :     void const* data() const noexcept
     901                 :     {
     902               2 :         return storage_;
     903                 :     }
     904                 : 
     905                 :     /// Return the size of the underlying storage.
     906                 :     std::size_t size() const noexcept;
     907                 : 
     908                 :     /// No-op resize.
     909                 :     void resize(std::size_t) noexcept {}
     910                 : };
     911                 : 
     912                 : } // namespace boost::corosio::socket_option
     913                 : 
     914                 : #endif // BOOST_COROSIO_SOCKET_OPTION_HPP
        

Generated by: LCOV version 2.3