in quic/codec/Decode.cpp [711:817]
QuicFrame parseFrame(
BufQueue& queue,
const PacketHeader& header,
const CodecParameters& params) {
folly::io::Cursor cursor(queue.front());
auto frameTypeInt = decodeQuicInteger(cursor);
if (!frameTypeInt) {
throw QuicTransportException(
"Invalid frame-type field", TransportErrorCode::FRAME_ENCODING_ERROR);
}
queue.trimStart(cursor - queue.front());
bool consumedQueue = false;
bool error = false;
SCOPE_EXIT {
if (consumedQueue || error) {
return;
}
queue.trimStart(cursor - queue.front());
};
cursor.reset(queue.front());
FrameType frameType = static_cast<FrameType>(frameTypeInt->first);
try {
switch (frameType) {
case FrameType::PADDING:
return QuicFrame(decodePaddingFrame(cursor));
case FrameType::PING:
return QuicFrame(decodePingFrame(cursor));
case FrameType::ACK:
return QuicFrame(decodeAckFrame(cursor, header, params));
case FrameType::ACK_ECN:
return QuicFrame(decodeAckFrameWithECN(cursor, header, params));
case FrameType::RST_STREAM:
return QuicFrame(decodeRstStreamFrame(cursor));
case FrameType::STOP_SENDING:
return QuicFrame(decodeStopSendingFrame(cursor));
case FrameType::CRYPTO_FRAME:
return QuicFrame(decodeCryptoFrame(cursor));
case FrameType::NEW_TOKEN:
return QuicFrame(decodeNewTokenFrame(cursor));
case FrameType::STREAM:
case FrameType::STREAM_FIN:
case FrameType::STREAM_LEN:
case FrameType::STREAM_LEN_FIN:
case FrameType::STREAM_OFF:
case FrameType::STREAM_OFF_FIN:
case FrameType::STREAM_OFF_LEN:
case FrameType::STREAM_OFF_LEN_FIN:
consumedQueue = true;
return QuicFrame(
decodeStreamFrame(queue, StreamTypeField(frameTypeInt->first)));
case FrameType::MAX_DATA:
return QuicFrame(decodeMaxDataFrame(cursor));
case FrameType::MAX_STREAM_DATA:
return QuicFrame(decodeMaxStreamDataFrame(cursor));
case FrameType::MAX_STREAMS_BIDI:
return QuicFrame(decodeBiDiMaxStreamsFrame(cursor));
case FrameType::MAX_STREAMS_UNI:
return QuicFrame(decodeUniMaxStreamsFrame(cursor));
case FrameType::DATA_BLOCKED:
return QuicFrame(decodeDataBlockedFrame(cursor));
case FrameType::STREAM_DATA_BLOCKED:
return QuicFrame(decodeStreamDataBlockedFrame(cursor));
case FrameType::STREAMS_BLOCKED_BIDI:
return QuicFrame(decodeBiDiStreamsBlockedFrame(cursor));
case FrameType::STREAMS_BLOCKED_UNI:
return QuicFrame(decodeUniStreamsBlockedFrame(cursor));
case FrameType::NEW_CONNECTION_ID:
return QuicFrame(decodeNewConnectionIdFrame(cursor));
case FrameType::RETIRE_CONNECTION_ID:
return QuicFrame(decodeRetireConnectionIdFrame(cursor));
case FrameType::PATH_CHALLENGE:
return QuicFrame(decodePathChallengeFrame(cursor));
case FrameType::PATH_RESPONSE:
return QuicFrame(decodePathResponseFrame(cursor));
case FrameType::CONNECTION_CLOSE:
return QuicFrame(decodeConnectionCloseFrame(cursor));
case FrameType::CONNECTION_CLOSE_APP_ERR:
return QuicFrame(decodeApplicationClose(cursor));
case FrameType::HANDSHAKE_DONE:
return QuicFrame(decodeHandshakeDoneFrame(cursor));
case FrameType::DATAGRAM: {
consumedQueue = true;
return QuicFrame(decodeDatagramFrame(queue, false /* hasLen */));
}
case FrameType::DATAGRAM_LEN: {
consumedQueue = true;
return QuicFrame(decodeDatagramFrame(queue, true /* hasLen */));
}
case FrameType::KNOB:
return QuicFrame(decodeKnobFrame(cursor));
case FrameType::ACK_FREQUENCY:
return QuicFrame(decodeAckFrequencyFrame(cursor));
}
} catch (const std::exception&) {
error = true;
throw QuicTransportException(
folly::to<std::string>(
"Frame format invalid, type=", frameTypeInt->first),
TransportErrorCode::FRAME_ENCODING_ERROR,
frameType);
}
error = true;
throw QuicTransportException(
folly::to<std::string>("Unknown frame, type=", frameTypeInt->first),
TransportErrorCode::FRAME_ENCODING_ERROR,
frameType);
}