From 08b27749ba96f5d39f8be60f3f14c48596609d53 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 19 Apr 2008 15:07:59 +0000 Subject: [PATCH] #890: be smarter about noticing seeds from tracker & pex --- libtransmission/peer-mgr.c | 44 ++++++++++++++----------------------- libtransmission/peer-mgr.h | 20 ++++++++++++----- libtransmission/peer-msgs.c | 25 +++++++++++---------- libtransmission/torrent.c | 25 ++++++++++++++++----- libtransmission/tracker.c | 42 +++++++++++++++-------------------- libtransmission/tracker.h | 5 +++-- 6 files changed, 83 insertions(+), 78 deletions(-) diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 1020f5aed..e3126448a 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -98,12 +98,6 @@ enum /* number of unchoked peers per torrent */ MAX_UNCHOKED_PEERS = 12, - /* corresponds to ut_pex's added.f flags */ - ADDED_F_ENCRYPTION_FLAG = 1, - - /* corresponds to ut_pex's added.f flags */ - ADDED_F_SEED_FLAG = 2, - /* number of bad pieces a peer is allowed to send before we ban them */ MAX_BAD_PIECES_PER_PEER = 3, @@ -1168,30 +1162,24 @@ tr_peerMgrAddPex( tr_peerMgr * manager, managerUnlock( manager ); } -void -tr_peerMgrAddPeers( tr_peerMgr * manager, - const uint8_t * torrentHash, - uint8_t from, - const uint8_t * peerCompact, - int peerCount ) +tr_pex * +tr_peerMgrCompactToPex( const void * compact, + size_t compactLen, + const char * added_f, + size_t * pexCount ) { - int i; - const uint8_t * walk = peerCompact; - Torrent * t; - - managerLock( manager ); - - t = getExistingTorrent( manager, torrentHash ); - for( i=0; t!=NULL && itorrent; tr_peerIoReadBytes( msgs->io, inbuf, tmp, msglen ); if( tr_torrentAllowsPex( tor ) && (( loaded = !tr_bencLoad( tmp, msglen, &val, NULL ))) - && (( sub = tr_bencDictFindType( &val, "added", TYPE_STR )))) + && (( added = tr_bencDictFindType( &val, "added", TYPE_STR )))) { - const int n = sub->val.s.i / 6 ; - if( n ) - tr_tordbg( tor, "Got %d peers from peer exchange", n ); - tr_peerMgrAddPeers( msgs->handle->peerMgr, - tor->info.hash, - TR_PEER_FROM_PEX, - (uint8_t*)sub->val.s.s, n ); + const char * added_f = NULL; + tr_pex * pex; + size_t i, n; + tr_bencDictFindStr( &val, "added.f", &added_f ); + pex = tr_peerMgrCompactToPex( added->val.s.s, added->val.s.i, added_f, &n ); + for( i=0; ihandle->peerMgr, tor->info.hash, + TR_PEER_FROM_PEX, pex+i ); + tr_free( pex ); } if( loaded ) @@ -1797,7 +1799,7 @@ sendPex( tr_peermsgs * msgs ) tr_pex * newPex = NULL; const int newCount = tr_peerMgrGetPeers( msgs->handle->peerMgr, msgs->torrent->info.hash, &newPex ); PexDiffs diffs; - tr_benc val, *added, *dropped, *flags; + tr_benc val, *added, *dropped; uint8_t *tmp, *walk; char * benc; int bencLen; @@ -1834,12 +1836,11 @@ sendPex( tr_peermsgs * msgs ) tr_bencInitStr( added, tmp, walk-tmp, FALSE ); /* "added.f" */ - flags = tr_bencDictAdd( &val, "added.f" ); tmp = walk = tr_new( uint8_t, diffs.addedCount ); for( i=0; imessageType ) { - case TR_TRACKER_PEERS: - tr_peerMgrAddPeers( tor->handle->peerMgr, - tor->info.hash, - TR_PEER_FROM_TRACKER, - event->peerCompact, - event->peerCount ); + case TR_TRACKER_PEERS: { + size_t i, n; + tr_pex * pex = tr_peerMgrCompactToPex( event->compact, + event->compactLen, + NULL, &n ); + if( event->allAreSeeds ) + tr_tordbg( tor, "Got %d seeds from tracker", (int)n ); + else + tr_torinf( tor, _( "Got %d peers from tracker" ), (int)n ); + + for( i=0; iallAreSeeds ) + pex[i].flags |= ADDED_F_SEED_FLAG; + tr_peerMgrAddPex( tor->handle->peerMgr, tor->info.hash, + TR_PEER_FROM_TRACKER, pex+i ); + } + + tr_free( pex ); break; + } case TR_TRACKER_WARNING: tr_torerr( tor, _( "Tracker warning: \"%s\"" ), event->text ); diff --git a/libtransmission/tracker.c b/libtransmission/tracker.c index 13e0ade04..5169578be 100644 --- a/libtransmission/tracker.c +++ b/libtransmission/tracker.c @@ -221,7 +221,7 @@ findTracker( tr_handle * handle, const uint8_t * hash ) **** PUBLISH ***/ -static const tr_tracker_event emptyEvent = { 0, NULL, NULL, NULL, 0 }; +static const tr_tracker_event emptyEvent = { 0, NULL, NULL, NULL, 0, 0 }; static void publishMessage( tr_tracker * t, const char * msg, int type ) @@ -256,15 +256,15 @@ publishWarning( tr_tracker * t, const char * msg ) } static void -publishNewPeers( tr_tracker * t, int count, uint8_t * peers ) +publishNewPeers( tr_tracker * t, int allAreSeeds, void * compact, int compactLen ) { tr_tracker_event event = emptyEvent; event.hash = t->hash; event.messageType = TR_TRACKER_PEERS; - event.peerCount = count; - event.peerCompact = peers; - tr_ndbg( t->name, "Torrent got %d new peers", count ); - if( count ) + event.allAreSeeds = allAreSeeds; + event.compact = compact; + event.compactLen = compactLen; + if( compactLen ) tr_publisherPublish( t->publisher, t, &event ); } @@ -360,7 +360,7 @@ updateAddresses( tr_tracker * t, const struct evhttp_request * req, int * tryAga /* Convert to compact form */ static uint8_t * -parseOldPeers( tr_benc * bePeers, int * setmePeerCount ) +parseOldPeers( tr_benc * bePeers, size_t * byteCount ) { int i; uint8_t *compact, *walk; @@ -393,7 +393,7 @@ parseOldPeers( tr_benc * bePeers, int * setmePeerCount ) walk += 2; } - *setmePeerCount = peerCount; + *byteCount = peerCount * 6; return compact; } @@ -432,6 +432,7 @@ onTrackerResponse( struct evhttp_request * req, void * vhash ) if( bencLoaded && benc.type==TYPE_DICT ) { tr_benc * tmp; + int incomplete = -1; if(( tmp = tr_bencDictFind( &benc, "failure reason" ))) { dbgmsg( t, "got failure message [%s]", tmp->val.s.s ); @@ -460,30 +461,23 @@ onTrackerResponse( struct evhttp_request * req, void * vhash ) t->seederCount = tmp->val.i; if(( tmp = tr_bencDictFind( &benc, "incomplete" ))) - t->leecherCount = tmp->val.i; + t->leecherCount = incomplete = tmp->val.i; if(( tmp = tr_bencDictFind( &benc, "peers" ))) { - int peerCount = 0; - uint8_t * peerCompact = NULL; + const int allAreSeeds = incomplete == 0; - if( tmp->type == TYPE_LIST ) /* original protocol */ + if( tmp->type == TYPE_STR ) /* "compact" extension */ { - if( tmp->val.l.count > 0 ) - peerCompact = parseOldPeers( tmp, &peerCount ); + publishNewPeers( t, allAreSeeds, tmp->val.s.s, tmp->val.s.i ); } - else if( tmp->type == TYPE_STR ) /* "compact" extension */ + else if( tmp->type == TYPE_LIST ) /* original protocol */ { - if( tmp->val.s.i >= 6 ) - { - peerCount = tmp->val.s.i / 6; - peerCompact = tr_new( uint8_t, tmp->val.s.i ); - memcpy( peerCompact, tmp->val.s.s, tmp->val.s.i ); - } + size_t byteCount = 0; + uint8_t * compact = parseOldPeers( tmp, &byteCount ); + publishNewPeers( t, allAreSeeds, compact, byteCount ); + tr_free( compact ); } - - publishNewPeers( t, peerCount, peerCompact ); - tr_free( peerCompact ); } } diff --git a/libtransmission/tracker.h b/libtransmission/tracker.h index aa8201819..94d1d5025 100644 --- a/libtransmission/tracker.h +++ b/libtransmission/tracker.h @@ -54,8 +54,9 @@ typedef struct const char * text; /* for TR_TRACKER_PEERS */ - const uint8_t * peerCompact; - int peerCount; + const uint8_t * compact; + int compactLen; + int allAreSeeds; } tr_tracker_event;