LCOV - code coverage report
Current view: top level - envoy/common - platform.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 11 27 40.7 %
Date: 2024-01-05 06:35:25 Functions: 0 0 -

          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

Generated by: LCOV version 1.15