@@ -16,6 +16,76 @@ void MoQCodec::onIngressStart(std::unique_ptr<folly::IOBuf> data) {
1616 ingress_.append (std::move (data));
1717}
1818
19+ folly::Expected<folly::Unit, ErrorCode> MoQControlCodec::parseFrameHeaderType (
20+ folly::io::Cursor& cursor,
21+ size_t & remainingLength) {
22+ auto type = quic::follyutils::decodeQuicInteger (cursor);
23+ if (!type) {
24+ XLOG (DBG6 ) << __func__ << " underflow" ;
25+ return folly::makeUnexpected (ErrorCode::PARSE_UNDERFLOW );
26+ }
27+ curFrameType_ = FrameType (type->first );
28+ remainingLength -= type->second ;
29+ if (!checkFrameAllowed (curFrameType_)) {
30+ XLOG (DBG4 ) << " Frame not allowed: 0x" << std::setfill (' 0' )
31+ << std::setw (sizeof (uint64_t ) * 2 ) << std::hex
32+ << (uint64_t )curFrameType_ << " on streamID=" << streamId_;
33+ return folly::makeUnexpected (ErrorCode::PROTOCOL_VIOLATION );
34+ }
35+ if (callback_) {
36+ callback_->onFrame (curFrameType_);
37+ }
38+ parseState_ = ParseState::FRAME_LENGTH ;
39+ return folly::unit;
40+ }
41+
42+ folly::Expected<folly::Unit, ErrorCode> MoQControlCodec::parseFrameLength (
43+ folly::io::Cursor& cursor,
44+ size_t & remainingLength) {
45+ uint64_t length = 0 ;
46+ size_t bytesParsed = 0 ;
47+
48+ bool parseFrameLengthAs16bit = false ;
49+ if (curFrameType_ == FrameType::CLIENT_SETUP ||
50+ curFrameType_ == FrameType::SERVER_SETUP ) {
51+ parseFrameLengthAs16bit = true ;
52+ } else if (
53+ curFrameType_ == FrameType::LEGACY_CLIENT_SETUP ||
54+ curFrameType_ == FrameType::LEGACY_SERVER_SETUP ) {
55+ parseFrameLengthAs16bit = false ;
56+ } else if (!moqFrameParser_.getVersion ().has_value ()) {
57+ XLOG (DBG4 )
58+ << " Received a non-setup frame before knowing the negotiated version" ;
59+ return folly::makeUnexpected (ErrorCode::PROTOCOL_VIOLATION );
60+ } else {
61+ parseFrameLengthAs16bit =
62+ (getDraftMajorVersion (*moqFrameParser_.getVersion ()) >= 11 );
63+ }
64+
65+ if (parseFrameLengthAs16bit) {
66+ if (remainingLength < 2 ) {
67+ XLOG (DBG6 ) << __func__ << " underflow" ;
68+ return folly::makeUnexpected (ErrorCode::PARSE_UNDERFLOW );
69+ }
70+ // Parse the length as a 16 bit integer
71+ length = cursor.readBE <uint16_t >();
72+ bytesParsed = 2 ;
73+ } else {
74+ // Parse the length as a varint
75+ auto decodeResult = quic::follyutils::decodeQuicInteger (cursor);
76+ if (!decodeResult) {
77+ XLOG (DBG6 ) << __func__ << " underflow" ;
78+ return folly::makeUnexpected (ErrorCode::PARSE_UNDERFLOW );
79+ }
80+ length = decodeResult->first ;
81+ bytesParsed = decodeResult->second ;
82+ }
83+ curFrameLength_ = length;
84+ remainingLength -= bytesParsed;
85+ parseState_ = ParseState::FRAME_PAYLOAD ;
86+ return folly::unit;
87+ }
88+
1989MoQCodec::ParseResult MoQControlCodec::onIngress (
2090 std::unique_ptr<folly::IOBuf> data,
2191 bool eom) {
@@ -25,73 +95,19 @@ MoQCodec::ParseResult MoQControlCodec::onIngress(
2595 while (!connError_ && remainingLength > 0 ) {
2696 switch (parseState_) {
2797 case ParseState::FRAME_HEADER_TYPE : {
28- auto type = quic::follyutils::decodeQuicInteger (cursor);
29- if (!type) {
30- XLOG (DBG6 ) << __func__ << " underflow" ;
31- connError_ = ErrorCode::PARSE_UNDERFLOW ;
32- break ;
33- }
34- curFrameType_ = FrameType (type->first );
35- remainingLength -= type->second ;
36- auto res = checkFrameAllowed (curFrameType_);
37- if (!res) {
38- XLOG (DBG4 ) << " Frame not allowed: 0x" << std::setfill (' 0' )
39- << std::setw (sizeof (uint64_t ) * 2 ) << std::hex
40- << (uint64_t )curFrameType_ << " on streamID=" << streamId_;
41- connError_.emplace (ErrorCode::PROTOCOL_VIOLATION );
98+ auto res = parseFrameHeaderType (cursor, remainingLength);
99+ if (res.hasError ()) {
100+ connError_ = res.error ();
42101 break ;
43102 }
44- if (callback_) {
45- callback_->onFrame (curFrameType_);
46- }
47- parseState_ = ParseState::FRAME_LENGTH ;
48103 [[fallthrough]] ;
49104 }
50105 case ParseState::FRAME_LENGTH : {
51- uint64_t length = 0 ;
52- size_t bytesParsed = 0 ;
53-
54- bool parseFrameLengthAs16bit = false ;
55- if (curFrameType_ == FrameType::CLIENT_SETUP ||
56- curFrameType_ == FrameType::SERVER_SETUP ) {
57- parseFrameLengthAs16bit = true ;
58- } else if (
59- curFrameType_ == FrameType::LEGACY_CLIENT_SETUP ||
60- curFrameType_ == FrameType::LEGACY_SERVER_SETUP ) {
61- parseFrameLengthAs16bit = false ;
62- } else if (!moqFrameParser_.getVersion ().has_value ()) {
63- XLOG (DBG4 )
64- << " Received a non-setup frame before knowing the negotiated version" ;
65- connError_.emplace (ErrorCode::PROTOCOL_VIOLATION );
106+ auto res = parseFrameLength (cursor, remainingLength);
107+ if (res.hasError ()) {
108+ connError_ = res.error ();
66109 break ;
67- } else {
68- parseFrameLengthAs16bit =
69- (getDraftMajorVersion (*moqFrameParser_.getVersion ()) >= 11 );
70- }
71-
72- if (parseFrameLengthAs16bit) {
73- if (remainingLength < 2 ) {
74- XLOG (DBG6 ) << __func__ << " underflow" ;
75- connError_ = ErrorCode::PARSE_UNDERFLOW ;
76- break ;
77- }
78- // Parse the length as a 16 bit integer
79- length = cursor.readBE <uint16_t >();
80- bytesParsed = 2 ;
81- } else {
82- // Parse the length as a varint
83- auto decodeResult = quic::follyutils::decodeQuicInteger (cursor);
84- if (!decodeResult) {
85- XLOG (DBG6 ) << __func__ << " underflow" ;
86- connError_ = ErrorCode::PARSE_UNDERFLOW ;
87- break ;
88- }
89- length = decodeResult->first ;
90- bytesParsed = decodeResult->second ;
91110 }
92- curFrameLength_ = length;
93- remainingLength -= bytesParsed;
94- parseState_ = ParseState::FRAME_PAYLOAD ;
95111 [[fallthrough]] ;
96112 }
97113 case ParseState::FRAME_PAYLOAD : {
0 commit comments