Index: code/branches/ipv6/src/external/enet/win32.c
===================================================================
--- code/branches/ipv6/src/external/enet/win32.c	(revision 7328)
+++ code/branches/ipv6/src/external/enet/win32.c	(revision 7390)
@@ -53,21 +53,105 @@
 }
 
+static enet_uint16
+enet_af (ENetAddressFamily family)
+{
+    if (family == ENET_IPV4)
+        return AF_INET;
+    if (family == ENET_IPV6)
+        return AF_INET6;
+    return 0;
+}
+
+static socklen_t
+enet_sa_size (ENetAddressFamily family)
+{
+    if (family == ENET_IPV4)
+        return sizeof (SOCKADDR_IN);
+    if (family == ENET_IPV6)
+        return sizeof (SOCKADDR_IN6);
+    return 0;
+}
+
+static ENetAddressFamily
+enet_address_set_address (ENetAddress * address, const SOCKADDR * sin)
+{
+    memset (address, 0, sizeof (ENetAddress));
+    if (sin -> sa_family == AF_INET)
+    {
+        address -> host = enet_address_map4 ((((SOCKADDR_IN *) sin) -> sin_addr.s_addr));
+        //address -> scopeID = 0;
+        address -> port = ENET_NET_TO_HOST_16 (((SOCKADDR_IN *) sin) -> sin_port);
+        return ENET_IPV4;
+    }
+    if (sin -> sa_family == AF_INET6)
+    {
+        address -> host = * (ENetHostAddress *) & ((SOCKADDR_IN6 *) sin) -> sin6_addr;
+        address -> scopeID = ((SOCKADDR_IN6 *) sin) -> sin6_scope_id;
+        address -> port = ENET_NET_TO_HOST_16 (((SOCKADDR_IN6 *) sin) -> sin6_port);
+        return ENET_IPV6;
+    }
+    return ENET_NO_ADDRESS_FAMILY;
+}
+
+static int
+enet_address_set_sin (SOCKADDR * sin, const ENetAddress * address, ENetAddressFamily family)
+{
+    memset (sin, 0, enet_sa_size(family));
+    if (family == ENET_IPV4 &&
+      (enet_get_address_family (address) == ENET_IPV4 ||
+      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
+    {
+        ((SOCKADDR_IN *) sin) -> sin_family = AF_INET;
+        ((SOCKADDR_IN *) sin) -> sin_addr = * (IN_ADDR *) & address -> host.addr[12];
+        ((SOCKADDR_IN *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
+        return 0;
+    }
+    else if (family == ENET_IPV6)
+    {
+        ((SOCKADDR_IN6 *) sin) -> sin6_family = AF_INET6;
+        ((SOCKADDR_IN6 *) sin) -> sin6_addr = * (IN6_ADDR *) & address -> host;
+        ((SOCKADDR_IN6 *) sin) -> sin6_scope_id = address -> scopeID;
+        ((SOCKADDR_IN6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
+        return 0;
+    }
+    return -1;
+}
+
 int
 enet_address_set_host (ENetAddress * address, const char * name)
 {
-    struct hostent * hostEntry;
-
-    hostEntry = gethostbyname (name);
-    if (hostEntry == NULL ||
-        hostEntry -> h_addrtype != AF_INET)
-    {
-        unsigned long host = inet_addr (name);
-        if (host == INADDR_NONE)
-            return -1;
-        address -> host = host;
-        return 0;
-    }
-
-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+    enet_uint16 port = address -> port;
+    ADDRINFO hints;
+    ADDRINFO * result;
+    ADDRINFO * res;
+
+    memset(& hints, 0, sizeof (hints));
+    hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
+    hints.ai_family = AF_UNSPEC;
+
+    if ( getaddrinfo(name, NULL, &hints, &result) )
+        return -1;
+
+    for (res = result; res != NULL; res = res -> ai_next)
+    {
+        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
+            break;
+    }
+
+    address -> port = port;
+    freeaddrinfo(result);
+    if (res == NULL) return -1;
+
+    return 0;
+}
+
+static int
+enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
+{
+    SOCKADDR_STORAGE sin;
+    enet_address_set_sin((SOCKADDR *) & sin, address, ENET_IPV6);
+
+    if ( getnameinfo((SOCKADDR *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
+        return -1;
 
     return 0;
@@ -77,9 +161,5 @@
 enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
 {
-    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
-    if (addr == NULL)
-        return -1;
-    strncpy (name, addr, nameLength);
-    return 0;
+    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
 }
 
@@ -87,41 +167,23 @@
 enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
 {
-    struct in_addr in;
-    struct hostent * hostEntry;
-    
-    in.s_addr = address -> host;
-    
-    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
-    if (hostEntry == NULL)
-      return enet_address_get_host_ip (address, name, nameLength);
-
-    strncpy (name, hostEntry -> h_name, nameLength);
-
-    return 0;
-}
-
-int
-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    memset (& sin, 0, sizeof (struct sockaddr_in));
-
-    sin.sin_family = AF_INET;
+    return enet_address_get_host_x(address, name, nameLength, 0);
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
+{
+    SOCKADDR_STORAGE sin;
 
     if (address != NULL)
     {
-       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-       sin.sin_addr.s_addr = address -> host;
+        enet_address_set_sin((SOCKADDR *) & sin, address, family);
     }
     else
     {
-       sin.sin_port = 0;
-       sin.sin_addr.s_addr = INADDR_ANY;
-    }
-
-    return bind (socket,
-                 (struct sockaddr *) & sin,
-                 sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+        ENetAddress address_ = { ENET_HOST_ANY, 0, 0 };
+        enet_address_set_sin((SOCKADDR *) & sin, & address_, family);
+    }
+
+    return bind (socket, (SOCKADDR *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
 }
 
@@ -133,5 +195,5 @@
 
 ENetSocket
-enet_socket_create (ENetSocketType type)
+enet_socket_create (ENetSocketType type, ENetAddressFamily family)
 {
     return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
@@ -174,26 +236,21 @@
 
 int
-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    memset (& sin, 0, sizeof (struct sockaddr_in));
-
-    sin.sin_family = AF_INET;
-    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-    sin.sin_addr.s_addr = address -> host;
-
-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
+{
+    SOCKADDR_STORAGE sin;
+    enet_address_set_sin((SOCKADDR *) & sin, address, family);
+
+    return connect (socket, (SOCKADDR *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
 }
 
 ENetSocket
-enet_socket_accept (ENetSocket socket, ENetAddress * address)
+enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
 {
     SOCKET result;
-    struct sockaddr_in sin;
-    int sinLength = sizeof (struct sockaddr_in);
+    SOCKADDR_STORAGE sin;
+    int sinLength = enet_sa_size (family);
 
     result = accept (socket, 
-                     address != NULL ? (struct sockaddr *) & sin : NULL, 
+                     address != NULL ? (SOCKADDR *) & sin : NULL,
                      address != NULL ? & sinLength : NULL);
 
@@ -203,6 +260,5 @@
     if (address != NULL)
     {
-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+        enet_address_set_address(address, (SOCKADDR *) & sin);
     }
 
@@ -220,16 +276,13 @@
                   const ENetAddress * address,
                   const ENetBuffer * buffers,
-                  size_t bufferCount)
-{
-    struct sockaddr_in sin;
+                  size_t bufferCount,
+                  ENetAddressFamily family)
+{
+    SOCKADDR_STORAGE sin;
     DWORD sentLength;
 
     if (address != NULL)
     {
-        memset (& sin, 0, sizeof (struct sockaddr_in));
-
-        sin.sin_family = AF_INET;
-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-        sin.sin_addr.s_addr = address -> host;
+        enet_address_set_sin((SOCKADDR *) & sin, address, family);
     }
 
@@ -239,6 +292,6 @@
                    & sentLength,
                    0,
-                   address != NULL ? (struct sockaddr *) & sin : 0,
-                   address != NULL ? sizeof (struct sockaddr_in) : 0,
+                   address != NULL ? (SOCKADDR *) & sin : 0,
+                   address != NULL ? enet_sa_size (family) : 0,
                    NULL,
                    NULL) == SOCKET_ERROR)
@@ -257,10 +310,11 @@
                      ENetAddress * address,
                      ENetBuffer * buffers,
-                     size_t bufferCount)
-{
-    INT sinLength = sizeof (struct sockaddr_in);
+                     size_t bufferCount,
+                     ENetAddressFamily family)
+{
+    INT sinLength = enet_sa_size (family);
     DWORD flags = 0,
           recvLength;
-    struct sockaddr_in sin;
+    SOCKADDR_STORAGE sin;
 
     if (WSARecvFrom (socket,
@@ -269,5 +323,5 @@
                      & recvLength,
                      & flags,
-                     address != NULL ? (struct sockaddr *) & sin : NULL,
+                     address != NULL ? (SOCKADDR *) & sin : NULL,
                      address != NULL ? & sinLength : NULL,
                      NULL,
@@ -289,6 +343,5 @@
     if (address != NULL)
     {
-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+        enet_address_set_address(address, (SOCKADDR *) & sin);
     }
 
@@ -308,23 +361,39 @@
 
 int
-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
 {
     fd_set readSet, writeSet;
     struct timeval timeVal;
     int selectCount;
-    
+
     timeVal.tv_sec = timeout / 1000;
     timeVal.tv_usec = (timeout % 1000) * 1000;
-    
+
     FD_ZERO (& readSet);
     FD_ZERO (& writeSet);
 
     if (* condition & ENET_SOCKET_WAIT_SEND)
-      FD_SET (socket, & writeSet);
+    {
+        if (socket4 != ENET_SOCKET_NULL)
+            FD_SET (socket4, & writeSet);
+        if (socket6 != ENET_SOCKET_NULL)
+            FD_SET (socket6, & writeSet);
+    }
 
     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      FD_SET (socket, & readSet);
-
-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+    {
+        if (socket4 != ENET_SOCKET_NULL)
+            FD_SET (socket4, & readSet);
+        if (socket6 != ENET_SOCKET_NULL)
+            FD_SET (socket6, & readSet);
+    }
+
+    ENetSocket maxSocket = 0;
+    if (socket4 != ENET_SOCKET_NULL)
+        maxSocket = socket4;
+    if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
+        maxSocket = socket6;
+
+    selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
 
     if (selectCount < 0)
@@ -336,12 +405,14 @@
       return 0;
 
-    if (FD_ISSET (socket, & writeSet))
-      * condition |= ENET_SOCKET_WAIT_SEND;
-    
-    if (FD_ISSET (socket, & readSet))
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-} 
+    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
+        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
+        * condition |= ENET_SOCKET_WAIT_SEND;
+
+    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & readSet)) ||
+        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & readSet)) )
+        * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+}
 
 #endif
