diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 9e6d3d2ae..ffff492be 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -558,12 +558,19 @@ broadcastGotBlock( Torrent * t, uint32_t index, uint32_t offset, uint32_t length static int reconnectPulse( void * vtorrent ); +static void +restartReconnectTimer( Torrent * t ) +{ + tr_timerFree( &t->reconnectTimer ); + if( t->isRunning ) + t->reconnectTimer = tr_timerNew( t->manager->handle, reconnectPulse, t, RECONNECT_PERIOD_MSEC ); +} + static void reconnectNow( Torrent * t ) { reconnectPulse( t ); - tr_timerFree( &t->reconnectTimer ); - t->reconnectTimer = tr_timerNew( t->manager->handle, reconnectPulse, t, RECONNECT_PERIOD_MSEC ); + restartReconnectTimer( t ); } static int @@ -589,12 +596,19 @@ reconnectSoon( Torrent * t ) static int rechokePulse( void * vtorrent ); +static void +restartChokeTimer( Torrent * t ) +{ + tr_timerFree( &t->rechokeTimer ); + if( t->isRunning ) + t->rechokeTimer = tr_timerNew( t->manager->handle, rechokePulse, t, RECHOKE_PERIOD_MSEC ); +} + static void rechokeNow( Torrent * t ) { rechokePulse( t ); - tr_timerFree( &t->rechokeTimer ); - t->rechokeTimer = tr_timerNew( t->manager->handle, rechokePulse, t, RECHOKE_PERIOD_MSEC ); + restartChokeTimer( t ); } static int @@ -876,6 +890,7 @@ tr_peerMgrStartTorrent( tr_peerMgr * manager, { Torrent * t = getExistingTorrent( manager, torrentHash ); t->isRunning = 1; + restartChokeTimer( t ); reconnectNow( t ); } @@ -885,7 +900,9 @@ tr_peerMgrStopTorrent( tr_peerMgr * manager, { Torrent * t = getExistingTorrent( manager, torrentHash ); t->isRunning = 0; - reconnectNow( t ); + tr_timerFree( &t->rechokeTimer ); + tr_timerFree( &t->reconnectTimer ); + reconnectPulse( t ); } void @@ -902,8 +919,8 @@ tr_peerMgrAddTorrent( tr_peerMgr * manager, t->tor = tor; t->peers = tr_ptrArrayNew( ); t->requested = tr_bitfieldNew( tor->blockCount ); - t->rechokeTimer = tr_timerNew( manager->handle, rechokePulse, t, RECHOKE_PERIOD_MSEC ); - t->reconnectTimer = tr_timerNew( manager->handle, reconnectPulse, t, RECONNECT_PERIOD_MSEC ); + restartChokeTimer( t ); + restartReconnectTimer( t ); memcpy( t->hash, tor->info.hash, SHA_DIGEST_LENGTH ); tr_ptrArrayInsertSorted( manager->torrents, t, torrentCompare ); diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index 3b90a2e99..554226a2f 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -44,26 +44,30 @@ enum { - BT_CHOKE = 0, - BT_UNCHOKE = 1, - BT_INTERESTED = 2, - BT_NOT_INTERESTED = 3, - BT_HAVE = 4, - BT_BITFIELD = 5, - BT_REQUEST = 6, - BT_PIECE = 7, - BT_CANCEL = 8, - BT_PORT = 9, - BT_SUGGEST = 13, - BT_HAVE_ALL = 14, - BT_HAVE_NONE = 15, - BT_REJECT = 16, - BT_ALLOWED_FAST = 17, - BT_LTEP = 20, + BT_CHOKE = 0, + BT_UNCHOKE = 1, + BT_INTERESTED = 2, + BT_NOT_INTERESTED = 3, + BT_HAVE = 4, + BT_BITFIELD = 5, + BT_REQUEST = 6, + BT_PIECE = 7, + BT_CANCEL = 8, + BT_PORT = 9, + BT_SUGGEST = 13, + BT_HAVE_ALL = 14, + BT_HAVE_NONE = 15, + BT_REJECT = 16, + BT_ALLOWED_FAST = 17, + BT_LTEP = 20, - LTEP_HANDSHAKE = 0, + LTEP_HANDSHAKE = 0, - OUR_LTEP_PEX = 1 + OUR_LTEP_PEX = 1, + + /* disregard requests that want more than this many bytes. + it's common practice in for BT clients to use a 16K threshold */ + MAX_REQUEST_BYTE_COUNT = (16 * 1024) }; enum @@ -611,9 +615,16 @@ requestIsValid( const tr_peermsgs * msgs, struct peer_request * req ) { const tr_torrent * tor = msgs->torrent; assert( req != NULL ); - assert( req->index < (uint32_t)tor->info.pieceCount ); - assert( (int)req->offset < tr_torPieceCountBytes( tor, (int)req->index ) ); - assert( tr_pieceOffset( tor, req->index, req->offset, req->length ) <= tor->info.totalSize ); + + if( req->index >= (uint32_t) tor->info.pieceCount ) + return FALSE; + if ( (int)req->offset >= tr_torPieceCountBytes( tor, (int)req->index ) ) + return FALSE; + if( req->length > MAX_REQUEST_BYTE_COUNT ) + return FALSE; + if( tr_pieceOffset( tor, req->index, req->offset, req->length ) > tor->info.totalSize ) + return FALSE; + return TRUE; }