Christian Weisgerber <[EMAIL PROTECTED]> wrote:

> I looked at the tracker responses, and they seemed fine.  (Not that
> I know the details of the protocol.)  I suspect transmission just
> fails to parse them.  It keeps hammering away at the tracker for a
> "correct" response, which looks like a fairly serious bug.

This corresponds to changeset 230 from the upstream SVN, which
introduces a less haphazard tracker response parsing.

Please test.


Index: Makefile
===================================================================
RCS file: /cvs/ports/net/transmission/Makefile,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile
--- Makefile    26 Apr 2006 20:05:06 -0000      1.1.1.1
+++ Makefile    26 Apr 2006 21:36:57 -0000
@@ -4,8 +4,8 @@
 COMMENT-gui=   "lightweight BitTorrent client with graphical interface"
 
 DISTNAME=      Transmission-0.5
-PKGNAME=       ${DISTNAME:L}
-PKGNAME-gui=   ${DISTNAME:L:S/-/-gui-/}
+PKGNAME=       ${DISTNAME:L}p0
+PKGNAME-gui=   ${DISTNAME:L:S/-/-gui-/}p0
 CATEGORIES=    net
 HOMEPAGE=      http://transmission.m0k.org/
 
Index: patches/patch-libtransmission_tracker_c
===================================================================
RCS file: patches/patch-libtransmission_tracker_c
diff -N patches/patch-libtransmission_tracker_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-libtransmission_tracker_c     26 Apr 2006 21:36:57 -0000
@@ -0,0 +1,175 @@
+$OpenBSD$
+--- libtransmission/tracker.c.orig     Sat Feb 11 17:37:11 2006
++++ libtransmission/tracker.c  Wed Apr 26 23:21:07 2006
+@@ -45,6 +45,11 @@ struct tr_tracker_s
+ #define TC_STATUS_RECV    4
+     char           status;
+ 
++#define TC_ATTEMPT_NOREACH 1
++#define TC_ATTEMPT_ERROR   2
++#define TC_ATTEMPT_OK      4
++    char           lastAttempt;
++
+     int            socket;
+     uint8_t      * buf;
+     int            size;
+@@ -67,10 +72,12 @@ tr_tracker_t * tr_trackerInit( tr_handle
+ 
+     tc->started  = 1;
+ 
++    tc->interval = 300;
+     tc->seeders  = -1;
+     tc->leechers = -1;
+ 
+     tc->status   = TC_STATUS_IDLE;
++    tc->lastAttempt = TC_ATTEMPT_NOREACH;
+     tc->size     = 1024;
+     tc->buf      = malloc( tc->size );
+ 
+@@ -84,12 +91,22 @@ static int shouldConnect( tr_tracker_t *
+ {
+     uint64_t now = tr_date();
+ 
+-    /* In any case, always wait 5 seconds between two requests */
+-    if( now < tc->dateTry + 5000 )
++    /* Unreachable tracker, try 10 seconds before trying again */
++    if( tc->lastAttempt == TC_ATTEMPT_NOREACH &&
++        now < tc->dateTry + 10000 )
+     {
+         return 0;
+     }
+ 
++    /* The tracker rejected us (like 4XX code, unauthorized IP...),
++       don't hammer it - we'll probably get the same answer next time
++       anyway */
++    if( tc->lastAttempt == TC_ATTEMPT_ERROR &&
++        now < tc->dateTry + 1000 * tc->interval )
++    {
++        return 0;
++    }
++
+     /* Do we need to send an event? */
+     if( tc->started || tc->completed || tc->stopped || 0 < tc->newPort )
+     {
+@@ -310,6 +327,8 @@ static void recvAnswer( tr_tracker_t * t
+     int i;
+     benc_val_t   beAll;
+     benc_val_t * bePeers, * beFoo;
++    uint8_t * body;
++    int bodylen;
+ 
+     if( tc->pos == tc->size )
+     {
+@@ -338,34 +357,70 @@ static void recvAnswer( tr_tracker_t * t
+     tc->status  = TC_STATUS_IDLE;
+     tc->dateTry = tr_date();
+ 
+-    if( tc->pos < 1 )
++    if( tc->pos < 12 || ( 0 != memcmp( tc->buf, "HTTP/1.0 ", 9 ) &&
++                          0 != memcmp( tc->buf, "HTTP/1.1 ", 9 ) ) )
+     {
+-        /* We got nothing */
++        /* We don't have a complete HTTP status line */
++        tr_inf( "Tracker: incomplete HTTP status line" );
++        tc->lastAttempt = TC_ATTEMPT_NOREACH;
+         return;
+     }
+ 
++    if( '2' != tc->buf[9] )
++    {
++        /* we didn't get a 2xx status code */
++        tr_err( "Tracker: invalid HTTP status code: %c%c%c",
++                tc->buf[9], tc->buf[10], tc->buf[11] );
++        tc->lastAttempt = TC_ATTEMPT_ERROR;
++        return;
++    }
++
++    /* find the end of the http headers */
++    body = tr_memmem( tc->buf, tc->pos, "\015\012\015\012", 4 );
++    if( NULL != body )
++    {
++        body += 4;
++    }
++    /* hooray for trackers that violate the HTTP spec */
++    else if( NULL != ( body = tr_memmem( tc->buf, tc->pos, "\015\015", 2 ) ) 
||
++             NULL != ( body = tr_memmem( tc->buf, tc->pos, "\012\012", 2 ) ) )
++    {
++        body += 2;
++    }
++    else
++    {
++        tr_err( "Tracker: could not find end of HTTP headers" );
++        tc->lastAttempt = TC_ATTEMPT_NOREACH;
++        return;
++    }
++    bodylen = tc->pos - (body - tc->buf);
++
+     /* Find the beginning of the dictionary */
+-    for( i = 0; i < tc->pos - 18; i++ )
++    for( i = 0; i < bodylen; i++ )
+     {
+-        /* Hem */
+-        if( !memcmp( &tc->buf[i], "d8:interval", 11 ) ||
+-            !memcmp( &tc->buf[i], "d8:complete", 11 ) ||
+-            !memcmp( &tc->buf[i], "d14:failure reason", 18 ) )
++        if( body[i] == 'd' )
+         {
++            /* This must be it */
+             break;
+         }
+     }
+ 
+-    if( i >= tc->pos - 18 )
++    if( i >= bodylen )
+     {
++        if( tc->stopped || 0 < tc->newPort )
++        {
++            tc->lastAttempt = TC_ATTEMPT_OK;
++            goto nodict;
++        }
+         tr_err( "Tracker: no dictionary in answer" );
+-        // printf( "%s\n", tc->buf );
++        tc->lastAttempt = TC_ATTEMPT_ERROR;
+         return;
+     }
+ 
+-    if( tr_bencLoad( &tc->buf[i], &beAll, NULL ) )
++    if( tr_bencLoad( &body[i], &beAll, NULL ) )
+     {
+         tr_err( "Tracker: error parsing bencoded data" );
++        tc->lastAttempt = TC_ATTEMPT_ERROR;
+         return;
+     }
+ 
+@@ -377,10 +432,12 @@ static void recvAnswer( tr_tracker_t * t
+         tor->status |= TR_TRACKER_ERROR;
+         snprintf( tor->error, sizeof( tor->error ),
+                   "%s", bePeers->val.s.s );
++        tc->lastAttempt = TC_ATTEMPT_ERROR;
+         goto cleanup;
+     }
+ 
+     tor->status &= ~TR_TRACKER_ERROR;
++    tc->lastAttempt = TC_ATTEMPT_OK;
+ 
+     if( !tc->interval )
+     {
+@@ -417,6 +474,10 @@ static void recvAnswer( tr_tracker_t * t
+ 
+     if( !( bePeers = tr_bencDictFind( &beAll, "peers" ) ) )
+     {
++        if( tc->stopped || 0 < tc->newPort )
++        {
++            goto nodict;
++        }
+         tr_err( "Tracker: no \"peers\" field" );
+         goto cleanup;
+     }
+@@ -477,6 +538,7 @@ static void recvAnswer( tr_tracker_t * t
+         }
+     }
+ 
++nodict:
+     /* Success */
+     tc->started   = 0;
+     tc->completed = 0;
Index: patches/patch-libtransmission_utils_c
===================================================================
RCS file: patches/patch-libtransmission_utils_c
diff -N patches/patch-libtransmission_utils_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-libtransmission_utils_c       26 Apr 2006 21:36:57 -0000
@@ -0,0 +1,37 @@
+$OpenBSD$
+--- libtransmission/utils.c.orig       Sat Feb 11 17:37:11 2006
++++ libtransmission/utils.c    Wed Apr 26 23:18:43 2006
+@@ -61,3 +61,33 @@ int tr_rand( int sup )
+     }
+     return rand() % sup;
+ }
++
++void * tr_memmem( const void *vbig, size_t big_len,
++                  const void *vlittle, size_t little_len )
++{
++    const char *big = vbig;
++    const char *little = vlittle;
++    size_t ii, jj;
++
++    if( 0 == big_len || 0 == little_len )
++    {
++        return NULL;
++    }
++
++    for( ii = 0; ii + little_len <= big_len; ii++ )
++    {
++        for( jj = 0; jj < little_len; jj++ )
++        {
++            if( big[ii + jj] != little[jj] )
++            {
++                break;
++            }
++        }
++        if( jj == little_len )
++        {
++            return (char*)big + ii;
++        }
++    }
++
++    return NULL;
++}
Index: patches/patch-libtransmission_utils_h
===================================================================
RCS file: patches/patch-libtransmission_utils_h
diff -N patches/patch-libtransmission_utils_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-libtransmission_utils_h       26 Apr 2006 21:36:57 -0000
@@ -0,0 +1,12 @@
+$OpenBSD$
+--- libtransmission/utils.h.orig       Sat Feb 11 17:37:11 2006
++++ libtransmission/utils.h    Wed Apr 26 23:18:43 2006
+@@ -33,6 +33,8 @@ void tr_msg  ( int level, char * msg, ..
+ 
+ int  tr_rand ( int );
+ 
++void * tr_memmem( const void *, size_t, const void *, size_t );
++
+ /***********************************************************************
+  * tr_date
+  ***********************************************************************
-- 
Christian "naddy" Weisgerber                          [EMAIL PROTECTED]

Reply via email to