User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en-US; rv:1.9) Gecko/2008051202 Firefox/3.0
Build Identifier: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en-US; rv:1.9) Gecko/2008051202 Firefox/3.0
When I try to reach sites that have an IPv4 and IPv6 address or only have an IPv6 address and I have a SOCKS5 proxy configured I get a blank page that says it's about:blank in the page info.
When doing a trace of all data being sent to the SOCKS5 proxy I see no requests for either the IPv6 address or IPv4 address (if it has one) of the site I'm trying to reach.
When I make Safari visit the same place, it works, and it does something I consider more correct, it sends a SOCKS5 request to connect to a 'Domain Name' address instead of an IPv4 or IPv6 address.
Steps to Reproduce:
1.Configure a SOCKS5 proxy in Advanced Network Settings in Firefox
A blank page
Google's IPv6 homepage.
If I configure a SOCKS5 proxy address of ::1 Firefox doesn't work at all. Every page is blank.
The problem I am having is exactly the same, even though I'm on Linux:
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008060507
SOCKS is a protocol that is hardcoded to work w/ IPv4. I'm sure some work is needed here...
I searched and found this bug while thinking about Bug 134105
--- Comment #126 from Gert Doering <firstname.lastname@example.org> 2007-11-16 07:43:05 PST ---
actually this functionality (servers-side DNS resolving for SOCKS5) is
something that would also help a lot if you connect to servers that have IPv6
addresses in DNS.
Right now, when Firefox is set to use a SOCKS proxy, and the target server has
IPv4 and IPv6, it will do *nothing* - it seems to decide internally "I want to
do IPv6, I cannot do that over SOCKS, so I don't do anything". It doesn't fall
back to IPv4 either. This can be worked around by turning off IPv6 in the
about:config - but turning off IPv6 is a workaround I really dislike.
As my laptop travels quite a lot between IPv6-enabled networks and networks
where I need to use SOCKS (and connect to servers that have IPv6), turning on
and off IPv6 all the time is a real nuisance.
Example server: http://www.space.net/
I looked at SOCKS 5 last night, it supports IPv6. I don't know if our implementation does...
Supporting IPv6 through SOCKS is the wrong route. What Firefox and Mozilla should do is use the name lookup mode of SOCKS 5 and connect to hostnames, not IPv4 or IPv6 addresses.
This may be a little difficult to work with .pac scripts since some of them ask for an address lookup of the host. I still think that address lookup should be deferred until the .pac script requests this, and even then hostname mode should be used for SOCKS 5 proxies.
This is what Safari does. I've taken to using Safari to browse IPv6 on this computer since Firefox doesn't work. I always use a SOCKS 5 proxy (my ssh client) so that all web traffic is tunneled over an encrypted link to my system at home so I can still be secure on a foreign and potentially hostile network.
SOCKS v5 has an internal data structure that explicitly supports IPv4, hostname (DNS/FQDN) and IPv6.
This is needed because the original URL might use any of the three data types.
I haven't looked at the SOCSK5 code, but this probably was not implemented when SOCKS5 was added (we had very little IPv6 support then).
The issues w/ PAC are probably related or dependent...
I looked at the implementation in these two files:
and it looks like at base the implementation supports both the IPv6 and domain name addressing modes of SOCKS5. I may have found the wrong files though.
I would like to compile my own Firefox but there is no stable version available yet through Mercurial and I'm unwilling to experiment to that degree. Otherwise I would do what I could to activate the various logging points and figure out exactly which code is being executed.
Note that you can work around this by enabling remote DNS resolution: go to about:config and set network.proxy.socks_remote_dns to true.
Created attachment 640358 [details] [diff] [review]
We fail to connect to IPv4 socks proxies if the destination address is IPv6 (or vice versa) because:
1. A new socket is created with PR_OpenTCPSocket(PR_AF_INET6) because the destination addr is IPv6.
2. It tries to connect to a socks proxy whose address family is IPv4 (PR_AF_INET).
3. The attempt fails because of address family mismatch.
We can't predict whether the socks proxy is IPv4 or not at the time of PR_OpenTCPSocket if the proxy address is given by a DNS name. Moreover, the PRFileDesc may be given by the lower IO layer. We have no control over the address family of the socket in this case.
So I had to swap the socket handle when address family mismatch was detected.
is beisi unavailble to do this? I don't know this code at all.
I just requested an additional review from you because I thought you knew the code, and would want to know how this fix worked. If I'm wrong go ahead and delete the review request.
Comment on attachment 640358 [details] [diff] [review]
biesi, let me know if you can't get to this and I'll take it
Let me try to summarize the current state of the bug as I understand it:
- This is a problem whenever connecting to a host through a proxy if one of them uses IPv6 and the other uses IPv6
- Even with network.proxy.socks_remote_dns=true, there is a problem because that always uses PR_AF_INET (https://mxr.mozilla.org/mozilla-central/source/netwerk/base/src/nsSocketTransport2.cpp#899)
This patch does a few things:
- Uses SOCKSv5 when the destination is IPv6, even when SOCKSv4 was the selected version
- When IPv6 is not supported on the host and the destination host is an IPv6 address, we convert the proxy address to a mapped v6 address (we can be sure that the proxy is v4 because we returned early when address families are equal). This works because NSPR puts a "fake" IPv6 layer on top of the stack which handles this case
- Otherwise we swap out the lower layer FD with the right socket type
Did I get this all right?
> one of them uses IPv6 and the other uses IPv6
one of them uses IPv4 and the other uses IPv6?
All others seem to be right. Thanks for the great summarization.
Comment on attachment 640358 [details] [diff] [review]
Review of attachment 640358 [details] [diff] [review]:
with the changes below, r=biesi
@@ +126,5 @@
> nsCString mDestinationHost;
> nsCString mProxyHost;
> PRInt32 mProxyPort;
> PRInt32 mVersion; // SOCKS version 4 or 5
> + PRInt32 mFamily;
I think it would be clearer to rename this mDestinationFamily...
@@ +291,5 @@
> PR_SetError(PR_BAD_ADDRESS_ERROR, 0);
> return PR_FAILURE;
> + // Try socks5 if the destination addrress is IPv6
this does make me a little uneasy, but I guess it's better to try SOCKS5 than to just fail.
@@ +338,5 @@
> +nsSOCKSSocketInfo::FixupAddressFamily(PRFileDesc *fd, PRNetAddr *proxy)
> + PRInt32 family = PR_NetAddrFamily(&mInternalProxyAddr);
...and to rename this one mProxyFamily, so that it's easy to see at a glance which is which.
Created attachment 644040 [details] [diff] [review]
patch for check in