LCOV - code coverage report
Current view: top level - envoy/network - socket.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 35 48 72.9 %
Date: 2024-01-05 06:35:25 Functions: 11 14 78.6 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <memory>
       4             : #include <string>
       5             : #include <vector>
       6             : 
       7             : #include "envoy/common/optref.h"
       8             : #include "envoy/common/platform.h"
       9             : #include "envoy/common/pure.h"
      10             : #include "envoy/config/core/v3/base.pb.h"
      11             : #include "envoy/network/address.h"
      12             : #include "envoy/network/io_handle.h"
      13             : #include "envoy/ssl/connection.h"
      14             : 
      15             : #include "absl/strings/string_view.h"
      16             : #include "absl/types/optional.h"
      17             : 
      18             : namespace Envoy {
      19             : namespace Network {
      20             : 
      21             : // SocketOptionName is an optional value that captures the setsockopt(2)
      22             : // arguments. The idea here is that if a socket option is not supported
      23             : // on a platform, we can make this the empty value, which allows us to
      24             : // avoid #ifdef proliferation.
      25             : struct SocketOptionName {
      26         507 :   SocketOptionName() = default;
      27             :   SocketOptionName(int level, int option, const std::string& name)
      28        2684 :       : value_(std::make_tuple(level, option, name)) {}
      29             : 
      30        1582 :   int level() const { return std::get<0>(value_.value()); }
      31        1582 :   int option() const { return std::get<1>(value_.value()); }
      32           0 :   const std::string& name() const { return std::get<2>(value_.value()); }
      33             : 
      34        4273 :   bool hasValue() const { return value_.has_value(); }
      35           0 :   bool operator==(const SocketOptionName& rhs) const { return value_ == rhs.value_; }
      36             : 
      37             : private:
      38             :   absl::optional<std::tuple<int, int, std::string>> value_;
      39             : };
      40             : 
      41             : // ENVOY_MAKE_SOCKET_OPTION_NAME is a helper macro to generate a
      42             : // SocketOptionName with a descriptive string name.
      43             : #define ENVOY_MAKE_SOCKET_OPTION_NAME(level, option)                                               \
      44        2684 :   ::Envoy::Network::SocketOptionName(level, option, #level "/" #option)
      45             : 
      46             : // Moved from source/common/network/socket_option_impl.h to avoid dependency loops.
      47             : #ifdef IP_TRANSPARENT
      48         227 : #define ENVOY_SOCKET_IP_TRANSPARENT ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_TRANSPARENT)
      49             : #else
      50             : #define ENVOY_SOCKET_IP_TRANSPARENT Network::SocketOptionName()
      51             : #endif
      52             : 
      53             : #ifdef IPV6_TRANSPARENT
      54         136 : #define ENVOY_SOCKET_IPV6_TRANSPARENT ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_TRANSPARENT)
      55             : #else
      56             : #define ENVOY_SOCKET_IPV6_TRANSPARENT Network::SocketOptionName()
      57             : #endif
      58             : 
      59             : #ifdef IP_FREEBIND
      60          91 : #define ENVOY_SOCKET_IP_FREEBIND ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_FREEBIND)
      61             : #else
      62             : #define ENVOY_SOCKET_IP_FREEBIND Network::SocketOptionName()
      63             : #endif
      64             : 
      65             : #ifdef IPV6_FREEBIND
      66          91 : #define ENVOY_SOCKET_IPV6_FREEBIND ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_FREEBIND)
      67             : #else
      68             : #define ENVOY_SOCKET_IPV6_FREEBIND Network::SocketOptionName()
      69             : #endif
      70             : 
      71             : #ifdef SO_KEEPALIVE
      72           0 : #define ENVOY_SOCKET_SO_KEEPALIVE ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_KEEPALIVE)
      73             : #else
      74             : #define ENVOY_SOCKET_SO_KEEPALIVE Network::SocketOptionName()
      75             : #endif
      76             : 
      77             : #ifdef SO_MARK
      78          25 : #define ENVOY_SOCKET_SO_MARK ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_MARK)
      79             : #else
      80             : #define ENVOY_SOCKET_SO_MARK Network::SocketOptionName()
      81             : #endif
      82             : 
      83             : #ifdef SO_NOSIGPIPE
      84             : #define ENVOY_SOCKET_SO_NOSIGPIPE ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_NOSIGPIPE)
      85             : #else
      86         293 : #define ENVOY_SOCKET_SO_NOSIGPIPE Network::SocketOptionName()
      87             : #endif
      88             : 
      89             : #ifdef SO_REUSEPORT
      90         134 : #define ENVOY_SOCKET_SO_REUSEPORT ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_REUSEPORT)
      91             : #else
      92             : #define ENVOY_SOCKET_SO_REUSEPORT Network::SocketOptionName()
      93             : #endif
      94             : 
      95             : #ifdef SO_ORIGINAL_DST
      96          99 : #define ENVOY_SOCKET_SO_ORIGINAL_DST ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_IP, SO_ORIGINAL_DST)
      97             : #else
      98             : #define ENVOY_SOCKET_SO_ORIGINAL_DST Network::SocketOptionName()
      99             : #endif
     100             : 
     101             : #ifdef IP6T_SO_ORIGINAL_DST
     102             : #define ENVOY_SOCKET_IP6T_SO_ORIGINAL_DST                                                          \
     103           8 :   ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_IPV6, IP6T_SO_ORIGINAL_DST)
     104             : #else
     105             : #define ENVOY_SOCKET_IP6T_SO_ORIGINAL_DST Network::SocketOptionName()
     106             : #endif
     107             : 
     108             : #ifdef UDP_GRO
     109           0 : #define ENVOY_SOCKET_UDP_GRO ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_UDP, UDP_GRO)
     110             : #else
     111             : #define ENVOY_SOCKET_UDP_GRO Network::SocketOptionName()
     112             : #endif
     113             : 
     114             : #ifdef TCP_KEEPCNT
     115           0 : #define ENVOY_SOCKET_TCP_KEEPCNT ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPCNT)
     116             : #else
     117             : #define ENVOY_SOCKET_TCP_KEEPCNT Network::SocketOptionName()
     118             : #endif
     119             : 
     120             : #ifdef TCP_KEEPIDLE
     121           0 : #define ENVOY_SOCKET_TCP_KEEPIDLE ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPIDLE)
     122             : #elif TCP_KEEPALIVE // macOS uses a different name from Linux for just this option.
     123             : #define ENVOY_SOCKET_TCP_KEEPIDLE ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPALIVE)
     124             : #else
     125             : #define ENVOY_SOCKET_TCP_KEEPIDLE Network::SocketOptionName()
     126             : #endif
     127             : 
     128             : #ifdef TCP_KEEPINTVL
     129           0 : #define ENVOY_SOCKET_TCP_KEEPINTVL ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPINTVL)
     130             : #else
     131             : #define ENVOY_SOCKET_TCP_KEEPINTVL Network::SocketOptionName()
     132             : #endif
     133             : 
     134             : #ifdef TCP_FASTOPEN
     135           1 : #define ENVOY_SOCKET_TCP_FASTOPEN ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_FASTOPEN)
     136             : #else
     137             : #define ENVOY_SOCKET_TCP_FASTOPEN Network::SocketOptionName()
     138             : #endif
     139             : 
     140             : // Linux uses IP_PKTINFO for both sending source address and receiving destination
     141             : // address.
     142             : // FreeBSD uses IP_RECVDSTADDR for receiving destination address and IP_SENDSRCADDR for sending
     143             : // source address. And these two have same value for convenience purpose.
     144             : #ifdef IP_RECVDSTADDR
     145             : #ifdef IP_SENDSRCADDR
     146             : static_assert(IP_RECVDSTADDR == IP_SENDSRCADDR);
     147             : #endif
     148             : #define ENVOY_IP_PKTINFO IP_RECVDSTADDR
     149             : #elif IP_PKTINFO
     150             : #define ENVOY_IP_PKTINFO IP_PKTINFO
     151             : #endif
     152             : 
     153         606 : #define ENVOY_SELF_IP_ADDR ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, ENVOY_IP_PKTINFO)
     154             : 
     155             : // Both Linux and FreeBSD use IPV6_RECVPKTINFO for both sending source address and
     156             : // receiving destination address.
     157         606 : #define ENVOY_SELF_IPV6_ADDR ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_RECVPKTINFO)
     158             : 
     159             : #ifdef SO_ATTACH_REUSEPORT_CBPF
     160             : #define ENVOY_ATTACH_REUSEPORT_CBPF                                                                \
     161           0 :   ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF)
     162             : #else
     163             : #define ENVOY_ATTACH_REUSEPORT_CBPF Network::SocketOptionName()
     164             : #endif
     165             : 
     166             : /**
     167             :  * Interface representing a single filter chain info.
     168             :  */
     169             : class FilterChainInfo {
     170             : public:
     171        1042 :   virtual ~FilterChainInfo() = default;
     172             : 
     173             :   /**
     174             :    * @return the name of this filter chain.
     175             :    */
     176             :   virtual absl::string_view name() const PURE;
     177             : };
     178             : 
     179             : class ListenerInfo;
     180             : 
     181             : using FilterChainInfoConstSharedPtr = std::shared_ptr<const FilterChainInfo>;
     182             : 
     183             : /**
     184             :  * Interfaces for providing a socket's various addresses. This is split into a getters interface
     185             :  * and a getters + setters interface. This is so that only the getters portion can be overridden
     186             :  * in certain cases.
     187             :  */
     188             : class ConnectionInfoProvider {
     189             : public:
     190        6485 :   virtual ~ConnectionInfoProvider() = default;
     191             : 
     192             :   /**
     193             :    * @return the local address of the socket.
     194             :    */
     195             :   virtual const Address::InstanceConstSharedPtr& localAddress() const PURE;
     196             : 
     197             :   /**
     198             :    * @return true if the local address has been restored to a value that is different from the
     199             :    *         address the socket was initially accepted at.
     200             :    */
     201             :   virtual bool localAddressRestored() const PURE;
     202             : 
     203             :   /**
     204             :    * @return the remote address of the socket.
     205             :    */
     206             :   virtual const Address::InstanceConstSharedPtr& remoteAddress() const PURE;
     207             : 
     208             :   /**
     209             :    * @return the direct remote address of the socket. This is the address of the directly
     210             :    *         connected peer, and cannot be modified by listener filters.
     211             :    */
     212             :   virtual const Address::InstanceConstSharedPtr& directRemoteAddress() const PURE;
     213             : 
     214             :   /**
     215             :    * @return SNI value for downstream host.
     216             :    */
     217             :   virtual absl::string_view requestedServerName() const PURE;
     218             : 
     219             :   /**
     220             :    * @return Connection ID of the downstream connection, or unset if not available.
     221             :    **/
     222             :   virtual absl::optional<uint64_t> connectionID() const PURE;
     223             : 
     224             :   /**
     225             :    * @return the name of the network interface used by local end of the connection, or unset if not
     226             :    *available.
     227             :    **/
     228             :   virtual absl::optional<absl::string_view> interfaceName() const PURE;
     229             : 
     230             :   /**
     231             :    * Dumps the state of the ConnectionInfoProvider to the given ostream.
     232             :    *
     233             :    * @param os the std::ostream to dump to.
     234             :    * @param indent_level the level of indentation.
     235             :    */
     236             :   virtual void dumpState(std::ostream& os, int indent_level) const PURE;
     237             : 
     238             :   /**
     239             :    * @return the downstream SSL connection. This will be nullptr if the downstream
     240             :    * connection does not use SSL.
     241             :    */
     242             :   virtual Ssl::ConnectionInfoConstSharedPtr sslConnection() const PURE;
     243             : 
     244             :   /**
     245             :    * @return ja3 fingerprint hash of the downstream connection, if any.
     246             :    */
     247             :   virtual absl::string_view ja3Hash() const PURE;
     248             : 
     249             :   /**
     250             :    * @return roundTripTime of the connection
     251             :    */
     252             :   virtual const absl::optional<std::chrono::milliseconds>& roundTripTime() const PURE;
     253             : 
     254             :   /**
     255             :    * @return the filter chain info provider backing this socket.
     256             :    */
     257             :   virtual OptRef<const FilterChainInfo> filterChainInfo() const PURE;
     258             : 
     259             :   /**
     260             :    * @return the listener info backing this socket.
     261             :    */
     262             :   virtual OptRef<const ListenerInfo> listenerInfo() const PURE;
     263             : };
     264             : 
     265             : class ConnectionInfoSetter : public ConnectionInfoProvider {
     266             : public:
     267             :   /**
     268             :    * Set the local address of the socket. On accepted sockets the local address defaults to the
     269             :    * one at which the connection was received at, which is the same as the listener's address, if
     270             :    * the listener is bound to a specific address.
     271             :    *
     272             :    * @param local_address the new local address.
     273             :    */
     274             :   virtual void setLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE;
     275             : 
     276             :   /**
     277             :    * Restores the local address of the socket. On accepted sockets the local address defaults to the
     278             :    * one at which the connection was received at, which is the same as the listener's address, if
     279             :    * the listener is bound to a specific address. Call this to restore the address to a value
     280             :    * different from the one the socket was initially accepted at. This should only be called when
     281             :    * restoring the original destination address of a connection redirected by iptables REDIRECT. The
     282             :    * caller is responsible for making sure the new address is actually different.
     283             :    *
     284             :    * @param local_address the new local address.
     285             :    */
     286             :   virtual void restoreLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE;
     287             : 
     288             :   /**
     289             :    * Set the remote address of the socket.
     290             :    */
     291             :   virtual void setRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE;
     292             : 
     293             :   /**
     294             :    * @param SNI value requested.
     295             :    */
     296             :   virtual void setRequestedServerName(const absl::string_view requested_server_name) PURE;
     297             : 
     298             :   /**
     299             :    * @param id Connection ID of the downstream connection.
     300             :    **/
     301             :   virtual void setConnectionID(uint64_t id) PURE;
     302             : 
     303             :   /**
     304             :    * @param enable whether to enable or disable setting interface name. While having an interface
     305             :    *               name might be helpful for debugging, it might come at a performance cost.
     306             :    */
     307             :   virtual void enableSettingInterfaceName(const bool enable) PURE;
     308             : 
     309             :   /**
     310             :    * @param interface_name the name of the network interface used by the local end of the
     311             :    *connection.
     312             :    **/
     313             :   virtual void maybeSetInterfaceName(IoHandle& io_handle) PURE;
     314             : 
     315             :   /**
     316             :    * @param connection_info sets the downstream ssl connection.
     317             :    */
     318             :   virtual void setSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) PURE;
     319             : 
     320             :   /**
     321             :    * @param JA3 fingerprint.
     322             :    */
     323             :   virtual void setJA3Hash(const absl::string_view ja3_hash) PURE;
     324             : 
     325             :   /**
     326             :    * @param  milliseconds of round trip time of previous connection
     327             :    */
     328             :   virtual void setRoundTripTime(std::chrono::milliseconds round_trip_time) PURE;
     329             : 
     330             :   /**
     331             :    * @param filter_chain_info the filter chain info provider backing this socket.
     332             :    */
     333             :   virtual void setFilterChainInfo(FilterChainInfoConstSharedPtr filter_chain_info) PURE;
     334             : 
     335             :   /**
     336             :    * @param listener_info the listener info provider backing this socket.
     337             :    */
     338             :   virtual void setListenerInfo(std::shared_ptr<const ListenerInfo> listener_info) PURE;
     339             : };
     340             : 
     341             : using ConnectionInfoSetterSharedPtr = std::shared_ptr<ConnectionInfoSetter>;
     342             : using ConnectionInfoProviderSharedPtr = std::shared_ptr<const ConnectionInfoProvider>;
     343             : 
     344             : /**
     345             :  * Base class for Sockets
     346             :  */
     347             : class Socket {
     348             : public:
     349        4435 :   virtual ~Socket() = default;
     350             : 
     351             :   /**
     352             :    * Type of sockets supported. See man 2 socket for more details
     353             :    */
     354             :   enum class Type { Stream, Datagram };
     355             : 
     356             :   /**
     357             :    * @return the connection info provider backing this socket.
     358             :    */
     359             :   virtual ConnectionInfoSetter& connectionInfoProvider() PURE;
     360             :   virtual const ConnectionInfoProvider& connectionInfoProvider() const PURE;
     361             :   virtual ConnectionInfoProviderSharedPtr connectionInfoProviderSharedPtr() const PURE;
     362             : 
     363             :   /**
     364             :    * @return IoHandle for the underlying connection
     365             :    */
     366             :   virtual IoHandle& ioHandle() PURE;
     367             : 
     368             :   /**
     369             :    * @return const IoHandle for the underlying connection
     370             :    */
     371             :   virtual const IoHandle& ioHandle() const PURE;
     372             : 
     373             :   /**
     374             :    * Used to duplicate the underlying file descriptor of the socket.
     375             :    * @return a pointer to the new Socket.
     376             :    */
     377             :   virtual std::unique_ptr<Socket> duplicate() PURE;
     378             : 
     379             :   /**
     380             :    * @return the type (stream or datagram) of the socket.
     381             :    */
     382             :   virtual Socket::Type socketType() const PURE;
     383             : 
     384             :   /**
     385             :    * @return the type (IP or pipe) of addresses used by the socket (subset of socket domain)
     386             :    */
     387             :   virtual Address::Type addressType() const PURE;
     388             : 
     389             :   /**
     390             :    * @return the IP version used by the socket if address type is IP, absl::nullopt otherwise
     391             :    */
     392             :   virtual absl::optional<Address::IpVersion> ipVersion() const PURE;
     393             : 
     394             :   /**
     395             :    * Close the underlying socket.
     396             :    */
     397             :   virtual void close() PURE;
     398             : 
     399             :   /**
     400             :    * Return true if close() hasn't been called.
     401             :    */
     402             :   virtual bool isOpen() const PURE;
     403             : 
     404             :   /**
     405             :    * Bind a socket to this address. The socket should have been created with a call to socket()
     406             :    * @param address address to bind the socket to.
     407             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     408             :    *   is successful, errno_ shouldn't be used.
     409             :    */
     410             :   virtual Api::SysCallIntResult bind(const Address::InstanceConstSharedPtr address) PURE;
     411             : 
     412             :   /**
     413             :    * Listen on bound socket.
     414             :    * @param backlog maximum number of pending connections for listener
     415             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     416             :    *   is successful, errno_ shouldn't be used.
     417             :    */
     418             :   virtual Api::SysCallIntResult listen(int backlog) PURE;
     419             : 
     420             :   /**
     421             :    * Connect a socket to this address. The socket should have been created with a call to socket()
     422             :    * on this object.
     423             :    * @param address remote address to connect to.
     424             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     425             :    *   is successful, errno_ shouldn't be used.
     426             :    */
     427             :   virtual Api::SysCallIntResult connect(const Address::InstanceConstSharedPtr address) PURE;
     428             : 
     429             :   /**
     430             :    * @see MSDN WSAIoctl. Controls the mode of a socket.
     431             :    */
     432             :   virtual Api::SysCallIntResult ioctl(unsigned long control_code, void* in_buffer,
     433             :                                       unsigned long in_buffer_len, void* out_buffer,
     434             :                                       unsigned long out_buffer_len,
     435             :                                       unsigned long* bytes_returned) PURE;
     436             : 
     437             :   /**
     438             :    * Propagates option to underlying socket (@see man 2 setsockopt)
     439             :    */
     440             :   virtual Api::SysCallIntResult setSocketOption(int level, int optname, const void* optval,
     441             :                                                 socklen_t optlen) PURE;
     442             : 
     443             :   /**
     444             :    * Retrieves option from underlying socket (@see man 2 getsockopt)
     445             :    */
     446             :   virtual Api::SysCallIntResult getSocketOption(int level, int optname, void* optval,
     447             :                                                 socklen_t* optlen) const PURE;
     448             : 
     449             :   /**
     450             :    * Toggle socket blocking state
     451             :    */
     452             :   virtual Api::SysCallIntResult setBlockingForTest(bool blocking) PURE;
     453             : 
     454             :   /**
     455             :    * Visitor class for setting socket options.
     456             :    */
     457             :   class Option {
     458             :   public:
     459        3359 :     virtual ~Option() = default;
     460             : 
     461             :     /**
     462             :      * @param socket the socket on which to apply options.
     463             :      * @param state the current state of the socket. Significant for options that can only be
     464             :      *        set for some particular state of the socket.
     465             :      * @return true if succeeded, false otherwise.
     466             :      */
     467             :     virtual bool setOption(Socket& socket,
     468             :                            envoy::config::core::v3::SocketOption::SocketState state) const PURE;
     469             : 
     470             :     /**
     471             :      * @param vector of bytes to which the option should append hash key data that will be used
     472             :      *        to separate connections based on the option. Any data already in the key vector must
     473             :      *        not be modified.
     474             :      */
     475             :     virtual void hashKey(std::vector<uint8_t>& key) const PURE;
     476             : 
     477             :     /**
     478             :      * Contains details about what this option applies to a socket.
     479             :      */
     480             :     struct Details {
     481             :       SocketOptionName name_;
     482             :       std::string value_; ///< Binary string representation of an option's value.
     483             : 
     484           0 :       bool operator==(const Details& other) const {
     485           0 :         return name_ == other.name_ && value_ == other.value_;
     486           0 :       }
     487             :     };
     488             : 
     489             :     /**
     490             :      * @param socket The socket for which we want to know the options that would be applied.
     491             :      * @param state The state at which we would apply the options.
     492             :      * @return What we would apply to the socket at the provided state. Empty if we'd apply nothing.
     493             :      */
     494             :     virtual absl::optional<Details>
     495             :     getOptionDetails(const Socket& socket,
     496             :                      envoy::config::core::v3::SocketOption::SocketState state) const PURE;
     497             : 
     498             :     /**
     499             :      * Whether the socket implementation is supported. Real implementations should typically return
     500             :      * true. Placeholder implementations may indicate such by returning false. Note this does NOT
     501             :      * inherently prevent an option from being applied if it's passed to socket/connection
     502             :      * interfaces.
     503             :      * @return Whether this is a supported socket option.
     504             :      */
     505             :     virtual bool isSupported() const PURE;
     506             :   };
     507             : 
     508             :   using OptionConstPtr = std::unique_ptr<const Option>;
     509             :   using OptionConstSharedPtr = std::shared_ptr<const Option>;
     510             :   using Options = std::vector<OptionConstSharedPtr>;
     511             :   using OptionsSharedPtr = std::shared_ptr<Options>;
     512             : 
     513        2317 :   static OptionsSharedPtr& appendOptions(OptionsSharedPtr& to, const OptionsSharedPtr& from) {
     514        2317 :     to->insert(to->end(), from->begin(), from->end());
     515        2317 :     return to;
     516        2317 :   }
     517             : 
     518             :   static bool applyOptions(const OptionsSharedPtr& options, Socket& socket,
     519        3574 :                            envoy::config::core::v3::SocketOption::SocketState state) {
     520        3574 :     if (options == nullptr) {
     521        1688 :       return true;
     522        1688 :     }
     523        3008 :     for (const auto& option : *options) {
     524        2737 :       if (!option->setOption(socket, state)) {
     525           0 :         return false;
     526           0 :       }
     527        2737 :     }
     528        1886 :     return true;
     529        1886 :   }
     530             : 
     531             :   /**
     532             :    * Add a socket option visitor for later retrieval with options().
     533             :    */
     534             :   virtual void addOption(const OptionConstSharedPtr&) PURE;
     535             : 
     536             :   /**
     537             :    * Add socket option visitors for later retrieval with options().
     538             :    */
     539             :   virtual void addOptions(const OptionsSharedPtr&) PURE;
     540             : 
     541             :   /**
     542             :    * @return the socket options stored earlier with addOption() and addOptions() calls, if any.
     543             :    */
     544             :   virtual const OptionsSharedPtr& options() const PURE;
     545             : };
     546             : 
     547             : using SocketPtr = std::unique_ptr<Socket>;
     548             : using SocketSharedPtr = std::shared_ptr<Socket>;
     549             : using SocketOptRef = absl::optional<std::reference_wrapper<Socket>>;
     550             : 
     551             : } // namespace Network
     552             : } // namespace Envoy

Generated by: LCOV version 1.15