(libT) #1532: patch from jhujhiti to remove (unused) fast extensions

This commit is contained in:
Charles Kerr 2008-11-29 20:37:34 +00:00
parent d6fce3abcb
commit 40b5fc5351
8 changed files with 7 additions and 341 deletions

View File

@ -110,7 +110,6 @@ TESTS = \
clients-test \
json-test \
rpc-test \
test-fastset \
test-peer-id \
utils-test
@ -151,10 +150,6 @@ rpc_test_SOURCES = rpc-test.c
rpc_test_LDADD = ${apps_ldadd}
rpc_test_LDFLAGS = ${apps_ldflags}
test_fastset_SOURCES = test-fastset.c
test_fastset_LDADD = ${apps_ldadd}
test_fastset_LDFLAGS = ${apps_ldflags}
test_peer_id_SOURCES = test-peer-id.c
test_peer_id_LDADD = ${apps_ldadd}
test_peer_id_LDFLAGS = ${apps_ldflags}

View File

@ -72,14 +72,6 @@ enum
#define HANDSHAKE_SET_LTEP( bits ) ( (void)0 )
#endif
#ifdef ENABLE_FASTPEER
#define HANDSHAKE_HAS_FASTEXT( bits ) ( ( ( bits )[7] & 0x04 ) ? 1 : 0 )
#define HANDSHAKE_SET_FASTEXT( bits ) ( ( bits )[7] |= 0x04 )
#else
#define HANDSHAKE_HAS_FASTEXT( bits ) ( 0 )
#define HANDSHAKE_SET_FASTEXT( bits ) ( (void)0 )
#endif
/* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol
these macros are to be used if both extended messaging and the
azureus protocol is supported, they indicate which protocol is preferred */
@ -214,7 +206,6 @@ buildHandshakeMessage( tr_handshake * handshake,
walk += HANDSHAKE_NAME_LEN;
memset( walk, 0, HANDSHAKE_FLAGS_LEN );
HANDSHAKE_SET_LTEP( walk );
HANDSHAKE_SET_FASTEXT( walk );
walk += HANDSHAKE_FLAGS_LEN;
memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );
@ -297,12 +288,6 @@ parseHandshake( tr_handshake * handshake,
dbgmsg( handshake, "using ltep" );
}
if( HANDSHAKE_HAS_FASTEXT( reserved ) )
{
tr_peerIoEnableFEXT( handshake->io, 1 );
dbgmsg( handshake, "using fext" );
}
return HANDSHAKE_OK;
}
@ -669,11 +654,6 @@ readHandshake( tr_handshake * handshake,
tr_peerIoEnableLTEP( handshake->io, 1 );
dbgmsg( handshake, "using ltep" );
}
if( HANDSHAKE_HAS_FASTEXT( reserved ) )
{
tr_peerIoEnableFEXT( handshake->io, 1 );
dbgmsg( handshake, "using fext" );
}
/* torrent hash */
tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof( hash ) );

View File

@ -84,7 +84,6 @@ struct tr_peerIo
tr_bool isIncoming;
tr_bool peerIdIsSet;
tr_bool extendedProtocolSupported;
tr_bool fastPeersSupported;
int magicNumber;
@ -499,16 +498,6 @@ tr_peerIoEnableLTEP( tr_peerIo * io,
io->extendedProtocolSupported = flag;
}
void
tr_peerIoEnableFEXT( tr_peerIo * io,
int flag )
{
assert( isPeerIo( io ) );
assert( flag == 0 || flag == 1 );
io->fastPeersSupported = flag;
}
int
tr_peerIoSupportsLTEP( const tr_peerIo * io )
{
@ -517,14 +506,6 @@ tr_peerIoSupportsLTEP( const tr_peerIo * io )
return io->extendedProtocolSupported;
}
int
tr_peerIoSupportsFEXT( const tr_peerIo * io )
{
assert( isPeerIo( io ) );
return io->fastPeersSupported;
}
/**
***
**/

View File

@ -53,13 +53,8 @@ tr_session* tr_peerIoGetSession( tr_peerIo * io );
void tr_peerIoEnableLTEP( tr_peerIo * io,
int flag );
void tr_peerIoEnableFEXT( tr_peerIo * io,
int flag );
int tr_peerIoSupportsLTEP( const tr_peerIo * io );
int tr_peerIoSupportsFEXT( const tr_peerIo * io );
/**
***
**/

View File

@ -455,54 +455,6 @@ torrentConstructor( tr_peerMgr * manager,
return t;
}
/**
* For explanation, see http://www.bittorrent.org/fast_extensions.html
* Also see the "test-allowed-set" unit test
*
* @param k number of pieces in set
* @param sz number of pieces in the torrent
* @param infohash torrent's SHA1 hash
* @param ip peer's address
*/
struct tr_bitfield *
tr_peerMgrGenerateAllowedSet(
const uint32_t k,
const uint32_t sz,
const uint8_t *
infohash,
const struct in_addr * ip )
{
uint8_t w[SHA_DIGEST_LENGTH + 4];
uint8_t x[SHA_DIGEST_LENGTH];
tr_bitfield * a;
uint32_t a_size;
*(uint32_t*)w = ntohl( htonl( ip->s_addr ) & 0xffffff00 ); /* (1) */
memcpy( w + 4, infohash, SHA_DIGEST_LENGTH ); /* (2) */
tr_sha1( x, w, sizeof( w ), NULL ); /* (3) */
a = tr_bitfieldNew( sz );
a_size = 0;
while( a_size < k )
{
int i;
for( i = 0; i < 5 && a_size < k; ++i ) /* (4) */
{
uint32_t j = i * 4; /* (5) */
uint32_t y = ntohl( *( uint32_t* )( x + j ) ); /* (6) */
uint32_t index = y % sz; /* (7) */
if( !tr_bitfieldHas( a, index ) ) /* (8) */
{
tr_bitfieldAdd( a, index ); /* (9) */
++a_size;
}
}
tr_sha1( x, x, sizeof( x ), NULL ); /* (3) */
}
return a;
}
static int bandwidthPulse( void * vmgr );

View File

@ -124,10 +124,4 @@ float* tr_peerMgrWebSpeeds( const tr_peerMgr * manager,
const uint8_t * torrentHash );
struct tr_bitfield * tr_peerMgrGenerateAllowedSet( const uint32_t setCount,
const uint32_t pieceCount,
const uint8_t infohash[20],
const struct in_addr * ip );
#endif

View File

@ -58,7 +58,6 @@ enum
BT_HAVE_ALL = 14,
BT_HAVE_NONE = 15,
BT_REJECT = 16,
BT_ALLOWED_FAST = 17,
BT_LTEP = 20,
LTEP_HANDSHAKE = 0,
@ -76,12 +75,6 @@ enum
MAX_QUEUE_SIZE = ( 100 ),
/* (fast peers) max number of pieces we fast-allow to another peer */
MAX_FAST_ALLOWED_COUNT = 10,
/* (fast peers) max threshold for allowing fast-pieces requests */
MAX_FAST_ALLOWED_THRESHOLD = 10,
/* how long an unsent request can stay queued before it's returned
back to the peer-mgr's pool of requests */
QUEUED_REQUEST_TTL_SECS = 20,
@ -288,7 +281,6 @@ struct tr_peermsgs
struct evbuffer * outMessages; /* all the non-piece messages */
struct request_list peerAskedFor;
struct request_list peerAskedForFast;
struct request_list clientAskedFor;
struct request_list clientWillAskFor;
@ -599,7 +591,7 @@ updateInterest( tr_peermsgs * msgs )
}
static void
cancelAllRequestsToClientExceptFast( tr_peermsgs * msgs )
cancelAllRequestsToClient( tr_peermsgs * msgs )
{
reqListClear( &msgs->peerAskedFor );
}
@ -624,7 +616,7 @@ tr_peerMsgsSetChoke( tr_peermsgs * msgs,
{
msgs->info->peerIsChoked = choke;
if( choke )
cancelAllRequestsToClientExceptFast( msgs );
cancelAllRequestsToClient( msgs );
protocolSendChoke( msgs, choke );
msgs->info->chokeChangedAt = now;
}
@ -644,121 +636,6 @@ tr_peerMsgsHave( tr_peermsgs * msgs,
updateInterest( msgs );
}
#if 0
static void
sendFastSuggest( tr_peermsgs * msgs,
uint32_t pieceIndex )
{
assert( msgs );
if( tr_peerIoSupportsFEXT( msgs->io ) )
{
tr_peerIoWriteUint32( msgs->io, msgs->outMessages,
sizeof( uint8_t ) + sizeof( uint32_t ) );
tr_peerIoWriteUint8( msgs->io, msgs->outMessages, BT_SUGGEST );
tr_peerIoWriteUint32( msgs->io, msgs->outMessages, pieceIndex );
}
}
static void
sendFastHave( tr_peermsgs * msgs,
int all )
{
assert( msgs );
if( tr_peerIoSupportsFEXT( msgs->io ) )
{
tr_peerIoWriteUint32( msgs->io, msgs->outMessages, sizeof( uint8_t ) );
tr_peerIoWriteUint8( msgs->io, msgs->outMessages,
( all ? BT_HAVE_ALL
: BT_HAVE_NONE ) );
updateInterest( msgs );
}
}
#endif
static void
sendFastReject( tr_peermsgs * msgs,
uint32_t pieceIndex,
uint32_t offset,
uint32_t length )
{
assert( msgs );
if( tr_peerIoSupportsFEXT( msgs->io ) )
{
struct evbuffer * out = msgs->outMessages;
const uint32_t len = sizeof( uint8_t ) + 3 * sizeof( uint32_t );
dbgmsg( msgs, "sending fast reject %u:%u->%u", pieceIndex, offset,
length );
tr_peerIoWriteUint32( msgs->io, out, len );
tr_peerIoWriteUint8( msgs->io, out, BT_REJECT );
tr_peerIoWriteUint32( msgs->io, out, pieceIndex );
tr_peerIoWriteUint32( msgs->io, out, offset );
tr_peerIoWriteUint32( msgs->io, out, length );
pokeBatchPeriod( msgs, LOW_PRIORITY_INTERVAL_SECS );
dbgmsg( msgs, "outMessage size is now %d",
(int)EVBUFFER_LENGTH( out ) );
}
}
static tr_bitfield*
getPeerAllowedPieces( tr_peermsgs * msgs )
{
if( !msgs->peerAllowedPieces && tr_peerIoSupportsFEXT( msgs->io ) )
{
msgs->peerAllowedPieces = tr_peerMgrGenerateAllowedSet(
MAX_FAST_ALLOWED_COUNT,
msgs->torrent->info.pieceCount,
msgs->torrent->info.hash,
tr_peerIoGetAddress( msgs->io, NULL ) );
}
return msgs->peerAllowedPieces;
}
static void
sendFastAllowed( tr_peermsgs * msgs,
uint32_t pieceIndex )
{
assert( msgs );
if( tr_peerIoSupportsFEXT( msgs->io ) )
{
struct evbuffer * out = msgs->outMessages;
dbgmsg( msgs, "sending fast allowed" );
tr_peerIoWriteUint32( msgs->io, out, sizeof( uint8_t ) +
sizeof( uint32_t ) );
tr_peerIoWriteUint8( msgs->io, out, BT_ALLOWED_FAST );
tr_peerIoWriteUint32( msgs->io, out, pieceIndex );
pokeBatchPeriod( msgs, LOW_PRIORITY_INTERVAL_SECS );
dbgmsg( msgs, "outMessage size is now %d",
(int)EVBUFFER_LENGTH( out ) );
}
}
static void
sendFastAllowedSet( tr_peermsgs * msgs )
{
tr_piece_index_t i = 0;
while( i <= msgs->torrent->info.pieceCount )
{
if( tr_bitfieldHas( getPeerAllowedPieces( msgs ), i ) )
sendFastAllowed( msgs, i );
i++;
}
}
static void
maybeSendFastAllowedSet( tr_peermsgs * msgs )
{
if( tr_bitfieldCountTrueBits( msgs->info->have ) <=
MAX_FAST_ALLOWED_THRESHOLD )
sendFastAllowedSet( msgs );
}
/**
***
**/
@ -1207,24 +1084,6 @@ updatePeerProgress( tr_peermsgs * msgs )
firePeerProgress( msgs );
}
static int
clientCanSendFastBlock( const tr_peermsgs * msgs UNUSED )
{
/* don't send a fast piece if peer has MAX_FAST_ALLOWED_THRESHOLD pieces */
if( tr_bitfieldCountTrueBits( msgs->info->have ) >
MAX_FAST_ALLOWED_THRESHOLD )
return FALSE;
/* ...or if we don't have ourself enough pieces */
if( tr_bitfieldCountTrueBits( tr_cpPieceBitfield( msgs->torrent->
completion ) ) <
MAX_FAST_ALLOWED_THRESHOLD )
return FALSE;
/* Maybe a bandwidth limit ? */
return TRUE;
}
static void
peerMadeRequest( tr_peermsgs * msgs,
const struct peer_request * req )
@ -1233,36 +1092,22 @@ peerMadeRequest( tr_peermsgs * msgs,
const int clientHasPiece = reqIsValid && tr_cpPieceIsComplete(
msgs->torrent->completion, req->index );
const int peerIsChoked = msgs->info->peerIsChoked;
const int peerIsFast = tr_peerIoSupportsFEXT( msgs->io );
const int pieceIsFast = reqIsValid && tr_bitfieldHas(
getPeerAllowedPieces( msgs ), req->index );
const int canSendFast = clientCanSendFastBlock( msgs );
if( !reqIsValid ) /* bad request */
{
dbgmsg( msgs, "rejecting an invalid request." );
sendFastReject( msgs, req->index, req->offset, req->length );
}
else if( !clientHasPiece ) /* we don't have it */
{
dbgmsg( msgs, "rejecting request for a piece we don't have." );
sendFastReject( msgs, req->index, req->offset, req->length );
}
else if( peerIsChoked && !peerIsFast ) /* doesn't he know he's choked? */
else if( peerIsChoked ) /* doesn't he know he's choked? */
{
tr_peerMsgsSetChoke( msgs, 1 );
sendFastReject( msgs, req->index, req->offset, req->length );
}
else if( peerIsChoked && peerIsFast && ( !pieceIsFast || !canSendFast ) )
{
sendFastReject( msgs, req->index, req->offset, req->length );
}
else /* YAY */
{
if( peerIsFast && pieceIsFast )
reqListAppend( &msgs->peerAskedForFast, req );
else
reqListAppend( &msgs->peerAskedFor, req );
reqListAppend( &msgs->peerAskedFor, req );
}
}
@ -1283,8 +1128,6 @@ messageLengthIsCorrect( const tr_peermsgs * msg,
case BT_HAVE:
case BT_SUGGEST:
case BT_ALLOWED_FAST:
return len == 5;
case BT_BITFIELD:
return len == ( msg->torrent->info.pieceCount + 7u ) / 8u + 1u;
@ -1409,7 +1252,7 @@ readBtMessage( tr_peermsgs * msgs,
dbgmsg( msgs, "got Choke" );
msgs->info->clientIsChoked = 1;
cancelAllRequestsToPeer( msgs );
cancelAllRequestsToClientExceptFast( msgs );
cancelAllRequestsToClient( msgs );
break;
case BT_UNCHOKE:
@ -1445,7 +1288,6 @@ readBtMessage( tr_peermsgs * msgs,
tr_peerIoReadBytes( msgs->io, inbuf, msgs->info->have->bits,
msglen );
updatePeerProgress( msgs );
maybeSendFastAllowedSet( msgs );
fireNeedReq( msgs );
break;
}
@ -1470,7 +1312,6 @@ readBtMessage( tr_peermsgs * msgs,
tr_peerIoReadUint32( msgs->io, inbuf, &r.length );
dbgmsg( msgs, "got a Cancel %u:%u->%u", r.index, r.offset,
r.length );
reqListRemove( &msgs->peerAskedForFast, &r );
reqListRemove( &msgs->peerAskedFor, &r );
break;
}
@ -1497,7 +1338,6 @@ readBtMessage( tr_peermsgs * msgs,
tr_bitfieldAddRange( msgs->info->have, 0,
msgs->torrent->info.pieceCount );
updatePeerProgress( msgs );
maybeSendFastAllowedSet( msgs );
break;
@ -1505,7 +1345,6 @@ readBtMessage( tr_peermsgs * msgs,
dbgmsg( msgs, "Got a BT_HAVE_NONE" );
tr_bitfieldClear( msgs->info->have );
updatePeerProgress( msgs );
maybeSendFastAllowedSet( msgs );
break;
case BT_REJECT:
@ -1519,14 +1358,6 @@ readBtMessage( tr_peermsgs * msgs,
break;
}
case BT_ALLOWED_FAST:
{
dbgmsg( msgs, "Got a BT_ALLOWED_FAST" );
tr_peerIoReadUint32( msgs->io, inbuf, &ui32 );
/* we don't do anything with this yet */
break;
}
case BT_LTEP:
dbgmsg( msgs, "Got a BT_LTEP" );
parseLtep( msgs, msglen, inbuf );
@ -1702,8 +1533,7 @@ static int
popNextRequest( tr_peermsgs * msgs,
struct peer_request * setme )
{
return reqListPop( &msgs->peerAskedForFast, setme )
|| reqListPop( &msgs->peerAskedFor, setme );
return reqListPop( &msgs->peerAskedFor, setme );
}
static size_t
@ -2065,7 +1895,6 @@ tr_peerMsgsNew( struct tr_torrent * torrent,
m->incoming.block = evbuffer_new( );
m->peerAllowedPieces = NULL;
m->peerAskedFor = REQUEST_LIST_INIT;
m->peerAskedForFast = REQUEST_LIST_INIT;
m->clientAskedFor = REQUEST_LIST_INIT;
m->clientWillAskFor = REQUEST_LIST_INIT;
*setme = tr_publisherSubscribe( m->publisher, func, userData );
@ -2092,8 +1921,7 @@ tr_peerMsgsFree( tr_peermsgs* msgs )
tr_publisherFree( &msgs->publisher );
reqListClear( &msgs->clientWillAskFor );
reqListClear( &msgs->clientAskedFor );
reqListClear( &msgs->peerAskedForFast );
reqListClear( &msgs->peerAskedFor );
tr_bitfieldFree( msgs->peerAllowedPieces );
evbuffer_free( msgs->incoming.block );
evbuffer_free( msgs->outMessages );

View File

@ -1,59 +0,0 @@
#include <stdio.h>
#include "transmission.h"
#include "net.h"
#include "peer-mgr.h"
#include "utils.h"
#define VERBOSE 0
#define check( A ) \
{ \
++test; \
if( A ){ \
if( VERBOSE ) \
fprintf( stderr, "PASS test #%d (%s, %d)\n", test, __FILE__,\
__LINE__ );\
} else { \
if( VERBOSE ) \
fprintf( stderr, "FAIL test #%d (%s, %d)\n", test, __FILE__,\
__LINE__ );\
return test; \
} \
}
int
main( void )
{
uint32_t i;
int test = 0;
tr_bitfield * bitfield;
uint8_t infohash[SHA_DIGEST_LENGTH];
struct in_addr addr;
uint32_t sz;
uint32_t k;
tr_piece_index_t pieces[] =
{ 1059, 431, 808, 1217, 287, 376, 1188, 353, 508 };
for( i = 0; i < SHA_DIGEST_LENGTH; ++i )
infohash[i] = 0xaa;
tr_netResolve( "80.4.4.200", &addr );
sz = 1313;
k = 7;
bitfield = tr_peerMgrGenerateAllowedSet( k, sz, infohash, &addr );
check( tr_bitfieldCountTrueBits( bitfield ) == k );
for( i = 0; i < k; ++i )
check( tr_bitfieldHas( bitfield, pieces[i] ) );
tr_bitfieldFree( bitfield );
k = 9;
bitfield = tr_peerMgrGenerateAllowedSet( k, sz, infohash, &addr );
check( tr_bitfieldCountTrueBits( bitfield ) == k );
for( i = 0; i < k; ++i )
check( tr_bitfieldHas( bitfield, pieces[i] ) );
tr_bitfieldFree( bitfield );
return 0;
}