net_wire/quic/frame/
stream.rs1use super::super::varint::QuicVarInt;
4use super::parse::{QuicFrameField, QuicFrameParseError};
5
6const MAX_STREAM_RANGE_END: u64 = (1 << 62) - 1;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct QuicStreamFrame<'a> {
11 bytes: &'a [u8],
12 frame_type: QuicVarInt<'a>,
13 stream_id: QuicVarInt<'a>,
14 offset: Option<QuicVarInt<'a>>,
15 length: Option<QuicVarInt<'a>>,
16 stream_data: &'a [u8],
17}
18
19impl<'a> QuicStreamFrame<'a> {
20 pub const fn as_bytes(self) -> &'a [u8] {
22 self.bytes
23 }
24
25 pub const fn frame_type(self) -> QuicVarInt<'a> {
27 self.frame_type
28 }
29
30 pub const fn stream_id(self) -> QuicVarInt<'a> {
32 self.stream_id
33 }
34
35 pub const fn offset(self) -> Option<QuicVarInt<'a>> {
39 self.offset
40 }
41
42 pub const fn length(self) -> Option<QuicVarInt<'a>> {
46 self.length
47 }
48
49 pub const fn stream_data(self) -> &'a [u8] {
51 self.stream_data
52 }
53
54 pub const fn fin(self) -> bool {
56 self.frame_type.value() & 0x01 != 0
57 }
58}
59
60pub(super) fn parse_stream<'a>(
61 bytes: &'a [u8],
62 frame_type: QuicVarInt<'a>,
63 offset: usize,
64) -> Result<(QuicStreamFrame<'a>, &'a [u8]), QuicFrameParseError> {
65 let flags = frame_type.value();
66 let has_offset = flags & 0x04 != 0;
67 let has_length = flags & 0x02 != 0;
68
69 let stream_id_start = frame_type.byte_len();
70 let stream_id_offset = offset + stream_id_start;
71 let stream_id = QuicVarInt::parse(&bytes[stream_id_start..]).map_err(|error| {
72 QuicFrameParseError::Field {
73 field: QuicFrameField::StreamId,
74 offset: stream_id_offset,
75 error,
76 }
77 })?;
78
79 let mut data_start = stream_id_start + stream_id.byte_len();
80 let range_offset = offset + data_start;
82 let stream_offset = if has_offset {
83 let field_offset = offset + data_start;
84 let value = QuicVarInt::parse(&bytes[data_start..]).map_err(|error| {
85 QuicFrameParseError::Field {
86 field: QuicFrameField::StreamOffset,
87 offset: field_offset,
88 error,
89 }
90 })?;
91 data_start += value.byte_len();
92 Some(value)
93 } else {
94 None
95 };
96
97 let length = if has_length {
98 let field_offset = offset + data_start;
99 let value = QuicVarInt::parse(&bytes[data_start..]).map_err(|error| {
100 QuicFrameParseError::Field {
101 field: QuicFrameField::StreamLength,
102 offset: field_offset,
103 error,
104 }
105 })?;
106 data_start += value.byte_len();
107 Some((value, field_offset))
108 } else {
109 None
110 };
111
112 let start = stream_offset.map_or(0, QuicVarInt::value);
113 let data_offset = offset + data_start;
114 let (length_varint, data_end) = match length {
115 Some((length, length_offset)) => {
116 let data_length = length.value();
117 validate_range(start, data_length, range_offset)?;
118 let length_usize = usize::try_from(data_length).map_err(|_| {
119 QuicFrameParseError::LengthNotRepresentable {
120 field: QuicFrameField::StreamLength,
121 offset: length_offset,
122 value: data_length,
123 }
124 })?;
125 let data_end = data_start.checked_add(length_usize).ok_or(
126 QuicFrameParseError::LengthOverflow {
127 field: QuicFrameField::StreamData,
128 offset: data_offset,
129 length: length_usize,
130 },
131 )?;
132 let available = bytes.len() - data_start;
133 if available < length_usize {
134 return Err(QuicFrameParseError::IncompleteBytes {
135 field: QuicFrameField::StreamData,
136 offset: data_offset,
137 required: length_usize,
138 available,
139 });
140 }
141 (Some(length), data_end)
142 }
143 None => {
144 let data_end = bytes.len();
145 let data_length = match u64::try_from(data_end - data_start) {
148 Ok(value) => value,
149 Err(_) => {
150 return Err(QuicFrameParseError::ImplicitLengthNotRepresentable {
151 field: QuicFrameField::StreamData,
152 offset: data_offset,
153 length: data_end - data_start,
154 });
155 }
156 };
157 validate_range(start, data_length, range_offset)?;
158 (None, data_end)
159 }
160 };
161
162 Ok((
163 QuicStreamFrame {
164 bytes: &bytes[..data_end],
165 frame_type,
166 stream_id,
167 offset: stream_offset,
168 length: length_varint,
169 stream_data: &bytes[data_start..data_end],
170 },
171 &bytes[data_end..],
172 ))
173}
174
175fn validate_range(start: u64, length: u64, offset: usize) -> Result<(), QuicFrameParseError> {
176 if start
177 .checked_add(length)
178 .is_none_or(|end| end > MAX_STREAM_RANGE_END)
179 {
180 return Err(QuicFrameParseError::FieldRangeOutOfRange {
181 field: QuicFrameField::StreamOffset,
182 offset,
183 start,
184 length,
185 maximum: MAX_STREAM_RANGE_END,
186 });
187 }
188 Ok(())
189}