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