1
#pragma once
2

            
3
#include <sys/resource.h>
4
#include <sys/stat.h>
5

            
6
#include <chrono>
7
#include <memory>
8
#include <string>
9
#include <vector>
10

            
11
#include "envoy/api/os_sys_calls_common.h"
12
#include "envoy/common/platform.h"
13
#include "envoy/common/pure.h"
14
#include "envoy/network/address.h"
15

            
16
namespace Envoy {
17
namespace Api {
18

            
19
struct EnvoyTcpInfo {
20
  std::chrono::microseconds tcpi_rtt;
21
  // Congestion window, in bytes. Note that posix's TCP_INFO socket option returns cwnd in packets,
22
  // we multiply it by MSS to get bytes.
23
  uint32_t tcpi_snd_cwnd = 0;
24
};
25

            
26
// Small struct to avoid exposing ifaddrs -- which is not defined in all platforms -- to the
27
// codebase.
28
struct InterfaceAddress {
29
  InterfaceAddress(absl::string_view interface_name, unsigned int interface_flags,
30
                   Envoy::Network::Address::InstanceConstSharedPtr interface_addr)
31
53384
      : interface_name_(interface_name), interface_flags_(interface_flags),
32
53384
        interface_addr_(interface_addr) {}
33

            
34
  std::string interface_name_;
35
  unsigned int interface_flags_;
36
  Envoy::Network::Address::InstanceConstSharedPtr interface_addr_;
37
};
38

            
39
using InterfaceAddressVector = std::vector<InterfaceAddress>;
40

            
41
class OsSysCalls {
42
public:
43
1571
  virtual ~OsSysCalls() = default;
44

            
45
  /**
46
   * @see bind (man 2 bind)
47
   */
48
  virtual SysCallIntResult bind(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) PURE;
49

            
50
  /**
51
   * @see chmod (man 2 chmod)
52
   */
53
  virtual SysCallIntResult chmod(const std::string& path, mode_t mode) PURE;
54

            
55
  /**
56
   * This interface is based on Windows `WSAIoctl`. It becomes equivalent with the POSIX interface
57
   * with `in_buffer` as `argp` and the rest of the parameters ignored.
58
   * @see ioctl (man 2 ioctl)
59
   * @see WSAIoctl (MSDN)
60
   */
61
  virtual SysCallIntResult ioctl(os_fd_t sockfd, unsigned long control_code, void* in_buffer,
62
                                 unsigned long in_buffer_len, void* out_buffer,
63
                                 unsigned long out_buffer_len, unsigned long* bytes_returned) PURE;
64

            
65
  /**
66
   * @see writev (man 2 writev)
67
   */
68
  virtual SysCallSizeResult writev(os_fd_t fd, const iovec* iov, int num_iov) PURE;
69

            
70
  /**
71
   * @see readv (man 2 readv)
72
   */
73
  virtual SysCallSizeResult readv(os_fd_t fd, const iovec* iov, int num_iov) PURE;
74

            
75
  /**
76
   * @see man 2 pwrite
77
   */
78
  virtual SysCallSizeResult pwrite(os_fd_t fd, const void* buffer, size_t length,
79
                                   off_t offset) const PURE;
80

            
81
  /**
82
   * @see man 2 pread
83
   */
84
  virtual SysCallSizeResult pread(os_fd_t fd, void* buffer, size_t length, off_t offset) const PURE;
85

            
86
  /**
87
   * @see send (man 2 send)
88
   */
89
  virtual SysCallSizeResult send(os_fd_t socket, void* buffer, size_t length, int flags) PURE;
90

            
91
  /**
92
   * @see recv (man 2 recv)
93
   */
94
  virtual SysCallSizeResult recv(os_fd_t socket, void* buffer, size_t length, int flags) PURE;
95

            
96
  /**
97
   * @see recvmsg (man 2 recvmsg)
98
   */
99
  virtual SysCallSizeResult recvmsg(os_fd_t sockfd, msghdr* msg, int flags) PURE;
100

            
101
  /**
102
   * @see recvmmsg (man 2 recvmmsg)
103
   */
104
  virtual SysCallIntResult recvmmsg(os_fd_t sockfd, struct mmsghdr* msgvec, unsigned int vlen,
105
                                    int flags, struct timespec* timeout) PURE;
106

            
107
  /**
108
   * return true if the OS supports recvmmsg() and sendmmsg().
109
   */
110
  virtual bool supportsMmsg() const PURE;
111

            
112
  /**
113
   * return true if the OS supports UDP GRO.
114
   */
115
  virtual bool supportsUdpGro() const PURE;
116

            
117
  /**
118
   * return true if the OS supports UDP GSO
119
   */
120
  virtual bool supportsUdpGso() const PURE;
121

            
122
  /**
123
   * return true if the OS support IP_TRANSPARENT or IPV6_TRANSPARENT options by the ip version.
124
   */
125
  virtual bool supportsIpTransparent(Network::Address::IpVersion version) const PURE;
126

            
127
  /**
128
   * return true if the OS supports multi-path TCP
129
   */
130
  virtual bool supportsMptcp() const PURE;
131

            
132
  /**
133
   * Release all resources allocated for fd.
134
   * @return zero on success, -1 returned otherwise.
135
   */
136
  virtual SysCallIntResult close(os_fd_t fd) PURE;
137

            
138
  /**
139
   * @see man 2 ftruncate
140
   */
141
  virtual SysCallIntResult ftruncate(int fd, off_t length) PURE;
142

            
143
  /**
144
   * @see man 2 mmap
145
   */
146
  virtual SysCallPtrResult mmap(void* addr, size_t length, int prot, int flags, int fd,
147
                                off_t offset) PURE;
148

            
149
  /**
150
   * @see man 2 stat
151
   */
152
  virtual SysCallIntResult stat(const char* pathname, struct stat* buf) PURE;
153

            
154
  /**
155
   * @see man 2 fstat
156
   */
157
  virtual SysCallIntResult fstat(os_fd_t fd, struct stat* buf) PURE;
158

            
159
  /**
160
   * @see man 2 setsockopt
161
   */
162
  virtual SysCallIntResult setsockopt(os_fd_t sockfd, int level, int optname, const void* optval,
163
                                      socklen_t optlen) PURE;
164

            
165
  /**
166
   * @see man 2 getsockopt
167
   */
168
  virtual SysCallIntResult getsockopt(os_fd_t sockfd, int level, int optname, void* optval,
169
                                      socklen_t* optlen) PURE;
170

            
171
  /**
172
   * @see man 2 socket
173
   */
174
  virtual SysCallSocketResult socket(int domain, int type, int protocol) PURE;
175

            
176
  /**
177
   * @see man 2 sendmsg
178
   */
179
  virtual SysCallSizeResult sendmsg(os_fd_t sockfd, const msghdr* message, int flags) PURE;
180

            
181
  /**
182
   * @see man 2 getsockname
183
   */
184
  virtual SysCallIntResult getsockname(os_fd_t sockfd, sockaddr* addr, socklen_t* addrlen) PURE;
185

            
186
  /**
187
   * @see man 2 gethostname
188
   */
189
  virtual SysCallIntResult gethostname(char* name, size_t length) PURE;
190

            
191
  /**
192
   * @see man 2 getpeername
193
   */
194
  virtual SysCallIntResult getpeername(os_fd_t sockfd, sockaddr* name, socklen_t* namelen) PURE;
195

            
196
  /**
197
   * Toggle the blocking state bit using fcntl
198
   */
199
  virtual SysCallIntResult setsocketblocking(os_fd_t sockfd, bool blocking) PURE;
200

            
201
  /**
202
   * @see man 2 connect
203
   */
204
  virtual SysCallIntResult connect(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) PURE;
205

            
206
  /**
207
   * @see man 2 open
208
   */
209
  virtual SysCallIntResult open(const char* pathname, int flags) const PURE;
210

            
211
  /**
212
   * @see man 2 open
213
   */
214
  virtual SysCallIntResult open(const char* pathname, int flags, mode_t mode) const PURE;
215

            
216
  /**
217
   * @see man 2 unlink
218
   */
219
  virtual SysCallIntResult unlink(const char* pathname) const PURE;
220

            
221
  /**
222
   * @see man 2 unlink
223
   */
224
  virtual SysCallIntResult linkat(os_fd_t olddirfd, const char* oldpath, os_fd_t newdirfd,
225
                                  const char* newpath, int flags) const PURE;
226

            
227
  /**
228
   * @see man 2 mkstemp
229
   */
230
  virtual SysCallIntResult mkstemp(char* tmplate) const PURE;
231

            
232
  /**
233
   * Returns true if mkstemp, linkat, unlink, open, close, pread and pwrite are fully supported.
234
   */
235
  virtual bool supportsAllPosixFileOperations() const PURE;
236

            
237
  /**
238
   * @see man 2 shutdown
239
   */
240
  virtual SysCallIntResult shutdown(os_fd_t sockfd, int how) PURE;
241

            
242
  /**
243
   * @see man 2 socketpair
244
   */
245
  virtual SysCallIntResult socketpair(int domain, int type, int protocol, os_fd_t sv[2]) PURE;
246

            
247
  /**
248
   * @see man 2 listen
249
   */
250
  virtual SysCallIntResult listen(os_fd_t sockfd, int backlog) PURE;
251

            
252
  /**
253
   * @see man 2 write
254
   */
255
  virtual SysCallSizeResult write(os_fd_t socket, const void* buffer, size_t length) PURE;
256

            
257
  /**
258
   * @see man 2 accept. The fds returned are configured to be non-blocking.
259
   */
260
  virtual SysCallSocketResult accept(os_fd_t socket, sockaddr* addr, socklen_t* addrlen) PURE;
261

            
262
  /**
263
   * @see man 2 dup(2).
264
   */
265
  virtual SysCallSocketResult duplicate(os_fd_t oldfd) PURE;
266

            
267
  /**
268
   * @see man TCP_INFO. Get the tcp info for the socket.
269
   */
270
  virtual SysCallBoolResult socketTcpInfo(os_fd_t sockfd, EnvoyTcpInfo* tcp_info) PURE;
271

            
272
  /**
273
   * return true if the OS supports getifaddrs.
274
   */
275
  virtual bool supportsGetifaddrs() const PURE;
276

            
277
  /**
278
   * @see man getifaddrs
279
   */
280
  virtual SysCallIntResult getifaddrs(InterfaceAddressVector& interfaces) PURE;
281

            
282
  /**
283
   * @see man getaddrinfo
284
   */
285
  virtual SysCallIntResult getaddrinfo(const char* node, const char* service, const addrinfo* hints,
286
                                       addrinfo** res) PURE;
287

            
288
  /**
289
   * @see man freeaddrinfo
290
   */
291
  virtual void freeaddrinfo(addrinfo* res) PURE;
292

            
293
  /**
294
   * @see man getrlimit
295
   */
296
  virtual SysCallIntResult getrlimit(int resource, struct rlimit* rlim) PURE;
297

            
298
  /**
299
   * @see man setrlimit
300
   */
301
  virtual SysCallIntResult setrlimit(int resource, const struct rlimit* rlim) PURE;
302
};
303

            
304
using OsSysCallsPtr = std::unique_ptr<OsSysCalls>;
305

            
306
} // namespace Api
307
} // namespace Envoy