Line data Source code
1 : #pragma once
2 :
3 : #include <chrono>
4 : #include <memory>
5 :
6 : #include "envoy/api/io_error.h"
7 : #include "envoy/api/os_sys_calls_common.h"
8 : #include "envoy/common/platform.h"
9 : #include "envoy/common/pure.h"
10 : #include "envoy/event/file_event.h"
11 : #include "envoy/network/address.h"
12 :
13 : #include "absl/container/fixed_array.h"
14 : #include "absl/types/optional.h"
15 :
16 : namespace Envoy {
17 : namespace Buffer {
18 : struct RawSlice;
19 : class Instance;
20 : } // namespace Buffer
21 :
22 : namespace Event {
23 : class Dispatcher;
24 : } // namespace Event
25 :
26 : using RawSliceArrays = absl::FixedArray<absl::FixedArray<Buffer::RawSlice>>;
27 :
28 : namespace Network {
29 :
30 : struct Win32RedirectRecords {
31 : // The size of the buffer is selected based on:
32 : // https://docs.microsoft.com/en-us/windows-hardware/drivers/network/sio-query-wfp-connection-redirect-records
33 : uint8_t buf_[2048];
34 : unsigned long buf_size_;
35 : };
36 :
37 : /**
38 : * IoHandle: an abstract interface for all I/O operations
39 : */
40 : class IoHandle {
41 : public:
42 8019 : virtual ~IoHandle() = default;
43 :
44 : /**
45 : * NOTE: Must NOT be used for new use cases!
46 : *
47 : * This is most probably not the function you are looking for. IoHandle has wrappers for most of
48 : * the POSIX socket api functions so there should be no need to interact with the internal fd by
49 : * means of syscalls. Moreover, depending on the IoHandle implementation, the fd might not be an
50 : * underlying OS file descriptor. If any api function is missing, a wrapper for it should be added
51 : * to the IoHandle interface.
52 : *
53 : * Return data associated with IoHandle. It is not necessarily a file descriptor.
54 : */
55 : virtual os_fd_t fdDoNotUse() const PURE;
56 :
57 : /**
58 : * Clean up IoHandle resources
59 : */
60 : virtual Api::IoCallUint64Result close() PURE;
61 :
62 : /**
63 : * Return true if close() hasn't been called.
64 : */
65 : virtual bool isOpen() const PURE;
66 :
67 : /**
68 : * Read data into given slices.
69 : * @param max_length supplies the maximum length to read.
70 : * @param slices points to the output location.
71 : * @param num_slice indicates the number of slices |slices| contains.
72 : * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
73 : * err_ = nullptr and rc_ = the bytes read for success.
74 : */
75 : virtual Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices,
76 : uint64_t num_slice) PURE;
77 :
78 : /**
79 : * Read from a io handle directly into buffer.
80 : * @param buffer supplies the buffer to read into.
81 : * @param max_length supplies the maximum length to read. A value of absl::nullopt means to read
82 : * as much data as possible, within the constraints of available buffer size.
83 : * @return a IoCallUint64Result with err_ = nullptr and rc_ = the number of bytes
84 : * read if successful, or err_ = some IoError for failure. If call failed, rc_ shouldn't be used.
85 : */
86 : virtual Api::IoCallUint64Result read(Buffer::Instance& buffer,
87 : absl::optional<uint64_t> max_length) PURE;
88 :
89 : /**
90 : * Write the data in slices out.
91 : * @param slices points to the location of data to be written.
92 : * @param num_slice indicates number of slices |slices| contains.
93 : * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
94 : * err_ = nullptr and rc_ = the bytes written for success.
95 : */
96 : virtual Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) PURE;
97 :
98 : /**
99 : * Write the contents of the buffer out to a file descriptor. Bytes that were successfully written
100 : * are drained from the buffer.
101 : * @param buffer supplies the buffer to write from.
102 : * @return a IoCallUint64Result with err_ = nullptr and rc_ = if successful, the number of bytes
103 : * written and drained from the buffer, or err_ = some IoError for failure. If call failed, rc_
104 : * shouldn't be used.
105 : */
106 : virtual Api::IoCallUint64Result write(Buffer::Instance& buffer) PURE;
107 :
108 : /**
109 : * Send a message to the address.
110 : * @param slices points to the location of data to be sent.
111 : * @param num_slice indicates number of slices |slices| contains.
112 : * @param flags flags to pass to the underlying sendmsg function (see man 2 sendmsg).
113 : * @param self_ip is the source address whose port should be ignored. Nullptr
114 : * if caller wants kernel to select source address.
115 : * @param peer_address is the destination address.
116 : * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
117 : * err_ = nullptr and rc_ = the bytes written for success.
118 : */
119 : virtual Api::IoCallUint64Result sendmsg(const Buffer::RawSlice* slices, uint64_t num_slice,
120 : int flags, const Address::Ip* self_ip,
121 : const Address::Instance& peer_address) PURE;
122 :
123 : struct RecvMsgPerPacketInfo {
124 : // The destination address from transport header.
125 : Address::InstanceConstSharedPtr local_address_;
126 : // The source address from transport header.
127 : Address::InstanceConstSharedPtr peer_address_;
128 : // The payload length of this packet.
129 : unsigned int msg_len_{0};
130 : // The gso_size, if specified in the transport header
131 : unsigned int gso_size_{0};
132 : // If true indicates a successful syscall, but the packet was dropped due to truncation. We do
133 : // not support receiving truncated packets.
134 : bool truncated_and_dropped_{false};
135 : };
136 :
137 : /**
138 : * The output parameter type for recvmsg and recvmmsg.
139 : */
140 : struct RecvMsgOutput {
141 : /*
142 : * @param num_packets_per_call is the max number of packets allowed per
143 : * recvmmsg call. For recvmsg call, any value larger than 0 is allowed, but
144 : * only one packet will be returned.
145 : * @param dropped_packets points to a variable to store how many packets are
146 : * dropped so far. If nullptr, recvmsg() won't try to get this information
147 : * from transport header.
148 : */
149 : RecvMsgOutput(size_t num_packets_per_call, uint32_t* dropped_packets)
150 504 : : dropped_packets_(dropped_packets), msg_(num_packets_per_call) {}
151 :
152 : // If not nullptr, its value is the total number of packets dropped. recvmsg() will update it
153 : // when more packets are dropped.
154 : uint32_t* dropped_packets_;
155 :
156 : // Packet headers for each received packet. It's populated according to packet receive order.
157 : // Only the first entry is used to return per packet information by recvmsg.
158 : absl::FixedArray<RecvMsgPerPacketInfo> msg_;
159 : };
160 :
161 : /**
162 : * Receive a message into given slices, output overflow, source/destination
163 : * addresses via passed-in parameters upon success.
164 : * @param slices points to the location of receiving buffer.
165 : * @param num_slice indicates number of slices |slices| contains.
166 : * @param self_port the port this handle is assigned to. This is used to populate
167 : * local_address because local port can't be retrieved from control message.
168 : * @param output modified upon each call to return fields requested in it.
169 : * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
170 : * err_ = nullptr and rc_ = the bytes received for success.
171 : */
172 : virtual Api::IoCallUint64Result recvmsg(Buffer::RawSlice* slices, const uint64_t num_slice,
173 : uint32_t self_port, RecvMsgOutput& output) PURE;
174 :
175 : /**
176 : * If the platform supports, receive multiple messages into given slices, output overflow,
177 : * source/destination addresses per message via passed-in parameters upon success.
178 : * @param slices are the receive buffers for the messages. Each message
179 : * received are stored in an individual entry of |slices|.
180 : * @param self_port is the same as the one in recvmsg().
181 : * @param output is modified upon each call and each message received.
182 : */
183 : virtual Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port,
184 : RecvMsgOutput& output) PURE;
185 :
186 : /**
187 : * Read data into given buffer for connected handles
188 : * @param buffer buffer to read the data into
189 : * @param length buffer length
190 : * @param flags flags to pass to the underlying recv function (see man 2 recv)
191 : */
192 : virtual Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) PURE;
193 :
194 : /**
195 : * return true if the platform supports recvmmsg() and sendmmsg().
196 : */
197 : virtual bool supportsMmsg() const PURE;
198 :
199 : /**
200 : * return true if the platform supports udp_gro
201 : */
202 : virtual bool supportsUdpGro() const PURE;
203 :
204 : /**
205 : * Bind to address. The handle should have been created with a call to socket()
206 : * @param address address to bind to.
207 : * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
208 : * is successful, errno_ shouldn't be used.
209 : */
210 : virtual Api::SysCallIntResult bind(Address::InstanceConstSharedPtr address) PURE;
211 :
212 : /**
213 : * Listen on bound handle.
214 : * @param backlog maximum number of pending connections for listener
215 : * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
216 : * is successful, errno_ shouldn't be used.
217 : */
218 : virtual Api::SysCallIntResult listen(int backlog) PURE;
219 :
220 : /**
221 : * Accept on listening handle
222 : * @param addr remote address to be returned
223 : * @param addrlen remote address length
224 : * @return accepted IoHandlePtr
225 : */
226 : virtual std::unique_ptr<IoHandle> accept(struct sockaddr* addr, socklen_t* addrlen) PURE;
227 :
228 : /**
229 : * Connect to address. The handle should have been created with a call to socket()
230 : * on this object.
231 : * @param address remote address to connect to.
232 : * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
233 : * is successful, errno_ shouldn't be used.
234 : */
235 : virtual Api::SysCallIntResult connect(Address::InstanceConstSharedPtr address) PURE;
236 :
237 : /**
238 : * Set option (see man 2 setsockopt)
239 : */
240 : virtual Api::SysCallIntResult setOption(int level, int optname, const void* optval,
241 : socklen_t optlen) PURE;
242 :
243 : /**
244 : * Get option (see man 2 getsockopt)
245 : */
246 : virtual Api::SysCallIntResult getOption(int level, int optname, void* optval,
247 : socklen_t* optlen) PURE;
248 :
249 : /**
250 : * @see MSDN WSAIoctl. Controls the mode of a socket.
251 : */
252 : virtual Api::SysCallIntResult ioctl(unsigned long control_code, void* in_buffer,
253 : unsigned long in_buffer_len, void* out_buffer,
254 : unsigned long out_buffer_len,
255 : unsigned long* bytes_returned) PURE;
256 : /**
257 : * Toggle blocking behavior
258 : * @param blocking flag to set/unset blocking state
259 : * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
260 : * is successful, errno_ shouldn't be used.
261 : */
262 : virtual Api::SysCallIntResult setBlocking(bool blocking) PURE;
263 :
264 : /**
265 : * @return the domain used by underlying socket (see man 2 socket)
266 : */
267 : virtual absl::optional<int> domain() PURE;
268 :
269 : /**
270 : * Get local address (ip:port pair)
271 : * @return local address as @ref Address::InstanceConstSharedPtr
272 : */
273 : virtual Address::InstanceConstSharedPtr localAddress() PURE;
274 :
275 : /**
276 : * Get peer's address (ip:port pair)
277 : * @return peer's address as @ref Address::InstanceConstSharedPtr
278 : */
279 : virtual Address::InstanceConstSharedPtr peerAddress() PURE;
280 :
281 : /**
282 : * Duplicates the handle. This is intended to be used only on listener sockets. (see man dup)
283 : * @return a pointer to the new handle.
284 : */
285 : virtual std::unique_ptr<IoHandle> duplicate() PURE;
286 :
287 : /**
288 : * Initializes the internal file event that will signal when the io handle is readable, writable
289 : * or closed. Each handle is allowed to have only a single file event. The internal file event is
290 : * managed by the handle and it is turned on and off when the socket would block. Calls to this
291 : * function must be paired with calls to reset the file event or close the socket.
292 : * @param dispatcher dispatcher to be used to allocate the file event.
293 : * @param cb supplies the callback to fire when the handle is ready.
294 : * @param trigger specifies whether to edge or level trigger.
295 : * @param events supplies a logical OR of @ref Event::FileReadyType events that the file event
296 : * should initially listen on.
297 : */
298 : virtual void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb,
299 : Event::FileTriggerType trigger, uint32_t events) PURE;
300 :
301 : /**
302 : * Activates file events for the current underlying fd.
303 : * @param events events that will be activated.
304 : */
305 : virtual void activateFileEvents(uint32_t events) PURE;
306 :
307 : /**
308 : * Enables file events for the current underlying fd.
309 : * @param events events that will be enabled.
310 : */
311 : virtual void enableFileEvents(uint32_t events) PURE;
312 :
313 : /**
314 : * Resets the file event.
315 : */
316 : virtual void resetFileEvents() PURE;
317 :
318 : /**
319 : * Shut down part of a full-duplex connection (see man 2 shutdown)
320 : */
321 : virtual Api::SysCallIntResult shutdown(int how) PURE;
322 :
323 : /**
324 : * @return absl::optional<std::chrono::milliseconds> An optional of the most recent round-trip
325 : * time of the connection. If the platform does not support this, then an empty optional is
326 : * returned.
327 : */
328 : virtual absl::optional<std::chrono::milliseconds> lastRoundTripTime() PURE;
329 :
330 : /**
331 : * @return the current congestion window in bytes, or unset if not available or not
332 : * congestion-controlled.
333 : * @note some congestion controller's cwnd is measured in number of packets, in that case the
334 : * return value is cwnd(in packets) times the connection's MSS.
335 : */
336 : virtual absl::optional<uint64_t> congestionWindowInBytes() const PURE;
337 :
338 : /**
339 : * @return the interface name for the socket, if the OS supports it. Otherwise, absl::nullopt.
340 : */
341 : virtual absl::optional<std::string> interfaceName() PURE;
342 : };
343 :
344 : using IoHandlePtr = std::unique_ptr<IoHandle>;
345 :
346 : } // namespace Network
347 : } // namespace Envoy
|