Index: libtransmission/announcer.c
===================================================================
--- libtransmission/announcer.c (revision 9219)
+++ libtransmission/announcer.c (working copy)
-30,8 +30,7 @@
#define dbgmsg( tier, ... ) \
if( tr_deepLoggingIsActive( ) ) do { \
char name[128]; \
- tr_snprintf
( name,
sizeof( name
),
"[%s--%s]", tr_torrentName
( tier
->tor
), \
- ( tier->currentTracker ? tier->currentTracker->host->name : "" ) ); \
+ tr_snprintf
( name,
sizeof( name
),
"[%s]", tr_torrentName
( tier
->tor
) ); \
tr_deepLog( __FILE__, __LINE__, name, __VA_ARGS__ ); \
} while( 0 )
-200,7 +199,7 @@
typedef struct tr_announcer
{
tr_ptrArray hosts; /* tr_host */
- tr_ptrArray stops; /* struct stop_message */
+ tr_ptrArray stopsArray[NUM_TR_AF_INET_TYPES]; /* struct stop_message */
tr_session * session;
struct event * upkeepTimer;
int announceSlotsAvailable;
-232,12 +231,14 @@
tr_announcerInit( tr_session * session )
{
tr_announcer * a;
+ int i;
assert( tr_isSession
( session
) );
a = tr_new0( tr_announcer, 1 );
a->hosts = TR_PTR_ARRAY_INIT;
- a->stops = TR_PTR_ARRAY_INIT;
+ for( i = 0 ; i < NUM_TR_AF_INET_TYPES ; i++ )
+ a->stopsArray[i] = TR_PTR_ARRAY_INIT;
a->session = session;
a->announceSlotsAvailable = MAX_CONCURRENT_ANNOUNCES;
a->scrapeSlotsAvailable = MAX_CONCURRENT_SCRAPES;
-254,6 +255,7 @@
tr_announcerClose( tr_session * session )
{
tr_announcer * announcer = session->announcer;
+ int i;
flushCloseMessages( announcer );
-261,7 +263,8 @@
tr_free( announcer->upkeepTimer );
announcer->upkeepTimer = NULL;
- tr_ptrArrayDestruct( &announcer->stops, NULL );
+ for( i = 0 ; i < NUM_TR_AF_INET_TYPES ; i++ )
+ tr_ptrArrayDestruct( &announcer->stopsArray[i], NULL );
tr_ptrArrayDestruct( &announcer->hosts, hostFree );
session->announcer = NULL;
-291,6 +294,9 @@
* to verify us if our IP address changes.
* This is immutable for the life of the tracker object. */
char key_param[KEYLEN + 1];
+
+ /* this tracker's address family */
+ tr_address_type af;
}
tr_tracker_item;
-307,9 +313,10 @@
}
static tr_tracker_item*
-trackerNew( tr_announcer * announcer,
- const char * announce,
- const char * scrape )
+trackerNew( tr_announcer * announcer,
+ const char * announce,
+ const char * scrape,
+ tr_address_type af)
{
tr_tracker_item * tracker = tr_new0( tr_tracker_item, 1 );
tracker->host = getHost( announcer, announce );
-319,6 +326,7 @@
tracker->seederCount = -1;
tracker->leecherCount = -1;
tracker->downloadCount = -1;
+ tracker->af = af;
return tracker;
}
-345,8 +353,8 @@
*/
typedef struct
{
- tr_ptrArray trackers; /* tr_tracker_item */
- tr_tracker_item * currentTracker;
+ tr_ptrArray trackersArray[NUM_TR_AF_INET_TYPES]; /* tr_tracker_item */
+ tr_tracker_item * currentTrackers[NUM_TR_AF_INET_TYPES];
tr_torrent * tor;
-366,7 +374,7 @@
/* unique lookup key */
int key;
- int currentTrackerIndex;
+ int currentTrackerIndexes[NUM_TR_AF_INET_TYPES];
int scrapeIntervalSec;
int announceIntervalSec;
int announceMinIntervalSec;
-376,9 +384,9 @@
int randOffset;
int lastAnnouncePeerCount;
- tr_bool isRunning;
- tr_bool isAnnouncing;
- tr_bool isScraping;
+ tr_bool isRunningArray[NUM_TR_AF_INET_TYPES];
+ tr_bool isAnnouncingArray[NUM_TR_AF_INET_TYPES];
+ tr_bool isScrapingArray[NUM_TR_AF_INET_TYPES];
char lastAnnounceStr[128];
char lastScrapeStr[128];
-389,15 +397,18 @@
tierNew( tr_torrent * tor )
{
tr_tier * t;
+ int i;
static int nextKey = 1;
const time_t now
= time( NULL );
t = tr_new0( tr_tier, 1 );
t->randOffset = tr_cryptoRandInt( 60 );
t->key = nextKey++;
- t->trackers = TR_PTR_ARRAY_INIT;
- t->currentTracker = NULL;
- t->currentTrackerIndex = -1;
+ for( i = 0 ; i < NUM_TR_AF_INET_TYPES ; i++ ) {
+ t->trackersArray[i] = TR_PTR_ARRAY_INIT;
+ t->currentTrackers[i] = NULL;
+ t->currentTrackerIndexes[i] = -1;
+ }
t->scrapeIntervalSec = DEFAULT_SCRAPE_INTERVAL_SEC;
t->announceIntervalSec = DEFAULT_ANNOUNCE_INTERVAL_SEC;
t->announceMinIntervalSec = DEFAULT_ANNOUNCE_MIN_INTERVAL_SEC;
-411,17 +422,19 @@
tierFree( void * vtier )
{
tr_tier * tier = vtier;
- tr_ptrArrayDestruct( &tier->trackers, trackerFree );
+ int i;
+ for( i = 0 ; i < NUM_TR_AF_INET_TYPES ; i++ )
+ tr_ptrArrayDestruct( &tier->trackersArray[i], trackerFree );
tr_free( tier );
}
static void
-tierIncrementTracker( tr_tier * tier )
+tierIncrementTracker( tr_tier * tier, tr_address_type af )
{
- const int i = ( tier->currentTrackerIndex + 1 )
- % tr_ptrArraySize( &tier->trackers );
- tier->currentTracker = tr_ptrArrayNth( &tier->trackers, i );
- tier->currentTrackerIndex = i;
+ const int i = ( tier->currentTrackerIndexes[af] + 1 )
+ % tr_ptrArraySize( &tier->trackersArray[af] );
+ tier->currentTrackers[af] = tr_ptrArrayNth( &tier->trackersArray[af], i );
+ tier->currentTrackerIndexes[af] = i;
/* reset some of the tier's fields */
tier->scrapeIntervalSec = DEFAULT_SCRAPE_INTERVAL_SEC;
-429,25 +442,26 @@
tier->announceMinIntervalSec = DEFAULT_ANNOUNCE_MIN_INTERVAL_SEC;
tier->retryAnnounceIntervalSec = FIRST_ANNOUNCE_RETRY_INTERVAL_SEC;
tier->retryScrapeIntervalSec = FIRST_SCRAPE_RETRY_INTERVAL_SEC;
- tier->isAnnouncing = FALSE;
- tier->isScraping = FALSE;
+ tier->isAnnouncingArray[af] = FALSE;
+ tier->isScrapingArray[af] = FALSE;
tier->lastAnnounceStartTime = 0;
tier->lastScrapeStartTime = 0;
}
static void
-tierAddTracker( tr_announcer * announcer,
- tr_tier * tier,
- const char * announce,
- const char * scrape )
+tierAddTracker( tr_announcer * announcer,
+ tr_tier * tier,
+ const char * announce,
+ const char * scrape,
+ tr_address_type af)
{
- tr_tracker_item * tracker = trackerNew( announcer, announce, scrape );
+ tr_tracker_item * tracker = trackerNew( announcer, announce, scrape, af );
- tr_ptrArrayAppend( &tier->trackers, tracker );
- dbgmsg( tier, "adding tracker %s", announce );
+ tr_ptrArrayAppend( &tier->trackersArray[af], tracker );
- if( !tier->currentTracker )
- tierIncrementTracker( tier );
+ dbgmsg( tier, "adding tracker %s address family %d", announce, af );
+ if( !tier->currentTrackers[af] )
+ tierIncrementTracker( tier, af );
}
-535,9 +549,9 @@
}
static void
-publishErrorMessageAndStop( tr_tier * tier, const char * msg )
+publishErrorMessageAndStop( tr_tier * tier, tr_address_type af, const char * msg )
{
- tier->isRunning = FALSE;
+ tier->isRunningArray[af] = FALSE;
publishMessage( tier, msg, TR_TRACKER_ERROR );
}
-590,6 +604,8 @@
walk
+= sizeof( tr_address
) + 2;
compactWalk += 6;
+
+ tr_dbg("new v4 peer %s", tr_ntop_non_ts(&addr));
}
publishNewPeers( tier, allAreSeeds, array, arrayLen );
-623,6 +639,8 @@
walk
+= sizeof( tr_address
) + 2;
+
+ tr_dbg("new v6 peer %s", tr_ntop_non_ts(&addr));
}
publishNewPeers( tier, allAreSeeds, array, arrayLen );
tr_free( array );
-634,11 +652,12 @@
createAnnounceURL( const tr_announcer * announcer,
const tr_torrent * torrent,
const tr_tier * tier,
+ tr_address_type af,
const char * eventName )
{
const int isStopping
= !strcmp( eventName,
"stopped" );
const int numwant = isStopping ? 0 : NUMWANT;
- const tr_tracker_item * tracker = tier->currentTracker;
+ const tr_tracker_item * tracker = tier->currentTrackers[af];
const char * ann = tracker->announce;
struct evbuffer * buf = evbuffer_new( );
char * ret;
-724,7 +743,11 @@
}
tierAddTracker( announcer, tier, tor->info.trackers[i].announce,
- tor->info.trackers[i].scrape );
+ tor->info.trackers[i].scrape,
+ TR_AF_INET );
+ tierAddTracker( announcer, tier, tor->info.trackers[i].announce,
+ tor->info.trackers[i].scrape,
+ TR_AF_INET6 );
}
}
-750,7 +773,7 @@
static tr_bool
tierCanManualAnnounce( const tr_tier * tier )
{
- return tier->isRunning
+ return ( tier->isRunningArray[TR_AF_INET] || tier->isRunningArray[TR_AF_INET6] )
&& tier
->manualAnnounceAllowedAt <
= time( NULL );
}
-787,7 +810,7 @@
n = tr_ptrArraySize( &tiers->tiers );
for( i=0; i<n; ++i ) {
tr_tier * tier = tr_ptrArrayNth( (tr_ptrArray*)&tiers->tiers, i );
- if( tier->isRunning )
+ if( tier->isRunningArray[TR_AF_INET] || tier->isRunningArray[TR_AF_INET6] )
ret = MIN( ret, tier->manualAnnounceAllowedAt );
}
-865,20 +888,22 @@
if( tor->tiers )
{
- int i;
+ int i, j;
const int n = tr_ptrArraySize( &tor->tiers->tiers );
for( i=0; i<n; ++i )
{
tr_tier * tier = tr_ptrArrayNth( &tor->tiers->tiers, i );
-
- if( tier->isRunning )
- {
- struct stop_message * s = tr_new0( struct stop_message, 1 );
- s->up = tor->uploadedCur;
- s->down = tor->downloadedCur;
- s->url = createAnnounceURL( announcer, tor, tier, "stopped" );
- s->host = tier->currentTracker->host;
- tr_ptrArrayInsertSorted( &announcer->stops, s, compareStops );
+
+ for( j = 0 ; j < NUM_TR_AF_INET_TYPES ; j++ ) {
+ if( tier->isRunningArray[j] )
+ {
+ struct stop_message * s = tr_new0( struct stop_message, 1 );
+ s->up = tor->uploadedCur;
+ s->down = tor->downloadedCur;
+ s->url = createAnnounceURL( announcer, tor, tier, j, "stopped" );
+ s->host = tier->currentTrackers[j]->host;
+ tr_ptrArrayInsertSorted( &announcer->stopsArray[j], s, compareStops );
+ }
}
}
-900,8 +925,10 @@
static tr_bool
tierIsNotResponding( const tr_tier * tier, const time_t now )
{
- return !tier->currentTracker
- || hostIsNotResponding( tier->currentTracker->host, now );
+ return !tier->currentTrackers[TR_AF_INET]
+ || hostIsNotResponding( tier->currentTrackers[TR_AF_INET]->host, now )
+ || !tier->currentTrackers[TR_AF_INET6]
+ || hostIsNotResponding( tier->currentTrackers[TR_AF_INET6]->host, now );
}
static int
-992,10 +1019,11 @@
}
static tr_bool
-parseAnnounceResponse( tr_tier * tier,
- const char * response,
- size_t responseLen,
- tr_bool * gotScrape )
+parseAnnounceResponse( tr_tier * tier,
+ tr_address_type af,
+ const char * response,
+ size_t responseLen,
+ tr_bool * gotScrape )
{
tr_benc benc;
tr_bool success = FALSE;
-1048,25 +1076,25 @@
if( tr_bencDictFindStr( &benc, "tracker id", &str ) )
{
- tier->currentTracker->tracker_id = tr_strdup( str );
+ tier->currentTrackers[af]->tracker_id = tr_strdup( str );
}
if( tr_bencDictFindInt( &benc, "complete", &i ) )
{
++scrapeFields;
- tier->currentTracker->seederCount = i;
+ tier->currentTrackers[af]->seederCount = i;
}
if( tr_bencDictFindInt( &benc, "incomplete", &i ) )
{
++scrapeFields;
- tier->currentTracker->leecherCount = incomplete = i;
+ tier->currentTrackers[af]->leecherCount = incomplete = i;
}
if( tr_bencDictFindInt( &benc, "downloaded", &i ) )
{
++scrapeFields;
- tier->currentTracker->downloadCount = i;
+ tier->currentTrackers[af]->downloadCount = i;
}
if( tr_bencDictFindRaw( &benc, "peers", &raw, &rawlen ) )
-1113,6 +1141,8 @@
/** If the request succeeds, the value for tier's "isRunning" flag */
tr_bool isRunningOnSuccess;
+
+ tr_address_type af;
};
static void
-1128,14 +1158,15 @@
tr_bool gotScrape = FALSE;
tr_bool success = FALSE;
const time_t now
= time ( NULL );
+ tr_address_type af = data->af;
if( announcer && tier )
{
tier->lastAnnouncePeerCount = 0;
- if( tier->currentTracker->host )
+ if( tier->currentTrackers[af]->host )
{
- tr_host * host = tier->currentTracker->host;
+ tr_host * host = tier->currentTrackers[af]->host;
host->lastRequestTime = data->timeSent;
host->lastResponseInterval = now - data->timeSent;
}
-1143,7 +1174,7 @@
if( responseCode == HTTP_OK )
{
tier->lastAnnounceTime = now;
- success = parseAnnounceResponse( tier, response, responseLen, &gotScrape );
+ success = parseAnnounceResponse( tier, af, response, responseLen, &gotScrape );
dbgmsg( tier, "success is %d", success );
}
else if( responseCode )
-1178,7 +1209,7 @@
if( tier )
{
- tier->isAnnouncing = FALSE;
+ tier->isAnnouncingArray[af] = FALSE;
if( responseCode == 0 )
{
-1217,7 +1248,7 @@
/* The request could not be understood by the server due to
* malformed syntax. The client SHOULD NOT repeat the
* request without modifications. */
- publishErrorMessageAndStop( tier, _( "Tracker returned a 4xx message" ) );
+ publishErrorMessageAndStop( tier, af, _( "Tracker returned a 4xx message" ) );
tier->manualAnnounceAllowedAt = ~(time_t)0;
}
else if( 500 <= responseCode && responseCode <= 599 )
-1242,10 +1273,10 @@
tier->lastAnnounceSucceeded = success;
if( success )
- tier->isRunning = data->isRunningOnSuccess;
+ tier->isRunningArray[af] = data->isRunningOnSuccess;
if( !success )
- tierIncrementTracker( tier );
+ tierIncrementTracker( tier, af );
}
if( announcer != NULL )
-1286,29 +1317,33 @@
struct announce_data * data;
const tr_torrent * tor = tier->tor;
const time_t now
= time( NULL );
+ int i;
- assert( !tier
->isAnnouncing
);
+ assert( !tier
->isAnnouncingArray
[TR_AF_INET
] ||
!tier
->isAnnouncingArray
[TR_AF_INET6
] );
- data = tr_new0( struct announce_data, 1 );
- data->torrentId = tr_torrentId( tor );
- data->tierId = tier->key;
- data->isRunningOnSuccess = tor->isRunning;
- data->timeSent = now;
+ for( i = 0 ; i < NUM_TR_AF_INET_TYPES ; i++ ) {
+ tier->isAnnouncingArray[i] = TRUE;
+ tier->lastAnnounceStartTime = now;
+ --announcer->announceSlotsAvailable;
- url = createAnnounceURL( announcer, tor, tier, getAnnounceEvent( tier ) );
+ data = tr_new0( struct announce_data, 1 );
+ data->torrentId = tr_torrentId( tor );
+ data->tierId = tier->key;
+ data->isRunningOnSuccess = tor->isRunning;
+ data->timeSent = now;
+ data->af = i;
+ url = createAnnounceURL( announcer, tor, tier, i, getAnnounceEvent( tier ) );
+ tr_webRun( announcer->session, url, i, NULL, onAnnounceDone, data );
+ }
- tier->isAnnouncing = TRUE;
- tier->lastAnnounceStartTime = now;
- --announcer->announceSlotsAvailable;
- tr_webRun( announcer->session, url, NULL, onAnnounceDone, data );
-
tr_free( url );
}
static tr_bool
-parseScrapeResponse( tr_tier * tier,
- const char * response,
- size_t responseLen )
+parseScrapeResponse( tr_tier * tier,
+ tr_address_type af,
+ const char * response,
+ size_t responseLen )
{
tr_bool success = FALSE;
tr_benc benc, *files;
-1330,16 +1365,16 @@
publishErrorClear( tier );
if( ( tr_bencDictFindInt( val, "complete", &intVal ) ) )
- tier->currentTracker->seederCount = intVal;
+ tier->currentTrackers[af]->seederCount = intVal;
if( ( tr_bencDictFindInt( val, "incomplete", &intVal ) ) )
- tier->currentTracker->leecherCount = intVal;
+ tier->currentTrackers[af]->leecherCount = intVal;
if( ( tr_bencDictFindInt( val, "downloaded", &intVal ) ) )
- tier->currentTracker->downloadCount = intVal;
+ tier->currentTrackers[af]->downloadCount = intVal;
if( ( tr_bencDictFindInt( val, "downloaders", &intVal ) ) )
- tier->currentTracker->downloaderCount = intVal;
+ tier->currentTrackers[af]->downloaderCount = intVal;
if( tr_bencDictFindDict( val, "flags", &flags ) )
if( ( tr_bencDictFindInt( flags, "min_request_interval", &intVal ) ) )
-1376,25 +1411,26 @@
tr_tier * tier = getTier( announcer, data->torrentId, data->tierId );
const time_t now
= time( NULL );
tr_bool success = FALSE;
-
+ tr_address_type af = data->af;
+
if( announcer )
++announcer->scrapeSlotsAvailable;
if( announcer && tier )
{
- tier->isScraping = FALSE;
+ tier->isScrapingArray[af] = FALSE;
tier->lastScrapeTime = now;
- if( tier->currentTracker->host )
+ if( tier->currentTrackers[af]->host )
{
- tr_host * host = tier->currentTracker->host;
+ tr_host * host = tier->currentTrackers[af]->host;
host->lastRequestTime = data->timeSent;
host->lastResponseInterval = now - data->timeSent;
}
if( responseCode == HTTP_OK )
{
- success = parseScrapeResponse( tier, response, responseLen );
+ success = parseScrapeResponse( tier, af, response, responseLen );
}
if( 200 <= responseCode && responseCode <= 299 )
-1444,54 +1480,64 @@
struct evbuffer * buf;
struct announce_data * data;
const time_t now
= time( NULL );
+ int i;
- assert( !tier
->isScraping
);
- assert( tier
->currentTracker
!= NULL );
+ assert( !tier
->isScrapingArray
[TR_AF_INET
] ||
!tier
->isScrapingArray
[TR_AF_INET6
] );
+ assert( tier
->currentTrackers
[TR_AF_INET
] != NULL );
+ assert( tier
->currentTrackers
[TR_AF_INET6
] != NULL );
assert( tr_isTorrent
( tier
->tor
) );
+
+ for( i = 0 ; i < NUM_TR_AF_INET_TYPES ; i++ ) {
+ tier->isScrapingArray[i] = TRUE;
+ tier->lastScrapeStartTime = now;
+ --announcer->scrapeSlotsAvailable;
+
+ data = tr_new0( struct announce_data, 1 );
+ data->torrentId = tr_torrentId( tier->tor );
+ data->tierId = tier->key;
- data = tr_new0( struct announce_data, 1 );
- data->torrentId = tr_torrentId( tier->tor );
- data->tierId = tier->key;
+ scrape = tier->currentTrackers[i]->scrape;
- scrape = tier->currentTracker->scrape;
+ buf = evbuffer_new( );
+ evbuffer_add_printf( buf, "%s%cinfo_hash=%s",
+ scrape,
+ strchr( scrape,
'?' ) ?
'&' : '?',
+ tier->tor->info.hashEscaped );
- buf = evbuffer_new( );
- evbuffer_add_printf( buf, "%s%cinfo_hash=%s",
- scrape,
- strchr( scrape,
'?' ) ?
'&' : '?',
- tier->tor->info.hashEscaped );
+ dbgmsg( tier, "scraping \"%s\"", (const char*)EVBUFFER_DATA(buf) );
+ tr_webRun( announcer->session, (const char*)EVBUFFER_DATA(buf), i, NULL, onScrapeDone, data );
- tier->isScraping = TRUE;
- tier->lastScrapeStartTime = now;
- --announcer->scrapeSlotsAvailable;
- dbgmsg( tier, "scraping \"%s\"", (const char*)EVBUFFER_DATA(buf) );
- tr_webRun( announcer->session, (const char*)EVBUFFER_DATA(buf), NULL, onScrapeDone, data );
-
- evbuffer_free( buf );
+ evbuffer_free( buf );
+ }
}
static void
flushCloseMessages( tr_announcer * announcer )
{
- int i;
- const int n = tr_ptrArraySize( &announcer->stops );
+ int i, j;
+
+ for( j = 0 ; j < NUM_TR_AF_INET_TYPES ; j++ ) {
+ const int n = tr_ptrArraySize( &announcer->stopsArray[j] );
- for( i=0; i<n; ++i )
- {
- struct stop_message * stop = tr_ptrArrayNth( &announcer->stops, i );
- tr_webRun( announcer->session, stop->url, NULL, NULL, NULL );
- stopFree( stop );
- }
+ for( i=0; i<n; ++i )
+ {
+ struct stop_message * stop = tr_ptrArrayNth( &announcer->stopsArray[j], i );
+ tr_webRun( announcer->session, stop->url, j, NULL, NULL, NULL );
+ stopFree( stop );
+ }
- tr_ptrArrayClear( &announcer->stops );
+ tr_ptrArrayClear( &announcer->stopsArray[j] );
+ }
}
static tr_bool
tierNeedsToAnnounce( const tr_tier * tier, const time_t now )
{
- return !tier->isAnnouncing
- && !tier->isScraping
+ return !tier->isAnnouncingArray[TR_AF_INET]
+ && !tier->isAnnouncingArray[TR_AF_INET6]
+ && !tier->isScrapingArray[TR_AF_INET]
+ && !tier->isScrapingArray[TR_AF_INET6]
&& ( tier->announceEvent != NULL )
&& ( tier->announceAt <= now );
}
-1499,10 +1545,13 @@
static tr_bool
tierNeedsToScrape( const tr_tier * tier, const time_t now )
{
- return !tier->isScraping
+ return !tier->isScrapingArray[TR_AF_INET]
+ && !tier->isScrapingArray[TR_AF_INET6]
&& ( tier->scrapeAt <= now )
- && ( tier->currentTracker != NULL )
- && ( tier->currentTracker->scrape != NULL );
+ && ( ( ( tier->currentTrackers[TR_AF_INET] != NULL )
+ && ( tier->currentTrackers[TR_AF_INET]->scrape != NULL ) )
+ || ( ( tier->currentTrackers[TR_AF_INET6] != NULL )
+ && ( tier->currentTrackers[TR_AF_INET6]->scrape != NULL ) ) );
}
static void
-1585,7 +1634,7 @@
tr_announcerStats( const tr_torrent * torrent,
int * setmeTrackerCount )
{
- int i;
+ int i, k;
int n;
int out = 0;
int tierCount;
-1596,7 +1645,8 @@
/* count the trackers... */
for( i=n=0, tierCount=tr_ptrArraySize( &torrent->tiers->tiers ); i<tierCount; ++i ) {
const tr_tier * tier = tr_ptrArrayNth( &torrent->tiers->tiers, i );
- n += tr_ptrArraySize( &tier->trackers );
+ for( k = 0 ; k < NUM_TR_AF_INET_TYPES ; k++ )
+ n += tr_ptrArraySize( &tier->trackersArray[k] );
}
/* alloc the stats */
-1608,42 +1658,46 @@
{
int j;
const tr_tier * tier = tr_ptrArrayNth( &torrent->tiers->tiers, i );
- n = tr_ptrArraySize( &tier->trackers );
- for( j=0; j<n; ++j )
- {
- const tr_tracker_item * tracker = tr_ptrArrayNth( (tr_ptrArray*)&tier->trackers, j );
- tr_tracker_stat * st = ret + out++;
+ for( k = 0 ; k < NUM_TR_AF_INET_TYPES ; k++ ) {
+ n = tr_ptrArraySize( &tier->trackersArray[k] );
+ for( j=0; j<n; ++j )
+ {
+ const tr_tracker_item * tracker = tr_ptrArrayNth( (tr_ptrArray*)&tier->trackersArray[k], j );
+ tr_tracker_stat * st = ret + out++;
- tr_strlcpy
( st
->host, tracker
->host
->name,
sizeof( st
->host
) );
- tr_strlcpy
( st
->announce, tracker
->announce,
sizeof( st
->announce
) );
- st->tier = i + 1;
- st->isActive = tracker == tier->currentTracker;
- st->lastScrapeStartTime = tier->lastScrapeStartTime;
- if(( st->hasScraped = tier->lastScrapeTime != 0 )) {
- st->lastScrapeTime = tier->lastScrapeTime;
- st->lastScrapeSucceeded = tier->lastScrapeSucceeded;
- tr_strlcpy
( st
->lastScrapeResult, tier
->lastScrapeStr,
sizeof( st
->lastScrapeResult
) );
- }
- st->isScraping = tier->isScraping;
- if(( st->willScrape = st->isActive && !tier->isScraping )) {
- st->nextScrapeTime = tier->scrapeAt;
- }
- st->lastAnnounceStartTime = tier->lastAnnounceStartTime;
- if(( st->hasAnnounced = tier->lastAnnounceTime != 0 )) {
- st->lastAnnounceTime = tier->lastAnnounceTime;
- tr_strlcpy
( st
->lastAnnounceResult, tier
->lastAnnounceStr,
sizeof( st
->lastAnnounceResult
) );
- if(( st->lastAnnounceSucceeded = tier->lastAnnounceSucceeded )) {
- st->lastAnnouncePeerCount = tier->lastAnnouncePeerCount;
- }
- }
- st->isAnnouncing = tier->isAnnouncing;
- if(( st->willAnnounce = torrent->isRunning && !tier->isAnnouncing )) {
- st->nextAnnounceTime = tier->announceAt;
- }
- st->seederCount = tracker->seederCount;
- st->leecherCount = tracker->leecherCount;
- st->downloadCount = tracker->downloadCount;
- }
+ tr_strlcpy
( st
->host, tracker
->host
->name,
sizeof( st
->host
) );
+ tr_strlcpy
( st
->announce, tracker
->announce,
sizeof( st
->announce
) );
+ st->tier = i + 1;
+ st->isActive = tracker == tier->currentTrackers[k];
+ st->lastScrapeStartTime = tier->lastScrapeStartTime;
+ if(( st->hasScraped = tier->lastScrapeTime != 0 )) {
+ st->lastScrapeTime = tier->lastScrapeTime;
+ st->lastScrapeSucceeded = tier->lastScrapeSucceeded;
+ tr_strlcpy
( st
->lastScrapeResult, tier
->lastScrapeStr,
sizeof( st
->lastScrapeResult
) );
+ }
+ st->isScraping = tier->isScrapingArray[k];
+ if(( st->willScrape = st->isActive && !tier->isScrapingArray[k] )) {
+ st->nextScrapeTime = tier->scrapeAt;
+ }
+ st->lastAnnounceStartTime = tier->lastAnnounceStartTime;
+ if(( st->hasAnnounced = tier->lastAnnounceTime != 0 )) {
+ st->lastAnnounceTime = tier->lastAnnounceTime;
+ tr_strlcpy
( st
->lastAnnounceResult, tier
->lastAnnounceStr,
sizeof( st
->lastAnnounceResult
) );
+ if(( st->lastAnnounceSucceeded = tier->lastAnnounceSucceeded )) {
+ st->lastAnnouncePeerCount = tier->lastAnnouncePeerCount;
+ }
+ }
+ st->isAnnouncing = tier->isAnnouncingArray[k];
+ if(( st->willAnnounce = torrent->isRunning && !tier->isAnnouncingArray[k] )) {
+ st->nextAnnounceTime = tier->announceAt;
+ }
+ st->seederCount = tracker->seederCount;
+ st->leecherCount = tracker->leecherCount;
+ st->downloadCount = tracker->downloadCount;
+
+ st->af = tracker->af;
+ }
+ }
}
return ret;
Index: libtransmission/rpcimpl.c
===================================================================
--- libtransmission/rpcimpl.c (revision 9219)
+++ libtransmission/rpcimpl.c (working copy)
-859,7 +859,7 @@
{
const int port = tr_sessionGetPeerPort( session );
char * url = tr_strdup_printf( "http://portcheck.transmissionbt.com/%d", port );
- tr_webRun( session, url, NULL, portTested, idle_data );
+ tr_webRun( session, url, TR_AF_UNSPEC, NULL, portTested, idle_data );
tr_free( url );
return NULL;
}
-916,7 +916,7 @@
struct tr_rpc_idle_data * idle_data )
{
const char * url = "http://update.transmissionbt.com/level1";
- tr_webRun( session, url, NULL, gotNewBlocklist, idle_data );
+ tr_webRun( session, url, TR_AF_UNSPEC, NULL, gotNewBlocklist, idle_data );
return NULL;
}
-1093,7 +1093,7 @@
struct add_torrent_idle_data * d = tr_new0( struct add_torrent_idle_data, 1 );
d->data = idle_data;
d->ctor = ctor;
- tr_webRun( session, filename, NULL, gotMetadataFromURL, d );
+ tr_webRun( session, filename, TR_AF_UNSPEC, NULL, gotMetadataFromURL, d );
}
else
{
Index: libtransmission/webseed.c
===================================================================
--- libtransmission/webseed.c (revision 9219)
+++ libtransmission/webseed.c (working copy)
-213,7 +213,7 @@
/*fprintf( stderr, "url is [%s]\n", url );*/
range = tr_strdup_printf( "%"PRIu64"-%"PRIu64, fileOffset, fileOffset + thisPass - 1 );
/*fprintf( stderr, "range is [%s] ... we want %lu total, we have %lu, so %lu are left, and we're asking for %lu this time\n", range, (unsigned long)w->byteCount, (unsigned long)have, (unsigned long)left, (unsigned long)thisPass );*/
- tr_webRun( w->session, url, range, webResponseFunc, w );
+ tr_webRun( w->session, url, TR_AF_UNSPEC, range, webResponseFunc, w );
tr_free( range );
tr_free( url );
}
Index: libtransmission/transmission.h
===================================================================
--- libtransmission/transmission.h (revision 9219)
+++ libtransmission/transmission.h (working copy)
-103,6 +103,15 @@
TR_ENCRYPTION_REQUIRED
}
tr_encryption_mode;
+
+typedef enum tr_address_type
+{
+ TR_AF_INET,
+ TR_AF_INET6,
+ NUM_TR_AF_INET_TYPES,
+ TR_AF_UNSPEC /* keep this after the NUM_ entry since it's not really an AF */
+}
+tr_address_type;
/***
-1315,6 +1324,9 @@
/* true if we're not scraping now but will at nextScrapeTime */
tr_bool willScrape;
+
+ /* address family (ipv4/ipv6) of this tracker */
+ tr_address_type af;
}
tr_tracker_stat;
Index: libtransmission/web.c
===================================================================
--- libtransmission/web.c (revision 9219)
+++ libtransmission/web.c (working copy)
-156,6 +156,7 @@
tr_session * session;
tr_web_done_func * done_func;
void * done_func_user_data;
+ tr_address_type af; /* address family */
};
static size_t
-209,7 +210,12 @@
tr_free( str );
}
- curl_easy_setopt( easy, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
+ if( task->af == TR_AF_INET )
+ curl_easy_setopt( easy, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
+ else if( task->af == TR_AF_INET6 )
+ curl_easy_setopt( easy, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6 );
+ else /* TR_AF_UNSPEC */
+ curl_easy_setopt( easy, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER );
/* set a time limit for announces & scrapes */
if( strstr( task
->url,
"scrape" ) != NULL )
-499,6 +505,7 @@
void
tr_webRun( tr_session * session,
const char * url,
+ tr_address_type af,
const char * range,
tr_web_done_func done_func,
void * done_func_user_data )
-516,6 +523,7 @@
task->done_func_user_data = done_func_user_data;
task->tag = ++tag;
task->response = evbuffer_new( );
+ task->af = af;
tr_runInEventThread( session, addTask, task );
}
Index: libtransmission/web.h
===================================================================
--- libtransmission/web.h (revision 9219)
+++ libtransmission/web.h (working copy)
-29,6 +29,7 @@
void tr_webRun( tr_session * session,
const char * url,
+ tr_address_type af,
const char * range,
tr_web_done_func done_func,
void * done_func_user_data );
Index: libtransmission/net.h
===================================================================
--- libtransmission/net.h (revision 9219)
+++ libtransmission/net.h (working copy)
-58,14 +58,6 @@
struct tr_session;
-typedef enum tr_address_type
-{
- TR_AF_INET,
- TR_AF_INET6,
- NUM_TR_AF_INET_TYPES
-}
-tr_address_type;
-
typedef struct tr_address
{
tr_address_type type;
Index: macosx/TrackerCell.m
===================================================================
--- macosx/TrackerCell.m (revision 9219)
+++ macosx/TrackerCell.m (working copy)
-295,7 +295,8 @@
{
- NSString * name
= [(TrackerNode
*)[self objectValue
] host
];
+ TrackerNode * node = [self objectValue];
+ NSString * name
= [NSString stringWithFormat
:@"%@ (%@)",
[node host
],
[node addressFamily
]];
return [[[NSAttributedString alloc
] initWithString
: name attributes
: fNameAttributes
] autorelease
];
}
Index: macosx/TrackerNode.h
===================================================================
--- macosx/TrackerNode.h (revision 9219)
+++ macosx/TrackerNode.h (working copy)
-33,6 +33,7 @@
- (id) initWithTrackerStat: (tr_tracker_stat *) stat;
- (NSInteger) totalSeeders;
Index: macosx/TrackerNode.m
===================================================================
--- macosx/TrackerNode.m (revision 9219)
+++ macosx/TrackerNode.m (working copy)
-49,6 +49,15 @@
return [NSString stringWithUTF8String
: fStat.host
];
}
+{
+ if( fStat.af == TR_AF_INET )
+ return @"IPv4";
+ if( fStat.af == TR_AF_INET6 )
+ return @"IPv6";
+ return @"?";
+}
+
{
return [NSString stringWithUTF8String
: fStat.announce
];