Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7433 was 7433, checked in by adrfried, 14 years ago

use the structs itself instead of typedefs

also dropped the superfluous AI_NUMERICSERV

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