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
12
      : 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,
41
                                  const IoHandle::UdpSaveCmsgConfig& udp_save_cmsg_config,
42
                                  RecvMsgOutput& output) override;
43

            
44
  Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port,
45
                                   const IoHandle::UdpSaveCmsgConfig& udp_save_cmsg_config,
46
                                   RecvMsgOutput& output) override;
47
  Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) override;
48

            
49
  void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb,
50
                           Event::FileTriggerType trigger, uint32_t events) override;
51
  void enableFileEvents(uint32_t events) override;
52

            
53
private:
54
  void reEnableEventBasedOnIOResult(const Api::IoCallUint64Result& result, uint32_t event);
55

            
56
  // On Windows we use the MSG_PEEK on recv instead of peeking the socket
57
  // we drain the socket to memory. Subsequent read calls need to read
58
  // first from the class buffer and then go to the underlying socket.
59

            
60
  // Implement the peek logic of recv for readability purposes
61
  Api::IoCallUint64Result emulatePeek(void* buffer, size_t length);
62

            
63
  /**
64
   * Drain the socket into `peek_buffer_`.
65
   * @param length is the desired length of data drained into the `peek_buffer_`.
66
   * @return the actual length of data drained into the `peek_buffer_`.
67
   */
68
  Api::IoCallUint64Result drainToPeekBuffer(size_t length);
69

            
70
  // Useful functions to read from the peek buffer based on
71
  // the signatures of readv/read/recv OS socket functions.
72
  Api::IoCallUint64Result readFromPeekBuffer(void* buffer, size_t length);
73
  Api::IoCallUint64Result readFromPeekBuffer(Buffer::Instance& buffer, size_t length);
74
  Api::IoCallUint64Result readvFromPeekBuffer(uint64_t max_length, Buffer::RawSlice* slices,
75
                                              uint64_t num_slice);
76
  Api::IoCallUint64Result peekFromPeekBuffer(void* buffer, size_t length);
77

            
78
  // For windows mimic MSG_PEEK
79
  Buffer::OwnedImpl peek_buffer_;
80
};
81
} // namespace Network
82
} // namespace Envoy