github.com/mikelsr/quic-go@v0.36.1-0.20230701132136-1d9415b66898/fuzzing/frames/cmd/corpus.go (about)

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