@@ -10,6 +10,7 @@ import (
10
10
"github.com/quic-go/quic-go/quicvarint"
11
11
"github.com/xtls/xray-core/common"
12
12
"github.com/xtls/xray-core/common/buf"
13
+ "github.com/xtls/xray-core/common/bytespool"
13
14
"github.com/xtls/xray-core/common/errors"
14
15
ptls "github.com/xtls/xray-core/common/protocol/tls"
15
16
"golang.org/x/crypto/hkdf"
@@ -141,7 +142,7 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
141
142
packetNumber = uint32 (n )
142
143
}
143
144
144
- if packetNumber != 0 {
145
+ if packetNumber != 0 && packetNumber != 1 {
145
146
return nil , errNotQuicInitial
146
147
}
147
148
@@ -159,32 +160,92 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
159
160
return nil , err
160
161
}
161
162
buffer = buf .FromBytes (decrypted )
162
- frameType , err := buffer .ReadByte ()
163
- if err != nil {
164
- return nil , io .ErrUnexpectedEOF
165
- }
166
- if frameType != 0x6 {
167
- // not crypto frame
168
- return & SniffHeader {domain : "" }, nil
169
- }
170
- if common .Error2 (quicvarint .Read (buffer )) != nil {
171
- return nil , io .ErrUnexpectedEOF
172
- }
173
- dataLen , err := quicvarint .Read (buffer )
174
- if err != nil {
175
- return nil , io .ErrUnexpectedEOF
176
- }
177
- if dataLen > uint64 (buffer .Len ()) {
178
- return nil , io .ErrUnexpectedEOF
163
+
164
+ cryptoLen := uint (0 )
165
+ cryptoData := bytespool .Alloc (buffer .Len ())
166
+ defer bytespool .Free (cryptoData )
167
+ for i := 0 ; ! buffer .IsEmpty (); i ++ {
168
+ frameType := byte (0x0 ) // Default to PADDING frame
169
+ for frameType == 0x0 && ! buffer .IsEmpty () {
170
+ frameType , _ = buffer .ReadByte ()
171
+ }
172
+ switch frameType {
173
+ case 0x00 : // PADDING frame
174
+ case 0x01 : // PING frame
175
+ case 0x02 , 0x03 : // ACK frame
176
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: Largest Acknowledged
177
+ return nil , io .ErrUnexpectedEOF
178
+ }
179
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ACK Delay
180
+ return nil , io .ErrUnexpectedEOF
181
+ }
182
+ ackRangeCount , err := quicvarint .Read (buffer ) // Field: ACK Range Count
183
+ if err != nil {
184
+ return nil , io .ErrUnexpectedEOF
185
+ }
186
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: First ACK Range
187
+ return nil , io .ErrUnexpectedEOF
188
+ }
189
+ for i := 0 ; i < int (ackRangeCount ); i ++ { // Field: ACK Range
190
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ACK Range -> Gap
191
+ return nil , io .ErrUnexpectedEOF
192
+ }
193
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ACK Range -> ACK Range Length
194
+ return nil , io .ErrUnexpectedEOF
195
+ }
196
+ }
197
+ if frameType == 0x03 {
198
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ECN Counts -> ECT0 Count
199
+ return nil , io .ErrUnexpectedEOF
200
+ }
201
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: ECN Counts -> ECT1 Count
202
+ return nil , io .ErrUnexpectedEOF
203
+ }
204
+ if _ , err = quicvarint .Read (buffer ); err != nil { //nolint:misspell // Field: ECN Counts -> ECT-CE Count
205
+ return nil , io .ErrUnexpectedEOF
206
+ }
207
+ }
208
+ case 0x06 : // CRYPTO frame, we will use this frame
209
+ offset , err := quicvarint .Read (buffer ) // Field: Offset
210
+ if err != nil {
211
+ return nil , io .ErrUnexpectedEOF
212
+ }
213
+ length , err := quicvarint .Read (buffer ) // Field: Length
214
+ if err != nil || length > uint64 (buffer .Len ()) {
215
+ return nil , io .ErrUnexpectedEOF
216
+ }
217
+ if cryptoLen < uint (offset + length ) {
218
+ cryptoLen = uint (offset + length )
219
+ }
220
+ if _ , err := buffer .Read (cryptoData [offset : offset + length ]); err != nil { // Field: Crypto Data
221
+ return nil , io .ErrUnexpectedEOF
222
+ }
223
+ case 0x1c : // CONNECTION_CLOSE frame, only 0x1c is permitted in initial packet
224
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: Error Code
225
+ return nil , io .ErrUnexpectedEOF
226
+ }
227
+ if _ , err = quicvarint .Read (buffer ); err != nil { // Field: Frame Type
228
+ return nil , io .ErrUnexpectedEOF
229
+ }
230
+ length , err := quicvarint .Read (buffer ) // Field: Reason Phrase Length
231
+ if err != nil {
232
+ return nil , io .ErrUnexpectedEOF
233
+ }
234
+ if _ , err := buffer .ReadBytes (int32 (length )); err != nil { // Field: Reason Phrase
235
+ return nil , io .ErrUnexpectedEOF
236
+ }
237
+ default :
238
+ // Only above frame types are permitted in initial packet.
239
+ // See https://www.rfc-editor.org/rfc/rfc9000.html#section-17.2.2-8
240
+ return nil , errNotQuicInitial
241
+ }
179
242
}
180
- frameData , err := buffer .ReadBytes (int32 (dataLen ))
181
- common .Must (err )
243
+
182
244
tlsHdr := & ptls.SniffHeader {}
183
- err = ptls .ReadClientHello (frameData , tlsHdr )
245
+ err = ptls .ReadClientHello (cryptoData [: cryptoLen ] , tlsHdr )
184
246
if err != nil {
185
247
return nil , err
186
248
}
187
-
188
249
return & SniffHeader {domain : tlsHdr .Domain ()}, nil
189
250
}
190
251
0 commit comments