diff --git a/transport/internet/http/dialer.go b/transport/internet/http/dialer.go index f214e9573..afeae38d6 100644 --- a/transport/internet/http/dialer.go +++ b/transport/internet/http/dialer.go @@ -3,6 +3,7 @@ package http import ( "context" gotls "crypto/tls" + gonet "net" "net/http" "net/url" "sync" @@ -14,7 +15,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/transport/internet" - "github.com/v2fly/v2ray-core/v5/transport/internet/tls" + "github.com/v2fly/v2ray-core/v5/transport/internet/security" "github.com/v2fly/v2ray-core/v5/transport/pipe" ) @@ -25,7 +26,7 @@ var ( type dialerCanceller func() -func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config, streamSettings *internet.MemoryStreamConfig) (*http.Client, dialerCanceller) { +func getHTTPClient(ctx context.Context, dest net.Destination, securityEngine *security.Engine, streamSettings *internet.MemoryStreamConfig) (*http.Client, dialerCanceller) { globalDialerAccess.Lock() defer globalDialerAccess.Unlock() @@ -44,7 +45,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C } transport := &http2.Transport{ - DialTLS: func(network string, addr string, tlsConfig *gotls.Config) (net.Conn, error) { + DialTLSContext: func(ctx context.Context, network, addr string, tlsConfig *gotls.Config) (gonet.Conn, error) { rawHost, rawPort, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -64,22 +65,26 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C return nil, err } - cn := gotls.Client(pconn, tlsConfig) - if err := cn.Handshake(); err != nil { + cn, err := (*securityEngine).Client(pconn, + security.OptionWithDestination{Dest: dest}) + if err != nil { return nil, err } - if !tlsConfig.InsecureSkipVerify { - if err := cn.VerifyHostname(tlsConfig.ServerName); err != nil { - return nil, err + + protocol := "" + if connAPLNGetter, ok := cn.(security.ConnectionApplicationProtocol); ok { + connectionALPN, err := connAPLNGetter.GetConnectionApplicationProtocol() + if err != nil { + return nil, newError("failed to get connection ALPN").Base(err).AtWarning() } + protocol = connectionALPN } - state := cn.ConnectionState() - if p := state.NegotiatedProtocol; p != http2.NextProtoTLS { - return nil, newError("http2: unexpected ALPN protocol " + p + "; want q" + http2.NextProtoTLS).AtError() + + if protocol != http2.NextProtoTLS { + return nil, newError("http2: unexpected ALPN protocol " + protocol + "; want q" + http2.NextProtoTLS).AtError() } return cn, nil }, - TLSClientConfig: tlsSettings.GetTLSConfig(tls.WithDestination(dest)), } client := &http.Client{ @@ -93,11 +98,14 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C // Dial dials a new TCP connection to the given destination. func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { httpSettings := streamSettings.ProtocolSettings.(*Config) - tlsConfig := tls.ConfigFromStreamSettings(streamSettings) - if tlsConfig == nil { + securityEngine, err := security.CreateSecurityEngineFromSettings(ctx, streamSettings) + if err != nil { + return nil, newError("unable to create security engine").Base(err) + } + if securityEngine == nil { return nil, newError("TLS must be enabled for http transport.").AtWarning() } - client, canceller := getHTTPClient(ctx, dest, tlsConfig, streamSettings) + client, canceller := getHTTPClient(ctx, dest, &securityEngine, streamSettings) opts := pipe.OptionsFromContext(ctx) preader, pwriter := pipe.New(opts...) diff --git a/transport/internet/tls/tls.go b/transport/internet/tls/tls.go index 389315316..14a8d77af 100644 --- a/transport/internet/tls/tls.go +++ b/transport/internet/tls/tls.go @@ -43,7 +43,7 @@ func (c *Conn) HandshakeAddress() net.Address { } // Client initiates a TLS client handshake on the given connection. -func Client(c net.Conn, config *tls.Config) net.Conn { +func Client(c net.Conn, config *tls.Config) *Conn { tlsConn := tls.Client(c, config) return &Conn{Conn: tlsConn} }