Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/api/os_sys_calls.h" 4 : #include "envoy/common/platform.h" 5 : #include "envoy/config/core/v3/base.pb.h" 6 : #include "envoy/network/listen_socket.h" 7 : 8 : #include "source/common/common/assert.h" 9 : #include "source/common/common/logger.h" 10 : 11 : namespace Envoy { 12 : namespace Network { 13 : 14 : class SocketOptionImpl : public Socket::Option, Logger::Loggable<Logger::Id::connection> { 15 : public: 16 : SocketOptionImpl(envoy::config::core::v3::SocketOption::SocketState in_state, 17 : Network::SocketOptionName optname, 18 : int value, // Yup, int. See setsockopt(2). 19 : absl::optional<Network::Socket::Type> socket_type = absl::nullopt) 20 : : SocketOptionImpl(in_state, optname, 21 : absl::string_view(reinterpret_cast<char*>(&value), sizeof(value)), 22 2416 : socket_type) {} 23 : 24 : SocketOptionImpl(envoy::config::core::v3::SocketOption::SocketState in_state, 25 : Network::SocketOptionName optname, absl::string_view value, 26 : absl::optional<Network::Socket::Type> socket_type = absl::nullopt) 27 : : in_state_(in_state), optname_(optname), value_(value.begin(), value.end()), 28 2470 : socket_type_(socket_type) { 29 2470 : ASSERT(reinterpret_cast<uintptr_t>(value_.data()) % alignof(void*) == 0); 30 2470 : } 31 : 32 : // Socket::Option 33 : bool setOption(Socket& socket, 34 : envoy::config::core::v3::SocketOption::SocketState state) const override; 35 : void hashKey(std::vector<uint8_t>& hash_key) const override; 36 : absl::optional<Details> 37 : getOptionDetails(const Socket& socket, 38 : envoy::config::core::v3::SocketOption::SocketState state) const override; 39 : bool isSupported() const override; 40 : 41 : /** 42 : * Set the option on the given socket. 43 : * @param socket the socket on which to apply the option. 44 : * @param optname the option name. 45 : * @param value the option value. 46 : * @param size the option value size. 47 : * @return a Api::SysCallIntResult with rc_ = 0 for success and rc = -1 for failure. If the call 48 : * is successful, errno_ shouldn't be used. 49 : */ 50 : static Api::SysCallIntResult setSocketOption(Socket& socket, 51 : const Network::SocketOptionName& optname, 52 : const void* value, size_t size); 53 : 54 : private: 55 : const envoy::config::core::v3::SocketOption::SocketState in_state_; 56 : const Network::SocketOptionName optname_; 57 : // This has to be a std::vector<uint8_t> but not std::string because std::string might inline 58 : // the buffer so its data() is not aligned in to alignof(void*). 59 : const std::vector<uint8_t> value_; 60 : // If present, specifies the socket type that this option applies to. Attempting to set this 61 : // option on a socket of a different type will be a no-op. 62 : absl::optional<Network::Socket::Type> socket_type_; 63 : }; 64 : 65 : } // namespace Network 66 : } // namespace Envoy