LCOV - code coverage report
Current view: top level - corosio - socket_option.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 93.2 % 44 41 3
Test Date: 2026-03-17 15:52:49 Functions: 100.0 % 20 20

           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         179 :     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              44 :     bool value() const noexcept
      66                 :     {
      67              44 :         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              46 :     void* data() noexcept
      84                 :     {
      85              46 :         return &value_;
      86                 :     }
      87                 : 
      88                 :     /// Return a pointer to the underlying storage.
      89             181 :     void const* data() const noexcept
      90                 :     {
      91             181 :         return &value_;
      92                 :     }
      93                 : 
      94                 :     /// Return the size of the underlying storage.
      95             227 :     std::size_t size() const noexcept
      96                 :     {
      97             227 :         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              46 :     void resize(std::size_t s) noexcept
     107                 :     {
     108              46 :         if (s == sizeof(char))
     109 MIS           0 :             value_ = *reinterpret_cast<unsigned char*>(&value_) ? 1 : 0;
     110 HIT          46 :     }
     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              14 :     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              24 :     int value() const noexcept
     141                 :     {
     142              24 :         return value_;
     143                 :     }
     144                 : 
     145                 :     /// Return a pointer to the underlying storage.
     146              22 :     void* data() noexcept
     147                 :     {
     148              22 :         return &value_;
     149                 :     }
     150                 : 
     151                 :     /// Return a pointer to the underlying storage.
     152              14 :     void const* data() const noexcept
     153                 :     {
     154              14 :         return &value_;
     155                 :     }
     156                 : 
     157                 :     /// Return the size of the underlying storage.
     158              36 :     std::size_t size() const noexcept
     159                 :     {
     160              36 :         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              22 :     void resize(std::size_t s) noexcept
     168                 :     {
     169              22 :         if (s == sizeof(char))
     170 MIS           0 :             value_ =
     171               0 :                 static_cast<int>(*reinterpret_cast<unsigned char*>(&value_));
     172 HIT          22 :     }
     173                 : };
     174                 : 
     175                 : /** Disable Nagle's algorithm (TCP_NODELAY).
     176                 : 
     177                 :     @par Example
     178                 :     @code
     179                 :     sock.set_option( socket_option::no_delay( true ) );
     180                 :     auto nd = sock.get_option<socket_option::no_delay>();
     181                 :     if ( nd.value() )
     182                 :         // Nagle's algorithm is disabled
     183                 :     @endcode
     184                 : */
     185                 : class BOOST_COROSIO_DECL no_delay : public boolean_option
     186                 : {
     187                 : public:
     188                 :     using boolean_option::boolean_option;
     189                 :     using boolean_option::operator=;
     190                 : 
     191                 :     /// Return the protocol level.
     192                 :     static int level() noexcept;
     193                 : 
     194                 :     /// Return the option name.
     195                 :     static int name() noexcept;
     196                 : };
     197                 : 
     198                 : /** Enable periodic keepalive probes (SO_KEEPALIVE).
     199                 : 
     200                 :     @par Example
     201                 :     @code
     202                 :     sock.set_option( socket_option::keep_alive( true ) );
     203                 :     @endcode
     204                 : */
     205                 : class BOOST_COROSIO_DECL keep_alive : public boolean_option
     206                 : {
     207                 : public:
     208                 :     using boolean_option::boolean_option;
     209                 :     using boolean_option::operator=;
     210                 : 
     211                 :     /// Return the protocol level.
     212                 :     static int level() noexcept;
     213                 : 
     214                 :     /// Return the option name.
     215                 :     static int name() noexcept;
     216                 : };
     217                 : 
     218                 : /** Restrict an IPv6 socket to IPv6 only (IPV6_V6ONLY).
     219                 : 
     220                 :     When enabled, the socket only accepts IPv6 connections.
     221                 :     When disabled, the socket accepts both IPv4 and IPv6
     222                 :     connections (dual-stack mode).
     223                 : 
     224                 :     @par Example
     225                 :     @code
     226                 :     sock.set_option( socket_option::v6_only( true ) );
     227                 :     @endcode
     228                 : */
     229                 : class BOOST_COROSIO_DECL v6_only : public boolean_option
     230                 : {
     231                 : public:
     232                 :     using boolean_option::boolean_option;
     233                 :     using boolean_option::operator=;
     234                 : 
     235                 :     /// Return the protocol level.
     236                 :     static int level() noexcept;
     237                 : 
     238                 :     /// Return the option name.
     239                 :     static int name() noexcept;
     240                 : };
     241                 : 
     242                 : /** Allow local address reuse (SO_REUSEADDR).
     243                 : 
     244                 :     @par Example
     245                 :     @code
     246                 :     acc.set_option( socket_option::reuse_address( true ) );
     247                 :     @endcode
     248                 : */
     249                 : class BOOST_COROSIO_DECL reuse_address : public boolean_option
     250                 : {
     251                 : public:
     252                 :     using boolean_option::boolean_option;
     253                 :     using boolean_option::operator=;
     254                 : 
     255                 :     /// Return the protocol level.
     256                 :     static int level() noexcept;
     257                 : 
     258                 :     /// Return the option name.
     259                 :     static int name() noexcept;
     260                 : };
     261                 : 
     262                 : /** Allow sending to broadcast addresses (SO_BROADCAST).
     263                 : 
     264                 :     Required for UDP sockets that send to broadcast addresses
     265                 :     such as 255.255.255.255. Without this option, `send_to`
     266                 :     returns an error.
     267                 : 
     268                 :     @par Example
     269                 :     @code
     270                 :     udp_socket sock( ioc );
     271                 :     sock.open();
     272                 :     sock.set_option( socket_option::broadcast( true ) );
     273                 :     @endcode
     274                 : */
     275                 : class BOOST_COROSIO_DECL broadcast : public boolean_option
     276                 : {
     277                 : public:
     278                 :     using boolean_option::boolean_option;
     279                 :     using boolean_option::operator=;
     280                 : 
     281                 :     /// Return the protocol level.
     282                 :     static int level() noexcept;
     283                 : 
     284                 :     /// Return the option name.
     285                 :     static int name() noexcept;
     286                 : };
     287                 : 
     288                 : /** Allow multiple sockets to bind to the same port (SO_REUSEPORT).
     289                 : 
     290                 :     Not available on all platforms. On unsupported platforms,
     291                 :     `set_option` will return an error.
     292                 : 
     293                 :     @par Example
     294                 :     @code
     295                 :     acc.open( tcp::v6() );
     296                 :     acc.set_option( socket_option::reuse_port( true ) );
     297                 :     acc.bind( endpoint( ipv6_address::any(), 8080 ) );
     298                 :     acc.listen();
     299                 :     @endcode
     300                 : */
     301                 : class BOOST_COROSIO_DECL reuse_port : public boolean_option
     302                 : {
     303                 : public:
     304                 :     using boolean_option::boolean_option;
     305                 :     using boolean_option::operator=;
     306                 : 
     307                 :     /// Return the protocol level.
     308                 :     static int level() noexcept;
     309                 : 
     310                 :     /// Return the option name.
     311                 :     static int name() noexcept;
     312                 : };
     313                 : 
     314                 : /** Set the receive buffer size (SO_RCVBUF).
     315                 : 
     316                 :     @par Example
     317                 :     @code
     318                 :     sock.set_option( socket_option::receive_buffer_size( 65536 ) );
     319                 :     auto opt = sock.get_option<socket_option::receive_buffer_size>();
     320                 :     int sz = opt.value();
     321                 :     @endcode
     322                 : */
     323                 : class BOOST_COROSIO_DECL receive_buffer_size : public integer_option
     324                 : {
     325                 : public:
     326                 :     using integer_option::integer_option;
     327                 :     using integer_option::operator=;
     328                 : 
     329                 :     /// Return the protocol level.
     330                 :     static int level() noexcept;
     331                 : 
     332                 :     /// Return the option name.
     333                 :     static int name() noexcept;
     334                 : };
     335                 : 
     336                 : /** Set the send buffer size (SO_SNDBUF).
     337                 : 
     338                 :     @par Example
     339                 :     @code
     340                 :     sock.set_option( socket_option::send_buffer_size( 65536 ) );
     341                 :     @endcode
     342                 : */
     343                 : class BOOST_COROSIO_DECL send_buffer_size : public integer_option
     344                 : {
     345                 : public:
     346                 :     using integer_option::integer_option;
     347                 :     using integer_option::operator=;
     348                 : 
     349                 :     /// Return the protocol level.
     350                 :     static int level() noexcept;
     351                 : 
     352                 :     /// Return the option name.
     353                 :     static int name() noexcept;
     354                 : };
     355                 : 
     356                 : /** The SO_LINGER socket option.
     357                 : 
     358                 :     Controls behavior when closing a socket with unsent data.
     359                 :     When enabled, `close()` blocks until pending data is sent
     360                 :     or the timeout expires.
     361                 : 
     362                 :     @par Example
     363                 :     @code
     364                 :     sock.set_option( socket_option::linger( true, 5 ) );
     365                 :     auto opt = sock.get_option<socket_option::linger>();
     366                 :     if ( opt.enabled() )
     367                 :         std::cout << "linger timeout: " << opt.timeout() << "s\n";
     368                 :     @endcode
     369                 : */
     370                 : class BOOST_COROSIO_DECL linger
     371                 : {
     372                 :     // Opaque storage for the platform's struct linger.
     373                 :     // POSIX: { int, int } = 8 bytes.
     374                 :     // Windows: { u_short, u_short } = 4 bytes.
     375                 :     static constexpr std::size_t max_storage_ = 8;
     376                 :     alignas(4) unsigned char storage_[max_storage_]{};
     377                 : 
     378                 : public:
     379                 :     /// Construct with default values (disabled, zero timeout).
     380                 :     linger() noexcept = default;
     381                 : 
     382                 :     /** Construct with explicit values.
     383                 : 
     384                 :         @param enabled `true` to enable linger behavior on close.
     385                 :         @param timeout The linger timeout in seconds.
     386                 :     */
     387                 :     linger(bool enabled, int timeout) noexcept;
     388                 : 
     389                 :     /// Return whether linger is enabled.
     390                 :     bool enabled() const noexcept;
     391                 : 
     392                 :     /// Set whether linger is enabled.
     393                 :     void enabled(bool v) noexcept;
     394                 : 
     395                 :     /// Return the linger timeout in seconds.
     396                 :     int timeout() const noexcept;
     397                 : 
     398                 :     /// Set the linger timeout in seconds.
     399                 :     void timeout(int v) noexcept;
     400                 : 
     401                 :     /// Return the protocol level.
     402                 :     static int level() noexcept;
     403                 : 
     404                 :     /// Return the option name.
     405                 :     static int name() noexcept;
     406                 : 
     407                 :     /// Return a pointer to the underlying storage.
     408              10 :     void* data() noexcept
     409                 :     {
     410              10 :         return storage_;
     411                 :     }
     412                 : 
     413                 :     /// Return a pointer to the underlying storage.
     414              18 :     void const* data() const noexcept
     415                 :     {
     416              18 :         return storage_;
     417                 :     }
     418                 : 
     419                 :     /// Return the size of the underlying storage.
     420                 :     std::size_t size() const noexcept;
     421                 : 
     422                 :     /** Normalize after `getsockopt`.
     423                 : 
     424                 :         No-op — `struct linger` is always returned at full size.
     425                 : 
     426                 :         @param s The number of bytes actually written by `getsockopt`.
     427                 :     */
     428              10 :     void resize(std::size_t) noexcept {}
     429                 : };
     430                 : 
     431                 : /** Enable loopback of outgoing multicast on IPv4 (IP_MULTICAST_LOOP).
     432                 : 
     433                 :     @par Example
     434                 :     @code
     435                 :     sock.set_option( socket_option::multicast_loop_v4( true ) );
     436                 :     @endcode
     437                 : */
     438                 : class BOOST_COROSIO_DECL multicast_loop_v4 : public boolean_option
     439                 : {
     440                 : public:
     441                 :     using boolean_option::boolean_option;
     442                 :     using boolean_option::operator=;
     443                 : 
     444                 :     /// Return the protocol level.
     445                 :     static int level() noexcept;
     446                 : 
     447                 :     /// Return the option name.
     448                 :     static int name() noexcept;
     449                 : };
     450                 : 
     451                 : /** Enable loopback of outgoing multicast on IPv6 (IPV6_MULTICAST_LOOP).
     452                 : 
     453                 :     @par Example
     454                 :     @code
     455                 :     sock.set_option( socket_option::multicast_loop_v6( true ) );
     456                 :     @endcode
     457                 : */
     458                 : class BOOST_COROSIO_DECL multicast_loop_v6 : public boolean_option
     459                 : {
     460                 : public:
     461                 :     using boolean_option::boolean_option;
     462                 :     using boolean_option::operator=;
     463                 : 
     464                 :     /// Return the protocol level.
     465                 :     static int level() noexcept;
     466                 : 
     467                 :     /// Return the option name.
     468                 :     static int name() noexcept;
     469                 : };
     470                 : 
     471                 : /** Set the multicast TTL for IPv4 (IP_MULTICAST_TTL).
     472                 : 
     473                 :     @par Example
     474                 :     @code
     475                 :     sock.set_option( socket_option::multicast_hops_v4( 4 ) );
     476                 :     @endcode
     477                 : */
     478                 : class BOOST_COROSIO_DECL multicast_hops_v4 : public integer_option
     479                 : {
     480                 : public:
     481                 :     using integer_option::integer_option;
     482                 :     using integer_option::operator=;
     483                 : 
     484                 :     /// Return the protocol level.
     485                 :     static int level() noexcept;
     486                 : 
     487                 :     /// Return the option name.
     488                 :     static int name() noexcept;
     489                 : };
     490                 : 
     491                 : /** Set the multicast hop limit for IPv6 (IPV6_MULTICAST_HOPS).
     492                 : 
     493                 :     @par Example
     494                 :     @code
     495                 :     sock.set_option( socket_option::multicast_hops_v6( 4 ) );
     496                 :     @endcode
     497                 : */
     498                 : class BOOST_COROSIO_DECL multicast_hops_v6 : public integer_option
     499                 : {
     500                 : public:
     501                 :     using integer_option::integer_option;
     502                 :     using integer_option::operator=;
     503                 : 
     504                 :     /// Return the protocol level.
     505                 :     static int level() noexcept;
     506                 : 
     507                 :     /// Return the option name.
     508                 :     static int name() noexcept;
     509                 : };
     510                 : 
     511                 : /** Set the outgoing interface for IPv6 multicast (IPV6_MULTICAST_IF).
     512                 : 
     513                 :     @par Example
     514                 :     @code
     515                 :     sock.set_option( socket_option::multicast_interface_v6( 1 ) );
     516                 :     @endcode
     517                 : */
     518                 : class BOOST_COROSIO_DECL multicast_interface_v6 : public integer_option
     519                 : {
     520                 : public:
     521                 :     using integer_option::integer_option;
     522                 :     using integer_option::operator=;
     523                 : 
     524                 :     /// Return the protocol level.
     525                 :     static int level() noexcept;
     526                 : 
     527                 :     /// Return the option name.
     528                 :     static int name() noexcept;
     529                 : };
     530                 : 
     531                 : /** Join an IPv4 multicast group (IP_ADD_MEMBERSHIP).
     532                 : 
     533                 :     @par Example
     534                 :     @code
     535                 :     sock.set_option( socket_option::join_group_v4(
     536                 :         ipv4_address( "239.255.0.1" ) ) );
     537                 :     @endcode
     538                 : */
     539                 : class BOOST_COROSIO_DECL join_group_v4
     540                 : {
     541                 :     static constexpr std::size_t max_storage_ = 8;
     542                 :     alignas(4) unsigned char storage_[max_storage_]{};
     543                 : 
     544                 : public:
     545                 :     /// Construct with default values.
     546                 :     join_group_v4() noexcept = default;
     547                 : 
     548                 :     /** Construct with a group and optional interface address.
     549                 : 
     550                 :         @param group The multicast group address to join.
     551                 :         @param iface The local interface to use (default: any).
     552                 :     */
     553                 :     join_group_v4(
     554                 :         ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
     555                 : 
     556                 :     /// Return the protocol level.
     557                 :     static int level() noexcept;
     558                 : 
     559                 :     /// Return the option name.
     560                 :     static int name() noexcept;
     561                 : 
     562                 :     /// Return a pointer to the underlying storage.
     563                 :     void* data() noexcept
     564                 :     {
     565                 :         return storage_;
     566                 :     }
     567                 : 
     568                 :     /// Return a pointer to the underlying storage.
     569               2 :     void const* data() const noexcept
     570                 :     {
     571               2 :         return storage_;
     572                 :     }
     573                 : 
     574                 :     /// Return the size of the underlying storage.
     575                 :     std::size_t size() const noexcept;
     576                 : 
     577                 :     /// No-op resize.
     578                 :     void resize(std::size_t) noexcept {}
     579                 : };
     580                 : 
     581                 : /** Leave an IPv4 multicast group (IP_DROP_MEMBERSHIP).
     582                 : 
     583                 :     @par Example
     584                 :     @code
     585                 :     sock.set_option( socket_option::leave_group_v4(
     586                 :         ipv4_address( "239.255.0.1" ) ) );
     587                 :     @endcode
     588                 : */
     589                 : class BOOST_COROSIO_DECL leave_group_v4
     590                 : {
     591                 :     static constexpr std::size_t max_storage_ = 8;
     592                 :     alignas(4) unsigned char storage_[max_storage_]{};
     593                 : 
     594                 : public:
     595                 :     /// Construct with default values.
     596                 :     leave_group_v4() noexcept = default;
     597                 : 
     598                 :     /** Construct with a group and optional interface address.
     599                 : 
     600                 :         @param group The multicast group address to leave.
     601                 :         @param iface The local interface (default: any).
     602                 :     */
     603                 :     leave_group_v4(
     604                 :         ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
     605                 : 
     606                 :     /// Return the protocol level.
     607                 :     static int level() noexcept;
     608                 : 
     609                 :     /// Return the option name.
     610                 :     static int name() noexcept;
     611                 : 
     612                 :     /// Return a pointer to the underlying storage.
     613                 :     void* data() noexcept
     614                 :     {
     615                 :         return storage_;
     616                 :     }
     617                 : 
     618                 :     /// Return a pointer to the underlying storage.
     619                 :     void const* data() const noexcept
     620                 :     {
     621                 :         return storage_;
     622                 :     }
     623                 : 
     624                 :     /// Return the size of the underlying storage.
     625                 :     std::size_t size() const noexcept;
     626                 : 
     627                 :     /// No-op resize.
     628                 :     void resize(std::size_t) noexcept {}
     629                 : };
     630                 : 
     631                 : /** Join an IPv6 multicast group (IPV6_JOIN_GROUP).
     632                 : 
     633                 :     @par Example
     634                 :     @code
     635                 :     sock.set_option( socket_option::join_group_v6(
     636                 :         ipv6_address( "ff02::1" ), 0 ) );
     637                 :     @endcode
     638                 : */
     639                 : class BOOST_COROSIO_DECL join_group_v6
     640                 : {
     641                 :     static constexpr std::size_t max_storage_ = 20;
     642                 :     alignas(4) unsigned char storage_[max_storage_]{};
     643                 : 
     644                 : public:
     645                 :     /// Construct with default values.
     646                 :     join_group_v6() noexcept = default;
     647                 : 
     648                 :     /** Construct with a group and optional interface index.
     649                 : 
     650                 :         @param group The multicast group address to join.
     651                 :         @param if_index The interface index (0 = kernel chooses).
     652                 :     */
     653                 :     join_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
     654                 : 
     655                 :     /// Return the protocol level.
     656                 :     static int level() noexcept;
     657                 : 
     658                 :     /// Return the option name.
     659                 :     static int name() noexcept;
     660                 : 
     661                 :     /// Return a pointer to the underlying storage.
     662                 :     void* data() noexcept
     663                 :     {
     664                 :         return storage_;
     665                 :     }
     666                 : 
     667                 :     /// Return a pointer to the underlying storage.
     668                 :     void const* data() const noexcept
     669                 :     {
     670                 :         return storage_;
     671                 :     }
     672                 : 
     673                 :     /// Return the size of the underlying storage.
     674                 :     std::size_t size() const noexcept;
     675                 : 
     676                 :     /// No-op resize.
     677                 :     void resize(std::size_t) noexcept {}
     678                 : };
     679                 : 
     680                 : /** Leave an IPv6 multicast group (IPV6_LEAVE_GROUP).
     681                 : 
     682                 :     @par Example
     683                 :     @code
     684                 :     sock.set_option( socket_option::leave_group_v6(
     685                 :         ipv6_address( "ff02::1" ), 0 ) );
     686                 :     @endcode
     687                 : */
     688                 : class BOOST_COROSIO_DECL leave_group_v6
     689                 : {
     690                 :     static constexpr std::size_t max_storage_ = 20;
     691                 :     alignas(4) unsigned char storage_[max_storage_]{};
     692                 : 
     693                 : public:
     694                 :     /// Construct with default values.
     695                 :     leave_group_v6() noexcept = default;
     696                 : 
     697                 :     /** Construct with a group and optional interface index.
     698                 : 
     699                 :         @param group The multicast group address to leave.
     700                 :         @param if_index The interface index (0 = kernel chooses).
     701                 :     */
     702                 :     leave_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
     703                 : 
     704                 :     /// Return the protocol level.
     705                 :     static int level() noexcept;
     706                 : 
     707                 :     /// Return the option name.
     708                 :     static int name() noexcept;
     709                 : 
     710                 :     /// Return a pointer to the underlying storage.
     711                 :     void* data() noexcept
     712                 :     {
     713                 :         return storage_;
     714                 :     }
     715                 : 
     716                 :     /// Return a pointer to the underlying storage.
     717                 :     void const* data() const noexcept
     718                 :     {
     719                 :         return storage_;
     720                 :     }
     721                 : 
     722                 :     /// Return the size of the underlying storage.
     723                 :     std::size_t size() const noexcept;
     724                 : 
     725                 :     /// No-op resize.
     726                 :     void resize(std::size_t) noexcept {}
     727                 : };
     728                 : 
     729                 : /** Set the outgoing interface for IPv4 multicast (IP_MULTICAST_IF).
     730                 : 
     731                 :     Unlike the integer-based `multicast_interface_v6`, this option
     732                 :     takes an `ipv4_address` identifying the local interface.
     733                 : 
     734                 :     @par Example
     735                 :     @code
     736                 :     sock.set_option( socket_option::multicast_interface_v4(
     737                 :         ipv4_address( "192.168.1.1" ) ) );
     738                 :     @endcode
     739                 : */
     740                 : class BOOST_COROSIO_DECL multicast_interface_v4
     741                 : {
     742                 :     static constexpr std::size_t max_storage_ = 4;
     743                 :     alignas(4) unsigned char storage_[max_storage_]{};
     744                 : 
     745                 : public:
     746                 :     /// Construct with default values (INADDR_ANY).
     747                 :     multicast_interface_v4() noexcept = default;
     748                 : 
     749                 :     /** Construct with an interface address.
     750                 : 
     751                 :         @param iface The local interface address.
     752                 :     */
     753                 :     explicit multicast_interface_v4(ipv4_address iface) noexcept;
     754                 : 
     755                 :     /// Return the protocol level.
     756                 :     static int level() noexcept;
     757                 : 
     758                 :     /// Return the option name.
     759                 :     static int name() noexcept;
     760                 : 
     761                 :     /// Return a pointer to the underlying storage.
     762                 :     void* data() noexcept
     763                 :     {
     764                 :         return storage_;
     765                 :     }
     766                 : 
     767                 :     /// Return a pointer to the underlying storage.
     768                 :     void const* data() const noexcept
     769                 :     {
     770                 :         return storage_;
     771                 :     }
     772                 : 
     773                 :     /// Return the size of the underlying storage.
     774                 :     std::size_t size() const noexcept;
     775                 : 
     776                 :     /// No-op resize.
     777                 :     void resize(std::size_t) noexcept {}
     778                 : };
     779                 : 
     780                 : } // namespace boost::corosio::socket_option
     781                 : 
     782                 : #endif // BOOST_COROSIO_SOCKET_OPTION_HPP
        

Generated by: LCOV version 2.3