From ef38b12fdabf014f22f3a26b2773466e030ccdb3 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Tue, 25 Aug 2020 12:50:48 +0800 Subject: [PATCH] multi: use timeout field in dialer --- chainregistry.go | 5 ++++- chanrestore.go | 2 +- discovery/bootstrapper.go | 16 ++++++++++++---- pilot.go | 4 +++- watchtower/wtclient/client.go | 3 ++- watchtower/wtclient/client_test.go | 16 +++++++++------- watchtower/wtclient/interface.go | 18 ++++-------------- 7 files changed, 35 insertions(+), 29 deletions(-) diff --git a/chainregistry.go b/chainregistry.go index f5d4ac79..59376765 100644 --- a/chainregistry.go +++ b/chainregistry.go @@ -767,7 +767,10 @@ func initNeutrinoBackend(cfg *Config, chainDir string) (*neutrino.ChainService, AddPeers: cfg.NeutrinoMode.AddPeers, ConnectPeers: cfg.NeutrinoMode.ConnectPeers, Dialer: func(addr net.Addr) (net.Conn, error) { - return cfg.net.Dial(addr.Network(), addr.String()) + return cfg.net.Dial( + addr.Network(), addr.String(), + cfg.ConnectionTimeout, + ) }, NameResolver: func(host string) ([]net.IP, error) { addrs, err := cfg.net.LookupHost(host) diff --git a/chanrestore.go b/chanrestore.go index c42f0de3..02696545 100644 --- a/chanrestore.go +++ b/chanrestore.go @@ -271,7 +271,7 @@ func (s *server) ConnectPeer(nodePub *btcec.PublicKey, addrs []net.Addr) error { // Attempt to connect to the peer using this full address. If // we're unable to connect to them, then we'll try the next // address in place of it. - err := s.ConnectToPeer(netAddr, true) + err := s.ConnectToPeer(netAddr, true, s.cfg.ConnectionTimeout) // If we're already connected to this peer, then we don't // consider this an error, so we'll exit here. diff --git a/discovery/bootstrapper.go b/discovery/bootstrapper.go index 8291ff22..6aced598 100644 --- a/discovery/bootstrapper.go +++ b/discovery/bootstrapper.go @@ -287,6 +287,10 @@ type DNSSeedBootstrapper struct { // the network seed. dnsSeeds [][2]string net tor.Net + + // timeout is the maximum amount of time a dial will wait for a connect to + // complete. + timeout time.Duration } // A compile time assertion to ensure that DNSSeedBootstrapper meets the @@ -300,8 +304,10 @@ var _ NetworkPeerBootstrapper = (*ChannelGraphBootstrapper)(nil) // used as a fallback for manual TCP resolution in the case of an error // receiving the UDP response. The second host should return a single A record // with the IP address of the authoritative name server. -func NewDNSSeedBootstrapper(seeds [][2]string, net tor.Net) NetworkPeerBootstrapper { - return &DNSSeedBootstrapper{dnsSeeds: seeds, net: net} +func NewDNSSeedBootstrapper( + seeds [][2]string, net tor.Net, + timeout time.Duration) NetworkPeerBootstrapper { + return &DNSSeedBootstrapper{dnsSeeds: seeds, net: net, timeout: timeout} } // fallBackSRVLookup attempts to manually query for SRV records we need to @@ -327,7 +333,7 @@ func (d *DNSSeedBootstrapper) fallBackSRVLookup(soaShim string, // Once we have the IP address, we'll establish a TCP connection using // port 53. dnsServer := net.JoinHostPort(addrs[0], "53") - conn, err := d.net.Dial("tcp", dnsServer) + conn, err := d.net.Dial("tcp", dnsServer, d.timeout) if err != nil { return nil, err } @@ -389,7 +395,9 @@ search: // obtain a random sample of the encoded public keys of nodes. // We use the lndLookupSRV function for this task. primarySeed := dnsSeedTuple[0] - _, addrs, err := d.net.LookupSRV("nodes", "tcp", primarySeed) + _, addrs, err := d.net.LookupSRV( + "nodes", "tcp", primarySeed, d.timeout, + ) if err != nil { log.Tracef("Unable to lookup SRV records via "+ "primary seed (%v): %v", primarySeed, err) diff --git a/pilot.go b/pilot.go index 3bd2436d..1078a43d 100644 --- a/pilot.go +++ b/pilot.go @@ -226,7 +226,9 @@ func initAutoPilot(svr *server, cfg *lncfg.AutoPilot, "address type %T", addr) } - err := svr.ConnectToPeer(lnAddr, false) + err := svr.ConnectToPeer( + lnAddr, false, svr.cfg.ConnectionTimeout, + ) if err != nil { // If we weren't able to connect to the // peer at this address, then we'll move diff --git a/watchtower/wtclient/client.go b/watchtower/wtclient/client.go index e85ea9cd..b093e744 100644 --- a/watchtower/wtclient/client.go +++ b/watchtower/wtclient/client.go @@ -14,6 +14,7 @@ import ( "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/watchtower/wtdb" "github.com/lightningnetwork/lnd/watchtower/wtpolicy" "github.com/lightningnetwork/lnd/watchtower/wtserver" @@ -137,7 +138,7 @@ type Config struct { // Dial connects to an addr using the specified net and returns the // connection object. - Dial Dial + Dial tor.DialFunc // AuthDialer establishes a brontide connection over an onion or clear // network. diff --git a/watchtower/wtclient/client_test.go b/watchtower/wtclient/client_test.go index caabf693..166ab228 100644 --- a/watchtower/wtclient/client_test.go +++ b/watchtower/wtclient/client_test.go @@ -16,6 +16,7 @@ import ( "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/watchtower/blob" "github.com/lightningnetwork/lnd/watchtower/wtclient" "github.com/lightningnetwork/lnd/watchtower/wtdb" @@ -84,7 +85,9 @@ func newMockNet(cb func(wtserver.Peer)) *mockNet { } } -func (m *mockNet) Dial(network string, address string) (net.Conn, error) { +func (m *mockNet) Dial(network string, address string, + timeout time.Duration) (net.Conn, error) { + return nil, nil } @@ -100,8 +103,9 @@ func (m *mockNet) ResolveTCPAddr(network string, address string) (*net.TCPAddr, panic("not implemented") } -func (m *mockNet) AuthDial(local keychain.SingleKeyECDH, netAddr *lnwire.NetAddress, - dialer func(string, string) (net.Conn, error)) (wtserver.Peer, error) { +func (m *mockNet) AuthDial(local keychain.SingleKeyECDH, + netAddr *lnwire.NetAddress, + dialer tor.DialFunc) (wtserver.Peer, error) { localPk := local.PubKey() localAddr := &net.TCPAddr{ @@ -433,10 +437,8 @@ func newHarness(t *testing.T, cfg harnessCfg) *testHarness { clientDB := wtmock.NewClientDB() clientCfg := &wtclient.Config{ - Signer: signer, - Dial: func(string, string) (net.Conn, error) { - return nil, nil - }, + Signer: signer, + Dial: mockNet.Dial, DB: clientDB, AuthDial: mockNet.AuthDial, SecretKeyRing: wtmock.NewSecretKeyRing(), diff --git a/watchtower/wtclient/interface.go b/watchtower/wtclient/interface.go index d532ee24..395e9576 100644 --- a/watchtower/wtclient/interface.go +++ b/watchtower/wtclient/interface.go @@ -4,9 +4,9 @@ import ( "net" "github.com/btcsuite/btcd/btcec" - "github.com/lightningnetwork/lnd/brontide" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/watchtower/wtdb" "github.com/lightningnetwork/lnd/watchtower/wtserver" ) @@ -95,22 +95,12 @@ type DB interface { AckUpdate(id *wtdb.SessionID, seqNum, lastApplied uint16) error } -// Dial connects to an addr using the specified net and returns the connection -// object. -type Dial func(net, addr string) (net.Conn, error) - // AuthDialer connects to a remote node using an authenticated transport, such as // brontide. The dialer argument is used to specify a resolver, which allows // this method to be used over Tor or clear net connections. -type AuthDialer func(localKey keychain.SingleKeyECDH, netAddr *lnwire.NetAddress, - dialer func(string, string) (net.Conn, error)) (wtserver.Peer, error) - -// AuthDial is the watchtower client's default method of dialing. -func AuthDial(localKey keychain.SingleKeyECDH, netAddr *lnwire.NetAddress, - dialer func(string, string) (net.Conn, error)) (wtserver.Peer, error) { - - return brontide.Dial(localKey, netAddr, dialer) -} +type AuthDialer func(localKey keychain.SingleKeyECDH, + netAddr *lnwire.NetAddress, + dialer tor.DialFunc) (wtserver.Peer, error) // ECDHKeyRing abstracts the ability to derive shared ECDH keys given a // description of the derivation path of a private key.