analyzer: make http3/quic handling more reliable

This commit is contained in:
2026-02-11 16:11:12 +05:30
parent fc38d0fa9d
commit 5fda34a476
2 changed files with 114 additions and 22 deletions

View File

@@ -1,6 +1,7 @@
package udp
import (
"bytes"
"errors"
"sort"
@@ -43,6 +44,7 @@ type quicStream struct {
debugCount int
frames map[int64][]byte
maxEnd int64
connIDs [][]byte
}
func (s *quicStream) Feed(rev bool, data []byte) (u *analyzer.PropUpdate, done bool) {
@@ -51,13 +53,34 @@ func (s *quicStream) Feed(rev bool, data []byte) (u *analyzer.PropUpdate, done b
// + compression methods (2 bytes) + no extensions
const minDataSize = 41
frs, err := quic.ReadCryptoFrames(data)
var parsedHdr *quic.Header
if hdr, _, err := quic.ParseInitialHeader(data); err == nil {
parsedHdr = hdr
s.rememberConnID(hdr.DestConnectionID)
s.rememberConnID(hdr.SrcConnectionID)
}
frs, err := quic.ReadCryptoFramesWithOptions(data, &quic.ReadCryptoFramesOptions{
AdditionalConnectionIDs: s.connIDs,
TryServerSecret: true,
})
if err != nil {
if errors.Is(err, quic.ErrNotInitialPacket) {
return nil, false
}
if s.debugCount < 4 {
s.logger.Debugf("failed to read QUIC CRYPTO frames: %v", err)
if parsedHdr != nil {
s.logger.Debugf(
"failed to read QUIC CRYPTO frames: version=%x dcid_len=%d scid_len=%d token_len=%d conn_id_hints=%d err=%v",
parsedHdr.Version,
len(parsedHdr.DestConnectionID),
len(parsedHdr.SrcConnectionID),
len(parsedHdr.Token),
len(s.connIDs),
err,
)
} else {
s.logger.Debugf("failed to read QUIC CRYPTO frames: %v", err)
}
s.debugCount++
}
s.invalidCount++
@@ -164,3 +187,19 @@ func (s *quicStream) contiguousPayloadFromZero() []byte {
}
return out
}
func (s *quicStream) rememberConnID(cid []byte) {
if len(cid) == 0 {
return
}
for _, existing := range s.connIDs {
if bytes.Equal(existing, cid) {
return
}
}
// Keep this bounded; QUIC CID rotations are small for handshake parsing.
if len(s.connIDs) >= 8 {
s.connIDs = s.connIDs[1:]
}
s.connIDs = append(s.connIDs, append([]byte(nil), cid...))
}