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/>.
9 * @file os_abstraction.h Network stuff has many things that needs to be
10 * included and/or implemented by default.
11 * All those things are in this file.
14 #ifndef NETWORK_CORE_OS_ABSTRACTION_H
15 #define NETWORK_CORE_OS_ABSTRACTION_H
18 * Abstraction of a network error where all implementation details of the
19 * error codes are encapsulated in this class and the abstraction layer.
23 int error
; ///< The underlying error number from errno or WSAGetLastError.
24 mutable std::string message
; ///< The string representation of the error (set on first call to #AsString).
26 NetworkError(int error
);
28 bool HasError() const;
29 bool WouldBlock() const;
30 bool IsConnectionReset() const;
31 bool IsConnectInProgress() const;
32 const std::string
&AsString() const;
34 static NetworkError
GetLast();
37 /* Include standard stuff per OS */
46 /* Windows has some different names for some types */
47 typedef unsigned long in_addr_t
;
49 /* Handle cross-compilation with --build=*-*-cygwin --host=*-*-mingw32 */
50 #if defined(__MINGW32__) && !defined(AI_ADDRCONFIG)
51 # define AI_ADDRCONFIG 0x00000400
54 #if !(defined(__MINGW32__) || defined(__CYGWIN__))
55 /* Windows has some different names for some types */
56 typedef SSIZE_T ssize_t
;
57 typedef int socklen_t
;
58 # define IPPROTO_IPV6 41
59 #endif /* !(__MINGW32__ && __CYGWIN__) */
64 # if defined(OPENBSD) || defined(__NetBSD__)
65 # define AI_ADDRCONFIG 0
68 # define INVALID_SOCKET -1
69 # define closesocket close
70 /* Need this for FIONREAD on solaris */
73 /* Includes needed for UNIX-like systems */
75 # include <sys/ioctl.h>
76 # include <sys/socket.h>
77 # include <netinet/in.h>
78 # include <netinet/tcp.h>
79 # include <arpa/inet.h>
82 # if !defined(INADDR_NONE)
83 # define INADDR_NONE 0xffffffff
86 # if defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
87 typedef uint32_t in_addr_t
;
91 # include <sys/time.h>
94 # if defined(__EMSCRIPTEN__)
95 /* Emscripten doesn't support AI_ADDRCONFIG and errors out on it. */
97 # define AI_ADDRCONFIG 0
98 /* Emscripten says it supports FD_SETSIZE fds, but it really only supports 64.
99 * https://github.com/emscripten-core/emscripten/issues/1711 */
101 # define FD_SETSIZE 64
104 /* Haiku says it supports FD_SETSIZE fds, but it really only supports 512. */
105 # if defined(__HAIKU__)
107 # define FD_SETSIZE 512
112 #ifdef __EMSCRIPTEN__
114 * Emscripten doesn't set 'addrlen' for accept(), getsockname(), getpeername()
115 * and recvfrom(), which confuses other functions and causes them to crash.
116 * This function needs to be called after these four functions to make sure
117 * 'addrlen' is patched up.
119 * https://github.com/emscripten-core/emscripten/issues/12996
121 * @param address The address returned by those four functions.
122 * @return The correct value for addrlen.
124 inline socklen_t
FixAddrLenForEmscripten(struct sockaddr_storage
&address
)
126 switch (address
.ss_family
) {
127 case AF_INET6
: return sizeof(struct sockaddr_in6
);
128 case AF_INET
: return sizeof(struct sockaddr_in
);
129 default: NOT_REACHED();
135 bool SetNonBlocking(SOCKET d
);
136 bool SetNoDelay(SOCKET d
);
137 bool SetReusePort(SOCKET d
);
138 NetworkError
GetSocketError(SOCKET d
);
140 /* Make sure these structures have the size we expect them to be */
141 static_assert(sizeof(in_addr
) == 4); ///< IPv4 addresses should be 4 bytes.
142 static_assert(sizeof(in6_addr
) == 16); ///< IPv6 addresses should be 16 bytes.
144 #endif /* NETWORK_CORE_OS_ABSTRACTION_H */