[Orxonox-commit 3401] r8088 - in code/trunk/src/external/enet: . patches
adrfried at orxonox.net
adrfried at orxonox.net
Fri Mar 18 00:08:45 CET 2011
Author: adrfried
Date: 2011-03-18 00:08:44 +0100 (Fri, 18 Mar 2011)
New Revision: 8088
Added:
code/trunk/src/external/enet/patches/0001-Add-IPv6-support-to-Enet.patch
Removed:
code/trunk/src/external/enet/patches/0001-IPv6-support.patch
Modified:
code/trunk/src/external/enet/ChangeLog
code/trunk/src/external/enet/LICENSE
code/trunk/src/external/enet/VERSION
code/trunk/src/external/enet/enet.h
code/trunk/src/external/enet/peer.c
code/trunk/src/external/enet/protocol.c
Log:
Updated Enet to version 1.3.1
updated patch
Modified: code/trunk/src/external/enet/ChangeLog
===================================================================
--- code/trunk/src/external/enet/ChangeLog 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/ChangeLog 2011-03-17 23:08:44 UTC (rev 8088)
@@ -1,3 +1,9 @@
+ENet 1.3.1 (February 10, 2011):
+
+* fixed bug in tracking of reliable data in transit
+* reliable data window size now scales with the throttle
+* fixed bug in fragment length calculation when checksums are used
+
ENet 1.3.0 (June 5, 2010):
* enet_host_create() now requires the channel limit to be specified as
Modified: code/trunk/src/external/enet/LICENSE
===================================================================
--- code/trunk/src/external/enet/LICENSE 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/LICENSE 2011-03-17 23:08:44 UTC (rev 8088)
@@ -1,4 +1,4 @@
-Copyright (c) 2002-2010 Lee Salzman
+Copyright (c) 2002-2011 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
Modified: code/trunk/src/external/enet/VERSION
===================================================================
--- code/trunk/src/external/enet/VERSION 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/VERSION 2011-03-17 23:08:44 UTC (rev 8088)
@@ -1,3 +1,2 @@
-ENet 1.3.0 fetched from CVS with last revision from
-Thu Jul 29 02:42:28 2010 +0000
-This is one small change beyond the 1.3.0 tarball.
+ENet 1.3.1 fetched from CVS with last revision from
+Thu Feb 10 02:54:08 2011 +0000
Modified: code/trunk/src/external/enet/enet.h
===================================================================
--- code/trunk/src/external/enet/enet.h 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/enet.h 2011-03-17 23:08:44 UTC (rev 8088)
@@ -25,7 +25,7 @@
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 0
+#define ENET_VERSION_PATCH 1
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
Copied: code/trunk/src/external/enet/patches/0001-Add-IPv6-support-to-Enet.patch (from rev 8079, code/trunk/src/external/enet/patches/0001-IPv6-support.patch)
===================================================================
--- code/trunk/src/external/enet/patches/0001-Add-IPv6-support-to-Enet.patch (rev 0)
+++ code/trunk/src/external/enet/patches/0001-Add-IPv6-support-to-Enet.patch 2011-03-17 23:08:44 UTC (rev 8088)
@@ -0,0 +1,1307 @@
+From 7a7274dad3f90d206e91c0712ea0d2599850b24e Mon Sep 17 00:00:00 2001
+From: Adrian Friedli <adi at koalatux.ch>
+Date: Thu, 2 Sep 2010 14:26:42 +0200
+Subject: [PATCH] Add IPv6 support to Enet
+
+---
+ host.c | 57 +++++++---
+ include/enet/enet.h | 64 ++++++++---
+ include/enet/win32.h | 4 +
+ protocol.c | 73 ++++++++++--
+ unix.c | 312 ++++++++++++++++++++++++++++++--------------------
+ win32.c | 247 ++++++++++++++++++++++++++--------------
+ 6 files changed, 507 insertions(+), 250 deletions(-)
+ mode change 100755 => 100644 Doxyfile
+ mode change 100755 => 100644 docs/FAQ.dox
+ mode change 100755 => 100644 docs/design.dox
+ mode change 100755 => 100644 docs/install.dox
+ mode change 100755 => 100644 docs/license.dox
+ mode change 100755 => 100644 docs/mainpage.dox
+ mode change 100755 => 100644 docs/tutorial.dox
+ mode change 100755 => 100644 enet.dsp
+
+diff --git a/Doxyfile b/Doxyfile
+old mode 100755
+new mode 100644
+diff --git a/docs/FAQ.dox b/docs/FAQ.dox
+old mode 100755
+new mode 100644
+diff --git a/docs/design.dox b/docs/design.dox
+old mode 100755
+new mode 100644
+diff --git a/docs/install.dox b/docs/install.dox
+old mode 100755
+new mode 100644
+diff --git a/docs/license.dox b/docs/license.dox
+old mode 100755
+new mode 100644
+diff --git a/docs/mainpage.dox b/docs/mainpage.dox
+old mode 100755
+new mode 100644
+diff --git a/docs/tutorial.dox b/docs/tutorial.dox
+old mode 100755
+new mode 100644
+diff --git a/enet.dsp b/enet.dsp
+old mode 100755
+new mode 100644
+diff --git a/host.c b/host.c
+index 8bb2433..a9d157b 100644
+--- a/host.c
++++ b/host.c
+@@ -7,6 +7,30 @@
+ #include <time.h>
+ #include "enet/enet.h"
+
++static ENetSocket
++enet_socket_create_bind (const ENetAddress * address, ENetAddressFamily family)
++{
++ ENetSocket socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, family);
++ if (socket == ENET_SOCKET_NULL)
++ return ENET_SOCKET_NULL;
++
++ /* This is not a conditional bind anymore,
++ * because WSARecvFrom returned WSAEINVAL on the IPv6 socket.
++ * TODO: Check for it's consequences. */
++ if (enet_socket_bind (socket, address, family) < 0)
++ {
++ enet_socket_destroy (socket);
++ return ENET_SOCKET_NULL;
++ }
++
++ enet_socket_set_option (socket, ENET_SOCKOPT_NONBLOCK, 1);
++ enet_socket_set_option (socket, ENET_SOCKOPT_BROADCAST, 1);
++ enet_socket_set_option (socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
++ enet_socket_set_option (socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
++
++ return socket;
++}
++
+ /** @defgroup host ENet host functions
+ @{
+ */
+@@ -31,6 +55,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
+ {
+ ENetHost * host;
+ ENetPeer * currentPeer;
++ int family;
+
+ if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
+ return NULL;
+@@ -48,23 +73,24 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
+ }
+ memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
+
+- host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
+- if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
+- {
+- if (host -> socket != ENET_SOCKET_NULL)
+- enet_socket_destroy (host -> socket);
++ family = (address == NULL || !memcmp (& address -> host, & ENET_HOST_ANY, sizeof (ENetHostAddress))) ?
++ ENET_IPV4 | ENET_IPV6 :
++ enet_get_address_family (address);
+
+- enet_free (host -> peers);
+- enet_free (host);
++ host -> socket4 = (family & ENET_IPV4) ?
++ enet_socket_create_bind (address, ENET_IPV4) :
++ ENET_SOCKET_NULL;
++ host -> socket6 = (family & ENET_IPV6) ?
++ enet_socket_create_bind (address, ENET_IPV6) :
++ ENET_SOCKET_NULL;
+
+- return NULL;
++ if (host -> socket4 == ENET_SOCKET_NULL && host -> socket6 == ENET_SOCKET_NULL)
++ {
++ enet_free (host -> peers);
++ enet_free (host);
++ return NULL;
+ }
+
+- enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
+- enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
+- enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
+- enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
+-
+ if (address != NULL)
+ host -> address = * address;
+
+@@ -133,7 +159,10 @@ enet_host_destroy (ENetHost * host)
+ {
+ ENetPeer * currentPeer;
+
+- enet_socket_destroy (host -> socket);
++ if (host -> socket4 != ENET_SOCKET_NULL)
++ enet_socket_destroy (host -> socket4);
++ if (host -> socket6 != ENET_SOCKET_NULL)
++ enet_socket_destroy (host -> socket6);
+
+ for (currentPeer = host -> peers;
+ currentPeer < & host -> peers [host -> peerCount];
+diff --git a/include/enet/enet.h b/include/enet/enet.h
+index b572590..8351166 100644
+--- a/include/enet/enet.h
++++ b/include/enet/enet.h
+@@ -53,12 +53,20 @@ typedef enum _ENetSocketOption
+ ENET_SOCKOPT_REUSEADDR = 5
+ } ENetSocketOption;
+
+-enum
++typedef struct _ENetHostAddress
+ {
+- ENET_HOST_ANY = 0, /**< specifies the default server host */
+- ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */
+-
+- ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
++ enet_uint8 addr[16];
++} ENetHostAddress;
++
++#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) */
++static const ENetHostAddress ENET_HOST_ANY = ENET_HOST_ANY_INIT; /**< specifies the default server host (global constant variable) */
++#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) */
++static const ENetHostAddress ENET_IPV4MAPPED_PREFIX = ENET_IPV4MAPPED_PREFIX_INIT; /**< specifies the IPv4-mapped IPv6 prefix (global constant variable) */
++#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) */
++static const ENetHostAddress ENET_HOST_BROADCAST = ENET_HOST_BROADCAST_INIT; /**< specifies a IPv4 subnet-wide broadcast (global constant variable) */
++enum {
++ ENET_IPV4MAPPED_PREFIX_LEN = 12, /**< specifies the length of the IPv4-mapped IPv6 prefix */
++ ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
+ };
+
+ /**
+@@ -73,11 +81,26 @@ enum
+ */
+ typedef struct _ENetAddress
+ {
+- enet_uint32 host;
++ ENetHostAddress host;
++#ifdef WIN32
++ u_long scopeID;
++#else
++ uint32_t scopeID;
++#endif
+ enet_uint16 port;
+ } ENetAddress;
+
+ /**
++ * The address family type.
++ */
++typedef enum _ENetAddressFamily
++{
++ ENET_NO_ADDRESS_FAMILY = 0,
++ ENET_IPV4 = (1 << 0),
++ ENET_IPV6 = (1 << 1)
++} ENetAddressFamily;
++
++/**
+ * Packet flag bit constants.
+ *
+ * The host must be specified in network byte-order, and the port must be in
+@@ -321,7 +344,8 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b
+ */
+ typedef struct _ENetHost
+ {
+- ENetSocket socket;
++ ENetSocket socket4;
++ ENetSocket socket6;
+ ENetAddress address; /**< Internet address of the host */
+ enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
+ enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
+@@ -441,14 +465,14 @@ ENET_API void enet_time_set (enet_uint32);
+ /** @defgroup socket ENet socket functions
+ @{
+ */
+-ENET_API ENetSocket enet_socket_create (ENetSocketType);
+-ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
++ENET_API ENetSocket enet_socket_create (ENetSocketType, ENetAddressFamily);
++ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *, ENetAddressFamily);
+ ENET_API int enet_socket_listen (ENetSocket, int);
+-ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
+-ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
+-ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
+-ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
+-ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
++ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *, ENetAddressFamily);
++ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *, ENetAddressFamily);
++ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t, ENetAddressFamily);
++ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t, ENetAddressFamily);
++ENET_API int enet_socket_wait (ENetSocket, ENetSocket, enet_uint32 *, enet_uint32);
+ ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
+ ENET_API void enet_socket_destroy (ENetSocket);
+ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
+@@ -488,6 +512,18 @@ ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN
+ */
+ ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
+
++/** Maps an IPv4 Address to an IPv6 address.
++ @param address IPv4 address in network byte order
++ @returns the IPv4-mapped IPv6 address in network byte order
++*/
++ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address);
++
++/** Returns the Address family of an (IPv4-mapped) IPv6 address.
++ @param address IPv6 address
++ @returns address family
++*/
++ENET_API ENetAddressFamily enet_get_address_family (const ENetAddress * address);
++
+ /** @} */
+
+ ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
+diff --git a/include/enet/win32.h b/include/enet/win32.h
+index 0e1cf0c..6145851 100644
+--- a/include/enet/win32.h
++++ b/include/enet/win32.h
+@@ -53,6 +53,10 @@ typedef fd_set ENetSocketSet;
+ #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+ #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
+
++#ifndef AI_ADDRCONFIG
++#define AI_ADDRCONFIG 0x0400 /* AI_ADDRCONFIG is not defined everywhere */
++#endif
++
+ #endif /* __ENET_WIN32_H__ */
+
+
+diff --git a/protocol.c b/protocol.c
+index 2237ba8..7205d1b 100644
+--- a/protocol.c
++++ b/protocol.c
+@@ -25,6 +25,22 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
+ sizeof (ENetProtocolThrottleConfigure),
+ };
+
++ENetHostAddress
++enet_address_map4 (enet_uint32 address)
++{
++ ENetHostAddress addr = ENET_IPV4MAPPED_PREFIX_INIT;
++ ((enet_uint32 *)addr.addr)[3] = address;
++ return addr;
++}
++
++ENetAddressFamily
++enet_get_address_family (const ENetAddress * address)
++{
++ if (!memcmp(& address->host, & ENET_IPV4MAPPED_PREFIX, ENET_IPV4MAPPED_PREFIX_LEN))
++ return ENET_IPV4;
++ return ENET_IPV6;
++}
++
+ size_t
+ enet_protocol_command_size (enet_uint8 commandNumber)
+ {
+@@ -266,9 +282,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
+ ++ currentPeer)
+ {
+ if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
+- currentPeer -> address.host == host -> receivedAddress.host &&
+ currentPeer -> address.port == host -> receivedAddress.port &&
+- currentPeer -> connectID == command -> connect.connectID)
++ currentPeer -> connectID == command -> connect.connectID &&
++ !memcmp(& currentPeer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)))
+ return NULL;
+ }
+
+@@ -852,10 +868,11 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
+ peer -> state == ENET_PEER_STATE_ZOMBIE ||
+- (host -> receivedAddress.host != peer -> address.host &&
+- peer -> address.host != ENET_HOST_BROADCAST) ||
+ (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
+- sessionID != peer -> incomingSessionID))
++ sessionID != peer -> incomingSessionID) ||
++ ( memcmp(& peer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)) &&
++ memcmp(& peer -> address.host, & ENET_HOST_BROADCAST, sizeof (ENetHostAddress)) &&
++ peer -> address.host.addr[0] != 0xff ) )
+ return 0;
+ }
+
+@@ -895,8 +912,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+
+ if (peer != NULL)
+ {
+- peer -> address.host = host -> receivedAddress.host;
+- peer -> address.port = host -> receivedAddress.port;
++ peer -> address = host -> receivedAddress;
+ peer -> incomingDataTotal += host -> receivedDataLength;
+ }
+
+@@ -1025,7 +1041,7 @@ commandError:
+ }
+
+ static int
+-enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
++enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event, ENetAddressFamily family)
+ {
+ for (;;)
+ {
+@@ -1035,10 +1051,11 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
+ buffer.data = host -> packetData [0];
+ buffer.dataLength = sizeof (host -> packetData [0]);
+
+- receivedLength = enet_socket_receive (host -> socket,
++ receivedLength = enet_socket_receive (family == ENET_IPV4 ? host -> socket4 : host -> socket6,
+ & host -> receivedAddress,
+ & buffer,
+- 1);
++ 1,
++ family);
+
+ if (receivedLength < 0)
+ return -1;
+@@ -1046,6 +1063,9 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
+ if (receivedLength == 0)
+ return 0;
+
++ if (enet_get_address_family (& host -> receivedAddress) != family)
++ return -1;
++
+ host -> receivedData = host -> packetData [0];
+ host -> receivedDataLength = receivedLength;
+
+@@ -1397,6 +1417,9 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
+ currentPeer < & host -> peers [host -> peerCount];
+ ++ currentPeer)
+ {
++ ENetAddressFamily family;
++ ENetSocket socket;
++
+ if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
+ currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
+ continue;
+@@ -1520,7 +1543,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
+
+ currentPeer -> lastSendTime = host -> serviceTime;
+
+- sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
++ family = enet_get_address_family (& currentPeer -> address);
++ socket = family == ENET_IPV4 ? host -> socket4 : host -> socket6;
++ if (socket == ENET_SOCKET_NULL)
++ return -1;
++ sentLength = enet_socket_send (socket,
++ & currentPeer -> address,
++ host -> buffers,
++ host -> bufferCount,
++ family);
+
+ enet_protocol_remove_sent_unreliable_commands (currentPeer);
+
+@@ -1631,7 +1662,23 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
+ break;
+ }
+
+- switch (enet_protocol_receive_incoming_commands (host, event))
++ if (host -> socket4 != ENET_SOCKET_NULL)
++ switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV4))
++ {
++ case 1:
++ return 1;
++
++ case -1:
++ perror ("Error receiving incoming packets");
++
++ return -1;
++
++ default:
++ break;
++ }
++
++ if (host -> socket6 != ENET_SOCKET_NULL)
++ switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV6))
+ {
+ case 1:
+ return 1;
+@@ -1683,7 +1730,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
+
+ waitCondition = ENET_SOCKET_WAIT_RECEIVE;
+
+- if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
++ if (enet_socket_wait (host -> socket4, host -> socket6, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
+ return -1;
+
+ host -> serviceTime = enet_time_get ();
+diff --git a/unix.c b/unix.c
+index 6971541..992ecd3 100644
+--- a/unix.c
++++ b/unix.c
+@@ -71,122 +71,161 @@ enet_time_set (enet_uint32 newTimeBase)
+ timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
+ }
+
+-int
+-enet_address_set_host (ENetAddress * address, const char * name)
++static enet_uint16
++enet_af (ENetAddressFamily family)
+ {
+- struct hostent * hostEntry = NULL;
+-#ifdef HAS_GETHOSTBYNAME_R
+- struct hostent hostData;
+- char buffer [2048];
+- int errnum;
+-
+-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+- gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+-#else
+- hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
+-#endif
+-#else
+- hostEntry = gethostbyname (name);
+-#endif
++ 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 (struct sockaddr_in);
++ if (family == ENET_IPV6)
++ return sizeof (struct sockaddr_in6);
++ return 0;
++}
+
+- if (hostEntry == NULL ||
+- hostEntry -> h_addrtype != AF_INET)
++static ENetAddressFamily
++enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
++{
++ memset (address, 0, sizeof (ENetAddress));
++ if (sin -> sa_family == AF_INET)
+ {
+-#ifdef HAS_INET_PTON
+- if (! inet_pton (AF_INET, name, & address -> host))
+-#else
+- if (! inet_aton (name, (struct in_addr *) & address -> host))
+-#endif
+- return -1;
+- return 0;
++ address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
++ /* address -> scopeID = 0; */
++ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
++ return ENET_IPV4;
+ }
+-
+- address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+-
+- return 0;
++ if (sin -> sa_family == AF_INET6)
++ {
++ address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
++ address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
++ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
++ return ENET_IPV6;
++ }
++ return ENET_NO_ADDRESS_FAMILY;
+ }
+
+-int
+-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
++static int
++enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
+ {
+-#ifdef HAS_INET_NTOP
+- if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
+-#else
+- char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+- if (addr != NULL)
+- strncpy (name, addr, nameLength);
+- else
+-#endif
+- return -1;
+- return 0;
++ 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))))
++ {
++ ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
++ ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
++ ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
++ return 0;
++ }
++ else if (family == ENET_IPV6)
++ {
++ ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
++ ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
++ ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
++ ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
++ return 0;
++ }
++ return -1;
+ }
+
+ int
+-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
++enet_address_set_host (ENetAddress * address, const char * name)
+ {
+- struct in_addr in;
+- struct hostent * hostEntry = NULL;
+-#ifdef HAS_GETHOSTBYADDR_R
+- struct hostent hostData;
+- char buffer [2048];
+- int errnum;
++ enet_uint16 port = address -> port;
++ struct addrinfo hints;
++ struct addrinfo * result;
++ struct addrinfo * res;
+
+- in.s_addr = address -> host;
++ memset(& hints, 0, sizeof (hints));
++ hints.ai_flags = AI_ADDRCONFIG;
++ hints.ai_family = AF_UNSPEC;
+
+-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+- gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+-#else
+- hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
+-#endif
+-#else
+- in.s_addr = address -> host;
++ if ( getaddrinfo(name, NULL, &hints, &result) )
++ return -1;
+
+- hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+-#endif
++ for (res = result; res != NULL; res = res -> ai_next)
++ {
++ if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
++ break;
++ }
+
+- if (hostEntry == NULL)
+- return enet_address_get_host_ip (address, name, nameLength);
++ address -> port = port;
++ freeaddrinfo(result);
++ if (res == NULL) return -1;
+
+- strncpy (name, hostEntry -> h_name, nameLength);
++ return 0;
++}
++
++static int
++enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
++{
++ struct sockaddr_storage sin;
++ enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
++
++ if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
++ return -1;
+
+ return 0;
+ }
+
+ int
+-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
++enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+ {
+- struct sockaddr_in sin;
++ return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
++}
+
+- memset (& sin, 0, sizeof (struct sockaddr_in));
++int
++enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
++{
++ return enet_address_get_host_x(address, name, nameLength, 0);
++}
+
+- sin.sin_family = AF_INET;
++int
++enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
++{
++ struct 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((struct sockaddr *) & sin, address, family);
+ }
+ else
+ {
+- sin.sin_port = 0;
+- sin.sin_addr.s_addr = INADDR_ANY;
++ ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
++ enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
+ }
+
+- return bind (socket,
+- (struct sockaddr *) & sin,
+- sizeof (struct sockaddr_in));
++ return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family));
+ }
+
+-int
++int
+ enet_socket_listen (ENetSocket socket, int backlog)
+ {
+ return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
+ }
+
+ 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);
++ ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
++
++#ifdef IPV6_V6ONLY
++ if (family == ENET_IPV6)
++ {
++ int value = 1;
++ setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
++ }
++#endif /* IPV6_V6ONLY */
++
++ return sock;
+ }
+
+ int
+@@ -226,42 +265,36 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+ }
+
+ int
+-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
++enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
+ {
+- struct sockaddr_in sin;
+-
+- memset (& sin, 0, sizeof (struct sockaddr_in));
++ struct sockaddr_storage sin;
++ enet_address_set_sin((struct sockaddr *) & sin, address, family);
+
+- 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));
++ return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family));
+ }
+
+ ENetSocket
+-enet_socket_accept (ENetSocket socket, ENetAddress * address)
++enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
+ {
+ int result;
+- struct sockaddr_in sin;
+- socklen_t sinLength = sizeof (struct sockaddr_in);
++ struct sockaddr_storage sin;
++ socklen_t sinLength = enet_sa_size (family);
+
+ result = accept (socket,
+- address != NULL ? (struct sockaddr *) & sin : NULL,
++ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL);
+-
++
+ if (result == -1)
+ return ENET_SOCKET_NULL;
+
+ 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, (struct sockaddr *) & sin);
+ }
+
+ return result;
+-}
+-
++}
++
+ void
+ enet_socket_destroy (ENetSocket socket)
+ {
+@@ -272,24 +305,20 @@ int
+ enet_socket_send (ENetSocket socket,
+ const ENetAddress * address,
+ const ENetBuffer * buffers,
+- size_t bufferCount)
++ size_t bufferCount,
++ ENetAddressFamily family)
+ {
+ struct msghdr msgHdr;
+- struct sockaddr_in sin;
++ struct sockaddr_storage sin;
+ int sentLength;
+
+ memset (& msgHdr, 0, sizeof (struct msghdr));
+
+ 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((struct sockaddr *) & sin, address, family);
+ msgHdr.msg_name = & sin;
+- msgHdr.msg_namelen = sizeof (struct sockaddr_in);
++ msgHdr.msg_namelen = enet_sa_size (family);
+ }
+
+ msgHdr.msg_iov = (struct iovec *) buffers;
+@@ -312,10 +341,11 @@ int
+ enet_socket_receive (ENetSocket socket,
+ ENetAddress * address,
+ ENetBuffer * buffers,
+- size_t bufferCount)
++ size_t bufferCount,
++ ENetAddressFamily family)
+ {
+ struct msghdr msgHdr;
+- struct sockaddr_in sin;
++ struct sockaddr_storage sin;
+ int recvLength;
+
+ memset (& msgHdr, 0, sizeof (struct msghdr));
+@@ -323,7 +353,7 @@ enet_socket_receive (ENetSocket socket,
+ if (address != NULL)
+ {
+ msgHdr.msg_name = & sin;
+- msgHdr.msg_namelen = sizeof (struct sockaddr_in);
++ msgHdr.msg_namelen = enet_sa_size (family);
+ }
+
+ msgHdr.msg_iov = (struct iovec *) buffers;
+@@ -346,8 +376,7 @@ enet_socket_receive (ENetSocket socket,
+
+ 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, (struct sockaddr *) & sin);
+ }
+
+ return recvLength;
+@@ -365,22 +394,38 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
+ }
+
+ 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)
+ {
+ #ifdef HAS_POLL
+- struct pollfd pollSocket;
++ struct pollfd pollSocket[2];
+ int pollCount;
+-
+- pollSocket.fd = socket;
+- pollSocket.events = 0;
++
++ pollSocket[0].fd = socket4;
++ pollSocket[1].fd = socket6;
++ pollSocket[0].events = 0;
++ pollSocket[1].events = 0;
++ /* pollSocket[0].revents = 0; */
++ pollSocket[1].revents = 0;
++
++ if (pollSocket[0].fd == ENET_SOCKET_NULL)
++ {
++ pollSocket[0].fd = pollSocket[1].fd;
++ pollSocket[1].fd = ENET_SOCKET_NULL;
++ }
+
+ if (* condition & ENET_SOCKET_WAIT_SEND)
+- pollSocket.events |= POLLOUT;
++ {
++ pollSocket[0].events |= POLLOUT;
++ pollSocket[1].events |= POLLOUT;
++ }
+
+ if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+- pollSocket.events |= POLLIN;
++ {
++ pollSocket[0].events |= POLLIN;
++ pollSocket[1].events |= POLLIN;
++ }
+
+- pollCount = poll (& pollSocket, 1, timeout);
++ pollCount = poll (pollSocket, pollSocket[1].fd != ENET_SOCKET_NULL ? 2 : 1, timeout);
+
+ if (pollCount < 0)
+ return -1;
+@@ -390,10 +435,10 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
+ if (pollCount == 0)
+ return 0;
+
+- if (pollSocket.revents & POLLOUT)
++ if ((pollSocket[0].revents | pollSocket[1].revents) & POLLOUT)
+ * condition |= ENET_SOCKET_WAIT_SEND;
+
+- if (pollSocket.revents & POLLIN)
++ if ((pollSocket[0].revents | pollSocket[1].revents) & POLLIN)
+ * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+ return 0;
+@@ -401,6 +446,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
+ fd_set readSet, writeSet;
+ struct timeval timeVal;
+ int selectCount;
++ ENetSocket maxSocket;
+
+ timeVal.tv_sec = timeout / 1000;
+ timeVal.tv_usec = (timeout % 1000) * 1000;
+@@ -409,12 +455,28 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
+ 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);
++ {
++ if (socket4 != ENET_SOCKET_NULL)
++ FD_SET (socket4, & readSet);
++ if (socket6 != ENET_SOCKET_NULL)
++ FD_SET (socket6, & readSet);
++ }
++
++ maxSocket = 0;
++ if (socket4 != ENET_SOCKET_NULL)
++ maxSocket = socket4;
++ if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
++ maxSocket = socket6;
+
+- selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
++ selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+ if (selectCount < 0)
+ return -1;
+@@ -424,11 +486,13 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
+ if (selectCount == 0)
+ return 0;
+
+- if (FD_ISSET (socket, & writeSet))
+- * condition |= ENET_SOCKET_WAIT_SEND;
++ if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
++ (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
++ * condition |= ENET_SOCKET_WAIT_SEND;
+
+- if (FD_ISSET (socket, & readSet))
+- * condition |= ENET_SOCKET_WAIT_RECEIVE;
++ 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
+diff --git a/win32.c b/win32.c
+index e1fae23..15b9888 100644
+--- a/win32.c
++++ b/win32.c
+@@ -4,23 +4,27 @@
+ */
+ #ifdef WIN32
+
++#define _WIN32_WINNT 0x0501
++
+ #include <time.h>
++#include <ws2tcpip.h>
+ #define ENET_BUILDING_LIB 1
+ #include "enet/enet.h"
++#include <ws2tcpip.h>
+
+ static enet_uint32 timeBase = 0;
+
+ int
+ enet_initialize (void)
+ {
+- WORD versionRequested = MAKEWORD (1, 1);
++ WORD versionRequested = MAKEWORD (2, 2);
+ WSADATA wsaData;
+
+ if (WSAStartup (versionRequested, & wsaData))
+ return -1;
+
+- if (LOBYTE (wsaData.wVersion) != 1||
+- HIBYTE (wsaData.wVersion) != 1)
++ if (LOBYTE (wsaData.wVersion) != 2||
++ HIBYTE (wsaData.wVersion) != 2)
+ {
+ WSACleanup ();
+
+@@ -52,77 +56,139 @@ enet_time_set (enet_uint32 newTimeBase)
+ timeBase = (enet_uint32) timeGetTime () - newTimeBase;
+ }
+
+-int
+-enet_address_set_host (ENetAddress * address, const char * name)
++static enet_uint16
++enet_af (ENetAddressFamily family)
+ {
+- struct hostent * hostEntry;
++ if (family == ENET_IPV4)
++ return AF_INET;
++ if (family == ENET_IPV6)
++ return AF_INET6;
++ return 0;
++}
+
+- hostEntry = gethostbyname (name);
+- if (hostEntry == NULL ||
+- hostEntry -> h_addrtype != AF_INET)
++static socklen_t
++enet_sa_size (ENetAddressFamily family)
++{
++ if (family == ENET_IPV4)
++ return sizeof (struct sockaddr_in);
++ if (family == ENET_IPV6)
++ return sizeof (struct sockaddr_in6);
++ return 0;
++}
++
++static ENetAddressFamily
++enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
++{
++ memset (address, 0, sizeof (ENetAddress));
++ if (sin -> sa_family == AF_INET)
+ {
+- unsigned long host = inet_addr (name);
+- if (host == INADDR_NONE)
+- return -1;
+- address -> host = host;
+- return 0;
++ address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
++ /* address -> scopeID = 0; */
++ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
++ return ENET_IPV4;
+ }
++ if (sin -> sa_family == AF_INET6)
++ {
++ address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
++ address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
++ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
++ return ENET_IPV6;
++ }
++ return ENET_NO_ADDRESS_FAMILY;
++}
+
+- address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+-
+- return 0;
++static int
++enet_address_set_sin (struct 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))))
++ {
++ ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
++ ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
++ ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
++ return 0;
++ }
++ else if (family == ENET_IPV6)
++ {
++ ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
++ ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
++ ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
++ ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
++ return 0;
++ }
++ return -1;
+ }
+
+ int
+-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
++enet_address_set_host (ENetAddress * address, const char * name)
+ {
+- char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+- if (addr == NULL)
++ enet_uint16 port = address -> port;
++ struct addrinfo hints;
++ struct addrinfo * result;
++ struct addrinfo * res;
++
++ memset(& hints, 0, sizeof (hints));
++ hints.ai_flags = AI_ADDRCONFIG;
++ hints.ai_family = AF_UNSPEC;
++
++ if ( getaddrinfo(name, NULL, &hints, &result) )
+ return -1;
+- strncpy (name, addr, nameLength);
++
++ 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;
+ }
+
+-int
+-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
++static int
++enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
+ {
+- 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);
++ struct sockaddr_storage sin;
++ enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
+
+- strncpy (name, hostEntry -> h_name, nameLength);
++ if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
++ return -1;
+
+ return 0;
+ }
+
+ int
+-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
++enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+ {
+- struct sockaddr_in sin;
++ return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
++}
+
+- memset (& sin, 0, sizeof (struct sockaddr_in));
++int
++enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
++{
++ return enet_address_get_host_x(address, name, nameLength, 0);
++}
+
+- sin.sin_family = AF_INET;
++int
++enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
++{
++ struct 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((struct sockaddr *) & sin, address, family);
+ }
+ else
+ {
+- sin.sin_port = 0;
+- sin.sin_addr.s_addr = INADDR_ANY;
++ ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
++ enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
+ }
+
+- return bind (socket,
+- (struct sockaddr *) & sin,
+- sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
++ return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
+ }
+
+ int
+@@ -132,9 +198,10 @@ enet_socket_listen (ENetSocket socket, int backlog)
+ }
+
+ 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);
++ ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
++ return sock;
+ }
+
+ int
+@@ -173,28 +240,23 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+ }
+
+ int
+-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
++enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
+ {
+- struct sockaddr_in sin;
+-
+- memset (& sin, 0, sizeof (struct sockaddr_in));
++ struct sockaddr_storage sin;
++ enet_address_set_sin((struct sockaddr *) & sin, address, family);
+
+- 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;
++ return connect (socket, (struct 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);
++ struct sockaddr_storage sin;
++ socklen_t sinLength = enet_sa_size (family);
+
+ result = accept (socket,
+- address != NULL ? (struct sockaddr *) & sin : NULL,
++ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL);
+
+ if (result == INVALID_SOCKET)
+@@ -202,8 +264,7 @@ enet_socket_accept (ENetSocket socket, ENetAddress * address)
+
+ 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, (struct sockaddr *) & sin);
+ }
+
+ return result;
+@@ -219,18 +280,15 @@ int
+ enet_socket_send (ENetSocket socket,
+ const ENetAddress * address,
+ const ENetBuffer * buffers,
+- size_t bufferCount)
++ size_t bufferCount,
++ ENetAddressFamily family)
+ {
+- struct sockaddr_in sin;
++ struct 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((struct sockaddr *) & sin, address, family);
+ }
+
+ if (WSASendTo (socket,
+@@ -239,7 +297,7 @@ enet_socket_send (ENetSocket socket,
+ & sentLength,
+ 0,
+ address != NULL ? (struct sockaddr *) & sin : 0,
+- address != NULL ? sizeof (struct sockaddr_in) : 0,
++ address != NULL ? enet_sa_size (family) : 0,
+ NULL,
+ NULL) == SOCKET_ERROR)
+ {
+@@ -256,12 +314,13 @@ int
+ enet_socket_receive (ENetSocket socket,
+ ENetAddress * address,
+ ENetBuffer * buffers,
+- size_t bufferCount)
++ size_t bufferCount,
++ ENetAddressFamily family)
+ {
+- INT sinLength = sizeof (struct sockaddr_in);
++ INT sinLength = enet_sa_size (family);
+ DWORD flags = 0,
+ recvLength;
+- struct sockaddr_in sin;
++ struct sockaddr_storage sin;
+
+ if (WSARecvFrom (socket,
+ (LPWSABUF) buffers,
+@@ -288,8 +347,7 @@ enet_socket_receive (ENetSocket socket,
+
+ 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, (struct sockaddr *) & sin);
+ }
+
+ return (int) recvLength;
+@@ -307,25 +365,42 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
+ }
+
+ 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;
+-
++ ENetSocket maxSocket;
++
+ 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);
++ {
++ if (socket4 != ENET_SOCKET_NULL)
++ FD_SET (socket4, & readSet);
++ if (socket6 != ENET_SOCKET_NULL)
++ FD_SET (socket6, & readSet);
++ }
+
+- selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
++ 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)
+ return -1;
+@@ -335,14 +410,16 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
+ if (selectCount == 0)
+ return 0;
+
+- if (FD_ISSET (socket, & writeSet))
+- * condition |= ENET_SOCKET_WAIT_SEND;
+-
+- if (FD_ISSET (socket, & readSet))
+- * condition |= ENET_SOCKET_WAIT_RECEIVE;
++ 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
+
+--
+1.7.4.1
+
Property changes on: code/trunk/src/external/enet/patches/0001-Add-IPv6-support-to-Enet.patch
___________________________________________________________________
Added: svn:eol-style
+ native
Deleted: code/trunk/src/external/enet/patches/0001-IPv6-support.patch
===================================================================
--- code/trunk/src/external/enet/patches/0001-IPv6-support.patch 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/patches/0001-IPv6-support.patch 2011-03-17 23:08:44 UTC (rev 8088)
@@ -1,1279 +0,0 @@
-From 68e3ac1c2876aedb62a77fdc7ba71e4983a6b99d Mon Sep 17 00:00:00 2001
-From: Adrian Friedli <adi at koalatux.ch>
-Date: Thu, 2 Sep 2010 14:26:42 +0200
-Subject: [PATCH] IPv6 support
-
----
- host.c | 57 +++++++---
- include/enet/enet.h | 64 ++++++++---
- include/enet/win32.h | 5 +
- protocol.c | 73 ++++++++++--
- unix.c | 312 ++++++++++++++++++++++++++++++--------------------
- win32.c | 245 ++++++++++++++++++++++++++--------------
- 6 files changed, 506 insertions(+), 250 deletions(-)
-
-diff --git a/host.c b/host.c
-index 8bb2433..a9d157b 100644
---- a/host.c
-+++ b/host.c
-@@ -7,6 +7,30 @@
- #include <time.h>
- #include "enet/enet.h"
-
-+static ENetSocket
-+enet_socket_create_bind (const ENetAddress * address, ENetAddressFamily family)
-+{
-+ ENetSocket socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, family);
-+ if (socket == ENET_SOCKET_NULL)
-+ return ENET_SOCKET_NULL;
-+
-+ /* This is not a conditional bind anymore,
-+ * because WSARecvFrom returned WSAEINVAL on the IPv6 socket.
-+ * TODO: Check for it's consequences. */
-+ if (enet_socket_bind (socket, address, family) < 0)
-+ {
-+ enet_socket_destroy (socket);
-+ return ENET_SOCKET_NULL;
-+ }
-+
-+ enet_socket_set_option (socket, ENET_SOCKOPT_NONBLOCK, 1);
-+ enet_socket_set_option (socket, ENET_SOCKOPT_BROADCAST, 1);
-+ enet_socket_set_option (socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
-+ enet_socket_set_option (socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
-+
-+ return socket;
-+}
-+
- /** @defgroup host ENet host functions
- @{
- */
-@@ -31,6 +55,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
- {
- ENetHost * host;
- ENetPeer * currentPeer;
-+ int family;
-
- if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
- return NULL;
-@@ -48,23 +73,24 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
- }
- memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
-
-- host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
-- if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
-- {
-- if (host -> socket != ENET_SOCKET_NULL)
-- enet_socket_destroy (host -> socket);
-+ family = (address == NULL || !memcmp (& address -> host, & ENET_HOST_ANY, sizeof (ENetHostAddress))) ?
-+ ENET_IPV4 | ENET_IPV6 :
-+ enet_get_address_family (address);
-
-- enet_free (host -> peers);
-- enet_free (host);
-+ host -> socket4 = (family & ENET_IPV4) ?
-+ enet_socket_create_bind (address, ENET_IPV4) :
-+ ENET_SOCKET_NULL;
-+ host -> socket6 = (family & ENET_IPV6) ?
-+ enet_socket_create_bind (address, ENET_IPV6) :
-+ ENET_SOCKET_NULL;
-
-- return NULL;
-+ if (host -> socket4 == ENET_SOCKET_NULL && host -> socket6 == ENET_SOCKET_NULL)
-+ {
-+ enet_free (host -> peers);
-+ enet_free (host);
-+ return NULL;
- }
-
-- enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
-- enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
-- enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
-- enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
--
- if (address != NULL)
- host -> address = * address;
-
-@@ -133,7 +159,10 @@ enet_host_destroy (ENetHost * host)
- {
- ENetPeer * currentPeer;
-
-- enet_socket_destroy (host -> socket);
-+ if (host -> socket4 != ENET_SOCKET_NULL)
-+ enet_socket_destroy (host -> socket4);
-+ if (host -> socket6 != ENET_SOCKET_NULL)
-+ enet_socket_destroy (host -> socket6);
-
- for (currentPeer = host -> peers;
- currentPeer < & host -> peers [host -> peerCount];
-diff --git a/include/enet/enet.h b/include/enet/enet.h
-index 2f656d6..7b468a0 100644
---- a/include/enet/enet.h
-+++ b/include/enet/enet.h
-@@ -53,12 +53,20 @@ typedef enum _ENetSocketOption
- ENET_SOCKOPT_REUSEADDR = 5
- } ENetSocketOption;
-
--enum
-+typedef struct _ENetHostAddress
- {
-- ENET_HOST_ANY = 0, /**< specifies the default server host */
-- ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */
--
-- ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
-+ enet_uint8 addr[16];
-+} ENetHostAddress;
-+
-+#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) */
-+static const ENetHostAddress ENET_HOST_ANY = ENET_HOST_ANY_INIT; /**< specifies the default server host (global constant variable) */
-+#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) */
-+static const ENetHostAddress ENET_IPV4MAPPED_PREFIX = ENET_IPV4MAPPED_PREFIX_INIT; /**< specifies the IPv4-mapped IPv6 prefix (global constant variable) */
-+#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) */
-+static const ENetHostAddress ENET_HOST_BROADCAST = ENET_HOST_BROADCAST_INIT; /**< specifies a IPv4 subnet-wide broadcast (global constant variable) */
-+enum {
-+ ENET_IPV4MAPPED_PREFIX_LEN = 12, /**< specifies the length of the IPv4-mapped IPv6 prefix */
-+ ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
- };
-
- /**
-@@ -73,11 +81,26 @@ enum
- */
- typedef struct _ENetAddress
- {
-- enet_uint32 host;
-+ ENetHostAddress host;
-+#ifdef WIN32
-+ u_long scopeID;
-+#else
-+ uint32_t scopeID;
-+#endif
- enet_uint16 port;
- } ENetAddress;
-
- /**
-+ * The address family type.
-+ */
-+typedef enum _ENetAddressFamily
-+{
-+ ENET_NO_ADDRESS_FAMILY = 0,
-+ ENET_IPV4 = (1 << 0),
-+ ENET_IPV6 = (1 << 1)
-+} ENetAddressFamily;
-+
-+/**
- * Packet flag bit constants.
- *
- * The host must be specified in network byte-order, and the port must be in
-@@ -321,7 +344,8 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b
- */
- typedef struct _ENetHost
- {
-- ENetSocket socket;
-+ ENetSocket socket4;
-+ ENetSocket socket6;
- ENetAddress address; /**< Internet address of the host */
- enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
- enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
-@@ -441,14 +465,14 @@ ENET_API void enet_time_set (enet_uint32);
- /** @defgroup socket ENet socket functions
- @{
- */
--ENET_API ENetSocket enet_socket_create (ENetSocketType);
--ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
-+ENET_API ENetSocket enet_socket_create (ENetSocketType, ENetAddressFamily);
-+ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *, ENetAddressFamily);
- ENET_API int enet_socket_listen (ENetSocket, int);
--ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
--ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
--ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
--ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
--ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
-+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *, ENetAddressFamily);
-+ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *, ENetAddressFamily);
-+ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t, ENetAddressFamily);
-+ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t, ENetAddressFamily);
-+ENET_API int enet_socket_wait (ENetSocket, ENetSocket, enet_uint32 *, enet_uint32);
- ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
- ENET_API void enet_socket_destroy (ENetSocket);
- ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
-@@ -488,6 +512,18 @@ ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN
- */
- ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
-
-+/** Maps an IPv4 Address to an IPv6 address.
-+ @param address IPv4 address in network byte order
-+ @returns the IPv4-mapped IPv6 address in network byte order
-+*/
-+ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address);
-+
-+/** Returns the Address family of an (IPv4-mapped) IPv6 address.
-+ @param address IPv6 address
-+ @returns address family
-+*/
-+ENET_API ENetAddressFamily enet_get_address_family (const ENetAddress * address);
-+
- /** @} */
-
- ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
-diff --git a/include/enet/win32.h b/include/enet/win32.h
-index 0e1cf0c..53a7ff7 100644
---- a/include/enet/win32.h
-+++ b/include/enet/win32.h
-@@ -14,6 +14,7 @@
-
- #include <stdlib.h>
- #include <winsock2.h>
-+#include <ws2tcpip.h>
-
- typedef SOCKET ENetSocket;
-
-@@ -53,6 +54,10 @@ typedef fd_set ENetSocketSet;
- #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
- #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
-
-+#ifndef AI_ADDRCONFIG
-+#define AI_ADDRCONFIG 0x0400 /* AI_ADDRCONFIG is not defined everywhere */
-+#endif
-+
- #endif /* __ENET_WIN32_H__ */
-
-
-diff --git a/protocol.c b/protocol.c
-index 8e26dfb..cfef646 100644
---- a/protocol.c
-+++ b/protocol.c
-@@ -25,6 +25,22 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
- sizeof (ENetProtocolThrottleConfigure),
- };
-
-+ENetHostAddress
-+enet_address_map4 (enet_uint32 address)
-+{
-+ ENetHostAddress addr = ENET_IPV4MAPPED_PREFIX_INIT;
-+ ((enet_uint32 *)addr.addr)[3] = address;
-+ return addr;
-+}
-+
-+ENetAddressFamily
-+enet_get_address_family (const ENetAddress * address)
-+{
-+ if (!memcmp(& address->host, & ENET_IPV4MAPPED_PREFIX, ENET_IPV4MAPPED_PREFIX_LEN))
-+ return ENET_IPV4;
-+ return ENET_IPV6;
-+}
-+
- size_t
- enet_protocol_command_size (enet_uint8 commandNumber)
- {
-@@ -262,9 +278,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
- ++ currentPeer)
- {
- if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
-- currentPeer -> address.host == host -> receivedAddress.host &&
- currentPeer -> address.port == host -> receivedAddress.port &&
-- currentPeer -> connectID == command -> connect.connectID)
-+ currentPeer -> connectID == command -> connect.connectID &&
-+ !memcmp(& currentPeer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)))
- return NULL;
- }
-
-@@ -848,10 +864,11 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
-
- if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
- peer -> state == ENET_PEER_STATE_ZOMBIE ||
-- (host -> receivedAddress.host != peer -> address.host &&
-- peer -> address.host != ENET_HOST_BROADCAST) ||
- (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
-- sessionID != peer -> incomingSessionID))
-+ sessionID != peer -> incomingSessionID) ||
-+ ( memcmp(& peer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)) &&
-+ memcmp(& peer -> address.host, & ENET_HOST_BROADCAST, sizeof (ENetHostAddress)) &&
-+ peer -> address.host.addr[0] != 0xff ) )
- return 0;
- }
-
-@@ -891,8 +908,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
-
- if (peer != NULL)
- {
-- peer -> address.host = host -> receivedAddress.host;
-- peer -> address.port = host -> receivedAddress.port;
-+ peer -> address = host -> receivedAddress;
- peer -> incomingDataTotal += host -> receivedDataLength;
- }
-
-@@ -1021,7 +1037,7 @@ commandError:
- }
-
- static int
--enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
-+enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event, ENetAddressFamily family)
- {
- for (;;)
- {
-@@ -1031,10 +1047,11 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
- buffer.data = host -> packetData [0];
- buffer.dataLength = sizeof (host -> packetData [0]);
-
-- receivedLength = enet_socket_receive (host -> socket,
-+ receivedLength = enet_socket_receive (family == ENET_IPV4 ? host -> socket4 : host -> socket6,
- & host -> receivedAddress,
- & buffer,
-- 1);
-+ 1,
-+ family);
-
- if (receivedLength < 0)
- return -1;
-@@ -1042,6 +1059,9 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
- if (receivedLength == 0)
- return 0;
-
-+ if (enet_get_address_family (& host -> receivedAddress) != family)
-+ return -1;
-+
- host -> receivedData = host -> packetData [0];
- host -> receivedDataLength = receivedLength;
-
-@@ -1373,6 +1393,9 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
- currentPeer < & host -> peers [host -> peerCount];
- ++ currentPeer)
- {
-+ ENetAddressFamily family;
-+ ENetSocket socket;
-+
- if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
- currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
- continue;
-@@ -1497,7 +1520,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
-
- currentPeer -> lastSendTime = host -> serviceTime;
-
-- sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
-+ family = enet_get_address_family (& currentPeer -> address);
-+ socket = family == ENET_IPV4 ? host -> socket4 : host -> socket6;
-+ if (socket == ENET_SOCKET_NULL)
-+ return -1;
-+ sentLength = enet_socket_send (socket,
-+ & currentPeer -> address,
-+ host -> buffers,
-+ host -> bufferCount,
-+ family);
-
- enet_protocol_remove_sent_unreliable_commands (currentPeer);
-
-@@ -1608,7 +1639,23 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
- break;
- }
-
-- switch (enet_protocol_receive_incoming_commands (host, event))
-+ if (host -> socket4 != ENET_SOCKET_NULL)
-+ switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV4))
-+ {
-+ case 1:
-+ return 1;
-+
-+ case -1:
-+ perror ("Error receiving incoming packets");
-+
-+ return -1;
-+
-+ default:
-+ break;
-+ }
-+
-+ if (host -> socket6 != ENET_SOCKET_NULL)
-+ switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV6))
- {
- case 1:
- return 1;
-@@ -1660,7 +1707,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
-
- waitCondition = ENET_SOCKET_WAIT_RECEIVE;
-
-- if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
-+ if (enet_socket_wait (host -> socket4, host -> socket6, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
- return -1;
-
- host -> serviceTime = enet_time_get ();
-diff --git a/unix.c b/unix.c
-index 6971541..992ecd3 100644
---- a/unix.c
-+++ b/unix.c
-@@ -71,122 +71,161 @@ enet_time_set (enet_uint32 newTimeBase)
- timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
- }
-
--int
--enet_address_set_host (ENetAddress * address, const char * name)
-+static enet_uint16
-+enet_af (ENetAddressFamily family)
- {
-- struct hostent * hostEntry = NULL;
--#ifdef HAS_GETHOSTBYNAME_R
-- struct hostent hostData;
-- char buffer [2048];
-- int errnum;
--
--#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-- gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
--#else
-- hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
--#endif
--#else
-- hostEntry = gethostbyname (name);
--#endif
-+ 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 (struct sockaddr_in);
-+ if (family == ENET_IPV6)
-+ return sizeof (struct sockaddr_in6);
-+ return 0;
-+}
-
-- if (hostEntry == NULL ||
-- hostEntry -> h_addrtype != AF_INET)
-+static ENetAddressFamily
-+enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
-+{
-+ memset (address, 0, sizeof (ENetAddress));
-+ if (sin -> sa_family == AF_INET)
- {
--#ifdef HAS_INET_PTON
-- if (! inet_pton (AF_INET, name, & address -> host))
--#else
-- if (! inet_aton (name, (struct in_addr *) & address -> host))
--#endif
-- return -1;
-- return 0;
-+ address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
-+ /* address -> scopeID = 0; */
-+ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
-+ return ENET_IPV4;
- }
--
-- address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
--
-- return 0;
-+ if (sin -> sa_family == AF_INET6)
-+ {
-+ address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
-+ address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
-+ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
-+ return ENET_IPV6;
-+ }
-+ return ENET_NO_ADDRESS_FAMILY;
- }
-
--int
--enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
-+static int
-+enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
- {
--#ifdef HAS_INET_NTOP
-- if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
--#else
-- char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
-- if (addr != NULL)
-- strncpy (name, addr, nameLength);
-- else
--#endif
-- return -1;
-- return 0;
-+ 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))))
-+ {
-+ ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
-+ ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
-+ ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
-+ return 0;
-+ }
-+ else if (family == ENET_IPV6)
-+ {
-+ ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
-+ ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
-+ ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
-+ ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
-+ return 0;
-+ }
-+ return -1;
- }
-
- int
--enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
-+enet_address_set_host (ENetAddress * address, const char * name)
- {
-- struct in_addr in;
-- struct hostent * hostEntry = NULL;
--#ifdef HAS_GETHOSTBYADDR_R
-- struct hostent hostData;
-- char buffer [2048];
-- int errnum;
-+ enet_uint16 port = address -> port;
-+ struct addrinfo hints;
-+ struct addrinfo * result;
-+ struct addrinfo * res;
-
-- in.s_addr = address -> host;
-+ memset(& hints, 0, sizeof (hints));
-+ hints.ai_flags = AI_ADDRCONFIG;
-+ hints.ai_family = AF_UNSPEC;
-
--#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-- gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
--#else
-- hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
--#endif
--#else
-- in.s_addr = address -> host;
-+ if ( getaddrinfo(name, NULL, &hints, &result) )
-+ return -1;
-
-- hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
--#endif
-+ for (res = result; res != NULL; res = res -> ai_next)
-+ {
-+ if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
-+ break;
-+ }
-
-- if (hostEntry == NULL)
-- return enet_address_get_host_ip (address, name, nameLength);
-+ address -> port = port;
-+ freeaddrinfo(result);
-+ if (res == NULL) return -1;
-
-- strncpy (name, hostEntry -> h_name, nameLength);
-+ return 0;
-+}
-+
-+static int
-+enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
-+{
-+ struct sockaddr_storage sin;
-+ enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
-+
-+ if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
-+ return -1;
-
- return 0;
- }
-
- int
--enet_socket_bind (ENetSocket socket, const ENetAddress * address)
-+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
- {
-- struct sockaddr_in sin;
-+ return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
-+}
-
-- memset (& sin, 0, sizeof (struct sockaddr_in));
-+int
-+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
-+{
-+ return enet_address_get_host_x(address, name, nameLength, 0);
-+}
-
-- sin.sin_family = AF_INET;
-+int
-+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
-+{
-+ struct 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((struct sockaddr *) & sin, address, family);
- }
- else
- {
-- sin.sin_port = 0;
-- sin.sin_addr.s_addr = INADDR_ANY;
-+ ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
-+ enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
- }
-
-- return bind (socket,
-- (struct sockaddr *) & sin,
-- sizeof (struct sockaddr_in));
-+ return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family));
- }
-
--int
-+int
- enet_socket_listen (ENetSocket socket, int backlog)
- {
- return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
- }
-
- 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);
-+ ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
-+
-+#ifdef IPV6_V6ONLY
-+ if (family == ENET_IPV6)
-+ {
-+ int value = 1;
-+ setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
-+ }
-+#endif /* IPV6_V6ONLY */
-+
-+ return sock;
- }
-
- int
-@@ -226,42 +265,36 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
- }
-
- int
--enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
- {
-- struct sockaddr_in sin;
--
-- memset (& sin, 0, sizeof (struct sockaddr_in));
-+ struct sockaddr_storage sin;
-+ enet_address_set_sin((struct sockaddr *) & sin, address, family);
-
-- 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));
-+ return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family));
- }
-
- ENetSocket
--enet_socket_accept (ENetSocket socket, ENetAddress * address)
-+enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
- {
- int result;
-- struct sockaddr_in sin;
-- socklen_t sinLength = sizeof (struct sockaddr_in);
-+ struct sockaddr_storage sin;
-+ socklen_t sinLength = enet_sa_size (family);
-
- result = accept (socket,
-- address != NULL ? (struct sockaddr *) & sin : NULL,
-+ address != NULL ? (struct sockaddr *) & sin : NULL,
- address != NULL ? & sinLength : NULL);
--
-+
- if (result == -1)
- return ENET_SOCKET_NULL;
-
- 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, (struct sockaddr *) & sin);
- }
-
- return result;
--}
--
-+}
-+
- void
- enet_socket_destroy (ENetSocket socket)
- {
-@@ -272,24 +305,20 @@ int
- enet_socket_send (ENetSocket socket,
- const ENetAddress * address,
- const ENetBuffer * buffers,
-- size_t bufferCount)
-+ size_t bufferCount,
-+ ENetAddressFamily family)
- {
- struct msghdr msgHdr;
-- struct sockaddr_in sin;
-+ struct sockaddr_storage sin;
- int sentLength;
-
- memset (& msgHdr, 0, sizeof (struct msghdr));
-
- 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((struct sockaddr *) & sin, address, family);
- msgHdr.msg_name = & sin;
-- msgHdr.msg_namelen = sizeof (struct sockaddr_in);
-+ msgHdr.msg_namelen = enet_sa_size (family);
- }
-
- msgHdr.msg_iov = (struct iovec *) buffers;
-@@ -312,10 +341,11 @@ int
- enet_socket_receive (ENetSocket socket,
- ENetAddress * address,
- ENetBuffer * buffers,
-- size_t bufferCount)
-+ size_t bufferCount,
-+ ENetAddressFamily family)
- {
- struct msghdr msgHdr;
-- struct sockaddr_in sin;
-+ struct sockaddr_storage sin;
- int recvLength;
-
- memset (& msgHdr, 0, sizeof (struct msghdr));
-@@ -323,7 +353,7 @@ enet_socket_receive (ENetSocket socket,
- if (address != NULL)
- {
- msgHdr.msg_name = & sin;
-- msgHdr.msg_namelen = sizeof (struct sockaddr_in);
-+ msgHdr.msg_namelen = enet_sa_size (family);
- }
-
- msgHdr.msg_iov = (struct iovec *) buffers;
-@@ -346,8 +376,7 @@ enet_socket_receive (ENetSocket socket,
-
- 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, (struct sockaddr *) & sin);
- }
-
- return recvLength;
-@@ -365,22 +394,38 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
- }
-
- 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)
- {
- #ifdef HAS_POLL
-- struct pollfd pollSocket;
-+ struct pollfd pollSocket[2];
- int pollCount;
--
-- pollSocket.fd = socket;
-- pollSocket.events = 0;
-+
-+ pollSocket[0].fd = socket4;
-+ pollSocket[1].fd = socket6;
-+ pollSocket[0].events = 0;
-+ pollSocket[1].events = 0;
-+ /* pollSocket[0].revents = 0; */
-+ pollSocket[1].revents = 0;
-+
-+ if (pollSocket[0].fd == ENET_SOCKET_NULL)
-+ {
-+ pollSocket[0].fd = pollSocket[1].fd;
-+ pollSocket[1].fd = ENET_SOCKET_NULL;
-+ }
-
- if (* condition & ENET_SOCKET_WAIT_SEND)
-- pollSocket.events |= POLLOUT;
-+ {
-+ pollSocket[0].events |= POLLOUT;
-+ pollSocket[1].events |= POLLOUT;
-+ }
-
- if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-- pollSocket.events |= POLLIN;
-+ {
-+ pollSocket[0].events |= POLLIN;
-+ pollSocket[1].events |= POLLIN;
-+ }
-
-- pollCount = poll (& pollSocket, 1, timeout);
-+ pollCount = poll (pollSocket, pollSocket[1].fd != ENET_SOCKET_NULL ? 2 : 1, timeout);
-
- if (pollCount < 0)
- return -1;
-@@ -390,10 +435,10 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
- if (pollCount == 0)
- return 0;
-
-- if (pollSocket.revents & POLLOUT)
-+ if ((pollSocket[0].revents | pollSocket[1].revents) & POLLOUT)
- * condition |= ENET_SOCKET_WAIT_SEND;
-
-- if (pollSocket.revents & POLLIN)
-+ if ((pollSocket[0].revents | pollSocket[1].revents) & POLLIN)
- * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
- return 0;
-@@ -401,6 +446,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
- fd_set readSet, writeSet;
- struct timeval timeVal;
- int selectCount;
-+ ENetSocket maxSocket;
-
- timeVal.tv_sec = timeout / 1000;
- timeVal.tv_usec = (timeout % 1000) * 1000;
-@@ -409,12 +455,28 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
- 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);
-+ {
-+ if (socket4 != ENET_SOCKET_NULL)
-+ FD_SET (socket4, & readSet);
-+ if (socket6 != ENET_SOCKET_NULL)
-+ FD_SET (socket6, & readSet);
-+ }
-+
-+ maxSocket = 0;
-+ if (socket4 != ENET_SOCKET_NULL)
-+ maxSocket = socket4;
-+ if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
-+ maxSocket = socket6;
-
-- selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
-+ selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
-
- if (selectCount < 0)
- return -1;
-@@ -424,11 +486,13 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
- if (selectCount == 0)
- return 0;
-
-- if (FD_ISSET (socket, & writeSet))
-- * condition |= ENET_SOCKET_WAIT_SEND;
-+ if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
-+ (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
-+ * condition |= ENET_SOCKET_WAIT_SEND;
-
-- if (FD_ISSET (socket, & readSet))
-- * condition |= ENET_SOCKET_WAIT_RECEIVE;
-+ 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
-diff --git a/win32.c b/win32.c
-index e1fae23..2607160 100644
---- a/win32.c
-+++ b/win32.c
-@@ -4,6 +4,8 @@
- */
- #ifdef WIN32
-
-+#define _WIN32_WINNT 0x0501
-+
- #include <time.h>
- #define ENET_BUILDING_LIB 1
- #include "enet/enet.h"
-@@ -13,14 +15,14 @@ static enet_uint32 timeBase = 0;
- int
- enet_initialize (void)
- {
-- WORD versionRequested = MAKEWORD (1, 1);
-+ WORD versionRequested = MAKEWORD (2, 2);
- WSADATA wsaData;
-
- if (WSAStartup (versionRequested, & wsaData))
- return -1;
-
-- if (LOBYTE (wsaData.wVersion) != 1||
-- HIBYTE (wsaData.wVersion) != 1)
-+ if (LOBYTE (wsaData.wVersion) != 2||
-+ HIBYTE (wsaData.wVersion) != 2)
- {
- WSACleanup ();
-
-@@ -52,77 +54,139 @@ enet_time_set (enet_uint32 newTimeBase)
- timeBase = (enet_uint32) timeGetTime () - newTimeBase;
- }
-
--int
--enet_address_set_host (ENetAddress * address, const char * name)
-+static enet_uint16
-+enet_af (ENetAddressFamily family)
- {
-- struct hostent * hostEntry;
-+ if (family == ENET_IPV4)
-+ return AF_INET;
-+ if (family == ENET_IPV6)
-+ return AF_INET6;
-+ return 0;
-+}
-
-- hostEntry = gethostbyname (name);
-- if (hostEntry == NULL ||
-- hostEntry -> h_addrtype != AF_INET)
-+static socklen_t
-+enet_sa_size (ENetAddressFamily family)
-+{
-+ if (family == ENET_IPV4)
-+ return sizeof (struct sockaddr_in);
-+ if (family == ENET_IPV6)
-+ return sizeof (struct sockaddr_in6);
-+ return 0;
-+}
-+
-+static ENetAddressFamily
-+enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
-+{
-+ memset (address, 0, sizeof (ENetAddress));
-+ if (sin -> sa_family == AF_INET)
- {
-- unsigned long host = inet_addr (name);
-- if (host == INADDR_NONE)
-- return -1;
-- address -> host = host;
-- return 0;
-+ address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
-+ /* address -> scopeID = 0; */
-+ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
-+ return ENET_IPV4;
- }
-+ if (sin -> sa_family == AF_INET6)
-+ {
-+ address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
-+ address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
-+ address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
-+ return ENET_IPV6;
-+ }
-+ return ENET_NO_ADDRESS_FAMILY;
-+}
-
-- address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
--
-- return 0;
-+static int
-+enet_address_set_sin (struct 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))))
-+ {
-+ ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
-+ ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
-+ ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
-+ return 0;
-+ }
-+ else if (family == ENET_IPV6)
-+ {
-+ ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
-+ ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
-+ ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
-+ ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
-+ return 0;
-+ }
-+ return -1;
- }
-
- int
--enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
-+enet_address_set_host (ENetAddress * address, const char * name)
- {
-- char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
-- if (addr == NULL)
-+ enet_uint16 port = address -> port;
-+ struct addrinfo hints;
-+ struct addrinfo * result;
-+ struct addrinfo * res;
-+
-+ memset(& hints, 0, sizeof (hints));
-+ hints.ai_flags = AI_ADDRCONFIG;
-+ hints.ai_family = AF_UNSPEC;
-+
-+ if ( getaddrinfo(name, NULL, &hints, &result) )
- return -1;
-- strncpy (name, addr, nameLength);
-+
-+ 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;
- }
-
--int
--enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
-+static int
-+enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
- {
-- 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);
-+ struct sockaddr_storage sin;
-+ enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
-
-- strncpy (name, hostEntry -> h_name, nameLength);
-+ if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
-+ return -1;
-
- return 0;
- }
-
- int
--enet_socket_bind (ENetSocket socket, const ENetAddress * address)
-+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
- {
-- struct sockaddr_in sin;
-+ return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
-+}
-
-- memset (& sin, 0, sizeof (struct sockaddr_in));
-+int
-+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
-+{
-+ return enet_address_get_host_x(address, name, nameLength, 0);
-+}
-
-- sin.sin_family = AF_INET;
-+int
-+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
-+{
-+ struct 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((struct sockaddr *) & sin, address, family);
- }
- else
- {
-- sin.sin_port = 0;
-- sin.sin_addr.s_addr = INADDR_ANY;
-+ ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
-+ enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
- }
-
-- return bind (socket,
-- (struct sockaddr *) & sin,
-- sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
-+ return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
- }
-
- int
-@@ -132,9 +196,10 @@ enet_socket_listen (ENetSocket socket, int backlog)
- }
-
- 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);
-+ ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
-+ return sock;
- }
-
- int
-@@ -173,28 +238,23 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
- }
-
- int
--enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
- {
-- struct sockaddr_in sin;
--
-- memset (& sin, 0, sizeof (struct sockaddr_in));
-+ struct sockaddr_storage sin;
-+ enet_address_set_sin((struct sockaddr *) & sin, address, family);
-
-- 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;
-+ return connect (socket, (struct 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);
-+ struct sockaddr_storage sin;
-+ socklen_t sinLength = enet_sa_size (family);
-
- result = accept (socket,
-- address != NULL ? (struct sockaddr *) & sin : NULL,
-+ address != NULL ? (struct sockaddr *) & sin : NULL,
- address != NULL ? & sinLength : NULL);
-
- if (result == INVALID_SOCKET)
-@@ -202,8 +262,7 @@ enet_socket_accept (ENetSocket socket, ENetAddress * address)
-
- 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, (struct sockaddr *) & sin);
- }
-
- return result;
-@@ -219,18 +278,15 @@ int
- enet_socket_send (ENetSocket socket,
- const ENetAddress * address,
- const ENetBuffer * buffers,
-- size_t bufferCount)
-+ size_t bufferCount,
-+ ENetAddressFamily family)
- {
-- struct sockaddr_in sin;
-+ struct 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((struct sockaddr *) & sin, address, family);
- }
-
- if (WSASendTo (socket,
-@@ -239,7 +295,7 @@ enet_socket_send (ENetSocket socket,
- & sentLength,
- 0,
- address != NULL ? (struct sockaddr *) & sin : 0,
-- address != NULL ? sizeof (struct sockaddr_in) : 0,
-+ address != NULL ? enet_sa_size (family) : 0,
- NULL,
- NULL) == SOCKET_ERROR)
- {
-@@ -256,12 +312,13 @@ int
- enet_socket_receive (ENetSocket socket,
- ENetAddress * address,
- ENetBuffer * buffers,
-- size_t bufferCount)
-+ size_t bufferCount,
-+ ENetAddressFamily family)
- {
-- INT sinLength = sizeof (struct sockaddr_in);
-+ INT sinLength = enet_sa_size (family);
- DWORD flags = 0,
- recvLength;
-- struct sockaddr_in sin;
-+ struct sockaddr_storage sin;
-
- if (WSARecvFrom (socket,
- (LPWSABUF) buffers,
-@@ -288,8 +345,7 @@ enet_socket_receive (ENetSocket socket,
-
- 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, (struct sockaddr *) & sin);
- }
-
- return (int) recvLength;
-@@ -307,25 +363,42 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
- }
-
- 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;
--
-+ ENetSocket maxSocket;
-+
- 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);
-+ {
-+ if (socket4 != ENET_SOCKET_NULL)
-+ FD_SET (socket4, & readSet);
-+ if (socket6 != ENET_SOCKET_NULL)
-+ FD_SET (socket6, & readSet);
-+ }
-
-- selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
-+ 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)
- return -1;
-@@ -335,14 +408,16 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
- if (selectCount == 0)
- return 0;
-
-- if (FD_ISSET (socket, & writeSet))
-- * condition |= ENET_SOCKET_WAIT_SEND;
--
-- if (FD_ISSET (socket, & readSet))
-- * condition |= ENET_SOCKET_WAIT_RECEIVE;
-+ 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
-
---
-1.7.1
-
Modified: code/trunk/src/external/enet/peer.c
===================================================================
--- code/trunk/src/external/enet/peer.c 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/peer.c 2011-03-17 23:08:44 UTC (rev 8088)
@@ -108,6 +108,8 @@
return -1;
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
+ if (peer -> host -> checksum != NULL)
+ fragmentLength -= sizeof(enet_uint32);
if (packet -> dataLength > fragmentLength)
{
Modified: code/trunk/src/external/enet/protocol.c
===================================================================
--- code/trunk/src/external/enet/protocol.c 2011-03-17 15:09:37 UTC (rev 8087)
+++ code/trunk/src/external/enet/protocol.c 2011-03-17 23:08:44 UTC (rev 8088)
@@ -188,6 +188,7 @@
ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand;
ENetProtocolCommand commandNumber;
+ int wasSent = 1;
for (currentCommand = enet_list_begin (& peer -> sentReliableCommands);
currentCommand != enet_list_end (& peer -> sentReliableCommands);
@@ -217,6 +218,8 @@
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
return ENET_PROTOCOL_COMMAND_NONE;
+
+ wasSent = 0;
}
if (channelID < peer -> channelCount)
@@ -237,7 +240,8 @@
if (outgoingCommand -> packet != NULL)
{
- peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
+ if (wasSent)
+ peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
-- outgoingCommand -> packet -> referenceCount;
@@ -1272,7 +1276,7 @@
return 0;
}
-static void
+static int
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
{
ENetProtocol * command = & host -> commands [host -> commandCount];
@@ -1282,6 +1286,7 @@
ENetChannel *channel;
enet_uint16 reliableWindow;
size_t commandSize;
+ int windowExceeded = 0, windowWrap = 0, canPing = 1;
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
@@ -1291,37 +1296,54 @@
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
- if (channel != NULL &&
- outgoingCommand -> sendAttempts < 1 &&
- ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
- (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
- channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
- (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
- break;
-
+ if (channel != NULL)
+ {
+ if (! windowWrap &&
+ outgoingCommand -> sendAttempts < 1 &&
+ ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
+ (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
+ channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
+ (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
+ windowWrap = 1;
+ if (windowWrap)
+ {
+ currentCommand = enet_list_next (currentCommand);
+
+ continue;
+ }
+ }
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ if (! windowExceeded)
+ {
+ enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
+
+ if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
+ windowExceeded = 1;
+ }
+ if (windowExceeded)
+ {
+ currentCommand = enet_list_next (currentCommand);
+
+ continue;
+ }
+ }
+
+ canPing = 0;
+
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
- peer -> mtu - host -> packetSize < commandSize)
+ peer -> mtu - host -> packetSize < commandSize ||
+ (outgoingCommand -> packet != NULL &&
+ (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
{
host -> continueSending = 1;
break;
}
- if (outgoingCommand -> packet != NULL)
- {
- if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
- break;
-
- if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))
- {
- host -> continueSending = 1;
-
- break;
- }
- }
-
currentCommand = enet_list_next (currentCommand);
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
@@ -1374,6 +1396,8 @@
host -> commandCount = command - host -> commands;
host -> bufferCount = buffer - host -> buffers;
+
+ return canPing;
}
static int
@@ -1414,10 +1438,9 @@
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
return 1;
- if (! enet_list_empty (& currentPeer -> outgoingReliableCommands))
- enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
- else
- if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
+ if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
+ enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
+ enet_list_empty (& currentPeer -> sentReliableCommands) &&
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL &&
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
{
More information about the Orxonox-commit
mailing list