Limit half-open connections at the Client level

This commit is contained in:
Matt Joiner 2020-09-30 16:56:27 +10:00
parent f5c6f28985
commit a2c7b384df
3 changed files with 14 additions and 3 deletions

View File

@ -75,6 +75,7 @@ type Client struct {
acceptLimiter map[ipStr]int
dialRateLimiter *rate.Limiter
numHalfOpen int
websocketTrackers websocketTrackers
}
@ -658,7 +659,10 @@ func (cl *Client) noLongerHalfOpen(t *Torrent, addr string) {
panic("invariant broken")
}
delete(t.halfOpen, addr)
cl.numHalfOpen--
for _, t := range cl.torrents {
t.openNewConns()
}
}
// Performs initiator handshakes and returns a connection. Returns nil *connection if no connection

View File

@ -102,6 +102,7 @@ type ClientConfig struct {
MinDialTimeout time.Duration
EstablishedConnsPerTorrent int
HalfOpenConnsPerTorrent int
TotalHalfOpenConns int
// Maximum number of peer addresses in reserve.
TorrentPeersHighWater int
// Minumum number of peers before effort is made to obtain more peers.
@ -155,6 +156,7 @@ func NewDefaultClientConfig() *ClientConfig {
MinDialTimeout: 3 * time.Second,
EstablishedConnsPerTorrent: 50,
HalfOpenConnsPerTorrent: 25,
TotalHalfOpenConns: 100,
TorrentPeersHighWater: 500,
TorrentPeersLowWater: 50,
HandshakesTimeout: 4 * time.Second,

View File

@ -1075,7 +1075,7 @@ func (t *Torrent) maxHalfOpen() int {
return int(min(max(5, extraIncoming)+establishedHeadroom, int64(t.cl.config.HalfOpenConnsPerTorrent)))
}
func (t *Torrent) openNewConns() {
func (t *Torrent) openNewConns() (initiated int) {
defer t.updateWantPeersEvent()
for t.peers.Len() != 0 {
if !t.wantConns() {
@ -1087,9 +1087,14 @@ func (t *Torrent) openNewConns() {
if len(t.cl.dialers) == 0 {
return
}
if t.cl.numHalfOpen >= t.cl.config.TotalHalfOpenConns {
return
}
p := t.peers.PopMax()
t.initiateConn(p)
initiated++
}
return
}
func (t *Torrent) getConnPieceInclination() []int {
@ -1889,7 +1894,6 @@ func (t *Torrent) initiateConn(peer PeerInfo) {
if peer.Id == t.cl.peerID {
return
}
if t.cl.badPeerAddr(peer.Addr) && !peer.Trusted {
return
}
@ -1897,6 +1901,7 @@ func (t *Torrent) initiateConn(peer PeerInfo) {
if t.addrActive(addr.String()) {
return
}
t.cl.numHalfOpen++
t.halfOpen[addr.String()] = peer
go t.cl.outgoingConnection(t, addr, peer.Source, peer.Trusted)
}