Ignore:
Timestamp:
Dec 2, 2008, 3:41:58 AM (13 years ago)
Author:
charles
Message:

(libT) re-apply jhujhiti's IPv6 patch. This merges in my tr_port cleanup, so any new bugs are mine :/

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/net.c

    r7224 r7231  
    4848#include "utils.h"
    4949
     50const tr_address tr_in6addr_any = { TR_AF_INET6, { IN6ADDR_ANY_INIT } };
     51const tr_address tr_inaddr_any = { TR_AF_INET,
     52    { { { { INADDR_ANY, 0x00, 0x00, 0x00 } } } } };
     53
    5054
    5155void
     
    6468}
    6569
    66 /***********************************************************************
    67  * DNS resolution
    68  *
    69  * Synchronous "resolution": only works with character strings
    70  * representing numbers expressed in the Internet standard `.' notation.
    71  * Returns a non-zero value if an error occurs.
    72  **********************************************************************/
    73 int
    74 tr_netResolve( const char *     address,
    75                struct in_addr * addr )
    76 {
    77     addr->s_addr = inet_addr( address );
    78     return addr->s_addr == 0xFFFFFFFF;
    79 }
     70
     71const char *
     72tr_ntop( const tr_address * src, char * dst, int size )
     73{
     74    if( src->type == TR_AF_INET )
     75        return inet_ntop( AF_INET, &src->addr, dst, size );
     76    else
     77        return inet_ntop( AF_INET6, &src->addr, dst, size );
     78}
     79
     80/*
     81 * Non-threadsafe version of tr_ntop, which uses a static memory area for a buffer.
     82 * This function is suitable to be called from libTransmission's networking code,
     83 * which is single-threaded.
     84 */
     85const char *
     86tr_ntop_non_ts( const tr_address * src )
     87{
     88    static char buf[INET6_ADDRSTRLEN];
     89    return tr_ntop( src, buf, sizeof( buf ) );
     90}
     91
     92tr_address *
     93tr_pton( const char * src, tr_address * dst )
     94{
     95    int retval = inet_pton( AF_INET, src, &dst->addr );
     96    if( retval < 0 )
     97        return NULL;
     98    else if( retval == 0 )
     99        retval = inet_pton( AF_INET6, src, &dst->addr );
     100    else
     101    {
     102        dst->type = TR_AF_INET;
     103        return dst;
     104    }
     105
     106    if( retval < 1 )
     107        return NULL;
     108    dst->type = TR_AF_INET6;
     109    return dst;
     110}
     111
     112/*
     113 * Compare two tr_address structures.
     114 * Returns:
     115 * <0 if a < b
     116 * >0 if a > b
     117 * 0  if a == b
     118 */
     119int
     120tr_compareAddresses( const tr_address * a, const tr_address * b)
     121{
     122    int retval;
     123    int addrlen;
     124
     125    /* IPv6 addresses are always "greater than" IPv4 */
     126    if( a->type == TR_AF_INET && b->type == TR_AF_INET6 )
     127        return 1;
     128    if( a->type == TR_AF_INET6 && b->type == TR_AF_INET )
     129        return -1;
     130
     131    if( a->type == TR_AF_INET )
     132        addrlen = sizeof( struct in_addr );
     133    else
     134        addrlen = sizeof( struct in6_addr );
     135    retval = memcmp( &a->addr, &b->addr, addrlen );
     136    if( retval == 0 )
     137        return 0;
     138     
     139    return retval;
     140}
    80141
    81142/***********************************************************************
     
    137198}
    138199
    139 int
    140 tr_netOpenTCP( tr_session            * session,
    141                const struct in_addr  * addr,
    142                tr_port                 port )
    143 {
    144     int                s;
    145     struct sockaddr_in sock;
    146     const int          type = SOCK_STREAM;
     200static void
     201setup_sockaddr( const tr_address        * addr,
     202                tr_port                   port,
     203                struct sockaddr_storage * sockaddr)
     204{
     205    struct sockaddr_in  sock4;
     206    struct sockaddr_in6 sock6;
     207
     208    if( addr->type == TR_AF_INET )
     209    {
     210        memset( &sock4, 0, sizeof( sock4 ) );
     211        sock4.sin_family      = AF_INET;
     212        sock4.sin_addr.s_addr = addr->addr.addr4.s_addr;
     213        sock4.sin_port        = port;
     214        memcpy( sockaddr, &sock4, sizeof( sock4 ) );
     215    }
     216    else
     217    {
     218        memset( &sock6, 0, sizeof( sock6 ) );
     219        sock6.sin6_family = AF_INET6;
     220        sock6.sin6_port = port;
     221        memcpy( &sock6.sin6_addr, &addr->addr, sizeof( struct in6_addr ) );
     222        memcpy( sockaddr, &sock6, sizeof( sock6 ) );
     223    }
     224}
     225 
     226int
     227tr_netOpenTCP( tr_session        * session,
     228               const tr_address  * addr,
     229               tr_port             port )
     230{
     231    int                     s;
     232    struct sockaddr_storage sock;
     233    const int               type = SOCK_STREAM;
    147234
    148235    if( ( s = createSocket( type ) ) < 0 )
     
    151238    setSndBuf( session, s );
    152239
    153     memset( &sock, 0, sizeof( sock ) );
    154     sock.sin_family      = AF_INET;
    155     sock.sin_addr.s_addr = addr->s_addr;
    156     sock.sin_port        = port;
     240    setup_sockaddr( addr, port, &sock );
    157241
    158242    if( ( connect( s, (struct sockaddr *) &sock,
    159                   sizeof( struct sockaddr_in ) ) < 0 )
     243                  sizeof( struct sockaddr ) ) < 0 )
    160244#ifdef WIN32
    161245      && ( sockerrno != WSAEWOULDBLOCK )
     
    164248    {
    165249        tr_err( _( "Couldn't connect socket %d to %s, port %d (errno %d - %s)" ),
    166                s, inet_ntoa( *addr ), (int)port, sockerrno, tr_strerror( sockerrno ) );
     250               s, tr_ntop_non_ts( addr ), (int)port, sockerrno, tr_strerror( sockerrno ) );
    167251        tr_netClose( s );
    168252        s = -1;
     
    176260
    177261int
    178 tr_netBindTCP( int port )
    179 {
    180     int                s;
    181     struct sockaddr_in sock;
    182     const int          type = SOCK_STREAM;
     262tr_netBindTCP( const tr_address * addr, tr_port port )
     263{
     264    int                      s;
     265    struct sockaddr_storage sock;
     266    const int                type = SOCK_STREAM;
    183267
    184268#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT )
     
    194278#endif
    195279
    196     memset( &sock, 0, sizeof( sock ) );
    197     sock.sin_family      = AF_INET;
    198     sock.sin_addr.s_addr = INADDR_ANY;
    199     sock.sin_port        = htons( port );
     280    setup_sockaddr( addr, htons( port ), &sock );
    200281
    201282    if( bind( s, (struct sockaddr *) &sock,
    202              sizeof( struct sockaddr_in ) ) )
    203     {
    204         tr_err( _( "Couldn't bind port %d: %s" ), port,
    205                tr_strerror( sockerrno ) );
     283             sizeof( struct sockaddr ) ) )
     284    {
     285        tr_err( _( "Couldn't bind port %d on %s: %s" ), port,
     286               tr_ntop_non_ts( addr ), tr_strerror( sockerrno ) );
    206287        tr_netClose( s );
    207288        return -1;
    208289    }
    209290
    210     tr_dbg(  "Bound socket %d to port %d", s, port );
     291    tr_dbg(  "Bound socket %d to port %d on %s",
     292             s, port, tr_ntop_non_ts( addr ) );
    211293    return s;
    212294}
    213295
    214296int
    215 tr_netAccept( tr_session      * session,
    216               int               b,
    217               struct in_addr  * addr,
    218               tr_port         * port )
     297tr_netAccept( tr_session  * session,
     298              int           b,
     299              tr_address  * addr,
     300              tr_port     * port )
    219301{
    220302    int fd = makeSocketNonBlocking( tr_fdSocketAccept( b, addr, port ) );
     
    228310    tr_fdSocketClose( s );
    229311}
    230 
    231 void
    232 tr_netNtop( const struct in_addr * addr,
    233             char *                 buf,
    234             int                    len )
    235 {
    236     const uint8_t * cast;
    237 
    238     cast = (const uint8_t *)addr;
    239     tr_snprintf( buf, len, "%hhu.%hhu.%hhu.%hhu",
    240                  cast[0], cast[1], cast[2], cast[3] );
    241 }
    242 
Note: See TracChangeset for help on using the changeset viewer.