gfe-relnote: In QUIC, enable multiple packet number support in QuicFramer. Not used yet. Not protected.
PiperOrigin-RevId: 239686851
Change-Id: Ia2bb33e823fa4d80ad11366f8bc58079e39eeb47
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 3e4f921..4640d39 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -316,6 +316,35 @@
return PACKET_4BYTE_PACKET_NUMBER;
}
+// Used to get packet number space before packet gets decrypted.
+PacketNumberSpace GetPacketNumberSpace(const QuicPacketHeader& header) {
+ switch (header.form) {
+ case GOOGLE_QUIC_PACKET:
+ QUIC_BUG << "Try to get packet number space of Google QUIC packet";
+ break;
+ case IETF_QUIC_SHORT_HEADER_PACKET:
+ return APPLICATION_DATA;
+ case IETF_QUIC_LONG_HEADER_PACKET:
+ switch (header.long_packet_type) {
+ case INITIAL:
+ return INITIAL_DATA;
+ case HANDSHAKE:
+ return HANDSHAKE_DATA;
+ case ZERO_RTT_PROTECTED:
+ return APPLICATION_DATA;
+ case VERSION_NEGOTIATION:
+ case RETRY:
+ case INVALID_PACKET_TYPE:
+ QUIC_BUG << "Try to get packet number space of long header type: "
+ << QuicUtils::QuicLongHeaderTypetoString(
+ header.long_packet_type);
+ break;
+ }
+ }
+
+ return NUM_PACKET_NUMBER_SPACES;
+}
+
QuicStringPiece TruncateErrorString(QuicStringPiece error) {
if (error.length() <= kMaxErrorStringLength) {
return error;
@@ -472,7 +501,8 @@
infer_packet_header_type_from_version_(perspective ==
Perspective::IS_CLIENT),
expected_connection_id_length_(expected_connection_id_length),
- should_update_expected_connection_id_length_(false) {
+ should_update_expected_connection_id_length_(false),
+ supports_multiple_packet_number_spaces_(false) {
DCHECK(!supported_versions.empty());
version_ = supported_versions_[0];
decrypter_ = QuicMakeUnique<NullDecrypter>(perspective);
@@ -1770,7 +1800,13 @@
if (header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
header->long_packet_type != VERSION_NEGOTIATION) {
// Process packet number.
- QuicPacketNumber base_packet_number = largest_packet_number_;
+ QuicPacketNumber base_packet_number;
+ if (supports_multiple_packet_number_spaces_) {
+ base_packet_number =
+ largest_decrypted_packet_numbers_[GetPacketNumberSpace(*header)];
+ } else {
+ base_packet_number = largest_packet_number_;
+ }
uint64_t full_packet_number;
if (!ProcessAndCalculatePacketNumber(
encrypted_reader, header->packet_number_length, base_packet_number,
@@ -1831,8 +1867,9 @@
header->length_length);
size_t decrypted_length = 0;
+ EncryptionLevel decrypted_level;
if (!DecryptPayload(encrypted, associated_data, *header, decrypted_buffer,
- buffer_length, &decrypted_length)) {
+ buffer_length, &decrypted_length, &decrypted_level)) {
if (IsIetfStatelessResetPacket(*header)) {
// This is a stateless reset packet.
QuicIetfStatelessResetPacket packet(
@@ -1848,7 +1885,13 @@
// Update the largest packet number after we have decrypted the packet
// so we are confident is not attacker controlled.
- largest_packet_number_.UpdateMax(header->packet_number);
+ if (supports_multiple_packet_number_spaces_) {
+ largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_level)]
+ .UpdateMax(header->packet_number);
+ } else {
+ largest_packet_number_.UpdateMax(header->packet_number);
+ }
if (!visitor_->OnPacketHeader(*header)) {
RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
@@ -1910,8 +1953,9 @@
header->length_length);
size_t decrypted_length = 0;
+ EncryptionLevel decrypted_level;
if (!DecryptPayload(encrypted, associated_data, *header, decrypted_buffer,
- buffer_length, &decrypted_length)) {
+ buffer_length, &decrypted_length, &decrypted_level)) {
RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
set_detailed_error("Unable to decrypt payload.");
return RaiseError(QUIC_DECRYPTION_FAILURE);
@@ -1921,7 +1965,13 @@
// Update the largest packet number after we have decrypted the packet
// so we are confident is not attacker controlled.
- largest_packet_number_.UpdateMax(header->packet_number);
+ if (supports_multiple_packet_number_spaces_) {
+ largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_level)]
+ .UpdateMax(header->packet_number);
+ } else {
+ largest_packet_number_.UpdateMax(header->packet_number);
+ }
if (!visitor_->OnPacketHeader(*header)) {
// The visitor suppresses further processing of the packet.
@@ -2418,7 +2468,13 @@
bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
QuicPacketHeader* header) {
- QuicPacketNumber base_packet_number = largest_packet_number_;
+ QuicPacketNumber base_packet_number;
+ if (supports_multiple_packet_number_spaces_) {
+ base_packet_number =
+ largest_decrypted_packet_numbers_[GetPacketNumberSpace(*header)];
+ } else {
+ base_packet_number = largest_packet_number_;
+ }
uint64_t full_packet_number;
if (!ProcessAndCalculatePacketNumber(
encrypted_reader, header->packet_number_length, base_packet_number,
@@ -3959,7 +4015,8 @@
const QuicPacketHeader& header,
char* decrypted_buffer,
size_t buffer_length,
- size_t* decrypted_length) {
+ size_t* decrypted_length,
+ EncryptionLevel* decrypted_level) {
DCHECK(decrypter_ != nullptr);
bool success = decrypter_->DecryptPacket(
@@ -3967,6 +4024,7 @@
decrypted_buffer, decrypted_length, buffer_length);
if (success) {
visitor_->OnDecryptedPacket(decrypter_level_);
+ *decrypted_level = decrypter_level_;
} else if (alternative_decrypter_ != nullptr) {
if (header.nonce != nullptr) {
DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
@@ -3991,6 +4049,7 @@
}
if (success) {
visitor_->OnDecryptedPacket(alternative_decrypter_level_);
+ *decrypted_level = decrypter_level_;
if (alternative_decrypter_latch_) {
// Switch to the alternative decrypter and latch so that we cannot
// switch back.
@@ -5700,5 +5759,19 @@
infer_packet_header_type_from_version_ = true;
}
+void QuicFramer::EnableMultiplePacketNumberSpacesSupport() {
+ if (supports_multiple_packet_number_spaces_) {
+ QUIC_BUG << "Multiple packet number spaces has already been enabled";
+ return;
+ }
+ if (largest_packet_number_.IsInitialized()) {
+ QUIC_BUG << "Try to enable multiple packet number spaces support after any "
+ "packet has been received.";
+ return;
+ }
+
+ supports_multiple_packet_number_spaces_ = true;
+}
+
#undef ENDPOINT // undef for jumbo builds
} // namespace quic