Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ipv6/src/external/enet/patches/0005-IPv6-for-Windows.patch @ 7394

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

IPv6 for Windows

I have not tested this, please test this and report issues to me.

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