1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2026-05-10 06:29:08 -04:00

QUIC sniffer restructure (#3360)

This commit is contained in:
Xiaokang Wang (Shelikhoo)
2025-03-23 18:16:29 +00:00
committed by GitHub
parent 77d2d1b172
commit c8c1120747
2 changed files with 26 additions and 28 deletions

View File

@@ -12,7 +12,6 @@ import (
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/common/bytespool"
"github.com/v2fly/v2ray-core/v5/common/errors"
"github.com/v2fly/v2ray-core/v5/common/protocol"
ptls "github.com/v2fly/v2ray-core/v5/common/protocol/tls"
@@ -49,12 +48,14 @@ var (
)
func SniffQUIC(b []byte) (*SniffHeader, error) {
if len(b) == 0 {
return nil, common.ErrNoClue
}
// Crypto data separated across packets
cryptoLen := 0
cryptoData := bytespool.Alloc(int32(len(b)))
defer func() {
bytespool.Free(cryptoData)
}()
cryptoDataBuf := buf.NewWithSize(32767)
defer cryptoDataBuf.Release()
cache := buf.New()
defer cache.Release()
@@ -230,14 +231,14 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
}
if cryptoLen < int(offset+length) {
cryptoLen = int(offset + length)
if len(cryptoData) < cryptoLen {
newCryptoData := bytespool.Alloc(int32(cryptoLen))
copy(newCryptoData, cryptoData)
bytespool.Free(cryptoData)
cryptoData = newCryptoData
if cryptoDataBuf.Cap() < int32(cryptoLen) {
return nil, io.ErrShortBuffer
}
if cryptoDataBuf.Len() != int32(cryptoLen) {
cryptoDataBuf.Extend(int32(cryptoLen) - cryptoDataBuf.Len())
}
}
if _, err := buffer.Read(cryptoData[offset : offset+length]); err != nil { // Field: Crypto Data
if _, err := buffer.Read(cryptoDataBuf.BytesRange(int32(offset), int32(offset+length))); err != nil { // Field: Crypto Data
return nil, io.ErrUnexpectedEOF
}
case 0x1c: // CONNECTION_CLOSE frame, only 0x1c is permitted in initial packet
@@ -262,7 +263,7 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
}
tlsHdr := &ptls.SniffHeader{}
err = ptls.ReadClientHello(cryptoData[:cryptoLen], tlsHdr)
err = ptls.ReadClientHello(cryptoDataBuf.BytesRange(0, int32(cryptoLen)), tlsHdr)
if err != nil {
// The crypto data may have not been fully recovered in current packets,
// So we continue to sniff rest packets.
@@ -271,6 +272,7 @@ func SniffQUIC(b []byte) (*SniffHeader, error) {
}
return &SniffHeader{domain: tlsHdr.Domain()}, nil
}
// All payload is parsed as valid QUIC packets, but we need more packets for crypto data to read client hello.
return nil, protocol.ErrProtoNeedMoreData
}