(trunk libT) #2112: provide "ipv6=" parameter to trackers

This commit is contained in:
Charles Kerr 2009-11-10 17:03:23 +00:00
parent 03e9189333
commit 44df1d5548
7 changed files with 88 additions and 60 deletions

View File

@ -649,6 +649,7 @@ createAnnounceURL( const tr_announcer * announcer,
const char * ann = tracker->announce;
struct evbuffer * buf = evbuffer_new( );
char * ret;
const unsigned char * ipv6;
evbuffer_add_printf( buf, "%s"
"%c"
@ -688,6 +689,23 @@ createAnnounceURL( const tr_announcer * announcer,
if( tracker->tracker_id && *tracker->tracker_id )
evbuffer_add_printf( buf, "&trackerid=%s", tracker->tracker_id );
/* There are two incompatible techniques for announcing an IPv6 address.
BEP-7 suggests adding an "ipv6=" parameter to the announce URL,
while OpenTracker requires that peers announce twice, once over IPv4
and once over IPv6.
To be safe, we should do both: add the "ipv6=" parameter and
announce twice. At any rate, we're already computing our IPv6
address (for the LTEP handshake), so this comes for free. */
ipv6 = tr_globalIPv6( );
if( ipv6 ) {
char ipv6_readable[INET6_ADDRSTRLEN];
inet_ntop( AF_INET6, ipv6, ipv6_readable, INET6_ADDRSTRLEN );
evbuffer_add_printf( buf, "&ipv6=");
tr_http_escape( buf, ipv6_readable, strlen(ipv6_readable), 0 );
}
ret = tr_strndup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) );
evbuffer_free( buf );
@ -1444,7 +1462,7 @@ onScrapeDone( tr_session * session,
{
tier->isScraping = FALSE;
tier->lastScrapeTime = now;
if( tier->currentTracker->host )
{
tr_host * host = tier->currentTracker->host;
@ -1557,7 +1575,7 @@ flushCloseMessages( tr_announcer * announcer )
static tr_bool
tierNeedsToAnnounce( const tr_tier * tier, const time_t now )
{
return !tier->isAnnouncing
return !tier->isAnnouncing
&& !tier->isScraping
&& ( tier->announceEvent != NULL )
&& ( tier->announceAt <= now );
@ -1726,7 +1744,7 @@ tr_announcerStats( const tr_torrent * torrent,
else if( tier->scrapeAt > now )
{
st->scrapeState = TR_TRACKER_WAITING;
st->nextScrapeTime = tier->scrapeAt;
st->nextScrapeTime = tier->scrapeAt;
}
else
st->scrapeState = TR_TRACKER_QUEUED;
@ -1748,7 +1766,7 @@ tr_announcerStats( const tr_torrent * torrent,
else if( tier->announceAt > now )
{
st->announceState = TR_TRACKER_WAITING;
st->nextAnnounceTime = tier->announceAt;
st->nextAnnounceTime = tier->announceAt;
}
else
st->announceState = TR_TRACKER_QUEUED;

View File

@ -603,3 +603,25 @@ tr_globalAddress( int af, void *addr, int *addr_len )
return -1;
}
}
/* Return our global IPv6 address, with caching. */
const unsigned char *
tr_globalIPv6( void )
{
static unsigned char ipv6[16];
static time_t last_time = 0;
static int have_ipv6 = 0;
const time_t now = time( NULL );
/* Re-check every half hour */
if( last_time < now - 1800 )
{
int addrlen = 16;
const int rc = tr_globalAddress( AF_INET6, ipv6, &addrlen );
have_ipv6 = ( rc >= 0 ) && ( addrlen == 16 );
last_time = now;
}
return have_ipv6 ? ipv6 : NULL;
}

View File

@ -122,4 +122,6 @@ void tr_netInit( void );
int tr_globalAddress(int af, void *addr, int *addr_len);
const unsigned char *tr_globalIPv6( void );
#endif /* _TR_NET_H_ */

View File

@ -807,28 +807,6 @@ tr_peerMsgsCancel( tr_peermsgs * msgs, tr_block_index_t block )
***
**/
/* Return our global IPv6 address, with caching. */
static const unsigned char *
globalIPv6( void )
{
static unsigned char ipv6[16];
static time_t last_time = 0;
static int have_ipv6 = 0;
const time_t now = time( NULL );
/* Re-check every half hour */
if( last_time < now - 1800 )
{
int addrlen = 16;
const int rc = tr_globalAddress( AF_INET6, ipv6, &addrlen );
have_ipv6 = ( rc >= 0 ) && ( addrlen == 16 );
last_time = now;
}
return have_ipv6 ? ipv6 : NULL;
}
static void
sendLtepHandshake( tr_peermsgs * msgs )
{
@ -837,7 +815,7 @@ sendLtepHandshake( tr_peermsgs * msgs )
int len;
int pex;
struct evbuffer * out = msgs->outMessages;
const unsigned char * ipv6 = globalIPv6();
const unsigned char * ipv6 = tr_globalIPv6();
if( msgs->clientSentLtepHandshake )
return;

View File

@ -647,3 +647,40 @@ tr_webGetResponseStr( long code )
compareResponseCodes );
return msg ? msg->text : "Unknown Error";
}
/* escapes a string to be URI-legal as per RFC 2396.
like curl_escape() but can optionally avoid munging slashes. */
void
tr_http_escape( struct evbuffer *out, const char *str, int len, int keep_slashes )
{
int i;
for( i = 0; i < len; i++ ) {
switch( str[i] ) {
case ',': case '-': case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
evbuffer_add( out, &str[i], 1 );
break;
case '/':
if(keep_slashes) {
evbuffer_add( out, &str[i], 1 );
break;
}
/* Fall through. */
default:
evbuffer_add_printf( out, "%%%02X", (unsigned)(str[i]&0xFF) );
break;
}
}
}

View File

@ -36,5 +36,6 @@ void tr_webRun( tr_session * session,
tr_web_done_func done_func,
void * done_func_user_data );
void tr_http_escape( struct evbuffer *out, const char *str, int len, int noslashes );
#endif

View File

@ -108,39 +108,9 @@ makeURL( tr_webseed * w,
evbuffer_add( out, url, url_len );
/* if url ends with a '/', add the torrent name */
if( url[url_len - 1] == '/' )
{
const char * str = file->name;
/* this is like curl_escape() but doesn't munge the
* '/' directory separators in the path */
while( str && *str )
{
switch( *str )
{
case ',': case '-': case '.': case '/':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
evbuffer_add( out, str, 1 );
break;
default:
evbuffer_add_printf( out, "%%%02X", *str );
break;
}
str++;
}
}
if( url[url_len - 1] == '/' && file->name )
tr_http_escape( out, file->name, strlen(file->name), 1 );
ret = tr_strndup( EVBUFFER_DATA( out ), EVBUFFER_LENGTH( out ) );
evbuffer_free( out );
return ret;