From a17962d5fcc59c565192b8e0f551dfd9b94e0a1f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 30 Dec 2010 19:15:47 +0000 Subject: [PATCH] (trunk libT) #3528 "TR_PREFS_KEY_BIND_ADDRESS_IPV4 breaks IPv6-only trackers" -- Implement suggestion #2 from Harry --- libtransmission/net.c | 2 +- libtransmission/session.c | 23 +++++++++++++++++++---- libtransmission/session.h | 5 ++++- libtransmission/web.c | 5 ++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/libtransmission/net.c b/libtransmission/net.c index cb8471871..c838ecae6 100644 --- a/libtransmission/net.c +++ b/libtransmission/net.c @@ -315,7 +315,7 @@ tr_netOpenPeerSocket( tr_session * session, addrlen = setup_sockaddr( addr, port, &sock ); /* set source address */ - source_addr = tr_sessionGetPublicAddress( session, addr->type ); + source_addr = tr_sessionGetPublicAddress( session, addr->type, NULL ); assert( source_addr ); sourcelen = setup_sockaddr( source_addr, 0, &source_sock ); if( bind( s, ( struct sockaddr * ) &source_sock, sourcelen ) ) diff --git a/libtransmission/session.c b/libtransmission/session.c index c6b163032..9ae408c84 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -218,17 +218,32 @@ open_incoming_peer_port( tr_session * session ) } const tr_address* -tr_sessionGetPublicAddress( const tr_session * session, int tr_af_type ) +tr_sessionGetPublicAddress( const tr_session * session, int tr_af_type, tr_bool * is_default_value ) { + const char * default_value; const struct tr_bindinfo * bindinfo; switch( tr_af_type ) { - case TR_AF_INET: bindinfo = session->public_ipv4; break; - case TR_AF_INET6: bindinfo = session->public_ipv6; break; - default: bindinfo = NULL; break; + case TR_AF_INET: + bindinfo = session->public_ipv4; + default_value = TR_DEFAULT_BIND_ADDRESS_IPV4; + break; + + case TR_AF_INET6: + bindinfo = session->public_ipv6; + default_value = TR_DEFAULT_BIND_ADDRESS_IPV6; + break; + + default: + bindinfo = NULL; + default_value = ""; + break; } + if( is_default_value != NULL ) + *is_default_value = !strcmp( default_value, tr_ntop_non_ts( &bindinfo->addr ) ); + return bindinfo ? &bindinfo->addr : NULL; } diff --git a/libtransmission/session.h b/libtransmission/session.h index b644c3f4f..4b12a53b2 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -224,7 +224,10 @@ void tr_sessionUnlock( tr_session * ); tr_bool tr_sessionIsLocked( const tr_session * ); -const struct tr_address* tr_sessionGetPublicAddress( const tr_session *, int tr_af_type ); +const struct tr_address* tr_sessionGetPublicAddress( const tr_session * session, + int tr_af_type, + tr_bool * is_default_value ); + struct tr_bindsockets * tr_sessionGetBindSockets( tr_session * ); diff --git a/libtransmission/web.c b/libtransmission/web.c index 8fcbd0499..83899ecad 100644 --- a/libtransmission/web.c +++ b/libtransmission/web.c @@ -143,6 +143,7 @@ static CURL * createEasy( tr_session * s, struct tr_web_task * task ) { const tr_address * addr; + tr_bool is_default_value; CURL * e = curl_easy_init( ); const long verbose = getenv( "TR_CURL_VERBOSE" ) != NULL; char * cookie_filename = tr_buildPath( s->configDir, "cookies.txt", NULL ); @@ -167,7 +168,9 @@ createEasy( tr_session * s, struct tr_web_task * task ) curl_easy_setopt( e, CURLOPT_WRITEDATA, task ); curl_easy_setopt( e, CURLOPT_WRITEFUNCTION, writeFunc ); - if(( addr = tr_sessionGetPublicAddress( s, TR_AF_INET ))) + if((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET, &is_default_value ))) && !is_default_value ) + curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) ); + else if ((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET6, &is_default_value ))) && !is_default_value ) curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) ); if( task->range )