in quic/codec/Decode.cpp [988:1065]
folly::Expected<ParsedLongHeader, TransportErrorCode> parseLongHeaderVariants(
LongHeader::Types type,
ParsedLongHeaderInvariant parsedLongHeaderInvariant,
folly::io::Cursor& cursor,
QuicNodeType nodeType) {
if (type == LongHeader::Types::Retry) {
// The integrity tag is kRetryIntegrityTagLen bytes in length, and the
// token must be at least one byte, so the remaining length must
// be > kRetryIntegrityTagLen.
if (cursor.totalLength() <= kRetryIntegrityTagLen) {
VLOG(5) << "Not enough bytes for retry token";
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
Buf token;
cursor.clone(token, cursor.totalLength() - kRetryIntegrityTagLen);
return ParsedLongHeader(
LongHeader(
type,
std::move(parsedLongHeaderInvariant.invariant),
token ? token->moveToFbString().toStdString() : std::string()),
PacketLength(0, 0));
}
// TODO Checking kMinInitialDestinationConnIdLength isn't necessary
// if this packet is in response to a retry.
if (type == LongHeader::Types::Initial && nodeType == QuicNodeType::Server &&
parsedLongHeaderInvariant.invariant.dstConnId.size() <
kMinInitialDestinationConnIdLength) {
VLOG(5)
<< "Dest Conn-Id length in client initial packet must be >= 8 bytes.";
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
Buf token;
if (type == LongHeader::Types::Initial) {
auto tokenLen = decodeQuicInteger(cursor);
if (!tokenLen) {
VLOG(5) << "Token len not found in Long header";
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
if (!cursor.canAdvance(tokenLen->first)) {
VLOG(5) << "Not enough input bytes to read input token";
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
if (tokenLen->first > 0) {
Buf tokenBuf;
// If tokenLen > token's actual length then the cursor will throw.
cursor.clone(tokenBuf, tokenLen->first);
token = std::move(tokenBuf);
}
}
auto pktLen = decodeQuicInteger(cursor);
if (!pktLen) {
VLOG(5) << "Packet len not found in Long header";
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
if (!cursor.canAdvance(pktLen->first)) {
VLOG(5) << "Not enough input bytes to read packet number";
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
size_t packetNumLen =
parsePacketNumberLength(parsedLongHeaderInvariant.initialByte);
if (!cursor.canAdvance(packetNumLen)) {
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
if (packetNumLen > kMaxPacketNumEncodingSize) {
return folly::makeUnexpected(TransportErrorCode::FRAME_ENCODING_ERROR);
}
return ParsedLongHeader(
LongHeader(
type,
std::move(parsedLongHeaderInvariant.invariant),
token ? token->moveToFbString().toStdString() : std::string()),
PacketLength(pktLen->first, pktLen->second));
}