00001
00002
00003
00004
00005
00006
00007
00008
00009
00016 #ifndef NETWORK_CORE_OS_ABSTRACTION_H
00017 #define NETWORK_CORE_OS_ABSTRACTION_H
00018
00019
00020
00021 #ifdef ENABLE_NETWORK
00022
00023
00024 #if defined(WIN32) || defined(WIN64)
00025 #include <errno.h>
00026 #include <winsock2.h>
00027 #include <ws2tcpip.h>
00028 #include <windows.h>
00029
00030 #define GET_LAST_ERROR() WSAGetLastError()
00031 #undef EWOULDBLOCK
00032 #define EWOULDBLOCK WSAEWOULDBLOCK
00033
00034 typedef unsigned long in_addr_t;
00035
00036 #if !(defined(__MINGW32__) || defined(__CYGWIN__))
00037
00038 typedef SSIZE_T ssize_t;
00039 typedef int socklen_t;
00040 # define IPPROTO_IPV6 41
00041 #else
00042 #include "../../os/windows/win32.h"
00043 #include "../../core/alloc_func.hpp"
00044
00045 #define AI_ADDRCONFIG 0x00000400
00046 #define IPV6_V6ONLY 27
00047
00048 static inline int OTTDgetnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, DWORD hostlen, char *serv, DWORD servlen, int flags)
00049 {
00050 static int (WINAPI *getnameinfo)(const struct sockaddr *, socklen_t, char *, DWORD, char *, DWORD, int) = NULL;
00051 static bool first_time = true;
00052
00053 if (first_time) {
00054 LoadLibraryList((Function*)&getnameinfo, "ws2_32.dll\0getnameinfo\0\0");
00055 first_time = false;
00056 }
00057
00058 if (getnameinfo != NULL) return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
00059
00060 strncpy(host, inet_ntoa(((const struct sockaddr_in *)sa)->sin_addr), hostlen);
00061 return 0;
00062 }
00063 #define getnameinfo OTTDgetnameinfo
00064
00065 static inline int OTTDgetaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
00066 {
00067 static int (WINAPI *getaddrinfo)(const char *, const char *, const struct addrinfo *, struct addrinfo **) = NULL;
00068 static bool first_time = true;
00069
00070 if (first_time) {
00071 LoadLibraryList((Function*)&getaddrinfo, "ws2_32.dll\0getaddrinfo\0\0");
00072 first_time = false;
00073 }
00074
00075 if (getaddrinfo != NULL) return getaddrinfo(nodename, servname, hints, res);
00076
00077 *res = NULL;
00078
00079 in_addr_t ip = inet_addr(nodename);
00080 if (ip == INADDR_NONE) {
00081 struct hostent *he = gethostbyname(nodename);
00082 if (he == NULL) return EAI_NONAME;
00083 ip = (*(struct in_addr *)he->h_addr).s_addr;
00084 }
00085
00086 struct sockaddr_in *sin = CallocT<struct sockaddr_in>(1);
00087 sin->sin_family = AF_INET;
00088 sin->sin_port = htons(strtoul(servname, NULL, 10));
00089 sin->sin_addr.s_addr = ip;
00090
00091 struct addrinfo *ai = CallocT<struct addrinfo>(1);
00092 ai->ai_family = PF_INET;
00093 ai->ai_addr = (struct sockaddr*)sin;
00094 ai->ai_addrlen = sizeof(*sin);
00095 ai->ai_socktype = hints->ai_socktype;
00096
00097 *res = ai;
00098 return 0;
00099 }
00100 #define getaddrinfo OTTDgetaddrinfo
00101
00102 static inline void OTTDfreeaddrinfo(struct addrinfo *ai)
00103 {
00104 static int (WINAPI *freeaddrinfo)(struct addrinfo *) = NULL;
00105 static bool first_time = true;
00106
00107 if (ai == NULL) return;
00108
00109 if (first_time) {
00110 LoadLibraryList((Function*)&freeaddrinfo, "ws2_32.dll\0freeaddrinfo\0\0");
00111 first_time = false;
00112 }
00113
00114 if (freeaddrinfo != NULL) {
00115 freeaddrinfo(ai);
00116 return;
00117 }
00118
00119 do {
00120 struct addrinfo *next = ai->ai_next;
00121 free(ai->ai_addr);
00122 free(ai);
00123 ai = next;
00124 } while (ai != NULL);
00125 }
00126 #define freeaddrinfo OTTDfreeaddrinfo
00127 #endif
00128 #endif
00129
00130
00131 #if defined(UNIX) && !defined(__OS2__)
00132 # if defined(OPENBSD) || defined(__NetBSD__)
00133 # define AI_ADDRCONFIG 0
00134 # endif
00135 # define SOCKET int
00136 # define INVALID_SOCKET -1
00137 # if !defined(__MORPHOS__) && !defined(__AMIGA__)
00138 # define ioctlsocket ioctl
00139 # if !defined(BEOS_NET_SERVER)
00140 # define closesocket close
00141 # endif
00142 # define GET_LAST_ERROR() (errno)
00143 # endif
00144
00145 # define BSD_COMP
00146
00147
00148 # include <unistd.h>
00149 # include <sys/ioctl.h>
00150 # if defined(__BEOS__) && defined(BEOS_NET_SERVER)
00151 # include <be/net/socket.h>
00152 # include <be/kernel/OS.h>
00153 # include <be/net/netdb.h>
00154 typedef unsigned long in_addr_t;
00155 # define INADDR_NONE INADDR_BROADCAST
00156 # else
00157 # include <sys/socket.h>
00158 # include <netinet/in.h>
00159 # include <netinet/tcp.h>
00160 # include <arpa/inet.h>
00161 # include <net/if.h>
00162
00163 # if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__HAIKU__) && !defined(__INNOTEK_LIBC__) \
00164 && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX)
00165
00166
00167
00168 # include <ifaddrs.h>
00169 # define HAVE_GETIFADDRS
00170 # endif
00171 # if !defined(INADDR_NONE)
00172 # define INADDR_NONE 0xffffffff
00173 # endif
00174 # if defined(__BEOS__) && !defined(BEOS_NET_SERVER)
00175
00176 # include <sys/sockio.h>
00177 # endif
00178 # endif
00179
00180 # if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1)
00181 typedef uint32_t in_addr_t;
00182 # endif
00183
00184 # include <errno.h>
00185 # include <sys/time.h>
00186 # include <netdb.h>
00187 #endif
00188
00189 #ifdef __BEOS__
00190 typedef int socklen_t;
00191 #endif
00192
00193 #ifdef __HAIKU__
00194 #define IPV6_V6ONLY 27
00195 #endif
00196
00197 #if defined(PSP)
00198 # include <sys/socket.h>
00199 # include <netinet/in.h>
00200 # include <arpa/inet.h>
00201 # include <pspnet.h>
00202 # include <pspnet_inet.h>
00203 # include <pspnet_apctl.h>
00204 # include <pspnet_resolver.h>
00205 # include <errno.h>
00206 # include <unistd.h>
00207 # include <sys/select.h>
00208 # include <sys/time.h>
00209 # include <sys/fd_set.h>
00210
00211 # define TCP_NODELAY 1
00212 # define SO_NONBLOCK 0x1009
00213 # define SOCKET int
00214 # define INVALID_SOCKET -1
00215 # define INADDR_NONE 0xffffffff
00216 # define closesocket close
00217 # define GET_LAST_ERROR() sceNetInetGetErrno()
00218 #endif
00219
00220
00221 #if defined(__OS2__)
00222 # define SOCKET int
00223 # define INVALID_SOCKET -1
00224 # define ioctlsocket ioctl
00225 # define closesocket close
00226 # define GET_LAST_ERROR() (sock_errno())
00227
00228
00229 # include <types.h>
00230 # include <unistd.h>
00231 # include <sys/ioctl.h>
00232 # include <sys/socket.h>
00233 # include <netinet/in.h>
00234 # include <netinet/tcp.h>
00235 # include <arpa/inet.h>
00236 # include <net/if.h>
00237 # include <errno.h>
00238 # include <sys/time.h>
00239 # include <netdb.h>
00240 # include <nerrno.h>
00241 # define INADDR_NONE 0xffffffff
00242
00243 typedef int socklen_t;
00244 #if !defined(__INNOTEK_LIBC__)
00245 typedef unsigned long in_addr_t;
00246 #endif
00247 #endif
00248
00249
00250 #if defined(__MORPHOS__) || defined(__AMIGA__)
00251 # include <exec/types.h>
00252 # include <proto/exec.h>
00253
00254
00255 # define UBYTE char
00256 # if defined(__MORPHOS__)
00257 # include <sys/filio.h>
00258 # include <sys/sockio.h>
00259 # include <netinet/in.h>
00260 # else
00261 # include <proto/socket.h>
00262 # endif
00263
00264
00265 # define closesocket(s) CloseSocket(s)
00266 # define GET_LAST_ERROR() Errno()
00267 # define ioctlsocket(s, request, status) IoctlSocket((LONG)s, (ULONG)request, (char*)status)
00268 # define ioctl ioctlsocket
00269
00270 typedef unsigned int in_addr_t;
00271 typedef long socklen_t;
00272 extern struct Library *SocketBase;
00273
00274 # ifdef __AMIGA__
00275
00276 extern struct Device *TimerBase;
00277 extern struct MsgPort *TimerPort;
00278 extern struct timerequest *TimerRequest;
00279 # endif
00280 #endif
00281
00287 static inline bool SetNonBlocking(SOCKET d)
00288 {
00289 #ifdef WIN32
00290 u_long nonblocking = 1;
00291 #else
00292 int nonblocking = 1;
00293 #endif
00294 #if (defined(__BEOS__) && defined(BEOS_NET_SERVER)) || defined(PSP)
00295 return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0;
00296 #else
00297 return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
00298 #endif
00299 }
00300
00306 static inline bool SetNoDelay(SOCKET d)
00307 {
00308
00309 #if !defined(BEOS_NET_SERVER)
00310 int b = 1;
00311
00312 return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
00313 #else
00314 return true;
00315 #endif
00316 }
00317
00318
00319 assert_compile(sizeof(in_addr) == 4);
00320 assert_compile(sizeof(in6_addr) == 16);
00321
00322 #endif
00323
00324 #endif