#include "announcer.h"
#include "crypto.h"
#include "net.h"
+#include "peer-mgr.h" /* tr_peerMgrCompactToPex() */
#include "ptrarray.h"
#include "session.h"
#include "tr-dht.h"
return -1; /* unknown */
}
-static int
-publishNewPeers( tr_tier * tier, int seeds, int leechers,
- const void * compact, int compactLen )
+static void
+publishPeersPex( tr_tier * tier, int seeds, int leechers,
+ const tr_pex * pex, int n )
{
tr_tracker_event e = emptyEvent;
e.messageType = TR_TRACKER_PEERS;
e.seedProbability = getSeedProbability( seeds, leechers );
- e.compact = compact;
- e.compactLen = compactLen;
+ e.pex = pex;
+ e.pexCount = n;
if( tier->tor->tiers->callback != NULL )
tier->tor->tiers->callback( tier->tor, &e, NULL );
-
- return compactLen / 6;
}
-static int
-publishNewPeersCompact( tr_tier * tier, int seeds, int leechers,
+static size_t
+publishPeersCompact( tr_tier * tier, int seeds, int leechers,
const void * compact, int compactLen )
{
- int i;
- const uint8_t *compactWalk;
- uint8_t *array, *walk;
- const int peerCount = compactLen / 6;
- const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 );
- tr_address addr;
- tr_port port;
-
- addr.type = TR_AF_INET;
- memset( &addr.addr, 0, sizeof( addr.addr ) );
- 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 );
+ size_t n = 0;
+ tr_pex * pex = tr_peerMgrCompactToPex( compact, compactLen, NULL, 0, &n );
+ publishPeersPex( tier, seeds, leechers, pex, n );
+ dbgmsg( tier, "got IPv4 list of %zu peers", n );
+ tr_free( pex );
+ return n;
+}
- tr_free( array );
-
- return peerCount;
+static size_t
+publishPeersCompact6( tr_tier * tier, int seeds, int leechers,
+ const void * compact, int compactLen )
+{
+ size_t n = 0;
+ tr_pex * pex = tr_peerMgrCompact6ToPex( compact, compactLen, NULL, 0, &n );
+ dbgmsg( tier, "got IPv6 list of %zu peers", n );
+ publishPeersPex( tier, seeds, leechers, pex, n );
+ tr_free( pex );
+ return n;
}
-static int
-publishNewPeersCompact6( tr_tier * tier, int seeds, int leechers,
- const void * compact, int compactLen )
+static size_t
+publishPeersDict( tr_tier * tier, int seeds, int leechers, tr_benc * peerList )
{
- int i;
- const uint8_t *compactWalk;
- uint8_t *array, *walk;
- const int peerCount = compactLen / 18;
- const int arrayLen = peerCount * ( sizeof( tr_address ) + 2 );
- tr_address addr;
- tr_port port;
-
- addr.type = TR_AF_INET6;
- memset( &addr.addr, 0, sizeof( addr.addr ) );
- 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 );
- memcpy( &port, compactWalk + 16, 2 );
- compactWalk += 18;
+ int64_t port;
+ const char * ip;
+ tr_address addr;
+ tr_benc * peer = tr_bencListChild( peerList, i );
- memcpy( walk, &addr, sizeof( addr ) );
- memcpy( walk + sizeof( addr ), &port, 2 );
- walk += sizeof( tr_address ) + 2;
- }
+ if( peer == NULL )
+ continue;
+ 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;
- publishNewPeers( tier, seeds, leechers, array, arrayLen );
- tr_free( array );
+ pex[n].addr = addr;
+ pex[n].port = htons( (uint16_t)port );
+ ++n;
+ }
- return peerCount;
+ dbgmsg( tier, "got benc list of %zu peers", n );
+ publishPeersPex( tier, seeds, leechers, pex, n );
+ tr_free( pex );
+ return n;
}
static char*
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
parseAnnounceResponse( tr_tier * tier,
/* "compact" extension */
const int seeders = tier->currentTracker->seederCount;
const int leechers = tier->currentTracker->leecherCount;
- peerCount += publishNewPeersCompact( tier, seeders, leechers, raw, rawlen );
+ peerCount += publishPeersCompact( tier, seeders, leechers, raw, rawlen );
gotPeers = TRUE;
}
else if( tr_bencDictFindList( &benc, "peers", &tmp ) )
/* original version of peers */
const int seeders = tier->currentTracker->seederCount;
const int leechers = tier->currentTracker->leecherCount;
- size_t byteCount = 0;
- uint8_t * array = parseOldPeers( tmp, &byteCount );
- peerCount += publishNewPeers( tier, seeders, leechers, array, byteCount );
+ peerCount += publishPeersDict( tier, seeders, leechers, tmp );
gotPeers = TRUE;
- tr_free( array );
}
if( tr_bencDictFindRaw( &benc, "peers6", &raw, &rawlen ) )
/* "compact" extension */
const int seeders = tier->currentTracker->seederCount;
const int leechers = tier->currentTracker->leecherCount;
- peerCount += publishNewPeersCompact6( tier, seeders, leechers, raw, rawlen );
+ peerCount += publishPeersCompact6( tier, seeders, leechers, raw, rawlen );
gotPeers = TRUE;
}