Browse Source

Use security engine for (tls like) security client without transport

Shelikhoo 2 years ago
parent
commit
de55f3a675

+ 11 - 4
app/proxyman/outbound/handler.go

@@ -17,7 +17,7 @@ import (
 	"github.com/v2fly/v2ray-core/v5/proxy"
 	"github.com/v2fly/v2ray-core/v5/proxy"
 	"github.com/v2fly/v2ray-core/v5/transport"
 	"github.com/v2fly/v2ray-core/v5/transport"
 	"github.com/v2fly/v2ray-core/v5/transport/internet"
 	"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"
 	"github.com/v2fly/v2ray-core/v5/transport/pipe"
 )
 )
 
 
@@ -182,9 +182,16 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
 				go handler.Dispatch(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter})
 				go handler.Dispatch(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter})
 				conn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader))
 				conn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader))
 
 
-				if config := tls.ConfigFromStreamSettings(h.streamSettings); config != nil {
-					tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
-					conn = tls.Client(conn, tlsConfig)
+				securityEngine, err := security.CreateSecurityEngineFromSettings(ctx, h.streamSettings)
+				if err != nil {
+					return nil, newError("unable to create security engine").Base(err)
+				}
+
+				if securityEngine != nil {
+					conn, err = securityEngine.Client(conn)
+					if err != nil {
+						return nil, newError("unable to create security protocol client from security engine").Base(err)
+					}
 				}
 				}
 
 
 				return h.getStatCouterConnection(conn), nil
 				return h.getStatCouterConnection(conn), nil

+ 9 - 0
transport/internet/security/errors.generated.go

@@ -0,0 +1,9 @@
+package security
+
+import "github.com/v2fly/v2ray-core/v5/common/errors"
+
+type errPathObjHolder struct{}
+
+func newError(values ...interface{}) *errors.Error {
+	return errors.New(values...).WithPathObj(errPathObjHolder{})
+}

+ 33 - 0
transport/internet/security/security.go

@@ -0,0 +1,33 @@
+package security
+
+//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
+
+import (
+	"github.com/v2fly/v2ray-core/v5/common/net"
+)
+
+type Engine interface {
+	Client(conn net.Conn, opts ...Option) (Conn, error)
+}
+
+type Conn interface {
+	net.Conn
+}
+
+type Option interface {
+	isSecurityOption()
+}
+
+type OptionWithALPN struct {
+	ALPNs []string
+}
+
+func (a OptionWithALPN) isSecurityOption() {
+}
+
+type OptionWithDestination struct {
+	Dest net.Destination
+}
+
+func (a OptionWithDestination) isSecurityOption() {
+}

+ 23 - 0
transport/internet/security/util.go

@@ -0,0 +1,23 @@
+package security
+
+import (
+	"context"
+
+	"github.com/v2fly/v2ray-core/v5/common"
+	"github.com/v2fly/v2ray-core/v5/transport/internet"
+)
+
+func CreateSecurityEngineFromSettings(context context.Context, settings *internet.MemoryStreamConfig) (Engine, error) {
+	if settings == nil || settings.SecurityType == "" {
+		return nil, nil
+	}
+	securityEngine, err := common.CreateObject(context, settings.SecuritySettings)
+	if err != nil {
+		return nil, newError("unable to create security engine from security settings").Base(err)
+	}
+	securityEngineTyped, ok := securityEngine.(Engine)
+	if !ok {
+		return nil, newError("type assertion error when create security engine from security settings")
+	}
+	return securityEngineTyped, nil
+}

+ 11 - 11
transport/internet/tcp/dialer.go

@@ -8,7 +8,7 @@ import (
 	"github.com/v2fly/v2ray-core/v5/common/serial"
 	"github.com/v2fly/v2ray-core/v5/common/serial"
 	"github.com/v2fly/v2ray-core/v5/common/session"
 	"github.com/v2fly/v2ray-core/v5/common/session"
 	"github.com/v2fly/v2ray-core/v5/transport/internet"
 	"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"
 )
 )
 
 
 // Dial dials a new TCP connection to the given destination.
 // Dial dials a new TCP connection to the given destination.
@@ -19,16 +19,16 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
-		tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
-		/*
-			if config.IsExperiment8357() {
-				conn = tls.UClient(conn, tlsConfig)
-			} else {
-				conn = tls.Client(conn, tlsConfig)
-			}
-		*/
-		conn = tls.Client(conn, tlsConfig)
+	securityEngine, err := security.CreateSecurityEngineFromSettings(ctx, streamSettings)
+	if err != nil {
+		return nil, newError("unable to create security engine").Base(err)
+	}
+
+	if securityEngine != nil {
+		conn, err = securityEngine.Client(conn)
+		if err != nil {
+			return nil, newError("unable to create security protocol client from security engine").Base(err)
+		}
 	}
 	}
 
 
 	tcpSettings := streamSettings.ProtocolSettings.(*Config)
 	tcpSettings := streamSettings.ProtocolSettings.(*Config)

+ 30 - 0
transport/internet/tls/engine.go

@@ -0,0 +1,30 @@
+package tls
+
+import (
+	"github.com/v2fly/v2ray-core/v5/common/net"
+	"github.com/v2fly/v2ray-core/v5/transport/internet/security"
+)
+
+type Engine struct {
+	config *Config
+}
+
+func (e *Engine) Client(conn net.Conn, opts ...security.Option) (security.Conn, error) {
+	var options []Option
+	for _, v := range opts {
+		switch s := v.(type) {
+		case security.OptionWithALPN:
+			options = append(options, WithNextProto(s.ALPNs...))
+		case security.OptionWithDestination:
+			options = append(options, WithDestination(s.Dest))
+		default:
+			return nil, newError("unknown option")
+		}
+	}
+	tlsConn := Client(conn, e.config.GetTLSConfig(options...))
+	return tlsConn, nil
+}
+
+func NewTLSSecurityEngineFromConfig(config *Config) (security.Engine, error) {
+	return &Engine{config: config}, nil
+}

+ 1 - 1
transport/internet/tls/tls.go

@@ -66,6 +66,6 @@ func Server(c net.Conn, config *tls.Config) net.Conn {
 
 
 func init() {
 func init() {
 	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
 	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
-		return nil, newError("tls should be used with v2tls")
+		return NewTLSSecurityEngineFromConfig(config.(*Config))
 	}))
 	}))
 }
 }