From 6a2bfd26d0826a5a1dbfb4a1f0e5f39cff36547a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= <i@sekai.icu>
Date: Thu, 16 Nov 2023 22:47:20 +0800
Subject: [PATCH] Fix QUIC sniffer

---
 common/sniff/quic.go | 67 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/common/sniff/quic.go b/common/sniff/quic.go
index c18e09a0e1..55dc1c0023 100644
--- a/common/sniff/quic.go
+++ b/common/sniff/quic.go
@@ -182,11 +182,52 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
 			break
 		}
 		switch frameType {
-		case 0x0:
+		case 0x00: // PADDING
 			continue
-		case 0x1:
+		case 0x01: // PING
 			continue
-		case 0x6:
+		case 0x02, 0x03: // ACK
+			_, err = qtls.ReadUvarint(decryptedReader) // Largest Acknowledged
+			if err != nil {
+				return nil, err
+			}
+			_, err = qtls.ReadUvarint(decryptedReader) // ACK Delay
+			if err != nil {
+				return nil, err
+			}
+			ackRangeCount, err := qtls.ReadUvarint(decryptedReader) // ACK Range Count
+			if err != nil {
+				return nil, err
+			}
+			_, err = qtls.ReadUvarint(decryptedReader) // First ACK Range
+			if err != nil {
+				return nil, err
+			}
+			for i := 0; i < int(ackRangeCount); i++ {
+				_, err = qtls.ReadUvarint(decryptedReader) // Gap
+				if err != nil {
+					return nil, err
+				}
+				_, err = qtls.ReadUvarint(decryptedReader) // ACK Range Length
+				if err != nil {
+					return nil, err
+				}
+			}
+			if frameType == 0x03 {
+				_, err = qtls.ReadUvarint(decryptedReader) // ECT0 Count
+				if err != nil {
+					return nil, err
+				}
+				_, err = qtls.ReadUvarint(decryptedReader) // ECT1 Count
+				if err != nil {
+					return nil, err
+				}
+				_, err = qtls.ReadUvarint(decryptedReader) // ECN-CE Count
+				if err != nil {
+					return nil, err
+				}
+			}
+		case 0x06: // CRYPTO
 			var offset uint64
 			offset, err = qtls.ReadUvarint(decryptedReader)
 			if err != nil {
@@ -208,8 +249,26 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
 			if err != nil {
 				return nil, err
 			}
+		case 0x1c: // CONNECTION_CLOSE
+			_, err = qtls.ReadUvarint(decryptedReader) // Error Code
+			if err != nil {
+				return nil, err
+			}
+			_, err = qtls.ReadUvarint(decryptedReader) // Frame Type
+			if err != nil {
+				return nil, err
+			}
+			var length uint64
+			length, err = qtls.ReadUvarint(decryptedReader) // Reason Phrase Length
+			if err != nil {
+				return nil, err
+			}
+			_, err = decryptedReader.Seek(int64(length), io.SeekCurrent) // Reason Phrase
+			if err != nil {
+				return nil, err
+			}
 		default:
-			// ignore unknown frame type
+			return nil, os.ErrInvalid
 		}
 	}
 	tlsHdr := make([]byte, 5)