1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-11 10:20:42 +00:00

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

This commit is contained in:
Shelikhoo 2022-12-16 18:48:25 +00:00 committed by Xiaokang Wang (Shelikhoo)
parent f8ac919d66
commit de55f3a675
7 changed files with 118 additions and 16 deletions

View File

@ -17,7 +17,7 @@ import (
"github.com/v2fly/v2ray-core/v5/proxy"
"github.com/v2fly/v2ray-core/v5/transport"
"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"
)
@ -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})
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

View File

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

View File

@ -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() {
}

View File

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

View File

@ -8,7 +8,7 @@ import (
"github.com/v2fly/v2ray-core/v5/common/serial"
"github.com/v2fly/v2ray-core/v5/common/session"
"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.
@ -19,16 +19,16 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
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)

View File

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

View File

@ -66,6 +66,6 @@ func Server(c net.Conn, config *tls.Config) net.Conn {
func init() {
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))
}))
}