mirror of
https://github.com/transmission/transmission
synced 2024-12-25 01:03:01 +00:00
(trunk libT) Refactor ipv6 bind socket check
This will let the RPC server use the same test mechanism eventually. Networking code belongs in net.c anyway.
This commit is contained in:
parent
53b730420f
commit
72ee19dcca
3 changed files with 41 additions and 15 deletions
|
@ -155,6 +155,35 @@ tr_compareAddresses( const tr_address * a, const tr_address * b)
|
|||
return memcmp( &a->addr, &b->addr, addrlen );
|
||||
}
|
||||
|
||||
tr_net_af_support
|
||||
tr_net_getAFSupport( tr_port port )
|
||||
{
|
||||
/* Do we care if an address is in use? Probably not, since it will be
|
||||
* caught later. This will only set up the list of sockets to bind. */
|
||||
static tr_bool alreadyDone = FALSE;
|
||||
static tr_net_af_support support = { FALSE, FALSE };
|
||||
int s4, s6;
|
||||
if( alreadyDone )
|
||||
return support;
|
||||
s6 = tr_netBindTCP( &tr_in6addr_any, port, TRUE );
|
||||
if( s6 >= 0 || -s6 != EAFNOSUPPORT ) /* we support ipv6 */
|
||||
{
|
||||
listen( s6, 1 );
|
||||
support.has_inet6 = TRUE;
|
||||
}
|
||||
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;
|
||||
return support;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Socket list housekeeping
|
||||
**********************************************************************/
|
||||
|
|
|
@ -87,6 +87,14 @@ void tr_normalizeV4Mapped( tr_address * const addr );
|
|||
|
||||
tr_bool tr_isAddress( const tr_address * a );
|
||||
|
||||
typedef struct tr_net_af_support
|
||||
{
|
||||
tr_bool has_inet6;
|
||||
tr_bool needs_inet4;
|
||||
} tr_net_af_support;
|
||||
|
||||
tr_net_af_support tr_net_getAFSupport( tr_port );
|
||||
|
||||
/***********************************************************************
|
||||
* Socket list housekeeping
|
||||
**********************************************************************/
|
||||
|
|
|
@ -234,29 +234,18 @@ sharedPulse( void * vshared )
|
|||
static tr_socketList *
|
||||
setupBindSockets( tr_port port )
|
||||
{
|
||||
/* Do we care if an address is in use? Probably not, since it will be
|
||||
* caught later. This will only set up the list of sockets to bind. */
|
||||
int s4, s6;
|
||||
tr_net_af_support support = tr_net_getAFSupport( port );
|
||||
tr_socketList * socks = NULL;
|
||||
s6 = tr_netBindTCP( &tr_in6addr_any, port, TRUE );
|
||||
if( s6 >= 0 || -s6 != EAFNOSUPPORT ) /* we support ipv6 */
|
||||
{
|
||||
if( support.has_inet6 )
|
||||
socks = tr_socketListNew( &tr_in6addr_any );
|
||||
listen( s6, 1 );
|
||||
}
|
||||
s4 = tr_netBindTCP( &tr_inaddr_any, port, TRUE );
|
||||
if( s4 >= 0 ) /* we bound *with* the ipv6 socket bound (need both)
|
||||
* or only have ipv4 */
|
||||
if( support.needs_inet4 )
|
||||
{
|
||||
if( socks )
|
||||
tr_socketListAppend( socks, &tr_inaddr_any );
|
||||
else
|
||||
socks = tr_socketListNew( &tr_inaddr_any );
|
||||
tr_netClose( s4 );
|
||||
}
|
||||
if( s6 >= 0 )
|
||||
tr_netClose( s6 );
|
||||
return socks;
|
||||
return socks; /* Because the dryer gremlins won't */
|
||||
}
|
||||
|
||||
tr_shared *
|
||||
|
|
Loading…
Reference in a new issue