Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/enet/win32.c @ 10915

Last change on this file since 10915 was 9683, checked in by landauf, 11 years ago

mingw with gcc 4.8 has its own version of sdkddkver.h which apparently requires different defines. it looks like those different defines work for all versions of mingw. we use now normal defines for msvc and different defines for mingw.
removed define from win32.c since it's already defined by a compiler flag

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