Do not queue coalesced undecryptable packets twice

This CL adds QuicFramerVisitorInterface::OnUndecryptablePacket and uses it to send undecryptable packets from QuicFramer to QuicConnection, instead of the previous mechanism which relied on QuicFramer::ProcessPacket returning QUIC_DECRYPTION_FAILURE. The new mechanism has the following advantages:
1) It only sends the current packet, without any subsequent coalesced packets
2) It knows if the decryption failed due to a missing key, which allows us to avoid buffering packets that we know we will never be able to decrypt

This mechanism is enabled for versions that KnowsWhichDecrypterToUse() (which are v47+ || TLS, none of which are currently enabled) and when the new flag quic_framer_uses_undecryptable_upcall is true - the intent being to enable this for all versions once the flag protection process is complete.

This CL also adds QuicDataReader::FullPayload which is required to extract only this packet without further coalesced packets, and associated test.

gfe-relnote: do not queue coalesced undecryptable packets twice, protected by disabled flag gfe2_restart_flag_quic_framer_uses_undecryptable_upcall
PiperOrigin-RevId: 263658152
Change-Id: I66aca2138e353306a5cf4fa9ec259680f4115890
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 93b8575..08593da 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -1843,6 +1843,16 @@
         return true;
       }
       if (hp_removal_failed) {
+        if (GetQuicRestartFlag(quic_framer_uses_undecryptable_upcall)) {
+          QUIC_RESTART_FLAG_COUNT_N(quic_framer_uses_undecryptable_upcall, 5,
+                                    7);
+          const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
+          const bool has_decryption_key =
+              decrypter_[decryption_level] != nullptr;
+          visitor_->OnUndecryptablePacket(
+              QuicEncryptedPacket(encrypted_reader->FullPayload()),
+              decryption_level, has_decryption_key);
+        }
         set_detailed_error("Unable to decrypt header protection.");
         return RaiseError(QUIC_DECRYPTION_FAILURE);
       }
@@ -1901,6 +1911,15 @@
       visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
       return true;
     }
+    if (GetQuicRestartFlag(quic_framer_uses_undecryptable_upcall)) {
+      QUIC_RESTART_FLAG_COUNT_N(quic_framer_uses_undecryptable_upcall, 6, 7);
+      const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
+      const bool has_decryption_key = version_.KnowsWhichDecrypterToUse() &&
+                                      decrypter_[decryption_level] != nullptr;
+      visitor_->OnUndecryptablePacket(
+          QuicEncryptedPacket(encrypted_reader->FullPayload()),
+          decryption_level, has_decryption_key);
+    }
     set_detailed_error("Unable to decrypt payload.");
     RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
     return RaiseError(QUIC_DECRYPTION_FAILURE);
@@ -1979,6 +1998,16 @@
   EncryptionLevel decrypted_level;
   if (!DecryptPayload(encrypted, associated_data, *header, decrypted_buffer,
                       buffer_length, &decrypted_length, &decrypted_level)) {
+    if (GetQuicRestartFlag(quic_framer_uses_undecryptable_upcall)) {
+      QUIC_RESTART_FLAG_COUNT_N(quic_framer_uses_undecryptable_upcall, 7, 7);
+      const EncryptionLevel decryption_level = decrypter_level_;
+      // This version uses trial decryption so we always report to our visitor
+      // that we are not certain we have the correct decryption key.
+      const bool has_decryption_key = false;
+      visitor_->OnUndecryptablePacket(
+          QuicEncryptedPacket(encrypted_reader->FullPayload()),
+          decryption_level, has_decryption_key);
+    }
     RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
     set_detailed_error("Unable to decrypt payload.");
     return RaiseError(QUIC_DECRYPTION_FAILURE);
@@ -4173,6 +4202,9 @@
   DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
   DCHECK_GE(level, decrypter_level_);
   DCHECK(!version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Setting decrypter from level "
+                << QuicUtils::EncryptionLevelToString(decrypter_level_)
+                << " to " << QuicUtils::EncryptionLevelToString(level);
   decrypter_[decrypter_level_] = nullptr;
   decrypter_[level] = std::move(decrypter);
   decrypter_level_ = level;
@@ -4184,6 +4216,10 @@
     bool latch_once_used) {
   DCHECK_NE(level, decrypter_level_);
   DCHECK(!version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Setting alternative decrypter from level "
+                << QuicUtils::EncryptionLevelToString(
+                       alternative_decrypter_level_)
+                << " to " << QuicUtils::EncryptionLevelToString(level);
   if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
     decrypter_[alternative_decrypter_level_] = nullptr;
   }
@@ -4195,11 +4231,15 @@
 void QuicFramer::InstallDecrypter(EncryptionLevel level,
                                   std::unique_ptr<QuicDecrypter> decrypter) {
   DCHECK(version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level "
+                << QuicUtils::EncryptionLevelToString(level);
   decrypter_[level] = std::move(decrypter);
 }
 
 void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
   DCHECK(version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level "
+                << QuicUtils::EncryptionLevelToString(level);
   decrypter_[level] = nullptr;
 }
 
@@ -4223,6 +4263,8 @@
                               std::unique_ptr<QuicEncrypter> encrypter) {
   DCHECK_GE(level, 0);
   DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
+  QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level "
+                << QuicUtils::EncryptionLevelToString(level);
   encrypter_[level] = std::move(encrypter);
 }
 
@@ -4359,8 +4401,9 @@
   QuicDecrypter* decrypter = decrypter_[expected_decryption_level].get();
   if (decrypter == nullptr) {
     QUIC_DVLOG(1)
+        << ENDPOINT
         << "No decrypter available for removing header protection at level "
-        << expected_decryption_level;
+        << QuicUtils::EncryptionLevelToString(expected_decryption_level);
     return false;
   }