]> granicus.if.org Git - transmission/commitdiff
(trunk libT) stop using ipv4-mapped listener sockets. this should have the added...
authorErick Turnquist <jhujhiti@adjectivism.org>
Sat, 7 Feb 2009 00:34:10 +0000 (00:34 +0000)
committerErick Turnquist <jhujhiti@adjectivism.org>
Sat, 7 Feb 2009 00:34:10 +0000 (00:34 +0000)
libtransmission/net.c
libtransmission/net.h
libtransmission/port-forwarding.c

index 618e498161a3275cbd6298db6237d36e3315b344..78bd7eef23a15523337e81f7cac89a00463bc8b8 100644 (file)
@@ -242,33 +242,22 @@ 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 )
+tr_bool
+tr_net_hasIPv6( 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;
+    static tr_bool alreadyDone = FALSE;
+    static tr_bool result      = FALSE;
+    int s;
     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 */
+        return result;
+    s = tr_netBindTCP( &tr_in6addr_any, port, TRUE );
+    if( s >= 0 || -s != EAFNOSUPPORT ) /* we support ipv6 */
     {
-        tr_netClose( s4 );
-        support.needs_inet4 = TRUE;
+        result = TRUE;
+        tr_netClose( s );
     }
-    if( s6 >= 0 )
-        tr_netClose( s6 );
     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;
     const int               type = SOCK_STREAM;
     int                     addrlen;
+    int                     retval;
 
-#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT )
-    int                optval;
+#if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT ) || defined( IPV6_V6ONLY )
+    int                optval = 1;
 #endif
 
     assert( tr_isAddress( addr ) );
@@ -549,10 +539,18 @@ tr_netBindTCP( const tr_address * addr, tr_port port, tr_bool suppressMsgs )
         return s;
 
 #ifdef SO_REUSEADDR
-    optval = 1;
     setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof( optval ) );
 #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 );
 
     if( bind( s, (struct sockaddr *) &sock,
index d8de8c5fb89d9ad564f727248e560a986f0d3cb1..cbe57b50c52c03124bfd1d745fe8464a7f9f0d83 100644 (file)
@@ -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 ); }
 
-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 );
+tr_bool tr_net_hasIPv6( tr_port );
 
 /***********************************************************************
  * Socket list housekeeping
index e014e120d57de1673183ba8847ee2b9b322b1862..37c4faab488d216e94611dbf5af2f2290aaf8f60 100644 (file)
@@ -224,17 +224,15 @@ sharedPulse( void * vshared )
 static tr_socketList *
 setupBindSockets( tr_port port )
 {
-    tr_net_af_support support = tr_net_getAFSupport( port );
+    tr_bool hasIPv6 = tr_net_hasIPv6( port );
     tr_socketList * socks = NULL;
-    if( support.has_inet6 )
+    if( hasIPv6 )
         socks = tr_socketListNew( &tr_in6addr_any );
-    if( support.needs_inet4 )
-    {
-        if( socks )
-            tr_socketListAppend( socks, &tr_inaddr_any );
-        else
-            socks = tr_socketListNew( &tr_inaddr_any );
-    }
+
+    if( socks )
+        tr_socketListAppend( socks, &tr_inaddr_any );
+    else
+        socks = tr_socketListNew( &tr_inaddr_any );
     return socks; /* Because the dryer gremlins won't */
 }