in neqo-transport/src/tparams.rs [277:340]
fn decode(dec: &mut Decoder) -> Res<Option<(TransportParameterId, Self)>> {
let tp = dec.decode_varint().ok_or(Error::NoMoreData)?;
let content = dec.decode_vvec().ok_or(Error::NoMoreData)?;
qtrace!("TP {tp:x} length {:x}", content.len());
let tp = match tp.try_into() {
Ok(tp) => tp,
Err(Error::UnknownTransportParameter) => return Ok(None), // Skip
Err(e) => return Err(e),
};
let mut d = Decoder::from(content);
let value = match tp {
OriginalDestinationConnectionId
| InitialSourceConnectionId
| RetrySourceConnectionId => Self::Bytes(d.decode_remainder().to_vec()),
StatelessResetToken => {
if d.remaining() != 16 {
return Err(Error::TransportParameterError);
}
Self::Bytes(d.decode_remainder().to_vec())
}
IdleTimeout
| InitialMaxData
| InitialMaxStreamDataBidiLocal
| InitialMaxStreamDataBidiRemote
| InitialMaxStreamDataUni
| MaxAckDelay
| MaxDatagramFrameSize => match d.decode_varint() {
Some(v) => Self::Integer(v),
None => return Err(Error::TransportParameterError),
},
InitialMaxStreamsBidi | InitialMaxStreamsUni => match d.decode_varint() {
Some(v) if v <= (1 << 60) => Self::Integer(v),
_ => return Err(Error::StreamLimitError),
},
MaxUdpPayloadSize => match d.decode_varint() {
Some(v) if v >= MIN_INITIAL_PACKET_SIZE.try_into()? => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
AckDelayExponent => match d.decode_varint() {
Some(v) if v <= 20 => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
ActiveConnectionIdLimit => match d.decode_varint() {
Some(v) if v >= 2 => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
DisableMigration | GreaseQuicBit => Self::Empty,
TransportParameterId::PreferredAddress => Self::decode_preferred_address(&mut d)?,
MinAckDelay => match d.decode_varint() {
Some(v) if v < (1 << 24) => Self::Integer(v),
_ => return Err(Error::TransportParameterError),
},
VersionInformation => Self::decode_versions(&mut d)?,
#[cfg(test)]
TransportParameterId::TestTransportParameter => {
Self::Bytes(d.decode_remainder().to_vec())
}
};
if d.remaining() > 0 {
return Err(Error::TooMuchData);
}
qtrace!("TP decoded; type {tp} val {value:?}");
Ok(Some((tp, value)))
}