From 76d2c49a1750d9a5a5e7b22bdc46330a702b114e Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 26 Nov 2020 15:49:45 +0100 Subject: [PATCH] lnd: fix Onion v2 support for Neutrino backends With this commit we make it possible to use an Onion v2 hidden service address as the Neutrino backend. This failed before because an .onion address cannot be looked up and converted into an IP address through the normal DNS resolving process, even when using a Tor socks proxy. Instead, we turn any v2 .onion address into a fake IPv6 representation before giving it to Neutrino's address manager and turn it back into an Onion host address when actually dialing. --- lnd.go | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lnd.go b/lnd.go index 11997d14..0643ba6f 100644 --- a/lnd.go +++ b/lnd.go @@ -1508,12 +1508,43 @@ func initNeutrinoBackend(cfg *Config, chainDir string) (*neutrino.ChainService, AddPeers: cfg.NeutrinoMode.AddPeers, ConnectPeers: cfg.NeutrinoMode.ConnectPeers, Dialer: func(addr net.Addr) (net.Conn, error) { + dialAddr := addr + if tor.IsOnionFakeIP(addr) { + // Because the Neutrino address manager only + // knows IP addresses, we need to turn any fake + // tcp6 address that actually encodes an Onion + // v2 address back into the hostname + // representation before we can pass it to the + // dialer. + var err error + dialAddr, err = tor.FakeIPToOnionHost(addr) + if err != nil { + return nil, err + } + } + return cfg.net.Dial( - addr.Network(), addr.String(), + dialAddr.Network(), dialAddr.String(), cfg.ConnectionTimeout, ) }, NameResolver: func(host string) ([]net.IP, error) { + if tor.IsOnionHost(host) { + // Neutrino internally uses btcd's address + // manager which only operates on an IP level + // and does not understand onion hosts. We need + // to turn an onion host into a fake + // representation of an IP address to make it + // possible to connect to a block filter backend + // that serves on an Onion v2 hidden service. + fakeIP, err := tor.OnionHostToFakeIP(host) + if err != nil { + return nil, err + } + + return []net.IP{fakeIP}, nil + } + addrs, err := cfg.net.LookupHost(host) if err != nil { return nil, err