- 分离 Request 的配置态与执行态,修复二次 Do、raw 模式网络配置失效和 body 来源互斥问题 - 新增 starnet trace 抽象,补齐 DNS/连接/TLS/重试事件,并优化动态 transport 缓存与代理解析路径 - 收紧非法代理为 fail-fast,多目标目标回退仅限幂等请求,修复 Host/TLS/SNI 等语义边界 - 补充防御性拷贝、专项回归测试、本地代理/TLS 用例与 README 行为说明
124 lines
3.3 KiB
Go
124 lines
3.3 KiB
Go
package tlssniffercore
|
|
|
|
import "crypto/tls"
|
|
|
|
func ComposeServerTLSConfig(base, selected *tls.Config) *tls.Config {
|
|
if base == nil {
|
|
return selected
|
|
}
|
|
if selected == nil {
|
|
return base
|
|
}
|
|
|
|
out := base.Clone()
|
|
ApplyServerTLSOverrides(out, selected)
|
|
return out
|
|
}
|
|
|
|
func ApplyServerTLSOverrides(dst, src *tls.Config) {
|
|
if dst == nil || src == nil {
|
|
return
|
|
}
|
|
|
|
if src.Rand != nil {
|
|
dst.Rand = src.Rand
|
|
}
|
|
if src.Time != nil {
|
|
dst.Time = src.Time
|
|
}
|
|
if len(src.Certificates) > 0 {
|
|
dst.Certificates = append([]tls.Certificate(nil), src.Certificates...)
|
|
}
|
|
if len(src.NameToCertificate) > 0 {
|
|
copied := make(map[string]*tls.Certificate, len(src.NameToCertificate))
|
|
for name, cert := range src.NameToCertificate {
|
|
copied[name] = cert
|
|
}
|
|
dst.NameToCertificate = copied
|
|
}
|
|
if src.GetCertificate != nil {
|
|
dst.GetCertificate = src.GetCertificate
|
|
}
|
|
if src.GetClientCertificate != nil {
|
|
dst.GetClientCertificate = src.GetClientCertificate
|
|
}
|
|
if src.GetConfigForClient != nil {
|
|
dst.GetConfigForClient = src.GetConfigForClient
|
|
}
|
|
if src.VerifyPeerCertificate != nil {
|
|
dst.VerifyPeerCertificate = src.VerifyPeerCertificate
|
|
}
|
|
if src.VerifyConnection != nil {
|
|
dst.VerifyConnection = src.VerifyConnection
|
|
}
|
|
if src.RootCAs != nil {
|
|
dst.RootCAs = src.RootCAs
|
|
}
|
|
if len(src.NextProtos) > 0 {
|
|
dst.NextProtos = append([]string(nil), src.NextProtos...)
|
|
}
|
|
if src.ServerName != "" {
|
|
dst.ServerName = src.ServerName
|
|
}
|
|
if src.ClientAuth > dst.ClientAuth {
|
|
dst.ClientAuth = src.ClientAuth
|
|
}
|
|
if src.ClientCAs != nil {
|
|
dst.ClientCAs = src.ClientCAs
|
|
}
|
|
if src.InsecureSkipVerify {
|
|
dst.InsecureSkipVerify = true
|
|
}
|
|
if len(src.CipherSuites) > 0 {
|
|
dst.CipherSuites = append([]uint16(nil), src.CipherSuites...)
|
|
}
|
|
if src.PreferServerCipherSuites {
|
|
dst.PreferServerCipherSuites = true
|
|
}
|
|
if src.SessionTicketsDisabled {
|
|
dst.SessionTicketsDisabled = true
|
|
}
|
|
if src.SessionTicketKey != ([32]byte{}) {
|
|
dst.SessionTicketKey = src.SessionTicketKey
|
|
}
|
|
if src.ClientSessionCache != nil {
|
|
dst.ClientSessionCache = src.ClientSessionCache
|
|
}
|
|
if src.UnwrapSession != nil {
|
|
dst.UnwrapSession = src.UnwrapSession
|
|
}
|
|
if src.WrapSession != nil {
|
|
dst.WrapSession = src.WrapSession
|
|
}
|
|
if src.MinVersion != 0 && (dst.MinVersion == 0 || src.MinVersion > dst.MinVersion) {
|
|
dst.MinVersion = src.MinVersion
|
|
}
|
|
if src.MaxVersion != 0 && (dst.MaxVersion == 0 || src.MaxVersion < dst.MaxVersion) {
|
|
dst.MaxVersion = src.MaxVersion
|
|
}
|
|
if len(src.CurvePreferences) > 0 {
|
|
dst.CurvePreferences = append([]tls.CurveID(nil), src.CurvePreferences...)
|
|
}
|
|
if src.DynamicRecordSizingDisabled {
|
|
dst.DynamicRecordSizingDisabled = true
|
|
}
|
|
if src.Renegotiation != 0 {
|
|
dst.Renegotiation = src.Renegotiation
|
|
}
|
|
if src.KeyLogWriter != nil {
|
|
dst.KeyLogWriter = src.KeyLogWriter
|
|
}
|
|
if len(src.EncryptedClientHelloConfigList) > 0 {
|
|
dst.EncryptedClientHelloConfigList = append([]byte(nil), src.EncryptedClientHelloConfigList...)
|
|
}
|
|
if src.EncryptedClientHelloRejectionVerify != nil {
|
|
dst.EncryptedClientHelloRejectionVerify = src.EncryptedClientHelloRejectionVerify
|
|
}
|
|
if src.GetEncryptedClientHelloKeys != nil {
|
|
dst.GetEncryptedClientHelloKeys = src.GetEncryptedClientHelloKeys
|
|
}
|
|
if len(src.EncryptedClientHelloKeys) > 0 {
|
|
dst.EncryptedClientHelloKeys = append([]tls.EncryptedClientHelloKey(nil), src.EncryptedClientHelloKeys...)
|
|
}
|
|
}
|