Skip to content

Commit 45aaf35

Browse files
committed
Improve QUIC and network sniffing with more robust error handling
* 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)
1 parent 5fb06bf commit 45aaf35

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

app/dispatcher/default.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package dispatcher
44

55
import (
66
"context"
7+
"io"
78
"strings"
89
"sync"
910
"time"
@@ -256,6 +257,16 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
256257
return metaresult, metadataErr
257258
}
258259

260+
var maxAttempt int
261+
switch network {
262+
case net.Network_TCP:
263+
maxAttempt = 2
264+
case net.Network_UDP:
265+
maxAttempt = 5
266+
default:
267+
maxAttempt = 2
268+
}
269+
259270
contentResult, contentErr := func() (SniffResult, error) {
260271
totalAttempt := 0
261272
for {
@@ -264,14 +275,14 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
264275
return nil, ctx.Err()
265276
default:
266277
totalAttempt++
267-
if totalAttempt > 2 {
278+
if totalAttempt > maxAttempt {
268279
return nil, errSniffingTimeout
269280
}
270281

271282
cReader.Cache(payload)
272283
if !payload.IsEmpty() {
273284
result, err := sniffer.Sniff(ctx, payload.Bytes(), network)
274-
if err != common.ErrNoClue {
285+
if err != common.ErrNoClue && err != io.EOF {
275286
return result, err
276287
}
277288
}

common/protocol/quic/sniff.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,15 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
9494
return nil, errNotQuic
9595
}
9696

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

102-
if _, err = buffer.ReadBytes(int32(tokenLen)); err != nil {
103-
return nil, errNotQuic
103+
if _, err = buffer.ReadBytes(int32(tokenLen)); err != nil {
104+
return nil, errNotQuic
105+
}
104106
}
105107

106108
packetLen, err := quicvarint.Read(buffer)

0 commit comments

Comments
 (0)