Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ipv6/src/external/enet/patches/0002-basic-IPv6-support-on-Linux-systems.patch @ 7330

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

patch libenet to support ipv6

This is only done for Linux so far.

File size: 12.5 KB
  • host.c

    From 85c3be6ab21fd875baa57ea119ed58d5c54f0115 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/2] basic IPv6 support on Linux systems
    
    ---
     host.c              |    2 +
     include/enet/enet.h |   29 ++++++++++++----
     protocol.c          |   17 ++++++----
     unix.c              |   90 ++++++++++++++++++++++++++++++--------------------
     4 files changed, 88 insertions(+), 50 deletions(-)
    
    diff --git a/host.c b/host.c
    index 8bb2433..5a18a59 100644
    a b enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL 
    4949    memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
    5050
    5151    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
     52    enet_socket_set_option (host -> socket, ENET_SOCKOPT_V6ONLY, 0); // Needs to be set before bind.
     53
    5254    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
    5355    {
    5456       if (host -> socket != ENET_SOCKET_NULL)
  • include/enet/enet.h

    diff --git a/include/enet/enet.h b/include/enet/enet.h
    index 2f656d6..a9f0759 100644
    a b typedef enum _ENetSocketOption 
    5050   ENET_SOCKOPT_BROADCAST = 2,
    5151   ENET_SOCKOPT_RCVBUF    = 3,
    5252   ENET_SOCKOPT_SNDBUF    = 4,
    53    ENET_SOCKOPT_REUSEADDR = 5
     53   ENET_SOCKOPT_REUSEADDR = 5,
     54   ENET_SOCKOPT_V6ONLY = 6
    5455} ENetSocketOption;
    5556
    56 enum
     57typedef struct _ENetHostAddress
    5758{
    58    ENET_HOST_ANY       = 0,            /**< specifies the default server host */
    59    ENET_HOST_BROADCAST = 0xFFFFFFFF,   /**< specifies a subnet-wide broadcast */
     59   enet_uint8 addr[16];
     60} ENetHostAddress;
    6061
    61    ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
    62 };
     62extern const ENetHostAddress ENET_HOST_ANY;       /**< specifies the default server host */
     63extern const ENetHostAddress ENET_HOST_BROADCAST; /**< specifies a IPv4 subnet-wide broadcast */
     64#define ENET_PORT_ANY 0                           /**< specifies that a port should be automatically chosen */
    6365
    6466/**
    6567 * Portable internet address structure.
    enum 
    7375 */
    7476typedef struct _ENetAddress
    7577{
    76    enet_uint32 host;
     78   ENetHostAddress host;
     79   enet_uint32 scopeID; //FIXME: this is of different size on Windows
    7780   enet_uint16 port;
    7881} ENetAddress;
    7982
    ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN 
    488491*/
    489492ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
    490493
     494/** Maps an IPv4 Address to an IPv6 address.
     495    @param address IPv4 address in network byte order
     496    @returns the IPv4-mapped IPv6 address in network byte order
     497*/
     498static inline ENetHostAddress enet_address_map4 (enet_uint32 address)
     499{
     500   ENetHostAddress addr = ENET_HOST_ANY;
     501   ((enet_uint16 *)addr.addr)[5] = 0xffff;
     502   ((enet_uint32 *)addr.addr)[3] = address;
     503   return addr;
     504}
     505
    491506/** @} */
    492507
    493508ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
  • protocol.c

    diff --git a/protocol.c b/protocol.c
    index 8e26dfb..318a2c7 100644
    a b  
    99#include "enet/time.h"
    1010#include "enet/enet.h"
    1111
     12const ENetHostAddress ENET_HOST_ANY = { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } };
     13const ENetHostAddress ENET_HOST_BROADCAST = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
     14
    1215static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
    1316{
    1417    0,
    enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet 
    262265         ++ currentPeer)
    263266    {
    264267        if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
    265             currentPeer -> address.host == host -> receivedAddress.host &&
    266268            currentPeer -> address.port == host -> receivedAddress.port &&
    267             currentPeer -> connectID == command -> connect.connectID)
     269            currentPeer -> connectID == command -> connect.connectID &&
     270            !memcmp(& currentPeer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)))
    268271          return NULL;
    269272    }
    270273
    enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 
    848851
    849852       if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
    850853           peer -> state == ENET_PEER_STATE_ZOMBIE ||
    851            (host -> receivedAddress.host != peer -> address.host &&
    852              peer -> address.host != ENET_HOST_BROADCAST) ||
    853854           (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
    854             sessionID != peer -> incomingSessionID))
     855            sessionID != peer -> incomingSessionID) ||
     856           ( memcmp(& peer -> address.host, & host -> receivedAddress.host, sizeof (ENetHostAddress)) &&
     857             memcmp(& peer -> address.host, & ENET_HOST_BROADCAST, sizeof (ENetHostAddress)) &&
     858             peer -> address.host.addr[0] != 0xff ) )
    855859         return 0;
    856860    }
    857861 
    enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 
    891895       
    892896    if (peer != NULL)
    893897    {
    894        peer -> address.host = host -> receivedAddress.host;
    895        peer -> address.port = host -> receivedAddress.port;
     898       peer -> address = host -> receivedAddress;
    896899       peer -> incomingDataTotal += host -> receivedDataLength;
    897900    }
    898901   
  • unix.c

    diff --git a/unix.c b/unix.c
    index 7329e8d..49fbace 100644
    a b enet_address_set_host (ENetAddress * address, const char * name) 
    7979    struct addrinfo * res;
    8080
    8181    memset(& hints, 0, sizeof (hints));
    82     hints.ai_flags = AI_NUMERICSERV;
    83     hints.ai_family = AF_INET;
     82    hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
     83    hints.ai_family = AF_UNSPEC;
    8484
    8585    if ( getaddrinfo(name, NULL, &hints, &result) )
    8686    {
    enet_address_set_host (ENetAddress * address, const char * name) 
    9191    {
    9292        if (res -> ai_family == AF_INET)
    9393        {
    94             address -> host = ((struct sockaddr_in *) res -> ai_addr ) -> sin_addr.s_addr;
     94            address -> host = enet_address_map4( ((struct sockaddr_in *) res -> ai_addr ) -> sin_addr.s_addr );
     95            address -> scopeID = 0;
     96            break;
     97        }
     98        if (res -> ai_family == AF_INET6)
     99        {
     100            address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) res -> ai_addr ) -> sin6_addr;
     101            address -> scopeID = ((struct sockaddr_in6 *) res -> ai_addr ) -> sin6_scope_id;
    95102            break;
    96103        }
    97104    }
    enet_address_set_host (ENetAddress * address, const char * name) 
    104111static int
    105112enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
    106113{
    107     struct sockaddr_in sin;
     114    struct sockaddr_in6 sin;
    108115
    109     memset (& sin, 0, sizeof (struct sockaddr_in));
     116    memset (& sin, 0, sizeof (struct sockaddr_in6));
    110117
    111     sin.sin_family = AF_INET;
    112     sin.sin_addr = * (struct in_addr *) & address -> host;
     118    sin.sin6_family = AF_INET6;
     119    sin.sin6_addr = * (struct in6_addr *) & address -> host;
     120    sin.sin6_scope_id = address -> scopeID;
    113121
    114122    if ( getnameinfo((struct sockaddr *) & sin, sizeof(sin), name, nameLength, NULL, 0, flags))
    115123    {
    enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng 
    134142int
    135143enet_socket_bind (ENetSocket socket, const ENetAddress * address)
    136144{
    137     struct sockaddr_in sin;
     145    struct sockaddr_in6 sin;
    138146
    139     memset (& sin, 0, sizeof (struct sockaddr_in));
     147    memset (& sin, 0, sizeof (struct sockaddr_in6));
    140148
    141     sin.sin_family = AF_INET;
     149    sin.sin6_family = AF_INET6;
    142150
    143151    if (address != NULL)
    144152    {
    145        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
    146        sin.sin_addr.s_addr = address -> host;
     153       sin.sin6_port = ENET_HOST_TO_NET_16 (address -> port);
     154       sin.sin6_addr = * (struct in6_addr *) & address -> host;
     155       sin.sin6_scope_id = address -> scopeID;
    147156    }
    148157    else
    149158    {
    150        sin.sin_port = 0;
    151        sin.sin_addr.s_addr = INADDR_ANY;
     159       sin.sin6_port = 0;
     160       sin.sin6_addr = in6addr_any;
     161       sin.sin6_scope_id = 0;
    152162    }
    153163
    154164    return bind (socket,
    155165                 (struct sockaddr *) & sin,
    156                  sizeof (struct sockaddr_in));
     166                 sizeof (struct sockaddr_in6));
    157167}
    158168
    159169int
    enet_socket_listen (ENetSocket socket, int backlog) 
    165175ENetSocket
    166176enet_socket_create (ENetSocketType type)
    167177{
    168     return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
     178    return socket (AF_INET6, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
    169179}
    170180
    171181int
    enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) 
    198208            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
    199209            break;
    200210
     211        case ENET_SOCKOPT_V6ONLY:
     212            result = setsockopt (socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *) & value, sizeof (int));
     213            break;
     214
    201215        default:
    202216            break;
    203217    }
    enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) 
    207221int
    208222enet_socket_connect (ENetSocket socket, const ENetAddress * address)
    209223{
    210     struct sockaddr_in sin;
     224    struct sockaddr_in6 sin;
    211225
    212     memset (& sin, 0, sizeof (struct sockaddr_in));
     226    memset (& sin, 0, sizeof (struct sockaddr_in6));
    213227
    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;
     228    sin.sin6_family = AF_INET6;
     229    sin.sin6_port = ENET_HOST_TO_NET_16 (address -> port);
     230    sin.sin6_addr = * (struct in6_addr *) & address -> host;
     231    sin.sin6_scope_id = address -> scopeID;
    217232
    218     return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
     233    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in6));
    219234}
    220235
    221236ENetSocket
    222237enet_socket_accept (ENetSocket socket, ENetAddress * address)
    223238{
    224239    int result;
    225     struct sockaddr_in sin;
    226     socklen_t sinLength = sizeof (struct sockaddr_in);
     240    struct sockaddr_in6 sin;
     241    socklen_t sinLength = sizeof (struct sockaddr_in6);
    227242
    228243    result = accept (socket,
    229244                     address != NULL ? (struct sockaddr *) & sin : NULL,
    enet_socket_accept (ENetSocket socket, ENetAddress * address) 
    234249
    235250    if (address != NULL)
    236251    {
    237         address -> host = (enet_uint32) sin.sin_addr.s_addr;
    238         address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
     252        address -> host = * (ENetHostAddress *) & sin.sin6_addr;
     253        address -> scopeID = sin.sin6_scope_id;
     254        address -> port = ENET_NET_TO_HOST_16 (sin.sin6_port);
    239255    }
    240256
    241257    return result;
    enet_socket_send (ENetSocket socket, 
    254270                  size_t bufferCount)
    255271{
    256272    struct msghdr msgHdr;
    257     struct sockaddr_in sin;
     273    struct sockaddr_in6 sin;
    258274    int sentLength;
    259275
    260276    memset (& msgHdr, 0, sizeof (struct msghdr));
    261277
    262278    if (address != NULL)
    263279    {
    264         memset (& sin, 0, sizeof (struct sockaddr_in));
     280        memset (& sin, 0, sizeof (struct sockaddr_in6));
    265281
    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;
     282        sin.sin6_family = AF_INET6;
     283        sin.sin6_port = ENET_HOST_TO_NET_16 (address -> port);
     284        sin.sin6_addr = * (struct in6_addr *) & address -> host;
     285        sin.sin6_scope_id = address -> scopeID;
    269286
    270287        msgHdr.msg_name = & sin;
    271         msgHdr.msg_namelen = sizeof (struct sockaddr_in);
     288        msgHdr.msg_namelen = sizeof (struct sockaddr_in6);
    272289    }
    273290
    274291    msgHdr.msg_iov = (struct iovec *) buffers;
    enet_socket_receive (ENetSocket socket, 
    294311                     size_t bufferCount)
    295312{
    296313    struct msghdr msgHdr;
    297     struct sockaddr_in sin;
     314    struct sockaddr_in6 sin;
    298315    int recvLength;
    299316
    300317    memset (& msgHdr, 0, sizeof (struct msghdr));
    enet_socket_receive (ENetSocket socket, 
    302319    if (address != NULL)
    303320    {
    304321        msgHdr.msg_name = & sin;
    305         msgHdr.msg_namelen = sizeof (struct sockaddr_in);
     322        msgHdr.msg_namelen = sizeof (struct sockaddr_in6);
    306323    }
    307324
    308325    msgHdr.msg_iov = (struct iovec *) buffers;
    enet_socket_receive (ENetSocket socket, 
    325342
    326343    if (address != NULL)
    327344    {
    328         address -> host = (enet_uint32) sin.sin_addr.s_addr;
    329         address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
     345        address -> host = * (ENetHostAddress *) & sin.sin6_addr;
     346        address -> scopeID = sin.sin6_scope_id;
     347        address -> port = ENET_NET_TO_HOST_16 (sin.sin6_port);
    330348    }
    331349
    332350    return recvLength;
Note: See TracBrowser for help on using the repository browser.