diff --git a/lncfg/address.go b/lncfg/address.go index 986a8905..0d33d6b3 100644 --- a/lncfg/address.go +++ b/lncfg/address.go @@ -121,6 +121,18 @@ func IsLoopback(addr string) bool { return false } +// isIPv6Host returns true if the host is IPV6 and false otherwise. +func isIPv6Host(host string) bool { + 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. func IsUnix(addr net.Addr) bool { return strings.HasPrefix(addr.Network(), "unix") @@ -217,13 +229,31 @@ 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) } - 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 } }