From 34892f4c7e85c1ce7ceeddf09682ba9cf39fedae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 8 Sep 2025 19:35:17 +0800 Subject: [PATCH] ktls: Add warning for inappropriate scenarios --- common/tls/client.go | 44 +++++++++++++++++++++++++++++++------ common/tls/server.go | 31 ++++++++++++++++++++++---- common/tls/std_server.go | 4 ++++ protocol/http/inbound.go | 7 +++++- protocol/mixed/inbound.go | 7 +++++- protocol/trojan/inbound.go | 8 ++++++- protocol/trojan/outbound.go | 9 +++++++- protocol/vless/inbound.go | 11 +++++++++- protocol/vless/outbound.go | 10 ++++++++- 9 files changed, 114 insertions(+), 17 deletions(-) diff --git a/common/tls/client.go b/common/tls/client.go index 19ba09b4..a84ce0f5 100644 --- a/common/tls/client.go +++ b/common/tls/client.go @@ -20,7 +20,12 @@ func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogger, dial if !options.Enabled { return dialer, nil } - config, err := NewClient(ctx, logger, serverAddress, options) + config, err := NewClientWithOptions(ClientOptions{ + Context: ctx, + Logger: logger, + ServerAddress: serverAddress, + Options: options, + }) if err != nil { return nil, err } @@ -28,15 +33,40 @@ func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogger, dial } func NewClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) { - if !options.Enabled { + return NewClientWithOptions(ClientOptions{ + Context: ctx, + Logger: logger, + ServerAddress: serverAddress, + Options: options, + }) +} + +type ClientOptions struct { + Context context.Context + Logger logger.ContextLogger + ServerAddress string + Options option.OutboundTLSOptions + KTLSCompatible bool +} + +func NewClientWithOptions(options ClientOptions) (Config, error) { + if !options.Options.Enabled { return nil, nil } - if options.Reality != nil && options.Reality.Enabled { - return NewRealityClient(ctx, logger, serverAddress, options) - } else if options.UTLS != nil && options.UTLS.Enabled { - return NewUTLSClient(ctx, logger, serverAddress, options) + if !options.KTLSCompatible { + if options.Options.KernelTx { + options.Logger.Warn("enabling kTLS TX in current scenarios will definitely reduce performance, please checkout https://sing-box.sagernet.org/configuration/shared/tls/#kernel_tx") + } } - return NewSTDClient(ctx, logger, serverAddress, options) + if options.Options.KernelRx { + options.Logger.Warn("enabling kTLS RX will definitely reduce performance, please checkout https://sing-box.sagernet.org/configuration/shared/tls/#kernel_rx") + } + if options.Options.Reality != nil && options.Options.Reality.Enabled { + return NewRealityClient(options.Context, options.Logger, options.ServerAddress, options.Options) + } else if options.Options.UTLS != nil && options.Options.UTLS.Enabled { + return NewUTLSClient(options.Context, options.Logger, options.ServerAddress, options.Options) + } + return NewSTDClient(options.Context, options.Logger, options.ServerAddress, options.Options) } func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (Conn, error) { diff --git a/common/tls/server.go b/common/tls/server.go index aec92bcd..74b240fc 100644 --- a/common/tls/server.go +++ b/common/tls/server.go @@ -12,14 +12,37 @@ import ( aTLS "github.com/sagernet/sing/common/tls" ) +type ServerOptions struct { + Context context.Context + Logger log.ContextLogger + Options option.InboundTLSOptions + KTLSCompatible bool +} + func NewServer(ctx context.Context, logger log.ContextLogger, options option.InboundTLSOptions) (ServerConfig, error) { - if !options.Enabled { + return NewServerWithOptions(ServerOptions{ + Context: ctx, + Logger: logger, + Options: options, + }) +} + +func NewServerWithOptions(options ServerOptions) (ServerConfig, error) { + if !options.Options.Enabled { return nil, nil } - if options.Reality != nil && options.Reality.Enabled { - return NewRealityServer(ctx, logger, options) + if !options.KTLSCompatible { + if options.Options.KernelTx { + options.Logger.Warn("enabling kTLS TX in current scenarios will definitely reduce performance, please checkout https://sing-box.sagernet.org/configuration/shared/tls/#kernel_tx") + } } - return NewSTDServer(ctx, logger, options) + if options.Options.KernelRx { + options.Logger.Warn("enabling kTLS RX will definitely reduce performance, please checkout https://sing-box.sagernet.org/configuration/shared/tls/#kernel_rx") + } + if options.Options.Reality != nil && options.Options.Reality.Enabled { + return NewRealityServer(options.Context, options.Logger, options.Options) + } + return NewSTDServer(options.Context, options.Logger, options.Options) } func ServerHandshake(ctx context.Context, conn net.Conn, config ServerConfig) (Conn, error) { diff --git a/common/tls/std_server.go b/common/tls/std_server.go index e735da1e..5ce12da6 100644 --- a/common/tls/std_server.go +++ b/common/tls/std_server.go @@ -10,6 +10,7 @@ import ( "github.com/sagernet/fswatch" "github.com/sagernet/sing-box/adapter" + C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing/common" @@ -273,6 +274,9 @@ func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option. echKeyPath: echKeyPath, } if options.KernelTx || options.KernelRx { + if !C.IsLinux { + return nil, E.New("kTLS is only supported on Linux") + } config = &KTlSServerConfig{ ServerConfig: config, logger: logger, diff --git a/protocol/http/inbound.go b/protocol/http/inbound.go index 68150fa7..e8a9a3da 100644 --- a/protocol/http/inbound.go +++ b/protocol/http/inbound.go @@ -43,7 +43,12 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo authenticator: auth.NewAuthenticator(options.Users), } if options.TLS != nil { - tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) + tlsConfig, err := tls.NewServerWithOptions(tls.ServerOptions{ + Context: ctx, + Logger: logger, + Options: common.PtrValueOrDefault(options.TLS), + KTLSCompatible: true, + }) if err != nil { return nil, err } diff --git a/protocol/mixed/inbound.go b/protocol/mixed/inbound.go index 5b531480..5591c315 100644 --- a/protocol/mixed/inbound.go +++ b/protocol/mixed/inbound.go @@ -46,7 +46,12 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo authenticator: auth.NewAuthenticator(options.Users), } if options.TLS != nil { - tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) + tlsConfig, err := tls.NewServerWithOptions(tls.ServerOptions{ + Context: ctx, + Logger: logger, + Options: common.PtrValueOrDefault(options.TLS), + KTLSCompatible: true, + }) if err != nil { return nil, err } diff --git a/protocol/trojan/inbound.go b/protocol/trojan/inbound.go index ec95a81e..24e8a023 100644 --- a/protocol/trojan/inbound.go +++ b/protocol/trojan/inbound.go @@ -50,7 +50,13 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo users: options.Users, } if options.TLS != nil { - tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) + tlsConfig, err := tls.NewServerWithOptions(tls.ServerOptions{ + Context: ctx, + Logger: logger, + Options: common.PtrValueOrDefault(options.TLS), + KTLSCompatible: common.PtrValueOrDefault(options.Transport).Type == "" && + !common.PtrValueOrDefault(options.Multiplex).Enabled, + }) if err != nil { return nil, err } diff --git a/protocol/trojan/outbound.go b/protocol/trojan/outbound.go index 779d437c..26c7c81f 100644 --- a/protocol/trojan/outbound.go +++ b/protocol/trojan/outbound.go @@ -51,7 +51,14 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL key: trojan.Key(options.Password), } if options.TLS != nil { - outbound.tlsConfig, err = tls.NewClient(ctx, logger, options.Server, common.PtrValueOrDefault(options.TLS)) + outbound.tlsConfig, err = tls.NewClientWithOptions(tls.ClientOptions{ + Context: ctx, + Logger: logger, + ServerAddress: options.Server, + Options: common.PtrValueOrDefault(options.TLS), + KTLSCompatible: common.PtrValueOrDefault(options.Transport).Type == "" && + !common.PtrValueOrDefault(options.Multiplex).Enabled, + }) if err != nil { return nil, err } diff --git a/protocol/vless/inbound.go b/protocol/vless/inbound.go index 3cc53db4..1df7cb01 100644 --- a/protocol/vless/inbound.go +++ b/protocol/vless/inbound.go @@ -68,7 +68,16 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo })) inbound.service = service if options.TLS != nil { - inbound.tlsConfig, err = tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) + inbound.tlsConfig, err = tls.NewServerWithOptions(tls.ServerOptions{ + Context: ctx, + Logger: logger, + Options: common.PtrValueOrDefault(options.TLS), + KTLSCompatible: common.PtrValueOrDefault(options.Transport).Type == "" && + !common.PtrValueOrDefault(options.Multiplex).Enabled && + common.All(options.Users, func(it option.VLESSUser) bool { + return it.Flow == "" + }), + }) if err != nil { return nil, err } diff --git a/protocol/vless/outbound.go b/protocol/vless/outbound.go index e746c5fe..ab774760 100644 --- a/protocol/vless/outbound.go +++ b/protocol/vless/outbound.go @@ -53,7 +53,15 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL serverAddr: options.ServerOptions.Build(), } if options.TLS != nil { - outbound.tlsConfig, err = tls.NewClient(ctx, logger, options.Server, common.PtrValueOrDefault(options.TLS)) + outbound.tlsConfig, err = tls.NewClientWithOptions(tls.ClientOptions{ + Context: ctx, + Logger: logger, + ServerAddress: options.Server, + Options: common.PtrValueOrDefault(options.TLS), + KTLSCompatible: common.PtrValueOrDefault(options.Transport).Type == "" && + !common.PtrValueOrDefault(options.Multiplex).Enabled && + options.Flow == "", + }) if err != nil { return nil, err }