@@ -2,17 +2,14 @@ package sniffer
22
33import (
44 "crypto"
5- "crypto/aes"
6- "crypto/cipher"
75 "encoding/binary"
86 "errors"
9- "io "
7+ "time "
108
11- "github.com/metacubex/mihomo/common/buf"
129 "github.com/metacubex/mihomo/common/utils"
10+ "github.com/metacubex/mihomo/constant"
1311 C "github.com/metacubex/mihomo/constant"
14-
15- "github.com/metacubex/quic-go/quicvarint"
12+ "github.com/metacubex/mihomo/constant/sniffer"
1613 "golang.org/x/crypto/hkdf"
1714)
1815
@@ -21,6 +18,10 @@ import (
2118const (
2219 versionDraft29 uint32 = 0xff00001d
2320 version1 uint32 = 0x1
21+ // Timeout before quic sniffer all packets
22+ quicWaitConn = time .Second * 3
23+ quicPacketTypeInitial = 0x00
24+ quicPacketType0RTT = 0x01
2425)
2526
2627var (
3031 errNotQuicInitial = errors .New ("not QUIC initial packet" )
3132)
3233
34+ var _ sniffer.Sniffer = (* QuicSniffer )(nil )
35+ var _ sniffer.MultiPacketSniffer = (* QuicSniffer )(nil )
36+
3337type QuicSniffer struct {
3438 * BaseSniffer
3539}
@@ -44,228 +48,25 @@ func NewQuicSniffer(snifferConfig SnifferConfig) (*QuicSniffer, error) {
4448 }, nil
4549}
4650
47- func (quic QuicSniffer ) Protocol () string {
51+ func (sniffer * QuicSniffer ) Protocol () string {
4852 return "quic"
4953}
5054
51- func (quic QuicSniffer ) SupportNetwork () C.NetWork {
55+ func (sniffer * QuicSniffer ) SupportNetwork () C.NetWork {
5256 return C .UDP
5357}
5458
55- func (quic QuicSniffer ) SniffData (b []byte ) (string , error ) {
56- buffer := buf .As (b )
57- typeByte , err := buffer .ReadByte ()
58- if err != nil {
59- return "" , errNotQuic
60- }
61- isLongHeader := typeByte & 0x80 > 0
62- if ! isLongHeader || typeByte & 0x40 == 0 {
63- return "" , errNotQuicInitial
64- }
65-
66- vb , err := buffer .ReadBytes (4 )
67- if err != nil {
68- return "" , errNotQuic
69- }
70-
71- versionNumber := binary .BigEndian .Uint32 (vb )
72-
73- if versionNumber != 0 && typeByte & 0x40 == 0 {
74- return "" , errNotQuic
75- } else if versionNumber != versionDraft29 && versionNumber != version1 {
76- return "" , errNotQuic
77- }
78-
79- if (typeByte & 0x30 )>> 4 != 0x0 {
80- return "" , errNotQuicInitial
81- }
82-
83- var destConnID []byte
84- if l , err := buffer .ReadByte (); err != nil {
85- return "" , errNotQuic
86- } else if destConnID , err = buffer .ReadBytes (int (l )); err != nil {
87- return "" , errNotQuic
88- }
89-
90- if l , err := buffer .ReadByte (); err != nil {
91- return "" , errNotQuic
92- } else if _ , err := buffer .ReadBytes (int (l )); err != nil {
93- return "" , errNotQuic
94- }
95-
96- tokenLen , err := quicvarint .Read (buffer )
97- if err != nil || tokenLen > uint64 (len (b )) {
98- return "" , errNotQuic
99- }
100-
101- if _ , err = buffer .ReadBytes (int (tokenLen )); err != nil {
102- return "" , errNotQuic
103- }
104-
105- packetLen , err := quicvarint .Read (buffer )
106- if err != nil {
107- return "" , errNotQuic
108- }
109-
110- hdrLen := len (b ) - buffer .Len ()
111-
112- var salt []byte
113- if versionNumber == version1 {
114- salt = quicSalt
115- } else {
116- salt = quicSaltOld
117- }
118- initialSecret := hkdf .Extract (crypto .SHA256 .New , destConnID , salt )
119- secret := hkdfExpandLabel (crypto .SHA256 , initialSecret , []byte {}, "client in" , crypto .SHA256 .Size ())
120- hpKey := hkdfExpandLabel (crypto .SHA256 , secret , []byte {}, "quic hp" , 16 )
121- block , err := aes .NewCipher (hpKey )
122- if err != nil {
123- return "" , err
124- }
125-
126- cache := buf .NewPacket ()
127- defer cache .Release ()
128-
129- mask := cache .Extend (block .BlockSize ())
130- block .Encrypt (mask , b [hdrLen + 4 :hdrLen + 4 + 16 ])
131- firstByte := b [0 ]
132- // Encrypt/decrypt first byte.
133- if isLongHeader {
134- // Long header: 4 bits masked
135- // High 4 bits are not protected.
136- firstByte ^= mask [0 ] & 0x0f
137- } else {
138- // Short header: 5 bits masked
139- // High 3 bits are not protected.
140- firstByte ^= mask [0 ] & 0x1f
141- }
142- packetNumberLength := int (firstByte & 0x3 + 1 ) // max = 4 (64-bit sequence number)
143- extHdrLen := hdrLen + packetNumberLength
144-
145- // copy to avoid modify origin data
146- extHdr := cache .Extend (extHdrLen )
147- copy (extHdr , b )
148- extHdr [0 ] = firstByte
149-
150- packetNumber := extHdr [hdrLen :extHdrLen ]
151- // Encrypt/decrypt packet number.
152- for i := range packetNumber {
153- packetNumber [i ] ^= mask [1 + i ]
154- }
155-
156- if packetNumber [0 ] != 0 && packetNumber [0 ] != 1 {
157- return "" , errNotQuicInitial
158- }
159-
160- data := b [extHdrLen : int (packetLen )+ hdrLen ]
161-
162- key := hkdfExpandLabel (crypto .SHA256 , secret , []byte {}, "quic key" , 16 )
163- iv := hkdfExpandLabel (crypto .SHA256 , secret , []byte {}, "quic iv" , 12 )
164- aesCipher , err := aes .NewCipher (key )
165- if err != nil {
166- return "" , err
167- }
168- aead , err := cipher .NewGCM (aesCipher )
169- if err != nil {
170- return "" , err
171- }
172- // We only decrypt once, so we do not need to XOR it back.
173- // https://github.com/quic-go/qtls-go1-20/blob/e132a0e6cb45e20ac0b705454849a11d09ba5a54/cipher_suites.go#L496
174- for i , b := range packetNumber {
175- iv [len (iv )- len (packetNumber )+ i ] ^= b
176- }
177- dst := cache .Extend (len (data ))
178- decrypted , err := aead .Open (dst [:0 ], iv , data , extHdr )
179- if err != nil {
180- return "" , err
181- }
182- buffer = buf .As (decrypted )
183-
184- cryptoLen := uint (0 )
185- cryptoData := cache .Extend (buffer .Len ())
186- for i := 0 ; ! buffer .IsEmpty (); i ++ {
187- frameType := byte (0x0 ) // Default to PADDING frame
188- for frameType == 0x0 && ! buffer .IsEmpty () {
189- frameType , _ = buffer .ReadByte ()
190- }
191- switch frameType {
192- case 0x00 : // PADDING frame
193- case 0x01 : // PING frame
194- case 0x02 , 0x03 : // ACK frame
195- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: Largest Acknowledged
196- return "" , io .ErrUnexpectedEOF
197- }
198- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ACK Delay
199- return "" , io .ErrUnexpectedEOF
200- }
201- ackRangeCount , err := quicvarint .Read (buffer ) // Field: ACK Range Count
202- if err != nil {
203- return "" , io .ErrUnexpectedEOF
204- }
205- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: First ACK Range
206- return "" , io .ErrUnexpectedEOF
207- }
208- for i := 0 ; i < int (ackRangeCount ); i ++ { // Field: ACK Range
209- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ACK Range -> Gap
210- return "" , io .ErrUnexpectedEOF
211- }
212- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ACK Range -> ACK Range Length
213- return "" , io .ErrUnexpectedEOF
214- }
215- }
216- if frameType == 0x03 {
217- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ECN Counts -> ECT0 Count
218- return "" , io .ErrUnexpectedEOF
219- }
220- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ECN Counts -> ECT1 Count
221- return "" , io .ErrUnexpectedEOF
222- }
223- if _ , err = quicvarint .Read (buffer ); err != nil { //nolint:misspell // Field: ECN Counts -> ECT-CE Count
224- return "" , io .ErrUnexpectedEOF
225- }
226- }
227- case 0x06 : // CRYPTO frame, we will use this frame
228- offset , err := quicvarint .Read (buffer ) // Field: Offset
229- if err != nil {
230- return "" , io .ErrUnexpectedEOF
231- }
232- length , err := quicvarint .Read (buffer ) // Field: Length
233- if err != nil || length > uint64 (buffer .Len ()) {
234- return "" , io .ErrUnexpectedEOF
235- }
236- if cryptoLen < uint (offset + length ) {
237- cryptoLen = uint (offset + length )
238- }
239- if _ , err := buffer .Read (cryptoData [offset : offset + length ]); err != nil { // Field: Crypto Data
240- return "" , io .ErrUnexpectedEOF
241- }
242- case 0x1c : // CONNECTION_CLOSE frame, only 0x1c is permitted in initial packet
243- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: Error Code
244- return "" , io .ErrUnexpectedEOF
245- }
246- if _ , err = quicvarint .Read (buffer ); err != nil { // Field: Frame Type
247- return "" , io .ErrUnexpectedEOF
248- }
249- length , err := quicvarint .Read (buffer ) // Field: Reason Phrase Length
250- if err != nil {
251- return "" , io .ErrUnexpectedEOF
252- }
253- if _ , err := buffer .ReadBytes (int (length )); err != nil { // Field: Reason Phrase
254- return "" , io .ErrUnexpectedEOF
255- }
256- default :
257- // Only above frame types are permitted in initial packet.
258- // See https://www.rfc-editor.org/rfc/rfc9000.html#section-17.2.2-8
259- return "" , errNotQuicInitial
260- }
261- }
262-
263- domain , err := ReadClientHello (cryptoData [:cryptoLen ])
264- if err != nil {
265- return "" , err
59+ func (sniffer * QuicSniffer ) WrapperSender (packetSender constant.PacketSender , override bool ) constant.PacketSender {
60+ return & quicConnection {
61+ sender : packetSender ,
62+ buffer : make ([]quicDataBlock , 0 ),
63+ chClose : make (chan struct {}),
64+ override : override ,
26665 }
66+ }
26767
268- return * domain , nil
68+ func (sniffer * QuicSniffer ) SniffData (b []byte ) (string , error ) {
69+ return "" , ErrorUnsupportedSniffer
26970}
27071
27172func hkdfExpandLabel (hash crypto.Hash , secret , context []byte , label string , length int ) []byte {
0 commit comments