chore: allow to set max-open-streams for tuic
This commit is contained in:
parent
896d30b151
commit
423850a7aa
2 changed files with 22 additions and 5 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
|
@ -42,6 +43,7 @@ type TuicOption struct {
|
|||
MaxUdpRelayPacketSize int `proxy:"max-udp-relay-packet-size,omitempty"`
|
||||
|
||||
FastOpen bool `proxy:"fast-open,omitempty"`
|
||||
MaxOpenStreams int `proxy:"max-open-streams,omitempty"`
|
||||
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
|
||||
Fingerprint string `proxy:"fingerprint,omitempty"`
|
||||
CustomCA string `proxy:"ca,omitempty"`
|
||||
|
@ -148,11 +150,20 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
|||
option.MaxUdpRelayPacketSize = 1500
|
||||
}
|
||||
|
||||
if option.MaxOpenStreams == 0 {
|
||||
option.MaxOpenStreams = 100
|
||||
}
|
||||
|
||||
// ensure server's incoming stream can handle correctly, increase to 1.1x
|
||||
quicMaxOpenStreams := int64(option.MaxOpenStreams)
|
||||
quicMaxOpenStreams = quicMaxOpenStreams + int64(math.Ceil(float64(quicMaxOpenStreams)/10.0))
|
||||
quicConfig := &quic.Config{
|
||||
InitialStreamReceiveWindow: uint64(option.ReceiveWindowConn),
|
||||
MaxStreamReceiveWindow: uint64(option.ReceiveWindowConn),
|
||||
InitialConnectionReceiveWindow: uint64(option.ReceiveWindow),
|
||||
MaxConnectionReceiveWindow: uint64(option.ReceiveWindow),
|
||||
MaxIncomingStreams: quicMaxOpenStreams,
|
||||
MaxIncomingUniStreams: quicMaxOpenStreams,
|
||||
KeepAlivePeriod: time.Duration(option.HeartbeatInterval) * time.Millisecond,
|
||||
DisablePathMTUDiscovery: option.DisableMTUDiscovery,
|
||||
EnableDatagrams: true,
|
||||
|
@ -186,6 +197,12 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
|||
prefer: C.NewDNSPrefer(option.IPVersion),
|
||||
},
|
||||
}
|
||||
// to avoid tuic's "too many open streams", decrease to 0.9x
|
||||
clientMaxOpenStreams := int64(option.MaxOpenStreams)
|
||||
clientMaxOpenStreams = clientMaxOpenStreams - int64(math.Ceil(float64(clientMaxOpenStreams)/10.0))
|
||||
if clientMaxOpenStreams < 1 {
|
||||
clientMaxOpenStreams = 1
|
||||
}
|
||||
clientOption := &tuic.ClientOption{
|
||||
DialFn: t.dial,
|
||||
TlsConfig: tlsConfig,
|
||||
|
@ -198,6 +215,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
|||
RequestTimeout: option.RequestTimeout,
|
||||
MaxUdpRelayPacketSize: option.MaxUdpRelayPacketSize,
|
||||
FastOpen: option.FastOpen,
|
||||
MaxOpenStreams: clientMaxOpenStreams,
|
||||
}
|
||||
|
||||
t.client = tuic.NewClientPool(clientOption)
|
||||
|
|
|
@ -28,8 +28,6 @@ var (
|
|||
TooManyOpenStreams = errors.New("tuic: too many open streams")
|
||||
)
|
||||
|
||||
const MaxOpenStreams = 100 - 90
|
||||
|
||||
type ClientOption struct {
|
||||
DialFn func(ctx context.Context, opts ...dialer.Option) (pc net.PacketConn, addr net.Addr, err error)
|
||||
|
||||
|
@ -43,6 +41,7 @@ type ClientOption struct {
|
|||
RequestTimeout int
|
||||
MaxUdpRelayPacketSize int
|
||||
FastOpen bool
|
||||
MaxOpenStreams int64
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
|
@ -52,7 +51,7 @@ type Client struct {
|
|||
quicConn quic.Connection
|
||||
connMutex sync.Mutex
|
||||
|
||||
openStreams atomic.Int32
|
||||
openStreams atomic.Int64
|
||||
|
||||
udpInputMap sync.Map
|
||||
|
||||
|
@ -255,7 +254,7 @@ func (t *Client) DialContext(ctx context.Context, metadata *C.Metadata) (net.Con
|
|||
return nil, err
|
||||
}
|
||||
openStreams := t.openStreams.Add(1)
|
||||
if openStreams >= MaxOpenStreams {
|
||||
if openStreams >= t.MaxOpenStreams {
|
||||
t.openStreams.Add(-1)
|
||||
return nil, TooManyOpenStreams
|
||||
}
|
||||
|
@ -396,7 +395,7 @@ func (t *Client) ListenPacketContext(ctx context.Context, metadata *C.Metadata)
|
|||
return nil, err
|
||||
}
|
||||
openStreams := t.openStreams.Add(1)
|
||||
if openStreams >= MaxOpenStreams {
|
||||
if openStreams >= t.MaxOpenStreams {
|
||||
t.openStreams.Add(-1)
|
||||
return nil, TooManyOpenStreams
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue