Move cert noise calibration into doppelganger scout

Instead of a separate cert_probe.go that duplicates the scout's TLS
connection logic, measure the cert chain size directly from the same
HTTPS connections the scout already makes.

Changes:
- Extend ScoutConnResult with payloadLen field
- Add Write interception to ScoutConn for handshake boundary detection
- Scout.learn() now computes cert size (sum of ApplicationData between
  CCS and first client Write) alongside inter-record durations
- Ganger aggregates cert sizes across raids and exposes NoiseParams()
  via atomic pointer for lock-free reads from proxy goroutines
- Proxy reads NoiseParams from Ganger on each handshake instead of
  probing at startup
- Remove cert_probe.go, disk cache, and related config options
  (noise-cache-path, noise-cache-ttl, noise-probe-count)

Falls back to legacy 2500-4700 range until the first scout raid
completes (typically within 1-2 seconds of startup).
This commit is contained in:
Alexey Dolotov
2026-03-27 16:34:42 +03:00
parent 80213ad35d
commit 9dfd992c1d
12 changed files with 177 additions and 363 deletions
+17 -4
View File
@@ -14,9 +14,10 @@ type ScoutConn struct {
results *ScoutConnCollected
rawBuf *bytes.Buffer
seenCCS bool
}
func (s ScoutConn) Read(p []byte) (int, error) {
func (s *ScoutConn) Read(p []byte) (int, error) {
buf := &bytes.Buffer{}
for {
@@ -31,7 +32,11 @@ func (s ScoutConn) Read(p []byte) (int, error) {
return 0, err
}
s.results.Add(recordType)
if recordType == tls.TypeChangeCipherSpec {
s.seenCCS = true
}
s.results.Add(recordType, int(length))
s.rawBuf.Write([]byte{recordType})
s.rawBuf.Write(tls.TLSVersion[:])
@@ -45,11 +50,19 @@ func (s ScoutConn) Read(p []byte) (int, error) {
}
}
func NewScoutConn(conn essentials.Conn, results *ScoutConnCollected) ScoutConn {
func (s *ScoutConn) Write(p []byte) (int, error) {
if s.seenCCS {
s.results.MarkWrite()
}
return s.Conn.Write(p)
}
func NewScoutConn(conn essentials.Conn, results *ScoutConnCollected) *ScoutConn {
rawBuf := &bytes.Buffer{}
rawBuf.Grow(tls.MaxRecordSize)
return ScoutConn{
return &ScoutConn{
Conn: tls.New(conn, false, false),
results: results,
rawBuf: rawBuf,