From 2c44b4e170e96d0383b78159bb56c201416e1537 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Sat, 3 Jun 2023 16:45:35 +0800 Subject: [PATCH] chore: update quic-go to 0.35.1 --- adapter/outbound/tuic.go | 13 ++++---- dns/doh.go | 12 +++++++- dns/doq.go | 23 +++++++++------ go.mod | 2 +- go.sum | 4 +-- listener/tuic/server.go | 4 +-- transport/hysteria/transport/client.go | 5 +++- transport/tuic/client.go | 9 +++--- transport/tuic/pool_client.go | 41 ++++++++++++++++---------- transport/tuic/server.go | 2 +- 10 files changed, 68 insertions(+), 47 deletions(-) diff --git a/adapter/outbound/tuic.go b/adapter/outbound/tuic.go index f2452ae2..ab371757 100644 --- a/adapter/outbound/tuic.go +++ b/adapter/outbound/tuic.go @@ -90,11 +90,7 @@ func (t *Tuic) SupportWithDialer() C.NetWork { return C.ALLNet } -func (t *Tuic) dial(ctx context.Context, opts ...dialer.Option) (pc net.PacketConn, addr net.Addr, err error) { - return t.dialWithDialer(ctx, dialer.NewDialer(opts...)) -} - -func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (pc net.PacketConn, addr net.Addr, err error) { +func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) { if len(t.option.DialerProxy) > 0 { dialer, err = proxydialer.NewByName(t.option.DialerProxy, dialer) if err != nil { @@ -106,10 +102,14 @@ func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (pc net.Pack return nil, nil, err } addr = udpAddr + var pc net.PacketConn pc, err = dialer.ListenPacket(ctx, "udp", "", udpAddr.AddrPort()) if err != nil { return nil, nil, err } + transport = &quic.Transport{Conn: pc} + transport.SetCreatedConn(true) // auto close conn + transport.SetSingleUse(true) // auto close transport return } @@ -220,9 +220,7 @@ func NewTuic(option TuicOption) (*Tuic, error) { if len(option.Ip) > 0 { addr = net.JoinHostPort(option.Ip, strconv.Itoa(option.Port)) } - host := option.Server if option.DisableSni { - host = "" tlsConfig.ServerName = "" } tkn := tuic.GenTKN(option.Token) @@ -254,7 +252,6 @@ func NewTuic(option TuicOption) (*Tuic, error) { clientOption := &tuic.ClientOption{ TlsConfig: tlsConfig, QuicConfig: quicConfig, - Host: host, Token: tkn, UdpRelayMode: option.UdpRelayMode, CongestionController: option.CongestionController, diff --git a/dns/doh.go b/dns/doh.go index dd8ba435..49e502fd 100644 --- a/dns/doh.go +++ b/dns/doh.go @@ -543,7 +543,17 @@ func (doh *dnsOverHTTPS) dialQuic(ctx context.Context, addr string, tlsCfg *tls. if err != nil { return nil, err } - return quic.DialEarlyContext(ctx, conn, &udpAddr, doh.url.Host, tlsCfg, cfg) + transport := quic.Transport{Conn: conn} + transport.SetCreatedConn(true) // auto close conn + transport.SetSingleUse(true) // auto close transport + tlsCfg = tlsCfg.Clone() + if host, _, err := net.SplitHostPort(doh.url.Host); err == nil { + tlsCfg.ServerName = host + } else { + // It's ok if net.SplitHostPort returns an error - it could be a hostname/IP address without a port. + tlsCfg.ServerName = doh.url.Host + } + return transport.DialEarly(ctx, &udpAddr, tlsCfg, cfg) } // probeH3 runs a test to check whether QUIC is faster than TLS for this diff --git a/dns/doq.go b/dns/doq.go index 73310340..f0016d79 100644 --- a/dns/doq.go +++ b/dns/doq.go @@ -302,14 +302,6 @@ func (doq *dnsOverQUIC) openStream(ctx context.Context, conn quic.Connection) (q // openConnection opens a new QUIC connection. func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn quic.Connection, err error) { - tlsConfig := tlsC.GetGlobalTLSConfig( - &tls.Config{ - InsecureSkipVerify: false, - NextProtos: []string{ - NextProtoDQ, - }, - SessionTicketsDisabled: false, - }) // we're using bootstrapped address instead of what's passed to the function // it does not create an actual connection, but it helps us determine // what IP is actually reachable (when there're v4/v6 addresses). @@ -338,7 +330,20 @@ func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn quic.Connectio return nil, err } - conn, err = quic.DialContext(ctx, udp, &udpAddr, host, tlsConfig, doq.getQUICConfig()) + tlsConfig := tlsC.GetGlobalTLSConfig( + &tls.Config{ + ServerName: host, + InsecureSkipVerify: false, + NextProtos: []string{ + NextProtoDQ, + }, + SessionTicketsDisabled: false, + }) + + transport := quic.Transport{Conn: udp} + transport.SetCreatedConn(true) // auto close conn + transport.SetSingleUse(true) // auto close transport + conn, err = transport.Dial(ctx, &udpAddr, tlsConfig, doq.getQUICConfig()) if err != nil { return nil, fmt.Errorf("opening quic connection to %s: %w", doq.addr, err) } diff --git a/go.mod b/go.mod index d7d6a9a8..89071513 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/mdlayher/netlink v1.7.2 - github.com/metacubex/quic-go v0.34.1-0.20230601081651-513972f322ee + github.com/metacubex/quic-go v0.35.2-0.20230603072621-ea2663348ebb github.com/metacubex/sing-shadowsocks v0.2.2-0.20230509230448-a5157cc00a1c github.com/metacubex/sing-shadowsocks2 v0.0.0-20230529235701-a238874242ca github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e diff --git a/go.sum b/go.sum index a2c2e197..d4c2e2f4 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,8 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/metacubex/gvisor v0.0.0-20230417114019-3c3ee672d60c h1:D62872jiuzC6b+3aI8tqfeyc6YgbfarYKywTnnvXwEM= github.com/metacubex/gvisor v0.0.0-20230417114019-3c3ee672d60c/go.mod h1:wqEuzdImyqD2MCGE8CYRJXbB77oSEJeoSSXXdwKjnsE= -github.com/metacubex/quic-go v0.34.1-0.20230601081651-513972f322ee h1:BcLrrY8wYQ/XdCVXdofXei2i8BDfWNn5ojbM8gQPJyw= -github.com/metacubex/quic-go v0.34.1-0.20230601081651-513972f322ee/go.mod h1:6pg8+Tje9KOltnj1whuvB2i5KFUMPp1TAF3oPhc5axM= +github.com/metacubex/quic-go v0.35.2-0.20230603072621-ea2663348ebb h1:92YTNmYXCSycERjKn/zPbeK5DiW3dd80j3+oVTEWTE8= +github.com/metacubex/quic-go v0.35.2-0.20230603072621-ea2663348ebb/go.mod h1:6pg8+Tje9KOltnj1whuvB2i5KFUMPp1TAF3oPhc5axM= github.com/metacubex/sing v0.0.0-20230530121223-b768faae5c6b h1:Bw4j3ktf5vivi5qm/ZQGtyRAgybRKSGJaMV1t3rtC+I= github.com/metacubex/sing v0.0.0-20230530121223-b768faae5c6b/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/metacubex/sing-shadowsocks v0.2.2-0.20230509230448-a5157cc00a1c h1:LpVNvlW/xE+mR8z76xJeYZlYznZXEmU4TeWeuygYdJg= diff --git a/listener/tuic/server.go b/listener/tuic/server.go index 92cc0b37..498708bf 100644 --- a/listener/tuic/server.go +++ b/listener/tuic/server.go @@ -52,9 +52,7 @@ func New(config LC.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- C.Packet MaxIncomingStreams: ServerMaxIncomingStreams, MaxIncomingUniStreams: ServerMaxIncomingStreams, EnableDatagrams: true, - Allow0RTT: func(addr net.Addr) bool { - return true - }, + Allow0RTT: true, } quicConfig.InitialStreamReceiveWindow = tuic.DefaultStreamReceiveWindow / 10 quicConfig.MaxStreamReceiveWindow = tuic.DefaultStreamReceiveWindow diff --git a/transport/hysteria/transport/client.go b/transport/hysteria/transport/client.go index e65e5016..67568bc8 100644 --- a/transport/hysteria/transport/client.go +++ b/transport/hysteria/transport/client.go @@ -76,7 +76,10 @@ func (ct *ClientTransport) QUICDial(proto string, server string, serverPorts str return nil, err } - qs, err := quic.DialContext(dialer.Context(), pktConn, serverUDPAddr, server, tlsConfig, quicConfig) + transport := quic.Transport{Conn: pktConn} + transport.SetCreatedConn(true) // auto close conn + transport.SetSingleUse(true) // auto close transport + qs, err := transport.Dial(dialer.Context(), serverUDPAddr, tlsConfig, quicConfig) if err != nil { _ = pktConn.Close() return nil, err diff --git a/transport/tuic/client.go b/transport/tuic/client.go index c18a9049..6fd2a241 100644 --- a/transport/tuic/client.go +++ b/transport/tuic/client.go @@ -28,12 +28,11 @@ var ( TooManyOpenStreams = errors.New("tuic: too many open streams") ) -type DialFunc func(ctx context.Context, dialer C.Dialer) (pc net.PacketConn, addr net.Addr, err error) +type DialFunc func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) type ClientOption struct { TlsConfig *tls.Config QuicConfig *quic.Config - Host string Token [32]byte UdpRelayMode string CongestionController string @@ -67,15 +66,15 @@ func (t *clientImpl) getQuicConn(ctx context.Context, dialer C.Dialer, dialFn Di if t.quicConn != nil { return t.quicConn, nil } - pc, addr, err := dialFn(ctx, dialer) + transport, addr, err := dialFn(ctx, dialer) if err != nil { return nil, err } var quicConn quic.Connection if t.ReduceRtt { - quicConn, err = quic.DialEarlyContext(ctx, pc, addr, t.Host, t.TlsConfig, t.QuicConfig) + quicConn, err = transport.DialEarly(ctx, addr, t.TlsConfig, t.QuicConfig) } else { - quicConn, err = quic.DialContext(ctx, pc, addr, t.Host, t.TlsConfig, t.QuicConfig) + quicConn, err = transport.Dial(ctx, addr, t.TlsConfig, t.QuicConfig) } if err != nil { return nil, err diff --git a/transport/tuic/pool_client.go b/transport/tuic/pool_client.go index 04ada7c0..223436cd 100644 --- a/transport/tuic/pool_client.go +++ b/transport/tuic/pool_client.go @@ -12,12 +12,14 @@ import ( N "github.com/Dreamacro/clash/common/net" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" + + "github.com/metacubex/quic-go" ) type dialResult struct { - pc net.PacketConn - addr net.Addr - err error + transport *quic.Transport + addr net.Addr + err error } type PoolClient struct { @@ -33,9 +35,12 @@ type PoolClient struct { } func (t *PoolClient) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.Conn, error) { - conn, err := t.getClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, dialFn) + newDialFn := func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) { + return t.dial(ctx, dialer, dialFn) + } + conn, err := t.getClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, newDialFn) if errors.Is(err, TooManyOpenStreams) { - conn, err = t.newClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, dialFn) + conn, err = t.newClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, newDialFn) } if err != nil { return nil, err @@ -44,9 +49,12 @@ func (t *PoolClient) DialContextWithDialer(ctx context.Context, metadata *C.Meta } func (t *PoolClient) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.PacketConn, error) { - pc, err := t.getClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, dialFn) + newDialFn := func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) { + return t.dial(ctx, dialer, dialFn) + } + pc, err := t.getClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, newDialFn) if errors.Is(err, TooManyOpenStreams) { - pc, err = t.newClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, dialFn) + pc, err = t.newClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, newDialFn) } if err != nil { return nil, err @@ -54,37 +62,38 @@ func (t *PoolClient) ListenPacketWithDialer(ctx context.Context, metadata *C.Met return N.NewRefPacketConn(pc, t), nil } -func (t *PoolClient) dial(ctx context.Context, dialer C.Dialer, dialFn DialFunc) (pc net.PacketConn, addr net.Addr, err error) { +func (t *PoolClient) dial(ctx context.Context, dialer C.Dialer, dialFn DialFunc) (transport *quic.Transport, addr net.Addr, err error) { t.dialResultMutex.Lock() dr, ok := t.dialResultMap[dialer] t.dialResultMutex.Unlock() if ok { - return dr.pc, dr.addr, dr.err + return dr.transport, dr.addr, dr.err } - pc, addr, err = dialFn(ctx, dialer) + transport, addr, err = dialFn(ctx, dialer) if err != nil { return nil, nil, err } - if _, ok := pc.(*net.UDPConn); ok { // only cache the system's UDPConn - dr.pc, dr.addr, dr.err = pc, addr, err + if _, ok := transport.Conn.(*net.UDPConn); ok { // only cache the system's UDPConn + transport.SetSingleUse(false) // don't close transport in each dial + dr.transport, dr.addr, dr.err = transport, addr, err t.dialResultMutex.Lock() t.dialResultMap[dialer] = dr t.dialResultMutex.Unlock() } - return pc, addr, err + return transport, addr, err } func (t *PoolClient) forceClose() { t.dialResultMutex.Lock() defer t.dialResultMutex.Unlock() for key := range t.dialResultMap { - pc := t.dialResultMap[key].pc - if pc != nil { - _ = pc.Close() + transport := t.dialResultMap[key].transport + if transport != nil { + _ = transport.Close() } delete(t.dialResultMap, key) } diff --git a/transport/tuic/server.go b/transport/tuic/server.go index fa0537b9..f8c4b20a 100644 --- a/transport/tuic/server.go +++ b/transport/tuic/server.go @@ -35,7 +35,7 @@ type ServerOption struct { type Server struct { *ServerOption - listener quic.EarlyListener + listener *quic.EarlyListener } func NewServer(option *ServerOption, pc net.PacketConn) (*Server, error) {