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.
#include "Store.h"
#include "icmp/net_db.h"
#include "ip/Intercept.h"
+#include "ip/tools.h"
static PSC fwdStartCompleteWrapper;
static PF fwdServerClosedWrapper;
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);
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",
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,
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",
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,
*/
#include "config.h"
-//#include "compat/getaddrinfo.h"
-//#include "compat/getnameinfo.h"
#include "Debug.h"
#include "ip/tools.h"
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);
#include "cache_snmp.h"
#include "comm.h"
#include "ipc/StartListening.h"
-//#include "compat/strsep.h"
#include "ip/Address.h"
#include "ip/tools.h"
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));
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));