From 51096225bd70ebb62e9c816b9358441e46aa2faf Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 8 Aug 2007 06:01:52 +0000 Subject: [PATCH] (trunk) rewrite peerCheck code based on comments from mtolman in http://transmission.m0k.org/forum/viewtopic.php?t=2106 --- libtransmission/peerutils.h | 121 ++++++++++++++---------------------- 1 file changed, 47 insertions(+), 74 deletions(-) diff --git a/libtransmission/peerutils.h b/libtransmission/peerutils.h index 90014c502..099b55a70 100644 --- a/libtransmission/peerutils.h +++ b/libtransmission/peerutils.h @@ -34,81 +34,54 @@ static int peerCmp( tr_peer_t * peer1, tr_peer_t * peer2 ) return memcmp( peer1->id, peer2->id, 20 ); } -static int checkPeer( tr_peer_t * peer ) +static int +checkPeer( tr_peer_t * peer ) { - tr_torrent_t * tor = peer->tor; - - uint64_t now; - int idleTime, peersWanted, percentOfRange; - int ret; - - now = tr_date(); - idleTime = now - peer->date; - - /* assume any peer over with an idleTime lower than - 8 seconds has not timed out */ - if ( idleTime > MIN_CON_TIMEOUT ) - { - peersWanted = ( TR_MAX_PEER_COUNT * PERCENT_PEER_WANTED ) / 100; - if ( tor->peerCount > peersWanted ) - { - /* strict requirements for connecting timeout */ - if ( peer->status < PEER_STATUS_CONNECTED ) - { - peer_dbg( "connection timeout, idled %i seconds", - ( idleTime / 1000 ) ); - return TR_ERROR; - } - - /* strict requirements for idle uploading timeout */ - if ( peer->inRequestCount && idleTime > MIN_UPLOAD_IDLE ) - { - peer_dbg( "idle uploader timeout, idled %i seconds", - ( idleTime / 1000 ) ); - return TR_ERROR; - } - - /* strict requirements for keep-alive timeout */ - if ( idleTime > MIN_KEEP_ALIVE ) - { - peer_dbg( "peer timeout, idled %i seconds", - ( idleTime / 1000 ) ); - return TR_ERROR; - } - } - /* if we are tight for peers, relax the enforcement of timeouts */ - else - { - percentOfRange = tor->peerCount / (TR_MAX_PEER_COUNT - peersWanted); - - /* relax requirements for connecting timeout */ - if ( peer->status < PEER_STATUS_CONNECTED && idleTime > MIN_CON_TIMEOUT + - ( MAX_CON_TIMEOUT - MIN_CON_TIMEOUT ) * percentOfRange ) - { - peer_dbg( "connection timeout, idled %i seconds", - ( idleTime / 1000 ) ); - return TR_ERROR; - } - - /* relax requirements for idle uploading timeout */ - if ( peer->inRequestCount && idleTime > MIN_UPLOAD_IDLE + - ( MAX_UPLOAD_IDLE - MIN_UPLOAD_IDLE ) * percentOfRange ) - { - peer_dbg( "idle uploader timeout, idled %i seconds", - ( idleTime / 1000 ) ); - return TR_ERROR; - } - - /* relax requirements for keep-alive timeout */ - if ( idleTime > MIN_KEEP_ALIVE + - ( MAX_KEEP_ALIVE - MIN_KEEP_ALIVE ) * percentOfRange ) - { - peer_dbg( "peer timeout, idled %i seconds", - ( idleTime / 1000 ) ); - return TR_ERROR; - } - } - } + int ret; + tr_torrent_t * tor = peer->tor; + const uint64_t now = tr_date( ); + const uint64_t idleTime = now - peer->date; + uint64_t lo, hi, minimum; + int relaxStrictnessIfFewerThanN; + double strictness; + + /* when deciding whether or not to keep a peer, judge its responsiveness + on a sliding scale that's based on how many other peers are available */ + relaxStrictnessIfFewerThanN = (int)(((TR_MAX_PEER_COUNT * PERCENT_PEER_WANTED) / 100.0) + 0.5); + + /* if we have >= relaxIfFewerThan, strictness is 100%. + if we have zero connections, strictness is 0% */ + if( tor->peerCount >= relaxStrictnessIfFewerThanN ) + strictness = 1.0; + else + strictness = tor->peerCount / (double)relaxStrictnessIfFewerThanN; + + /* test: has it been too long since we were properly connected to them? */ + lo = MIN_CON_TIMEOUT; + hi = MAX_CON_TIMEOUT; + minimum = lo + ((hi-lo) * strictness); + if( peer->status < PEER_STATUS_CONNECTED && idleTime > minimum ) { + peer_dbg( "connection timeout, idled %i seconds", (int)(idleTime/1000) ); + return TR_ERROR; + } + + /* test: have we been waiting on a request for too long? */ + lo = MIN_UPLOAD_IDLE; + hi = MAX_UPLOAD_IDLE; + minimum = lo + ((hi-lo) * strictness); + if( peer->inRequestCount && idleTime > minimum ) { + peer_dbg( "idle uploader timeout, idled %d seconds", (int)(idleTime/1000)); + return TR_ERROR; + } + + /* test: has it been too long since the peer gave us any response at all? */ + lo = MIN_KEEP_ALIVE; + hi = MAX_KEEP_ALIVE; + minimum = lo + ((hi-lo) * strictness); + if( idleTime > minimum ) { + peer_dbg( "peer timeout, idled %d seconds", (int)(idleTime/1000) ); + return TR_ERROR; + } if( PEER_STATUS_CONNECTED == peer->status ) {