0
0
mirror of https://github.com/XTLS/REALITY.git synced 2025-08-24 23:48:36 +00:00
This commit is contained in:
Meo597 2025-06-08 18:28:17 +08:00
parent d7bec4a74f
commit 8a58ed1c1a
2 changed files with 19 additions and 11 deletions

View File

@ -538,9 +538,9 @@ const (
) )
type LimitFallback struct { type LimitFallback struct {
AfterBytes int64 AfterBytes uint64
BytesPerSec int64 BytesPerSec uint64
BurstBytesPerSec int64 BurstBytesPerSec uint64
} }
// A Config structure is used to configure a TLS client or server. // A Config structure is used to configure a TLS client or server.

24
tls.go
View File

@ -43,6 +43,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math"
"net" "net"
"os" "os"
"runtime" "runtime"
@ -119,11 +120,18 @@ func (c *RatelimitedConn) Write(b []byte) (int, error) {
return n, err return n, err
} }
func NewBucketWithRate(bytesPerSec int64, burstBytesPerSec int64) *ratelimit.Bucket { func NewBucketWithRate(bytesPerSec uint64, burstBytesPerSec uint64) *ratelimit.Bucket {
if burstBytesPerSec < bytesPerSec { if burstBytesPerSec < bytesPerSec {
burstBytesPerSec = bytesPerSec burstBytesPerSec = bytesPerSec
} }
return ratelimit.NewBucketWithRate(float64(bytesPerSec), burstBytesPerSec) return ratelimit.NewBucketWithRate(float64(bytesPerSec), ToInt64(burstBytesPerSec))
}
func ToInt64(u uint64) int64 {
if u > math.MaxInt64 {
return math.MaxInt64
}
return int64(u)
} }
var ( var (
@ -254,14 +262,14 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
if config.Show && hs.clientHello != nil { if config.Show && hs.clientHello != nil {
fmt.Printf("REALITY remoteAddr: %v\tforwarded SNI: %v\n", remoteAddr, hs.clientHello.serverName) fmt.Printf("REALITY remoteAddr: %v\tforwarded SNI: %v\n", remoteAddr, hs.clientHello.serverName)
} }
if config.LimitFallbackUpload.BytesPerSec == 0 || config.LimitFallbackUpload.BurstBytesPerSec == 0 { if config.LimitFallbackUpload.BytesPerSec == 0 {
io.Copy(target, underlying) io.Copy(target, underlying)
} else { } else {
// Limit upload speed for fallback connection // Limit upload speed for fallback connection
io.Copy(&RatelimitedConn{ io.Copy(&RatelimitedConn{
Conn: target, Conn: target,
Bucket: NewBucketWithRate(config.LimitFallbackUpload.BytesPerSec, config.LimitFallbackUpload.BurstBytesPerSec), Bucket: NewBucketWithRate(config.LimitFallbackUpload.BytesPerSec, config.LimitFallbackUpload.BurstBytesPerSec),
LimitAfter: config.LimitFallbackUpload.AfterBytes - config.LimitFallbackUpload.BurstBytesPerSec, LimitAfter: ToInt64(config.LimitFallbackUpload.AfterBytes) - ToInt64(config.LimitFallbackUpload.BurstBytesPerSec),
}, underlying) }, underlying)
} }
} }
@ -394,28 +402,28 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
if hs.c.conn == conn { // if we processed the Client Hello successfully but the target did not if hs.c.conn == conn { // if we processed the Client Hello successfully but the target did not
waitGroup.Add(1) waitGroup.Add(1)
go func() { go func() {
if config.LimitFallbackUpload.BytesPerSec == 0 || config.LimitFallbackUpload.BurstBytesPerSec == 0 { if config.LimitFallbackUpload.BytesPerSec == 0 {
io.Copy(target, underlying) io.Copy(target, underlying)
} else { } else {
// Limit upload speed for fallback connection (handshake ok but hello failed) // Limit upload speed for fallback connection (handshake ok but hello failed)
io.Copy(&RatelimitedConn{ io.Copy(&RatelimitedConn{
Conn: target, Conn: target,
Bucket: NewBucketWithRate(config.LimitFallbackUpload.BytesPerSec, config.LimitFallbackUpload.BurstBytesPerSec), Bucket: NewBucketWithRate(config.LimitFallbackUpload.BytesPerSec, config.LimitFallbackUpload.BurstBytesPerSec),
LimitAfter: config.LimitFallbackUpload.AfterBytes - config.LimitFallbackUpload.BurstBytesPerSec, LimitAfter: ToInt64(config.LimitFallbackUpload.AfterBytes) - ToInt64(config.LimitFallbackUpload.BurstBytesPerSec),
}, underlying) }, underlying)
} }
waitGroup.Done() waitGroup.Done()
}() }()
} }
conn.Write(s2cSaved) conn.Write(s2cSaved)
if config.LimitFallbackDownload.BytesPerSec == 0 || config.LimitFallbackDownload.BurstBytesPerSec == 0 { if config.LimitFallbackDownload.BytesPerSec == 0 {
io.Copy(underlying, target) io.Copy(underlying, target)
} else { } else {
// Limit download speed for fallback connection // Limit download speed for fallback connection
io.Copy(&RatelimitedConn{ io.Copy(&RatelimitedConn{
Conn: underlying, Conn: underlying,
Bucket: NewBucketWithRate(config.LimitFallbackDownload.BytesPerSec, config.LimitFallbackDownload.BurstBytesPerSec), Bucket: NewBucketWithRate(config.LimitFallbackDownload.BytesPerSec, config.LimitFallbackDownload.BurstBytesPerSec),
LimitAfter: config.LimitFallbackDownload.AfterBytes - config.LimitFallbackDownload.BurstBytesPerSec, LimitAfter: ToInt64(config.LimitFallbackDownload.AfterBytes) - ToInt64(config.LimitFallbackDownload.BurstBytesPerSec),
}, target) }, target)
} }
// Here is bidirectional direct forwarding: // Here is bidirectional direct forwarding: