From 610c912c5a40249a9e57859cc1d0b99cdf01c3a8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jun 2010 16:31:38 +0000 Subject: [PATCH] (trunk libT) #3329 "connection problems when downloading" -- randomize the peer arrays so that all untested peers will have an equal chance of being used. Suggested by Longinus00 --- libtransmission/peer-mgr.c | 47 +++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 1ef84f42c..74f71fd71 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -2498,30 +2498,41 @@ rechokeDownloads( Torrent * t ) /* separate the peers into "good" (ones with a low cancel-to-block ratio), * untested peers, and "bad" (ones with a high cancel-to-block ratio). * That's the order in which we'll choose who to show interest in */ - for( i=0; ipeers, i ); + /* Randomize the peer array so the peers in the three groups will be unsorted... */ + int n = peerCount; + tr_peer ** peers = tr_memdup( tr_ptrArrayBase( &t->peers ), n * sizeof( tr_peer * ) ); - if( !isPeerInteresting( t->tor, peer ) ) + while( n > 0 ) { - tr_peerMsgsSetInterested( peer->msgs, FALSE ); - } - else - { - const int blocks = tr_historyGet( peer->blocksSentToClient, now, msec ); - const int cancels = tr_historyGet( peer->cancelsSentToPeer, now, msec ); + const int i = tr_cryptoWeakRandInt( n ); + tr_peer * peer = tr_ptrArrayNth( &t->peers, i ); - if( !blocks && !cancels ) - untested[untestedCount++] = peer; - else if( !cancels ) - good[goodCount++] = peer; - else if( !blocks ) - bad[badCount++] = peer; - else if( ( cancels * 10 ) < blocks ) - good[goodCount++] = peer; + if( !isPeerInteresting( t->tor, peer ) ) + { + tr_peerMsgsSetInterested( peer->msgs, FALSE ); + } else - bad[badCount++] = peer; + { + const int blocks = tr_historyGet( peer->blocksSentToClient, now, msec ); + const int cancels = tr_historyGet( peer->cancelsSentToPeer, now, msec ); + + if( !blocks && !cancels ) + untested[untestedCount++] = peer; + else if( !cancels ) + good[goodCount++] = peer; + else if( !blocks ) + bad[badCount++] = peer; + else if( ( cancels * 10 ) < blocks ) + good[goodCount++] = peer; + else + bad[badCount++] = peer; + } + + tr_removeElementFromArray( peers, i, sizeof(tr_peer*), n-- ); } + + tr_free( peers ); } t->interestedCount = 0;