fix(strelaysrv): make the session limiter session-dependent (fixes #10072) (#10073)

### 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)
This commit is contained in:
domain
2025-04-30 14:25:01 +00:00
committed by GitHub
parent f61843ef2e
commit aad6c2fe33
3 changed files with 8 additions and 6 deletions
+1 -1
View File
@@ -184,7 +184,7 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config, token strin
continue continue
} }
// requestedPeer is the server, id is the client // requestedPeer is the server, id is the client
ses := newSession(requestedPeer, id, sessionLimiter, globalLimiter) ses := newSession(requestedPeer, id, sessionLimitBps, globalLimiter)
go ses.Serve() go ses.Serve()
-4
View File
@@ -51,7 +51,6 @@ var (
globalLimitBps int globalLimitBps int
overLimit atomic.Bool overLimit atomic.Bool
descriptorLimit int64 descriptorLimit int64
sessionLimiter *rate.Limiter
globalLimiter *rate.Limiter globalLimiter *rate.Limiter
networkBufferSize int networkBufferSize int
@@ -228,9 +227,6 @@ func main() {
} }
} }
if sessionLimitBps > 0 {
sessionLimiter = rate.NewLimiter(rate.Limit(sessionLimitBps), 2*sessionLimitBps)
}
if globalLimitBps > 0 { if globalLimitBps > 0 {
globalLimiter = rate.NewLimiter(rate.Limit(globalLimitBps), 2*globalLimitBps) globalLimiter = rate.NewLimiter(rate.Limit(globalLimitBps), 2*globalLimitBps)
} }
+7 -1
View File
@@ -27,7 +27,7 @@ var (
bytesProxied atomic.Int64 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) serverkey := make([]byte, 32)
_, err := rand.Read(serverkey) _, err := rand.Read(serverkey)
if err != nil { if err != nil {
@@ -40,12 +40,17 @@ func newSession(serverid, clientid syncthingprotocol.DeviceID, sessionRateLimit,
return nil return nil
} }
var sessionRateLimit *rate.Limiter
if sessionLimitBps > 0 {
sessionRateLimit = rate.NewLimiter(rate.Limit(sessionLimitBps), 2*sessionLimitBps)
}
ses := &session{ ses := &session{
serverkey: serverkey, serverkey: serverkey,
serverid: serverid, serverid: serverid,
clientkey: clientkey, clientkey: clientkey,
clientid: clientid, clientid: clientid,
rateLimit: makeRateLimitFunc(sessionRateLimit, globalRateLimit), rateLimit: makeRateLimitFunc(sessionRateLimit, globalRateLimit),
limiter: sessionRateLimit,
connsChan: make(chan net.Conn), connsChan: make(chan net.Conn),
conns: make([]net.Conn, 0, 2), conns: make([]net.Conn, 0, 2),
} }
@@ -109,6 +114,7 @@ type session struct {
clientid syncthingprotocol.DeviceID clientid syncthingprotocol.DeviceID
rateLimit func(bytes int) rateLimit func(bytes int)
limiter *rate.Limiter
connsChan chan net.Conn connsChan chan net.Conn
conns []net.Conn conns []net.Conn