mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-02 19:57:35 +03:00
uTLS is not yet bumped to the new version, so this commit breaks the dependencies relationship by getting rid of the local replace.
103 lines
2.6 KiB
Go
103 lines
2.6 KiB
Go
package header
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
|
|
"github.com/refraction-networking/uquic/internal/protocol"
|
|
"github.com/refraction-networking/uquic/internal/wire"
|
|
)
|
|
|
|
const version = protocol.Version1
|
|
|
|
// PrefixLen is the number of bytes used for configuration
|
|
const PrefixLen = 1
|
|
|
|
// Fuzz fuzzes the QUIC header.
|
|
//
|
|
//go:generate go run ./cmd/corpus.go
|
|
func Fuzz(data []byte) int {
|
|
if len(data) < PrefixLen {
|
|
return 0
|
|
}
|
|
connIDLen := int(data[0] % 21)
|
|
data = data[PrefixLen:]
|
|
|
|
if wire.IsVersionNegotiationPacket(data) {
|
|
return fuzzVNP(data)
|
|
}
|
|
connID, err := wire.ParseConnectionID(data, connIDLen)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
|
|
if !wire.IsLongHeaderPacket(data[0]) {
|
|
wire.ParseShortHeader(data, connIDLen)
|
|
return 1
|
|
}
|
|
|
|
is0RTTPacket := wire.Is0RTTPacket(data)
|
|
hdr, _, _, err := wire.ParsePacket(data)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
if hdr.DestConnectionID != connID {
|
|
panic(fmt.Sprintf("Expected connection IDs to match: %s vs %s", hdr.DestConnectionID, connID))
|
|
}
|
|
if (hdr.Type == protocol.PacketType0RTT) != is0RTTPacket {
|
|
panic("inconsistent 0-RTT packet detection")
|
|
}
|
|
|
|
var extHdr *wire.ExtendedHeader
|
|
// Parse the extended header, if this is not a Retry packet.
|
|
if hdr.Type == protocol.PacketTypeRetry {
|
|
extHdr = &wire.ExtendedHeader{Header: *hdr}
|
|
} else {
|
|
var err error
|
|
extHdr, err = hdr.ParseExtended(bytes.NewReader(data), version)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
}
|
|
// We always use a 2-byte encoding for the Length field in Long Header packets.
|
|
// Serializing the header will fail when using a higher value.
|
|
if hdr.Length > 16383 {
|
|
return 1
|
|
}
|
|
b, err := extHdr.Append(nil, version)
|
|
if err != nil {
|
|
// We are able to parse packets with connection IDs longer than 20 bytes,
|
|
// but in QUIC version 1, we don't write headers with longer connection IDs.
|
|
if hdr.DestConnectionID.Len() <= protocol.MaxConnIDLen &&
|
|
hdr.SrcConnectionID.Len() <= protocol.MaxConnIDLen {
|
|
panic(err)
|
|
}
|
|
return 0
|
|
}
|
|
// GetLength is not implemented for Retry packets
|
|
if hdr.Type != protocol.PacketTypeRetry {
|
|
if expLen := extHdr.GetLength(version); expLen != protocol.ByteCount(len(b)) {
|
|
panic(fmt.Sprintf("inconsistent header length: %#v. Expected %d, got %d", extHdr, expLen, len(b)))
|
|
}
|
|
}
|
|
return 1
|
|
}
|
|
|
|
func fuzzVNP(data []byte) int {
|
|
connID, err := wire.ParseConnectionID(data, 0)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
dest, src, versions, err := wire.ParseVersionNegotiationPacket(data)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
if !bytes.Equal(dest, connID.Bytes()) {
|
|
panic("connection IDs don't match")
|
|
}
|
|
if len(versions) == 0 {
|
|
panic("no versions")
|
|
}
|
|
wire.ComposeVersionNegotiation(src, dest, versions)
|
|
return 1
|
|
}
|