Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/enet/patches/0001-Add-IPv6-support-to-Enet.patch @ 10580

Last change on this file since 10580 was 8351, checked in by rgrieder, 13 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

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