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 }