Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7382 was 7378, checked in by adrfried, 14 years ago

split libenet patch into smaller ones

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