diff --git a/go.mod b/go.mod index 666a03e4..b50e48e8 100644 --- a/go.mod +++ b/go.mod @@ -45,9 +45,9 @@ require ( github.com/sagernet/netlink v0.0.0-20260814022025-64455d367bbf github.com/sagernet/nftables v0.3.0-mod.4 github.com/sagernet/quic-go v0.61.0-sing-box-mod.7 - github.com/sagernet/sing v0.9.4 + github.com/sagernet/sing v0.9.5 github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 - github.com/sagernet/sing-mux v0.3.6 + github.com/sagernet/sing-mux v0.3.8 github.com/sagernet/sing-openconnect v0.0.0-20260810065514-53aa8058f8df github.com/sagernet/sing-openvpn v0.0.0-20260729104525-103eb5fe5eb6 github.com/sagernet/sing-quic v0.7.0 diff --git a/go.sum b/go.sum index 95579cb2..c34178eb 100644 --- a/go.sum +++ b/go.sum @@ -318,12 +318,12 @@ github.com/sagernet/nftables v0.3.0-mod.4 h1:vnOtcDYeSXv2e5RoRuGH0lrpttQFJ8iC4IC github.com/sagernet/nftables v0.3.0-mod.4/go.mod h1:8kslHG4VvYNihcco+i6uxIX7qbT8A56T0y5q7U44ZaQ= github.com/sagernet/quic-go v0.61.0-sing-box-mod.7 h1:sW2O+DoNF+my1PGlSZ3zG2N+fdxLR3DC0l4sXCM0lBE= github.com/sagernet/quic-go v0.61.0-sing-box-mod.7/go.mod h1:hmLC8GJPp+BrpBgrgJnacvI4fZGIhasuy1ROJJ8GR4E= -github.com/sagernet/sing v0.9.4 h1:nIdH+Yvy4NzTezB+c3z/9of1jLRggnrtMtb3uMOIaNM= -github.com/sagernet/sing v0.9.4/go.mod h1:K3Owt3xPhHugvlnlPPxZJ/exXdaJfEPOTNorGk4AXjo= +github.com/sagernet/sing v0.9.5 h1:BHaElRqhHhkH747xIkxgsqgRJxkIiuAlpnfwiJnu2aY= +github.com/sagernet/sing v0.9.5/go.mod h1:K3Owt3xPhHugvlnlPPxZJ/exXdaJfEPOTNorGk4AXjo= github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 h1:3y6++yIa8XlDhxPkpR4p+7RUHVY2KTP9CPIGnWmOlO8= github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3/go.mod h1:XEqEDYRCAYLaoPjZ1ifVWJg5iWAJHL2gOAXe/PM28Cg= -github.com/sagernet/sing-mux v0.3.6 h1:ix+CPhZsR9XIAmEVLIUdz+itDzXs1T6iKO8eF/XOVOQ= -github.com/sagernet/sing-mux v0.3.6/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= +github.com/sagernet/sing-mux v0.3.8 h1:mM0TLUkr36aEhgUHi9Qh60qcAbD2fZcmnJ30937xxrY= +github.com/sagernet/sing-mux v0.3.8/go.mod h1:jricpwCOndDsTEM1TM3piJvhL/2Mm7OhLkm+JadJJ1Q= github.com/sagernet/sing-openconnect v0.0.0-20260810065514-53aa8058f8df h1:ogyC7KPTWueN7kXFhKSdHeS5/t/zBjQgAOpWjqnrMos= github.com/sagernet/sing-openconnect v0.0.0-20260810065514-53aa8058f8df/go.mod h1:4AKZLVcvY3r54UaK2Gbnm7aN8pOwdLz+y4EP0QFZ5Eg= github.com/sagernet/sing-openvpn v0.0.0-20260729104525-103eb5fe5eb6 h1:ZAvhkor0prJ8KEX9EmTEH+gJ1WlA3ffjS8GZT6KKq9c= diff --git a/transport/v2raygrpclite/conn.go b/transport/v2raygrpclite/conn.go index b1f45222..896183b9 100644 --- a/transport/v2raygrpclite/conn.go +++ b/transport/v2raygrpclite/conn.go @@ -64,7 +64,7 @@ func (c *GunConn) Read(b []byte) (n int, err error) { } func (c *GunConn) read(b []byte) (n int, err error) { - if c.reader == nil { + if c.create != nil { <-c.create if c.err != nil { return 0, c.err @@ -144,7 +144,17 @@ func (c *GunConn) FrontHeadroom() int { } func (c *GunConn) Close() error { - err := common.Close(c.rawReader, c.writer) + var reader io.Reader + if c.create != nil { + select { + case <-c.create: + reader = c.rawReader + default: + } + } else { + reader = c.rawReader + } + err := common.Close(reader, c.writer) if c.cancel != nil { c.cancel() } diff --git a/transport/v2rayhttp/client.go b/transport/v2rayhttp/client.go index fdd9210c..bba65960 100644 --- a/transport/v2rayhttp/client.go +++ b/transport/v2rayhttp/client.go @@ -16,6 +16,7 @@ import ( "github.com/sagernet/sing-box/common/tls" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" @@ -30,7 +31,7 @@ type Client struct { ctx context.Context dialer N.Dialer serverAddr M.Socksaddr - transport http.RoundTripper + transport common.TypedValue[http.RoundTripper] http2 bool requestURL url.URL host []string @@ -77,7 +78,7 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt if !strings.HasPrefix(requestURL.Path, "/") { requestURL.Path = "/" + requestURL.Path } - return &Client{ + client := &Client{ ctx: ctx, dialer: dialer, serverAddr: serverAddr, @@ -85,9 +86,10 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt host: options.Host, method: options.Method, headers: options.Headers.Build(), - transport: transport, http2: tlsConfig != nil, - }, nil + } + client.transport.Store(transport) + return client, nil } func (c *Client) DialContext(ctx context.Context) (net.Conn, error) { @@ -151,7 +153,7 @@ func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) { cancel() }) go func() { - response, err := c.transport.RoundTrip(request) + response, err := c.transport.Load().RoundTrip(request) handshakeTimer.Stop() if err != nil { if handshakeTimedOut.Load() { @@ -169,6 +171,6 @@ func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) { } func (c *Client) Close() error { - c.transport = ResetTransport(c.transport) + c.transport.Store(ResetTransport(c.transport.Load())) return nil } diff --git a/transport/v2rayhttp/conn.go b/transport/v2rayhttp/conn.go index 5f5cadb9..758eda7f 100644 --- a/transport/v2rayhttp/conn.go +++ b/transport/v2rayhttp/conn.go @@ -159,10 +159,10 @@ func (c *HTTP2Conn) Setup(reader io.Reader, err error) { } func (c *HTTP2Conn) Read(b []byte) (n int, err error) { - if c.reader == nil { + if c.create != nil { <-c.create if c.err != nil { - return 0, c.err + return 0, baderror.WrapH2(c.err) } } n, err = c.reader.Read(b) @@ -175,7 +175,17 @@ func (c *HTTP2Conn) Write(b []byte) (n int, err error) { } func (c *HTTP2Conn) Close() error { - err := common.Close(c.reader, c.writer) + var reader io.Reader + if c.create != nil { + select { + case <-c.create: + reader = c.reader + default: + } + } else { + reader = c.reader + } + err := common.Close(reader, c.writer) if c.cancel != nil { c.cancel() }