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