From: Amos Jeffries Date: Tue, 10 Aug 2010 10:33:04 +0000 (-0600) Subject: Add IPv6 wrappers around more outbound ports. X-Git-Tag: take1~401 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=715b5def01c89e96b5287c3087fd9e4d216efa88;p=thirdparty%2Fsquid.git Add IPv6 wrappers around more outbound ports. This protects TCP DNS links, peer probes and CONNECT tunnels against IPv4/IPv6 crossover in split-stack or IPv4-only systems. Also corrects the error message output on generated forwarding errors. --- diff --git a/src/dns_internal.cc b/src/dns_internal.cc index c709ddbc3f..ce0c5bd6f2 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -200,10 +200,15 @@ idnsAddNameserver(const char *buf) if (A.IsAnyAddr()) { debugs(78, 0, "WARNING: Squid does not accept " << A << " in DNS server specifications."); - A = "127.0.0.1"; + A.SetLocalhost(); debugs(78, 0, "Will be using " << A << " instead, assuming you meant that DNS is running on the same machine"); } + if (!Ip::EnableIpv6 && !A.SetIPv4()) { + debugs(78, DBG_IMPORTANT, "WARNING: IPv6 is disabled. Discarding " << A << " in DNS server specifications."); + return; + } + if (nns == nns_alloc) { int oldalloc = nns_alloc; ns *oldptr = nameservers; @@ -741,6 +746,12 @@ idnsInitVC(int ns) else addr = Config.Addrs.udp_incoming; + if (nameservers[ns].S.IsIPv4() && !addr.SetIPv4()) { + debugs(31, DBG_CRITICAL, "ERROR: Cannot contact DNS nameserver " << nameservers[ns].S << " from " << addr); + addr.SetAnyAddr(); + addr.SetIPv4(); + } + vc->queue = new MemBuf; vc->msg = new MemBuf; diff --git a/src/forward.cc b/src/forward.cc index 41461410ca..41f1fabb4d 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -874,9 +874,9 @@ FwdState::connectStart() // if IPv6 is disabled try to force IPv4-only outgoing. if (!Ip::EnableIpv6 && !outgoing.SetIPv4()) { - debugs(50, 4, "fwdConnectStart: " << xstrerror()); + debugs(50, 4, "fwdConnectStart: IPv6 is Disabled. Cannot connect from " << outgoing); ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); - anErr->xerrno = errno; + anErr->xerrno = EAFNOSUPPORT; fail(anErr); self = NULL; // refcounted return; diff --git a/src/neighbors.cc b/src/neighbors.cc index e0f0717fe0..1ac6cdd7ea 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1381,6 +1381,20 @@ peerProbeConnect(peer * p) Ip::Address temp(getOutgoingAddr(NULL,p)); + // if IPv6 is disabled try to force IPv4-only outgoing. + if (!Ip::EnableIpv6 && !temp.SetIPv4()) { + debugs(50, DBG_IMPORTANT, "WARNING: IPv6 is disabled. Failed to use " << temp << " to probe " << p->host); + return ret; + } + + // 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. + temp.SetIPv4(); + } + fd = comm_open(SOCK_STREAM, IPPROTO_TCP, temp, COMM_NONBLOCKING, p->host); if (fd < 0) diff --git a/src/tunnel.cc b/src/tunnel.cc index 1812b015ff..f308bc498b 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -641,6 +641,25 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr) statCounter.server.other.requests++; /* Create socket. */ Ip::Address temp = getOutgoingAddr(request,NULL); + + // if IPv6 is disabled try to force IPv4-only outgoing. + if (!Ip::EnableIpv6 && !temp.SetIPv4()) { + debugs(50, 4, "tunnelStart: IPv6 is Disabled. Tunnel failed from " << temp); + ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + anErr->xerrno = EAFNOSUPPORT; + 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. + temp.SetIPv4(); + } + int flags = COMM_NONBLOCKING; if (request->flags.spoof_client_ip) { flags |= COMM_TRANSPARENT;