mirror of
https://github.com/transmission/transmission
synced 2025-02-26 16:02:51 +00:00
(trunk libT) stop using ipv4-mapped listener sockets. this should have the added effect of fixing #1789
This commit is contained in:
parent
f3a2a35952
commit
94b98030cb
3 changed files with 31 additions and 41 deletions
|
@ -242,33 +242,22 @@ tr_compareAddresses( const tr_address * a, const tr_address * b)
|
||||||
return memcmp( &a->addr, &b->addr, addrlen );
|
return memcmp( &a->addr, &b->addr, addrlen );
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_net_af_support
|
tr_bool
|
||||||
tr_net_getAFSupport( tr_port port )
|
tr_net_hasIPv6( tr_port port )
|
||||||
{
|
{
|
||||||
/* Do we care if an address is in use? Probably not, since it will be
|
static tr_bool alreadyDone = FALSE;
|
||||||
* caught later. This will only set up the list of sockets to bind. */
|
static tr_bool result = FALSE;
|
||||||
static tr_bool alreadyDone = FALSE;
|
int s;
|
||||||
static tr_net_af_support support = { FALSE, FALSE };
|
|
||||||
int s4, s6;
|
|
||||||
if( alreadyDone )
|
if( alreadyDone )
|
||||||
return support;
|
return result;
|
||||||
s6 = tr_netBindTCP( &tr_in6addr_any, port, TRUE );
|
s = tr_netBindTCP( &tr_in6addr_any, port, TRUE );
|
||||||
if( s6 >= 0 || -s6 != EAFNOSUPPORT ) /* we support ipv6 */
|
if( s >= 0 || -s != EAFNOSUPPORT ) /* we support ipv6 */
|
||||||
{
|
{
|
||||||
listen( s6, 1 );
|
result = TRUE;
|
||||||
support.has_inet6 = TRUE;
|
tr_netClose( s );
|
||||||
}
|
}
|
||||||
s4 = tr_netBindTCP( &tr_inaddr_any, port, TRUE );
|
|
||||||
if( s4 >= 0 ) /* we bound *with* the ipv6 socket bound (need both)
|
|
||||||
* or only have ipv4 */
|
|
||||||
{
|
|
||||||
tr_netClose( s4 );
|
|
||||||
support.needs_inet4 = TRUE;
|
|
||||||
}
|
|
||||||
if( s6 >= 0 )
|
|
||||||
tr_netClose( s6 );
|
|
||||||
alreadyDone = TRUE;
|
alreadyDone = TRUE;
|
||||||
return support;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -537,9 +526,10 @@ tr_netBindTCP( const tr_address * addr, tr_port port, tr_bool suppressMsgs )
|
||||||
struct sockaddr_storage sock;
|
struct sockaddr_storage sock;
|
||||||
const int type = SOCK_STREAM;
|
const int type = SOCK_STREAM;
|
||||||
int addrlen;
|
int addrlen;
|
||||||
|
int retval;
|
||||||
|
|
||||||
#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT )
|
#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT ) || defined( IPV6_V6ONLY )
|
||||||
int optval;
|
int optval = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( tr_isAddress( addr ) );
|
assert( tr_isAddress( addr ) );
|
||||||
|
@ -549,10 +539,18 @@ tr_netBindTCP( const tr_address * addr, tr_port port, tr_bool suppressMsgs )
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
#ifdef SO_REUSEADDR
|
#ifdef SO_REUSEADDR
|
||||||
optval = 1;
|
|
||||||
setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof( optval ) );
|
setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof( optval ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef IPV6_V6ONLY
|
||||||
|
if( retval = setsockopt( s, IPPROTO_IPV6, IPV6_V6ONLY, &optval,
|
||||||
|
sizeof( optval ) ) == -1 ) {
|
||||||
|
/* the kernel may not support this. if not, ignore it */
|
||||||
|
if( errno != ENOPROTOOPT )
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
addrlen = setup_sockaddr( addr, htons( port ), &sock );
|
addrlen = setup_sockaddr( addr, htons( port ), &sock );
|
||||||
|
|
||||||
if( bind( s, (struct sockaddr *) &sock,
|
if( bind( s, (struct sockaddr *) &sock,
|
||||||
|
|
|
@ -94,13 +94,7 @@ void tr_suspectAddress( const tr_address * a, const char * source );
|
||||||
|
|
||||||
static TR_INLINE tr_bool tr_isAddress( const tr_address * a ) { return ( a != NULL ) && ( a->type==TR_AF_INET || a->type==TR_AF_INET6 ); }
|
static TR_INLINE tr_bool tr_isAddress( const tr_address * a ) { return ( a != NULL ) && ( a->type==TR_AF_INET || a->type==TR_AF_INET6 ); }
|
||||||
|
|
||||||
typedef struct tr_net_af_support
|
tr_bool tr_net_hasIPv6( tr_port );
|
||||||
{
|
|
||||||
tr_bool has_inet6;
|
|
||||||
tr_bool needs_inet4;
|
|
||||||
} tr_net_af_support;
|
|
||||||
|
|
||||||
tr_net_af_support tr_net_getAFSupport( tr_port );
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Socket list housekeeping
|
* Socket list housekeeping
|
||||||
|
|
|
@ -224,17 +224,15 @@ sharedPulse( void * vshared )
|
||||||
static tr_socketList *
|
static tr_socketList *
|
||||||
setupBindSockets( tr_port port )
|
setupBindSockets( tr_port port )
|
||||||
{
|
{
|
||||||
tr_net_af_support support = tr_net_getAFSupport( port );
|
tr_bool hasIPv6 = tr_net_hasIPv6( port );
|
||||||
tr_socketList * socks = NULL;
|
tr_socketList * socks = NULL;
|
||||||
if( support.has_inet6 )
|
if( hasIPv6 )
|
||||||
socks = tr_socketListNew( &tr_in6addr_any );
|
socks = tr_socketListNew( &tr_in6addr_any );
|
||||||
if( support.needs_inet4 )
|
|
||||||
{
|
if( socks )
|
||||||
if( socks )
|
tr_socketListAppend( socks, &tr_inaddr_any );
|
||||||
tr_socketListAppend( socks, &tr_inaddr_any );
|
else
|
||||||
else
|
socks = tr_socketListNew( &tr_inaddr_any );
|
||||||
socks = tr_socketListNew( &tr_inaddr_any );
|
|
||||||
}
|
|
||||||
return socks; /* Because the dryer gremlins won't */
|
return socks; /* Because the dryer gremlins won't */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue