mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-06-29 13:22:06 +03:00
Improve TLS fragments
This commit is contained in:
@@ -25,7 +25,7 @@ import (
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
)
|
||||
|
||||
func parseECHClientConfig(ctx context.Context, options option.OutboundTLSOptions, tlsConfig *tls.Config) (Config, error) {
|
||||
func parseECHClientConfig(ctx context.Context, stdConfig *STDClientConfig, options option.OutboundTLSOptions) (Config, error) {
|
||||
var echConfig []byte
|
||||
if len(options.ECH.Config) > 0 {
|
||||
echConfig = []byte(strings.Join(options.ECH.Config, "\n"))
|
||||
@@ -45,11 +45,11 @@ func parseECHClientConfig(ctx context.Context, options option.OutboundTLSOptions
|
||||
if block == nil || block.Type != "ECH CONFIGS" || len(rest) > 0 {
|
||||
return nil, E.New("invalid ECH configs pem")
|
||||
}
|
||||
tlsConfig.EncryptedClientHelloConfigList = block.Bytes
|
||||
return &STDClientConfig{tlsConfig}, nil
|
||||
stdConfig.config.EncryptedClientHelloConfigList = block.Bytes
|
||||
return stdConfig, nil
|
||||
} else {
|
||||
return &STDECHClientConfig{
|
||||
STDClientConfig: STDClientConfig{tlsConfig},
|
||||
STDClientConfig: stdConfig,
|
||||
dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
|
||||
}, nil
|
||||
}
|
||||
@@ -103,7 +103,7 @@ func reloadECHKeys(echKeyPath string, tlsConfig *tls.Config) error {
|
||||
}
|
||||
|
||||
type STDECHClientConfig struct {
|
||||
STDClientConfig
|
||||
*STDClientConfig
|
||||
access sync.Mutex
|
||||
dnsRouter adapter.DNSRouter
|
||||
lastTTL time.Duration
|
||||
@@ -171,7 +171,7 @@ func (s *STDECHClientConfig) fetchAndHandshake(ctx context.Context, conn net.Con
|
||||
}
|
||||
|
||||
func (s *STDECHClientConfig) Clone() Config {
|
||||
return &STDECHClientConfig{STDClientConfig: STDClientConfig{s.config.Clone()}, dnsRouter: s.dnsRouter, lastUpdate: s.lastUpdate}
|
||||
return &STDECHClientConfig{STDClientConfig: s.STDClientConfig.Clone().(*STDClientConfig), dnsRouter: s.dnsRouter, lastUpdate: s.lastUpdate}
|
||||
}
|
||||
|
||||
func UnmarshalECHKeys(raw []byte) ([]tls.EncryptedClientHelloKey, error) {
|
||||
|
||||
@@ -7,15 +7,21 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/tlsfragment"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/ntp"
|
||||
)
|
||||
|
||||
type STDClientConfig struct {
|
||||
config *tls.Config
|
||||
ctx context.Context
|
||||
config *tls.Config
|
||||
fragment bool
|
||||
fragmentFallbackDelay time.Duration
|
||||
recordFragment bool
|
||||
}
|
||||
|
||||
func (s *STDClientConfig) ServerName() string {
|
||||
@@ -39,11 +45,14 @@ func (s *STDClientConfig) Config() (*STDConfig, error) {
|
||||
}
|
||||
|
||||
func (s *STDClientConfig) Client(conn net.Conn) (Conn, error) {
|
||||
if s.recordFragment {
|
||||
conn = tf.NewConn(conn, s.ctx, s.fragment, s.recordFragment, s.fragmentFallbackDelay)
|
||||
}
|
||||
return tls.Client(conn, s.config), nil
|
||||
}
|
||||
|
||||
func (s *STDClientConfig) Clone() Config {
|
||||
return &STDClientConfig{s.config.Clone()}
|
||||
return &STDClientConfig{s.ctx, s.config.Clone(), s.fragment, s.fragmentFallbackDelay, s.recordFragment}
|
||||
}
|
||||
|
||||
func NewSTDClient(ctx context.Context, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
|
||||
@@ -127,8 +136,10 @@ func NewSTDClient(ctx context.Context, serverAddress string, options option.Outb
|
||||
}
|
||||
tlsConfig.RootCAs = certPool
|
||||
}
|
||||
stdConfig := &STDClientConfig{ctx, &tlsConfig, options.Fragment, time.Duration(options.FragmentFallbackDelay), options.RecordFragment}
|
||||
if options.ECH != nil && options.ECH.Enabled {
|
||||
return parseECHClientConfig(ctx, options, &tlsConfig)
|
||||
return parseECHClientConfig(ctx, stdConfig, options)
|
||||
} else {
|
||||
return stdConfig, nil
|
||||
}
|
||||
return &STDClientConfig{&tlsConfig}, nil
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ import (
|
||||
"net/netip"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/tlsfragment"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/ntp"
|
||||
@@ -22,8 +24,12 @@ import (
|
||||
)
|
||||
|
||||
type UTLSClientConfig struct {
|
||||
config *utls.Config
|
||||
id utls.ClientHelloID
|
||||
ctx context.Context
|
||||
config *utls.Config
|
||||
id utls.ClientHelloID
|
||||
fragment bool
|
||||
fragmentFallbackDelay time.Duration
|
||||
recordFragment bool
|
||||
}
|
||||
|
||||
func (e *UTLSClientConfig) ServerName() string {
|
||||
@@ -50,6 +56,9 @@ func (e *UTLSClientConfig) Config() (*STDConfig, error) {
|
||||
}
|
||||
|
||||
func (e *UTLSClientConfig) Client(conn net.Conn) (Conn, error) {
|
||||
if e.recordFragment {
|
||||
conn = tf.NewConn(conn, e.ctx, e.fragment, e.recordFragment, e.fragmentFallbackDelay)
|
||||
}
|
||||
return &utlsALPNWrapper{utlsConnWrapper{utls.UClient(conn, e.config.Clone(), e.id)}, e.config.NextProtos}, nil
|
||||
}
|
||||
|
||||
@@ -59,8 +68,7 @@ func (e *UTLSClientConfig) SetSessionIDGenerator(generator func(clientHello []by
|
||||
|
||||
func (e *UTLSClientConfig) Clone() Config {
|
||||
return &UTLSClientConfig{
|
||||
config: e.config.Clone(),
|
||||
id: e.id,
|
||||
e.ctx, e.config.Clone(), e.id, e.fragment, e.fragmentFallbackDelay, e.recordFragment,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +200,7 @@ func NewUTLSClient(ctx context.Context, serverAddress string, options option.Out
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &UTLSClientConfig{&tlsConfig, id}, nil
|
||||
return &UTLSClientConfig{ctx, &tlsConfig, id, options.Fragment, time.Duration(options.FragmentFallbackDelay), options.RecordFragment}, nil
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user