From 14a400b7f60394c8c81cd99d50d00ddea75165d8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 12 Feb 2009 20:43:07 +0000 Subject: [PATCH] (trunk libT) #1810: DoS vulnerability wrt incoming connections --- libtransmission/handshake.c | 16 +++++++++++++++- libtransmission/port-forwarding.c | 8 +------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libtransmission/handshake.c b/libtransmission/handshake.c index 1708c2a99..6684b9bbd 100644 --- a/libtransmission/handshake.c +++ b/libtransmission/handshake.c @@ -59,7 +59,10 @@ enum VC_LENGTH = 8, KEY_LEN = 96, CRYPTO_PROVIDE_PLAINTEXT = 1, - CRYPTO_PROVIDE_CRYPTO = 2 + CRYPTO_PROVIDE_CRYPTO = 2, + + /* how long to wait before giving up on a handshake */ + HANDSHAKE_TIMEOUT_MSEC = 60 * 1000 }; @@ -106,6 +109,7 @@ struct tr_handshake uint8_t peer_id[PEER_ID_LEN]; handshakeDoneCB doneCB; void * doneUserData; + tr_timer * timeout; }; /** @@ -1099,6 +1103,8 @@ tr_handshakeFree( tr_handshake * handshake ) if( handshake->io ) tr_peerIoUnref( handshake->io ); /* balanced by the ref in tr_handshakeNew */ + tr_timerFree( &handshake->timeout ); + tr_free( handshake ); } @@ -1160,6 +1166,13 @@ gotError( tr_peerIo * io UNUSED, *** **/ +static int +handshakeTimeout( void * handshake ) +{ + tr_handshakeAbort( handshake ); + return FALSE; +} + tr_handshake* tr_handshakeNew( tr_peerIo * io, tr_encryption_mode encryptionMode, @@ -1175,6 +1188,7 @@ tr_handshakeNew( tr_peerIo * io, handshake->doneCB = doneCB; handshake->doneUserData = doneUserData; handshake->session = tr_peerIoGetSession( io ); + handshake->timeout = tr_timerNew( handshake->session, handshakeTimeout, handshake, HANDSHAKE_TIMEOUT_MSEC ); tr_peerIoRef( io ); /* balanced by the unref in tr_handshakeFree */ tr_peerIoSetIOFuncs( handshake->io, canRead, NULL, gotError, handshake ); diff --git a/libtransmission/port-forwarding.c b/libtransmission/port-forwarding.c index 37c4faab4..6f6d0f6d0 100644 --- a/libtransmission/port-forwarding.c +++ b/libtransmission/port-forwarding.c @@ -165,8 +165,6 @@ bindCb( int * const socket, static void incomingPeersPulse( tr_shared * s ) { - tr_bool allPaused; - if( s->shouldChange ) { tr_socketListForEach( s->bindSockets, &closeCb, s ); @@ -175,9 +173,6 @@ incomingPeersPulse( tr_shared * s ) tr_socketListForEach( s->bindSockets, &bindCb, s ); } - allPaused = tr_sessionGetActiveTorrentCount( s->session ) == 0; - - /* if we have any running torrents, check for new incoming peer connections */ /* (jhujhiti): * This has been changed from a loop that will end when the listener queue * is exhausted to one that will only check for one connection at a time. @@ -185,8 +180,7 @@ incomingPeersPulse( tr_shared * s ) * time between pulses (currently one second). However, just to be safe, * I have increased the length of the listener queue from 5 to 10 * (see acceptCb() above). */ - if( !allPaused ) - tr_socketListForEach( s->bindSockets, &acceptCb, s ); + tr_socketListForEach( s->bindSockets, &acceptCb, s ); } static int