#890: be smarter about noticing seeds from tracker & pex

This commit is contained in:
Charles Kerr 2008-04-19 15:07:59 +00:00
parent 1ae1607025
commit 08b27749ba
6 changed files with 83 additions and 78 deletions

View File

@ -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 && i<peerCount; ++i )
{
struct in_addr addr;
uint16_t port;
memcpy( &addr, walk, 4 ); walk += 4;
memcpy( &port, walk, 2 ); walk += 2;
maybeEnsureAtomExists( t, &addr, port, 0, from );
size_t i;
size_t n = compactLen / 6;
const uint8_t * walk = compact;
tr_pex * pex = tr_new0( tr_pex, n );
for( i=0; i<n; ++i ) {
memcpy( &pex[i].in_addr, walk, 4 ); walk += 4;
memcpy( &pex[i].port, walk, 2 ); walk += 2;
if( added_f )
pex[i].flags = added_f[i];
}
managerUnlock( manager );
*pexCount = n;
return pex;
}
/**

View File

@ -27,6 +27,15 @@ struct tr_peer_stat;
struct tr_torrent;
typedef struct tr_peerMgr tr_peerMgr;
enum
{
/* 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,
};
typedef struct tr_pex
{
struct in_addr in_addr;
@ -50,12 +59,11 @@ void tr_peerMgrAddIncoming( tr_peerMgr * manager,
uint16_t port,
int socket );
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 );
void tr_peerMgrAddPex( tr_peerMgr * manager,
const uint8_t * torrentHash,
uint8_t from,

View File

@ -941,21 +941,23 @@ parseUtPex( tr_peermsgs * msgs, int msglen, struct evbuffer * inbuf )
{
int loaded = 0;
uint8_t * tmp = tr_new( uint8_t, msglen );
tr_benc val, *sub;
tr_benc val, *added;
const tr_torrent * tor = msgs->torrent;
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; i<n; ++i )
tr_peerMgrAddPex( msgs->handle->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; i<diffs.addedCount; ++i )
*walk++ = diffs.added[i].flags;
assert( ( walk - tmp ) == diffs.addedCount );
tr_bencInitStr( flags, tmp, walk-tmp, FALSE );
tr_bencDictAddRaw( &val, "added.f", tmp, walk-tmp );
/* "dropped" */
dropped = tr_bencDictAdd( &val, "dropped" );

View File

@ -152,13 +152,26 @@ onTrackerResponse( void * tracker UNUSED, void * vevent, void * user_data )
switch( event->messageType )
{
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; i<n; ++i ) {
if( event->allAreSeeds )
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 );

View File

@ -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 );
}
}

View File

@ -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;