source:
code/branches/ipv6/src/external/enet/patches/0002-basic-IPv6-support-on-Linux-systems.patch
@
7382
Last change on this file since 7382 was 7378, checked in by adrfried, 14 years ago | |
---|---|
File size: 13.2 KB |
-
include/enet/enet.h
From fc72c66f6b8a6b1d924ffa86861ce00a1c591839 Mon Sep 17 00:00:00 2001 From: Adrian Friedli <adi@koalatux.ch> Date: Thu, 2 Sep 2010 14:27:07 +0200 Subject: [PATCH 2/4] basic IPv6 support on Linux systems this uses IPv4-mapped IPv6 addresses --- include/enet/enet.h | 22 ++++++-- protocol.c | 26 +++++++--- unix.c | 134 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 114 insertions(+), 68 deletions(-) diff --git a/include/enet/enet.h b/include/enet/enet.h index 2f656d6..d3ca971 100644
a b typedef enum _ENetSocketOption 53 53 ENET_SOCKOPT_REUSEADDR = 5 54 54 } ENetSocketOption; 55 55 56 enum 56 typedef struct _ENetHostAddress 57 57 { 58 ENET_HOST_ANY = 0, /**< specifies the default server host */59 ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */ 58 enet_uint8 addr[16]; 59 } ENetHostAddress; 60 60 61 ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */ 62 }; 61 extern const ENetHostAddress ENET_HOST_ANY; /**< specifies the default server host */ 62 extern const ENetHostAddress ENET_IPV4MAPPED_PREFIX; /**< specifies the IPv4-mapped IPv6 prefix */ 63 extern const ENetHostAddress ENET_HOST_BROADCAST; /**< specifies a IPv4 subnet-wide broadcast */ 64 #define ENET_IPV4MAPPED_PREFIX_LEN 12 /**< specifies the length of the IPv4-mapped IPv6 prefix */ 65 #define ENET_PORT_ANY 0 /**< specifies that a port should be automatically chosen */ 63 66 64 67 /** 65 68 * Portable internet address structure. … … enum 73 76 */ 74 77 typedef struct _ENetAddress 75 78 { 76 enet_uint32 host; 79 ENetHostAddress host; 80 enet_uint32 scopeID; //FIXME: this is of different size on Windows 77 81 enet_uint16 port; 78 82 } ENetAddress; 79 83 … … ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN 488 492 */ 489 493 ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength); 490 494 495 /** Maps an IPv4 Address to an IPv6 address. 496 @param address IPv4 address in network byte order 497 @returns the IPv4-mapped IPv6 address in network byte order 498 */ 499 ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address); 500 491 501 /** @} */ 492 502 493 503 ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32); -
protocol.c
diff --git a/protocol.c b/protocol.c index 8e26dfb..930835e 100644
a b 9 9 #include "enet/time.h" 10 10 #include "enet/enet.h" 11 11 12 const ENetHostAddress ENET_HOST_ANY = { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }; 13 const ENetHostAddress ENET_IPV4MAPPED_PREFIX = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0,0,0,0 } }; 14 const ENetHostAddress ENET_HOST_BROADCAST = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; 15 12 16 static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = 13 17 { 14 18 0, … … static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = 25 29 sizeof (ENetProtocolThrottleConfigure), 26 30 }; 27 31 32 ENetHostAddress 33 enet_address_map4 (enet_uint32 address) 34 { 35 ENetHostAddress addr = ENET_IPV4MAPPED_PREFIX; 36 ((enet_uint32 *)addr.addr)[3] = address; 37 return addr; 38 } 39 28 40 size_t 29 41 enet_protocol_command_size (enet_uint8 commandNumber) 30 42 { … … enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet 262 274 ++ currentPeer) 263 275 { 264 276 if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && 265 currentPeer -> address.host == host -> receivedAddress.host &&266 277 currentPeer -> address.port == host -> receivedAddress.port && 267 currentPeer -> connectID == command -> connect.connectID) 278 currentPeer -> connectID == command -> connect.connectID && 279 !memcmp(& currentPeer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress))) 268 280 return NULL; 269 281 } 270 282 … … enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 848 860 849 861 if (peer -> state == ENET_PEER_STATE_DISCONNECTED || 850 862 peer -> state == ENET_PEER_STATE_ZOMBIE || 851 (host -> receivedAddress.host != peer -> address.host &&852 peer -> address.host != ENET_HOST_BROADCAST) ||853 863 (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && 854 sessionID != peer -> incomingSessionID)) 864 sessionID != peer -> incomingSessionID) || 865 ( memcmp(& peer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)) && 866 memcmp(& peer -> address.host, & ENET_HOST_BROADCAST, sizeof (ENetHostAddress)) && 867 peer -> address.host.addr[0] != 0xff ) ) 855 868 return 0; 856 869 } 857 870 … … enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 891 904 892 905 if (peer != NULL) 893 906 { 894 peer -> address.host = host -> receivedAddress.host; 895 peer -> address.port = host -> receivedAddress.port; 907 peer -> address = host -> receivedAddress; 896 908 peer -> incomingDataTotal += host -> receivedDataLength; 897 909 } 898 910 -
unix.c
diff --git a/unix.c b/unix.c index 7329e8d..de032bb 100644
a b enet_time_set (enet_uint32 newTimeBase) 71 71 timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; 72 72 } 73 73 74 static int 75 enet_address_set_address (ENetAddress * address, const struct sockaddr * sin) 76 { 77 memset (address, 0, sizeof (ENetAddress)); 78 if (sin -> sa_family == AF_INET) 79 { 80 address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr)); 81 //address -> scopeID = 0; 82 address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port); 83 return 0; 84 } 85 if (sin -> sa_family == AF_INET6) 86 { 87 address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr; 88 address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id; 89 address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port); 90 return 0; 91 } 92 return -1; 93 } 94 95 static int 96 enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, sa_family_t family) 97 { 98 if (family == AF_INET) 99 { 100 memset (sin, 0, sizeof (struct sockaddr_in)); 101 ((struct sockaddr_in *) sin) -> sin_family = AF_INET; 102 ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12]; 103 ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port); 104 return 0; 105 } 106 else if (family == AF_INET6) 107 { 108 memset (sin, 0, sizeof (struct sockaddr_in6)); 109 ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6; 110 ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host; 111 ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID; 112 ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port); 113 return 0; 114 } 115 return -1; 116 } 117 74 118 int 75 119 enet_address_set_host (ENetAddress * address, const char * name) 76 120 { 121 enet_uint16 port = address -> port; 77 122 struct addrinfo hints; 78 123 struct addrinfo * result; 79 124 struct addrinfo * res; 80 125 81 126 memset(& hints, 0, sizeof (hints)); 82 hints.ai_flags = AI_NUMERICSERV ;83 hints.ai_family = AF_ INET;127 hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG; 128 hints.ai_family = AF_UNSPEC; 84 129 85 130 if ( getaddrinfo(name, NULL, &hints, &result) ) 86 {87 131 return -1; 88 }89 132 90 133 for (res = result; res != NULL; res = res -> ai_next) 91 134 { 92 if (res -> ai_family == AF_INET) 93 { 94 address -> host = ((struct sockaddr_in *) res -> ai_addr ) -> sin_addr.s_addr; 135 if ( !enet_address_set_address(address, res -> ai_addr) ) 95 136 break; 96 }97 137 } 138 139 address -> port = port; 98 140 freeaddrinfo(result); 99 141 if (res == NULL) return -1; 100 142 … … enet_address_set_host (ENetAddress * address, const char * name) 104 146 static int 105 147 enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags) 106 148 { 107 struct sockaddr_in sin; 108 109 memset (& sin, 0, sizeof (struct sockaddr_in)); 149 struct sockaddr_storage sin; 150 enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6); 110 151 111 sin.sin_family = AF_INET; 112 sin.sin_addr = * (struct in_addr *) & address -> host; 113 114 if ( getnameinfo((struct sockaddr *) & sin, sizeof(sin), name, nameLength, NULL, 0, flags)) 115 { 152 if ( getnameinfo((struct sockaddr *) & sin, sizeof(struct sockaddr_in6), name, nameLength, NULL, 0, flags)) 116 153 return -1; 117 }118 154 119 155 return 0; 120 156 } … … enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng 134 170 int 135 171 enet_socket_bind (ENetSocket socket, const ENetAddress * address) 136 172 { 137 struct sockaddr_in sin; 138 139 memset (& sin, 0, sizeof (struct sockaddr_in)); 140 141 sin.sin_family = AF_INET; 173 struct sockaddr_storage sin; 142 174 143 175 if (address != NULL) 144 176 { 145 sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 146 sin.sin_addr.s_addr = address -> host; 177 enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6); 147 178 } 148 179 else 149 180 { 150 sin.sin_port = 0;151 sin.sin_addr.s_addr = INADDR_ANY;181 ENetAddress address_ = { ENET_HOST_ANY, 0, 0 }; 182 enet_address_set_sin((struct sockaddr *) & sin, & address_, AF_INET6); 152 183 } 153 184 154 return bind (socket, 155 (struct sockaddr *) & sin, 156 sizeof (struct sockaddr_in)); 185 return bind (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in6)); 157 186 } 158 187 159 int 188 int 160 189 enet_socket_listen (ENetSocket socket, int backlog) 161 190 { 162 191 return listen (socket, backlog < 0 ? SOMAXCONN : backlog); … … enet_socket_listen (ENetSocket socket, int backlog) 165 194 ENetSocket 166 195 enet_socket_create (ENetSocketType type) 167 196 { 168 return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); 197 ENetSocket sock = socket (AF_INET6, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); 198 199 #ifdef IPV6_V6ONLY 200 int value = 0; 201 setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int)); 202 #endif // IPV6_V6ONLY 203 204 return sock; 169 205 } 170 206 171 207 int … … enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) 207 243 int 208 244 enet_socket_connect (ENetSocket socket, const ENetAddress * address) 209 245 { 210 struct sockaddr_in sin; 246 struct sockaddr_storage sin; 247 enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6); 211 248 212 memset (& sin, 0, sizeof (struct sockaddr_in)); 213 214 sin.sin_family = AF_INET; 215 sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 216 sin.sin_addr.s_addr = address -> host; 217 218 return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); 249 return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in6)); 219 250 } 220 251 221 252 ENetSocket 222 253 enet_socket_accept (ENetSocket socket, ENetAddress * address) 223 254 { 224 255 int result; 225 struct sockaddr_ insin;226 socklen_t sinLength = sizeof (struct sockaddr_in );256 struct sockaddr_storage sin; 257 socklen_t sinLength = sizeof (struct sockaddr_in6); 227 258 228 259 result = accept (socket, 229 260 address != NULL ? (struct sockaddr *) & sin : NULL, … … enet_socket_accept (ENetSocket socket, ENetAddress * address) 234 265 235 266 if (address != NULL) 236 267 { 237 address -> host = (enet_uint32) sin.sin_addr.s_addr; 238 address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); 268 enet_address_set_address(address, (struct sockaddr *) & sin); 239 269 } 240 270 241 271 return result; … … enet_socket_send (ENetSocket socket, 254 284 size_t bufferCount) 255 285 { 256 286 struct msghdr msgHdr; 257 struct sockaddr_ insin;287 struct sockaddr_storage sin; 258 288 int sentLength; 259 289 260 290 memset (& msgHdr, 0, sizeof (struct msghdr)); 261 291 262 292 if (address != NULL) 263 293 { 264 memset (& sin, 0, sizeof (struct sockaddr_in)); 265 266 sin.sin_family = AF_INET; 267 sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 268 sin.sin_addr.s_addr = address -> host; 269 294 enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6); 270 295 msgHdr.msg_name = & sin; 271 msgHdr.msg_namelen = sizeof (struct sockaddr_in );296 msgHdr.msg_namelen = sizeof (struct sockaddr_in6); 272 297 } 273 298 274 299 msgHdr.msg_iov = (struct iovec *) buffers; … … enet_socket_receive (ENetSocket socket, 294 319 size_t bufferCount) 295 320 { 296 321 struct msghdr msgHdr; 297 struct sockaddr_ insin;322 struct sockaddr_storage sin; 298 323 int recvLength; 299 324 300 325 memset (& msgHdr, 0, sizeof (struct msghdr)); … … enet_socket_receive (ENetSocket socket, 302 327 if (address != NULL) 303 328 { 304 329 msgHdr.msg_name = & sin; 305 msgHdr.msg_namelen = sizeof (struct sockaddr_in );330 msgHdr.msg_namelen = sizeof (struct sockaddr_in6); 306 331 } 307 332 308 333 msgHdr.msg_iov = (struct iovec *) buffers; … … enet_socket_receive (ENetSocket socket, 325 350 326 351 if (address != NULL) 327 352 { 328 address -> host = (enet_uint32) sin.sin_addr.s_addr; 329 address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); 353 enet_address_set_address(address, (struct sockaddr *) & sin); 330 354 } 331 355 332 356 return recvLength;
Note: See TracBrowser
for help on using the repository browser.