1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
//! QUIC frame parsing diagnostics.
use core::fmt;
use super::super::varint::{QuicVarIntLen, QuicVarIntParseError};
/// Identifies a semantic field in a QUIC frame.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum QuicFrameField {
/// The CRYPTO frame's offset field.
CryptoOffset,
/// The CRYPTO frame's data-length field.
CryptoLength,
/// The CRYPTO frame's opaque data bytes.
CryptoData,
/// The frame's token-length field.
TokenLength,
/// The frame's opaque token bytes.
Token,
/// The frame's stream-ID field.
StreamId,
/// The STREAM frame's offset field.
StreamOffset,
/// The STREAM frame's data-length field.
StreamLength,
/// The STREAM frame's opaque data bytes.
StreamData,
/// The frame's maximum-data field.
MaximumData,
/// The frame's maximum-stream-data field.
MaximumStreamData,
/// The frame's maximum-streams field.
MaximumStreams,
/// The frame's application-error-code field.
ApplicationErrorCode,
/// The CONNECTION_CLOSE frame's error-code field.
ConnectionCloseErrorCode,
/// The transport CONNECTION_CLOSE frame's triggering-frame-type field.
TriggeringFrameType,
/// The CONNECTION_CLOSE frame's reason-phrase-length field.
ReasonPhraseLength,
/// The CONNECTION_CLOSE frame's opaque reason-phrase bytes.
ReasonPhrase,
/// The frame's final-size field.
FinalSize,
/// The frame's opaque path-validation data.
PathData,
/// The frame's connection-ID sequence-number field.
SequenceNumber,
/// The frame's retire-prior-to field.
RetirePriorTo,
/// The frame's connection-ID-length field.
ConnectionIdLength,
/// The frame's opaque connection-ID bytes.
ConnectionId,
/// The frame's stateless-reset-token bytes.
StatelessResetToken,
/// The ACK frame's largest-acknowledged field.
LargestAcknowledged,
/// The ACK frame's acknowledgment-delay field.
AckDelay,
/// The ACK frame's additional-range count field.
AckRangeCount,
/// The ACK frame's first acknowledgment-range field.
FirstAckRange,
/// An ACK frame's additional-range gap field.
AckGap,
/// An ACK frame's additional-range length field.
AckRangeLength,
/// The ACK_ECN frame's ECT(0) count field.
Ect0Count,
/// The ACK_ECN frame's ECT(1) count field.
Ect1Count,
/// The ACK_ECN frame's ECN-CE count field.
EcnCeCount,
}
/// Failure to parse a QUIC plaintext frame sequence.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuicFrameParseError {
/// The supplied plaintext frame sequence contains no frames.
EmptySequence,
/// The frame-type variable integer is incomplete at the indicated sequence offset.
FrameType {
/// Absolute byte offset of the frame type from the sequence start.
offset: usize,
/// Exact variable-integer parsing failure.
error: QuicVarIntParseError,
},
/// A semantic frame field variable integer is incomplete at the indicated sequence offset.
Field {
/// Semantic field whose variable integer could not be parsed.
field: QuicFrameField,
/// Absolute byte offset of the field from the sequence start.
offset: usize,
/// Exact variable-integer parsing failure.
error: QuicVarIntParseError,
},
/// A semantic frame field exceeds its RFC-defined maximum value.
FieldValueOutOfRange {
/// Semantic field whose decoded value exceeds its maximum.
field: QuicFrameField,
/// Absolute byte offset of the field from the sequence start.
offset: usize,
/// Decoded field value.
value: u64,
/// Greatest permitted field value.
maximum: u64,
},
/// A semantic frame field exceeds the decoded value of another field.
FieldValueExceedsField {
/// Semantic field whose decoded value is too large.
field: QuicFrameField,
/// Absolute byte offset of the field from the sequence start.
offset: usize,
/// Decoded field value.
value: u64,
/// Semantic field supplying the maximum value.
maximum_field: QuicFrameField,
/// Decoded maximum-field value.
maximum: u64,
},
/// A decoded frame byte range exceeds its RFC-defined maximum end offset.
FieldRangeOutOfRange {
/// Semantic field encoding the decoded range start.
field: QuicFrameField,
/// Absolute byte offset of the encoded range-start field from the sequence start.
offset: usize,
/// Decoded range start.
start: u64,
/// Decoded range length.
length: u64,
/// Greatest permitted decoded range end.
maximum: u64,
},
/// A decoded bounded-byte field length cannot be represented as `usize` on this target.
LengthNotRepresentable {
/// Semantic field whose length cannot be represented.
field: QuicFrameField,
/// Absolute byte offset of the encoded length from the sequence start.
offset: usize,
/// Decoded wire length.
value: u64,
},
/// An implicit bounded-byte field length cannot be represented as `u64`.
ImplicitLengthNotRepresentable {
/// Semantic field whose implicit length cannot be represented.
field: QuicFrameField,
/// Absolute byte offset of the bounded byte field from the sequence start.
offset: usize,
/// Native byte length derived from the supplied slice.
length: usize,
},
/// Computing the end of a bounded-byte field overflows `usize`.
LengthOverflow {
/// Semantic bounded-byte field whose end cannot be represented.
field: QuicFrameField,
/// Absolute byte offset of the bounded byte field from the sequence start.
offset: usize,
/// Representable bounded byte-field length.
length: usize,
},
/// A bounded-byte field is incomplete.
IncompleteBytes {
/// Semantic bounded-byte field that is incomplete.
field: QuicFrameField,
/// Absolute byte offset of the bounded byte field from the sequence start.
offset: usize,
/// Bytes required by the bounded byte field.
required: usize,
/// Bytes available for the bounded byte field.
available: usize,
},
/// A semantically required nonempty field is empty.
EmptyField {
/// Semantic field that must not be empty.
field: QuicFrameField,
/// Absolute byte offset of the field from the sequence start.
offset: usize,
},
/// Computing an ACK range packet number would be negative.
AckRangeUnderflow {
/// ACK field whose encoded value caused the underflow.
field: QuicFrameField,
/// Absolute byte offset of the encoded field from the sequence start.
offset: usize,
/// Packet number before subtracting this field.
base: u64,
/// Decoded field value being subtracted.
value: u64,
/// Additional fixed adjustment applied after `value`.
adjustment: u64,
},
/// The frame type has no safe boundary without implementing its type-specific layout.
UnsupportedFrameType {
/// Decoded raw frame-type value.
value: u64,
/// Exact encoded frame-type width.
length: QuicVarIntLen,
/// Absolute byte offset of the frame type from the sequence start.
offset: usize,
},
}
impl fmt::Display for QuicFrameParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::EmptySequence => write!(f, "QUIC plaintext frame sequence is empty"),
Self::FrameType { offset, error } => write!(
f,
"QUIC frame type at offset {offset} cannot be parsed: {error}"
),
Self::Field {
field,
offset,
error,
} => write!(
f,
"QUIC frame {field:?} field at offset {offset} cannot be parsed: {error}"
),
Self::FieldValueOutOfRange {
field,
offset,
value,
maximum,
} => write!(
f,
"QUIC frame {field:?} field at offset {offset} has value {value}, exceeding maximum {maximum}"
),
Self::FieldValueExceedsField {
field,
offset,
value,
maximum_field,
maximum,
} => write!(
f,
"QUIC frame {field:?} field at offset {offset} has value {value}, exceeding {maximum_field:?} value {maximum}"
),
Self::FieldRangeOutOfRange {
field,
offset,
start,
length,
maximum,
} => write!(
f,
"QUIC frame {field:?} range at offset {offset} has start {start} plus length {length}, exceeding maximum end {maximum}"
),
Self::LengthNotRepresentable {
field,
offset,
value,
} => write!(
f,
"QUIC frame {field:?} length at offset {offset} has unrepresentable value {value}"
),
Self::ImplicitLengthNotRepresentable {
field,
offset,
length,
} => write!(
f,
"QUIC frame {field:?} implicit length at offset {offset} cannot represent native length {length} as u64"
),
Self::LengthOverflow {
field,
offset,
length,
} => write!(
f,
"QUIC frame {field:?} bounded field at offset {offset} overflows with length {length}"
),
Self::IncompleteBytes {
field,
offset,
required,
available,
} => write!(
f,
"QUIC frame {field:?} bytes at offset {offset} are incomplete: need {required} bytes, have {available}"
),
Self::EmptyField { field, offset } => write!(
f,
"QUIC frame {field:?} field at offset {offset} must be nonempty"
),
Self::AckRangeUnderflow {
field,
offset,
base,
value,
adjustment,
} => write!(
f,
"QUIC ACK {field:?} field at offset {offset} underflows: {base} minus {value} minus {adjustment}"
),
Self::UnsupportedFrameType {
value,
length,
offset,
} => write!(
f,
"QUIC frame type {value} at offset {offset} with encoded width {} is unsupported",
length.byte_len()
),
}
}
}