(trunk libT) #2575: PEX is not meant to do forwarding

This commit is contained in:
Charles Kerr 2009-11-20 07:47:31 +00:00
parent 9383a6abfd
commit 22f7a64aa2
4 changed files with 75 additions and 35 deletions

View File

@ -1775,46 +1775,79 @@ compareAtomsByUsefulness( const void * va, const void *vb )
}
int
tr_peerMgrGetPeers( tr_torrent * tor, tr_pex ** setme_pex, uint8_t af, int maxPeerCount )
tr_peerMgrGetPeers( tr_torrent * tor,
tr_pex ** setme_pex,
uint8_t af,
uint8_t list_mode,
int maxCount )
{
int i;
int n;
int count = 0;
int atomCount = 0;
const Torrent * t = tor->torrentPeers;
struct peer_atom ** atoms = NULL;
tr_pex * pex;
tr_pex * walk;
assert( tr_isTorrent( tor ) );
assert( setme_pex != NULL );
assert( setme_pex != NULL );
assert( af==TR_AF_INET || af==TR_AF_INET6 );
assert( list_mode==TR_PEERS_CONNECTED || list_mode==TR_PEERS_ALL );
managerLock( t->manager );
/**
*** build a list of atoms
**/
if( list_mode == TR_PEERS_CONNECTED ) /* connected peers only */
{
int i;
const int atomCount = tr_ptrArraySize( &t->pool );
const int pexCount = MIN( atomCount, maxPeerCount );
const tr_peer ** peers = (const tr_peer **) tr_ptrArrayBase( &t->peers );
atomCount = tr_ptrArraySize( &t->peers );
atoms = tr_new( struct peer_atom *, atomCount );
for( i=0; i<atomCount; ++i )
atoms[i] = peers[i]->atom;
}
else /* TR_PEERS_ALL */
{
const struct peer_atom ** atomsBase = (const struct peer_atom**) tr_ptrArrayBase( &t->pool );
struct peer_atom ** atoms = tr_memdup( atomsBase, atomCount * sizeof( struct peer_atom * ) );
/* for now, this will waste memory on torrents that have both
* ipv6 and ipv4 peers */
tr_pex * pex = tr_new0( tr_pex, atomCount );
tr_pex * walk = pex;
qsort( atoms, atomCount, sizeof( struct peer_atom * ), compareAtomsByUsefulness );
for( i=0; i<atomCount && count<pexCount; ++i )
{
const struct peer_atom * atom = atoms[i];
if( atom->addr.type == af )
{
assert( tr_isAddress( &atom->addr ) );
walk->addr = atom->addr;
walk->port = atom->port;
walk->flags = atom->flags;
++count;
++walk;
}
}
assert( ( walk - pex ) == count );
*setme_pex = pex;
tr_free( atoms );
atomCount = tr_ptrArraySize( &t->pool );
atoms = tr_memdup( atomsBase, atomCount * sizeof( struct peer_atom * ) );
}
qsort( atoms, atomCount, sizeof( struct peer_atom * ), compareAtomsByUsefulness );
/**
*** add the first N of them into our return list
**/
n = MIN( atomCount, maxCount );
pex = walk = tr_new0( tr_pex, n );
for( i=0; i<atomCount && count<n; ++i )
{
const struct peer_atom * atom = atoms[i];
if( atom->addr.type == af )
{
assert( tr_isAddress( &atom->addr ) );
walk->addr = atom->addr;
walk->port = atom->port;
walk->flags = atom->flags;
++count;
++walk;
}
}
qsort( pex, count, sizeof( tr_pex ), tr_pexCompare );
assert( ( walk - pex ) == count );
*setme_pex = pex;
/* cleanup */
tr_free( atoms );
managerUnlock( t->manager );
return count;
}

View File

@ -160,10 +160,17 @@ void tr_peerMgrSetBlame( tr_torrent * tor,
tr_piece_index_t pieceIndex,
int success );
enum
{
TR_PEERS_CONNECTED,
TR_PEERS_ALL
};
int tr_peerMgrGetPeers( tr_torrent * tor,
tr_pex ** setme_pex,
uint8_t af,
int maxPeerCount );
uint8_t address_type,
uint8_t peer_list_mode,
int max_peer_count );
void tr_peerMgrStartTorrent( tr_torrent * tor );

View File

@ -1917,8 +1917,8 @@ sendPex( tr_peermsgs * msgs )
PexDiffs diffs6;
tr_pex * newPex = NULL;
tr_pex * newPex6 = NULL;
const int newCount = tr_peerMgrGetPeers( msgs->torrent, &newPex, TR_AF_INET, MAX_PEX_PEER_COUNT );
const int newCount6 = tr_peerMgrGetPeers( msgs->torrent, &newPex6, TR_AF_INET6, MAX_PEX_PEER_COUNT );
const int newCount = tr_peerMgrGetPeers( msgs->torrent, &newPex, TR_AF_INET, TR_PEERS_CONNECTED, MAX_PEX_PEER_COUNT );
const int newCount6 = tr_peerMgrGetPeers( msgs->torrent, &newPex6, TR_AF_INET6, TR_PEERS_CONNECTED, MAX_PEX_PEER_COUNT );
/* build the diffs */
diffs.added = tr_new( tr_pex, newCount );

View File

@ -83,12 +83,12 @@ savePeers( tr_benc * dict, const tr_torrent * tor )
int count;
tr_pex * pex;
count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET, MAX_REMEMBERED_PEERS );
count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET, TR_PEERS_ALL, MAX_REMEMBERED_PEERS );
if( count > 0 )
tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof( tr_pex ) * count );
tr_free( pex );
count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET6, MAX_REMEMBERED_PEERS );
count = tr_peerMgrGetPeers( (tr_torrent*) tor, &pex, TR_AF_INET6, TR_PEERS_ALL, MAX_REMEMBERED_PEERS );
if( count > 0 )
tr_bencDictAddRaw( dict, KEY_PEERS6, pex, sizeof( tr_pex ) * count );