1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-25 01:03:01 +00:00

(trunk libT) #3933 "announcer.c peer parsing could be simpler" -- fixed.

Remove redundant code by using tr_peerMgrCompactToPex() and tr_peerMgrCompact6ToPex() to parse compact ipv4 and ipv6 peer lists. Simplify the old-style benc peer list parsing and fix a bug that returned too few bytes in the old-style peer array.
This commit is contained in:
Jordan Lee 2011-01-22 17:45:54 +00:00
parent 68130d9c4e
commit 75ffe999d4
3 changed files with 72 additions and 116 deletions

View file

@ -21,6 +21,7 @@
#include "announcer.h" #include "announcer.h"
#include "crypto.h" #include "crypto.h"
#include "net.h" #include "net.h"
#include "peer-mgr.h" /* tr_peerMgrCompactToPex() */
#include "ptrarray.h" #include "ptrarray.h"
#include "session.h" #include "session.h"
#include "tr-dht.h" #include "tr-dht.h"
@ -631,87 +632,82 @@ getSeedProbability( int seeds, int leechers )
return -1; /* unknown */ return -1; /* unknown */
} }
static int static void
publishNewPeers( tr_tier * tier, int seeds, int leechers, publishPeersPex( tr_tier * tier, int seeds, int leechers,
const void * compact, int compactLen ) const tr_pex * pex, int n )
{ {
tr_tracker_event e = emptyEvent; tr_tracker_event e = emptyEvent;
e.messageType = TR_TRACKER_PEERS; e.messageType = TR_TRACKER_PEERS;
e.seedProbability = getSeedProbability( seeds, leechers ); e.seedProbability = getSeedProbability( seeds, leechers );
e.compact = compact; e.pex = pex;
e.compactLen = compactLen; e.pexCount = n;
if( tier->tor->tiers->callback != NULL ) if( tier->tor->tiers->callback != NULL )
tier->tor->tiers->callback( tier->tor, &e, NULL ); tier->tor->tiers->callback( tier->tor, &e, NULL );
return compactLen / 6;
} }
static int static size_t
publishNewPeersCompact( tr_tier * tier, int seeds, int leechers, publishPeersCompact( tr_tier * tier, int seeds, int leechers,
const void * compact, int compactLen ) const void * compact, int compactLen )
{ {
int i; size_t n = 0;
const uint8_t *compactWalk; tr_pex * pex = tr_peerMgrCompactToPex( compact, compactLen, NULL, 0, &n );
uint8_t *array, *walk; publishPeersPex( tier, seeds, leechers, pex, n );
const int peerCount = compactLen / 6; dbgmsg( tier, "got IPv4 list of %zu peers", n );
const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 ); tr_free( pex );
tr_address addr; return n;
tr_port port; }
addr.type = TR_AF_INET; static size_t
memset( &addr.addr, 0, sizeof( addr.addr ) ); publishPeersCompact6( tr_tier * tier, int seeds, int leechers,
array = tr_new( uint8_t, arrayLen );
for ( i=0, walk=array, compactWalk=compact ; i<peerCount ; ++i )
{
memcpy( &addr.addr.addr4, compactWalk, 4 );
memcpy( &port, compactWalk + 4, 2 );
memcpy( walk, &addr, sizeof( addr ) );
memcpy( walk + sizeof( addr ), &port, 2 );
walk += sizeof( tr_address ) + 2;
compactWalk += 6;
}
publishNewPeers( tier, seeds, leechers, array, arrayLen );
tr_free( array );
return peerCount;
}
static int
publishNewPeersCompact6( tr_tier * tier, int seeds, int leechers,
const void * compact, int compactLen ) const void * compact, int compactLen )
{ {
int i; size_t n = 0;
const uint8_t *compactWalk; tr_pex * pex = tr_peerMgrCompact6ToPex( compact, compactLen, NULL, 0, &n );
uint8_t *array, *walk; dbgmsg( tier, "got IPv6 list of %zu peers", n );
const int peerCount = compactLen / 18; publishPeersPex( tier, seeds, leechers, pex, n );
const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 ); tr_free( pex );
tr_address addr; return n;
tr_port port; }
addr.type = TR_AF_INET6; static size_t
memset( &addr.addr, 0, sizeof( addr.addr ) ); publishPeersDict( tr_tier * tier, int seeds, int leechers, tr_benc * peerList )
array = tr_new( uint8_t, arrayLen ); {
for ( i = 0, walk = array, compactWalk = compact ; i < peerCount ; ++i ) size_t i;
size_t n;
const size_t len = tr_bencListSize( peerList );
tr_pex * pex = tr_new0( tr_pex, len );
for( i=n=0; i<len; ++i )
{ {
memcpy( &addr.addr.addr6, compactWalk, 16 ); int64_t port;
memcpy( &port, compactWalk + 16, 2 ); const char * ip;
compactWalk += 18; tr_address addr;
tr_benc * peer = tr_bencListChild( peerList, i );
memcpy( walk, &addr, sizeof( addr ) ); if( peer == NULL )
memcpy( walk + sizeof( addr ), &port, 2 ); continue;
walk += sizeof( tr_address ) + 2; if( !tr_bencDictFindStr( peer, "ip", &ip ) )
continue;
if( tr_pton( ip, &addr ) == NULL )
continue;
if( !tr_bencDictFindInt( peer, "port", &port ) )
continue;
if( ( port < 0 ) || ( port > USHRT_MAX ) )
continue;
if( !tr_isValidPeerAddress( &addr, port ) )
continue;
pex[n].addr = addr;
pex[n].port = htons( (uint16_t)port );
++n;
} }
publishNewPeers( tier, seeds, leechers, array, arrayLen ); dbgmsg( tier, "got benc list of %zu peers", n );
tr_free( array ); publishPeersPex( tier, seeds, leechers, pex, n );
tr_free( pex );
return peerCount; return n;
} }
static char* static char*
@ -1163,43 +1159,6 @@ compareTiers( const void * va, const void * vb )
return ret; return ret;
} }
static uint8_t *
parseOldPeers( tr_benc * bePeers, size_t * byteCount )
{
int i;
uint8_t * array, *walk;
const int peerCount = bePeers->val.l.count;
assert( tr_bencIsList( bePeers ) );
array = tr_new( uint8_t, peerCount * ( sizeof( tr_address ) + 2 ) );
for( i = 0, walk = array; i < peerCount; ++i )
{
const char * s;
int64_t itmp;
tr_address addr;
tr_port port;
tr_benc * peer = &bePeers->val.l.vals[i];
if( tr_bencDictFindStr( peer, "ip", &s ) )
if( tr_pton( s, &addr ) == NULL )
continue;
if( !tr_bencDictFindInt( peer, "port", &itmp )
|| itmp < 0
|| itmp > USHRT_MAX )
continue;
memcpy( walk, &addr, sizeof( tr_address ) );
port = htons( (uint16_t)itmp );
memcpy( walk + sizeof( tr_address ), &port, 2 );
walk += sizeof( tr_address ) + 2;
}
*byteCount = peerCount * sizeof( tr_address ) + 2;
return array;
}
static tr_bool static tr_bool
parseAnnounceResponse( tr_tier * tier, parseAnnounceResponse( tr_tier * tier,
@ -1292,7 +1251,7 @@ parseAnnounceResponse( tr_tier * tier,
/* "compact" extension */ /* "compact" extension */
const int seeders = tier->currentTracker->seederCount; const int seeders = tier->currentTracker->seederCount;
const int leechers = tier->currentTracker->leecherCount; const int leechers = tier->currentTracker->leecherCount;
peerCount += publishNewPeersCompact( tier, seeders, leechers, raw, rawlen ); peerCount += publishPeersCompact( tier, seeders, leechers, raw, rawlen );
gotPeers = TRUE; gotPeers = TRUE;
} }
else if( tr_bencDictFindList( &benc, "peers", &tmp ) ) else if( tr_bencDictFindList( &benc, "peers", &tmp ) )
@ -1300,11 +1259,8 @@ parseAnnounceResponse( tr_tier * tier,
/* original version of peers */ /* original version of peers */
const int seeders = tier->currentTracker->seederCount; const int seeders = tier->currentTracker->seederCount;
const int leechers = tier->currentTracker->leecherCount; const int leechers = tier->currentTracker->leecherCount;
size_t byteCount = 0; peerCount += publishPeersDict( tier, seeders, leechers, tmp );
uint8_t * array = parseOldPeers( tmp, &byteCount );
peerCount += publishNewPeers( tier, seeders, leechers, array, byteCount );
gotPeers = TRUE; gotPeers = TRUE;
tr_free( array );
} }
if( tr_bencDictFindRaw( &benc, "peers6", &raw, &rawlen ) ) if( tr_bencDictFindRaw( &benc, "peers6", &raw, &rawlen ) )
@ -1312,7 +1268,7 @@ parseAnnounceResponse( tr_tier * tier,
/* "compact" extension */ /* "compact" extension */
const int seeders = tier->currentTracker->seederCount; const int seeders = tier->currentTracker->seederCount;
const int leechers = tier->currentTracker->leecherCount; const int leechers = tier->currentTracker->leecherCount;
peerCount += publishNewPeersCompact6( tier, seeders, leechers, raw, rawlen ); peerCount += publishPeersCompact6( tier, seeders, leechers, raw, rawlen );
gotPeers = TRUE; gotPeers = TRUE;
} }

View file

@ -35,6 +35,8 @@ typedef enum
} }
TrackerEventType; TrackerEventType;
struct tr_pex;
/** @brief Notification object to tell listeners about announce or scrape occurences */ /** @brief Notification object to tell listeners about announce or scrape occurences */
typedef struct typedef struct
{ {
@ -46,8 +48,8 @@ typedef struct
const char * tracker; const char * tracker;
/* for TR_TRACKER_PEERS */ /* for TR_TRACKER_PEERS */
const uint8_t * compact; const struct tr_pex * pex;
int compactLen; size_t pexCount;
/* [0...100] for probability a peer is a seed. calculated by the leecher/seeder ratio */ /* [0...100] for probability a peer is a seed. calculated by the leecher/seeder ratio */
int8_t seedProbability; int8_t seedProbability;

View file

@ -493,23 +493,21 @@ onTrackerResponse( tr_torrent * tor, const tr_tracker_event * event, void * unus
{ {
case TR_TRACKER_PEERS: case TR_TRACKER_PEERS:
{ {
size_t i, n; size_t i;
const int8_t seedProbability = event->seedProbability; const int8_t seedProbability = event->seedProbability;
const tr_bool allAreSeeds = seedProbability == 100; const tr_bool allAreSeeds = seedProbability == 100;
tr_pex * pex = tr_peerMgrArrayToPex( event->compact,
event->compactLen, &n );
if( allAreSeeds )
tr_tordbg( tor, "Got %d seeds from tracker", (int)n );
else
tr_tordbg( tor, "Got %d peers from tracker", (int)n );
for( i = 0; i < n; ++i ) if( allAreSeeds )
tr_peerMgrAddPex( tor, TR_PEER_FROM_TRACKER, pex+i, seedProbability ); tr_tordbg( tor, "Got %zu seeds from tracker", event->pexCount );
else
tr_tordbg( tor, "Got %zu peers from tracker", event->pexCount );
for( i = 0; i < event->pexCount; ++i )
tr_peerMgrAddPex( tor, TR_PEER_FROM_TRACKER, &event->pex[i], seedProbability );
if( allAreSeeds && tr_torrentIsPrivate( tor ) ) if( allAreSeeds && tr_torrentIsPrivate( tor ) )
tr_peerMgrMarkAllAsSeeds( tor ); tr_peerMgrMarkAllAsSeeds( tor );
tr_free( pex );
break; break;
} }