github.com/daeuniverse/quic-go@v0.0.0-20240413031024-943f218e0810/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/daeuniverse/quic-go" 10 "github.com/daeuniverse/quic-go/fuzzing/internal/helper" 11 "github.com/daeuniverse/quic-go/internal/protocol" 12 "github.com/daeuniverse/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 }