Ignore:
Timestamp:
Dec 15, 2008, 12:17:08 AM (12 years ago)
Author:
charles
Message:

(trunk libT) add ipv6 support by jhujhiti. I think this is the largest user-contributed patch we've ever used... thanks jhujhiti :)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/net.c

    r7232 r7397  
    2727#include <stdlib.h>
    2828#include <string.h>
     29#include <assert.h>
    2930
    3031#include <sys/types.h>
     
    108109    dst->type = TR_AF_INET6;
    109110    return dst;
    110 }
     111}
     112
     113void
     114tr_normalizeV4Mapped( tr_address * const addr )
     115{
     116    if( addr->type == TR_AF_INET6 && IN6_IS_ADDR_V4MAPPED( &addr->addr.addr6 ) )
     117    {
     118        addr->type = TR_AF_INET;
     119        memcpy( &addr->addr.addr4.s_addr, addr->addr.addr6.s6_addr + 12, 4 );
     120    }
     121}
    111122
    112123/*
     
    141152
    142153/***********************************************************************
     154 * Socket list housekeeping
     155 **********************************************************************/
     156struct tr_socketList
     157{
     158    int             socket;
     159    tr_address      addr;
     160    tr_socketList * next;
     161};
     162
     163tr_socketList *
     164tr_socketListAppend( tr_socketList * const head,
     165                     const tr_address * const addr )
     166{
     167    tr_socketList * tmp;
     168    assert( head );
     169    for( tmp = head; tmp->next; tmp = tmp->next );
     170    tmp->next = tr_socketListNew( addr );
     171    return tmp->next;
     172}
     173
     174tr_socketList *
     175tr_socketListNew( const tr_address * const addr )
     176{
     177    tr_socketList * tmp;
     178    tmp = tr_new( tr_socketList, 1 );
     179    tmp->socket = -1;
     180    tmp->addr = *addr;
     181    tmp->next = NULL;
     182    return tmp;
     183}
     184
     185void
     186tr_socketListFree( tr_socketList * const head )
     187{
     188    assert( head );
     189    if( head->next )
     190        tr_socketListFree( head->next );
     191    tr_free( head );
     192}
     193
     194void
     195tr_socketListRemove( tr_socketList * const head,
     196                     tr_socketList * const el)
     197{
     198    tr_socketList * tmp;
     199    assert( head );
     200    assert( el );
     201    for( tmp = head; tmp->next && tmp->next != el; tmp = tmp->next );
     202    tmp->next = el->next;
     203    el->next = NULL;
     204    tr_socketListFree(el);
     205}
     206
     207void
     208tr_socketListTruncate( tr_socketList * const head,
     209                       tr_socketList * const start )
     210{
     211    tr_socketList * tmp;
     212    assert( head );
     213    assert( start );
     214    for( tmp = head; tmp->next && tmp->next != start; tmp = tmp->next );
     215    tr_socketListFree( start );
     216    tmp->next = NULL;
     217}
     218
     219int
     220tr_socketListGetSocket( const tr_socketList * const el )
     221{
     222    assert( el );
     223    return el->socket;
     224}
     225
     226const tr_address *
     227tr_socketListGetAddress( const tr_socketList * const el )
     228{
     229    assert( el );
     230    return &el->addr;
     231}
     232
     233void
     234tr_socketListForEach( tr_socketList * const head,
     235                      void ( * cb ) ( int * const,
     236                                      tr_address * const,
     237                                      void * const),
     238                      void * const userData )
     239{
     240    tr_socketList * tmp;
     241    for( tmp = head; tmp; tmp = tmp->next )
     242        cb( &tmp->socket, &tmp->addr, userData );
     243}
     244
     245/***********************************************************************
    143246 * TCP sockets
    144247 **********************************************************************/
     
    162265        if( evutil_make_socket_nonblocking( fd ) )
    163266        {
     267            int tmperrno;
    164268            tr_err( _( "Couldn't create socket: %s" ),
    165269                   tr_strerror( sockerrno ) );
     270            tmperrno = sockerrno;
    166271            tr_netClose( fd );
    167             fd = -1;
     272            fd = -tmperrno;
    168273        }
    169274    }
     
    173278
    174279static int
    175 createSocket( int type )
    176 {
    177     return makeSocketNonBlocking( tr_fdSocketCreate( type ) );
     280createSocket( int domain, int type )
     281{
     282    return makeSocketNonBlocking( tr_fdSocketCreate( domain, type ) );
    178283}
    179284
     
    192297}
    193298
    194 static void
    195 setup_sockaddr( const tr_address        * addr,
    196                 tr_port                   port,
    197                 struct sockaddr_storage * sockaddr)
    198 {
    199     struct sockaddr_in  sock4;
    200     struct sockaddr_in6 sock6;
    201 
    202     if( addr->type == TR_AF_INET )
    203     {
    204         memset( &sock4, 0, sizeof( sock4 ) );
    205         sock4.sin_family      = AF_INET;
    206         sock4.sin_addr.s_addr = addr->addr.addr4.s_addr;
    207         sock4.sin_port        = port;
    208         memcpy( sockaddr, &sock4, sizeof( sock4 ) );
    209     }
    210     else
    211     {
    212         memset( &sock6, 0, sizeof( sock6 ) );
    213         sock6.sin6_family = AF_INET6;
    214         sock6.sin6_port = port;
    215         memcpy( &sock6.sin6_addr, &addr->addr, sizeof( struct in6_addr ) );
    216         memcpy( sockaddr, &sock6, sizeof( sock6 ) );
    217     }
    218 }
    219  
    220 int
    221 tr_netOpenTCP( tr_session        * session,
    222                const tr_address  * addr,
    223                tr_port             port )
    224 {
    225     int                     s;
    226     struct sockaddr_storage sock;
    227     const int               type = SOCK_STREAM;
    228 
    229     if( ( s = createSocket( type ) ) < 0 )
    230         return -1;
     299static socklen_t
     300setup_sockaddr( const tr_address        * addr,
     301                tr_port                   port,
     302                struct sockaddr_storage * sockaddr)
     303{
     304    struct sockaddr_in  sock4;
     305    struct sockaddr_in6 sock6;
     306    if( addr->type == TR_AF_INET )
     307    {
     308        memset( &sock4, 0, sizeof( sock4 ) );
     309        sock4.sin_family      = AF_INET;
     310        sock4.sin_addr.s_addr = addr->addr.addr4.s_addr;
     311        sock4.sin_port        = port;
     312        memcpy( sockaddr, &sock4, sizeof( sock4 ) );
     313        return sizeof( struct sockaddr_in );
     314    }
     315    else
     316    {
     317        memset( &sock6, 0, sizeof( sock6 ) );
     318        sock6.sin6_family = AF_INET6;
     319        sock6.sin6_port = port;
     320        sock6.sin6_flowinfo = 0;
     321        sock6.sin6_addr = addr->addr.addr6;
     322        memcpy( sockaddr, &sock6, sizeof( sock6 ) );
     323        return sizeof( struct sockaddr_in6 );
     324    }
     325}
     326
     327int
     328tr_netOpenTCP( tr_session        * session,
     329               const tr_address  * addr,
     330               tr_port             port )
     331{
     332    int                     s;
     333    struct sockaddr_storage sock;
     334    const int               type = SOCK_STREAM;
     335    socklen_t               addrlen;
     336
     337    if( ( s = createSocket( ( addr->type == TR_AF_INET ? AF_INET : AF_INET6 ),
     338                            type ) ) < 0 )
     339        return s;
    231340
    232341    setSndBuf( session, s );
    233342
    234     setup_sockaddr( addr, port, &sock );
     343    addrlen = setup_sockaddr( addr, port, &sock );
    235344
    236345    if( ( connect( s, (struct sockaddr *) &sock,
    237                   sizeof( struct sockaddr ) ) < 0 )
     346                  addrlen ) < 0 )
    238347#ifdef WIN32
    239348      && ( sockerrno != WSAEWOULDBLOCK )
     
    241350      && ( sockerrno != EINPROGRESS ) )
    242351    {
     352        int tmperrno;
    243353        tr_err( _( "Couldn't connect socket %d to %s, port %d (errno %d - %s)" ),
    244354               s, tr_ntop_non_ts( addr ), (int)port, sockerrno, tr_strerror( sockerrno ) );
     355        tmperrno = sockerrno;
    245356        tr_netClose( s );
    246         s = -1;
     357        s = -tmperrno;
    247358    }
    248359
     
    254365
    255366int
    256 tr_netBindTCP( const tr_address * addr, tr_port port )
    257 {
    258     int                      s;
    259     struct sockaddr_storage  sock;
    260     const int                type = SOCK_STREAM;
     367tr_netBindTCP( const tr_address * addr, tr_port port, tr_bool suppressMsgs )
     368{
     369    int                     s;
     370    struct sockaddr_storage sock;
     371    const int               type = SOCK_STREAM;
     372    int                     addrlen;
    261373
    262374#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT )
     
    264376#endif
    265377
    266     if( ( s = createSocket( type ) ) < 0 )
    267         return -1;
     378    if( ( s = createSocket( ( addr->type == TR_AF_INET ? AF_INET : AF_INET6 ),
     379                            type ) ) < 0 )
     380        return s;
    268381
    269382#ifdef SO_REUSEADDR
     
    272385#endif
    273386
    274     setup_sockaddr( addr, htons( port ), &sock );
     387    addrlen = setup_sockaddr( addr, htons( port ), &sock );
    275388
    276389    if( bind( s, (struct sockaddr *) &sock,
    277              sizeof( struct sockaddr ) ) )
    278     {
    279         tr_err( _( "Couldn't bind port %d on %s: %s" ), port,
    280                tr_ntop_non_ts( addr ), tr_strerror( sockerrno ) );
     390             addrlen ) )
     391    {
     392        int tmperrno;
     393        if( !suppressMsgs )
     394            tr_err( _( "Couldn't bind port %d on %s: %s" ), port,
     395                    tr_ntop_non_ts( addr ), tr_strerror( sockerrno ) );
     396        tmperrno = sockerrno;
    281397        tr_netClose( s );
    282         return -1;
    283     }
    284 
    285     tr_dbg(  "Bound socket %d to port %d on %s",
    286              s, port, tr_ntop_non_ts( addr ) );
     398        return -tmperrno;
     399    }
     400    if( !suppressMsgs )
     401        tr_dbg(  "Bound socket %d to port %d on %s",
     402                 s, port, tr_ntop_non_ts( addr ) );
    287403    return s;
    288404}
Note: See TracChangeset for help on using the changeset viewer.