Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/enet/patches/0001-IPv6-support.patch @ 7669

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

Merged ipv6 branch

Orxonox now includes a modified version of ENet 1.3.0

  • Property svn:eol-style set to native
File size: 44.1 KB
RevLine 
[7443]1From 68e3ac1c2876aedb62a77fdc7ba71e4983a6b99d Mon Sep 17 00:00:00 2001
2From: Adrian Friedli <adi@koalatux.ch>
3Date: Thu, 2 Sep 2010 14:26:42 +0200
4Subject: [PATCH] IPv6 support
5
6---
7 host.c               |   57 +++++++---
8 include/enet/enet.h  |   64 ++++++++---
9 include/enet/win32.h |    5 +
10 protocol.c           |   73 ++++++++++--
11 unix.c               |  312 ++++++++++++++++++++++++++++++--------------------
12 win32.c              |  245 ++++++++++++++++++++++++++--------------
13 6 files changed, 506 insertions(+), 250 deletions(-)
14
15diff --git a/host.c b/host.c
16index 8bb2433..a9d157b 100644
17--- a/host.c
18+++ b/host.c
19@@ -7,6 +7,30 @@
20 #include <time.h>
21 #include "enet/enet.h"
22 
23+static ENetSocket
24+enet_socket_create_bind (const ENetAddress * address, ENetAddressFamily family)
25+{
26+    ENetSocket socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, family);
27+    if (socket == ENET_SOCKET_NULL)
28+        return ENET_SOCKET_NULL;
29+
30+    /* This is not a conditional bind anymore,
31+     * because WSARecvFrom returned WSAEINVAL on the IPv6 socket.
32+     * TODO: Check for it's consequences. */
33+    if (enet_socket_bind (socket, address, family) < 0)
34+    {
35+        enet_socket_destroy (socket);
36+        return ENET_SOCKET_NULL;
37+    }
38+
39+    enet_socket_set_option (socket, ENET_SOCKOPT_NONBLOCK, 1);
40+    enet_socket_set_option (socket, ENET_SOCKOPT_BROADCAST, 1);
41+    enet_socket_set_option (socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
42+    enet_socket_set_option (socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
43+
44+    return socket;
45+}
46+
47 /** @defgroup host ENet host functions
48     @{
49 */
50@@ -31,6 +55,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
51 {
52     ENetHost * host;
53     ENetPeer * currentPeer;
54+    int family;
55 
56     if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
57       return NULL;
58@@ -48,23 +73,24 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
59     }
60     memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
61 
62-    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
63-    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
64-    {
65-       if (host -> socket != ENET_SOCKET_NULL)
66-         enet_socket_destroy (host -> socket);
67+    family = (address == NULL || !memcmp (& address -> host, & ENET_HOST_ANY, sizeof (ENetHostAddress))) ?
68+        ENET_IPV4 | ENET_IPV6 :
69+        enet_get_address_family (address);
70 
71-       enet_free (host -> peers);
72-       enet_free (host);
73+    host -> socket4 = (family & ENET_IPV4) ?
74+      enet_socket_create_bind (address, ENET_IPV4) :
75+      ENET_SOCKET_NULL;
76+    host -> socket6 = (family & ENET_IPV6) ?
77+      enet_socket_create_bind (address, ENET_IPV6) :
78+      ENET_SOCKET_NULL;
79 
80-       return NULL;
81+    if (host -> socket4 == ENET_SOCKET_NULL && host -> socket6 == ENET_SOCKET_NULL)
82+    {
83+        enet_free (host -> peers);
84+        enet_free (host);
85+        return NULL;
86     }
87 
88-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
89-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
90-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
91-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
92-
93     if (address != NULL)
94       host -> address = * address;
95 
96@@ -133,7 +159,10 @@ enet_host_destroy (ENetHost * host)
97 {
98     ENetPeer * currentPeer;
99 
100-    enet_socket_destroy (host -> socket);
101+    if (host -> socket4 != ENET_SOCKET_NULL)
102+      enet_socket_destroy (host -> socket4);
103+    if (host -> socket6 != ENET_SOCKET_NULL)
104+      enet_socket_destroy (host -> socket6);
105 
106     for (currentPeer = host -> peers;
107          currentPeer < & host -> peers [host -> peerCount];
108diff --git a/include/enet/enet.h b/include/enet/enet.h
109index 2f656d6..7b468a0 100644
110--- a/include/enet/enet.h
111+++ b/include/enet/enet.h
112@@ -53,12 +53,20 @@ typedef enum _ENetSocketOption
113    ENET_SOCKOPT_REUSEADDR = 5
114 } ENetSocketOption;
115 
116-enum
117+typedef struct _ENetHostAddress
118 {
119-   ENET_HOST_ANY       = 0,            /**< specifies the default server host */
120-   ENET_HOST_BROADCAST = 0xFFFFFFFF,   /**< specifies a subnet-wide broadcast */
121-
122-   ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
123+   enet_uint8 addr[16];
124+} ENetHostAddress;
125+
126+#define ENET_HOST_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }                         /**< specifies the default server host (macro for variable initialization) */
127+static const ENetHostAddress ENET_HOST_ANY = ENET_HOST_ANY_INIT;                           /**< specifies the default server host (global constant variable) */
128+#define ENET_IPV4MAPPED_PREFIX_INIT { { 0,0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,0,0 } }          /**< specifies the IPv4-mapped IPv6 prefix (macro for variable initialization) */
129+static const ENetHostAddress ENET_IPV4MAPPED_PREFIX = ENET_IPV4MAPPED_PREFIX_INIT;         /**< specifies the IPv4-mapped IPv6 prefix (global constant variable) */
130+#define ENET_HOST_BROADCAST_INIT { { 0,0,0,0,0,0,0,0,0,0,0xff,0xff,0xff,0xff,0xff,0xff } } /**< specifies a IPv4 subnet-wide broadcast (macro for variable initialization) */
131+static const ENetHostAddress ENET_HOST_BROADCAST = ENET_HOST_BROADCAST_INIT;               /**< specifies a IPv4 subnet-wide broadcast (global constant variable) */
132+enum {
133+    ENET_IPV4MAPPED_PREFIX_LEN = 12,                                                       /**< specifies the length of the IPv4-mapped IPv6 prefix */
134+    ENET_PORT_ANY              = 0                                                         /**< specifies that a port should be automatically chosen */
135 };
136 
137 /**
138@@ -73,11 +81,26 @@ enum
139  */
140 typedef struct _ENetAddress
141 {
142-   enet_uint32 host;
143+   ENetHostAddress host;
144+#ifdef WIN32
145+   u_long scopeID;
146+#else
147+   uint32_t scopeID;
148+#endif
149    enet_uint16 port;
150 } ENetAddress;
151 
152 /**
153+ * The address family type.
154+ */
155+typedef enum _ENetAddressFamily
156+{
157+    ENET_NO_ADDRESS_FAMILY = 0,
158+    ENET_IPV4 = (1 << 0),
159+    ENET_IPV6 = (1 << 1)
160+} ENetAddressFamily;
161+
162+/**
163  * Packet flag bit constants.
164  *
165  * The host must be specified in network byte-order, and the port must be in
166@@ -321,7 +344,8 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b
167   */
168 typedef struct _ENetHost
169 {
170-   ENetSocket           socket;
171+   ENetSocket           socket4;
172+   ENetSocket           socket6;
173    ENetAddress          address;                     /**< Internet address of the host */
174    enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
175    enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
176@@ -441,14 +465,14 @@ ENET_API void enet_time_set (enet_uint32);
177 /** @defgroup socket ENet socket functions
178     @{
179 */
180-ENET_API ENetSocket enet_socket_create (ENetSocketType);
181-ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *);
182+ENET_API ENetSocket enet_socket_create (ENetSocketType, ENetAddressFamily);
183+ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *, ENetAddressFamily);
184 ENET_API int        enet_socket_listen (ENetSocket, int);
185-ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
186-ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *);
187-ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
188-ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
189-ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
190+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *, ENetAddressFamily);
191+ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *, ENetAddressFamily);
192+ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t, ENetAddressFamily);
193+ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t, ENetAddressFamily);
194+ENET_API int        enet_socket_wait (ENetSocket, ENetSocket, enet_uint32 *, enet_uint32);
195 ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
196 ENET_API void       enet_socket_destroy (ENetSocket);
197 ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
198@@ -488,6 +512,18 @@ ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN
199 */
200 ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
201 
202+/** Maps an IPv4 Address to an IPv6 address.
203+    @param address IPv4 address in network byte order
204+    @returns the IPv4-mapped IPv6 address in network byte order
205+*/
206+ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address);
207+
208+/** Returns the Address family of an (IPv4-mapped) IPv6 address.
209+    @param address IPv6 address
210+    @returns address family
211+*/
212+ENET_API ENetAddressFamily enet_get_address_family (const ENetAddress * address);
213+
214 /** @} */
215 
216 ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
217diff --git a/include/enet/win32.h b/include/enet/win32.h
218index 0e1cf0c..53a7ff7 100644
219--- a/include/enet/win32.h
220+++ b/include/enet/win32.h
221@@ -14,6 +14,7 @@
222 
223 #include <stdlib.h>
224 #include <winsock2.h>
225+#include <ws2tcpip.h>
226 
227 typedef SOCKET ENetSocket;
228 
229@@ -53,6 +54,10 @@ typedef fd_set ENetSocketSet;
230 #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
231 #define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
232 
233+#ifndef AI_ADDRCONFIG
234+#define AI_ADDRCONFIG 0x0400 /* AI_ADDRCONFIG is not defined everywhere */
235+#endif
236+
237 #endif /* __ENET_WIN32_H__ */
238 
239 
240diff --git a/protocol.c b/protocol.c
241index 8e26dfb..cfef646 100644
242--- a/protocol.c
243+++ b/protocol.c
244@@ -25,6 +25,22 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
245     sizeof (ENetProtocolThrottleConfigure),
246 };
247 
248+ENetHostAddress
249+enet_address_map4 (enet_uint32 address)
250+{
251+    ENetHostAddress addr = ENET_IPV4MAPPED_PREFIX_INIT;
252+    ((enet_uint32 *)addr.addr)[3] = address;
253+    return addr;
254+}
255+
256+ENetAddressFamily
257+enet_get_address_family (const ENetAddress * address)
258+{
259+    if (!memcmp(& address->host, & ENET_IPV4MAPPED_PREFIX, ENET_IPV4MAPPED_PREFIX_LEN))
260+        return ENET_IPV4;
261+    return ENET_IPV6;
262+}
263+
264 size_t
265 enet_protocol_command_size (enet_uint8 commandNumber)
266 {
267@@ -262,9 +278,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
268          ++ currentPeer)
269     {
270         if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
271-            currentPeer -> address.host == host -> receivedAddress.host &&
272             currentPeer -> address.port == host -> receivedAddress.port &&
273-            currentPeer -> connectID == command -> connect.connectID)
274+            currentPeer -> connectID == command -> connect.connectID &&
275+            !memcmp(& currentPeer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)))
276           return NULL;
277     }
278 
279@@ -848,10 +864,11 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
280 
281        if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
282            peer -> state == ENET_PEER_STATE_ZOMBIE ||
283-           (host -> receivedAddress.host != peer -> address.host &&
284-             peer -> address.host != ENET_HOST_BROADCAST) ||
285            (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
286-            sessionID != peer -> incomingSessionID))
287+            sessionID != peer -> incomingSessionID) ||
288+           ( memcmp(& peer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)) &&
289+             memcmp(& peer -> address.host, & ENET_HOST_BROADCAST, sizeof (ENetHostAddress)) &&
290+             peer -> address.host.addr[0] != 0xff ) )
291          return 0;
292     }
293 
294@@ -891,8 +908,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
295       
296     if (peer != NULL)
297     {
298-       peer -> address.host = host -> receivedAddress.host;
299-       peer -> address.port = host -> receivedAddress.port;
300+       peer -> address = host -> receivedAddress;
301        peer -> incomingDataTotal += host -> receivedDataLength;
302     }
303     
304@@ -1021,7 +1037,7 @@ commandError:
305 }
306 
307 static int
308-enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
309+enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event, ENetAddressFamily family)
310 {
311     for (;;)
312     {
313@@ -1031,10 +1047,11 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
314        buffer.data = host -> packetData [0];
315        buffer.dataLength = sizeof (host -> packetData [0]);
316 
317-       receivedLength = enet_socket_receive (host -> socket,
318+       receivedLength = enet_socket_receive (family == ENET_IPV4 ? host -> socket4 : host -> socket6,
319                                              & host -> receivedAddress,
320                                              & buffer,
321-                                             1);
322+                                             1,
323+                                             family);
324 
325        if (receivedLength < 0)
326          return -1;
327@@ -1042,6 +1059,9 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
328        if (receivedLength == 0)
329          return 0;
330 
331+       if (enet_get_address_family (& host -> receivedAddress) != family)
332+         return -1;
333+
334        host -> receivedData = host -> packetData [0];
335        host -> receivedDataLength = receivedLength;
336       
337@@ -1373,6 +1393,9 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
338          currentPeer < & host -> peers [host -> peerCount];
339          ++ currentPeer)
340     {
341+        ENetAddressFamily family;
342+        ENetSocket socket;
343+
344         if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
345             currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
346           continue;
347@@ -1497,7 +1520,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
348 
349         currentPeer -> lastSendTime = host -> serviceTime;
350 
351-        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
352+        family = enet_get_address_family (& currentPeer -> address);
353+        socket = family == ENET_IPV4 ? host -> socket4 : host -> socket6;
354+        if (socket == ENET_SOCKET_NULL)
355+          return -1;
356+        sentLength = enet_socket_send (socket,
357+                                           & currentPeer -> address,
358+                                           host -> buffers,
359+                                           host -> bufferCount,
360+                                           family);
361 
362         enet_protocol_remove_sent_unreliable_commands (currentPeer);
363 
364@@ -1608,7 +1639,23 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
365           break;
366        }
367 
368-       switch (enet_protocol_receive_incoming_commands (host, event))
369+       if (host -> socket4 != ENET_SOCKET_NULL)
370+         switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV4))
371+       {
372+       case 1:
373+          return 1;
374+
375+       case -1:
376+          perror ("Error receiving incoming packets");
377+
378+          return -1;
379+
380+       default:
381+          break;
382+       }
383+
384+       if (host -> socket6 != ENET_SOCKET_NULL)
385+         switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV6))
386        {
387        case 1:
388           return 1;
389@@ -1660,7 +1707,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
390 
391        waitCondition = ENET_SOCKET_WAIT_RECEIVE;
392 
393-       if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
394+       if (enet_socket_wait (host -> socket4, host -> socket6, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
395          return -1;
396       
397        host -> serviceTime = enet_time_get ();
398diff --git a/unix.c b/unix.c
399index 6971541..992ecd3 100644
400--- a/unix.c
401+++ b/unix.c
402@@ -71,122 +71,161 @@ enet_time_set (enet_uint32 newTimeBase)
403     timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
404 }
405 
406-int
407-enet_address_set_host (ENetAddress * address, const char * name)
408+static enet_uint16
409+enet_af (ENetAddressFamily family)
410 {
411-    struct hostent * hostEntry = NULL;
412-#ifdef HAS_GETHOSTBYNAME_R
413-    struct hostent hostData;
414-    char buffer [2048];
415-    int errnum;
416-
417-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
418-    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
419-#else
420-    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
421-#endif
422-#else
423-    hostEntry = gethostbyname (name);
424-#endif
425+    if (family == ENET_IPV4)
426+        return AF_INET;
427+    if (family == ENET_IPV6)
428+        return AF_INET6;
429+    return 0;
430+}
431+
432+static socklen_t
433+enet_sa_size (ENetAddressFamily family)
434+{
435+    if (family == ENET_IPV4)
436+        return sizeof (struct sockaddr_in);
437+    if (family == ENET_IPV6)
438+        return sizeof (struct sockaddr_in6);
439+    return 0;
440+}
441 
442-    if (hostEntry == NULL ||
443-        hostEntry -> h_addrtype != AF_INET)
444+static ENetAddressFamily
445+enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
446+{
447+    memset (address, 0, sizeof (ENetAddress));
448+    if (sin -> sa_family == AF_INET)
449     {
450-#ifdef HAS_INET_PTON
451-        if (! inet_pton (AF_INET, name, & address -> host))
452-#else
453-        if (! inet_aton (name, (struct in_addr *) & address -> host))
454-#endif
455-            return -1;
456-        return 0;
457+        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
458+        /* address -> scopeID = 0; */
459+        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
460+        return ENET_IPV4;
461     }
462-
463-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
464-
465-    return 0;
466+    if (sin -> sa_family == AF_INET6)
467+    {
468+        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
469+        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
470+        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
471+        return ENET_IPV6;
472+    }
473+    return ENET_NO_ADDRESS_FAMILY;
474 }
475 
476-int
477-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
478+static int
479+enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
480 {
481-#ifdef HAS_INET_NTOP
482-    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
483-#else
484-    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
485-    if (addr != NULL)
486-        strncpy (name, addr, nameLength);
487-    else
488-#endif
489-        return -1;
490-    return 0;
491+    memset (sin, 0, enet_sa_size(family));
492+    if (family == ENET_IPV4 &&
493+      (enet_get_address_family (address) == ENET_IPV4 ||
494+      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
495+    {
496+        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
497+        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
498+        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
499+        return 0;
500+    }
501+    else if (family == ENET_IPV6)
502+    {
503+        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
504+        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
505+        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
506+        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
507+        return 0;
508+    }
509+    return -1;
510 }
511 
512 int
513-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
514+enet_address_set_host (ENetAddress * address, const char * name)
515 {
516-    struct in_addr in;
517-    struct hostent * hostEntry = NULL;
518-#ifdef HAS_GETHOSTBYADDR_R
519-    struct hostent hostData;
520-    char buffer [2048];
521-    int errnum;
522+    enet_uint16 port = address -> port;
523+    struct addrinfo hints;
524+    struct addrinfo * result;
525+    struct addrinfo * res;
526 
527-    in.s_addr = address -> host;
528+    memset(& hints, 0, sizeof (hints));
529+    hints.ai_flags = AI_ADDRCONFIG;
530+    hints.ai_family = AF_UNSPEC;
531 
532-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
533-    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
534-#else
535-    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
536-#endif
537-#else
538-    in.s_addr = address -> host;
539+    if ( getaddrinfo(name, NULL, &hints, &result) )
540+        return -1;
541 
542-    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
543-#endif
544+    for (res = result; res != NULL; res = res -> ai_next)
545+    {
546+        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
547+            break;
548+    }
549 
550-    if (hostEntry == NULL)
551-      return enet_address_get_host_ip (address, name, nameLength);
552+    address -> port = port;
553+    freeaddrinfo(result);
554+    if (res == NULL) return -1;
555 
556-    strncpy (name, hostEntry -> h_name, nameLength);
557+    return 0;
558+}
559+
560+static int
561+enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
562+{
563+    struct sockaddr_storage sin;
564+    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
565+
566+    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
567+        return -1;
568 
569     return 0;
570 }
571 
572 int
573-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
574+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
575 {
576-    struct sockaddr_in sin;
577+    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
578+}
579 
580-    memset (& sin, 0, sizeof (struct sockaddr_in));
581+int
582+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
583+{
584+    return enet_address_get_host_x(address, name, nameLength, 0);
585+}
586 
587-    sin.sin_family = AF_INET;
588+int
589+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
590+{
591+    struct sockaddr_storage sin;
592 
593     if (address != NULL)
594     {
595-       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
596-       sin.sin_addr.s_addr = address -> host;
597+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
598     }
599     else
600     {
601-       sin.sin_port = 0;
602-       sin.sin_addr.s_addr = INADDR_ANY;
603+        ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
604+        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
605     }
606 
607-    return bind (socket,
608-                 (struct sockaddr *) & sin,
609-                 sizeof (struct sockaddr_in));
610+    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family));
611 }
612 
613-int
614+int
615 enet_socket_listen (ENetSocket socket, int backlog)
616 {
617     return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
618 }
619 
620 ENetSocket
621-enet_socket_create (ENetSocketType type)
622+enet_socket_create (ENetSocketType type, ENetAddressFamily family)
623 {
624-    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
625+    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
626+
627+#ifdef IPV6_V6ONLY
628+    if (family == ENET_IPV6)
629+    {
630+        int value = 1;
631+        setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
632+    }
633+#endif /* IPV6_V6ONLY */
634+
635+    return sock;
636 }
637 
638 int
639@@ -226,42 +265,36 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
640 }
641 
642 int
643-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
644+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
645 {
646-    struct sockaddr_in sin;
647-
648-    memset (& sin, 0, sizeof (struct sockaddr_in));
649+    struct sockaddr_storage sin;
650+    enet_address_set_sin((struct sockaddr *) & sin, address, family);
651 
652-    sin.sin_family = AF_INET;
653-    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
654-    sin.sin_addr.s_addr = address -> host;
655-
656-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
657+    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family));
658 }
659 
660 ENetSocket
661-enet_socket_accept (ENetSocket socket, ENetAddress * address)
662+enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
663 {
664     int result;
665-    struct sockaddr_in sin;
666-    socklen_t sinLength = sizeof (struct sockaddr_in);
667+    struct sockaddr_storage sin;
668+    socklen_t sinLength = enet_sa_size (family);
669 
670     result = accept (socket,
671-                     address != NULL ? (struct sockaddr *) & sin : NULL,
672+                     address != NULL ? (struct sockaddr *) & sin : NULL,
673                      address != NULL ? & sinLength : NULL);
674-   
675+
676     if (result == -1)
677       return ENET_SOCKET_NULL;
678 
679     if (address != NULL)
680     {
681-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
682-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
683+        enet_address_set_address(address, (struct sockaddr *) & sin);
684     }
685 
686     return result;
687-}
688-   
689+}
690+
691 void
692 enet_socket_destroy (ENetSocket socket)
693 {
694@@ -272,24 +305,20 @@ int
695 enet_socket_send (ENetSocket socket,
696                   const ENetAddress * address,
697                   const ENetBuffer * buffers,
698-                  size_t bufferCount)
699+                  size_t bufferCount,
700+                  ENetAddressFamily family)
701 {
702     struct msghdr msgHdr;
703-    struct sockaddr_in sin;
704+    struct sockaddr_storage sin;
705     int sentLength;
706 
707     memset (& msgHdr, 0, sizeof (struct msghdr));
708 
709     if (address != NULL)
710     {
711-        memset (& sin, 0, sizeof (struct sockaddr_in));
712-
713-        sin.sin_family = AF_INET;
714-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
715-        sin.sin_addr.s_addr = address -> host;
716-
717+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
718         msgHdr.msg_name = & sin;
719-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
720+        msgHdr.msg_namelen = enet_sa_size (family);
721     }
722 
723     msgHdr.msg_iov = (struct iovec *) buffers;
724@@ -312,10 +341,11 @@ int
725 enet_socket_receive (ENetSocket socket,
726                      ENetAddress * address,
727                      ENetBuffer * buffers,
728-                     size_t bufferCount)
729+                     size_t bufferCount,
730+                     ENetAddressFamily family)
731 {
732     struct msghdr msgHdr;
733-    struct sockaddr_in sin;
734+    struct sockaddr_storage sin;
735     int recvLength;
736 
737     memset (& msgHdr, 0, sizeof (struct msghdr));
738@@ -323,7 +353,7 @@ enet_socket_receive (ENetSocket socket,
739     if (address != NULL)
740     {
741         msgHdr.msg_name = & sin;
742-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
743+        msgHdr.msg_namelen = enet_sa_size (family);
744     }
745 
746     msgHdr.msg_iov = (struct iovec *) buffers;
747@@ -346,8 +376,7 @@ enet_socket_receive (ENetSocket socket,
748 
749     if (address != NULL)
750     {
751-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
752-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
753+        enet_address_set_address(address, (struct sockaddr *) & sin);
754     }
755 
756     return recvLength;
757@@ -365,22 +394,38 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
758 }
759 
760 int
761-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
762+enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
763 {
764 #ifdef HAS_POLL
765-    struct pollfd pollSocket;
766+    struct pollfd pollSocket[2];
767     int pollCount;
768-   
769-    pollSocket.fd = socket;
770-    pollSocket.events = 0;
771+
772+    pollSocket[0].fd = socket4;
773+    pollSocket[1].fd = socket6;
774+    pollSocket[0].events = 0;
775+    pollSocket[1].events = 0;
776+    /* pollSocket[0].revents = 0; */
777+    pollSocket[1].revents = 0;
778+
779+    if (pollSocket[0].fd == ENET_SOCKET_NULL)
780+    {
781+        pollSocket[0].fd = pollSocket[1].fd;
782+        pollSocket[1].fd = ENET_SOCKET_NULL;
783+    }
784 
785     if (* condition & ENET_SOCKET_WAIT_SEND)
786-      pollSocket.events |= POLLOUT;
787+    {
788+        pollSocket[0].events |= POLLOUT;
789+        pollSocket[1].events |= POLLOUT;
790+    }
791 
792     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
793-      pollSocket.events |= POLLIN;
794+    {
795+        pollSocket[0].events |= POLLIN;
796+        pollSocket[1].events |= POLLIN;
797+    }
798 
799-    pollCount = poll (& pollSocket, 1, timeout);
800+    pollCount = poll (pollSocket, pollSocket[1].fd != ENET_SOCKET_NULL ? 2 : 1, timeout);
801 
802     if (pollCount < 0)
803       return -1;
804@@ -390,10 +435,10 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
805     if (pollCount == 0)
806       return 0;
807 
808-    if (pollSocket.revents & POLLOUT)
809+    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLOUT)
810       * condition |= ENET_SOCKET_WAIT_SEND;
811     
812-    if (pollSocket.revents & POLLIN)
813+    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLIN)
814       * condition |= ENET_SOCKET_WAIT_RECEIVE;
815 
816     return 0;
817@@ -401,6 +446,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
818     fd_set readSet, writeSet;
819     struct timeval timeVal;
820     int selectCount;
821+    ENetSocket maxSocket;
822 
823     timeVal.tv_sec = timeout / 1000;
824     timeVal.tv_usec = (timeout % 1000) * 1000;
825@@ -409,12 +455,28 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
826     FD_ZERO (& writeSet);
827 
828     if (* condition & ENET_SOCKET_WAIT_SEND)
829-      FD_SET (socket, & writeSet);
830+    {
831+        if (socket4 != ENET_SOCKET_NULL)
832+            FD_SET (socket4, & writeSet);
833+        if (socket6 != ENET_SOCKET_NULL)
834+            FD_SET (socket6, & writeSet);
835+    }
836 
837     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
838-      FD_SET (socket, & readSet);
839+    {
840+        if (socket4 != ENET_SOCKET_NULL)
841+            FD_SET (socket4, & readSet);
842+        if (socket6 != ENET_SOCKET_NULL)
843+            FD_SET (socket6, & readSet);
844+    }
845+
846+    maxSocket = 0;
847+    if (socket4 != ENET_SOCKET_NULL)
848+        maxSocket = socket4;
849+    if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
850+        maxSocket = socket6;
851 
852-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
853+    selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
854 
855     if (selectCount < 0)
856       return -1;
857@@ -424,11 +486,13 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
858     if (selectCount == 0)
859       return 0;
860 
861-    if (FD_ISSET (socket, & writeSet))
862-      * condition |= ENET_SOCKET_WAIT_SEND;
863+    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
864+        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
865+        * condition |= ENET_SOCKET_WAIT_SEND;
866 
867-    if (FD_ISSET (socket, & readSet))
868-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
869+    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & readSet)) ||
870+        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & readSet)) )
871+        * condition |= ENET_SOCKET_WAIT_RECEIVE;
872 
873     return 0;
874 #endif
875diff --git a/win32.c b/win32.c
876index e1fae23..2607160 100644
877--- a/win32.c
878+++ b/win32.c
879@@ -4,6 +4,8 @@
880 */
881 #ifdef WIN32
882 
883+#define _WIN32_WINNT 0x0501
884+
885 #include <time.h>
886 #define ENET_BUILDING_LIB 1
887 #include "enet/enet.h"
888@@ -13,14 +15,14 @@ static enet_uint32 timeBase = 0;
889 int
890 enet_initialize (void)
891 {
892-    WORD versionRequested = MAKEWORD (1, 1);
893+    WORD versionRequested = MAKEWORD (2, 2);
894     WSADATA wsaData;
895   
896     if (WSAStartup (versionRequested, & wsaData))
897        return -1;
898 
899-    if (LOBYTE (wsaData.wVersion) != 1||
900-        HIBYTE (wsaData.wVersion) != 1)
901+    if (LOBYTE (wsaData.wVersion) != 2||
902+        HIBYTE (wsaData.wVersion) != 2)
903     {
904        WSACleanup ();
905       
906@@ -52,77 +54,139 @@ enet_time_set (enet_uint32 newTimeBase)
907     timeBase = (enet_uint32) timeGetTime () - newTimeBase;
908 }
909 
910-int
911-enet_address_set_host (ENetAddress * address, const char * name)
912+static enet_uint16
913+enet_af (ENetAddressFamily family)
914 {
915-    struct hostent * hostEntry;
916+    if (family == ENET_IPV4)
917+        return AF_INET;
918+    if (family == ENET_IPV6)
919+        return AF_INET6;
920+    return 0;
921+}
922 
923-    hostEntry = gethostbyname (name);
924-    if (hostEntry == NULL ||
925-        hostEntry -> h_addrtype != AF_INET)
926+static socklen_t
927+enet_sa_size (ENetAddressFamily family)
928+{
929+    if (family == ENET_IPV4)
930+        return sizeof (struct sockaddr_in);
931+    if (family == ENET_IPV6)
932+        return sizeof (struct sockaddr_in6);
933+    return 0;
934+}
935+
936+static ENetAddressFamily
937+enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
938+{
939+    memset (address, 0, sizeof (ENetAddress));
940+    if (sin -> sa_family == AF_INET)
941     {
942-        unsigned long host = inet_addr (name);
943-        if (host == INADDR_NONE)
944-            return -1;
945-        address -> host = host;
946-        return 0;
947+        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
948+        /* address -> scopeID = 0; */
949+        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
950+        return ENET_IPV4;
951     }
952+    if (sin -> sa_family == AF_INET6)
953+    {
954+        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
955+        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
956+        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
957+        return ENET_IPV6;
958+    }
959+    return ENET_NO_ADDRESS_FAMILY;
960+}
961 
962-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
963-
964-    return 0;
965+static int
966+enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
967+{
968+    memset (sin, 0, enet_sa_size(family));
969+    if (family == ENET_IPV4 &&
970+      (enet_get_address_family (address) == ENET_IPV4 ||
971+      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
972+    {
973+        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
974+        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
975+        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
976+        return 0;
977+    }
978+    else if (family == ENET_IPV6)
979+    {
980+        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
981+        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
982+        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
983+        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
984+        return 0;
985+    }
986+    return -1;
987 }
988 
989 int
990-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
991+enet_address_set_host (ENetAddress * address, const char * name)
992 {
993-    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
994-    if (addr == NULL)
995+    enet_uint16 port = address -> port;
996+    struct addrinfo hints;
997+    struct addrinfo * result;
998+    struct addrinfo * res;
999+
1000+    memset(& hints, 0, sizeof (hints));
1001+    hints.ai_flags = AI_ADDRCONFIG;
1002+    hints.ai_family = AF_UNSPEC;
1003+
1004+    if ( getaddrinfo(name, NULL, &hints, &result) )
1005         return -1;
1006-    strncpy (name, addr, nameLength);
1007+
1008+    for (res = result; res != NULL; res = res -> ai_next)
1009+    {
1010+        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
1011+            break;
1012+    }
1013+
1014+    address -> port = port;
1015+    freeaddrinfo(result);
1016+    if (res == NULL) return -1;
1017+
1018     return 0;
1019 }
1020 
1021-int
1022-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
1023+static int
1024+enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
1025 {
1026-    struct in_addr in;
1027-    struct hostent * hostEntry;
1028-   
1029-    in.s_addr = address -> host;
1030-   
1031-    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
1032-    if (hostEntry == NULL)
1033-      return enet_address_get_host_ip (address, name, nameLength);
1034+    struct sockaddr_storage sin;
1035+    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
1036 
1037-    strncpy (name, hostEntry -> h_name, nameLength);
1038+    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
1039+        return -1;
1040 
1041     return 0;
1042 }
1043 
1044 int
1045-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
1046+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
1047 {
1048-    struct sockaddr_in sin;
1049+    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
1050+}
1051 
1052-    memset (& sin, 0, sizeof (struct sockaddr_in));
1053+int
1054+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
1055+{
1056+    return enet_address_get_host_x(address, name, nameLength, 0);
1057+}
1058 
1059-    sin.sin_family = AF_INET;
1060+int
1061+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
1062+{
1063+    struct sockaddr_storage sin;
1064 
1065     if (address != NULL)
1066     {
1067-       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
1068-       sin.sin_addr.s_addr = address -> host;
1069+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
1070     }
1071     else
1072     {
1073-       sin.sin_port = 0;
1074-       sin.sin_addr.s_addr = INADDR_ANY;
1075+        ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
1076+        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
1077     }
1078 
1079-    return bind (socket,
1080-                 (struct sockaddr *) & sin,
1081-                 sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
1082+    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
1083 }
1084 
1085 int
1086@@ -132,9 +196,10 @@ enet_socket_listen (ENetSocket socket, int backlog)
1087 }
1088 
1089 ENetSocket
1090-enet_socket_create (ENetSocketType type)
1091+enet_socket_create (ENetSocketType type, ENetAddressFamily family)
1092 {
1093-    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
1094+    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
1095+    return sock;
1096 }
1097 
1098 int
1099@@ -173,28 +238,23 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
1100 }
1101 
1102 int
1103-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
1104+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
1105 {
1106-    struct sockaddr_in sin;
1107-
1108-    memset (& sin, 0, sizeof (struct sockaddr_in));
1109+    struct sockaddr_storage sin;
1110+    enet_address_set_sin((struct sockaddr *) & sin, address, family);
1111 
1112-    sin.sin_family = AF_INET;
1113-    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
1114-    sin.sin_addr.s_addr = address -> host;
1115-
1116-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
1117+    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family)) == SOCKET_ERROR ? -1 : 0;
1118 }
1119 
1120 ENetSocket
1121-enet_socket_accept (ENetSocket socket, ENetAddress * address)
1122+enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
1123 {
1124     SOCKET result;
1125-    struct sockaddr_in sin;
1126-    int sinLength = sizeof (struct sockaddr_in);
1127+    struct sockaddr_storage sin;
1128+    socklen_t sinLength = enet_sa_size (family);
1129 
1130     result = accept (socket,
1131-                     address != NULL ? (struct sockaddr *) & sin : NULL,
1132+                     address != NULL ? (struct sockaddr *) & sin : NULL,
1133                      address != NULL ? & sinLength : NULL);
1134 
1135     if (result == INVALID_SOCKET)
1136@@ -202,8 +262,7 @@ enet_socket_accept (ENetSocket socket, ENetAddress * address)
1137 
1138     if (address != NULL)
1139     {
1140-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
1141-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
1142+        enet_address_set_address(address, (struct sockaddr *) & sin);
1143     }
1144 
1145     return result;
1146@@ -219,18 +278,15 @@ int
1147 enet_socket_send (ENetSocket socket,
1148                   const ENetAddress * address,
1149                   const ENetBuffer * buffers,
1150-                  size_t bufferCount)
1151+                  size_t bufferCount,
1152+                  ENetAddressFamily family)
1153 {
1154-    struct sockaddr_in sin;
1155+    struct sockaddr_storage sin;
1156     DWORD sentLength;
1157 
1158     if (address != NULL)
1159     {
1160-        memset (& sin, 0, sizeof (struct sockaddr_in));
1161-
1162-        sin.sin_family = AF_INET;
1163-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
1164-        sin.sin_addr.s_addr = address -> host;
1165+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
1166     }
1167 
1168     if (WSASendTo (socket,
1169@@ -239,7 +295,7 @@ enet_socket_send (ENetSocket socket,
1170                    & sentLength,
1171                    0,
1172                    address != NULL ? (struct sockaddr *) & sin : 0,
1173-                   address != NULL ? sizeof (struct sockaddr_in) : 0,
1174+                   address != NULL ? enet_sa_size (family) : 0,
1175                    NULL,
1176                    NULL) == SOCKET_ERROR)
1177     {
1178@@ -256,12 +312,13 @@ int
1179 enet_socket_receive (ENetSocket socket,
1180                      ENetAddress * address,
1181                      ENetBuffer * buffers,
1182-                     size_t bufferCount)
1183+                     size_t bufferCount,
1184+                     ENetAddressFamily family)
1185 {
1186-    INT sinLength = sizeof (struct sockaddr_in);
1187+    INT sinLength = enet_sa_size (family);
1188     DWORD flags = 0,
1189           recvLength;
1190-    struct sockaddr_in sin;
1191+    struct sockaddr_storage sin;
1192 
1193     if (WSARecvFrom (socket,
1194                      (LPWSABUF) buffers,
1195@@ -288,8 +345,7 @@ enet_socket_receive (ENetSocket socket,
1196 
1197     if (address != NULL)
1198     {
1199-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
1200-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
1201+        enet_address_set_address(address, (struct sockaddr *) & sin);
1202     }
1203 
1204     return (int) recvLength;
1205@@ -307,25 +363,42 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
1206 }
1207 
1208 int
1209-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
1210+enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
1211 {
1212     fd_set readSet, writeSet;
1213     struct timeval timeVal;
1214     int selectCount;
1215-   
1216+    ENetSocket maxSocket;
1217+
1218     timeVal.tv_sec = timeout / 1000;
1219     timeVal.tv_usec = (timeout % 1000) * 1000;
1220-   
1221+
1222     FD_ZERO (& readSet);
1223     FD_ZERO (& writeSet);
1224 
1225     if (* condition & ENET_SOCKET_WAIT_SEND)
1226-      FD_SET (socket, & writeSet);
1227+    {
1228+        if (socket4 != ENET_SOCKET_NULL)
1229+            FD_SET (socket4, & writeSet);
1230+        if (socket6 != ENET_SOCKET_NULL)
1231+            FD_SET (socket6, & writeSet);
1232+    }
1233 
1234     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
1235-      FD_SET (socket, & readSet);
1236+    {
1237+        if (socket4 != ENET_SOCKET_NULL)
1238+            FD_SET (socket4, & readSet);
1239+        if (socket6 != ENET_SOCKET_NULL)
1240+            FD_SET (socket6, & readSet);
1241+    }
1242 
1243-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
1244+    maxSocket = 0;
1245+    if (socket4 != ENET_SOCKET_NULL)
1246+        maxSocket = socket4;
1247+    if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
1248+        maxSocket = socket6;
1249+
1250+    selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
1251 
1252     if (selectCount < 0)
1253       return -1;
1254@@ -335,14 +408,16 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
1255     if (selectCount == 0)
1256       return 0;
1257 
1258-    if (FD_ISSET (socket, & writeSet))
1259-      * condition |= ENET_SOCKET_WAIT_SEND;
1260-   
1261-    if (FD_ISSET (socket, & readSet))
1262-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
1263+    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
1264+        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
1265+        * condition |= ENET_SOCKET_WAIT_SEND;
1266+
1267+    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & readSet)) ||
1268+        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & readSet)) )
1269+        * condition |= ENET_SOCKET_WAIT_RECEIVE;
1270 
1271     return 0;
1272-}
1273+}
1274 
1275 #endif
1276 
1277--
12781.7.1
1279
Note: See TracBrowser for help on using the repository browser.