network: don't try too many connections

Consider mainnet, it has an AttemptConnPeers of 20, so may already have 3
peers and request 20 more, then have 4th connected and attemtp 20 more again,
this leads to a huge number of connections easily.
This commit is contained in:
Roman Khimov 2022-11-17 18:03:04 +03:00
parent 6bce973ac2
commit 075a54192c

View file

@ -49,6 +49,7 @@ type DefaultDiscovery struct {
goodAddrs map[string]capability.Capabilities goodAddrs map[string]capability.Capabilities
unconnectedAddrs map[string]int unconnectedAddrs map[string]int
attempted map[string]bool attempted map[string]bool
outstanding int32
optimalFanOut int32 optimalFanOut int32
networkSize int32 networkSize int32
requestCh chan int requestCh chan int
@ -119,6 +120,8 @@ func (d *DefaultDiscovery) pushToPoolOrDrop(addr string) {
// RequestRemote tries to establish a connection with n nodes. // RequestRemote tries to establish a connection with n nodes.
func (d *DefaultDiscovery) RequestRemote(requested int) { func (d *DefaultDiscovery) RequestRemote(requested int) {
outstanding := int(atomic.LoadInt32(&d.outstanding))
requested -= outstanding
for ; requested > 0; requested-- { for ; requested > 0; requested-- {
var nextAddr string var nextAddr string
d.lock.Lock() d.lock.Lock()
@ -146,6 +149,7 @@ func (d *DefaultDiscovery) RequestRemote(requested int) {
} }
d.attempted[nextAddr] = true d.attempted[nextAddr] = true
d.lock.Unlock() d.lock.Unlock()
atomic.AddInt32(&d.outstanding, 1)
go d.tryAddress(nextAddr) go d.tryAddress(nextAddr)
} }
} }
@ -291,6 +295,7 @@ func (d *DefaultDiscovery) updateNetSize() {
func (d *DefaultDiscovery) tryAddress(addr string) { func (d *DefaultDiscovery) tryAddress(addr string) {
p, err := d.transport.Dial(addr, d.dialTimeout) p, err := d.transport.Dial(addr, d.dialTimeout)
atomic.AddInt32(&d.outstanding, -1)
d.lock.Lock() d.lock.Lock()
delete(d.attempted, addr) delete(d.attempted, addr)
if err == nil { if err == nil {