Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ipv6/src/external/enet/win32.c @ 7435

Last change on this file since 7435 was 7435, checked in by landauf, 14 years ago

build fixes for MinGW

File size: 11.0 KB
RevLine 
[7328]1/**
2 @file  win32.c
3 @brief ENet Win32 system specific functions
4*/
5#ifdef WIN32
[7435]6
7#define _WIN32_WINNT 0x0501
[7328]8
9#include <time.h>
10#define ENET_BUILDING_LIB 1
11#include "enet/enet.h"
12
13static enet_uint32 timeBase = 0;
14
15int
16enet_initialize (void)
17{
[7394]18    WORD versionRequested = MAKEWORD (2, 2);
[7328]19    WSADATA wsaData;
20   
21    if (WSAStartup (versionRequested, & wsaData))
22       return -1;
23
[7394]24    if (LOBYTE (wsaData.wVersion) != 2||
25        HIBYTE (wsaData.wVersion) != 2)
[7328]26    {
27       WSACleanup ();
28       
29       return -1;
30    }
31
32    timeBeginPeriod (1);
33
34    return 0;
35}
36
37void
38enet_deinitialize (void)
39{
40    timeEndPeriod (1);
41
42    WSACleanup ();
43}
44
45enet_uint32
46enet_time_get (void)
47{
48    return (enet_uint32) timeGetTime () - timeBase;
49}
50
51void
52enet_time_set (enet_uint32 newTimeBase)
53{
54    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
55}
56
[7390]57static enet_uint16
58enet_af (ENetAddressFamily family)
59{
60    if (family == ENET_IPV4)
61        return AF_INET;
62    if (family == ENET_IPV6)
63        return AF_INET6;
64    return 0;
65}
66
67static socklen_t
68enet_sa_size (ENetAddressFamily family)
69{
70    if (family == ENET_IPV4)
[7433]71        return sizeof (struct sockaddr_in);
[7390]72    if (family == ENET_IPV6)
[7433]73        return sizeof (struct sockaddr_in6);
[7390]74    return 0;
75}
76
77static ENetAddressFamily
[7433]78enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
[7390]79{
80    memset (address, 0, sizeof (ENetAddress));
81    if (sin -> sa_family == AF_INET)
82    {
[7433]83        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
[7392]84        /* address -> scopeID = 0; */
[7433]85        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
[7390]86        return ENET_IPV4;
87    }
88    if (sin -> sa_family == AF_INET6)
89    {
[7433]90        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
91        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
92        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
[7390]93        return ENET_IPV6;
94    }
95    return ENET_NO_ADDRESS_FAMILY;
96}
97
98static int
[7433]99enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
[7390]100{
101    memset (sin, 0, enet_sa_size(family));
102    if (family == ENET_IPV4 &&
103      (enet_get_address_family (address) == ENET_IPV4 ||
104      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
105    {
[7433]106        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
107        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
108        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
[7390]109        return 0;
110    }
111    else if (family == ENET_IPV6)
112    {
[7433]113        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
114        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
115        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
116        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
[7390]117        return 0;
118    }
119    return -1;
120}
121
[7328]122int
123enet_address_set_host (ENetAddress * address, const char * name)
124{
[7390]125    enet_uint16 port = address -> port;
[7433]126    struct addrinfo hints;
127    struct addrinfo * result;
128    struct addrinfo * res;
[7328]129
[7435]130    memset(& hints, 0, sizeof (hints));
131#ifdef AI_ADDRCONFIG
132    hints.ai_flags = AI_ADDRCONFIG;
133#else
134    hints.ai_flags = 0x0400; // AI_ADDRCONFIG is defined as 0x0400
135#endif
[7390]136    hints.ai_family = AF_UNSPEC;
137
138    if ( getaddrinfo(name, NULL, &hints, &result) )
139        return -1;
140
141    for (res = result; res != NULL; res = res -> ai_next)
[7328]142    {
[7390]143        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
144            break;
[7328]145    }
146
[7390]147    address -> port = port;
148    freeaddrinfo(result);
149    if (res == NULL) return -1;
[7328]150
151    return 0;
152}
153
[7390]154static int
155enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
[7328]156{
[7433]157    struct sockaddr_storage sin;
158    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
[7390]159
[7433]160    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
[7328]161        return -1;
[7390]162
[7328]163    return 0;
164}
165
166int
[7390]167enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
168{
169    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
170}
171
172int
[7328]173enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
174{
[7390]175    return enet_address_get_host_x(address, name, nameLength, 0);
[7328]176}
177
178int
[7390]179enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
[7328]180{
[7433]181    struct sockaddr_storage sin;
[7328]182
183    if (address != NULL)
184    {
[7433]185        enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]186    }
187    else
188    {
[7397]189        ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
[7433]190        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
[7328]191    }
192
[7433]193    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
[7328]194}
195
196int
197enet_socket_listen (ENetSocket socket, int backlog)
198{
199    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
200}
201
202ENetSocket
[7390]203enet_socket_create (ENetSocketType type, ENetAddressFamily family)
[7328]204{
[7433]205    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
206    return sock;
[7328]207}
208
209int
210enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
211{
212    int result = SOCKET_ERROR;
213    switch (option)
214    {
215        case ENET_SOCKOPT_NONBLOCK:
216        {
217            u_long nonBlocking = (u_long) value;
218            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
219            break;
220        }
221
222        case ENET_SOCKOPT_BROADCAST:
223            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
224            break;
225
226        case ENET_SOCKOPT_REUSEADDR:
227            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
228            break;
229
230        case ENET_SOCKOPT_RCVBUF:
231            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
232            break;
233
234        case ENET_SOCKOPT_SNDBUF:
235            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
236            break;
237
238        default:
239            break;
240    }
241    return result == SOCKET_ERROR ? -1 : 0;
242}
243
244int
[7390]245enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
[7328]246{
[7433]247    struct sockaddr_storage sin;
248    enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]249
[7433]250    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family)) == SOCKET_ERROR ? -1 : 0;
[7328]251}
252
253ENetSocket
[7390]254enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
[7328]255{
256    SOCKET result;
[7433]257    struct sockaddr_storage sin;
258    socklen_t sinLength = enet_sa_size (family);
[7328]259
260    result = accept (socket, 
[7433]261                     address != NULL ? (struct sockaddr *) & sin : NULL,
[7328]262                     address != NULL ? & sinLength : NULL);
263
264    if (result == INVALID_SOCKET)
265      return ENET_SOCKET_NULL;
266
267    if (address != NULL)
268    {
[7433]269        enet_address_set_address(address, (struct sockaddr *) & sin);
[7328]270    }
271
272    return result;
273}
274
275void
276enet_socket_destroy (ENetSocket socket)
277{
278    closesocket (socket);
279}
280
281int
282enet_socket_send (ENetSocket socket,
283                  const ENetAddress * address,
284                  const ENetBuffer * buffers,
[7390]285                  size_t bufferCount,
286                  ENetAddressFamily family)
[7328]287{
[7433]288    struct sockaddr_storage sin;
[7328]289    DWORD sentLength;
290
291    if (address != NULL)
292    {
[7433]293        enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]294    }
295
296    if (WSASendTo (socket, 
297                   (LPWSABUF) buffers,
298                   (DWORD) bufferCount,
299                   & sentLength,
300                   0,
[7433]301                   address != NULL ? (struct sockaddr *) & sin : 0,
[7390]302                   address != NULL ? enet_sa_size (family) : 0,
[7328]303                   NULL,
304                   NULL) == SOCKET_ERROR)
305    {
306       if (WSAGetLastError () == WSAEWOULDBLOCK)
307         return 0;
308
309       return -1;
310    }
311
312    return (int) sentLength;
313}
314
315int
316enet_socket_receive (ENetSocket socket,
317                     ENetAddress * address,
318                     ENetBuffer * buffers,
[7390]319                     size_t bufferCount,
320                     ENetAddressFamily family)
[7328]321{
[7390]322    INT sinLength = enet_sa_size (family);
[7328]323    DWORD flags = 0,
324          recvLength;
[7433]325    struct sockaddr_storage sin;
[7328]326
327    if (WSARecvFrom (socket,
328                     (LPWSABUF) buffers,
329                     (DWORD) bufferCount,
330                     & recvLength,
331                     & flags,
[7433]332                     address != NULL ? (struct sockaddr *) & sin : NULL,
[7328]333                     address != NULL ? & sinLength : NULL,
334                     NULL,
335                     NULL) == SOCKET_ERROR)
336    {
337       switch (WSAGetLastError ())
338       {
339       case WSAEWOULDBLOCK:
340       case WSAECONNRESET:
341          return 0;
342       }
343
344       return -1;
345    }
346
347    if (flags & MSG_PARTIAL)
348      return -1;
349
350    if (address != NULL)
351    {
[7433]352        enet_address_set_address(address, (struct sockaddr *) & sin);
[7328]353    }
354
355    return (int) recvLength;
356}
357
358int
359enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
360{
361    struct timeval timeVal;
362
363    timeVal.tv_sec = timeout / 1000;
364    timeVal.tv_usec = (timeout % 1000) * 1000;
365
366    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
367}
368
369int
[7390]370enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
[7328]371{
372    fd_set readSet, writeSet;
373    struct timeval timeVal;
374    int selectCount;
[7391]375    ENetSocket maxSocket;
[7390]376
[7328]377    timeVal.tv_sec = timeout / 1000;
378    timeVal.tv_usec = (timeout % 1000) * 1000;
[7390]379
[7328]380    FD_ZERO (& readSet);
381    FD_ZERO (& writeSet);
382
383    if (* condition & ENET_SOCKET_WAIT_SEND)
[7390]384    {
385        if (socket4 != ENET_SOCKET_NULL)
386            FD_SET (socket4, & writeSet);
387        if (socket6 != ENET_SOCKET_NULL)
388            FD_SET (socket6, & writeSet);
389    }
[7328]390
391    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
[7390]392    {
393        if (socket4 != ENET_SOCKET_NULL)
394            FD_SET (socket4, & readSet);
395        if (socket6 != ENET_SOCKET_NULL)
396            FD_SET (socket6, & readSet);
397    }
[7328]398
[7391]399    maxSocket = 0;
[7390]400    if (socket4 != ENET_SOCKET_NULL)
401        maxSocket = socket4;
402    if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
403        maxSocket = socket6;
[7328]404
[7390]405    selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
406
[7328]407    if (selectCount < 0)
408      return -1;
409
410    * condition = ENET_SOCKET_WAIT_NONE;
411
412    if (selectCount == 0)
413      return 0;
414
[7390]415    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
416        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
417        * condition |= ENET_SOCKET_WAIT_SEND;
[7328]418
[7390]419    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & readSet)) ||
420        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & readSet)) )
421        * condition |= ENET_SOCKET_WAIT_RECEIVE;
422
[7328]423    return 0;
[7390]424}
[7328]425
426#endif
427
Note: See TracBrowser for help on using the repository browser.