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:
parent
68130d9c4e
commit
75ffe999d4
3 changed files with 72 additions and 116 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue