in quic/s2n-quic-core/src/havoc.rs [477:650]
fn havoc<R: Random>(&mut self, rand: &mut R, buffer: &mut EncoderBuffer) {
type GenFrame<R> = for<'a> fn(
rand: &'a mut R,
payload: &'a mut [u8],
remaining_capacity: usize,
) -> frame::Frame<'a, AckRanges<'a, R>, &'a mut [u8]>;
let frames: &[GenFrame<R>] = &[
|rand, _data, cap| {
frame::Padding {
length: rand.gen_range(1..cap as _) as _,
}
.into()
},
|_rand, _data, _cap| frame::Ping.into(),
// TODO ACK
|rand, _data, _cap| {
frame::ResetStream {
stream_id: rand.gen_varint(),
application_error_code: rand.gen_varint(),
final_size: rand.gen_varint(),
}
.into()
},
|rand, _data, _cap| {
frame::StopSending {
stream_id: rand.gen_varint(),
application_error_code: rand.gen_varint(),
}
.into()
},
|rand, data, cap| {
let data = rand.gen_slice(&mut data[..cap]);
frame::Crypto {
offset: rand.gen_varint(),
data,
}
.into()
},
|rand, data, cap| {
let token = rand.gen_slice(&mut data[..cap]);
frame::NewToken { token }.into()
},
|rand, data, cap| {
let data = rand.gen_slice(&mut data[..cap]);
frame::Stream {
stream_id: rand.gen_varint(),
offset: rand.gen_varint(),
data,
is_last_frame: rand.gen_bool(),
is_fin: rand.gen_bool(),
}
.into()
},
|rand, _data, _cap| {
frame::MaxData {
maximum_data: rand.gen_varint(),
}
.into()
},
|rand, _data, _cap| {
frame::MaxStreamData {
stream_id: rand.gen_varint(),
maximum_stream_data: rand.gen_varint(),
}
.into()
},
|rand, _data, _cap| {
frame::MaxStreams {
stream_type: if rand.gen_bool() {
StreamType::Unidirectional
} else {
StreamType::Bidirectional
},
maximum_streams: rand.gen_varint(),
}
.into()
},
|rand, _data, _cap| {
frame::DataBlocked {
data_limit: rand.gen_varint(),
}
.into()
},
|rand, _data, _cap| {
frame::StreamDataBlocked {
stream_id: rand.gen_varint(),
stream_data_limit: rand.gen_varint(),
}
.into()
},
|rand, _data, _cap| {
frame::StreamsBlocked {
stream_type: if rand.gen_bool() {
StreamType::Unidirectional
} else {
StreamType::Bidirectional
},
stream_limit: rand.gen_varint(),
}
.into()
},
|rand, data, cap| {
let (stateless_reset_token, data) = data.split_at_mut(STATELESS_RESET_TOKEN_LEN);
rand.fill(stateless_reset_token);
let stateless_reset_token = (&*stateless_reset_token).try_into().unwrap();
// connection ID lengths are encoded with a u8
let cap = cap.min(u8::MAX as usize);
let connection_id = rand.gen_slice(&mut data[..cap]);
frame::NewConnectionId {
sequence_number: rand.gen_varint(),
retire_prior_to: rand.gen_varint(),
connection_id,
stateless_reset_token,
}
.into()
},
|rand, _data, _cap| {
frame::RetireConnectionId {
sequence_number: rand.gen_varint(),
}
.into()
},
|rand, data, _cap| {
let data = &mut data[..frame::path_challenge::DATA_LEN];
rand.fill(data);
let data = (&*data).try_into().unwrap();
frame::PathChallenge { data }.into()
},
|rand, data, _cap| {
let data = &mut data[..frame::path_challenge::DATA_LEN];
rand.fill(data);
let data = (&*data).try_into().unwrap();
frame::PathResponse { data }.into()
},
|rand, data, cap| {
frame::ConnectionClose {
error_code: rand.gen_varint(),
frame_type: if rand.gen_bool() {
Some(rand.gen_varint())
} else {
None
},
reason: if rand.gen_bool() {
let reason = rand.gen_slice(&mut data[..cap]);
Some(reason)
} else {
None
},
}
.into()
},
|_rand, _data, _cap| frame::HandshakeDone.into(),
|rand, data, cap| {
let data = rand.gen_slice(&mut data[..cap]);
frame::Datagram {
is_last_frame: rand.gen_bool(),
data,
}
.into()
},
];
let index = rand.gen_range(0..frames.len() as u64) as usize;
let mut payload = [0u8; 16_000];
let frame = frames[index](rand, &mut payload, buffer.remaining_capacity());
if frame.encoding_size() <= buffer.remaining_capacity() {
buffer.encode(&frame);
}
}