Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ipv6/src/external/enet/patches/0004-using-two-separate-sockets-for-IPv4-and-IPv6.patch @ 7389

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

fix some stuff

File size: 12.2 KB
RevLine 
[7389]1From 9801a6bcd072870248a6b07245fc09a9492f8f51 Mon Sep 17 00:00:00 2001
[7378]2From: Adrian Friedli <adi@koalatux.ch>
3Date: Wed, 8 Sep 2010 12:50:04 +0200
4Subject: [PATCH 4/4] using two separate sockets for IPv4 and IPv6
5
6---
[7389]7 host.c              |   53 +++++++++++++++++++++++++++++++++++++-------------
8 include/enet/enet.h |   11 ++++++++-
9 protocol.c          |   47 +++++++++++++++++++++++++++++++++++++++-----
10 unix.c              |   47 ++++++++++++++++++++++++++++++++------------
11 4 files changed, 123 insertions(+), 35 deletions(-)
[7378]12
13diff --git a/host.c b/host.c
[7389]14index 9ccf894..46e52c9 100644
[7378]15--- a/host.c
16+++ b/host.c
[7389]17@@ -7,6 +7,27 @@
18 #include <time.h>
19 #include "enet/enet.h"
20 
21+static ENetSocket
22+enet_socket_create_bind (const ENetAddress * address, ENetAddressFamily family)
23+{
24+    ENetSocket socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, family);
25+    if (socket == ENET_SOCKET_NULL)
26+        return ENET_SOCKET_NULL;
27+
28+    if (address != NULL && enet_socket_bind (socket, address, family) < 0)
29+    {
30+        enet_socket_destroy (socket);
31+        return ENET_SOCKET_NULL;
32+    }
33+
34+    enet_socket_set_option (socket, ENET_SOCKOPT_NONBLOCK, 1);
35+    enet_socket_set_option (socket, ENET_SOCKOPT_BROADCAST, 1);
36+    enet_socket_set_option (socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
37+    enet_socket_set_option (socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
38+
39+    return socket;
40+}
41+
42 /** @defgroup host ENet host functions
43     @{
44 */
45@@ -48,23 +69,24 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
[7378]46     }
47     memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
48 
49-    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, ENET_IPV6);
50-    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address, ENET_IPV6) < 0))
[7389]51-    {
[7378]52-       if (host -> socket != ENET_SOCKET_NULL)
53-         enet_socket_destroy (host -> socket);
[7389]54+    int family = (address == NULL || !memcmp (& address -> host, & ENET_HOST_ANY, sizeof (ENetHostAddress))) ?
55+        ENET_IPV4 | ENET_IPV6 :
56+        enet_get_address_family (address);
[7378]57 
[7389]58-       enet_free (host -> peers);
59-       enet_free (host);
60+    host -> socket4 = (family & ENET_IPV4) ?
61+      enet_socket_create_bind (address, ENET_IPV4) :
62+      ENET_SOCKET_NULL;
63+    host -> socket6 = (family & ENET_IPV6) ?
64+      enet_socket_create_bind (address, ENET_IPV6) :
65+      ENET_SOCKET_NULL;
66 
67-       return NULL;
68+    if (host -> socket4 == ENET_SOCKET_NULL && host -> socket6 == ENET_SOCKET_NULL)
69+    {
70+        enet_free (host -> peers);
71+        enet_free (host);
72+        return NULL;
[7378]73     }
74 
75-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
76-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
77-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
78-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
[7389]79-
[7378]80     if (address != NULL)
81       host -> address = * address;
[7389]82 
83@@ -133,7 +155,10 @@ enet_host_destroy (ENetHost * host)
[7378]84 {
85     ENetPeer * currentPeer;
86 
87-    enet_socket_destroy (host -> socket);
[7389]88+    if (host -> socket4 != ENET_SOCKET_NULL)
89+      enet_socket_destroy (host -> socket4);
90+    if (host -> socket6 != ENET_SOCKET_NULL)
91+      enet_socket_destroy (host -> socket6);
[7378]92 
93     for (currentPeer = host -> peers;
94          currentPeer < & host -> peers [host -> peerCount];
95diff --git a/include/enet/enet.h b/include/enet/enet.h
[7389]96index 7f5876f..616fe7f 100644
[7378]97--- a/include/enet/enet.h
98+++ b/include/enet/enet.h
99@@ -335,7 +335,8 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b
100   */
101 typedef struct _ENetHost
102 {
103-   ENetSocket           socket;
104+   ENetSocket           socket4;
105+   ENetSocket           socket6;
106    ENetAddress          address;                     /**< Internet address of the host */
107    enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
108    enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
109@@ -462,7 +463,7 @@ ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *, ENetAddressFa
110 ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *, ENetAddressFamily);
111 ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t, ENetAddressFamily);
112 ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t, ENetAddressFamily);
113-ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
114+ENET_API int        enet_socket_wait (ENetSocket, ENetSocket, enet_uint32 *, enet_uint32);
115 ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
116 ENET_API void       enet_socket_destroy (ENetSocket);
117 ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
118@@ -508,6 +509,12 @@ ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName
119 */
120 ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address);
121 
122+/** Returns the Address family of an (IPv4-mapped) IPv6 address.
123+    @param address IPv6 address
124+    @returns address family
125+*/
126+ENET_API ENetAddressFamily enet_get_address_family (const ENetAddress * address);
127+
128 /** @} */
129 
130 ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
131diff --git a/protocol.c b/protocol.c
[7389]132index 4c4850a..505c684 100644
[7378]133--- a/protocol.c
134+++ b/protocol.c
135@@ -37,6 +37,14 @@ enet_address_map4 (enet_uint32 address)
136     return addr;
137 }
138 
139+ENetAddressFamily
140+enet_get_address_family (const ENetAddress * address)
141+{
142+    if (!memcmp(& address->host, & ENET_IPV4MAPPED_PREFIX, ENET_IPV4MAPPED_PREFIX_LEN))
143+        return ENET_IPV4;
144+    return ENET_IPV6;
145+}
146+
147 size_t
148 enet_protocol_command_size (enet_uint8 commandNumber)
149 {
150@@ -1033,7 +1041,7 @@ commandError:
151 }
152 
153 static int
154-enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
155+enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event, ENetAddressFamily family)
156 {
157     for (;;)
158     {
159@@ -1043,11 +1051,11 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
160        buffer.data = host -> packetData [0];
161        buffer.dataLength = sizeof (host -> packetData [0]);
162 
163-       receivedLength = enet_socket_receive (host -> socket,
164+       receivedLength = enet_socket_receive (family == ENET_IPV4 ? host -> socket4 : host -> socket6,
165                                              & host -> receivedAddress,
166                                              & buffer,
167                                              1,
168-                                             ENET_IPV6);
169+                                             family);
170 
171        if (receivedLength < 0)
172          return -1;
173@@ -1055,6 +1063,9 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
174        if (receivedLength == 0)
175          return 0;
176 
177+       if (enet_get_address_family (& host -> receivedAddress) != family)
178+         return -1;
179+
180        host -> receivedData = host -> packetData [0];
181        host -> receivedDataLength = receivedLength;
182       
[7389]183@@ -1510,7 +1521,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
[7378]184 
185         currentPeer -> lastSendTime = host -> serviceTime;
186 
187-        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount, ENET_IPV6);
188+        ENetAddressFamily family = enet_get_address_family (& currentPeer -> address);
[7389]189+        ENetSocket socket = family == ENET_IPV4 ? host -> socket4 : host -> socket6;
190+        if (socket == ENET_SOCKET_NULL)
191+          return -1;
192+        sentLength = enet_socket_send (socket,
[7378]193+                                           & currentPeer -> address,
194+                                           host -> buffers,
195+                                           host -> bufferCount,
196+                                           family);
197 
198         enet_protocol_remove_sent_unreliable_commands (currentPeer);
199 
[7389]200@@ -1621,7 +1640,23 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
[7378]201           break;
202        }
203 
204-       switch (enet_protocol_receive_incoming_commands (host, event))
[7389]205+       if (host -> socket4 != ENET_SOCKET_NULL)
206+         switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV4))
[7378]207+       {
208+       case 1:
209+          return 1;
210+
211+       case -1:
212+          perror ("Error receiving incoming packets");
213+
214+          return -1;
215+
216+       default:
217+          break;
218+       }
219+
[7389]220+       if (host -> socket6 != ENET_SOCKET_NULL)
221+         switch (enet_protocol_receive_incoming_commands (host, event, ENET_IPV6))
[7378]222        {
223        case 1:
224           return 1;
[7389]225@@ -1673,7 +1708,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
[7378]226 
227        waitCondition = ENET_SOCKET_WAIT_RECEIVE;
228 
229-       if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
230+       if (enet_socket_wait (host -> socket4, host -> socket6, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
231          return -1;
232       
233        host -> serviceTime = enet_time_get ();
234diff --git a/unix.c b/unix.c
[7389]235index 13a24d8..22ffb76 100644
[7378]236--- a/unix.c
237+++ b/unix.c
238@@ -117,7 +117,9 @@ static int
239 enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
240 {
241     memset (sin, 0, enet_sa_size(family));
242-    if (family == ENET_IPV4)
243+    if (family == ENET_IPV4 &&
244+      (enet_get_address_family (address) == ENET_IPV4 ||
[7389]245+      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
[7378]246     {
247         ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
248         ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
249@@ -219,7 +221,7 @@ enet_socket_create (ENetSocketType type, ENetAddressFamily family)
250 #ifdef IPV6_V6ONLY
251     if (family == ENET_IPV6)
252     {
253-        int value = 0;
254+        int value = 1;
255         setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
256     }
257 #endif // IPV6_V6ONLY
[7389]258@@ -393,22 +395,38 @@ enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocket
[7378]259 }
260 
261 int
262-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
263+enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
264 {
265-#ifdef HAS_POLL
266-    struct pollfd pollSocket;
267+//#ifdef HAS_POLL
268+    struct pollfd pollSocket[2];
269     int pollCount;
[7389]270-   
[7378]271-    pollSocket.fd = socket;
272-    pollSocket.events = 0;
[7389]273+
[7378]274+    pollSocket[0].fd = socket4;
275+    pollSocket[1].fd = socket6;
276+    pollSocket[0].events = 0;
277+    pollSocket[1].events = 0;
[7389]278+    //pollSocket[0].revents = 0;
279+    pollSocket[1].revents = 0;
280+
281+    if (pollSocket[0].fd == ENET_SOCKET_NULL)
282+    {
283+        pollSocket[0].fd = pollSocket[1].fd;
284+        pollSocket[1].fd = ENET_SOCKET_NULL;
285+    }
[7378]286 
287     if (* condition & ENET_SOCKET_WAIT_SEND)
288-      pollSocket.events |= POLLOUT;
289+    {
290+        pollSocket[0].events |= POLLOUT;
291+        pollSocket[1].events |= POLLOUT;
292+    }
293 
294     if (* condition & ENET_SOCKET_WAIT_RECEIVE)
295-      pollSocket.events |= POLLIN;
296+    {
297+        pollSocket[0].events |= POLLIN;
298+        pollSocket[1].events |= POLLIN;
299+    }
300 
301-    pollCount = poll (& pollSocket, 1, timeout);
[7389]302+    pollCount = poll (pollSocket, pollSocket[1].fd != ENET_SOCKET_NULL ? 2 : 1, timeout);
[7378]303 
304     if (pollCount < 0)
305       return -1;
[7389]306@@ -418,13 +436,15 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
[7378]307     if (pollCount == 0)
308       return 0;
309 
310-    if (pollSocket.revents & POLLOUT)
311+    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLOUT)
312       * condition |= ENET_SOCKET_WAIT_SEND;
313     
314-    if (pollSocket.revents & POLLIN)
315+    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLIN)
316       * condition |= ENET_SOCKET_WAIT_RECEIVE;
317 
318     return 0;
319+/*
[7389]320+FIXME: implement or remove this
[7378]321 #else
322     fd_set readSet, writeSet;
323     struct timeval timeVal;
[7389]324@@ -460,6 +480,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
[7378]325 
326     return 0;
327 #endif
328+*/
329 }
330 
331 #endif
332--
3331.7.1
334
Note: See TracBrowser for help on using the repository browser.