Skip to content

Commit

Permalink
Improve QUIC and network sniffing with more robust error handling
Browse files Browse the repository at this point in the history
* Max sniffing attempts based on network type
* Handle additional edge cases in QUIC packet parsing (only initial packets have tokens)
* Prevent premature timeout in network sniffing (io.EOF)
  • Loading branch information
Vigilans committed Feb 12, 2025
1 parent 5fb06bf commit 45aaf35
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
15 changes: 13 additions & 2 deletions app/dispatcher/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package dispatcher

import (
"context"
"io"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -256,6 +257,16 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
return metaresult, metadataErr
}

var maxAttempt int
switch network {
case net.Network_TCP:
maxAttempt = 2
case net.Network_UDP:
maxAttempt = 5
default:
maxAttempt = 2
}

contentResult, contentErr := func() (SniffResult, error) {
totalAttempt := 0
for {
Expand All @@ -264,14 +275,14 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
return nil, ctx.Err()
default:
totalAttempt++
if totalAttempt > 2 {
if totalAttempt > maxAttempt {
return nil, errSniffingTimeout
}

cReader.Cache(payload)
if !payload.IsEmpty() {
result, err := sniffer.Sniff(ctx, payload.Bytes(), network)
if err != common.ErrNoClue {
if err != common.ErrNoClue && err != io.EOF {
return result, err
}
}
Expand Down
14 changes: 8 additions & 6 deletions common/protocol/quic/sniff.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,15 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
return nil, errNotQuic
}

tokenLen, err := quicvarint.Read(buffer)
if err != nil || tokenLen > uint64(len(b)) {
return nil, errNotQuic
}
if isQuicInitial { // Only initial packets have token, see https://datatracker.ietf.org/doc/html/rfc9000#section-17.2.2
tokenLen, err := quicvarint.Read(buffer)
if err != nil || tokenLen > uint64(len(b)) {
return nil, errNotQuic
}

if _, err = buffer.ReadBytes(int32(tokenLen)); err != nil {
return nil, errNotQuic
if _, err = buffer.ReadBytes(int32(tokenLen)); err != nil {
return nil, errNotQuic
}
}

packetLen, err := quicvarint.Read(buffer)
Expand Down

0 comments on commit 45aaf35

Please sign in to comment.