1use quiche::h3::frame::Frame as QFrame;
30use quiche::h3::Error as H3Error;
31use quiche::h3::Result;
32use quiche::Connection;
33
34use crate::frame::H3iFrame;
35
36const MAX_STREAM_STATE_SIZE: usize = 2_000_000;
38
39#[derive(Debug, Default, PartialEq, Eq)]
40enum FrameState {
41 #[default]
42 Type,
43 Len,
44 Val,
45}
46
47#[derive(Debug, Eq, PartialEq)]
48pub enum InterruptCause {
50 FinBit,
51 ResetStream(u64),
52}
53
54#[derive(Debug, Eq, PartialEq)]
55pub enum FrameParseResult {
57 Retry,
62 FrameParsed { h3i_frame: H3iFrame, fin: bool },
65 Interrupted(InterruptCause),
68}
69
70pub(crate) struct FrameParser {
79 ty: Option<u64>,
80 len: Option<u64>,
81
82 stream_id: u64,
83
84 curr_state: FrameState,
85 state_buf: Vec<u8>,
86 state_offset: usize,
87 state_len: usize,
88}
89
90impl FrameParser {
91 pub(crate) fn new(stream_id: u64) -> Self {
92 Self {
93 stream_id,
94 ..Default::default()
95 }
96 }
97
98 pub(crate) fn try_parse_frame(
119 &mut self, qconn: &mut Connection,
120 ) -> Result<FrameParseResult> {
121 loop {
122 let (len, fin) = match self.try_fill_buffer(qconn, self.stream_id) {
123 Ok((l, f)) => (l, f),
124 Err(H3Error::TransportError(quiche::Error::StreamReset(err))) =>
125 return Ok(FrameParseResult::Interrupted(
126 InterruptCause::ResetStream(err),
127 )),
128 Err(e) => return Err(e),
129 };
130
131 log::trace!(
132 "{} stream={} read bytes={len:?}",
133 qconn.trace_id(),
134 self.stream_id
135 );
136
137 if fin && self.frame_incomplete() {
138 return Ok(FrameParseResult::Interrupted(InterruptCause::FinBit));
139 };
140
141 match self.curr_state {
142 FrameState::Type => {
143 let Ok(varint) = self.try_consume_varint() else {
144 return Ok(FrameParseResult::Retry);
147 };
148
149 self.set_frame_type(varint)?;
150 self.state_transition(FrameState::Len, 1)?;
151 },
152 FrameState::Len => {
153 let Ok(varint) = self.try_consume_varint() else {
154 return Ok(FrameParseResult::Retry);
157 };
158
159 self.set_frame_len(varint)?;
160 self.state_transition(
161 FrameState::Val,
162 self.len.expect("frame len is not set") as usize,
163 )?;
164 },
165 FrameState::Val => {
166 if self.state_buffer_complete() {
167 let h3i_frame = self.build_h3i_frame()?;
168 let ty = match self.ty.unwrap() {
170 0x0 => "DATA".to_string(),
171 0x1 => "HEADERS".to_string(),
172 0x3 => "CANCEL_PUSH".to_string(),
173 0x4 => "SETTINGS".to_string(),
174 0x5 => "PUSH_PROMISE".to_string(),
175 0x7 => "GOAWAY".to_string(),
176 0xd => "MAX_PUSH_AWAY".to_string(),
177 _ => format!("UNKNOWN val={}", self.ty.unwrap()),
178 };
179 log::info!(
180 "{} stream={} frame rx ty={} len={}",
181 qconn.trace_id(),
182 self.stream_id,
183 ty,
184 self.len.unwrap()
185 );
186
187 *self = Self::new(self.stream_id);
189 return Ok(FrameParseResult::FrameParsed {
190 h3i_frame,
191 fin,
192 });
193 };
194
195 return Err(H3Error::TransportError(quiche::Error::Done));
199 },
200 }
201 }
202 }
203
204 fn frame_incomplete(&self) -> bool {
205 !self.state_buf.is_empty() && !self.state_buffer_complete()
206 }
207
208 fn try_fill_buffer(
209 &mut self, qconn: &mut Connection, stream_id: u64,
210 ) -> Result<(usize, bool)> {
211 if self.state_buffer_complete() {
212 return Ok((0, qconn.stream_finished(stream_id)));
213 }
214
215 let buf = &mut self.state_buf[self.state_offset..self.state_len];
216 match qconn.stream_recv(stream_id, buf) {
217 Ok((len, fin)) => {
218 self.state_offset += len;
219 Ok((len, fin))
220 },
221 Err(e) => Err(H3Error::TransportError(e)),
222 }
223 }
224
225 fn try_consume_varint(&mut self) -> Result<u64> {
226 if self.state_offset == 1 {
227 self.state_len = octets::varint_parse_len(self.state_buf[0]);
228 self.state_buf.resize(self.state_len, 0);
229 }
230
231 if !self.state_buffer_complete() {
232 return Err(H3Error::TransportError(quiche::Error::Done));
233 }
234
235 let varint = octets::Octets::with_slice(&self.state_buf).get_varint()?;
236 Ok(varint)
237 }
238
239 fn state_buffer_complete(&self) -> bool {
240 self.state_offset == self.state_len
241 }
242
243 fn state_transition(
244 &mut self, new_state: FrameState, expected_len: usize,
245 ) -> Result<()> {
246 if expected_len > MAX_STREAM_STATE_SIZE {
250 return Err(quiche::h3::Error::ExcessiveLoad);
251 }
252
253 self.state_buf.resize(expected_len, 0);
254 self.curr_state = new_state;
255 self.state_offset = 0;
256 self.state_len = expected_len;
257
258 Ok(())
259 }
260
261 fn set_frame_type(&mut self, ty: u64) -> Result<()> {
262 self.ty = Some(ty);
263 self.state_transition(FrameState::Len, 1)?;
264
265 Ok(())
266 }
267
268 fn set_frame_len(&mut self, len: u64) -> Result<()> {
269 self.len = Some(len);
270 self.state_transition(FrameState::Val, len as usize)?;
271
272 Ok(())
273 }
274
275 fn build_h3i_frame(&mut self) -> Result<H3iFrame> {
276 let qframe = QFrame::from_bytes(
277 self.ty.expect("frame ty not set"),
278 self.len.expect("frame len not set"),
279 &self.state_buf,
280 )?;
281
282 match qframe {
283 QFrame::Headers { ref header_block } => {
284 let mut qpack_decoder = quiche::h3::qpack::Decoder::new();
285 let headers =
286 qpack_decoder.decode(header_block, u64::MAX).unwrap();
287
288 Ok(H3iFrame::Headers(headers.into()))
289 },
290 _ => Ok(qframe.into()),
291 }
292 }
293}
294
295impl std::fmt::Debug for FrameParser {
296 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
297 let s = format!(
298 "FrameParser {{ stream: {}, type: {:?}, length: {:?} }}",
299 self.stream_id, self.ty, self.len,
300 );
301
302 write!(f, "{}", s)
303 }
304}
305
306impl Default for FrameParser {
307 fn default() -> Self {
308 Self {
309 ty: None,
310 len: None,
311 curr_state: FrameState::default(),
312 stream_id: 0,
313 state_buf: vec![0],
314 state_offset: 0,
315 state_len: 1,
316 }
317 }
318}
319
320#[cfg(test)]
321mod tests {
322 use super::*;
323 use quiche::h3::frame::Frame;
324 use quiche::h3::testing::*;
325
326 fn session() -> Result<Session> {
327 Session::new()
328 }
329
330 #[test]
334 fn simple_case() {
335 let mut s = session().unwrap();
336 s.handshake().unwrap();
337
338 let mut parser = FrameParser::new(0);
339 let expected = Frame::Data {
340 payload: vec![1, 2, 3, 4, 5],
341 };
342 s.send_frame_client(expected.clone(), 0, true)
343 .expect("first");
344
345 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
346 assert_eq!(res, FrameParseResult::FrameParsed {
347 h3i_frame: H3iFrame::QuicheH3(expected),
348 fin: true
349 });
350 }
351
352 #[test]
353 fn type_precedes_split() {
354 let mut s = session().unwrap();
355 s.handshake().unwrap();
356
357 let mut parser = FrameParser::new(0);
358 let expected = Frame::Data {
359 payload: vec![10; 10],
360 };
361 s.send_arbitrary_stream_data_client(&[0], 0, false)
362 .expect("first");
363 let res = parser.try_parse_frame(&mut s.pipe.server);
364 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
365
366 s.send_arbitrary_stream_data_client(&[10; 11], 0, true)
367 .expect("second");
368 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
369 assert_eq!(res, FrameParseResult::FrameParsed {
370 h3i_frame: H3iFrame::QuicheH3(expected),
371 fin: true
372 });
373 }
374
375 #[test]
376 fn type_multiple_bytes() {
377 let mut s = session().unwrap();
378 s.handshake().unwrap();
379
380 let mut parser = FrameParser::new(0);
381 let expected = Frame::Unknown {
382 raw_type: 64,
383 payload: vec![1, 2, 3, 4, 5],
384 };
385 s.send_arbitrary_stream_data_client(&[64, 64, 5, 1, 2, 3, 4, 5], 0, true)
386 .expect("first");
387
388 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
389 assert_eq!(res, FrameParseResult::Retry);
390
391 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
392 assert_eq!(res, FrameParseResult::FrameParsed {
393 h3i_frame: H3iFrame::QuicheH3(expected),
394 fin: true
395 });
396 }
397
398 #[test]
399 fn type_multiple_buffers() {
400 let mut s = session().unwrap();
401 s.handshake().unwrap();
402
403 let mut parser = FrameParser::new(0);
404 let expected = Frame::Unknown {
405 raw_type: 64,
406 payload: vec![1, 2, 3, 4, 5],
407 };
408
409 s.send_arbitrary_stream_data_client(&[64], 0, false)
410 .expect("first");
411 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
412 assert_eq!(res, FrameParseResult::Retry);
413
414 let res = parser.try_parse_frame(&mut s.pipe.server);
415 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
416
417 s.send_arbitrary_stream_data_client(&[64, 5, 1, 2, 3, 4, 5], 0, true)
418 .expect("second");
419 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
420 assert_eq!(res, FrameParseResult::FrameParsed {
421 h3i_frame: H3iFrame::QuicheH3(expected),
422 fin: true
423 });
424 }
425
426 #[test]
427 fn type_multiple_buffers_precedes_split() {
428 let mut s = session().unwrap();
429 s.handshake().unwrap();
430
431 let mut parser = FrameParser::default();
432 let expected = Frame::Unknown {
433 raw_type: 64,
434 payload: vec![1, 2, 3, 4, 5],
435 };
436
437 s.send_arbitrary_stream_data_client(&[64, 64], 0, false)
438 .expect("first");
439 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
440 assert_eq!(res, FrameParseResult::Retry);
441
442 let res = parser.try_parse_frame(&mut s.pipe.server);
443 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
444
445 s.send_arbitrary_stream_data_client(&[5, 1, 2, 3, 4, 5], 0, false)
446 .expect("second");
447 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
448 assert_eq!(res, FrameParseResult::FrameParsed {
449 h3i_frame: H3iFrame::QuicheH3(expected),
450 fin: false
451 });
452 }
453
454 #[test]
455 fn len_precedes_split() {
456 let mut s = session().unwrap();
457 s.handshake().unwrap();
458
459 let mut parser = FrameParser::default();
460 let expected = Frame::Data {
461 payload: vec![57; 10],
462 };
463
464 s.send_arbitrary_stream_data_client(&[0, 10], 0, false)
465 .expect("first");
466 let res = parser.try_parse_frame(&mut s.pipe.server);
467 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
468
469 s.send_arbitrary_stream_data_client(&[57; 10], 0, true)
470 .expect("second");
471 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
472 assert_eq!(res, FrameParseResult::FrameParsed {
473 h3i_frame: H3iFrame::QuicheH3(expected),
474 fin: true
475 });
476 }
477
478 #[test]
479 fn len_multiple_bytes() {
480 let mut s = session().unwrap();
481 s.handshake().unwrap();
482
483 let mut b = vec![0, 64, 64];
484 let mut payload = vec![0; 64];
485 let mut parser = FrameParser::default();
486 let expected = Frame::Data {
487 payload: payload.clone(),
488 };
489 b.append(&mut payload);
490
491 s.send_arbitrary_stream_data_client(&b, 0, true)
492 .expect("first");
493 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
494 assert_eq!(res, FrameParseResult::Retry);
495
496 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
497 assert_eq!(res, FrameParseResult::FrameParsed {
498 h3i_frame: H3iFrame::QuicheH3(expected),
499 fin: true
500 });
501 }
502
503 #[test]
504 fn len_multiple_buffers() {
505 let mut s = session().unwrap();
506 s.handshake().unwrap();
507
508 let mut parser = FrameParser::default();
509 let expected = Frame::Data {
510 payload: vec![64; 64],
511 };
512
513 s.send_arbitrary_stream_data_client(&[0, 64], 0, false)
514 .expect("first");
515 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
516 assert_eq!(res, FrameParseResult::Retry);
517
518 let res = parser.try_parse_frame(&mut s.pipe.server);
519 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
520
521 s.send_arbitrary_stream_data_client(&[64; 65], 0, true)
522 .expect("second");
523 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
524 assert_eq!(res, FrameParseResult::FrameParsed {
525 h3i_frame: H3iFrame::QuicheH3(expected),
526 fin: true
527 });
528 }
529
530 #[test]
531 fn len_multiple_buffers_precedes_split() {
532 let mut s = session().unwrap();
533 s.handshake().unwrap();
534
535 let mut parser = FrameParser::default();
536 let expected = Frame::Data {
537 payload: vec![0; 64],
538 };
539
540 s.send_arbitrary_stream_data_client(&[0, 64, 64], 0, false)
541 .expect("first");
542 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
543 assert_eq!(res, FrameParseResult::Retry);
544
545 let res = parser.try_parse_frame(&mut s.pipe.server);
546 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
547
548 s.send_arbitrary_stream_data_client(&[0; 64], 0, true)
549 .expect("second");
550 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
551 assert_eq!(res, FrameParseResult::FrameParsed {
552 h3i_frame: H3iFrame::QuicheH3(expected),
553 fin: true
554 });
555 }
556
557 #[test]
558 fn no_val() {
559 let mut s = session().unwrap();
560 s.handshake().unwrap();
561
562 let mut parser = FrameParser::default();
563 let first = Frame::Unknown {
564 raw_type: 64,
565 payload: vec![],
566 };
567 let second = Frame::Data {
568 payload: vec![1, 2, 3],
569 };
570
571 s.send_arbitrary_stream_data_client(&[64, 64, 0, 0, 3, 1, 2, 3], 0, true)
572 .expect("first");
573 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
574 assert_eq!(res, FrameParseResult::Retry);
575
576 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
577 assert_eq!(res, FrameParseResult::FrameParsed {
578 h3i_frame: H3iFrame::QuicheH3(first),
579 fin: false
580 });
581
582 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
583 assert_eq!(res, FrameParseResult::FrameParsed {
584 h3i_frame: H3iFrame::QuicheH3(second),
585 fin: true
586 });
587 }
588
589 #[test]
590 fn val_multiple_buffers() {
591 let mut s = session().unwrap();
592 s.handshake().unwrap();
593
594 let mut parser = FrameParser::default();
595 let expected = Frame::Data {
596 payload: vec![1, 2, 3, 4, 5],
597 };
598
599 s.send_arbitrary_stream_data_client(&[0, 5, 1], 0, false)
600 .expect("first");
601 let res = parser.try_parse_frame(&mut s.pipe.server);
602 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
603
604 s.send_arbitrary_stream_data_client(&[2, 3, 4, 5], 0, false)
605 .expect("second");
606 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
607 assert_eq!(res, FrameParseResult::FrameParsed {
608 h3i_frame: H3iFrame::QuicheH3(expected),
609 fin: false
610 });
611 }
612
613 #[test]
614 fn val_doesnt_extend_to_buffer_end() {
615 let mut s = session().unwrap();
616 s.handshake().unwrap();
617
618 let mut parser = FrameParser::default();
619 let expected = Frame::Data {
620 payload: vec![1, 2, 3, 4, 5],
621 };
622
623 s.send_arbitrary_stream_data_client(&[0, 5, 1, 2, 3, 4, 5, 0], 0, true)
624 .expect("first");
625 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
626 assert_eq!(res, FrameParseResult::FrameParsed {
627 h3i_frame: H3iFrame::QuicheH3(expected),
628 fin: false
629 });
630
631 let res = parser.try_parse_frame(&mut s.pipe.server);
632 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
633 assert_eq!(parser.ty, Some(0));
634 assert_eq!(parser.curr_state, FrameState::Len);
635 }
636
637 #[test]
638 fn multiple_frames_in_buffer() {
639 let mut s = session().unwrap();
640 s.handshake().unwrap();
641
642 let mut parser = FrameParser::default();
643 let first = Frame::Data {
644 payload: vec![1, 2, 3],
645 };
646 let second = Frame::Data {
647 payload: vec![1, 2, 3, 4],
648 };
649
650 s.send_arbitrary_stream_data_client(
651 &[0, 3, 1, 2, 3, 0, 4, 1, 2, 3, 4],
652 0,
653 true,
654 )
655 .expect("first");
656 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
657 assert_eq!(res, FrameParseResult::FrameParsed {
658 h3i_frame: H3iFrame::QuicheH3(first),
659 fin: false
660 });
661 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
662 assert_eq!(res, FrameParseResult::FrameParsed {
663 h3i_frame: H3iFrame::QuicheH3(second),
664 fin: true
665 });
666 }
667
668 #[test]
669 fn multiple_frames_multiple_buffers() {
670 let mut s = session().unwrap();
671 s.handshake().unwrap();
672
673 let mut parser = FrameParser::default();
674 let first = Frame::Data {
675 payload: vec![1, 2, 3],
676 };
677 let second = Frame::Data {
678 payload: vec![1, 2, 3, 4],
679 };
680 let third = Frame::Data {
681 payload: vec![1, 2, 3],
682 };
683
684 s.send_arbitrary_stream_data_client(
685 &[0, 3, 1, 2, 3, 0, 4, 1, 2, 3, 4, 0, 3, 1],
686 0,
687 false,
688 )
689 .expect("first");
690 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
691 assert_eq!(res, FrameParseResult::FrameParsed {
692 h3i_frame: H3iFrame::QuicheH3(first),
693 fin: false
694 });
695 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
696 assert_eq!(res, FrameParseResult::FrameParsed {
697 h3i_frame: H3iFrame::QuicheH3(second),
698 fin: false
699 });
700
701 let res = parser.try_parse_frame(&mut s.pipe.server);
702 assert_eq!(res, Err(H3Error::TransportError(quiche::Error::Done)));
703 assert_eq!(parser.ty, Some(0));
704 assert_eq!(parser.len, Some(3));
705 assert_eq!(parser.state_buf, vec![1, 0, 0]);
706
707 s.send_arbitrary_stream_data_client(&[2, 3], 0, true)
708 .expect("second");
709 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
710 assert_eq!(res, FrameParseResult::FrameParsed {
711 h3i_frame: H3iFrame::QuicheH3(third),
712 fin: true
713 });
714 }
715
716 #[test]
717 fn multiple_frames_nonzero_stream() {
718 let mut s = session().unwrap();
719 s.handshake().unwrap();
720
721 let mut parser = FrameParser::default();
722 let first = Frame::Data {
723 payload: vec![1, 2, 3],
724 };
725 let second = Frame::Data {
726 payload: vec![1, 2, 3, 4, 5],
727 };
728
729 s.send_arbitrary_stream_data_client(&[0, 3, 1, 2, 3], 0, true)
730 .expect("first");
731 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
732 assert_eq!(res, FrameParseResult::FrameParsed {
733 h3i_frame: H3iFrame::QuicheH3(first.clone()),
734 fin: true
735 });
736
737 parser = FrameParser::new(4);
738 s.send_arbitrary_stream_data_client(&[0, 5, 1, 2, 3, 4, 5], 4, false)
739 .expect("second");
740 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
741 assert_eq!(res, FrameParseResult::FrameParsed {
742 h3i_frame: H3iFrame::QuicheH3(second),
743 fin: false
744 });
745
746 s.send_arbitrary_stream_data_client(&[0, 3, 1, 2, 3], 4, true)
747 .expect("third");
748 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
749 assert_eq!(res, FrameParseResult::FrameParsed {
750 h3i_frame: H3iFrame::QuicheH3(first),
751 fin: true
752 });
753 }
754
755 #[test]
756 fn interrupted() {
757 let mut s = session().unwrap();
758 s.handshake().unwrap();
759
760 let mut parser = FrameParser::default();
761 s.send_arbitrary_stream_data_client(&[0, 3, 1, 2], 0, true)
762 .expect("send");
763
764 assert_eq!(
765 parser.try_parse_frame(&mut s.pipe.server),
766 Ok(FrameParseResult::Interrupted(InterruptCause::FinBit))
767 );
768 }
769
770 #[test]
771 fn stream_reset() {
772 let mut s = session().unwrap();
773 s.handshake().unwrap();
774
775 let mut parser = FrameParser::default();
776 let expected = Frame::Data {
777 payload: vec![1, 2, 3, 4, 5],
778 };
779
780 s.send_arbitrary_stream_data_client(&[0, 5, 1, 2, 3, 4, 5], 0, false)
781 .expect("first");
782 let res = parser.try_parse_frame(&mut s.pipe.server).unwrap();
783 assert_eq!(res, FrameParseResult::FrameParsed {
784 h3i_frame: H3iFrame::QuicheH3(expected),
785 fin: false
786 });
787
788 s.pipe
789 .client
790 .stream_shutdown(0, quiche::Shutdown::Write, 0)
791 .expect("shutdown");
792 s.pipe.advance().expect("advance");
793 assert_eq!(
794 parser.try_parse_frame(&mut s.pipe.server),
795 Ok(FrameParseResult::Interrupted(InterruptCause::ResetStream(
796 0
797 )))
798 );
799 }
800}