Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/common/platform.h" 4 : #include "envoy/config/core/v3/base.pb.h" 5 : #include "envoy/network/listen_socket.h" 6 : 7 : #include "source/common/common/logger.h" 8 : #include "source/common/network/socket_option_impl.h" 9 : 10 : #include "absl/types/optional.h" 11 : 12 : namespace Envoy { 13 : namespace Network { 14 : 15 : class AddrFamilyAwareSocketOptionImpl : public Socket::Option, 16 : Logger::Loggable<Logger::Id::connection> { 17 : public: 18 : AddrFamilyAwareSocketOptionImpl(envoy::config::core::v3::SocketOption::SocketState in_state, 19 : SocketOptionName ipv4_optname, SocketOptionName ipv6_optname, 20 : int value) 21 825 : : AddrFamilyAwareSocketOptionImpl(in_state, ipv4_optname, value, ipv6_optname, value) {} 22 : AddrFamilyAwareSocketOptionImpl(envoy::config::core::v3::SocketOption::SocketState in_state, 23 : SocketOptionName ipv4_optname, int ipv4_value, 24 : SocketOptionName ipv6_optname, int ipv6_value) 25 : : ipv4_option_(std::make_unique<SocketOptionImpl>(in_state, ipv4_optname, ipv4_value)), 26 825 : ipv6_option_(std::make_unique<SocketOptionImpl>(in_state, ipv6_optname, ipv6_value)) {} 27 : AddrFamilyAwareSocketOptionImpl(envoy::config::core::v3::SocketOption::SocketState in_state, 28 : SocketOptionName ipv4_optname, absl::string_view ipv4_value, 29 : SocketOptionName ipv6_optname, absl::string_view ipv6_value) 30 : : ipv4_option_(std::make_unique<SocketOptionImpl>(in_state, ipv4_optname, ipv4_value)), 31 0 : ipv6_option_(std::make_unique<SocketOptionImpl>(in_state, ipv6_optname, ipv6_value)) {} 32 : AddrFamilyAwareSocketOptionImpl(Socket::OptionConstPtr&& ipv4_option, 33 : Socket::OptionConstPtr&& ipv6_option) 34 0 : : ipv4_option_(std::move(ipv4_option)), ipv6_option_(std::move(ipv6_option)) {} 35 : 36 : // Socket::Option 37 : bool setOption(Socket& socket, 38 : envoy::config::core::v3::SocketOption::SocketState state) const override; 39 0 : void hashKey(std::vector<uint8_t>& hash_key) const override { 40 0 : // Add both sub-options to the hash. 41 0 : ipv4_option_->hashKey(hash_key); 42 0 : ipv6_option_->hashKey(hash_key); 43 0 : } 44 : absl::optional<Details> 45 : getOptionDetails(const Socket& socket, 46 : envoy::config::core::v3::SocketOption::SocketState state) const override; 47 0 : bool isSupported() const override { return true; } 48 : 49 : /** 50 : * Set a socket option that applies at both IPv4 and IPv6 socket levels. When the underlying FD 51 : * is IPv6, this function will attempt to set at IPv6 unless the platform only supports the 52 : * option at the IPv4 level. 53 : * @param socket. 54 : * @param ipv4_optname SocketOptionName for IPv4 level. Set to empty if not supported on 55 : * platform. 56 : * @param ipv6_optname SocketOptionName for IPv6 level. Set to empty if not supported on 57 : * platform. 58 : * @param optval as per setsockopt(2). 59 : * @param optlen as per setsockopt(2). 60 : * @return int as per setsockopt(2). `ENOTSUP` is returned if the option is not supported on the 61 : * platform for fd after the above option level fallback semantics are taken into account or the 62 : * socket is non-IP. 63 : */ 64 : static bool setIpSocketOption(Socket& socket, 65 : envoy::config::core::v3::SocketOption::SocketState state, 66 : const Socket::Option& ipv4_option, 67 : const Socket::Option& ipv6_option); 68 : 69 : private: 70 : const Socket::OptionConstPtr ipv4_option_; 71 : const Socket::OptionConstPtr ipv6_option_; 72 : }; 73 : 74 : } // namespace Network 75 : } // namespace Envoy