diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 34a59fa5..54864cbb 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -43,7 +43,7 @@ func (r *cachedReader) Cache(b *buf.Buffer, deadline time.Duration) error { r.cache, _ = buf.MergeMulti(r.cache, mb) } b.Clear() - rawBytes := b.Extend(b.Cap()) + rawBytes := b.Extend(min(r.cache.Len(), b.Cap())) n := r.cache.Copy(rawBytes) b.Resize(0, int32(n)) r.Unlock() diff --git a/common/protocol/quic/sniff.go b/common/protocol/quic/sniff.go index 61171c01..3a22d454 100644 --- a/common/protocol/quic/sniff.go +++ b/common/protocol/quic/sniff.go @@ -10,7 +10,6 @@ import ( "github.com/quic-go/quic-go/quicvarint" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/bytespool" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/protocol" ptls "github.com/xtls/xray-core/common/protocol/tls" @@ -53,9 +52,9 @@ func SniffQUIC(b []byte) (*SniffHeader, error) { } // Crypto data separated across packets - cryptoLen := 0 - cryptoData := bytespool.Alloc(32767) - defer bytespool.Free(cryptoData) + cryptoLen := int32(0) + cryptoDataBuf := buf.NewWithSize(32767) + defer cryptoDataBuf.Release() cache := buf.New() defer cache.Release() @@ -143,7 +142,7 @@ func SniffQUIC(b []byte) (*SniffHeader, error) { cache.Clear() mask := cache.Extend(int32(block.BlockSize())) - block.Encrypt(mask, b[hdrLen+4:hdrLen+4+16]) + block.Encrypt(mask, b[hdrLen+4:hdrLen+4+len(mask)]) b[0] ^= mask[0] & 0xf packetNumberLength := int(b[0]&0x3 + 1) for i := range packetNumberLength { @@ -217,15 +216,15 @@ func SniffQUIC(b []byte) (*SniffHeader, error) { if err != nil || length > uint64(buffer.Len()) { return nil, io.ErrUnexpectedEOF } - if cryptoLen < int(offset+length) { - newCryptoLen := int(offset + length) - if len(cryptoData) < newCryptoLen { + currentCryptoLen := int32(offset + length) + if cryptoLen < currentCryptoLen { + if cryptoDataBuf.Cap() < currentCryptoLen { return nil, io.ErrShortBuffer } - wipeBytes(cryptoData[cryptoLen:newCryptoLen]) - cryptoLen = newCryptoLen + cryptoDataBuf.Extend(currentCryptoLen - cryptoLen) + cryptoLen = currentCryptoLen } - if _, err := buffer.Read(cryptoData[offset : offset+length]); err != nil { // Field: Crypto Data + if _, err := buffer.Read(cryptoDataBuf.BytesRange(int32(offset), currentCryptoLen)); err != nil { // Field: Crypto Data return nil, io.ErrUnexpectedEOF } case 0x1c: // CONNECTION_CLOSE frame, only 0x1c is permitted in initial packet @@ -250,7 +249,7 @@ func SniffQUIC(b []byte) (*SniffHeader, error) { } tlsHdr := &ptls.SniffHeader{} - err = ptls.ReadClientHello(cryptoData[:cryptoLen], tlsHdr) + err = ptls.ReadClientHello(cryptoDataBuf.BytesRange(0, cryptoLen), tlsHdr) if err != nil { // The crypto data may have not been fully recovered in current packets, // So we continue to sniff rest packets. @@ -263,12 +262,6 @@ func SniffQUIC(b []byte) (*SniffHeader, error) { return nil, protocol.ErrProtoNeedMoreData } -func wipeBytes(b []byte) { - for i := range len(b) { - b[i] = 0x0 - } -} - func hkdfExpandLabel(hash crypto.Hash, secret, context []byte, label string, length int) []byte { b := make([]byte, 3, 3+6+len(label)+1+len(context)) binary.BigEndian.PutUint16(b, uint16(length))