chore: tuic add max_udp_relay_packet_size

This commit is contained in:
wwqgtxx 2022-11-25 12:43:23 +08:00
parent a13dedb6e4
commit f542351404
4 changed files with 60 additions and 30 deletions

View file

@ -243,6 +243,7 @@ proxies:
# request_timeout: 8000
udp_relay_mode: native # Available: "native", "quic". Default: "native"
# congestion_controller: bbr # Available: "cubic", "new_reno", "bbr". Default: "cubic"
# max_udp_relay_packet_size: 1500
# skip-cert-verify: true
```

View file

@ -41,6 +41,7 @@ type TuicOption struct {
UdpRelayMode string `proxy:"udp_relay_mode,omitempty"`
CongestionController string `proxy:"congestion_controller,omitempty"`
DisableSni bool `proxy:"disable_sni,omitempty"`
MaxUdpRelayPacketSize int `proxy:"max_udp_relay_packet_size,omitempty"`
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
Fingerprint string `proxy:"fingerprint,omitempty"`
@ -152,6 +153,10 @@ func NewTuic(option TuicOption) (*Tuic, error) {
option.UdpRelayMode = "native"
}
if option.MaxUdpRelayPacketSize == 0 {
option.MaxUdpRelayPacketSize = 1500
}
quicConfig := &quic.Config{
InitialStreamReceiveWindow: uint64(option.ReceiveWindowConn),
MaxStreamReceiveWindow: uint64(option.ReceiveWindowConn),
@ -186,9 +191,21 @@ func NewTuic(option TuicOption) (*Tuic, error) {
clientMapMutex.Lock()
defer clientMapMutex.Unlock()
if client, ok := clientMap[o]; ok && client != nil {
for key := range clientMap {
client := clientMap[key]
if client == nil {
delete(clientMap, key) // It is safe in Golang
continue
}
if key == o {
client.LastVisited = time.Now()
return client
}
if time.Now().Sub(client.LastVisited) > 30*time.Minute {
delete(clientMap, key)
continue
}
}
client := &tuic.Client{
TlsConfig: tlsConfig,
QuicConfig: quicConfig,
@ -198,6 +215,8 @@ func NewTuic(option TuicOption) (*Tuic, error) {
CongestionController: option.CongestionController,
ReduceRtt: option.ReduceRtt,
RequestTimeout: option.RequestTimeout,
MaxUdpRelayPacketSize: option.MaxUdpRelayPacketSize,
LastVisited: time.Now(),
}
clientMap[o] = client
runtime.SetFinalizer(client, closeTuicClient)

View file

@ -471,6 +471,7 @@ proxies:
# request_timeout: 8000
udp_relay_mode: native # Available: "native", "quic". Default: "native"
# congestion_controller: bbr # Available: "cubic", "new_reno", "bbr". Default: "cubic"
# max_udp_relay_packet_size: 1500
# skip-cert-verify: true
# ShadowsocksR

View file

@ -6,6 +6,7 @@ import (
"context"
"crypto/tls"
"errors"
"fmt"
"math/rand"
"net"
"net/netip"
@ -28,6 +29,9 @@ type Client struct {
CongestionController string
ReduceRtt bool
RequestTimeout int
MaxUdpRelayPacketSize int
LastVisited time.Time
quicConn quic.Connection
connMutex sync.Mutex
@ -237,6 +241,7 @@ func (t *Client) DialContext(ctx context.Context, metadata *C.Metadata, dialFn f
}
_, err = buf.WriteTo(stream)
if err != nil {
_ = stream.Close()
return nil, err
}
return stream, err
@ -379,6 +384,9 @@ func (q *quicStreamPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err err
}
func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
if len(p) > q.client.MaxUdpRelayPacketSize {
return 0, fmt.Errorf("udp packet too large(%d > %d)", len(p), q.client.MaxUdpRelayPacketSize)
}
defer func() {
q.client.deferQuicConn(q.quicConn, err)
}()
@ -401,6 +409,7 @@ func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err erro
}
_, err = buf.WriteTo(stream)
if err != nil {
_ = stream.Close()
return
}
err = stream.Close()