OpenTTD Source  1.11.0-beta2
os_abstraction.h
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
14 #ifndef NETWORK_CORE_OS_ABSTRACTION_H
15 #define NETWORK_CORE_OS_ABSTRACTION_H
16 
17 /* Include standard stuff per OS */
18 
19 /* Windows stuff */
20 #if defined(_WIN32)
21 #include <errno.h>
22 #include <winsock2.h>
23 #include <ws2tcpip.h>
24 #include <windows.h>
25 
26 #define GET_LAST_ERROR() WSAGetLastError()
27 #undef EWOULDBLOCK
28 #define EWOULDBLOCK WSAEWOULDBLOCK
29 /* Windows has some different names for some types */
30 typedef unsigned long in_addr_t;
31 
32 /* Handle cross-compilation with --build=*-*-cygwin --host=*-*-mingw32 */
33 #if defined(__MINGW32__) && !defined(AI_ADDRCONFIG)
34 # define AI_ADDRCONFIG 0x00000400
35 #endif
36 
37 #if !(defined(__MINGW32__) || defined(__CYGWIN__))
38  /* Windows has some different names for some types */
39  typedef SSIZE_T ssize_t;
40  typedef int socklen_t;
41 # define IPPROTO_IPV6 41
42 #endif /* !(__MINGW32__ && __CYGWIN__) */
43 #endif /* _WIN32 */
44 
45 /* UNIX stuff */
46 #if defined(UNIX) && !defined(__OS2__)
47 # if defined(OPENBSD) || defined(__NetBSD__)
48 # define AI_ADDRCONFIG 0
49 # endif
50 # define SOCKET int
51 # define INVALID_SOCKET -1
52 # define ioctlsocket ioctl
53 # define closesocket close
54 # define GET_LAST_ERROR() (errno)
55 /* Need this for FIONREAD on solaris */
56 # define BSD_COMP
57 
58 /* Includes needed for UNIX-like systems */
59 # include <unistd.h>
60 # include <sys/ioctl.h>
61 # include <sys/socket.h>
62 # include <netinet/in.h>
63 # include <netinet/tcp.h>
64 # include <arpa/inet.h>
65 # include <net/if.h>
66 /* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
67 # if !defined(__sgi__) && !defined(SUNOS) && !defined(__INNOTEK_LIBC__) \
68  && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX)
69 /* If for any reason ifaddrs.h does not exist on your system, comment out
70  * the following two lines and an alternative way will be used to fetch
71  * the list of IPs from the system. */
72 # include <ifaddrs.h>
73 # define HAVE_GETIFADDRS
74 # endif
75 # if !defined(INADDR_NONE)
76 # define INADDR_NONE 0xffffffff
77 # endif
78 
79 # if defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
80  typedef uint32_t in_addr_t;
81 # endif
82 
83 # include <errno.h>
84 # include <sys/time.h>
85 # include <netdb.h>
86 
87 # if defined(__EMSCRIPTEN__)
88 /* Emscripten doesn't support AI_ADDRCONFIG and errors out on it. */
89 # undef AI_ADDRCONFIG
90 # define AI_ADDRCONFIG 0
91 /* Emscripten says it supports FD_SETSIZE fds, but it really only supports 64.
92  * https://github.com/emscripten-core/emscripten/issues/1711 */
93 # undef FD_SETSIZE
94 # define FD_SETSIZE 64
95 # endif
96 #endif /* UNIX */
97 
98 /* OS/2 stuff */
99 #if defined(__OS2__)
100 # define SOCKET int
101 # define INVALID_SOCKET -1
102 # define ioctlsocket ioctl
103 # define closesocket close
104 # define GET_LAST_ERROR() (sock_errno())
105 
106 /* Includes needed for OS/2 systems */
107 # include <types.h>
108 # include <unistd.h>
109 # include <sys/ioctl.h>
110 # include <sys/socket.h>
111 # include <netinet/in.h>
112 # include <netinet/tcp.h>
113 # include <arpa/inet.h>
114 # include <net/if.h>
115 # include <errno.h>
116 # include <sys/time.h>
117 # include <netdb.h>
118 # include <nerrno.h>
119 # define INADDR_NONE 0xffffffff
120 # include "../../3rdparty/os2/getaddrinfo.h"
121 # include "../../3rdparty/os2/getnameinfo.h"
122 
123 #define IPV6_V6ONLY 27
124 
125 /*
126  * IPv6 address
127  */
128 struct in6_addr {
129  union {
130  uint8_t __u6_addr8[16];
131  uint16_t __u6_addr16[8];
132  uint32_t __u6_addr32[4];
133  } __u6_addr; /* 128-bit IP6 address */
134 };
135 
136 #define s6_addr __u6_addr.__u6_addr8
137 
138 struct sockaddr_in6 {
139  uint8_t sin6_len; /* length of this struct */
140  sa_family_t sin6_family; /* AF_INET6 */
141  in_port_t sin6_port; /* Transport layer port # */
142  uint32_t sin6_flowinfo; /* IP6 flow information */
143  struct in6_addr sin6_addr; /* IP6 address */
144  uint32_t sin6_scope_id; /* scope zone index */
145 };
146 
147 typedef int socklen_t;
148 #if !defined(__INNOTEK_LIBC__)
149 typedef unsigned long in_addr_t;
150 #endif /* __INNOTEK_LIBC__ */
151 
152 #endif /* OS/2 */
153 
154 #ifdef __EMSCRIPTEN__
155 
166 static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address)
167 {
168  switch (address.ss_family) {
169  case AF_INET6: return sizeof(struct sockaddr_in6);
170  case AF_INET: return sizeof(struct sockaddr_in);
171  default: NOT_REACHED();
172  }
173 }
174 #endif
175 
181 static inline bool SetNonBlocking(SOCKET d)
182 {
183 #ifdef __EMSCRIPTEN__
184  return true;
185 #else
186 # ifdef _WIN32
187  u_long nonblocking = 1;
188 # else
189  int nonblocking = 1;
190 # endif
191  return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
192 #endif
193 }
194 
200 static inline bool SetNoDelay(SOCKET d)
201 {
202 #ifdef __EMSCRIPTEN__
203  return true;
204 #else
205  /* XXX should this be done at all? */
206  int b = 1;
207  /* The (const char*) cast is needed for windows */
208  return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
209 #endif
210 }
211 
212 /* Make sure these structures have the size we expect them to be */
213 static_assert(sizeof(in_addr) == 4);
214 static_assert(sizeof(in6_addr) == 16);
215 
216 #endif /* NETWORK_CORE_OS_ABSTRACTION_H */
SetNoDelay
static bool SetNoDelay(SOCKET d)
Try to set the socket to not delay sending.
Definition: os_abstraction.h:200
SetNonBlocking
static bool SetNonBlocking(SOCKET d)
Try to set the socket into non-blocking mode.
Definition: os_abstraction.h:181