github.com/quic-go/quic-go@v0.44.0/fuzzing/frames/cmd/corpus.go (about)

     1  package main
     2  
     3  import (
     4  	"log"
     5  	"time"
     6  
     7  	"golang.org/x/exp/rand"
     8  
     9  	"github.com/quic-go/quic-go"
    10  	"github.com/quic-go/quic-go/fuzzing/internal/helper"
    11  	"github.com/quic-go/quic-go/internal/protocol"
    12  	"github.com/quic-go/quic-go/internal/wire"
    13  )
    14  
    15  const version = protocol.Version1
    16  
    17  func getRandomData(l int) []byte {
    18  	b := make([]byte, l)
    19  	rand.Read(b)
    20  	return b
    21  }
    22  
    23  func getRandomNumber() uint64 {
    24  	switch 1 << uint8(rand.Intn(3)) {
    25  	case 1:
    26  		return uint64(rand.Int63n(64))
    27  	case 2:
    28  		return uint64(rand.Int63n(16384))
    29  	case 4:
    30  		return uint64(rand.Int63n(1073741824))
    31  	case 8:
    32  		return uint64(rand.Int63n(4611686018427387904))
    33  	default:
    34  		panic("unexpected length")
    35  	}
    36  }
    37  
    38  func getRandomNumberLowerOrEqual(target uint64) uint64 {
    39  	if target == 0 {
    40  		return 0
    41  	}
    42  	return uint64(rand.Int63n(int64(target)))
    43  }
    44  
    45  // returns a *maximum* number of num ACK ranges
    46  func getAckRanges(num int) []wire.AckRange {
    47  	var ranges []wire.AckRange
    48  
    49  	prevSmallest := uint64(rand.Int63n(4611686018427387904))
    50  	for i := 0; i < num; i++ {
    51  		if prevSmallest <= 2 {
    52  			break
    53  		}
    54  		largest := getRandomNumberLowerOrEqual(prevSmallest - 2)
    55  		smallest := getRandomNumberLowerOrEqual(largest)
    56  
    57  		ranges = append(ranges, wire.AckRange{
    58  			Smallest: protocol.PacketNumber(smallest),
    59  			Largest:  protocol.PacketNumber(largest),
    60  		})
    61  		prevSmallest = smallest
    62  	}
    63  	return ranges
    64  }
    65  
    66  func getFrames() []wire.Frame {
    67  	frames := []wire.Frame{
    68  		&wire.StreamFrame{ // STREAM frame at 0 offset, with FIN bit
    69  			StreamID: protocol.StreamID(getRandomNumber()),
    70  			Fin:      true,
    71  		},
    72  		&wire.StreamFrame{ // STREAM frame at 0 offset, with data and FIN bit
    73  			StreamID: protocol.StreamID(getRandomNumber()),
    74  			Fin:      true,
    75  			Data:     getRandomData(100),
    76  		},
    77  		&wire.StreamFrame{ // STREAM frame at non-zero offset, with data
    78  			StreamID: protocol.StreamID(getRandomNumber()),
    79  			Offset:   protocol.ByteCount(getRandomNumber()),
    80  			Data:     getRandomData(50),
    81  		},
    82  		&wire.StreamFrame{ // STREAM frame at non-zero offset, with data and FIN bit
    83  			StreamID: protocol.StreamID(getRandomNumber()),
    84  			Offset:   protocol.ByteCount(getRandomNumber()),
    85  			Data:     getRandomData(50),
    86  			Fin:      true,
    87  		},
    88  		&wire.StreamFrame{ // STREAM frame at non-zero offset, with data and FIN bit. Long enough to use the buffer.
    89  			StreamID: protocol.StreamID(getRandomNumber()),
    90  			Offset:   protocol.ByteCount(getRandomNumber()),
    91  			Data:     getRandomData(2 * protocol.MinStreamFrameBufferSize),
    92  			Fin:      true,
    93  		},
    94  		&wire.StreamFrame{ // STREAM frame at maximum offset, with FIN bit
    95  			StreamID: protocol.StreamID(getRandomNumber()),
    96  			Offset:   protocol.MaxByteCount - 5,
    97  			Data:     getRandomData(5),
    98  			Fin:      true,
    99  		},
   100  		&wire.StreamFrame{ // STREAM frame with data at maximum offset
   101  			StreamID: protocol.StreamID(getRandomNumber()),
   102  			Offset:   protocol.MaxByteCount,
   103  			Data:     getRandomData(10),
   104  		},
   105  		&wire.AckFrame{
   106  			AckRanges: getAckRanges(1),
   107  			DelayTime: time.Duration(getRandomNumber()),
   108  		},
   109  		&wire.AckFrame{
   110  			AckRanges: getAckRanges(5),
   111  			DelayTime: time.Duration(getRandomNumber()),
   112  		},
   113  		&wire.AckFrame{
   114  			AckRanges: getAckRanges(300),
   115  			DelayTime: time.Duration(getRandomNumber()),
   116  		},
   117  		&wire.AckFrame{
   118  			AckRanges: getAckRanges(3),
   119  			DelayTime: time.Duration(getRandomNumber()),
   120  			ECT0:      getRandomNumber(),
   121  			ECT1:      getRandomNumber(),
   122  			ECNCE:     getRandomNumber(),
   123  		},
   124  		&wire.PingFrame{},
   125  		&wire.ResetStreamFrame{
   126  			StreamID:  protocol.StreamID(getRandomNumber()),
   127  			ErrorCode: quic.StreamErrorCode(getRandomNumber()),
   128  			FinalSize: protocol.ByteCount(getRandomNumber()),
   129  		},
   130  		&wire.ResetStreamFrame{ // at maximum offset
   131  			StreamID:  protocol.StreamID(getRandomNumber()),
   132  			ErrorCode: quic.StreamErrorCode(getRandomNumber()),
   133  			FinalSize: protocol.MaxByteCount,
   134  		},
   135  		&wire.StopSendingFrame{
   136  			StreamID:  protocol.StreamID(getRandomNumber()),
   137  			ErrorCode: quic.StreamErrorCode(getRandomNumber()),
   138  		},
   139  		&wire.CryptoFrame{
   140  			Data: getRandomData(100),
   141  		},
   142  		&wire.CryptoFrame{
   143  			Offset: protocol.ByteCount(getRandomNumber()),
   144  			Data:   getRandomData(50),
   145  		},
   146  		&wire.NewTokenFrame{
   147  			Token: getRandomData(10),
   148  		},
   149  		&wire.MaxDataFrame{
   150  			MaximumData: protocol.ByteCount(getRandomNumber()),
   151  		},
   152  		&wire.MaxDataFrame{
   153  			MaximumData: protocol.MaxByteCount,
   154  		},
   155  		&wire.MaxStreamDataFrame{
   156  			StreamID:          protocol.StreamID(getRandomNumber()),
   157  			MaximumStreamData: protocol.ByteCount(getRandomNumber()),
   158  		},
   159  		&wire.MaxStreamDataFrame{
   160  			StreamID:          protocol.StreamID(getRandomNumber()),
   161  			MaximumStreamData: protocol.MaxByteCount,
   162  		},
   163  		&wire.MaxStreamsFrame{
   164  			Type:         protocol.StreamTypeUni,
   165  			MaxStreamNum: protocol.StreamNum(getRandomNumber()),
   166  		},
   167  		&wire.MaxStreamsFrame{
   168  			Type:         protocol.StreamTypeBidi,
   169  			MaxStreamNum: protocol.StreamNum(getRandomNumber()),
   170  		},
   171  		&wire.DataBlockedFrame{
   172  			MaximumData: protocol.ByteCount(getRandomNumber()),
   173  		},
   174  		&wire.DataBlockedFrame{
   175  			MaximumData: protocol.MaxByteCount,
   176  		},
   177  		&wire.StreamDataBlockedFrame{
   178  			StreamID:          protocol.StreamID(getRandomNumber()),
   179  			MaximumStreamData: protocol.ByteCount(getRandomNumber()),
   180  		},
   181  		&wire.StreamDataBlockedFrame{
   182  			StreamID:          protocol.StreamID(getRandomNumber()),
   183  			MaximumStreamData: protocol.MaxByteCount,
   184  		},
   185  		&wire.StreamsBlockedFrame{
   186  			Type:        protocol.StreamTypeUni,
   187  			StreamLimit: protocol.StreamNum(getRandomNumber()),
   188  		},
   189  		&wire.StreamsBlockedFrame{
   190  			Type:        protocol.StreamTypeBidi,
   191  			StreamLimit: protocol.StreamNum(getRandomNumber()),
   192  		},
   193  		&wire.RetireConnectionIDFrame{
   194  			SequenceNumber: getRandomNumber(),
   195  		},
   196  		&wire.ConnectionCloseFrame{ // QUIC error with empty reason
   197  			IsApplicationError: false,
   198  			ErrorCode:          getRandomNumber(),
   199  			ReasonPhrase:       "",
   200  		},
   201  		&wire.ConnectionCloseFrame{ // QUIC error with reason
   202  			IsApplicationError: false,
   203  			// TODO: add frame type
   204  			ErrorCode:    getRandomNumber(),
   205  			ReasonPhrase: string(getRandomData(100)),
   206  		},
   207  		&wire.ConnectionCloseFrame{ // application error with empty reason
   208  			IsApplicationError: true,
   209  			ErrorCode:          getRandomNumber(),
   210  			ReasonPhrase:       "",
   211  		},
   212  		&wire.ConnectionCloseFrame{ // application error with reason
   213  			IsApplicationError: true,
   214  			ErrorCode:          getRandomNumber(),
   215  			ReasonPhrase:       string(getRandomData(100)),
   216  		},
   217  	}
   218  
   219  	seq1 := getRandomNumber()
   220  	seq2 := getRandomNumber()
   221  	var token1, token2 protocol.StatelessResetToken
   222  	copy(token1[:], getRandomData(16))
   223  	copy(token2[:], getRandomData(16))
   224  	frames = append(frames, []wire.Frame{
   225  		&wire.NewConnectionIDFrame{
   226  			SequenceNumber:      seq1,
   227  			RetirePriorTo:       seq1 / 2,
   228  			ConnectionID:        protocol.ParseConnectionID(getRandomData(4)),
   229  			StatelessResetToken: token1,
   230  		},
   231  		&wire.NewConnectionIDFrame{
   232  			SequenceNumber:      seq2,
   233  			RetirePriorTo:       seq2,
   234  			ConnectionID:        protocol.ParseConnectionID(getRandomData(17)),
   235  			StatelessResetToken: token2,
   236  		},
   237  	}...)
   238  
   239  	var data1 [8]byte
   240  	copy(data1[:], getRandomData(8))
   241  	frames = append(frames, &wire.PathChallengeFrame{
   242  		Data: data1,
   243  	})
   244  
   245  	var data2 [8]byte
   246  	copy(data2[:], getRandomData(8))
   247  	frames = append(frames, &wire.PathResponseFrame{
   248  		Data: data2,
   249  	})
   250  
   251  	return frames
   252  }
   253  
   254  func main() {
   255  	for _, f := range getFrames() {
   256  		b, err := f.Append(nil, version)
   257  		if err != nil {
   258  			log.Fatal(err)
   259  		}
   260  		if err := helper.WriteCorpusFileWithPrefix("corpus", b, 1); err != nil {
   261  			log.Fatal(err)
   262  		}
   263  	}
   264  
   265  	for i := 0; i < 30; i++ {
   266  		frames := getFrames()
   267  
   268  		var b []byte
   269  		for j := 0; j < rand.Intn(30)+2; j++ {
   270  			if rand.Intn(10) == 0 { // write a PADDING frame
   271  				b = append(b, 0)
   272  			}
   273  			f := frames[rand.Intn(len(frames))]
   274  			var err error
   275  			b, err = f.Append(b, version)
   276  			if err != nil {
   277  				log.Fatal(err)
   278  			}
   279  			if rand.Intn(10) == 0 { // write a PADDING frame
   280  				b = append(b, 0)
   281  			}
   282  		}
   283  		if err := helper.WriteCorpusFileWithPrefix("corpus", b, 1); err != nil {
   284  			log.Fatal(err)
   285  		}
   286  	}
   287  }