]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Limit half-open connections at the Client level
authorMatt Joiner <anacrolix@gmail.com>
Wed, 30 Sep 2020 06:56:27 +0000 (16:56 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 30 Sep 2020 06:56:27 +0000 (16:56 +1000)
client.go
config.go
torrent.go

index fafb6e2d72d7f94d96cc2d4f5eb67f29b6595622..6292d778fdbb31c5e6b82b6f421b44d625c3ffa5 100644 (file)
--- a/client.go
+++ b/client.go
@@ -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)
-       t.openNewConns()
+       cl.numHalfOpen--
+       for _, t := range cl.torrents {
+               t.openNewConns()
+       }
 }
 
 // Performs initiator handshakes and returns a connection. Returns nil *connection if no connection
index c28ee124560d8e063a16d1e8e39ad19d1f5790d6..4af86cf6826f873b0b6ccecd4d127c8782302ec3 100644 (file)
--- a/config.go
+++ b/config.go
@@ -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,
index 639e330e21ad61f2cbeb2ea778c7b4554e9e3846..21069ec5fe0cd0324b42aaf2a460f01dc36a9785 100644 (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)
 }