]> granicus.if.org Git - transmission/commitdiff
(trunk libT) #3519 "Webseeds don't work" -- handle nonresponsive webseeds
authorJordan Lee <jordan@transmissionbt.com>
Thu, 3 Feb 2011 04:17:48 +0000 (04:17 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Thu, 3 Feb 2011 04:17:48 +0000 (04:17 +0000)
Don't keep trying to use nonresponsive webseeds or it will generate unnecessary network traffic and kill us during endgame.

libtransmission/webseed.c

index 6e27a13422b2f601cc74a4600077b1603a6cfd2e..88b6dcd1b31bba56f65f4b8a2f87a14ba937bd64 100644 (file)
@@ -51,11 +51,14 @@ struct tr_webseed
     size_t               base_url_len;
     int                  torrent_id;
     tr_bool              is_stopping;
+    int                  consecutive_failures;
 };
 
 enum
 {
-    TR_IDLE_TIMER_MSEC = 2000
+    TR_IDLE_TIMER_MSEC = 2000,
+
+    MAX_CONSECUIVE_FAILURES = 5
 };
 
 static void
@@ -84,13 +87,24 @@ publish( tr_webseed * w, tr_peer_event * e )
 }
 
 static void
-fire_client_got_block( tr_torrent * tor, tr_webseed * w, tr_block_index_t block )
+fire_client_got_rej( tr_torrent * tor, tr_webseed * w, tr_block_index_t block )
 {
     tr_peer_event e = blank_event;
+    e.eventType = TR_PEER_CLIENT_GOT_REJ;
     e.pieceIndex = tr_torBlockPiece( tor, block );
     e.offset = tor->blockSize * block - tor->info.pieceSize * e.pieceIndex;
     e.length = tr_torBlockCountBytes( tor, block );
+    publish( w, &e );
+}
+
+static void
+fire_client_got_block( tr_torrent * tor, tr_webseed * w, tr_block_index_t block )
+{
+    tr_peer_event e = blank_event;
     e.eventType = TR_PEER_CLIENT_GOT_BLOCK;
+    e.pieceIndex = tr_torBlockPiece( tor, block );
+    e.offset = tor->blockSize * block - tor->info.pieceSize * e.pieceIndex;
+    e.length = tr_torBlockCountBytes( tor, block );
     publish( w, &e );
 }
 
@@ -140,7 +154,10 @@ on_idle( tr_webseed * w )
     {
         webseed_free( w );
     }
-    else if( !w->is_stopping && tor && tor->isRunning && !tr_torrentIsSeed( tor ) )
+    else if( !w->is_stopping && tor
+                             && tor->isRunning
+                             && !tr_torrentIsSeed( tor )
+                             && ( w->consecutive_failures < MAX_CONSECUIVE_FAILURES ) )
     {
         int i;
         int got = 0;
@@ -185,29 +202,44 @@ web_response_func( tr_session    * session,
                    void          * vtask )
 {
     struct tr_webseed_task * t = vtask;
+    tr_webseed * w = t->webseed;
     tr_torrent * tor = tr_torrentFindFromId( session, t->torrent_id );
     const int success = ( response_code == 206 );
 
-    if( success && tor )
+    if( success )
+        w->consecutive_failures = 0;
+    else
+        ++w->consecutive_failures;
+
+    if( tor )
     {
-        if( evbuffer_get_length( t->content ) < t->length )
-        {
-            task_request_next_chunk( t );
-        }
-        else
+        if( !success )
         {
-            tr_webseed * w = t->webseed;
-
-            tr_cacheWriteBlock( session->cache, tor,
-                                t->piece_index, t->piece_offset, t->length,
-                                t->content );
-            fire_client_got_block( tor, w, t->block );
+            fire_client_got_rej( tor, w, t->block );
 
             tr_list_remove_data( &w->tasks, t );
             evbuffer_free( t->content );
             tr_free( t );
-
-            on_idle( w );
+        }
+        else
+        {
+            if( evbuffer_get_length( t->content ) < t->length )
+            {
+                task_request_next_chunk( t );
+            }
+            else
+            {
+                tr_cacheWriteBlock( session->cache, tor,
+                                    t->piece_index, t->piece_offset, t->length,
+                                    t->content );
+                fire_client_got_block( tor, w, t->block );
+
+                tr_list_remove_data( &w->tasks, t );
+                evbuffer_free( t->content );
+                tr_free( t );
+
+                on_idle( w );
+            }
         }
     }
 }