2009-08-21 22:21:05 +02:00
|
|
|
/*
|
|
|
|
* This file is part of OpenTTD.
|
|
|
|
* 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.
|
|
|
|
* 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.
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
/**
|
|
|
|
* @file os_abstraction.h Network stuff has many things that needs to be
|
|
|
|
* included and/or implemented by default.
|
|
|
|
* All those things are in this file.
|
|
|
|
*/
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2007-02-23 09:37:33 +01:00
|
|
|
#ifndef NETWORK_CORE_OS_ABSTRACTION_H
|
|
|
|
#define NETWORK_CORE_OS_ABSTRACTION_H
|
|
|
|
|
2021-04-30 15:38:22 +02:00
|
|
|
/**
|
|
|
|
* Abstraction of a network error where all implementation details of the
|
|
|
|
* error codes are encapsulated in this class and the abstraction layer.
|
|
|
|
*/
|
|
|
|
class NetworkError {
|
|
|
|
private:
|
|
|
|
int error; ///< The underlying error number from errno or WSAGetLastError.
|
|
|
|
mutable std::string message; ///< The string representation of the error (set on first call to #AsString).
|
|
|
|
public:
|
|
|
|
NetworkError(int error);
|
|
|
|
|
|
|
|
bool HasError() const;
|
|
|
|
bool WouldBlock() const;
|
|
|
|
bool IsConnectionReset() const;
|
|
|
|
bool IsConnectInProgress() const;
|
2021-06-13 21:41:07 +02:00
|
|
|
const std::string &AsString() const;
|
2021-04-30 15:38:22 +02:00
|
|
|
|
|
|
|
static NetworkError GetLast();
|
|
|
|
};
|
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
/* Include standard stuff per OS */
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
/* Windows stuff */
|
2018-12-09 02:28:14 +01:00
|
|
|
#if defined(_WIN32)
|
2010-06-28 20:14:00 +02:00
|
|
|
#include <errno.h>
|
2004-12-23 23:31:46 +01:00
|
|
|
#include <winsock2.h>
|
|
|
|
#include <ws2tcpip.h>
|
2005-10-03 00:39:56 +02:00
|
|
|
#include <windows.h>
|
2004-12-23 21:23:05 +01:00
|
|
|
|
2009-04-03 16:01:45 +02:00
|
|
|
/* Windows has some different names for some types */
|
|
|
|
typedef unsigned long in_addr_t;
|
|
|
|
|
2019-10-05 07:50:33 +02:00
|
|
|
/* Handle cross-compilation with --build=*-*-cygwin --host=*-*-mingw32 */
|
|
|
|
#if defined(__MINGW32__) && !defined(AI_ADDRCONFIG)
|
|
|
|
# define AI_ADDRCONFIG 0x00000400
|
|
|
|
#endif
|
|
|
|
|
2005-03-14 20:27:19 +01:00
|
|
|
#if !(defined(__MINGW32__) || defined(__CYGWIN__))
|
2007-01-02 18:34:03 +01:00
|
|
|
/* Windows has some different names for some types */
|
2004-12-23 23:31:46 +01:00
|
|
|
typedef SSIZE_T ssize_t;
|
2005-02-07 21:36:41 +01:00
|
|
|
typedef int socklen_t;
|
2009-04-04 01:44:31 +02:00
|
|
|
# define IPPROTO_IPV6 41
|
2019-01-13 17:12:52 +01:00
|
|
|
#endif /* !(__MINGW32__ && __CYGWIN__) */
|
2018-12-09 02:28:14 +01:00
|
|
|
#endif /* _WIN32 */
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
/* UNIX stuff */
|
2023-06-16 14:23:55 +02:00
|
|
|
#if defined(UNIX)
|
2010-05-10 19:11:24 +02:00
|
|
|
# if defined(OPENBSD) || defined(__NetBSD__)
|
2010-01-16 23:01:33 +01:00
|
|
|
# define AI_ADDRCONFIG 0
|
|
|
|
# endif
|
2004-12-04 18:54:56 +01:00
|
|
|
# define SOCKET int
|
|
|
|
# define INVALID_SOCKET -1
|
2019-03-04 19:46:11 +01:00
|
|
|
# define closesocket close
|
2007-01-02 18:34:03 +01:00
|
|
|
/* Need this for FIONREAD on solaris */
|
2004-12-04 18:54:56 +01:00
|
|
|
# define BSD_COMP
|
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
/* Includes needed for UNIX-like systems */
|
2004-12-04 18:54:56 +01:00
|
|
|
# include <unistd.h>
|
|
|
|
# include <sys/ioctl.h>
|
2019-03-04 19:46:11 +01:00
|
|
|
# include <sys/socket.h>
|
|
|
|
# include <netinet/in.h>
|
|
|
|
# include <netinet/tcp.h>
|
|
|
|
# include <arpa/inet.h>
|
|
|
|
# include <net/if.h>
|
2007-01-02 18:34:03 +01:00
|
|
|
/* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
|
2023-06-16 14:23:55 +02:00
|
|
|
# if !defined(__sgi__) && !defined(SUNOS) \
|
2019-03-04 19:46:11 +01:00
|
|
|
&& !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX)
|
2007-01-02 18:34:03 +01:00
|
|
|
/* If for any reason ifaddrs.h does not exist on your system, comment out
|
|
|
|
* the following two lines and an alternative way will be used to fetch
|
|
|
|
* the list of IPs from the system. */
|
2019-03-04 19:46:11 +01:00
|
|
|
# include <ifaddrs.h>
|
|
|
|
# define HAVE_GETIFADDRS
|
|
|
|
# endif
|
|
|
|
# if !defined(INADDR_NONE)
|
|
|
|
# define INADDR_NONE 0xffffffff
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# if defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
|
2004-12-23 20:23:56 +01:00
|
|
|
typedef uint32_t in_addr_t;
|
2005-02-28 23:33:31 +01:00
|
|
|
# endif
|
2004-12-23 20:23:56 +01:00
|
|
|
|
2004-12-04 18:54:56 +01:00
|
|
|
# include <errno.h>
|
|
|
|
# include <sys/time.h>
|
|
|
|
# include <netdb.h>
|
2020-12-05 21:57:47 +01:00
|
|
|
|
|
|
|
# if defined(__EMSCRIPTEN__)
|
|
|
|
/* Emscripten doesn't support AI_ADDRCONFIG and errors out on it. */
|
|
|
|
# undef AI_ADDRCONFIG
|
|
|
|
# define AI_ADDRCONFIG 0
|
|
|
|
/* Emscripten says it supports FD_SETSIZE fds, but it really only supports 64.
|
|
|
|
* https://github.com/emscripten-core/emscripten/issues/1711 */
|
|
|
|
# undef FD_SETSIZE
|
|
|
|
# define FD_SETSIZE 64
|
|
|
|
# endif
|
2021-05-21 01:34:50 +02:00
|
|
|
|
|
|
|
/* Haiku says it supports FD_SETSIZE fds, but it really only supports 512. */
|
|
|
|
# if defined(__HAIKU__)
|
|
|
|
# undef FD_SETSIZE
|
|
|
|
# define FD_SETSIZE 512
|
|
|
|
# endif
|
|
|
|
|
2009-03-15 01:32:18 +01:00
|
|
|
#endif /* UNIX */
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2020-12-09 17:13:34 +01:00
|
|
|
#ifdef __EMSCRIPTEN__
|
|
|
|
/**
|
|
|
|
* Emscripten doesn't set 'addrlen' for accept(), getsockname(), getpeername()
|
|
|
|
* and recvfrom(), which confuses other functions and causes them to crash.
|
|
|
|
* This function needs to be called after these four functions to make sure
|
|
|
|
* 'addrlen' is patched up.
|
|
|
|
*
|
|
|
|
* https://github.com/emscripten-core/emscripten/issues/12996
|
|
|
|
*
|
|
|
|
* @param address The address returned by those four functions.
|
|
|
|
* @return The correct value for addrlen.
|
|
|
|
*/
|
|
|
|
static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address)
|
|
|
|
{
|
|
|
|
switch (address.ss_family) {
|
|
|
|
case AF_INET6: return sizeof(struct sockaddr_in6);
|
|
|
|
case AF_INET: return sizeof(struct sockaddr_in);
|
|
|
|
default: NOT_REACHED();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-02-07 10:56:16 +01:00
|
|
|
|
2021-04-30 19:21:02 +02:00
|
|
|
bool SetNonBlocking(SOCKET d);
|
|
|
|
bool SetNoDelay(SOCKET d);
|
2021-04-27 11:51:00 +02:00
|
|
|
bool SetReusePort(SOCKET d);
|
2021-04-30 19:21:02 +02:00
|
|
|
NetworkError GetSocketError(SOCKET d);
|
2021-04-27 20:18:43 +02:00
|
|
|
|
2009-04-09 01:41:48 +02:00
|
|
|
/* Make sure these structures have the size we expect them to be */
|
2020-12-27 11:44:22 +01:00
|
|
|
static_assert(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
|
|
|
|
static_assert(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
|
2009-04-09 01:41:48 +02:00
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
#endif /* NETWORK_CORE_OS_ABSTRACTION_H */
|