Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ipv6/src/external/enet/patches/patch @ 7377

Last change on this file since 7377 was 7377, checked in by adrfried, 15 years ago

using two separate sockets for ipv4 and ipv6

File size: 26.8 KB
RevLine 
[7377]1diff --git a/host.c b/host.c
2index 8bb2433..85dfa3c 100644
3--- a/host.c
4+++ b/host.c
5@@ -48,11 +48,15 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
6     }
7     memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
8 
9-    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
10-    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
11+
12+    // FIXME: check address for ANY_ADRESS if not only bind to specific protocol
13+    // FIXME: allow to fail one of the two protocols
14+    /* IPv4 */
15+    host -> socket4 = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, ENET_IPV4);
16+    if (host -> socket4 == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket4, address, ENET_IPV4) < 0))
17     {
18-       if (host -> socket != ENET_SOCKET_NULL)
19-         enet_socket_destroy (host -> socket);
20+       if (host -> socket4 != ENET_SOCKET_NULL)
21+         enet_socket_destroy (host -> socket4);
22 
23        enet_free (host -> peers);
24        enet_free (host);
25@@ -60,10 +64,32 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
26        return NULL;
27     }
28 
29-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
30-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
31-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
32-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
33+    enet_socket_set_option (host -> socket4, ENET_SOCKOPT_NONBLOCK, 1);
34+    enet_socket_set_option (host -> socket4, ENET_SOCKOPT_BROADCAST, 1);
35+    enet_socket_set_option (host -> socket4, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
36+    enet_socket_set_option (host -> socket4, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
37+
38+    /* IPv6 */
39+    host -> socket6 = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, ENET_IPV6);
40+    if (host -> socket6 == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket6, address, ENET_IPV6) < 0))
41+    {
42+       if (host -> socket6 != ENET_SOCKET_NULL)
43+       {
44+           enet_socket_destroy (host -> socket4);
45+           enet_socket_destroy (host -> socket6);
46+       }
47+
48+       enet_free (host -> peers);
49+       enet_free (host);
50+
51+       return NULL;
52+    }
53+
54+    enet_socket_set_option (host -> socket6, ENET_SOCKOPT_NONBLOCK, 1);
55+    enet_socket_set_option (host -> socket6, ENET_SOCKOPT_BROADCAST, 1);
56+    enet_socket_set_option (host -> socket6, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
57+    enet_socket_set_option (host -> socket6, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
58+
59 
60     if (address != NULL)
61       host -> address = * address;
62@@ -133,7 +159,8 @@ enet_host_destroy (ENetHost * host)
63 {
64     ENetPeer * currentPeer;
65 
66-    enet_socket_destroy (host -> socket);
67+    enet_socket_destroy (host -> socket4);
68+    enet_socket_destroy (host -> socket6);
69 
70     for (currentPeer = host -> peers;
71          currentPeer < & host -> peers [host -> peerCount];
72diff --git a/include/enet/enet.h b/include/enet/enet.h
73index 2f656d6..39cf93e 100644
74--- a/include/enet/enet.h
75+++ b/include/enet/enet.h
76@@ -53,13 +53,16 @@ typedef enum _ENetSocketOption
77    ENET_SOCKOPT_REUSEADDR = 5
78 } ENetSocketOption;
79 
80-enum
81+typedef struct _ENetHostAddress
82 {
83-   ENET_HOST_ANY       = 0,            /**< specifies the default server host */
84-   ENET_HOST_BROADCAST = 0xFFFFFFFF,   /**< specifies a subnet-wide broadcast */
85+   enet_uint8 addr[16];
86+} ENetHostAddress;
87 
88-   ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
89-};
90+extern const ENetHostAddress ENET_HOST_ANY;          /**< specifies the default server host */
91+extern const ENetHostAddress ENET_IPV4MAPPED_PREFIX; /**< specifies the IPv4-mapped IPv6 prefix */
92+extern const ENetHostAddress ENET_HOST_BROADCAST;    /**< specifies a IPv4 subnet-wide broadcast */
93+#define ENET_IPV4MAPPED_PREFIX_LEN 12                /**< specifies the length of the IPv4-mapped IPv6 prefix */
94+#define ENET_PORT_ANY 0                              /**< specifies that a port should be automatically chosen */
95 
96 /**
97  * Portable internet address structure.
98@@ -73,11 +76,22 @@ enum
99  */
100 typedef struct _ENetAddress
101 {
102-   enet_uint32 host;
103+   ENetHostAddress host;
104+   enet_uint32 scopeID; //FIXME: this is of different size on Windows
105    enet_uint16 port;
106 } ENetAddress;
107 
108 /**
109+ * The address family type.
110+ */
111+typedef enum _ENetAddressFamily
112+{
113+    ENET_NO_ADDRESS_FAMILY = 0,
114+    ENET_IPV4 = 1,
115+    ENET_IPV6 = 2
116+} ENetAddressFamily;
117+
118+/**
119  * Packet flag bit constants.
120  *
121  * The host must be specified in network byte-order, and the port must be in
122@@ -321,7 +335,8 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b
123   */
124 typedef struct _ENetHost
125 {
126-   ENetSocket           socket;
127+   ENetSocket           socket4;
128+   ENetSocket           socket6;
129    ENetAddress          address;                     /**< Internet address of the host */
130    enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
131    enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
132@@ -441,14 +456,14 @@ ENET_API void enet_time_set (enet_uint32);
133 /** @defgroup socket ENet socket functions
134     @{
135 */
136-ENET_API ENetSocket enet_socket_create (ENetSocketType);
137-ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *);
138+ENET_API ENetSocket enet_socket_create (ENetSocketType, ENetAddressFamily);
139+ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *, ENetAddressFamily);
140 ENET_API int        enet_socket_listen (ENetSocket, int);
141-ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
142-ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *);
143-ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
144-ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
145-ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
146+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *, ENetAddressFamily);
147+ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *, ENetAddressFamily);
148+ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t, ENetAddressFamily);
149+ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t, ENetAddressFamily);
150+ENET_API int        enet_socket_wait (ENetSocket, ENetSocket, enet_uint32 *, enet_uint32);
151 ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
152 ENET_API void       enet_socket_destroy (ENetSocket);
153 ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
154@@ -488,6 +503,18 @@ ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN
155 */
156 ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
157 
158+/** Maps an IPv4 Address to an IPv6 address.
159+    @param address IPv4 address in network byte order
160+    @returns the IPv4-mapped IPv6 address in network byte order
161+*/
162+ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address);
163+
164+/** Returns the Address family of an (IPv4-mapped) IPv6 address.
165+    @param address IPv6 address
166+    @returns address family
167+*/
168+ENET_API ENetAddressFamily enet_get_address_family (const ENetAddress * address);
169+
170 /** @} */
171 
172 ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
173diff --git a/protocol.c b/protocol.c
174index 8e26dfb..37f6387 100644
175--- a/protocol.c
176+++ b/protocol.c
177@@ -9,6 +9,10 @@
178 #include "enet/time.h"
179 #include "enet/enet.h"
180 
181+const ENetHostAddress ENET_HOST_ANY = { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } };
182+const ENetHostAddress ENET_IPV4MAPPED_PREFIX = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0,0,0,0 } };
183+const ENetHostAddress ENET_HOST_BROADCAST = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
184+
185 static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
186 {
187     0,
188@@ -25,6 +29,22 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
189     sizeof (ENetProtocolThrottleConfigure),
190 };
191 
192+ENetHostAddress
193+enet_address_map4 (enet_uint32 address)
194+{
195+    ENetHostAddress addr = ENET_IPV4MAPPED_PREFIX;
196+    ((enet_uint32 *)addr.addr)[3] = address;
197+    return addr;
198+}
199+
200+ENetAddressFamily
201+enet_get_address_family (const ENetAddress * address)
202+{
203+    if (!memcmp(& address->host, & ENET_IPV4MAPPED_PREFIX, ENET_IPV4MAPPED_PREFIX_LEN))
204+        return ENET_IPV4;
205+    return ENET_IPV6;
206+}
207+
208 size_t
209 enet_protocol_command_size (enet_uint8 commandNumber)
210 {
211@@ -262,9 +282,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
212          ++ currentPeer)
213     {
214         if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
215-            currentPeer -> address.host == host -> receivedAddress.host &&
216             currentPeer -> address.port == host -> receivedAddress.port &&
217-            currentPeer -> connectID == command -> connect.connectID)
218+            currentPeer -> connectID == command -> connect.connectID &&
219+            !memcmp(& currentPeer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)))
220           return NULL;
221     }
222 
223@@ -848,10 +868,11 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
224 
225        if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
226            peer -> state == ENET_PEER_STATE_ZOMBIE ||
227-           (host -> receivedAddress.host != peer -> address.host &&
228-             peer -> address.host != ENET_HOST_BROADCAST) ||
229            (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
230-            sessionID != peer -> incomingSessionID))
231+            sessionID != peer -> incomingSessionID) ||
232+           ( memcmp(& peer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)) &&
233+             memcmp(& peer -> address.host, & ENET_HOST_BROADCAST, sizeof (ENetHostAddress)) &&
234+             peer -> address.host.addr[0] != 0xff ) )
235          return 0;
236     }
237 
238@@ -891,8 +912,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
239       
240     if (peer != NULL)
241     {
242-       peer -> address.host = host -> receivedAddress.host;
243-       peer -> address.port = host -> receivedAddress.port;
244+       peer -> address = host -> receivedAddress;
245        peer -> incomingDataTotal += host -> receivedDataLength;
246     }
247     
248@@ -1021,7 +1041,7 @@ commandError:
249 }
250 
251 static int
252-enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
253+enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event, ENetAddressFamily family)
254 {
255     for (;;)
256     {
257@@ -1031,10 +1051,11 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
258        buffer.data = host -> packetData [0];
259        buffer.dataLength = sizeof (host -> packetData [0]);
260 
261-       receivedLength = enet_socket_receive (host -> socket,
262+       receivedLength = enet_socket_receive (family == ENET_IPV4 ? host -> socket4 : host -> socket6,
263                                              & host -> receivedAddress,
264                                              & buffer,
265-                                             1);
266+                                             1,
267+                                             family);
268 
269        if (receivedLength < 0)
270          return -1;
271@@ -1042,6 +1063,9 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
272        if (receivedLength == 0)
273          return 0;
274 
275+       if (enet_get_address_family (& host -> receivedAddress) != family)
276+         return -1;
277+
278        host -> receivedData = host -> packetData [0];
279        host -> receivedDataLength = receivedLength;
280       
281@@ -1497,7 +1521,12 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
282 
283         currentPeer -> lastSendTime = host -> serviceTime;
284 
285-        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
286+        ENetAddressFamily family = enet_get_address_family (& currentPeer -> address);
287+        sentLength = enet_socket_send (family == ENET_IPV4 ? host -> socket4 : host -> socket6,
288+                                           & currentPeer -> address,
289+                                           host -> buffers,
290+                                           host -> bufferCount,
291+                                           family);
292 
293         enet_protocol_remove_sent_unreliable_commands (currentPeer);
294 
295@@ -1608,7 +1637,21 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
296           break;
297        }
298 
299-       switch (enet_protocol_receive_incoming_commands (host, event))
300+       switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV4))
301+       {
302+       case 1:
303+          return 1;
304+
305+       case -1:
306+          perror ("Error receiving incoming packets");
307+
308+          return -1;
309+
310+       default:
311+          break;
312+       }
313+
314+       switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV6))
315        {
316        case 1:
317           return 1;
318@@ -1660,7 +1703,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
319 
320        waitCondition = ENET_SOCKET_WAIT_RECEIVE;
321 
322-       if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
323+       if (enet_socket_wait (host -> socket4, host -> socket6, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
324          return -1;
325       
326        host -> serviceTime = enet_time_get ();
327diff --git a/unix.c b/unix.c
328index 6971541..96d17f8 100644
329--- a/unix.c
330+++ b/unix.c
331@@ -71,122 +71,162 @@ enet_time_set (enet_uint32 newTimeBase)
332     timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
333 }
334 
335-int
336-enet_address_set_host (ENetAddress * address, const char * name)
337+static enet_uint16
338+enet_af (ENetAddressFamily family)
339 {
340-    struct hostent * hostEntry = NULL;
341-#ifdef HAS_GETHOSTBYNAME_R
342-    struct hostent hostData;
343-    char buffer [2048];
344-    int errnum;
345-
346-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
347-    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
348-#else
349-    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
350-#endif
351-#else
352-    hostEntry = gethostbyname (name);
353-#endif
354+    if (family == ENET_IPV4)
355+        return AF_INET;
356+    if (family == ENET_IPV6)
357+        return AF_INET6;
358+    return 0;
359+}
360 
361-    if (hostEntry == NULL ||
362-        hostEntry -> h_addrtype != AF_INET)
363-    {
364-#ifdef HAS_INET_PTON
365-        if (! inet_pton (AF_INET, name, & address -> host))
366-#else
367-        if (! inet_aton (name, (struct in_addr *) & address -> host))
368-#endif
369-            return -1;
370-        return 0;
371-    }
372+static socklen_t
373+enet_sa_size (ENetAddressFamily family)
374+{
375+    if (family == ENET_IPV4)
376+        return sizeof (struct sockaddr_in);
377+    if (family == ENET_IPV6)
378+        return sizeof (struct sockaddr_in6);
379+    return 0;
380+}
381 
382-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
383 
384-    return 0;
385+static ENetAddressFamily
386+enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
387+{
388+    memset (address, 0, sizeof (ENetAddress));
389+    if (sin -> sa_family == AF_INET)
390+    {
391+        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
392+        //address -> scopeID = 0;
393+        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
394+        return ENET_IPV4;
395+    }
396+    if (sin -> sa_family == AF_INET6)
397+    {
398+        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
399+        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
400+        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
401+        return ENET_IPV6;
402+    }
403+    return ENET_NO_ADDRESS_FAMILY;
404 }
405 
406-int
407-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
408+static int
409+enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
410 {
411-#ifdef HAS_INET_NTOP
412-    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
413-#else
414-    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
415-    if (addr != NULL)
416-        strncpy (name, addr, nameLength);
417-    else
418-#endif
419-        return -1;
420-    return 0;
421+    memset (sin, 0, enet_sa_size(family));
422+    if (family == ENET_IPV4 &&
423+      (enet_get_address_family (address) == ENET_IPV4 ||
424+      !memcmp (address, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
425+    {
426+        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
427+        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
428+        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
429+        return 0;
430+    }
431+    else if (family == ENET_IPV6)
432+    {
433+        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
434+        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
435+        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
436+        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
437+        return 0;
438+    }
439+    return -1;
440 }
441 
442 int
443-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
444+enet_address_set_host (ENetAddress * address, const char * name)
445 {
446-    struct in_addr in;
447-    struct hostent * hostEntry = NULL;
448-#ifdef HAS_GETHOSTBYADDR_R
449-    struct hostent hostData;
450-    char buffer [2048];
451-    int errnum;
452+    enet_uint16 port = address -> port;
453+    struct addrinfo hints;
454+    struct addrinfo * result;
455+    struct addrinfo * res;
456 
457-    in.s_addr = address -> host;
458+    memset(& hints, 0, sizeof (hints));
459+    hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
460+    hints.ai_family = AF_UNSPEC;
461 
462-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
463-    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
464-#else
465-    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
466-#endif
467-#else
468-    in.s_addr = address -> host;
469+    if ( getaddrinfo(name, NULL, &hints, &result) )
470+        return -1;
471 
472-    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
473-#endif
474+    for (res = result; res != NULL; res = res -> ai_next)
475+    {
476+        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
477+            break;
478+    }
479 
480-    if (hostEntry == NULL)
481-      return enet_address_get_host_ip (address, name, nameLength);
482+    address -> port = port;
483+    freeaddrinfo(result);
484+    if (res == NULL) return -1;
485 
486-    strncpy (name, hostEntry -> h_name, nameLength);
487+    return 0;
488+}
489+
490+static int
491+enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
492+{
493+    struct sockaddr_storage sin;
494+    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
495+
496+    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
497+        return -1;
498 
499     return 0;
500 }
501 
502 int
503-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
504+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
505 {
506-    struct sockaddr_in sin;
507+    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
508+}
509 
510-    memset (& sin, 0, sizeof (struct sockaddr_in));
511+int
512+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
513+{
514+    return enet_address_get_host_x(address, name, nameLength, 0);
515+}
516 
517-    sin.sin_family = AF_INET;
518+int
519+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
520+{
521+    struct sockaddr_storage sin;
522 
523     if (address != NULL)
524     {
525-       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
526-       sin.sin_addr.s_addr = address -> host;
527+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
528     }
529     else
530     {
531-       sin.sin_port = 0;
532-       sin.sin_addr.s_addr = INADDR_ANY;
533+        ENetAddress address_ = { ENET_HOST_ANY, 0, 0 };
534+        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
535     }
536 
537-    return bind (socket,
538-                 (struct sockaddr *) & sin,
539-                 sizeof (struct sockaddr_in));
540+    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family));
541 }
542 
543-int
544+int
545 enet_socket_listen (ENetSocket socket, int backlog)
546 {
547     return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
548 }
549 
550 ENetSocket
551-enet_socket_create (ENetSocketType type)
552+enet_socket_create (ENetSocketType type, ENetAddressFamily family)
553 {
554-    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
555+    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
556+
557+#ifdef IPV6_V6ONLY
558+    if (family == ENET_IPV6)
559+    {
560+        int value = 1;
561+        setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
562+    }
563+#endif // IPV6_V6ONLY
564+
565+    return sock;
566 }
567 
568 int
569@@ -226,37 +266,31 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
570 }
571 
572 int
573-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
574+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
575 {
576-    struct sockaddr_in sin;
577-
578-    memset (& sin, 0, sizeof (struct sockaddr_in));
579+    struct sockaddr_storage sin;
580+    enet_address_set_sin((struct sockaddr *) & sin, address, family);
581 
582-    sin.sin_family = AF_INET;
583-    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
584-    sin.sin_addr.s_addr = address -> host;
585-
586-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
587+    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family));
588 }
589 
590 ENetSocket
591-enet_socket_accept (ENetSocket socket, ENetAddress * address)
592+enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
593 {
594     int result;
595-    struct sockaddr_in sin;
596-    socklen_t sinLength = sizeof (struct sockaddr_in);
597+    struct sockaddr_storage sin;
598+    socklen_t sinLength = enet_sa_size (family);
599 
600     result = accept (socket,
601                      address != NULL ? (struct sockaddr *) & sin : NULL,
602                      address != NULL ? & sinLength : NULL);
603-   
604+
605     if (result == -1)
606       return ENET_SOCKET_NULL;
607 
608     if (address != NULL)
609     {
610-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
611-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
612+        enet_address_set_address(address, (struct sockaddr *) & sin);
613     }
614 
615     return result;
616@@ -272,24 +306,20 @@ int
617 enet_socket_send (ENetSocket socket,
618                   const ENetAddress * address,
619                   const ENetBuffer * buffers,
620-                  size_t bufferCount)
621+                  size_t bufferCount,
622+                  ENetAddressFamily family)
623 {
624     struct msghdr msgHdr;
625-    struct sockaddr_in sin;
626+    struct sockaddr_storage sin;
627     int sentLength;
628 
629     memset (& msgHdr, 0, sizeof (struct msghdr));
630 
631     if (address != NULL)
632     {
633-        memset (& sin, 0, sizeof (struct sockaddr_in));
634-
635-        sin.sin_family = AF_INET;
636-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
637-        sin.sin_addr.s_addr = address -> host;
638-
639+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
640         msgHdr.msg_name = & sin;
641-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
642+        msgHdr.msg_namelen = enet_sa_size (family);
643     }
644 
645     msgHdr.msg_iov = (struct iovec *) buffers;
646@@ -312,10 +342,11 @@ int
647 enet_socket_receive (ENetSocket socket,
648                      ENetAddress * address,
649                      ENetBuffer * buffers,
650-                     size_t bufferCount)
651+                     size_t bufferCount,
652+                     ENetAddressFamily family)
653 {
654     struct msghdr msgHdr;
655-    struct sockaddr_in sin;
656+    struct sockaddr_storage sin;
657     int recvLength;
658 
659     memset (& msgHdr, 0, sizeof (struct msghdr));
660@@ -323,7 +354,7 @@ enet_socket_receive (ENetSocket socket,
661     if (address != NULL)
662     {
663         msgHdr.msg_name = & sin;
664-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
665+        msgHdr.msg_namelen = enet_sa_size (family);
666     }
667 
668     msgHdr.msg_iov = (struct iovec *) buffers;
669@@ -346,8 +377,7 @@ enet_socket_receive (ENetSocket socket,
670 
671     if (address != NULL)
672     {
673-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
674-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
675+        enet_address_set_address(address, (struct sockaddr *) & sin);
676     }
677 
678     return recvLength;
679@@ -365,22 +395,31 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
680 }
681 
682 int
683-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
684+enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
685 {
686-#ifdef HAS_POLL
687-    struct pollfd pollSocket;
688+    //FIXME allow only one of the sockets being available
689+//#ifdef HAS_POLL
690+    struct pollfd pollSocket[2];
691     int pollCount;
692     
693-    pollSocket.fd = socket;
694-    pollSocket.events = 0;
695+    pollSocket[0].fd = socket4;
696+    pollSocket[1].fd = socket6;
697+    pollSocket[0].events = 0;
698+    pollSocket[1].events = 0;
699 
700     if (* condition & ENET_SOCKET_WAIT_SEND)
701-      pollSocket.events |= POLLOUT;
702+    {
703+        pollSocket[0].events |= POLLOUT;
704+        pollSocket[1].events |= POLLOUT;
705+    }
706 
707     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
708-      pollSocket.events |= POLLIN;
709+    {
710+        pollSocket[0].events |= POLLIN;
711+        pollSocket[1].events |= POLLIN;
712+    }
713 
714-    pollCount = poll (& pollSocket, 1, timeout);
715+    pollCount = poll (pollSocket, 2, timeout);
716 
717     if (pollCount < 0)
718       return -1;
719@@ -390,13 +429,15 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
720     if (pollCount == 0)
721       return 0;
722 
723-    if (pollSocket.revents & POLLOUT)
724+    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLOUT)
725       * condition |= ENET_SOCKET_WAIT_SEND;
726     
727-    if (pollSocket.revents & POLLIN)
728+    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLIN)
729       * condition |= ENET_SOCKET_WAIT_RECEIVE;
730 
731     return 0;
732+/*
733+FIXME: implement this
734 #else
735     fd_set readSet, writeSet;
736     struct timeval timeVal;
737@@ -432,6 +473,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
738 
739     return 0;
740 #endif
741+*/
742 }
743 
744 #endif
Note: See TracBrowser for help on using the repository browser.