(trunk libT) #2112: provide "ipv6=" parameter to trackers
This commit is contained in:
parent
03e9189333
commit
44df1d5548
|
@ -649,6 +649,7 @@ createAnnounceURL( const tr_announcer * announcer,
|
||||||
const char * ann = tracker->announce;
|
const char * ann = tracker->announce;
|
||||||
struct evbuffer * buf = evbuffer_new( );
|
struct evbuffer * buf = evbuffer_new( );
|
||||||
char * ret;
|
char * ret;
|
||||||
|
const unsigned char * ipv6;
|
||||||
|
|
||||||
evbuffer_add_printf( buf, "%s"
|
evbuffer_add_printf( buf, "%s"
|
||||||
"%c"
|
"%c"
|
||||||
|
@ -688,6 +689,23 @@ createAnnounceURL( const tr_announcer * announcer,
|
||||||
if( tracker->tracker_id && *tracker->tracker_id )
|
if( tracker->tracker_id && *tracker->tracker_id )
|
||||||
evbuffer_add_printf( buf, "&trackerid=%s", 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 ) );
|
ret = tr_strndup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) );
|
||||||
evbuffer_free( buf );
|
evbuffer_free( buf );
|
||||||
|
|
||||||
|
|
|
@ -603,3 +603,25 @@ tr_globalAddress( int af, void *addr, int *addr_len )
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -122,4 +122,6 @@ void tr_netInit( void );
|
||||||
|
|
||||||
int tr_globalAddress(int af, void *addr, int *addr_len);
|
int tr_globalAddress(int af, void *addr, int *addr_len);
|
||||||
|
|
||||||
|
const unsigned char *tr_globalIPv6( void );
|
||||||
|
|
||||||
#endif /* _TR_NET_H_ */
|
#endif /* _TR_NET_H_ */
|
||||||
|
|
|
@ -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
|
static void
|
||||||
sendLtepHandshake( tr_peermsgs * msgs )
|
sendLtepHandshake( tr_peermsgs * msgs )
|
||||||
{
|
{
|
||||||
|
@ -837,7 +815,7 @@ sendLtepHandshake( tr_peermsgs * msgs )
|
||||||
int len;
|
int len;
|
||||||
int pex;
|
int pex;
|
||||||
struct evbuffer * out = msgs->outMessages;
|
struct evbuffer * out = msgs->outMessages;
|
||||||
const unsigned char * ipv6 = globalIPv6();
|
const unsigned char * ipv6 = tr_globalIPv6();
|
||||||
|
|
||||||
if( msgs->clientSentLtepHandshake )
|
if( msgs->clientSentLtepHandshake )
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -647,3 +647,40 @@ tr_webGetResponseStr( long code )
|
||||||
compareResponseCodes );
|
compareResponseCodes );
|
||||||
return msg ? msg->text : "Unknown Error";
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,5 +36,6 @@ void tr_webRun( tr_session * session,
|
||||||
tr_web_done_func done_func,
|
tr_web_done_func done_func,
|
||||||
void * done_func_user_data );
|
void * done_func_user_data );
|
||||||
|
|
||||||
|
void tr_http_escape( struct evbuffer *out, const char *str, int len, int noslashes );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -108,38 +108,8 @@ makeURL( tr_webseed * w,
|
||||||
evbuffer_add( out, url, url_len );
|
evbuffer_add( out, url, url_len );
|
||||||
|
|
||||||
/* if url ends with a '/', add the torrent name */
|
/* if url ends with a '/', add the torrent name */
|
||||||
if( url[url_len - 1] == '/' )
|
if( url[url_len - 1] == '/' && file->name )
|
||||||
{
|
tr_http_escape( out, file->name, strlen(file->name), 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = tr_strndup( EVBUFFER_DATA( out ), EVBUFFER_LENGTH( out ) );
|
ret = tr_strndup( EVBUFFER_DATA( out ), EVBUFFER_LENGTH( out ) );
|
||||||
evbuffer_free( out );
|
evbuffer_free( out );
|
||||||
|
|
Loading…
Reference in New Issue