fix: tuic udp native mode can't relay packetSize>1200

This commit is contained in:
wwqgtxx 2023-03-16 21:09:44 +08:00
parent 998d407d44
commit 3ae4285702
7 changed files with 38 additions and 15 deletions

View file

@ -51,6 +51,7 @@ type TuicOption struct {
ReceiveWindowConn int `proxy:"recv-window-conn,omitempty"` ReceiveWindowConn int `proxy:"recv-window-conn,omitempty"`
ReceiveWindow int `proxy:"recv-window,omitempty"` ReceiveWindow int `proxy:"recv-window,omitempty"`
DisableMTUDiscovery bool `proxy:"disable-mtu-discovery,omitempty"` DisableMTUDiscovery bool `proxy:"disable-mtu-discovery,omitempty"`
MaxDatagramFrameSize int `proxy:"max-datagram-frame-size,omitempty"`
SNI string `proxy:"sni,omitempty"` SNI string `proxy:"sni,omitempty"`
} }
@ -175,6 +176,15 @@ func NewTuic(option TuicOption) (*Tuic, error) {
option.MaxOpenStreams = 100 option.MaxOpenStreams = 100
} }
if option.MaxDatagramFrameSize == 0 {
option.MaxDatagramFrameSize = option.MaxUdpRelayPacketSize + tuic.PacketOverHead
}
if option.MaxDatagramFrameSize > 1400 {
option.MaxDatagramFrameSize = 1400
}
option.MaxUdpRelayPacketSize = option.MaxDatagramFrameSize - tuic.PacketOverHead
// ensure server's incoming stream can handle correctly, increase to 1.1x // ensure server's incoming stream can handle correctly, increase to 1.1x
quicMaxOpenStreams := int64(option.MaxOpenStreams) quicMaxOpenStreams := int64(option.MaxOpenStreams)
quicMaxOpenStreams = quicMaxOpenStreams + int64(math.Ceil(float64(quicMaxOpenStreams)/10.0)) quicMaxOpenStreams = quicMaxOpenStreams + int64(math.Ceil(float64(quicMaxOpenStreams)/10.0))
@ -187,6 +197,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
MaxIncomingUniStreams: quicMaxOpenStreams, MaxIncomingUniStreams: quicMaxOpenStreams,
KeepAlivePeriod: time.Duration(option.HeartbeatInterval) * time.Millisecond, KeepAlivePeriod: time.Duration(option.HeartbeatInterval) * time.Millisecond,
DisablePathMTUDiscovery: option.DisableMTUDiscovery, DisablePathMTUDiscovery: option.DisableMTUDiscovery,
MaxDatagramFrameSize: int64(option.MaxDatagramFrameSize),
EnableDatagrams: true, EnableDatagrams: true,
} }
if option.ReceiveWindowConn == 0 { if option.ReceiveWindowConn == 0 {

2
go.mod
View file

@ -19,7 +19,7 @@ require (
github.com/jpillora/backoff v1.0.0 github.com/jpillora/backoff v1.0.0
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
github.com/mdlayher/netlink v1.7.2-0.20221213171556-9881fafed8c7 github.com/mdlayher/netlink v1.7.2-0.20221213171556-9881fafed8c7
github.com/metacubex/quic-go v0.33.1 github.com/metacubex/quic-go v0.33.2
github.com/metacubex/sing-shadowsocks v0.1.1-0.20230226153717-4e80da7e6947 github.com/metacubex/sing-shadowsocks v0.1.1-0.20230226153717-4e80da7e6947
github.com/metacubex/sing-tun v0.1.2 github.com/metacubex/sing-tun v0.1.2
github.com/metacubex/sing-wireguard v0.0.0-20230310035749-f7595fcae5cb github.com/metacubex/sing-wireguard v0.0.0-20230310035749-f7595fcae5cb

4
go.sum
View file

@ -91,8 +91,8 @@ github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc= github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
github.com/metacubex/gvisor v0.0.0-20230315105319-c03631d706be h1:zg8lXHo8t+dCSPHQ/wCJui1V+eO9TSh9NoIjKNvUykA= github.com/metacubex/gvisor v0.0.0-20230315105319-c03631d706be h1:zg8lXHo8t+dCSPHQ/wCJui1V+eO9TSh9NoIjKNvUykA=
github.com/metacubex/gvisor v0.0.0-20230315105319-c03631d706be/go.mod h1:wqEuzdImyqD2MCGE8CYRJXbB77oSEJeoSSXXdwKjnsE= github.com/metacubex/gvisor v0.0.0-20230315105319-c03631d706be/go.mod h1:wqEuzdImyqD2MCGE8CYRJXbB77oSEJeoSSXXdwKjnsE=
github.com/metacubex/quic-go v0.33.1 h1:ZIxZFGivpSLOEZuuNkLy+aPvo1RP4uRBjNg3SAkXwIg= github.com/metacubex/quic-go v0.33.2 h1:DsDdTaLvGI0eVV0C/jzPrw5MBwK5VR20r5Mt9uU5Djw=
github.com/metacubex/quic-go v0.33.1/go.mod h1:9nOiGX6kqV3+ZbkDKdTNzdFD726QQHPH6WDb36jUSpA= github.com/metacubex/quic-go v0.33.2/go.mod h1:9nOiGX6kqV3+ZbkDKdTNzdFD726QQHPH6WDb36jUSpA=
github.com/metacubex/sing-shadowsocks v0.1.1-0.20230226153717-4e80da7e6947 h1:NnjC2+aIiyzzvFlo+C2WzBOJdsp+HAtu18FZomqYhUE= github.com/metacubex/sing-shadowsocks v0.1.1-0.20230226153717-4e80da7e6947 h1:NnjC2+aIiyzzvFlo+C2WzBOJdsp+HAtu18FZomqYhUE=
github.com/metacubex/sing-shadowsocks v0.1.1-0.20230226153717-4e80da7e6947/go.mod h1:U2gwhxzqgbhKCgn2B4z3t0Cj0LpMWFl/02BGCoG421w= github.com/metacubex/sing-shadowsocks v0.1.1-0.20230226153717-4e80da7e6947/go.mod h1:U2gwhxzqgbhKCgn2B4z3t0Cj0LpMWFl/02BGCoG421w=
github.com/metacubex/sing-tun v0.1.2 h1:rQzy+11rt2ZCpCNIsFab5lWoYDTqkdaurofHo8f97yU= github.com/metacubex/sing-tun v0.1.2 h1:rQzy+11rt2ZCpCNIsFab5lWoYDTqkdaurofHo8f97yU=

View file

@ -15,6 +15,7 @@ type TuicServer struct {
AuthenticationTimeout int `yaml:"authentication-timeout" json:"authentication-timeout,omitempty"` AuthenticationTimeout int `yaml:"authentication-timeout" json:"authentication-timeout,omitempty"`
ALPN []string `yaml:"alpn" json:"alpn,omitempty"` ALPN []string `yaml:"alpn" json:"alpn,omitempty"`
MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"` MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
MaxDatagramFrameSize int `yaml:"max-datagram-frame-size" json:"max-datagram-frame-size,omitempty"`
} }
func (t TuicServer) String() string { func (t TuicServer) String() string {

View file

@ -61,6 +61,16 @@ func New(config LC.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- C.Packet
quicConfig.InitialConnectionReceiveWindow = tuic.DefaultConnectionReceiveWindow / 10 quicConfig.InitialConnectionReceiveWindow = tuic.DefaultConnectionReceiveWindow / 10
quicConfig.MaxConnectionReceiveWindow = tuic.DefaultConnectionReceiveWindow quicConfig.MaxConnectionReceiveWindow = tuic.DefaultConnectionReceiveWindow
if config.MaxUdpRelayPacketSize == 0 {
config.MaxUdpRelayPacketSize = 1500
}
maxDatagramFrameSize := config.MaxUdpRelayPacketSize + tuic.PacketOverHead
if maxDatagramFrameSize > 1400 {
maxDatagramFrameSize = 1400
}
config.MaxUdpRelayPacketSize = maxDatagramFrameSize - tuic.PacketOverHead
quicConfig.MaxDatagramFrameSize = int64(maxDatagramFrameSize)
tokens := make([][32]byte, len(config.Token)) tokens := make([][32]byte, len(config.Token))
for i, token := range config.Token { for i, token := range config.Token {
tokens[i] = tuic.GenTKN(token) tokens[i] = tuic.GenTKN(token)

View file

@ -1,7 +1,6 @@
package tuic package tuic
import ( import (
"fmt"
"net" "net"
"net/netip" "net/netip"
"sync" "sync"
@ -201,7 +200,7 @@ 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) { func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
if q.udpRelayMode != "quic" && len(p) > q.maxUdpRelayPacketSize { if q.udpRelayMode != "quic" && len(p) > q.maxUdpRelayPacketSize {
return 0, fmt.Errorf("udp packet too large(%d > %d)", len(p), q.maxUdpRelayPacketSize) return 0, quic.ErrMessageTooLarge(q.maxUdpRelayPacketSize)
} }
if q.closed { if q.closed {
return 0, net.ErrClosed return 0, net.ErrClosed

View file

@ -282,6 +282,8 @@ func (c Packet) BytesLen() int {
return c.CommandHead.BytesLen() + 4 + 2 + c.ADDR.BytesLen() + len(c.DATA) return c.CommandHead.BytesLen() + 4 + 2 + c.ADDR.BytesLen() + len(c.DATA)
} }
var PacketOverHead = NewPacket(0, 0, NewAddressAddrPort(netip.AddrPortFrom(netip.IPv6Unspecified(), 0)), nil).BytesLen()
type Dissociate struct { type Dissociate struct {
CommandHead CommandHead
ASSOC_ID uint32 ASSOC_ID uint32