1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-27 22:36:12 -04:00

feat: use security engine in h2 transport

This will enable uTLS support for h2 transport.
This commit is contained in:
pathC 2023-08-09 08:38:12 +00:00 committed by Shelikhoo
parent a98f468ac4
commit 21b7a0046b
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316
2 changed files with 24 additions and 16 deletions

View File

@ -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...)

View File

@ -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}
}