Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/api/io_error.h" 4 : #include "envoy/api/os_sys_calls.h" 5 : #include "envoy/common/platform.h" 6 : #include "envoy/event/dispatcher.h" 7 : #include "envoy/network/io_handle.h" 8 : 9 : #include "source/common/common/logger.h" 10 : #include "source/common/network/io_socket_error_impl.h" 11 : #include "source/common/network/io_socket_handle_base_impl.h" 12 : #include "source/common/runtime/runtime_features.h" 13 : 14 : namespace Envoy { 15 : namespace Network { 16 : 17 : /** 18 : * IoHandle derivative for sockets. 19 : */ 20 : class IoSocketHandleImpl : public IoSocketHandleBaseImpl { 21 : public: 22 : explicit IoSocketHandleImpl(os_fd_t fd = INVALID_SOCKET, bool socket_v6only = false, 23 : absl::optional<int> domain = absl::nullopt) 24 : : IoSocketHandleBaseImpl(fd, socket_v6only, domain), 25 : udp_read_normalize_addresses_( 26 7792 : Runtime::runtimeFeatureEnabled("envoy.restart_features.udp_read_normalize_addresses")) { 27 7792 : } 28 : 29 : // Close underlying socket if close() hasn't been call yet. 30 : ~IoSocketHandleImpl() override; 31 : 32 : Api::IoCallUint64Result close() override; 33 : 34 : Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices, 35 : uint64_t num_slice) override; 36 : Api::IoCallUint64Result read(Buffer::Instance& buffer, 37 : absl::optional<uint64_t> max_length) override; 38 : 39 : Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) override; 40 : 41 : Api::IoCallUint64Result write(Buffer::Instance& buffer) override; 42 : 43 : Api::IoCallUint64Result sendmsg(const Buffer::RawSlice* slices, uint64_t num_slice, int flags, 44 : const Address::Ip* self_ip, 45 : const Address::Instance& peer_address) override; 46 : 47 : Api::IoCallUint64Result recvmsg(Buffer::RawSlice* slices, const uint64_t num_slice, 48 : uint32_t self_port, RecvMsgOutput& output) override; 49 : 50 : Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port, 51 : RecvMsgOutput& output) override; 52 : Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) override; 53 : 54 : Api::SysCallIntResult bind(Address::InstanceConstSharedPtr address) override; 55 : Api::SysCallIntResult listen(int backlog) override; 56 : IoHandlePtr accept(struct sockaddr* addr, socklen_t* addrlen) override; 57 : Api::SysCallIntResult connect(Address::InstanceConstSharedPtr address) override; 58 : void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb, 59 : Event::FileTriggerType trigger, uint32_t events) override; 60 : 61 : IoHandlePtr duplicate() override; 62 : 63 : void activateFileEvents(uint32_t events) override; 64 : void enableFileEvents(uint32_t events) override; 65 : 66 698 : void resetFileEvents() override { file_event_.reset(); } 67 : 68 : Api::SysCallIntResult shutdown(int how) override; 69 : 70 : protected: 71 : // Converts a SysCallSizeResult to IoCallUint64Result. 72 : template <typename T> 73 12829 : Api::IoCallUint64Result sysCallResultToIoCallResult(const Api::SysCallResult<T>& result) { 74 12829 : if (result.return_value_ >= 0) { 75 : // Return nullptr as IoError upon success. 76 11168 : return Api::IoCallUint64Result(result.return_value_, Api::IoError::none()); 77 11168 : } 78 1661 : if (result.errno_ == SOCKET_ERROR_INVAL) { 79 0 : ENVOY_LOG(error, "Invalid argument passed in."); 80 0 : } 81 1661 : return Api::IoCallUint64Result( 82 1661 : /*rc=*/0, (result.errno_ == SOCKET_ERROR_AGAIN 83 : // EAGAIN is frequent enough that its memory allocation should be avoided. 84 1661 : ? IoSocketError::getIoSocketEagainError() 85 1661 : : IoSocketError::create(result.errno_))); 86 12829 : } 87 : 88 : Event::FileEventPtr file_event_{nullptr}; 89 : 90 : // The minimum cmsg buffer size to filled in destination address, packets dropped and gso 91 : // size when receiving a packet. It is possible for a received packet to contain both IPv4 92 : // and IPV6 addresses. 93 : const size_t cmsg_space_{CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct in_pktinfo)) + 94 : CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(uint16_t))}; 95 : 96 : const bool udp_read_normalize_addresses_; 97 : }; 98 : } // namespace Network 99 : } // namespace Envoy