Changeset 230 for trunk/libtransmission


Ignore:
Timestamp:
Apr 11, 2006, 10:37:43 PM (16 years ago)
Author:
titer
Message:

Merged simple_http_parsing branch

Location:
trunk/libtransmission
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/tracker.c

    r228 r230  
    4747    char           status;
    4848
     49#define TC_ATTEMPT_NOREACH 1
     50#define TC_ATTEMPT_ERROR   2
     51#define TC_ATTEMPT_OK      4
     52    char           lastAttempt;
     53
    4954    tr_resolve_t * resolve;
    5055    int            socket;
     
    7378    tc->started  = 1;
    7479
     80    tc->interval = 300;
    7581    tc->seeders  = -1;
    7682    tc->leechers = -1;
    7783
    7884    tc->status   = TC_STATUS_IDLE;
     85    tc->lastAttempt = TC_ATTEMPT_NOREACH;
    7986    tc->size     = 1024;
    8087    tc->buf      = malloc( tc->size );
     
    93100    uint64_t now = tr_date();
    94101
    95     /* In any case, always wait 5 seconds between two requests */
    96     if( now < tc->dateTry + 5000 )
     102    /* Unreachable tracker, try 10 seconds before trying again */
     103    if( tc->lastAttempt == TC_ATTEMPT_NOREACH &&
     104        now < tc->dateTry + 10000 )
     105    {
     106        return 0;
     107    }
     108
     109    /* The tracker rejected us (like 4XX code, unauthorized IP...),
     110       don't hammer it - we'll probably get the same answer next time
     111       anyway */
     112    if( tc->lastAttempt == TC_ATTEMPT_ERROR &&
     113        now < tc->dateTry + 1000 * tc->interval )
    97114    {
    98115        return 0;
     
    356373    benc_val_t   beAll;
    357374    benc_val_t * bePeers, * beFoo;
     375    uint8_t * body;
     376    int bodylen;
    358377
    359378    if( tc->pos == tc->size )
     
    384403    tc->dateTry = tr_date();
    385404
    386     if( tc->pos < 1 )
    387     {
    388         /* We got nothing */
     405    if( tc->pos < 12 || ( 0 != memcmp( tc->buf, "HTTP/1.0 ", 9 ) &&
     406                          0 != memcmp( tc->buf, "HTTP/1.1 ", 9 ) ) )
     407    {
     408        /* We don't have a complete HTTP status line */
     409        tr_inf( "Tracker: incomplete HTTP status line" );
     410        tc->lastAttempt = TC_ATTEMPT_NOREACH;
    389411        return;
    390412    }
    391413
     414    if( '2' != tc->buf[9] )
     415    {
     416        /* we didn't get a 2xx status code */
     417        tr_err( "Tracker: invalid HTTP status code: %c%c%c",
     418                tc->buf[9], tc->buf[10], tc->buf[11] );
     419        tc->lastAttempt = TC_ATTEMPT_ERROR;
     420        return;
     421    }
     422
     423    /* find the end of the http headers */
     424    body = tr_memmem( tc->buf, tc->pos, "\015\012\015\012", 4 );
     425    if( NULL != body )
     426    {
     427        body += 4;
     428    }
     429    /* hooray for trackers that violate the HTTP spec */
     430    else if( NULL != ( body = tr_memmem( tc->buf, tc->pos, "\015\015", 2 ) ) ||
     431             NULL != ( body = tr_memmem( tc->buf, tc->pos, "\012\012", 2 ) ) )
     432    {
     433        body += 2;
     434    }
     435    else
     436    {
     437        tr_err( "Tracker: could not find end of HTTP headers" );
     438        tc->lastAttempt = TC_ATTEMPT_NOREACH;
     439        return;
     440    }
     441    bodylen = tc->pos - (body - tc->buf);
     442
    392443    /* Find the beginning of the dictionary */
    393     for( i = 0; i < tc->pos - 18; i++ )
    394     {
    395         /* Hem */
    396         if( !memcmp( &tc->buf[i], "d8:interval", 11 ) ||
    397             !memcmp( &tc->buf[i], "d8:complete", 11 ) ||
    398             !memcmp( &tc->buf[i], "d14:failure reason", 18 ) )
    399         {
     444    for( i = 0; i < bodylen; i++ )
     445    {
     446        if( body[i] == 'd' )
     447        {
     448            /* This must be it */
    400449            break;
    401450        }
    402451    }
    403452
    404     if( i >= tc->pos - 18 )
    405     {
     453    if( i >= bodylen )
     454    {
     455        if( tc->stopped || 0 < tc->newPort )
     456        {
     457            tc->lastAttempt = TC_ATTEMPT_OK;
     458            goto nodict;
     459        }
    406460        tr_err( "Tracker: no dictionary in answer" );
    407         // printf( "%s\n", tc->buf );
     461        tc->lastAttempt = TC_ATTEMPT_ERROR;
    408462        return;
    409463    }
    410464
    411     if( tr_bencLoad( &tc->buf[i], &beAll, NULL ) )
     465    if( tr_bencLoad( &body[i], &beAll, NULL ) )
    412466    {
    413467        tr_err( "Tracker: error parsing bencoded data" );
     468        tc->lastAttempt = TC_ATTEMPT_ERROR;
    414469        return;
    415470    }
     
    423478        snprintf( tor->trackerError, sizeof( tor->trackerError ),
    424479                  "%s", bePeers->val.s.s );
     480        tc->lastAttempt = TC_ATTEMPT_ERROR;
    425481        goto cleanup;
    426482    }
     483
    427484    tor->error &= ~TR_ETRACKER;
     485    tc->lastAttempt = TC_ATTEMPT_OK;
    428486
    429487    if( !tc->interval )
     
    462520    if( !( bePeers = tr_bencDictFind( &beAll, "peers" ) ) )
    463521    {
     522        if( tc->stopped || 0 < tc->newPort )
     523        {
     524            goto nodict;
     525        }
    464526        tr_err( "Tracker: no \"peers\" field" );
    465527        goto cleanup;
     
    522584    }
    523585
     586nodict:
    524587    /* Success */
    525588    tc->started   = 0;
  • trunk/libtransmission/utils.c

    r1 r230  
    6262    return rand() % sup;
    6363}
     64
     65void * tr_memmem( const void *vbig, size_t big_len,
     66                  const void *vlittle, size_t little_len )
     67{
     68    const char *big = vbig;
     69    const char *little = vlittle;
     70    size_t ii, jj;
     71
     72    if( 0 == big_len || 0 == little_len )
     73    {
     74        return NULL;
     75    }
     76
     77    for( ii = 0; ii + little_len <= big_len; ii++ )
     78    {
     79        for( jj = 0; jj < little_len; jj++ )
     80        {
     81            if( big[ii + jj] != little[jj] )
     82            {
     83                break;
     84            }
     85        }
     86        if( jj == little_len )
     87        {
     88            return (char*)big + ii;
     89        }
     90    }
     91
     92    return NULL;
     93}
  • trunk/libtransmission/utils.h

    r7 r230  
    3333
    3434int  tr_rand ( int );
     35
     36void * tr_memmem( const void *, size_t, const void *, size_t );
    3537
    3638/***********************************************************************
Note: See TracChangeset for help on using the changeset viewer.