mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
86 lines
1.8 KiB
Go
86 lines
1.8 KiB
Go
package frames
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
|
|
"github.com/lucas-clemente/quic-go/internal/protocol"
|
|
"github.com/lucas-clemente/quic-go/internal/wire"
|
|
)
|
|
|
|
const version = protocol.VersionTLS
|
|
|
|
// PrefixLen is the number of bytes used for configuration
|
|
const PrefixLen = 1
|
|
|
|
func toEncLevel(v uint8) protocol.EncryptionLevel {
|
|
switch v % 3 {
|
|
default:
|
|
return protocol.EncryptionInitial
|
|
case 1:
|
|
return protocol.EncryptionHandshake
|
|
case 2:
|
|
return protocol.Encryption1RTT
|
|
}
|
|
}
|
|
|
|
// Fuzz fuzzes the QUIC frames.
|
|
//go:generate go run ./cmd/corpus.go
|
|
func Fuzz(data []byte) int {
|
|
if len(data) < PrefixLen {
|
|
return 0
|
|
}
|
|
encLevel := toEncLevel(data[0])
|
|
data = data[PrefixLen:]
|
|
|
|
parser := wire.NewFrameParser(version)
|
|
parser.SetAckDelayExponent(protocol.DefaultAckDelayExponent)
|
|
|
|
r := bytes.NewReader(data)
|
|
initialLen := r.Len()
|
|
|
|
var frames []wire.Frame
|
|
|
|
for r.Len() > 0 {
|
|
f, err := parser.ParseNext(r, encLevel)
|
|
if err != nil {
|
|
break
|
|
}
|
|
frames = append(frames, f)
|
|
}
|
|
parsedLen := initialLen - r.Len()
|
|
|
|
if len(frames) == 0 {
|
|
return 0
|
|
}
|
|
|
|
b := &bytes.Buffer{}
|
|
for _, f := range frames {
|
|
if f == nil { // PADDING frame
|
|
b.WriteByte(0x0)
|
|
continue
|
|
}
|
|
// We accept empty STREAM frames, but we don't write them.
|
|
if sf, ok := f.(*wire.StreamFrame); ok {
|
|
if sf.DataLen() == 0 {
|
|
sf.PutBack()
|
|
continue
|
|
}
|
|
}
|
|
lenBefore := b.Len()
|
|
if err := f.Write(b, version); err != nil {
|
|
panic(fmt.Sprintf("Error writing frame %#v: %s", f, err))
|
|
}
|
|
frameLen := b.Len() - lenBefore
|
|
if f.Length(version) != protocol.ByteCount(frameLen) {
|
|
panic(fmt.Sprintf("Inconsistent frame length for %#v: expected %d, got %d", f, frameLen, f.Length(version)))
|
|
}
|
|
if sf, ok := f.(*wire.StreamFrame); ok {
|
|
sf.PutBack()
|
|
}
|
|
}
|
|
if b.Len() > parsedLen {
|
|
panic(fmt.Sprintf("Serialized length (%d) is longer than parsed length (%d)", b.Len(), parsedLen))
|
|
}
|
|
return 1
|
|
}
|