From 80eb5dbece6b58602ed83ecf831ca77a06d7937f Mon Sep 17 00:00:00 2001 From: eugene Date: Fri, 5 Feb 2021 15:37:39 -0500 Subject: [PATCH 1/3] lncfg: add isIPv6Host helper to force v6 addrs through system resolver With this commit, if --tor.active is specified, then IPv6 addresses will no longer go through the connmgr.TorLookupIP function from btcd. This function does not have proper IPv6 support and would fail with the error "tor general error". Instead, use the system resolver. --- lncfg/address.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lncfg/address.go b/lncfg/address.go index 84a90ce9..0681be96 100644 --- a/lncfg/address.go +++ b/lncfg/address.go @@ -121,6 +121,12 @@ func IsLoopback(addr string) bool { return false } +// isIPv6Host returns true if the host is IPV6 and false otherwise. +func isIPv6Host(host string) bool { + // An IPv4 host without the port shouldn't have a colon. + return strings.Contains(host, ":") +} + // IsUnix returns true if an address describes an Unix socket address. func IsUnix(addr net.Addr) bool { return strings.HasPrefix(addr.Network(), "unix") @@ -217,9 +223,10 @@ func ParseAddressString(strAddress string, defaultPort string, } // Otherwise, we'll attempt the resolve the host. The Tor - // resolver is unable to resolve local addresses, so we'll use - // the system resolver instead. - if rawHost == "" || IsLoopback(rawHost) { + // resolver is unable to resolve local or IPv6 addresses, so + // we'll use the system resolver instead. + if rawHost == "" || IsLoopback(rawHost) || + isIPv6Host(rawHost) { return net.ResolveTCPAddr("tcp", addrWithPort) } From 099efadd92fd90527163e26ededfd26db0315dcb Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Feb 2021 18:35:44 -0800 Subject: [PATCH 2/3] lncfg: use net.ParseIP to detect IPv6 addresses --- lncfg/address.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lncfg/address.go b/lncfg/address.go index 0681be96..9f91552f 100644 --- a/lncfg/address.go +++ b/lncfg/address.go @@ -123,8 +123,14 @@ func IsLoopback(addr string) bool { // isIPv6Host returns true if the host is IPV6 and false otherwise. func isIPv6Host(host string) bool { - // An IPv4 host without the port shouldn't have a colon. - return strings.Contains(host, ":") + v6Addr := net.ParseIP(host) + if v6Addr == nil { + return false + } + + // The documentation states that if the IP address is an IPv6 address, + // then To4() will return nil. + return v6Addr.To4() == nil } // IsUnix returns true if an address describes an Unix socket address. From e41091a765e305e12137ef6734e7b7aee4be079e Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Feb 2021 18:36:54 -0800 Subject: [PATCH 3/3] lncfg: detect tor resolution error case and fallback to system resolver In this commit, we fix a bug that would cause resolution of items in /etc/hosts (or the like) to fail as Tor wouldn't recognize them as proper host names. With this commit, we'll catch this error and fall back to the system's resolver. --- lncfg/address.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lncfg/address.go b/lncfg/address.go index 9f91552f..4b8c3e9a 100644 --- a/lncfg/address.go +++ b/lncfg/address.go @@ -233,10 +233,27 @@ func ParseAddressString(strAddress string, defaultPort string, // we'll use the system resolver instead. if rawHost == "" || IsLoopback(rawHost) || isIPv6Host(rawHost) { + return net.ResolveTCPAddr("tcp", addrWithPort) } - return tcpResolver("tcp", addrWithPort) + // If we've reached this point, then it's possible that this + // resolve returns an error if it isn't able to resolve the + // host. For eaxmple, local entries in /etc/hosts will fail to + // be resolved by Tor. In order to handle this case, we'll fall + // back to the normal system resolver if we fail with an + // identifiable error. + addr, err := tcpResolver("tcp", addrWithPort) + if err != nil { + torErrStr := "tor host is unreachable" + if strings.Contains(err.Error(), torErrStr) { + return net.ResolveTCPAddr("tcp", addrWithPort) + } + + return nil, err + } + + return addr, nil } }