]> granicus.if.org Git - transmission/commitdiff
(trunk libT) Refactor ipv6 bind socket check
authorErick Turnquist <jhujhiti@adjectivism.org>
Thu, 18 Dec 2008 05:55:22 +0000 (05:55 +0000)
committerErick Turnquist <jhujhiti@adjectivism.org>
Thu, 18 Dec 2008 05:55:22 +0000 (05:55 +0000)
This will let the RPC server use the same test mechanism eventually. Networking code belongs in net.c anyway.

libtransmission/net.c
libtransmission/net.h
libtransmission/port-forwarding.c

index 9df3b47a65d795bce63325f97023cb076644ad62..2a61ae76ad18ef935902e08bfc2e21bd43692ea7 100644 (file)
@@ -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
  **********************************************************************/
index f49f80c97dae7358f8cdddab704bae04c816312b..bf556c15bda1c1a9b6e5743a680243117df11179 100644 (file)
@@ -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
  **********************************************************************/
index cc5e3cc964f375877c2ccbc197225504d171dee4..ba5924f482cb7ee4034125948f7839e59191b38a 100644 (file)
@@ -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 *