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/buffer/buffer_impl.h" 10 : #include "source/common/common/logger.h" 11 : #include "source/common/network/io_socket_error_impl.h" 12 : #include "source/common/network/io_socket_handle_impl.h" 13 : 14 : namespace Envoy { 15 : namespace Network { 16 : 17 : /** 18 : * IoHandle derivative for win32 emulated edge sockets. 19 : */ 20 : class Win32SocketHandleImpl : public IoSocketHandleImpl { 21 : public: 22 : explicit Win32SocketHandleImpl(os_fd_t fd = INVALID_SOCKET, bool socket_v6only = false, 23 : absl::optional<int> domain = absl::nullopt) 24 0 : : IoSocketHandleImpl(fd, socket_v6only, domain) {} 25 : 26 : Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices, 27 : uint64_t num_slice) override; 28 : Api::IoCallUint64Result read(Buffer::Instance& buffer, 29 : absl::optional<uint64_t> max_length) override; 30 : 31 : Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) override; 32 : 33 : Api::IoCallUint64Result write(Buffer::Instance& buffer) override; 34 : 35 : Api::IoCallUint64Result sendmsg(const Buffer::RawSlice* slices, uint64_t num_slice, int flags, 36 : const Address::Ip* self_ip, 37 : const Address::Instance& peer_address) override; 38 : 39 : Api::IoCallUint64Result recvmsg(Buffer::RawSlice* slices, const uint64_t num_slice, 40 : uint32_t self_port, RecvMsgOutput& output) override; 41 : 42 : Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port, 43 : RecvMsgOutput& output) override; 44 : Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) override; 45 : 46 : void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb, 47 : Event::FileTriggerType trigger, uint32_t events) override; 48 : void enableFileEvents(uint32_t events) override; 49 : 50 : private: 51 : void reEnableEventBasedOnIOResult(const Api::IoCallUint64Result& result, uint32_t event); 52 : 53 : // On Windows we use the MSG_PEEK on recv instead of peeking the socket 54 : // we drain the socket to memory. Subsequent read calls need to read 55 : // first from the class buffer and then go to the underlying socket. 56 : 57 : // Implement the peek logic of recv for readability purposes 58 : Api::IoCallUint64Result emulatePeek(void* buffer, size_t length); 59 : 60 : /** 61 : * Drain the socket into `peek_buffer_`. 62 : * @param length is the desired length of data drained into the `peek_buffer_`. 63 : * @return the actual length of data drained into the `peek_buffer_`. 64 : */ 65 : Api::IoCallUint64Result drainToPeekBuffer(size_t length); 66 : 67 : // Useful functions to read from the peek buffer based on 68 : // the signatures of readv/read/recv OS socket functions. 69 : Api::IoCallUint64Result readFromPeekBuffer(void* buffer, size_t length); 70 : Api::IoCallUint64Result readFromPeekBuffer(Buffer::Instance& buffer, size_t length); 71 : Api::IoCallUint64Result readvFromPeekBuffer(uint64_t max_length, Buffer::RawSlice* slices, 72 : uint64_t num_slice); 73 : Api::IoCallUint64Result peekFromPeekBuffer(void* buffer, size_t length); 74 : 75 : // For windows mimic MSG_PEEK 76 : Buffer::OwnedImpl peek_buffer_; 77 : }; 78 : } // namespace Network 79 : } // namespace Envoy