Add QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked method.

PiperOrigin-RevId: 338581332
Change-Id: Id473128041ea65d776fc63a4c25dc3077503856a
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 91e3ea0..71bb8be 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -3715,6 +3715,12 @@
          GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_;
 }
 
+bool QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const {
+  return lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
+         (!GetLargestAckedPacket().IsInitialized() ||
+          GetLargestAckedPacket() < lowest_packet_sent_in_current_key_phase_);
+}
+
 bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) {
   QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate";
   if (!IsKeyUpdateAllowed()) {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 376c623..a3da511 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -824,6 +824,10 @@
   // Returns true if it is currently allowed to initiate a key update.
   bool IsKeyUpdateAllowed() const;
 
+  // Returns true if packets have been sent in the current 1-RTT key phase but
+  // none of these packets have been acked.
+  bool HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const;
+
   // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed()
   // is false. Returns false on error.
   bool InitiateKeyUpdate(KeyUpdateReason reason);
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 0b94236..02c716f 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -12151,6 +12151,7 @@
   // Key update should still not be allowed, since no packet has been acked
   // from the current key phase.
   EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Send packet 1.
   QuicPacketNumber last_packet;
@@ -12160,6 +12161,7 @@
   // Key update should still not be allowed, even though a packet was sent in
   // the current key phase it hasn't been acked yet.
   EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
   // Receive ack for packet 1.
@@ -12170,6 +12172,7 @@
   // OnDecryptedFirstPacketInKeyPhase is called even on the first key phase,
   // so discard_previous_keys_alarm_ should be set now.
   EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Key update should now be allowed.
   EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
@@ -12184,6 +12187,7 @@
   // key phase has been received. (The alarm that was set above should be
   // cleared if it hasn't fired before the next key update happened.)
   EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Pretend that peer accepts the key update.
   EXPECT_CALL(peer_framer_visitor_,
@@ -12201,11 +12205,13 @@
   // Send packet 2.
   SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
   EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
   // Receive ack for packet 2.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
   QuicAckFrame frame2 = InitAckFrame(2);
   ProcessAckPacket(&frame2);
   EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Key update should be allowed again now that a packet has been acked from
   // the current key phase.
@@ -12236,12 +12242,14 @@
 
   // Another key update should not be allowed yet.
   EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Receive ack for packet 3.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
   QuicAckFrame frame3 = InitAckFrame(3);
   ProcessAckPacket(&frame3);
   EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Key update should be allowed now.
   EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
@@ -12253,6 +12261,7 @@
   EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
   EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
   EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 }
 
 TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) {