Skip to content

Commit

Permalink
refactor: protect VarInt from being modified casually
Browse files Browse the repository at this point in the history
  • Loading branch information
huster-zhangpeng committed Jun 24, 2024
1 parent d3ae6bf commit ee71809
Show file tree
Hide file tree
Showing 22 changed files with 184 additions and 141 deletions.
55 changes: 30 additions & 25 deletions qbase/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub mod ext {

let be_max_idle_timeout = |input| {
let (remain, timeout) = be_varint(input)?;
Ok((remain, Duration::from_secs(timeout.0)))
Ok((remain, Duration::from_secs(timeout.into_inner())))
};

let be_preferred_address = |input| {
Expand Down Expand Up @@ -142,7 +142,7 @@ pub mod ext {
impl WriteParameters for bytes::BytesMut {
fn put_transport_parameters(&mut self, params: &TransportParameters) {
let put_varint = |buf: &mut Self, tag: u8, varint: VarInt| {
if varint.0 > 0 {
if varint.into_inner() > 0 {
buf.put_u8(tag);
buf.put_varint(&varint);
}
Expand Down Expand Up @@ -171,7 +171,12 @@ pub mod ext {
};

put_connection_id(self, 0x00, &params.original_destination_connection_id);
put_varint(self, 0x01, VarInt(params.max_idle_timeout.as_secs()));
put_varint(
self,
0x01,
VarInt::from_u64(params.max_idle_timeout.as_secs())
.expect("max_idle timeout can not exceed 2^62 seconds"),
);
put_reset_token(self, 0x02, &params.statelss_reset_token);
put_varint(self, 0x03, params.max_udp_payload_size);
put_varint(self, 0x04, params.initial_max_data);
Expand Down Expand Up @@ -258,22 +263,22 @@ impl Default for TransportParameters {
original_destination_connection_id: None,
max_idle_timeout: Duration::from_secs(0),
statelss_reset_token: None,
max_udp_payload_size: VarInt(65527), // 65535 - 8
initial_max_data: VarInt(0),
initial_max_stream_data_bidi_local: VarInt(0),
initial_max_stream_data_bidi_remote: VarInt(0),
initial_max_stream_data_uni: VarInt(0),
initial_max_streams_bidi: VarInt(0),
initial_max_streams_uni: VarInt(0),
ack_delay_exponent: VarInt(3),
max_ack_delay: VarInt(25),
max_udp_payload_size: VarInt::from_u32(65527), // 65535 - 8
initial_max_data: VarInt::default(),
initial_max_stream_data_bidi_local: VarInt::default(),
initial_max_stream_data_bidi_remote: VarInt::default(),
initial_max_stream_data_uni: VarInt::default(),
initial_max_streams_bidi: VarInt::default(),
initial_max_streams_uni: VarInt::default(),
ack_delay_exponent: VarInt::from_u32(3),
max_ack_delay: VarInt::from_u32(25),
disable_active_migration: false,
preferred_address: None,
active_connection_id_limit: VarInt(2),
active_connection_id_limit: VarInt::from_u32(2),
initial_source_connection_id: None,
retry_source_connection_id: None,
version_information: None,
max_datagram_frame_size: VarInt(65535),
max_datagram_frame_size: VarInt::from_u32(65535),
grease_quic_bit: false,
}
}
Expand All @@ -293,15 +298,15 @@ mod test {
original_destination_connection_id: Some(orgin_cid),
max_idle_timeout: Duration::from_secs(0x12345678),
statelss_reset_token: Some(ResetToken::new(&[0x01; RESET_TOKEN_SIZE])),
max_udp_payload_size: VarInt(0x1234),
initial_max_data: VarInt(0x1234),
initial_max_stream_data_bidi_local: VarInt(0),
initial_max_stream_data_bidi_remote: VarInt(0),
initial_max_stream_data_uni: VarInt(0),
initial_max_streams_bidi: VarInt(0x1234),
initial_max_streams_uni: VarInt(0x1234),
ack_delay_exponent: VarInt(0x12),
max_ack_delay: VarInt(0x1234),
max_udp_payload_size: VarInt::from_u32(0x1234),
initial_max_data: VarInt::from_u32(0x1234),
initial_max_stream_data_bidi_local: VarInt::from_u32(0),
initial_max_stream_data_bidi_remote: VarInt::from_u32(0),
initial_max_stream_data_uni: VarInt::from_u32(0),
initial_max_streams_bidi: VarInt::from_u32(0x1234),
initial_max_streams_uni: VarInt::from_u32(0x1234),
ack_delay_exponent: VarInt::from_u32(0x12),
max_ack_delay: VarInt::from_u32(0x1234),
disable_active_migration: true,
preferred_address: Some(PreferredAddress {
address_v4: Some(SocketAddrV4::new(
Expand All @@ -317,10 +322,10 @@ mod test {
connection_id: init_cid,
stateless_reset_token: ResetToken::new(&[0x02; RESET_TOKEN_SIZE]),
}),
active_connection_id_limit: VarInt(0x1234),
active_connection_id_limit: VarInt::from_u32(0x1234),
initial_source_connection_id: Some(init_cid),
retry_source_connection_id: Some(init_cid),
max_datagram_frame_size: VarInt(65535),
max_datagram_frame_size: VarInt::from_u32(65535),
// 下面两个字段 rfc 里没有?
version_information: None,
grease_quic_bit: false,
Expand Down
36 changes: 18 additions & 18 deletions qbase/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,24 @@ impl TryFrom<VarInt> for ErrorKind {
impl From<ErrorKind> for VarInt {
fn from(value: ErrorKind) -> Self {
match value {
ErrorKind::None => VarInt(0x00),
ErrorKind::Internal => VarInt(0x01),
ErrorKind::ConnectionRefused => VarInt(0x02),
ErrorKind::FlowControl => VarInt(0x03),
ErrorKind::StreamLimit => VarInt(0x04),
ErrorKind::StreamState => VarInt(0x05),
ErrorKind::FinalSize => VarInt(0x06),
ErrorKind::FrameEncoding => VarInt(0x07),
ErrorKind::TransportParameter => VarInt(0x08),
ErrorKind::ConnectionIdLimit => VarInt(0x09),
ErrorKind::ProtocolViolation => VarInt(0x0a),
ErrorKind::InvalidToken => VarInt(0x0b),
ErrorKind::Application => VarInt(0x0c),
ErrorKind::CryptoBufferExceeded => VarInt(0x0d),
ErrorKind::KeyUpdate => VarInt(0x0e),
ErrorKind::AeadLimitReached => VarInt(0x0f),
ErrorKind::NoViablePath => VarInt(0x10),
ErrorKind::Crypto(x) => VarInt(0x0100 + x as u64),
ErrorKind::None => VarInt::from(0x00u8),
ErrorKind::Internal => VarInt::from(0x01u8),
ErrorKind::ConnectionRefused => VarInt::from(0x02u8),
ErrorKind::FlowControl => VarInt::from(0x03u8),
ErrorKind::StreamLimit => VarInt::from(0x04u8),
ErrorKind::StreamState => VarInt::from(0x05u8),
ErrorKind::FinalSize => VarInt::from(0x06u8),
ErrorKind::FrameEncoding => VarInt::from(0x07u8),
ErrorKind::TransportParameter => VarInt::from(0x08u8),
ErrorKind::ConnectionIdLimit => VarInt::from(0x09u8),
ErrorKind::ProtocolViolation => VarInt::from(0x0au8),
ErrorKind::InvalidToken => VarInt::from(0x0bu8),
ErrorKind::Application => VarInt::from(0x0cu8),
ErrorKind::CryptoBufferExceeded => VarInt::from(0x0du8),
ErrorKind::KeyUpdate => VarInt::from(0x0eu8),
ErrorKind::AeadLimitReached => VarInt::from(0x0fu8),
ErrorKind::NoViablePath => VarInt::from(0x10u8),
ErrorKind::Crypto(x) => VarInt::from(0x0100u16 | x as u16),
}
}
}
Expand Down
40 changes: 20 additions & 20 deletions qbase/src/frame/ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ mod tests {
assert_eq!(
ecn,
EcnCounts {
ect0: VarInt(0x1234),
ect1: VarInt(0x1234),
ce: VarInt(0x1234),
ect0: VarInt::from_u32(0x1234),
ect1: VarInt::from_u32(0x1234),
ce: VarInt::from_u32(0x1234),
}
);
}
Expand All @@ -229,10 +229,10 @@ mod tests {
assert_eq!(
ack_frame,
AckFrame {
largest: VarInt(0x1234),
delay: VarInt(0x1234),
first_range: VarInt(0x1234),
ranges: vec![(VarInt(3), VarInt(20))],
largest: VarInt::from_u32(0x1234),
delay: VarInt::from_u32(0x1234),
first_range: VarInt::from_u32(0x1234),
ranges: vec![(VarInt::from_u32(3), VarInt::from_u32(20))],
ecn: None,
}
);
Expand All @@ -242,9 +242,9 @@ mod tests {
fn test_write_ecn_count() {
let mut buf = Vec::new();
let ecn = EcnCounts {
ect0: VarInt(0x1234),
ect1: VarInt(0x1234),
ce: VarInt(0x1234),
ect0: VarInt::from_u32(0x1234),
ect1: VarInt::from_u32(0x1234),
ce: VarInt::from_u32(0x1234),
};
buf.put_ecn_counts(&ecn);
assert_eq!(buf, vec![0x52, 0x34, 0x52, 0x34, 0x52, 0x34]);
Expand All @@ -254,10 +254,10 @@ mod tests {
fn test_write_ack_frame() {
let mut buf = Vec::new();
let frame = AckFrame {
largest: VarInt(0x1234),
delay: VarInt(0x1234),
first_range: VarInt(0x1234),
ranges: vec![(VarInt(3), VarInt(20))],
largest: VarInt::from_u32(0x1234),
delay: VarInt::from_u32(0x1234),
first_range: VarInt::from_u32(0x1234),
ranges: vec![(VarInt::from_u32(3), VarInt::from_u32(20))],
ecn: None,
};

Expand All @@ -272,13 +272,13 @@ mod tests {
fn test_ack_frame_into_iter() {
// let mut frame = AckFrame::new(1000, 0, 0x1234, None).unwrap();
let frame = AckFrame {
largest: VarInt(1000),
delay: VarInt(0x1234),
first_range: VarInt(0),
largest: VarInt::from_u32(1000),
delay: VarInt::from_u32(0x1234),
first_range: VarInt::from_u32(0),
ranges: vec![
(VarInt(0), VarInt(2)),
(VarInt(4), VarInt(30)),
(VarInt(7), VarInt(40)),
(VarInt::from_u32(0), VarInt::from_u32(2)),
(VarInt::from_u32(4), VarInt::from_u32(30)),
(VarInt::from_u32(7), VarInt::from_u32(40)),
],
ecn: None,
};
Expand Down
2 changes: 1 addition & 1 deletion qbase/src/frame/connection_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl super::BeFrame for ConnectionCloseFrame {
1 + VarInt::from(self.error_kind).encoding_size()
+ self.frame_type.is_some() as usize
// reason's length could not exceed 16KB
+ VarInt(self.reason.len() as u64).encoding_size()
+ VarInt::try_from(self.reason.len()).unwrap().encoding_size()
+ self.reason.len()
}
}
Expand Down
10 changes: 5 additions & 5 deletions qbase/src/frame/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl CryptoFrame {
capacity
// Must accommodate at least one byte, 'len' takes up 1 byte,
// content takes up 1 byte. If these are not satisfied, return None.
.checked_sub(1 + VarInt(offset).encoding_size() + 2)
.checked_sub(1 + VarInt::from_u64(offset).unwrap().encoding_size() + 2)
.map(|remaining| match remaining {
// Including the 1 byte already considered in check_sub,
// 'length' still takes up 1 byte.
Expand Down Expand Up @@ -134,8 +134,8 @@ mod tests {
assert_eq!(
frame,
CryptoFrame {
offset: VarInt(0x1234),
length: VarInt(0x5678),
offset: VarInt::from_u32(0x1234),
length: VarInt::from_u32(0x5678),
}
);
}
Expand All @@ -145,8 +145,8 @@ mod tests {
use super::WriteCryptoFrame;
let mut buf = bytes::BytesMut::new();
let frame = CryptoFrame {
offset: VarInt(0x1234),
length: VarInt(0x5),
offset: VarInt::from_u32(0x1234),
length: VarInt::from_u32(0x5),
};
buf.put_crypto_frame(&frame, b"hello");
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions qbase/src/frame/data_blocked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ mod tests {
assert_eq!(
frame,
DataBlockedFrame {
limit: crate::varint::VarInt(0x1234)
limit: crate::varint::VarInt::from_u32(0x1234)
}
);
}
Expand All @@ -81,7 +81,7 @@ mod tests {
use super::WriteDataBlockedFrame;
let mut buf = Vec::new();
buf.put_data_blocked_frame(&DataBlockedFrame {
limit: crate::varint::VarInt(0x1234),
limit: crate::varint::VarInt::from_u32(0x1234),
});
assert_eq!(buf, vec![DATA_BLOCKED_FRAME_TYPE, 0x52, 0x34]);
}
Expand Down
2 changes: 1 addition & 1 deletion qbase/src/frame/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn complete_frame(
FrameType::Stream(flag) => {
let (input, frame) = stream_frame_with_flag(flag)(input)?;
let start = raw.len() - input.len();
let len = frame.length;
let len = frame.len();
if input.len() < len {
Err(nom::Err::Incomplete(nom::Needed::new(len - input.len())))
} else {
Expand Down
4 changes: 2 additions & 2 deletions qbase/src/frame/max_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ mod tests {
assert_eq!(
frame,
MaxDataFrame {
max_data: VarInt(0x1234),
max_data: VarInt::from_u32(0x1234),
}
);
}
Expand All @@ -93,7 +93,7 @@ mod tests {

let mut buf = Vec::new();
buf.put_max_data_frame(&MaxDataFrame {
max_data: VarInt(0x1234),
max_data: VarInt::from_u32(0x1234),
});
assert_eq!(buf, vec![MAX_DATA_FRAME_TYPE, 0x52, 0x34]);
}
Expand Down
8 changes: 4 additions & 4 deletions qbase/src/frame/max_stream_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,17 @@ mod tests {
use super::be_max_stream_data_frame;
let buf = vec![0x52, 0x34, 0x80, 0, 0x56, 0x78];
let (_, frame) = be_max_stream_data_frame(&buf).unwrap();
assert_eq!(frame.stream_id, VarInt(0x1234).into());
assert_eq!(frame.max_stream_data, VarInt(0x5678));
assert_eq!(frame.stream_id, VarInt::from_u32(0x1234).into());
assert_eq!(frame.max_stream_data, VarInt::from_u32(0x5678));
}

#[test]
fn test_write_max_stream_data_frame() {
use super::WriteMaxStreamDataFrame;
let mut buf = Vec::new();
buf.put_max_stream_data_frame(&MaxStreamDataFrame {
stream_id: VarInt(0x1234).into(),
max_stream_data: VarInt(0x5678),
stream_id: VarInt::from_u32(0x1234).into(),
max_stream_data: VarInt::from_u32(0x5678),
});
assert_eq!(
buf,
Expand Down
8 changes: 4 additions & 4 deletions qbase/src/frame/max_streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ mod tests {
})(buf.as_ref())
.unwrap();
assert_eq!(input, &[]);
assert_eq!(frame, MaxStreamsFrame::Bi(VarInt(0x1234)));
assert_eq!(frame, MaxStreamsFrame::Bi(VarInt::from_u32(0x1234)));

let buf = vec![MAX_STREAMS_FRAME_TYPE | 0x1, 0x52, 0x36];
let (input, frame) = flat_map(be_varint, |frame_type| {
Expand All @@ -126,7 +126,7 @@ mod tests {
})(buf.as_ref())
.unwrap();
assert_eq!(input, &[]);
assert_eq!(frame, MaxStreamsFrame::Uni(VarInt(0x1236)));
assert_eq!(frame, MaxStreamsFrame::Uni(VarInt::from_u32(0x1236)));
}

#[test]
Expand Down Expand Up @@ -164,10 +164,10 @@ mod tests {
fn test_write_max_streams_frame() {
use super::WriteMaxStreamsFrame;
let mut buf = Vec::new();
buf.put_max_streams_frame(&MaxStreamsFrame::Bi(VarInt(0x1234)));
buf.put_max_streams_frame(&MaxStreamsFrame::Bi(VarInt::from_u32(0x1234)));
assert_eq!(buf, vec![MAX_STREAMS_FRAME_TYPE, 0x52, 0x34]);
buf.clear();
buf.put_max_streams_frame(&MaxStreamsFrame::Uni(VarInt(0x1236)));
buf.put_max_streams_frame(&MaxStreamsFrame::Uni(VarInt::from_u32(0x1236)));
assert_eq!(buf, vec![0x13, 0x52, 0x36]);
}
}
12 changes: 6 additions & 6 deletions qbase/src/frame/reset_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ mod tests {
assert_eq!(
frame,
ResetStreamFrame {
stream_id: VarInt(0x1234).into(),
app_error_code: VarInt(0x5678),
final_size: VarInt(0x9abc),
stream_id: VarInt::from_u32(0x1234).into(),
app_error_code: VarInt::from_u32(0x5678),
final_size: VarInt::from_u32(0x9abc),
}
);
}
Expand All @@ -119,11 +119,11 @@ mod tests {
fn test_write_reset_stream_frame() {
let mut buf = Vec::new();
buf.put_reset_stream_frame(&ResetStreamFrame {
stream_id: VarInt(0x1234).into(),
stream_id: VarInt::from_u32(0x1234).into(),
// 0x5678 = 0b01010110 01111000 => 0b10000000 0x00 0x56 0x78
app_error_code: VarInt(0x5678),
app_error_code: VarInt::from_u32(0x5678),
// 0x9abc = 0b10011010 10111100 => 0b10000000 0x00 0x9a 0xbc
final_size: VarInt(0x9abc),
final_size: VarInt::from_u32(0x9abc),
});
assert_eq!(
buf,
Expand Down
Loading

0 comments on commit ee71809

Please sign in to comment.