OpenTTD Source  1.11.2
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 <string>
18 
23 class NetworkError {
24 private:
25  int error;
26  mutable std::string message;
27 public:
28  NetworkError(int error);
29 
30  bool HasError() const;
31  bool WouldBlock() const;
32  bool IsConnectionReset() const;
33  bool IsConnectInProgress() const;
34  const char *AsString() const;
35 
36  static NetworkError GetLast();
37 };
38 
39 /* Include standard stuff per OS */
40 
41 /* Windows stuff */
42 #if defined(_WIN32)
43 #include <errno.h>
44 #include <winsock2.h>
45 #include <ws2tcpip.h>
46 #include <windows.h>
47 
48 /* Windows has some different names for some types */
49 typedef unsigned long in_addr_t;
50 
51 /* Handle cross-compilation with --build=*-*-cygwin --host=*-*-mingw32 */
52 #if defined(__MINGW32__) && !defined(AI_ADDRCONFIG)
53 # define AI_ADDRCONFIG 0x00000400
54 #endif
55 
56 #if !(defined(__MINGW32__) || defined(__CYGWIN__))
57  /* Windows has some different names for some types */
58  typedef SSIZE_T ssize_t;
59  typedef int socklen_t;
60 # define IPPROTO_IPV6 41
61 #endif /* !(__MINGW32__ && __CYGWIN__) */
62 #endif /* _WIN32 */
63 
64 /* UNIX stuff */
65 #if defined(UNIX) && !defined(__OS2__)
66 # if defined(OPENBSD) || defined(__NetBSD__)
67 # define AI_ADDRCONFIG 0
68 # endif
69 # define SOCKET int
70 # define INVALID_SOCKET -1
71 # define closesocket close
72 /* Need this for FIONREAD on solaris */
73 # define BSD_COMP
74 
75 /* Includes needed for UNIX-like systems */
76 # include <unistd.h>
77 # include <sys/ioctl.h>
78 # include <sys/socket.h>
79 # include <netinet/in.h>
80 # include <netinet/tcp.h>
81 # include <arpa/inet.h>
82 # include <net/if.h>
83 /* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
84 # if !defined(__sgi__) && !defined(SUNOS) && !defined(__INNOTEK_LIBC__) \
85  && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX)
86 /* If for any reason ifaddrs.h does not exist on your system, comment out
87  * the following two lines and an alternative way will be used to fetch
88  * the list of IPs from the system. */
89 # include <ifaddrs.h>
90 # define HAVE_GETIFADDRS
91 # endif
92 # if !defined(INADDR_NONE)
93 # define INADDR_NONE 0xffffffff
94 # endif
95 
96 # if defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
97  typedef uint32_t in_addr_t;
98 # endif
99 
100 # include <errno.h>
101 # include <sys/time.h>
102 # include <netdb.h>
103 
104 # if defined(__EMSCRIPTEN__)
105 /* Emscripten doesn't support AI_ADDRCONFIG and errors out on it. */
106 # undef AI_ADDRCONFIG
107 # define AI_ADDRCONFIG 0
108 /* Emscripten says it supports FD_SETSIZE fds, but it really only supports 64.
109  * https://github.com/emscripten-core/emscripten/issues/1711 */
110 # undef FD_SETSIZE
111 # define FD_SETSIZE 64
112 # endif
113 #endif /* UNIX */
114 
115 /* OS/2 stuff */
116 #if defined(__OS2__)
117 # define SOCKET int
118 # define INVALID_SOCKET -1
119 # define closesocket close
120 
121 /* Includes needed for OS/2 systems */
122 # include <types.h>
123 # include <unistd.h>
124 # include <sys/ioctl.h>
125 # include <sys/socket.h>
126 # include <netinet/in.h>
127 # include <netinet/tcp.h>
128 # include <arpa/inet.h>
129 # include <net/if.h>
130 # include <errno.h>
131 # include <sys/time.h>
132 # include <netdb.h>
133 # include <nerrno.h>
134 # define INADDR_NONE 0xffffffff
135 # include "../../3rdparty/os2/getaddrinfo.h"
136 # include "../../3rdparty/os2/getnameinfo.h"
137 
138 #define IPV6_V6ONLY 27
139 
140 /*
141  * IPv6 address
142  */
143 struct in6_addr {
144  union {
145  uint8_t __u6_addr8[16];
146  uint16_t __u6_addr16[8];
147  uint32_t __u6_addr32[4];
148  } __u6_addr; /* 128-bit IP6 address */
149 };
150 
151 #define s6_addr __u6_addr.__u6_addr8
152 
153 struct sockaddr_in6 {
154  uint8_t sin6_len; /* length of this struct */
155  sa_family_t sin6_family; /* AF_INET6 */
156  in_port_t sin6_port; /* Transport layer port # */
157  uint32_t sin6_flowinfo; /* IP6 flow information */
158  struct in6_addr sin6_addr; /* IP6 address */
159  uint32_t sin6_scope_id; /* scope zone index */
160 };
161 
162 typedef int socklen_t;
163 #if !defined(__INNOTEK_LIBC__)
164 typedef unsigned long in_addr_t;
165 #endif /* __INNOTEK_LIBC__ */
166 
167 #endif /* OS/2 */
168 
169 #ifdef __EMSCRIPTEN__
170 
181 static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address)
182 {
183  switch (address.ss_family) {
184  case AF_INET6: return sizeof(struct sockaddr_in6);
185  case AF_INET: return sizeof(struct sockaddr_in);
186  default: NOT_REACHED();
187  }
188 }
189 #endif
190 
191 
192 bool SetNonBlocking(SOCKET d);
193 bool SetNoDelay(SOCKET d);
194 NetworkError GetSocketError(SOCKET d);
195 
196 /* Make sure these structures have the size we expect them to be */
197 static_assert(sizeof(in_addr) == 4);
198 static_assert(sizeof(in6_addr) == 16);
199 
200 #endif /* NETWORK_CORE_OS_ABSTRACTION_H */
NetworkError::HasError
bool HasError() const
Check whether an error was actually set.
Definition: os_abstraction.cpp:107
NetworkError::message
std::string message
The string representation of the error (set on first call to AsString).
Definition: os_abstraction.h:26
NetworkError::WouldBlock
bool WouldBlock() const
Check whether this error describes that the operation would block.
Definition: os_abstraction.cpp:38
NetworkError::GetLast
static NetworkError GetLast()
Get the last network error.
Definition: os_abstraction.cpp:116
NetworkError::error
int error
The underlying error number from errno or WSAGetLastError.
Definition: os_abstraction.h:25
SetNonBlocking
bool SetNonBlocking(SOCKET d)
Try to set the socket into non-blocking mode.
Definition: os_abstraction.cpp:133
NetworkError::IsConnectInProgress
bool IsConnectInProgress() const
Check whether this error describes a connect is in progress.
Definition: os_abstraction.cpp:66
NetworkError::IsConnectionReset
bool IsConnectionReset() const
Check whether this error describes a connection reset.
Definition: os_abstraction.cpp:53
NetworkError
Abstraction of a network error where all implementation details of the error codes are encapsulated i...
Definition: os_abstraction.h:23
SetNoDelay
bool SetNoDelay(SOCKET d)
Try to set the socket to not delay sending.
Definition: os_abstraction.cpp:151
GetSocketError
NetworkError GetSocketError(SOCKET d)
Get the error from a socket, if any.
Definition: os_abstraction.cpp:167
NetworkError::NetworkError
NetworkError(int error)
Construct the network error with the given error code.
Definition: os_abstraction.cpp:30
NetworkError::AsString
const char * AsString() const
Get the string representation of the error message.
Definition: os_abstraction.cpp:79