From c40140bbae2f2bbb3fd33161e60c5c118ff9eaec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 3 Aug 2023 15:03:29 +0800 Subject: [PATCH] Fix UDP async write --- go.mod | 4 ++-- go.sum | 8 ++++---- test/go.mod | 4 ++-- test/go.sum | 2 ++ transport/trojan/protocol.go | 14 +++++++++++--- transport/vless/client.go | 28 +++++++++++++++++++++------- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index f80a556f..9239496f 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/sing v0.2.10-0.20230802105922-c6a69b4912ee github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 - github.com/sagernet/sing-mux v0.1.2 + github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/sing-shadowsocks2 v0.1.3 github.com/sagernet/sing-shadowtls v0.1.4 @@ -45,7 +45,7 @@ require ( go4.org/netipx v0.0.0-20230728184502-ec4c8b891b28 golang.org/x/crypto v0.11.0 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df - golang.org/x/net v0.12.0 + golang.org/x/net v0.13.0 golang.org/x/sys v0.10.0 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 google.golang.org/grpc v1.57.0 diff --git a/go.sum b/go.sum index 44c62112..3ca3b15a 100644 --- a/go.sum +++ b/go.sum @@ -122,8 +122,8 @@ github.com/sagernet/sing v0.2.10-0.20230802105922-c6a69b4912ee h1:5MATgtWMh2TCAV github.com/sagernet/sing v0.2.10-0.20230802105922-c6a69b4912ee/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.2 h1:av2/m6e+Gh+ECTuJZqYCjJz55BNkot0VyRMkREqyF/g= -github.com/sagernet/sing-mux v0.1.2/go.mod h1:r2V8AlOzXaRCHXK7fILCUGzuI2iILweTaG8C5xlpHxo= +github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 h1:IQ7oBBKz+lwIqwI9IMStlQ9YSUu3eKJmNTip0aLbvOI= +github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY= github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY= github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA= @@ -187,8 +187,8 @@ golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/test/go.mod b/test/go.mod index 8cf94321..d4e42fbb 100644 --- a/test/go.mod +++ b/test/go.mod @@ -16,7 +16,7 @@ require ( github.com/spyzhov/ajson v0.7.1 github.com/stretchr/testify v1.8.4 go.uber.org/goleak v1.2.0 - golang.org/x/net v0.12.0 + golang.org/x/net v0.13.0 ) require ( @@ -74,7 +74,7 @@ require ( github.com/sagernet/quic-go v0.0.0-20230731012313-1327e4015111 // 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.2 // indirect + github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 // indirect github.com/sagernet/sing-shadowtls v0.1.4 // indirect github.com/sagernet/sing-tun v0.1.11 // indirect github.com/sagernet/sing-vmess v0.1.7 // indirect diff --git a/test/go.sum b/test/go.sum index ae31ba7d..766545db 100644 --- a/test/go.sum +++ b/test/go.sum @@ -150,6 +150,7 @@ github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659/go.mod h1:W7GH github.com/sagernet/sing-mux v0.1.1-0.20230703132253-2cedde0fbc90 h1:aEe2HrRc9OTS7IZ8RHyh224OhltnwRQs4/y89UsHPo8= github.com/sagernet/sing-mux v0.1.1-0.20230703132253-2cedde0fbc90/go.mod h1:sm126rB5EUi9HLf4jCSHTqo+XRPbh4BoEVeLbr2WRbE= github.com/sagernet/sing-mux v0.1.2/go.mod h1:r2V8AlOzXaRCHXK7fILCUGzuI2iILweTaG8C5xlpHxo= +github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY= github.com/sagernet/sing-shadowsocks v0.2.3-0.20230703131347-b044960bd355 h1:XOgNZYnkDrx5qtNS4kqIOHMhjZuc7mJ2pY/x3EyZX8Q= github.com/sagernet/sing-shadowsocks v0.2.3-0.20230703131347-b044960bd355/go.mod h1:atEATsxqPo8qCPcFt8Rw7TFEJ70egCoMR7PziX4jmjI= github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= @@ -229,6 +230,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/transport/trojan/protocol.go b/transport/trojan/protocol.go index b81b9046..b208c084 100644 --- a/transport/trojan/protocol.go +++ b/transport/trojan/protocol.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "net" "os" + "sync" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" @@ -84,6 +85,7 @@ func (c *ClientConn) Upstream() any { type ClientPacketConn struct { net.Conn + access sync.Mutex key [KeyLength]byte headerWritten bool } @@ -105,9 +107,15 @@ func (c *ClientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { func (c *ClientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { if !c.headerWritten { - err := ClientHandshakePacket(c.Conn, c.key, destination, buffer) - c.headerWritten = true - return err + c.access.Lock() + if c.headerWritten { + c.access.Unlock() + } else { + err := ClientHandshakePacket(c.Conn, c.key, destination, buffer) + c.headerWritten = true + c.access.Unlock() + return err + } } return WritePacket(c.Conn, buffer, destination) } diff --git a/transport/vless/client.go b/transport/vless/client.go index 14a4e4c8..cb9ca9cb 100644 --- a/transport/vless/client.go +++ b/transport/vless/client.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "io" "net" + "sync" "github.com/sagernet/sing-vmess" "github.com/sagernet/sing/common" @@ -190,6 +191,7 @@ func (c *Conn) Upstream() any { type PacketConn struct { net.Conn + access sync.Mutex key [16]byte destination M.Socksaddr flow string @@ -218,11 +220,17 @@ func (c *PacketConn) Read(b []byte) (n int, err error) { func (c *PacketConn) Write(b []byte) (n int, err error) { if !c.requestWritten { - err = WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination, c.flow}, nil) - if err == nil { - n = len(b) + c.access.Lock() + if c.requestWritten { + c.access.Unlock() + } else { + err = WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination, c.flow}, nil) + if err == nil { + n = len(b) + } + c.requestWritten = true + c.access.Unlock() } - c.requestWritten = true } err = binary.Write(c.Conn, binary.BigEndian, uint16(len(b))) if err != nil { @@ -236,9 +244,15 @@ func (c *PacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) er dataLen := buffer.Len() binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(dataLen)) if !c.requestWritten { - err := WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination, c.flow}, buffer.Bytes()) - c.requestWritten = true - return err + c.access.Lock() + if c.requestWritten { + c.access.Unlock() + } else { + err := WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination, c.flow}, buffer.Bytes()) + c.requestWritten = true + c.access.Unlock() + return err + } } return common.Error(c.Conn.Write(buffer.Bytes())) }