Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

IPv6 for Windows

I have not tested this, please test this and report issues to me.

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/5] 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 
    5353   ENET_SOCKOPT_REUSEADDR = 5
    5454} ENetSocketOption;
    5555
    56 enum
     56typedef struct _ENetHostAddress
    5757{
    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;
    6060
    61    ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
    62 };
     61extern const ENetHostAddress ENET_HOST_ANY;          /**< specifies the default server host */
     62extern const ENetHostAddress ENET_IPV4MAPPED_PREFIX; /**< specifies the IPv4-mapped IPv6 prefix */
     63extern 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 */
    6366
    6467/**
    6568 * Portable internet address structure.
    enum 
    7376 */
    7477typedef struct _ENetAddress
    7578{
    76    enet_uint32 host;
     79   ENetHostAddress host;
     80   enet_uint32 scopeID; //FIXME: this is of different size on Windows
    7781   enet_uint16 port;
    7882} ENetAddress;
    7983
    ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN 
    488492*/
    489493ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
    490494
     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*/
     499ENET_API ENetHostAddress enet_address_map4 (enet_uint32 address);
     500
    491501/** @} */
    492502
    493503ENET_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  
    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_IPV4MAPPED_PREFIX = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0,0,0,0 } };
     14const ENetHostAddress ENET_HOST_BROADCAST = { { 0,0,0,0,0,0,0,0,0,0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
     15
    1216static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
    1317{
    1418    0,
    static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = 
    2529    sizeof (ENetProtocolThrottleConfigure),
    2630};
    2731
     32ENetHostAddress
     33enet_address_map4 (enet_uint32 address)
     34{
     35    ENetHostAddress addr = ENET_IPV4MAPPED_PREFIX;
     36    ((enet_uint32 *)addr.addr)[3] = address;
     37    return addr;
     38}
     39
    2840size_t
    2941enet_protocol_command_size (enet_uint8 commandNumber)
    3042{
    enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet 
    262274         ++ currentPeer)
    263275    {
    264276        if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
    265             currentPeer -> address.host == host -> receivedAddress.host &&
    266277            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)))
    268280          return NULL;
    269281    }
    270282
    enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 
    848860
    849861       if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
    850862           peer -> state == ENET_PEER_STATE_ZOMBIE ||
    851            (host -> receivedAddress.host != peer -> address.host &&
    852              peer -> address.host != ENET_HOST_BROADCAST) ||
    853863           (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 ) )
    855868         return 0;
    856869    }
    857870 
    enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 
    891904       
    892905    if (peer != NULL)
    893906    {
    894        peer -> address.host = host -> receivedAddress.host;
    895        peer -> address.port = host -> receivedAddress.port;
     907       peer -> address = host -> receivedAddress;
    896908       peer -> incomingDataTotal += host -> receivedDataLength;
    897909    }
    898910   
  • unix.c

    diff --git a/unix.c b/unix.c
    index 7329e8d..de032bb 100644
    a b enet_time_set (enet_uint32 newTimeBase) 
    7171    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
    7272}
    7373
     74static int
     75enet_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
     95static int
     96enet_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
    74118int
    75119enet_address_set_host (ENetAddress * address, const char * name)
    76120{
     121    enet_uint16 port = address -> port;
    77122    struct addrinfo hints;
    78123    struct addrinfo * result;
    79124    struct addrinfo * res;
    80125
    81126    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;
    84129
    85130    if ( getaddrinfo(name, NULL, &hints, &result) )
    86     {
    87131        return -1;
    88     }
    89132
    90133    for (res = result; res != NULL; res = res -> ai_next)
    91134    {
    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) )
    95136            break;
    96         }
    97137    }
     138
     139    address -> port = port;
    98140    freeaddrinfo(result);
    99141    if (res == NULL) return -1;
    100142
    enet_address_set_host (ENetAddress * address, const char * name) 
    104146static int
    105147enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
    106148{
    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);
    110151
    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))
    116153        return -1;
    117     }
    118154
    119155    return 0;
    120156}
    enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng 
    134170int
    135171enet_socket_bind (ENetSocket socket, const ENetAddress * address)
    136172{
    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;
    142174
    143175    if (address != NULL)
    144176    {
    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);
    147178    }
    148179    else
    149180    {
    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);
    152183    }
    153184
    154     return bind (socket,
    155                  (struct sockaddr *) & sin,
    156                  sizeof (struct sockaddr_in));
     185    return bind (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in6));
    157186}
    158187
    159 int 
     188int
    160189enet_socket_listen (ENetSocket socket, int backlog)
    161190{
    162191    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
    enet_socket_listen (ENetSocket socket, int backlog) 
    165194ENetSocket
    166195enet_socket_create (ENetSocketType type)
    167196{
    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;
    169205}
    170206
    171207int
    enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) 
    207243int
    208244enet_socket_connect (ENetSocket socket, const ENetAddress * address)
    209245{
    210     struct sockaddr_in sin;
     246    struct sockaddr_storage sin;
     247    enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6);
    211248
    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));
    219250}
    220251
    221252ENetSocket
    222253enet_socket_accept (ENetSocket socket, ENetAddress * address)
    223254{
    224255    int result;
    225     struct sockaddr_in sin;
    226     socklen_t sinLength = sizeof (struct sockaddr_in);
     256    struct sockaddr_storage sin;
     257    socklen_t sinLength = sizeof (struct sockaddr_in6);
    227258
    228259    result = accept (socket,
    229260                     address != NULL ? (struct sockaddr *) & sin : NULL,
    enet_socket_accept (ENetSocket socket, ENetAddress * address) 
    234265
    235266    if (address != NULL)
    236267    {
    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);
    239269    }
    240270
    241271    return result;
    enet_socket_send (ENetSocket socket, 
    254284                  size_t bufferCount)
    255285{
    256286    struct msghdr msgHdr;
    257     struct sockaddr_in sin;
     287    struct sockaddr_storage sin;
    258288    int sentLength;
    259289
    260290    memset (& msgHdr, 0, sizeof (struct msghdr));
    261291
    262292    if (address != NULL)
    263293    {
    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);
    270295        msgHdr.msg_name = & sin;
    271         msgHdr.msg_namelen = sizeof (struct sockaddr_in);
     296        msgHdr.msg_namelen = sizeof (struct sockaddr_in6);
    272297    }
    273298
    274299    msgHdr.msg_iov = (struct iovec *) buffers;
    enet_socket_receive (ENetSocket socket, 
    294319                     size_t bufferCount)
    295320{
    296321    struct msghdr msgHdr;
    297     struct sockaddr_in sin;
     322    struct sockaddr_storage sin;
    298323    int recvLength;
    299324
    300325    memset (& msgHdr, 0, sizeof (struct msghdr));
    enet_socket_receive (ENetSocket socket, 
    302327    if (address != NULL)
    303328    {
    304329        msgHdr.msg_name = & sin;
    305         msgHdr.msg_namelen = sizeof (struct sockaddr_in);
     330        msgHdr.msg_namelen = sizeof (struct sockaddr_in6);
    306331    }
    307332
    308333    msgHdr.msg_iov = (struct iovec *) buffers;
    enet_socket_receive (ENetSocket socket, 
    325350
    326351    if (address != NULL)
    327352    {
    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);
    330354    }
    331355
    332356    return recvLength;
Note: See TracBrowser for help on using the repository browser.