Changeset 164


Ignore:
Timestamp:
Mar 24, 2006, 12:18:38 PM (17 years ago)
Author:
titer
Message:

Adds non-blocking (threaded) DNS resolution

Location:
trunk/libtransmission
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/net.c

    r26 r164  
    11/******************************************************************************
    2  * Copyright (c) 2005 Eric Petit
     2 * Copyright (c) 2005-2006 Transmission authors and contributors
    33 *
    44 * Permission is hereby granted, free of charge, to any person obtaining a
     
    5959}
    6060
     61struct tr_resolve_s
     62{
     63    int            status;
     64    char           * address;
     65    struct in_addr addr;
     66
     67    tr_lock_t      lock;
     68    tr_thread_t    thread;
     69};
     70
     71static void resolveFunc( void * _r )
     72{
     73    tr_resolve_t * r = _r;
     74    struct hostent * host;
     75
     76    tr_lockLock( &r->lock );
     77    r->addr.s_addr = inet_addr( r->address );
     78    if( r->addr.s_addr != 0xFFFFFFFF )
     79    {
     80        r->status = TR_RESOLVE_OK;
     81        tr_lockUnlock( &r->lock );
     82        return;
     83    }
     84    tr_lockUnlock( &r->lock );
     85
     86    if( !( host = gethostbyname( r->address ) ) )
     87    {
     88        tr_lockLock( &r->lock );
     89        r->status = TR_RESOLVE_ERROR;
     90        tr_lockUnlock( &r->lock );
     91        return;
     92    }
     93    tr_lockLock( &r->lock );
     94    memcpy( &r->addr, host->h_addr, host->h_length );
     95    r->status = TR_RESOLVE_OK;
     96    tr_lockUnlock( &r->lock );
     97}
     98
     99tr_resolve_t * tr_netResolveInit( char * address )
     100{
     101    tr_resolve_t * r = malloc( sizeof( tr_resolve_t ) );
     102
     103    r->status  = TR_RESOLVE_WAIT;
     104    r->address = address;
     105
     106    tr_lockInit( &r->lock );
     107    tr_threadCreate( &r->thread, resolveFunc, r );
     108
     109    return r;
     110}
     111
     112int tr_netResolvePulse( tr_resolve_t * r, struct in_addr * addr )
     113{
     114    int ret;
     115
     116    tr_lockLock( &r->lock );
     117    ret = r->status;
     118    if( ret == TR_RESOLVE_OK )
     119    {
     120        *addr = r->addr;
     121    }
     122    tr_lockUnlock( &r->lock );
     123
     124    return ret;
     125}
     126
     127void tr_netResolveClose( tr_resolve_t * r )
     128{
     129    tr_threadJoin( &r->thread );
     130    tr_lockClose( &r->lock );
     131    free( r );
     132}
     133
     134/* Blocking version */
    61135int tr_netResolve( char * address, struct in_addr * addr )
    62136{
    63     struct hostent * host;
    64 
    65     addr->s_addr = inet_addr( address );
    66     if( addr->s_addr != 0xFFFFFFFF )
    67     {
    68         return 0;
    69     }
    70 
    71     if( !( host = gethostbyname( address ) ) )
    72     {
    73         tr_err( "Could not resolve (%s)", address );
    74         return -1;
    75     }
    76     memcpy( addr, host->h_addr, host->h_length );
    77 
    78     return 0;
     137    tr_resolve_t * r = tr_netResolveInit( address );
     138    int ret;
     139
     140    for( ;; )
     141    {
     142        ret = tr_netResolvePulse( r, addr );
     143        if( ret != TR_RESOLVE_WAIT )
     144        {
     145            break;
     146        }
     147        tr_wait( 20 );
     148    }
     149
     150    tr_netResolveClose( r );
     151    return ( ret != TR_RESOLVE_OK );
    79152}
    80153
  • trunk/libtransmission/net.h

    r26 r164  
    11/******************************************************************************
    2  * Copyright (c) 2005 Eric Petit
     2 * Copyright (c) 2005-2006 Transmission authors and contributors
    33 *
    44 * Permission is hereby granted, free of charge, to any person obtaining a
     
    2121 *****************************************************************************/
    2222
     23#define TR_RESOLVE_WAIT  0
     24#define TR_RESOLVE_ERROR 1
     25#define TR_RESOLVE_OK    2
     26typedef struct tr_resolve_s tr_resolve_t;
     27tr_resolve_t * tr_netResolveInit( char * );
     28int            tr_netResolvePulse( tr_resolve_t *, struct in_addr * );
     29void           tr_netResolveClose( tr_resolve_t * );
     30
    2331int  tr_netResolve ( char *, struct in_addr * );
    2432int  tr_netOpen    ( struct in_addr addr, in_port_t port );
  • trunk/libtransmission/tracker.c

    r162 r164  
    4242
    4343#define TC_STATUS_IDLE    1
    44 #define TC_STATUS_CONNECT 2
    45 #define TC_STATUS_RECV    4
     44#define TC_STATUS_RESOLVE 2
     45#define TC_STATUS_CONNECT 4
     46#define TC_STATUS_RECV    8
    4647    char           status;
    4748
     49    tr_resolve_t * resolve;
    4850    int            socket;
    4951    uint8_t      * buf;
     
    137139    if( ( tc->status & TC_STATUS_IDLE ) && shouldConnect( tc ) )
    138140    {
    139         struct in_addr addr;
    140 
    141         if( tr_fdSocketWillCreate( tor->fdlimit, 1 ) )
    142         {
    143             return 0;
    144         }
    145 
    146         if( tr_netResolve( inf->trackerAddress, &addr ) )
    147         {
    148             tr_fdSocketClosed( tor->fdlimit, 1 );
    149             return 0;
    150         }
    151 
    152         tc->socket = tr_netOpen( addr, htons( inf->trackerPort ) );
    153         if( tc->socket < 0 )
    154         {
    155             tr_fdSocketClosed( tor->fdlimit, 1 );
    156             return 0;
    157         }
     141        tc->resolve = tr_netResolveInit( inf->trackerAddress );
    158142
    159143        tr_inf( "Tracker: connecting to %s:%d (%s)",
     
    165149                      "getting peers" ) ) ) );
    166150
    167         tc->status  = TC_STATUS_CONNECT;
     151        tc->status  = TC_STATUS_RESOLVE;
    168152        tc->dateTry = tr_date();
     153    }
     154
     155    if( tc->status & TC_STATUS_RESOLVE )
     156    {
     157        int ret;
     158        struct in_addr addr;
     159
     160        ret = tr_netResolvePulse( tc->resolve, &addr );
     161        if( ret == TR_RESOLVE_WAIT )
     162        {
     163            return 0;
     164        }
     165        else
     166        {
     167            tr_netResolveClose( tc->resolve );
     168        }
     169       
     170        if( ret == TR_RESOLVE_ERROR )
     171        {
     172            tc->status = TC_STATUS_IDLE;
     173            return 0;
     174        }
     175
     176        if( tr_fdSocketWillCreate( tor->fdlimit, 1 ) )
     177        {
     178            return 0;
     179        }
     180
     181        tc->socket = tr_netOpen( addr, htons( inf->trackerPort ) );
     182        if( tc->socket < 0 )
     183        {
     184            tr_fdSocketClosed( tor->fdlimit, 1 );
     185            return 0;
     186        }
     187
     188        tc->status = TC_STATUS_CONNECT;
    169189    }
    170190
Note: See TracChangeset for help on using the changeset viewer.