]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Basic split-stack functionality
authorAmos Jeffries <amosjeffries@squid-cache.org>
Sun, 1 Aug 2010 12:54:47 +0000 (06:54 -0600)
committerAmos Jeffries <amosjeffries@squid-cache.org>
Sun, 1 Aug 2010 12:54:47 +0000 (06:54 -0600)
Enable split-stack detection by default.

There is now enough split-stack support to enable accepting IPv6 client
connections on systems with separate IPv4/IPv6 stacks. Also some limited
server connection capabilities (see tcp_outgoing_addr config hacks).

SNMP, ICP, HTCP listeners and outbound connections currently default to
IPv4-only on these systems to retain backward-compatibility.
But may be explicity configured to IPv6-only. There is no support as yet
for dual-protocol behaviour in the sockets of these three protocols.

src/forward.cc
src/htcp.cc
src/icp_v2.cc
src/ip/tools.cc
src/snmp_core.cc

index fcc5d009f4b462e6967816aef6a81cdfa20187d7..41461410caea3f87a0c6ca6fc0b5af3f6397d917 100644 (file)
@@ -48,6 +48,7 @@
 #include "Store.h"
 #include "icmp/net_db.h"
 #include "ip/Intercept.h"
+#include "ip/tools.h"
 
 static PSC fwdStartCompleteWrapper;
 static PF fwdServerClosedWrapper;
@@ -871,6 +872,24 @@ FwdState::connectStart()
 
     outgoing = getOutgoingAddr(request, fs->_peer);
 
+    // if IPv6 is disabled try to force IPv4-only outgoing.
+    if (!Ip::EnableIpv6 && !outgoing.SetIPv4()) {
+        debugs(50, 4, "fwdConnectStart: " << xstrerror());
+        ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request);
+        anErr->xerrno = errno;
+        fail(anErr);
+        self = NULL;   // refcounted
+        return;
+    }
+
+    // if IPv6 is split-stack, prefer IPv4
+    if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK) {
+        // NP: This is not a great choice of default,
+        // but with the current Internet being IPv4-majority has a higher success rate.
+        // if setting to IPv4 fails we dont care, that just means to use IPv6 outgoing.
+        outgoing.SetIPv4();
+    }
+
     tos = getOutgoingTOS(request);
 
     debugs(17, 3, "fwdConnectStart: got outgoing addr " << outgoing << ", tos " << tos);
index 71f427526997f0277ee5bbc82094bd0fcbaca8f7..88cbe91d914e4eb2e3f42b1ab49352d24b3e90a1 100644 (file)
@@ -1508,6 +1508,10 @@ htcpInit(void)
         debugs(31, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << incomingAddr << " is not an IPv4 address.");
         fatal("HTCP port cannot be opened.");
     }
+    /* split-stack for now requires default IPv4-only HTCP */
+    if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && incomingAddr.IsAnyAddr()) {
+        incomingAddr.SetIPv4();
+    }
 
     AsyncCall::Pointer call = asyncCall(31, 2,
                                         "htcpIncomingConnectionOpened",
@@ -1527,6 +1531,11 @@ htcpInit(void)
             debugs(31, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << outgoingAddr << " is not an IPv4 address.");
             fatal("HTCP port cannot be opened.");
         }
+        /* split-stack for now requires default IPv4-only HTCP */
+        if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && outgoingAddr.IsAnyAddr()) {
+            outgoingAddr.SetIPv4();
+        }
+
         enter_suid();
         htcpOutSocket = comm_open_listener(SOCK_DGRAM,
                                            IPPROTO_UDP,
index 781831e623679a7abf6b105ec44ca3f062dbb292..284e3abe3b91d45916a5f799355385b9feaac503 100644 (file)
@@ -691,6 +691,10 @@ icpConnectionsOpen(void)
         debugs(12, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << addr << " is not an IPv4 address.");
         fatal("ICP port cannot be opened.");
     }
+    /* split-stack for now requires default IPv4-only ICP */
+    if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && addr.IsAnyAddr()) {
+        addr.SetIPv4();
+    }
 
     AsyncCall::Pointer call = asyncCall(12, 2,
                                         "icpIncomingConnectionOpened",
@@ -712,6 +716,10 @@ icpConnectionsOpen(void)
             debugs(49, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << addr << " is not an IPv4 address.");
             fatal("ICP port cannot be opened.");
         }
+        /* split-stack for now requires default IPv4-only ICP */
+        if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && addr.IsAnyAddr()) {
+            addr.SetIPv4();
+        }
 
         theOutIcpConnection = comm_open_listener(SOCK_DGRAM,
                               IPPROTO_UDP,
index 20a6c16281eec0d7d59843e5a0ca2fcf3ba1a53a..d8ddf51efea1e648c4bbfad5e81079c694280b2d 100644 (file)
@@ -31,8 +31,6 @@
  */
 
 #include "config.h"
-//#include "compat/getaddrinfo.h"
-//#include "compat/getnameinfo.h"
 #include "Debug.h"
 #include "ip/tools.h"
 
@@ -67,9 +65,7 @@ Ip::ProbeTransport()
         EnableIpv6 |= IPV6_SPECIAL_V4MAPPING;
     } else {
         debugs(3, 2, "Detected split IPv4 and IPv6 stacks ...");
-        // EnableIpv6 |= IPV6_SPECIAL_SPLITSTACK;
-        // TODO: remove death when split-stack is supported.
-        EnableIpv6 = IPV6_OFF;
+        EnableIpv6 |= IPV6_SPECIAL_SPLITSTACK;
     }
     close(s);
 
index 57a93a1ee59960f65dd3a4970bceb36eeff28424..25d4d80a1cf1671e4755fba17319c57939c2c1c4 100644 (file)
@@ -34,7 +34,6 @@
 #include "cache_snmp.h"
 #include "comm.h"
 #include "ipc/StartListening.h"
-//#include "compat/strsep.h"
 #include "ip/Address.h"
 #include "ip/tools.h"
 
@@ -311,6 +310,11 @@ snmpConnectionOpen(void)
             debugs(49, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << Config.Addrs.snmp_incoming << " is not an IPv4 address.");
             fatal("SNMP port cannot be opened.");
         }
+        /* split-stack for now requires IPv4-only SNMP */
+        if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && Config.Addrs.snmp_incoming.IsAnyAddr()) {
+            Config.Addrs.snmp_incoming.SetIPv4();
+        }
+
         AsyncCall::Pointer call = asyncCall(49, 2,
                                             "snmpIncomingConnectionOpened",
                                             SnmpListeningStartedDialer(&snmpIncomingConnectionOpened));
@@ -328,6 +332,10 @@ snmpConnectionOpen(void)
                 debugs(49, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << Config.Addrs.snmp_outgoing << " is not an IPv4 address.");
                 fatal("SNMP port cannot be opened.");
             }
+            /* split-stack for now requires IPv4-only SNMP */
+            if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && Config.Addrs.snmp_outgoing.IsAnyAddr()) {
+                Config.Addrs.snmp_outgoing.SetIPv4();
+            }
             AsyncCall::Pointer call = asyncCall(49, 2,
                                                 "snmpOutgoingConnectionOpened",
                                                 SnmpListeningStartedDialer(&snmpOutgoingConnectionOpened));