starnet/tlsstats.go
starainrt 9ac9b65bc5
fix(starnet): 收紧 TLS ClientHello 嗅探并补齐边界测试
- 用轻量 ClientHello 解析替代假握手式 TLS 嗅探
  - 保留截断和 max-bytes 场景下的 TLS 分类与缓冲回放能力
  - 拒绝首个 record 完整但并非 ClientHello 的伪 TLS 流量
  - 为动态 TLS 配置选择透出更完整的 ClientHello 元数据
  - 拆分 TLS 初始化失败统计为 sniff/config/plain rejected
  - 补充正常、分片、截断、限长、伪 TLS 等回归测试
2026-03-27 12:05:23 +08:00

56 lines
1.9 KiB
Go

package starnet
import "sync/atomic"
// StatsSnapshot is a read-only copy of runtime counters.
type StatsSnapshot struct {
Accepted uint64
TLSDetected uint64
PlainDetected uint64
InitFailures uint64
SniffFailures uint64
TLSConfigFailures uint64
PlainRejected uint64
Closed uint64
}
// Stats provides lock-free counters.
type Stats struct {
accepted uint64
tlsDetected uint64
plainDetected uint64
initFailures uint64
sniffFailures uint64
tlsConfigFailures uint64
plainRejected uint64
closed uint64
}
func (s *Stats) incAccepted() { atomic.AddUint64(&s.accepted, 1) }
func (s *Stats) incTLSDetected() { atomic.AddUint64(&s.tlsDetected, 1) }
func (s *Stats) incPlainDetected() { atomic.AddUint64(&s.plainDetected, 1) }
func (s *Stats) incInitFailures() { atomic.AddUint64(&s.initFailures, 1) }
func (s *Stats) incClosed() { atomic.AddUint64(&s.closed, 1) }
func (s *Stats) incSniffFailures() { atomic.AddUint64(&s.sniffFailures, 1); s.incInitFailures() }
func (s *Stats) incTLSConfigFailures() { atomic.AddUint64(&s.tlsConfigFailures, 1); s.incInitFailures() }
func (s *Stats) incPlainRejected() { atomic.AddUint64(&s.plainRejected, 1); s.incInitFailures() }
// Snapshot returns a stable view of counters.
func (s *Stats) Snapshot() StatsSnapshot {
return StatsSnapshot{
Accepted: atomic.LoadUint64(&s.accepted),
TLSDetected: atomic.LoadUint64(&s.tlsDetected),
PlainDetected: atomic.LoadUint64(&s.plainDetected),
InitFailures: atomic.LoadUint64(&s.initFailures),
SniffFailures: atomic.LoadUint64(&s.sniffFailures),
TLSConfigFailures: atomic.LoadUint64(&s.tlsConfigFailures),
PlainRejected: atomic.LoadUint64(&s.plainRejected),
Closed: atomic.LoadUint64(&s.closed),
}
}
// Logger is a minimal logging abstraction.
type Logger interface {
Printf(format string, v ...interface{})
}