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