starnet/tlsconfig.go

91 lines
2.4 KiB
Go
Raw Normal View History

2026-03-08 20:19:40 +08:00
package starnet
import (
"crypto/tls"
"net"
"time"
)
// GetConfigForClientFunc selects TLS config by hostname/SNI.
type GetConfigForClientFunc func(hostname string) (*tls.Config, error)
// ClientHelloMeta carries sniffed TLS metadata and connection context.
type ClientHelloMeta struct {
ServerName string
LocalAddr net.Addr
RemoteAddr net.Addr
SupportedProtos []string
SupportedVersions []uint16
CipherSuites []uint16
}
// Clone returns a detached copy safe for callers to mutate.
func (m *ClientHelloMeta) Clone() *ClientHelloMeta {
if m == nil {
return nil
}
out := *m
if m.SupportedProtos != nil {
out.SupportedProtos = append([]string(nil), m.SupportedProtos...)
}
if m.SupportedVersions != nil {
out.SupportedVersions = append([]uint16(nil), m.SupportedVersions...)
}
if m.CipherSuites != nil {
out.CipherSuites = append([]uint16(nil), m.CipherSuites...)
}
return &out
}
// GetConfigForClientHelloFunc selects TLS config by sniffed TLS metadata.
type GetConfigForClientHelloFunc func(hello *ClientHelloMeta) (*tls.Config, error)
2026-03-08 20:19:40 +08:00
// ListenerConfig controls listener behavior.
type ListenerConfig struct {
// BaseTLSConfig is used for TLS when dynamic selection returns nil.
BaseTLSConfig *tls.Config
// GetConfigForClient selects TLS config for a hostname/SNI.
// Deprecated: prefer GetConfigForClientHello for richer context.
2026-03-08 20:19:40 +08:00
GetConfigForClient GetConfigForClientFunc
// GetConfigForClientHello selects TLS config for sniffed TLS metadata.
GetConfigForClientHello GetConfigForClientHelloFunc
2026-03-08 20:19:40 +08:00
// AllowNonTLS allows plain TCP fallback.
AllowNonTLS bool
// SniffTimeout bounds protocol sniffing time. 0 means no timeout.
SniffTimeout time.Duration
// MaxClientHelloBytes limits buffered sniff data.
// If <= 0, default 64KiB.
MaxClientHelloBytes int
// Logger is optional.
Logger Logger
}
// DefaultListenerConfig returns a conservative default config.
func DefaultListenerConfig() ListenerConfig {
return ListenerConfig{
AllowNonTLS: false,
SniffTimeout: 5 * time.Second,
MaxClientHelloBytes: 64 * 1024,
}
}
// TLSDefaults returns a TLS config baseline.
// Caller should set Certificates / GetCertificate as needed.
func TLSDefaults() *tls.Config {
return &tls.Config{
MinVersion: tls.VersionTLS12,
}
}
// DialConfig controls dialing behavior.
type DialConfig struct {
Timeout time.Duration
LocalAddr net.Addr
}