From d0634a78291a8d7702ba7a9ab3385739fb8d0293 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 26 Mar 2021 12:26:45 +0300 Subject: [PATCH 1/2] network: don't attempt to connect to the same node twice We can have multiple copies of the same address in the pool and we should only proceed to connect once per attempt. --- pkg/network/discovery.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pkg/network/discovery.go b/pkg/network/discovery.go index 9d7073226..25da5a5ba 100644 --- a/pkg/network/discovery.go +++ b/pkg/network/discovery.go @@ -45,6 +45,7 @@ type DefaultDiscovery struct { connectedAddrs map[string]bool goodAddrs map[string]capability.Capabilities unconnectedAddrs map[string]int + attempted map[string]bool isDead bool requestCh chan int pool chan string @@ -60,6 +61,7 @@ func NewDefaultDiscovery(addrs []string, dt time.Duration, ts Transporter) *Defa connectedAddrs: make(map[string]bool), goodAddrs: make(map[string]capability.Capabilities), unconnectedAddrs: make(map[string]int), + attempted: make(map[string]bool), requestCh: make(chan int), pool: make(chan string, maxPoolSize), } @@ -189,7 +191,11 @@ func (d *DefaultDiscovery) RegisterConnectedAddr(addr string) { } func (d *DefaultDiscovery) tryAddress(addr string) { - if err := d.transport.Dial(addr, d.dialTimeout); err != nil { + err := d.transport.Dial(addr, d.dialTimeout) + d.lock.Lock() + delete(d.attempted, addr) + d.lock.Unlock() + if err != nil { d.RegisterBadAddr(addr) d.RequestRemote(1) } @@ -225,14 +231,14 @@ func (d *DefaultDiscovery) run() { requested = r } case addr := <-d.pool: - d.lock.RLock() - addrIsConnected := d.connectedAddrs[addr] - d.lock.RUnlock() updatePoolCountMetric(d.PoolCount()) - if !addrIsConnected { + d.lock.Lock() + if !d.connectedAddrs[addr] && !d.attempted[addr] { + d.attempted[addr] = true go d.tryAddress(addr) requested-- } + d.lock.Unlock() default: // Empty pool var added int d.lock.Lock() From fa4380c9da0041083db4bd863eca846819c62968 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 26 Mar 2021 12:31:07 +0300 Subject: [PATCH 2/2] network: prevent putting duplicate addresses into pool from peer's data It can't be trusted. --- pkg/network/server.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/network/server.go b/pkg/network/server.go index e7272da9e..af5287cd1 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -916,9 +916,11 @@ func (s *Server) handleAddrCmd(p Peer, addrs *payload.AddressList) error { if !p.CanProcessAddr() { return errors.New("unexpected addr received") } + dups := make(map[string]bool) for _, a := range addrs.Addrs { addr, err := a.GetTCPAddress() - if err == nil { + if err == nil && !dups[addr] { + dups[addr] = true s.discovery.BackFill(addr) } }