From 0bf21d9db21b9e94327b8d385cc9818b50cc8a14 Mon Sep 17 00:00:00 2001 From: domain <32405309+szu17dmy@users.noreply.github.com> Date: Wed, 30 Apr 2025 22:25:01 +0800 Subject: [PATCH] fix(strelaysrv): make the session limiter session-dependent (fixes #10072) (#10073) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Purpose Make the session limiter only apply to current session. ### Testing Relay 2 or more sessions and check if the sum of the connection speed can exceed the specified per-session rate. 2 sessions (-global-rate=50000000 and -per-session-rate=6250000): ![图片](https://github.com/user-attachments/assets/133e531a-ed49-4890-aef7-821c628bcfc8) 1 session (-global-rate=50000000 and -per-session-rate=6250000): ![图片](https://github.com/user-attachments/assets/ac89ea53-2d8e-4347-9bbc-4780d85e38d7) --- cmd/strelaysrv/listener.go | 2 +- cmd/strelaysrv/main.go | 4 ---- cmd/strelaysrv/session.go | 8 +++++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/strelaysrv/listener.go b/cmd/strelaysrv/listener.go index 164769047..3c4a2e427 100644 --- a/cmd/strelaysrv/listener.go +++ b/cmd/strelaysrv/listener.go @@ -184,7 +184,7 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config, token strin continue } // requestedPeer is the server, id is the client - ses := newSession(requestedPeer, id, sessionLimiter, globalLimiter) + ses := newSession(requestedPeer, id, sessionLimitBps, globalLimiter) go ses.Serve() diff --git a/cmd/strelaysrv/main.go b/cmd/strelaysrv/main.go index e96e9af86..c1d264081 100644 --- a/cmd/strelaysrv/main.go +++ b/cmd/strelaysrv/main.go @@ -51,7 +51,6 @@ var ( globalLimitBps int overLimit atomic.Bool descriptorLimit int64 - sessionLimiter *rate.Limiter globalLimiter *rate.Limiter networkBufferSize int @@ -228,9 +227,6 @@ func main() { } } - if sessionLimitBps > 0 { - sessionLimiter = rate.NewLimiter(rate.Limit(sessionLimitBps), 2*sessionLimitBps) - } if globalLimitBps > 0 { globalLimiter = rate.NewLimiter(rate.Limit(globalLimitBps), 2*globalLimitBps) } diff --git a/cmd/strelaysrv/session.go b/cmd/strelaysrv/session.go index 1426216e5..79d1184fc 100644 --- a/cmd/strelaysrv/session.go +++ b/cmd/strelaysrv/session.go @@ -27,7 +27,7 @@ var ( bytesProxied atomic.Int64 ) -func newSession(serverid, clientid syncthingprotocol.DeviceID, sessionRateLimit, globalRateLimit *rate.Limiter) *session { +func newSession(serverid, clientid syncthingprotocol.DeviceID, sessionLimitBps int, globalRateLimit *rate.Limiter) *session { serverkey := make([]byte, 32) _, err := rand.Read(serverkey) if err != nil { @@ -40,12 +40,17 @@ func newSession(serverid, clientid syncthingprotocol.DeviceID, sessionRateLimit, return nil } + var sessionRateLimit *rate.Limiter + if sessionLimitBps > 0 { + sessionRateLimit = rate.NewLimiter(rate.Limit(sessionLimitBps), 2*sessionLimitBps) + } ses := &session{ serverkey: serverkey, serverid: serverid, clientkey: clientkey, clientid: clientid, rateLimit: makeRateLimitFunc(sessionRateLimit, globalRateLimit), + limiter: sessionRateLimit, connsChan: make(chan net.Conn), conns: make([]net.Conn, 0, 2), } @@ -109,6 +114,7 @@ type session struct { clientid syncthingprotocol.DeviceID rateLimit func(bytes int) + limiter *rate.Limiter connsChan chan net.Conn conns []net.Conn