Closed Bug 411119 Opened 15 years ago Closed 15 years ago

Re-enabling IPv6 on mac breaks SOCKS support for localhost


(Core :: Networking, defect, P1)






(Reporter: bugzilla, Assigned: david)



(Keywords: regression)


(2 files)

Turning on ipv6 on again on mac (Bug 408881) broke SOCKS proxy support.  With SOCKS enabled and configured with a host and port, pages do not load and page info shows about:blank as the location.  (I did have pages load a few times but I think that was just because I neglected to nuke the cache; it is stored separately from the profile on mac)

run `tcpdump -i lo0 'port 8000'` as root and watch for output after the initial couple lines
make a new profile
rm -rf "$profilepath"/* && cat > "$profilepath"/prefs.js <<'EOF'
user_pref("network.proxy.socks", "localhost");
user_pref("network.proxy.socks_port", 8000);
user_pref("network.proxy.type", 1);
start firefox with said profile

default homepage and firstrun page appear in tabs, load completely

2 blank tabs with page info showing location about:blank (a couple times real content showed but that it likely because I forgot to nuke the profile's cache)

throw in
user_pref("network.dns.disableIPv6", true);
in addition and everything works fine.

regression range:

Note this is broken with local and remote dns queries. (network.proxy.socks_remote_dns)
Flags: blocking1.9?
Forgot to mention: tcpdump results in no additional output with broken SOCKS and plenty of output with functional SOCKS, indicating that no connection is made (or refused) and eliminates the possibility of this being dependent on the proxy server.
Does socks work if you configure the host as instead of localhost?

If so, what is happening is probably this: on the Mac with IPv6 enabled, "localhost" resolves to ::1. Firefox is connecting to "localhost", i.e. ::1, and the SOCKS proxy running on your local host is IPv4-only, so the connection is refused.

If that's the case, then this bug is arguably invalid: you have configured Firefox to use a SOCKS proxy (localhost) that does not exist (since, if IPv6 is enabled, "localhost" means "::1").

Note that this is not the case under Linux, where localhost is always and ::1 is ip6-localhost. I remember wondering about the reason for that at the time :)
(In reply to comment #2)
Yup, that seems to be it.  I guess this is really just "SOCKS chokes on IPv6 proxy server".
Severity: major → normal
well does your socks server listen on ::1? Try:

netstat -ln | grep 8080

What does that show?
Jeremy, what does your /etc/hosts file look like? If localhost maps to both and ::1, then it's reasonable to assume that the SOCKS proxy code should retry over IPv4 if the IPv6 connection fails.
Slightly more verbose note re Lorenzo's comment;

On OS X 10.4, it appears that despite the intelligence in getaddrinfo for stubbornly not returning IPv6 addresses unless the system has successfully connected to an IPv6 network since the last reboot, loopback always returns
both the IPv4 and the IPv6 address.

This is probably because:

1. /etc/hosts on OS X 10.4 contains explicitly and ::1

2. Even if you "ip6 -x" to remove all IPv6 addresses on all interfaces, the ::1
   address is not removed from loopback

Really, if SOCKS is listening only on, then the SOCKS code should
quickly fail to connect to ::1 then successfully connect to  But
as per your comment above, it looks like it doesn't.
BTW, is this a test case or a real use case?  Using a SOCKS proxy on localhost seems like a fairly unlikely thing to want to do.
The problem seems to be the code at

    // Sync resolve the proxy hostname.
    PRNetAddr proxyAddr;
        nsCOMPtr<nsIDNSService> dns;
        nsCOMPtr<nsIDNSRecord> rec; 
        nsresult rv;

        dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
        if (NS_FAILED(rv))
            return PR_FAILURE;

        rv = dns->Resolve(proxyHost, 0, getter_AddRefs(rec));
        if (NS_FAILED(rv))
            return PR_FAILURE;

        rv = rec->GetNextAddr(info->ProxyPort(), &proxyAddr);
        if (NS_FAILED(rv))
            return PR_FAILURE;
    // Connect to the proxy server.
    status = fd->lower->methods->connect(fd->lower, &proxyAddr, connectWait);

The connection code needs to look like this:

dns lookup
while IP addresses left to try
advance to next address in dns results
if connect succeeds break
Here's a trivial (but untested) patch to address this.
If you could test, that would be great :)
Jeremy, are you able to confirm if this patch (the 2nd one) resolves this issue for you?

Moving to blocking - clearly bad regression
Flags: blocking1.9? → blocking1.9+
Priority: -- → P1
Summary: turning on ipv6 on again on mac (Bug 408881) broke SOCKS proxy support → Re-enabling IPv6 on mac breaks SOCKS support for localhost
Assignee: nobody → david
Keywords: checkin-needed
Checking in netwerk/socket/base/nsSOCKSIOLayer.cpp;
/cvsroot/mozilla/netwerk/socket/base/nsSOCKSIOLayer.cpp,v  <--  nsSOCKSIOLayer.cpp
new revision: 1.19; previous revision: 1.18
Closed: 15 years ago
Keywords: checkin-needed
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.9 M11
Sorry, I didn't get back to you sooner.

trunk 20080107_2221 WFM with localhost as proxy.

(In reply to comment #7)
> BTW, is this a test case or a real use case?  Using a SOCKS proxy on localhost
> seems like a fairly unlikely thing to want to do.

Yes.  2 examples:
* tunneling a cleartext proxy connection through stunnel/ssh
* using ssh's builtin SOCKS emulation to route browser connections through an ssh server.

My guess is most people using a proxy bound to loopback would end up specifying localhost in Firefox prefs unless told to do something different. (and for that matter existing tutorials/docs)
You need to log in before you can comment on or make changes to this bug.