Ignore:
Timestamp:
Dec 5, 2006, 12:14:52 AM (15 years ago)
Author:
livings124
Message:

initial support for announce-list (currently crashes when a tracker fails)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/multitracker/libtransmission/tracker.c

    r1149 r1154  
    4848    uint64_t       dateScrape;
    4949    int            lastScrapeFailed;
     50   
     51    int            shouldsetAnnounce;
     52    int            announceTier;
     53    int            announceTierLast;
    5054
    5155#define TC_ATTEMPT_NOREACH 1
     
    6266};
    6367
     68static void        setAnnounce( tr_tracker_t * tc, tr_announce_list_item_t * announceItem );
     69static int         announceToScrape( char * announce, char * scrape );
     70static void        failureAnnouncing( tr_tracker_t * tc );
    6471static tr_http_t * getQuery         ( tr_tracker_t * tc );
    6572static tr_http_t * getScrapeQuery   ( tr_tracker_t * tc );
     
    7582    tc->tor            = tor;
    7683    tc->id             = tor->id;
     84   
     85    setAnnounce( tc, &tor->info.trackerAnnounceList[0] );
    7786
    7887    tc->started        = 1;
     
    92101}
    93102
     103static void setAnnounce( tr_tracker_t * tc, tr_announce_list_item_t * announceItem )
     104{
     105    tr_torrent_t * tor = tc->tor;
     106    tr_info_t    * inf = &tor->info;
     107   
     108    tr_lockLock( &tor->lock );
     109   
     110    snprintf( inf->trackerAddress, 256, "%s", announceItem->address );
     111    inf->trackerPort = announceItem->port;
     112    snprintf( inf->trackerAnnounce, MAX_PATH_LENGTH, "%s", announceItem->announce );
     113   
     114    inf->trackerCanScrape = announceToScrape( announceItem->announce, inf->trackerScrape );
     115    tc->dateScrape = 0;
     116   
     117    tr_lockUnlock( &tor->lock );
     118}
     119
     120static int announceToScrape( char * announce, char * scrape )
     121{   
     122    char * slash, * nextSlash;
     123    int pre, post;
     124   
     125    slash = strchr( announce, '/' );
     126    while( ( nextSlash = strchr( slash + 1, '/' ) ) )
     127    {
     128        slash = nextSlash;
     129    }
     130    slash++;
     131   
     132    if( !strncmp( slash, "announce", 8 ) )
     133    {
     134        pre  = (long) slash - (long) announce;
     135        post = strlen( announce ) - pre - 8;
     136        memcpy( scrape, announce, pre );
     137        sprintf( &scrape[pre], "scrape" );
     138        memcpy( &scrape[pre+6], &announce[pre+8], post );
     139        scrape[pre+6+post] = 0;
     140       
     141        return 1;
     142    }
     143    else
     144    {
     145        return 0;
     146    }
     147}
     148
     149static void failureAnnouncing( tr_tracker_t * tc )
     150{
     151    tr_torrent_t * tor = tc->tor;
     152    tr_info_t    * inf = &tor->info;
     153   
     154    int i;
     155    tr_announce_list_item_t * announceItem;
     156   
     157    tc->announceTierLast++;
     158    tc->shouldsetAnnounce = 1;
     159   
     160    /* If there are no more trackers don't try to change the announce */
     161    if( tc->announceTier <= inf->trackerAnnounceTiers)
     162        return;
     163   
     164    announceItem = &inf->trackerAnnounceList[tc->announceTier];
     165    for( i = 0; i <= tc->announceTierLast; i++ )
     166    {
     167        announceItem = announceItem->nextItem;
     168    }
     169   
     170    if( announceItem == NULL )
     171    {
     172        tc->shouldsetAnnounce = 0;
     173    }
     174}
     175
    94176static int shouldConnect( tr_tracker_t * tc )
    95177{
    96178    tr_torrent_t * tor = tc->tor;
    97179    uint64_t       now;
    98 
     180   
     181    /* Last tracker failed, try next */
     182    if( tc->shouldsetAnnounce )
     183    {
     184        return 1;
     185    }
     186   
    99187    now = tr_date();
    100188
     
    162250static int shouldScrape( tr_tracker_t * tc )
    163251{
     252    tr_torrent_t * tor = tc->tor;
     253    tr_info_t    * inf = &tor->info;
    164254    uint64_t now, interval;
    165255
    166     /* scrape not supported */
    167     if( !tc->tor->scrape[0] )
     256    /* in process of changing tracker or scrape not supported */
     257    if( tc->shouldsetAnnounce || !inf->trackerCanScrape )
    168258    {
    169259        return 0;
     
    192282    tr_info_t    * inf = &tor->info;
    193283    const char   * data;
    194     int            len;
     284    int            len, i;
     285    tr_announce_list_item_t * announceItem;
    195286
    196287    if( ( NULL == tc->http ) && shouldConnect( tc ) )
    197288    {
     289        if( tc->shouldsetAnnounce )
     290        {
     291            tr_err( "Tracker: %s failed to connect, trying next", inf->trackerAddress );
     292           
     293            announceItem = &inf->trackerAnnounceList[tc->announceTier];
     294            for( i = 0; i <= tc->announceTierLast; i++ )
     295            {
     296                announceItem = announceItem->nextItem;
     297            }
     298           
     299            if( announceItem != NULL )
     300            {
     301                tc->announceTierLast++;
     302               
     303                /* Move address to front of tier in announce list */
     304            }
     305            else
     306            {
     307                tc->announceTierLast = 0;
     308                tc->announceTier++;
     309               
     310                announceItem = &inf->trackerAnnounceList[tc->announceTier];
     311            }
     312           
     313            setAnnounce( tc, announceItem );
     314           
     315            tc->shouldsetAnnounce = 0;
     316        }
     317        else
     318        {
     319            if( tc->announceTier != 0 )
     320            {
     321                setAnnounce( tc, inf->trackerAnnounceList );
     322                tc->announceTier = 0;
     323            }
     324            tc->announceTierLast = 0;
     325        }
     326       
    198327        if( tr_fdSocketWillCreate( tor->fdlimit, 1 ) )
    199328        {
     
    222351                killHttp( &tc->http, tor->fdlimit );
    223352                tc->dateTry = tr_date();
    224                 break;
     353               
     354                failureAnnouncing( tc );
     355                if ( tc->shouldsetAnnounce )
     356                {
     357                    tr_trackerPulse( tc );
     358                }
     359               
     360                return;
    225361
    226362            case TR_OK:
    227363                readAnswer( tc, data, len );
    228364                killHttp( &tc->http, tor->fdlimit );
     365               
     366                /* Something happened to need to try next address */
     367                if ( tc->shouldsetAnnounce )
     368                {
     369                    tr_trackerPulse( tc );
     370                    return;
     371                }
     372               
    229373                break;
    230374        }
     
    258402                readScrapeAnswer( tc, data, len );
    259403                killHttp( &tc->httpScrape, tor->fdlimit );
     404               
    260405                break;
    261406        }
     
    377522    char           start;
    378523
    379     start = ( strchr( tor->scrape, '?' ) ? '&' : '?' );
     524    start = ( strchr( inf->trackerScrape, '?' ) ? '&' : '?' );
    380525
    381526    return tr_httpClient( TR_HTTP_GET, inf->trackerAddress, inf->trackerPort,
    382527                          "%s%c"
    383528                          "info_hash=%s",
    384                           tor->scrape, start, tor->escapedHashString );
     529                          inf->trackerScrape, start, tor->escapedHashString );
    385530}
    386531
     
    397542    tc->dateTry = tr_date();
    398543    code = tr_httpResponseCode( data, len );
     544   
    399545    if( 0 > code )
    400546    {
     
    402548        tr_inf( "Tracker: invalid HTTP status line" );
    403549        tc->lastAttempt = TC_ATTEMPT_NOREACH;
     550        failureAnnouncing( tc );
    404551        return;
    405552    }
     
    410557        tr_err( "Tracker: invalid HTTP status code: %i", code );
    411558        tc->lastAttempt = TC_ATTEMPT_ERROR;
     559        failureAnnouncing( tc );
    412560        return;
    413561    }
     
    419567        tr_err( "Tracker: could not find end of HTTP headers" );
    420568        tc->lastAttempt = TC_ATTEMPT_NOREACH;
     569        failureAnnouncing( tc );
    421570        return;
    422571    }
     
    443592        tr_err( "Tracker: no valid dictionary found in answer" );
    444593        tc->lastAttempt = TC_ATTEMPT_ERROR;
     594        failureAnnouncing( tc );
    445595        return;
    446596    }
     
    455605                  "%s", bePeers->val.s.s );
    456606        tc->lastAttempt = TC_ATTEMPT_ERROR;
     607        failureAnnouncing( tc );
    457608        goto cleanup;
    458609    }
     
    543694        }
    544695        tr_err( "Tracker: no \"peers\" field" );
     696        failureAnnouncing( tc );
    545697        goto cleanup;
    546698    }
     
    755907int tr_trackerScrape( tr_torrent_t * tor, int * s, int * l, int * d )
    756908{
     909    tr_info_t    * inf = &tor->info;
     910   
    757911    tr_tracker_t * tc;
    758912    tr_http_t    * http;
     
    761915    int            ret;
    762916
    763     if( !tor->scrape[0] )
     917    if( !inf->trackerCanScrape )
    764918    {
    765919        return 1;
Note: See TracChangeset for help on using the changeset viewer.