Align OnRetransmissionTimeout more closely with RFC9002.

When both Initial and Handshake keys are available at the client, switches to sending a PING in Handshake to remove the server's amplification limit and allow it to drop Initial keys, as specified by RFC9002.

PiperOrigin-RevId: 382177508
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index cd4e6be..3b3069b 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -4322,27 +4322,28 @@
                     << retransmission_mode << ", send PING";
     QUICHE_DCHECK_LT(0u,
                      sent_packet_manager_.pending_timer_transmission_count());
-    EncryptionLevel level = encryption_level_;
-    PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES;
     if (SupportsMultiplePacketNumberSpaces()) {
+      // Based on https://datatracker.ietf.org/doc/html/rfc9002#appendix-A.9
+      PacketNumberSpace packet_number_space;
       if (sent_packet_manager_
               .GetEarliestPacketSentTimeForPto(&packet_number_space)
               .IsInitialized()) {
-        level = QuicUtils::GetEncryptionLevel(packet_number_space);
-      }
-      if (level == ENCRYPTION_ZERO_RTT) {
+        SendPingAtLevel(QuicUtils::GetEncryptionLevel(packet_number_space));
+      } else {
+        // The client must PTO when there is nothing in flight if the server
+        // could be blocked from sending by the amplification limit
         QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-        // Do not send 0-RTT PING since it will only elicit (unprocessable)
-        // 1-RTT acknowledgement from server, which does not speed up recovery.
-        if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
-          level = ENCRYPTION_INITIAL;
-        } else if (framer_.HasEncrypterOfEncryptionLevel(
-                       ENCRYPTION_HANDSHAKE)) {
-          level = ENCRYPTION_HANDSHAKE;
+        if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE)) {
+          SendPingAtLevel(ENCRYPTION_HANDSHAKE);
+        } else if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+          SendPingAtLevel(ENCRYPTION_INITIAL);
+        } else {
+          QUIC_BUG(quic_bug_no_pto) << "PTO fired but nothing was sent.";
         }
       }
+    } else {
+      SendPingAtLevel(encryption_level_);
     }
-    SendPingAtLevel(level);
   }
   if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
     sent_packet_manager_.AdjustPendingTimerTransmissions();