Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

moved AI_ADDRCONFIG definition to header

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