Properly report bound addresses when using Tor#8
Conversation
Fix a bug where proxied address host was incorrectly set using the full byte buffer rather than reading the correct number of bytes (4 for IPv4 and 16 for IPv6).
Confirm bound address reported by the proxy is not an unspecified address to avoid returning an unhelpful value like "0.0.0.0:0" to the caller. For example, Tor will return an unspecified address rather than disclose the actual address it bound to. Fallback to the address of the connection to the proxy itself.
| if c.boundAddr != nil { | ||
| return c.boundAddr | ||
| ip := net.ParseIP(c.boundAddr.Host) | ||
| if ip != nil && !ip.IsUnspecified() { |
There was a problem hiding this comment.
The first commit makes sense and is an obvious bug fix.
This probably should be the following to match the described semantics:
| if ip != nil && !ip.IsUnspecified() { | |
| if ip == nil || !ip.IsUnspecified() { |
That would allow it to continue returning hostnames which is explicitly allowed by RFC 1928. Under the requests section (section 4) of the RFC, it explicitly allows for ATYP == DOMAINNAME: X'03.
Your diff, as written, would fail to parse a hostname making ip == nil and then fall through to return the local address of the local connection.
That said, I concede that, in practice, every SOCK5 proxy I've ever seen only ever returns IP addresses, so in practice, it really won't matter. Still, I think the suggestion code is strictly more accurate.
|
This is not something that should hold up this PR, because it is simply addresses the abstraction that already exists, and in that regard, it is fine for what it does. However, upon looking at this diff, I personally think the abstraction is not really all that accurate and it should probably be changed. The package is effectively treating the returned By reporting the proxy's bound address as Personally, I think it would make much more sense to return the actual local address of the connection made to the proxy, because that is in fact the connection we've made. Then, because the caller might also want to know details about the local address the proxy ultimately selected (say it's a multi-homed proxy, or maybe the proxy exposes a NAT address, etc) when it makes the separate connection on your behalf, I would expose that via something like That approach would keep the For a more concrete example of what I'm describing in case it isn't clear. Imagine the following setup:
Then you do: conn, err := proxy.Dial("tcp", 203.0.x.x:9108)
// err handling elidedWith the current abstraction, So now, if you were want to find out which interface the connection is using in the typical way everything else in Go works, you can't! e.g. if host(conn.LocalAddr()) == host(listener1.Addr() {
// Using interface associated with listener1
} else if host(conn.LocalAddr()) == host(listener2.Addr() {
// Using interface associated with listener2
}On the other hand, if it were changed in the way I think makes more sense, not only would that work, but if you want to know the address the proxy actually reported via |
I noticed when using dcrd over Tor that
getpeerinfowould return malformedaddrlocalvalues. Tracked that down to a bug which is fixed in the first commit. Then every address was reported as "0.0.0.0:0" which is fixed by the second commit.