From c0bbb3849d0698f0e31eab6915645c869bdf9482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 21 Aug 2023 18:11:44 +0800 Subject: [PATCH] Fix TUIC UDP --- go.mod | 6 ++-- go.sum | 12 +++---- inbound/tuic.go | 6 ++++ test/box_test.go | 15 +++++++++ test/clash_test.go | 13 +++++--- test/config/tuic-client.json | 3 +- test/go.mod | 13 ++++---- test/go.sum | 28 +++++++---------- test/tuic_test.go | 5 +-- transport/tuic/packet.go | 61 +++++++++++++++++++++++------------- 10 files changed, 100 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index 6f26eebe..6004077d 100644 --- a/go.mod +++ b/go.mod @@ -23,15 +23,15 @@ require ( github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59 github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 - github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 + github.com/sagernet/quic-go v0.0.0-20230821100820-d38697ecdbb0 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29 + github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/sing-shadowsocks2 v0.1.3 github.com/sagernet/sing-shadowtls v0.1.4 - github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 + github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641 github.com/sagernet/sing-vmess v0.1.7 github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 diff --git a/go.sum b/go.sum index c859cf25..caae8167 100644 --- a/go.sum +++ b/go.sum @@ -107,14 +107,14 @@ github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTS github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= -github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 h1:4dyzZWAEo9BNQN7yJsVSiN/Pm1hmUfkGJdEyWMkUnVE= -github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I= +github.com/sagernet/quic-go v0.0.0-20230821100820-d38697ecdbb0 h1:NCda9SkbANuTWSxf6GVKNXHfYgOIV3byai5T5J9R0UU= +github.com/sagernet/quic-go v0.0.0-20230821100820-d38697ecdbb0/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= -github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29 h1:TGSiSJ5noRdmDW0vd1sc/WICJWoT2ulOhD/igXh8PJc= -github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA= +github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d h1:4kgoOCE48CuQcBUcoRnE0QTPXkl8yM8i7Nipmzp/978= +github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA= github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 h1:1DAKccGNqTYJ8nsBR765FS0LVBVXfuFlFAHqKsGN3EI= github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659/go.mod h1:W7GHTZFS8RkoLI3bA2LFY27/0E+uoQESWtMFLepO/JA= github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I= @@ -125,8 +125,8 @@ github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbs github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw= github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= -github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 h1:ZqNuG9t4lAZbiqMSJN/nNv7ZtRRpm7h46KrmnkuhW9w= -github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA= +github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641 h1:a8lktNrCWZJisB+nPraW+qB73ZofgPtGmlfqNYcO79g= +github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA= github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4= github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= diff --git a/inbound/tuic.go b/inbound/tuic.go index f8ce24a0..9b5c4ef3 100644 --- a/inbound/tuic.go +++ b/inbound/tuic.go @@ -99,6 +99,12 @@ func (h *TUIC) newPacketConnection(ctx context.Context, conn N.PacketConn, metad } func (h *TUIC) Start() error { + if h.tlsConfig != nil { + err := h.tlsConfig.Start() + if err != nil { + return err + } + } packetConn, err := h.myInboundAdapter.ListenUDP() if err != nil { return err diff --git a/test/box_test.go b/test/box_test.go index 0cb533c4..4ce61d46 100644 --- a/test/box_test.go +++ b/test/box_test.go @@ -74,6 +74,21 @@ func testSuit(t *testing.T, clientPort uint16, testPort uint16) { // require.NoError(t, testPacketConnTimeout(t, dialUDP)) } +func testSuitLargeUDP(t *testing.T, clientPort uint16, testPort uint16) { + dialer := socks.NewClient(N.SystemDialer, M.ParseSocksaddrHostPort("127.0.0.1", clientPort), socks.Version5, "", "") + dialTCP := func() (net.Conn, error) { + return dialer.DialContext(context.Background(), "tcp", M.ParseSocksaddrHostPort("127.0.0.1", testPort)) + } + dialUDP := func() (net.PacketConn, error) { + return dialer.ListenPacket(context.Background(), M.ParseSocksaddrHostPort("127.0.0.1", testPort)) + } + require.NoError(t, testPingPongWithConn(t, testPort, dialTCP)) + require.NoError(t, testPingPongWithPacketConn(t, testPort, dialUDP)) + require.NoError(t, testLargeDataWithConn(t, testPort, dialTCP)) + require.NoError(t, testLargeDataWithPacketConn(t, testPort, dialUDP)) + require.NoError(t, testLargeDataWithPacketConnSize(t, testPort, 1250, dialUDP)) +} + func testTCP(t *testing.T, clientPort uint16, testPort uint16) { dialer := socks.NewClient(N.SystemDialer, M.ParseSocksaddrHostPort("127.0.0.1", clientPort), socks.Version5, "", "") dialTCP := func() (net.Conn, error) { diff --git a/test/clash_test.go b/test/clash_test.go index 7ea03ebc..af9e80b4 100644 --- a/test/clash_test.go +++ b/test/clash_test.go @@ -38,8 +38,8 @@ const ( ImageShadowsocksR = "teddysun/shadowsocks-r:latest" ImageXRayCore = "teddysun/xray:latest" ImageShadowsocksLegacy = "mritd/shadowsocks:latest" - ImageTUICServer = "" - ImageTUICClient = "" + ImageTUICServer = "kilvn/tuic-server:latest" + ImageTUICClient = "kilvn/tuic-client:latest" ) var allImages = []string{ @@ -55,8 +55,8 @@ var allImages = []string{ ImageShadowsocksR, ImageXRayCore, ImageShadowsocksLegacy, - // ImageTUICServer, - // ImageTUICClient, + ImageTUICServer, + ImageTUICClient, } var localIP = netip.MustParseAddr("127.0.0.1") @@ -364,6 +364,10 @@ func testLargeDataWithConn(t *testing.T, port uint16, cc func() (net.Conn, error } func testLargeDataWithPacketConn(t *testing.T, port uint16, pcc func() (net.PacketConn, error)) error { + return testLargeDataWithPacketConnSize(t, port, 1024, pcc) +} + +func testLargeDataWithPacketConnSize(t *testing.T, port uint16, chunkSize int, pcc func() (net.PacketConn, error)) error { l, err := listenPacket("udp", ":"+F.ToString(port)) if err != nil { return err @@ -373,7 +377,6 @@ func testLargeDataWithPacketConn(t *testing.T, port uint16, pcc func() (net.Pack rAddr := &net.UDPAddr{IP: localIP.AsSlice(), Port: int(port)} times := 50 - chunkSize := int64(1024) pingCh, pongCh, test := newLargeDataPair() writeRandData := func(pc net.PacketConn, addr net.Addr) (map[int][]byte, error) { diff --git a/test/config/tuic-client.json b/test/config/tuic-client.json index c1042b53..254fba80 100644 --- a/test/config/tuic-client.json +++ b/test/config/tuic-client.json @@ -1,6 +1,7 @@ { "relay": { - "server": "127.0.0.1:10000", + "server": "example.org:10000", + "ip": "127.0.0.1", "uuid": "FE35D05B-8803-45C4-BAE6-723AD2CD5D3D", "password": "tuic", "certificates": [ diff --git a/test/go.mod b/test/go.mod index bdf18e4d..e50af866 100644 --- a/test/go.mod +++ b/test/go.mod @@ -7,15 +7,15 @@ require github.com/sagernet/sing-box v0.0.0 replace github.com/sagernet/sing-box => ../ require ( - github.com/docker/docker v20.10.18+incompatible + github.com/docker/docker v24.0.5+incompatible github.com/docker/go-connections v0.4.0 github.com/gofrs/uuid/v5 v5.0.0 - github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29 + github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/sing-shadowsocks2 v0.1.3 - github.com/spyzhov/ajson v0.7.1 + github.com/spyzhov/ajson v0.9.0 github.com/stretchr/testify v1.8.4 - go.uber.org/goleak v1.2.0 + go.uber.org/goleak v1.2.1 golang.org/x/net v0.14.0 ) @@ -70,12 +70,12 @@ require ( github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 // indirect github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect - github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 // indirect + github.com/sagernet/quic-go v0.0.0-20230821100820-d38697ecdbb0 // indirect github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 // indirect github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c // indirect github.com/sagernet/sing-shadowtls v0.1.4 // indirect - github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 // indirect + github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641 // indirect github.com/sagernet/sing-vmess v0.1.7 // indirect github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect @@ -83,7 +83,6 @@ require ( github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f // indirect github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect github.com/zeebo/blake3 v0.2.3 // indirect diff --git a/test/go.sum b/test/go.sum index 5282ad07..38446a97 100644 --- a/test/go.sum +++ b/test/go.sum @@ -27,8 +27,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.18+incompatible h1:SN84VYXTBNGn92T/QwIRPlum9zfemfitN7pbsp26WSc= -github.com/docker/docker v20.10.18+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= +github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -123,14 +123,14 @@ github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTS github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= -github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 h1:4dyzZWAEo9BNQN7yJsVSiN/Pm1hmUfkGJdEyWMkUnVE= -github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I= +github.com/sagernet/quic-go v0.0.0-20230821100820-d38697ecdbb0 h1:NCda9SkbANuTWSxf6GVKNXHfYgOIV3byai5T5J9R0UU= +github.com/sagernet/quic-go v0.0.0-20230821100820-d38697ecdbb0/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= -github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29 h1:TGSiSJ5noRdmDW0vd1sc/WICJWoT2ulOhD/igXh8PJc= -github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA= +github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d h1:4kgoOCE48CuQcBUcoRnE0QTPXkl8yM8i7Nipmzp/978= +github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA= github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 h1:1DAKccGNqTYJ8nsBR765FS0LVBVXfuFlFAHqKsGN3EI= github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659/go.mod h1:W7GHTZFS8RkoLI3bA2LFY27/0E+uoQESWtMFLepO/JA= github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I= @@ -141,8 +141,8 @@ github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbs github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw= github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= -github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 h1:ZqNuG9t4lAZbiqMSJN/nNv7ZtRRpm7h46KrmnkuhW9w= -github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA= +github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641 h1:a8lktNrCWZJisB+nPraW+qB73ZofgPtGmlfqNYcO79g= +github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA= github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4= github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= @@ -157,10 +157,8 @@ github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f h1:Kvo8w8Y9l github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f/go.mod h1:mySs0abhpc/gLlvhoq7HP1RzOaRmIXVeZGCh++zoApk= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spyzhov/ajson v0.7.1 h1:1MDIlPc6x0zjNtpa7tDzRAyFAvRX+X8ZsvtYz5lZg6A= -github.com/spyzhov/ajson v0.7.1/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA= +github.com/spyzhov/ajson v0.9.0 h1:tF46gJGOenYVj+k9K1U1XpCxVWhmiyY5PsVCAs1+OJ0= +github.com/spyzhov/ajson v0.9.0/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -182,8 +180,8 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= @@ -199,7 +197,6 @@ golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -231,7 +228,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/test/tuic_test.go b/test/tuic_test.go index 3851d132..cee39d10 100644 --- a/test/tuic_test.go +++ b/test/tuic_test.go @@ -94,7 +94,7 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) { }, }, }) - testSuit(t, clientPort, testPort) + testSuitLargeUDP(t, clientPort, testPort) } func TestTUICInbound(t *testing.T) { @@ -130,6 +130,7 @@ func TestTUICInbound(t *testing.T) { caPem: "/etc/tuic/ca.pem", }, }) + testSuitLargeUDP(t, clientPort, testPort) } func TestTUICOutbound(t *testing.T) { @@ -174,5 +175,5 @@ func TestTUICOutbound(t *testing.T) { }, }, }) - testSuit(t, clientPort, testPort) + testSuitLargeUDP(t, clientPort, testPort) } diff --git a/transport/tuic/packet.go b/transport/tuic/packet.go index a3a0c35a..5e1a80b4 100644 --- a/transport/tuic/packet.go +++ b/transport/tuic/packet.go @@ -41,7 +41,6 @@ type udpMessage struct { fragmentTotal uint8 fragmentID uint8 destination M.Socksaddr - dataLength uint16 data *buf.Buffer } @@ -72,7 +71,7 @@ func (m *udpMessage) pack() *buf.Buffer { } func (m *udpMessage) headerSize() int { - return 2 + 10 + addressSerializer.AddrPortLen(m.destination) + return 10 + addressSerializer.AddrPortLen(m.destination) } func fragUDPMessage(message *udpMessage, maxPacketSize int) []*udpMessage { @@ -106,18 +105,19 @@ func fragUDPMessage(message *udpMessage, maxPacketSize int) []*udpMessage { } type udpPacketConn struct { - ctx context.Context - cancel common.ContextCancelCauseFunc - sessionID uint16 - quicConn quic.Connection - data chan *udpMessage - udpStream bool - udpMTU int - packetId atomic.Uint32 - closeOnce sync.Once - isServer bool - defragger *udpDefragger - onDestroy func() + ctx context.Context + cancel common.ContextCancelCauseFunc + sessionID uint16 + quicConn quic.Connection + data chan *udpMessage + udpStream bool + udpMTU int + udpMTUTime time.Time + packetId atomic.Uint32 + closeOnce sync.Once + isServer bool + defragger *udpDefragger + onDestroy func() } func newUDPPacketConn(ctx context.Context, quicConn quic.Connection, udpStream bool, isServer bool, onDestroy func()) *udpPacketConn { @@ -186,6 +186,15 @@ func (c *udpPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { } } +func (c *udpPacketConn) needFragment() bool { + nowTime := time.Now() + if c.udpMTU > 0 && nowTime.Sub(c.udpMTUTime) < 5*time.Second { + c.udpMTUTime = nowTime + return true + } + return false +} + func (c *udpPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { defer buffer.Release() select { @@ -211,7 +220,7 @@ func (c *udpPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) } defer message.releaseMessage() var err error - if !c.udpStream && c.udpMTU > 0 && buffer.Len() > c.udpMTU { + if !c.udpStream && c.needFragment() && buffer.Len() > c.udpMTU { err = c.writePackets(fragUDPMessage(message, c.udpMTU)) } else { err = c.writePacket(message) @@ -224,6 +233,7 @@ func (c *udpPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) return err } c.udpMTU = int(tooLargeErr) + c.udpMTUTime = time.Now() return c.writePackets(fragUDPMessage(message, c.udpMTU)) } @@ -265,6 +275,7 @@ func (c *udpPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { return } c.udpMTU = int(tooLargeErr) + c.udpMTUTime = time.Now() err = c.writePackets(fragUDPMessage(message, c.udpMTU)) if err == nil { return len(p), nil @@ -414,10 +425,14 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage { } newMessage := udpMessagePool.Get().(*udpMessage) *newMessage = *item.messages[0] - if m.dataLength > 0 { - newMessage.data = buf.NewSize(int(m.dataLength)) + var dataLength uint16 + for _, message := range item.messages { + dataLength += uint16(message.data.Len()) + } + if dataLength > 0 { + newMessage.data = buf.NewSize(int(dataLength)) for _, message := range item.messages { - newMessage.data.Write(message.data.Bytes()) + common.Must1(newMessage.data.Write(message.data.Bytes())) message.releaseMessage() } item.messages = nil @@ -447,7 +462,8 @@ func readUDPMessage(message *udpMessage, reader io.Reader) error { if err != nil { return err } - err = binary.Read(reader, binary.BigEndian, &message.dataLength) + var dataLength uint16 + err = binary.Read(reader, binary.BigEndian, &dataLength) if err != nil { return err } @@ -455,7 +471,7 @@ func readUDPMessage(message *udpMessage, reader io.Reader) error { if err != nil { return err } - message.data = buf.NewSize(int(message.dataLength)) + message.data = buf.NewSize(int(dataLength)) _, err = message.data.ReadFullFrom(reader, message.data.FreeLen()) if err != nil { return err @@ -481,7 +497,8 @@ func decodeUDPMessage(message *udpMessage, data []byte) error { if err != nil { return err } - err = binary.Read(reader, binary.BigEndian, &message.dataLength) + var dataLength uint16 + err = binary.Read(reader, binary.BigEndian, &dataLength) if err != nil { return err } @@ -489,7 +506,7 @@ func decodeUDPMessage(message *udpMessage, data []byte) error { if err != nil { return err } - if reader.Len() != int(message.dataLength) { + if reader.Len() != int(dataLength) { return io.ErrUnexpectedEOF } message.data = buf.As(data[len(data)-reader.Len():])