Line data Source code
1 : #pragma once 2 : // NOLINT(namespace-envoy) 3 : 4 : // This common "platform.h" header exists to simplify the most common references 5 : // to non-ANSI C/C++ headers, required on Windows, Posix, Linux, BSD etc, 6 : // and to provide substitute definitions when absolutely required. 7 : // 8 : // The goal is to eventually not require this file of envoy header declarations, 9 : // but limit the use of these architecture-specific types and declarations 10 : // to the corresponding .cc implementation files. 11 : #include "absl/strings/string_view.h" 12 : 13 : #ifdef _MSC_VER 14 : 15 : #include <windows.h> 16 : #include <winsock2.h> 17 : 18 : // These must follow afterwards 19 : #include <mswsock.h> 20 : #include <ws2tcpip.h> 21 : #include <mstcpip.h> 22 : 23 : // This is introduced in Windows SDK 10.0.17063.0 which is required 24 : // to build Envoy on Windows (we will reevaluate whether earlier builds 25 : // of Windows can be detected and PipeInstance marked unsupported at runtime.) 26 : #include <afunix.h> 27 : 28 : // <windows.h> defines some frequently used symbols, so we need to undef these 29 : // interfering symbols. 30 : #undef ASSERT 31 : #undef DELETE 32 : #undef ERROR 33 : #undef GetMessage 34 : #undef interface 35 : #undef TRUE 36 : #undef IGNORE 37 : 38 : #include <io.h> 39 : #include <stdint.h> 40 : #include <time.h> 41 : 42 : #define htole16(x) (x) 43 : #define htole32(x) (x) 44 : #define htole64(x) (x) 45 : #define le16toh(x) (x) 46 : #define le32toh(x) (x) 47 : #define le64toh(x) (x) 48 : 49 : #define htobe16(x) htons((x)) 50 : #define htobe32(x) htonl((x)) 51 : #define htobe64(x) htonll((x)) 52 : #define be16toh(x) ntohs((x)) 53 : #define be32toh(x) ntohl((x)) 54 : #define be64toh(x) ntohll((x)) 55 : 56 : #define PACKED_STRUCT(definition, ...) \ 57 : __pragma(pack(push, 1)) definition, ##__VA_ARGS__; \ 58 : __pragma(pack(pop)) 59 : 60 : typedef ptrdiff_t ssize_t; 61 : 62 : // This is needed so the OsSysCalls interface compiles on Windows, 63 : // shmOpen takes mode_t as an argument. 64 : typedef uint32_t mode_t; 65 : 66 : typedef SOCKET os_fd_t; 67 : typedef HANDLE filesystem_os_id_t; // NOLINT(modernize-use-using) 68 : typedef DWORD signal_t; // NOLINT(modernize-use-using) 69 : 70 : typedef unsigned int sa_family_t; 71 : 72 : // Posix structure for scatter/gather I/O, not present on Windows. 73 : struct iovec { 74 : void* iov_base; 75 : size_t iov_len; 76 : }; 77 : 78 : // Posix structure for describing messages sent by 'sendmsg` and received by 79 : // 'recvmsg' 80 : struct msghdr { 81 : void* msg_name; 82 : socklen_t msg_namelen; 83 : iovec* msg_iov; 84 : size_t msg_iovlen; 85 : void* msg_control; 86 : size_t msg_controllen; 87 : int msg_flags; 88 : }; 89 : 90 : // Windows cmsghdr elements are just slightly different than Posix, 91 : // they are defined with the cmsg_len as a 32 bit uint, not size_t 92 : // We express our sendmsg and recvmsg in terms of Posix structures 93 : // and semantics, but won't adjust the cmsghdr elements. 94 : // The default Windows macros dereference the Windows style msghdr 95 : // member Control, which is an indirection that doesn't exist on posix. 96 : 97 : #undef CMSG_FIRSTHDR 98 : #define CMSG_FIRSTHDR(msg) \ 99 : (((msg)->msg_controllen >= sizeof(WSACMSGHDR)) ? (LPWSACMSGHDR)(msg)->msg_control \ 100 : : (LPWSACMSGHDR)NULL) 101 : 102 : #undef CMSG_NXTHDR 103 : #define CMSG_NXTHDR(msg, cmsg) \ 104 : (((cmsg) == NULL) \ 105 : ? CMSG_FIRSTHDR(msg) \ 106 : : ((((PUCHAR)(cmsg) + WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len) + sizeof(WSACMSGHDR)) > \ 107 : (PUCHAR)((msg)->msg_control) + (msg)->msg_controllen) \ 108 : ? (LPWSACMSGHDR)NULL \ 109 : : (LPWSACMSGHDR)((PUCHAR)(cmsg) + WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len)))) 110 : 111 : #ifdef CMSG_DATA 112 : #undef CMSG_DATA 113 : #endif 114 : #define CMSG_DATA(msg) WSA_CMSG_DATA(msg) 115 : 116 : // Following Cygwin's porting example (may not be comprehensive) 117 : #define SO_REUSEPORT SO_REUSEADDR 118 : 119 : // Solve for rfc2292 (need to address rfc3542?) 120 : #ifndef IPV6_RECVPKTINFO 121 : #define IPV6_RECVPKTINFO IPV6_PKTINFO 122 : #endif 123 : 124 : #define INVALID_HANDLE INVALID_HANDLE_VALUE 125 : #define SOCKET_VALID(sock) ((sock) != INVALID_SOCKET) 126 : #define SOCKET_INVALID(sock) ((sock) == INVALID_SOCKET) 127 : #define SOCKET_FAILURE(rc) ((rc) == SOCKET_ERROR) 128 : #define SET_SOCKET_INVALID(sock) (sock) = INVALID_SOCKET 129 : 130 : // arguments to shutdown 131 : #define ENVOY_SHUT_RD SD_RECEIVE 132 : #define ENVOY_SHUT_WR SD_SEND 133 : #define ENVOY_SHUT_RDWR SD_BOTH 134 : 135 : // winsock2 functions return distinct set of error codes, disjoint from POSIX errors (that are 136 : // also available on Windows and set by POSIX function invocations). Here we map winsock2 error 137 : // codes with platform agnostic macros that correspond to the same or roughly similar errors on 138 : // POSIX systems for use in cross-platform socket error handling. 139 : #define SOCKET_ERROR_AGAIN WSAEWOULDBLOCK 140 : #define SOCKET_ERROR_NOT_SUP WSAEOPNOTSUPP 141 : #define SOCKET_ERROR_AF_NO_SUP WSAEAFNOSUPPORT 142 : #define SOCKET_ERROR_IN_PROGRESS WSAEINPROGRESS 143 : // winsock2 does not differentiate between PERM and ACCESS violations 144 : #define SOCKET_ERROR_PERM WSAEACCES 145 : #define SOCKET_ERROR_ACCESS WSAEACCES 146 : #define SOCKET_ERROR_MSG_SIZE WSAEMSGSIZE 147 : #define SOCKET_ERROR_INTR WSAEINTR 148 : #define SOCKET_ERROR_ADDR_NOT_AVAIL WSAEADDRNOTAVAIL 149 : #define SOCKET_ERROR_INVAL WSAEINVAL 150 : #define SOCKET_ERROR_ADDR_IN_USE WSAEADDRINUSE 151 : #define SOCKET_ERROR_BADF WSAEBADF 152 : #define SOCKET_ERROR_CONNRESET WSAECONNRESET 153 : #define SOCKET_ERROR_NETUNREACH WSAENETUNREACH 154 : 155 : #define HANDLE_ERROR_PERM ERROR_ACCESS_DENIED 156 : #define HANDLE_ERROR_INVALID ERROR_INVALID_HANDLE 157 : 158 : #define ENVOY_WIN32_SIGNAL_COUNT 1 159 : #define ENVOY_SIGTERM 0 160 : 161 : namespace Platform { 162 : constexpr absl::string_view null_device_path{"NUL"}; 163 : 164 : constexpr bool win32SupportsOriginalDestination() { 165 : #if defined(SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS) && defined(SO_ORIGINAL_DST) 166 : return true; 167 : #else 168 : return false; 169 : #endif 170 : } 171 : 172 : } // namespace Platform 173 : 174 : #else // POSIX 175 : 176 : #include <arpa/inet.h> 177 : #include <fcntl.h> 178 : #include <ifaddrs.h> 179 : #include <netdb.h> 180 : #include <netinet/in.h> 181 : #if !defined(DO_NOT_INCLUDE_NETINET_TCP_H) 182 : #include <netinet/tcp.h> 183 : #endif 184 : #include <netinet/udp.h> // for UDP_GRO 185 : #include <sys/ioctl.h> 186 : #include <sys/mman.h> // for mode_t 187 : #include <sys/socket.h> 188 : #include <sys/stat.h> 189 : #include <sys/uio.h> // for iovec 190 : #include <sys/un.h> 191 : #include <sys/wait.h> 192 : #include <unistd.h> 193 : 194 : #ifdef __APPLE__ 195 : #include <libkern/OSByteOrder.h> 196 : #define htole16(x) OSSwapHostToLittleInt16((x)) 197 : #define htole32(x) OSSwapHostToLittleInt32((x)) 198 : #define htole64(x) OSSwapHostToLittleInt64((x)) 199 : #define le16toh(x) OSSwapLittleToHostInt16((x)) 200 : #define le32toh(x) OSSwapLittleToHostInt32((x)) 201 : #define le64toh(x) OSSwapLittleToHostInt64((x)) 202 : #define htobe16(x) OSSwapHostToBigInt16((x)) 203 : #define htobe32(x) OSSwapHostToBigInt32((x)) 204 : #define htobe64(x) OSSwapHostToBigInt64((x)) 205 : #define be16toh(x) OSSwapBigToHostInt16((x)) 206 : #define be32toh(x) OSSwapBigToHostInt32((x)) 207 : #define be64toh(x) OSSwapBigToHostInt64((x)) 208 : 209 : #undef TRUE 210 : #else 211 : #include <endian.h> 212 : #endif 213 : 214 : #if defined(__linux__) 215 : #include <linux/netfilter_ipv4.h> 216 : #endif 217 : 218 0 : #define PACKED_STRUCT(definition, ...) definition, ##__VA_ARGS__ __attribute__((packed)) 219 : 220 : #ifndef IP6T_SO_ORIGINAL_DST 221 : // From linux/netfilter_ipv6/ip6_tables.h 222 : #define IP6T_SO_ORIGINAL_DST 80 223 : #endif 224 : 225 : #ifndef SOL_UDP 226 : #define SOL_UDP 17 227 : #endif 228 : 229 : #ifndef UDP_GRO 230 : #define UDP_GRO 104 231 : #endif 232 : 233 : #ifndef UDP_SEGMENT 234 : #define UDP_SEGMENT 103 235 : #endif 236 : 237 : #ifndef IPPROTO_MPTCP 238 0 : #define IPPROTO_MPTCP 262 239 : #endif 240 : 241 : typedef int os_fd_t; // NOLINT(modernize-use-using) 242 : typedef int filesystem_os_id_t; // NOLINT(modernize-use-using) 243 : typedef int signal_t; // NOLINT(modernize-use-using) 244 : 245 440 : #define INVALID_HANDLE -1 246 0 : #define INVALID_SOCKET -1 247 73751 : #define SOCKET_VALID(sock) ((sock) >= 0) 248 2612 : #define SOCKET_INVALID(sock) ((sock) == -1) 249 4747 : #define SOCKET_FAILURE(rc) ((rc) == -1) 250 7397 : #define SET_SOCKET_INVALID(sock) (sock) = -1 251 : 252 : // arguments to shutdown 253 : #define ENVOY_SHUT_RD SHUT_RD 254 252 : #define ENVOY_SHUT_WR SHUT_WR 255 : #define ENVOY_SHUT_RDWR SHUT_RDWR 256 : 257 : // Mapping POSIX socket errors to common error names 258 3351 : #define SOCKET_ERROR_AGAIN EAGAIN 259 0 : #define SOCKET_ERROR_NOT_SUP ENOTSUP 260 0 : #define SOCKET_ERROR_AF_NO_SUP EAFNOSUPPORT 261 1328 : #define SOCKET_ERROR_IN_PROGRESS EINPROGRESS 262 0 : #define SOCKET_ERROR_PERM EPERM 263 0 : #define SOCKET_ERROR_ACCESS EACCES 264 0 : #define SOCKET_ERROR_MSG_SIZE EMSGSIZE 265 0 : #define SOCKET_ERROR_INTR EINTR 266 0 : #define SOCKET_ERROR_ADDR_NOT_AVAIL EADDRNOTAVAIL 267 1661 : #define SOCKET_ERROR_INVAL EINVAL 268 0 : #define SOCKET_ERROR_ADDR_IN_USE EADDRINUSE 269 0 : #define SOCKET_ERROR_BADF EBADF 270 55 : #define SOCKET_ERROR_CONNRESET ECONNRESET 271 0 : #define SOCKET_ERROR_NETUNREACH ENETUNREACH 272 : 273 : // Mapping POSIX file errors to common error names 274 0 : #define HANDLE_ERROR_PERM EACCES 275 0 : #define HANDLE_ERROR_INVALID EBADF 276 : 277 98 : #define ENVOY_SIGTERM SIGTERM 278 : 279 : namespace Platform { 280 : constexpr absl::string_view null_device_path{"/dev/null"}; 281 : } 282 : #endif 283 : 284 : // Note: chromium disabled recvmmsg regardless of ndk version. However, the only Android target 285 : // currently actively using Envoy is Envoy Mobile, where recvmmsg is not actively disabled. In fact, 286 : // defining mmsghdr here caused a conflicting definition with the ndk's definition of the struct 287 : // (https://github.com/envoyproxy/envoy-mobile/pull/772/checks?check_run_id=534152886#step:4:64). 288 : // Therefore, we decided to remove the Android check introduced here in 289 : // https://github.com/envoyproxy/envoy/pull/10120. If someone out there encounters problems with 290 : // this please bring up in Envoy's slack channel #envoy-udp-quic-dev. 291 : #if defined(__linux__) || defined(__EMSCRIPTEN__) 292 : #define ENVOY_MMSG_MORE 1 293 : #else 294 : #define ENVOY_MMSG_MORE 0 295 : #define MSG_WAITFORONE 0x10000 // recvmmsg(): block until 1+ packets avail. 296 : // Posix structure for describing messages sent by 'sendmmsg` and received by 297 : // 'recvmmsg' 298 : struct mmsghdr { 299 : struct msghdr msg_hdr; 300 : unsigned int msg_len; 301 : }; 302 : #endif 303 : 304 : // TODO: Remove once bazel supports NDKs > 21 305 : #define SUPPORTS_CPP_17_CONTIGUOUS_ITERATOR 306 : #ifdef __ANDROID_API__ 307 : #if __ANDROID_API__ < 24 308 : #undef SUPPORTS_CPP_17_CONTIGUOUS_ITERATOR 309 : #endif // __ANDROID_API__ < 24 310 : #endif // ifdef __ANDROID_API__ 311 : 312 : // https://android.googlesource.com/platform/bionic/+/master/docs/status.md 313 : // ``pthread_getname_np`` is introduced in API 26 314 : #define SUPPORTS_PTHREAD_NAMING 0 315 : #if defined(__ANDROID_API__) 316 : #if __ANDROID_API__ >= 26 317 : #undef SUPPORTS_PTHREAD_NAMING 318 : #define SUPPORTS_PTHREAD_NAMING 1 319 : #endif // __ANDROID_API__ >= 26 320 : #elif defined(__linux__) 321 : #undef SUPPORTS_PTHREAD_NAMING 322 : #define SUPPORTS_PTHREAD_NAMING 1 323 : #endif // defined(__ANDROID_API__) 324 : 325 : #if defined(__linux__) 326 : // On Linux, default listen backlog size to net.core.somaxconn which is runtime configurable 327 0 : #define ENVOY_TCP_BACKLOG_SIZE -1 328 : #else 329 : // On non-Linux platforms use 128 which is libevent listener default 330 : #define ENVOY_TCP_BACKLOG_SIZE 128 331 : #endif