Handle PINGs in QUIC connection.

Currently, sending and retransmission of PINGs are handled by control frame manager (and session).

Protected by FLAGS_quic_reloadable_flag_quic_let_connection_handle_pings.

PiperOrigin-RevId: 335072367
Change-Id: I79f20404656beee3d9404c1ccaa8ef2f00af567c
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index b18b367..06488e5 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -4024,7 +4024,11 @@
             connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
 
   // Simulate firing of the retransmittable on wire and send a PING.
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   clock_.AdvanceTime(retransmittable_on_wire_timeout);
   connection_.GetPingAlarm()->Fire();
 
@@ -4038,13 +4042,21 @@
       QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs);
   srtt = manager_->GetRttStats()->SmoothedOrInitialRtt();
 
-  // First TLP without unacked stream data will no longer use TLPR.
-  expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout);
+  if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    // Arm RTO mode since there is only PING in flight.
+    expected_delay = manager_->GetPtoDelay();
+  } else {
+    // First TLP without unacked stream data will no longer use TLPR.
+    expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout);
+  }
   EXPECT_EQ(expected_delay,
             connection_.GetRetransmissionAlarm()->deadline() - clock_.Now());
 
   // Verify the path degrading delay = TLP delay + 1st RTO + 2nd RTO.
   // Add 1st RTO.
+  if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout);
+  }
   retransmission_delay =
       std::max(manager_->GetRttStats()->smoothed_rtt() +
                    4 * manager_->GetRttStats()->mean_deviation(),
@@ -4071,7 +4083,12 @@
 
   // Verify the retransmission delay.
   // First TLP without unacked stream data will no longer use TLPR.
-  expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout);
+  if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    // Arm RTO mode since there is only PING in flight.
+    expected_delay = manager_->GetPtoDelay();
+  } else {
+    expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout);
+  }
   expected_delay = expected_delay - QuicTime::Delta::FromMilliseconds(5);
   EXPECT_EQ(expected_delay,
             connection_.GetRetransmissionAlarm()->deadline() - clock_.Now());
@@ -4597,7 +4614,11 @@
 
   writer_->Reset();
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   connection_.GetPingAlarm()->Fire();
   size_t padding_frame_count = writer_->padding_frames().size();
   EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
@@ -4651,9 +4672,11 @@
 
   writer_->Reset();
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-    connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
-  }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+    }));
+  }
   connection_.GetPingAlarm()->Fire();
   size_t padding_frame_count = writer_->padding_frames().size();
   EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
@@ -7159,9 +7182,11 @@
 
   // Simulate firing the ping alarm and sending a PING.
   clock_.AdvanceTime(retransmittable_on_wire_timeout);
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-    connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
-  }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+    }));
+  }
   connection_.GetPingAlarm()->Fire();
 
   // Now there's a retransmittable packet (PING) on the wire, so the path
@@ -7862,9 +7887,11 @@
   EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
 
   // Simulate the alarm firing and check that a PING is sent.
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-    connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
-  }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+    }));
+  }
   connection_.GetPingAlarm()->Fire();
   size_t padding_frame_count = writer_->padding_frames().size();
   if (GetParam().no_stop_waiting) {
@@ -7935,9 +7962,11 @@
 
   // Simulate the alarm firing and check that a PING is sent.
   writer_->Reset();
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-    connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
-  }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+    }));
+  }
   connection_.GetPingAlarm()->Fire();
   size_t padding_frame_count = writer_->padding_frames().size();
   if (GetParam().no_stop_waiting) {
@@ -7997,9 +8026,11 @@
               connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
     // Simulate the alarm firing and check that a PING is sent.
     writer_->Reset();
-    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-      SendPing();
-    }));
+    if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+      EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+        SendPing();
+      }));
+    }
     clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
     connection_.GetPingAlarm()->Fire();
   }
@@ -8024,9 +8055,11 @@
 
     // Simulate the alarm firing and check that a PING is sent.
     writer_->Reset();
-    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-      SendPing();
-    }));
+    if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+      EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+        SendPing();
+      }));
+    }
     clock_.AdvanceTime(retransmittable_on_wire_timeout);
     connection_.GetPingAlarm()->Fire();
   }
@@ -8092,7 +8125,11 @@
 
   // Simulate the alarm firing and check that a PING is sent.
   writer_->Reset();
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
   connection_.GetPingAlarm()->Fire();
 
@@ -8128,9 +8165,11 @@
               connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
     // Simulate the alarm firing and check that a PING is sent.
     writer_->Reset();
-    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
-      SendPing();
-    }));
+    if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+      EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+        SendPing();
+      }));
+    }
     clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
     connection_.GetPingAlarm()->Fire();
     // Advance 5ms to receive next packet.
@@ -8148,7 +8187,11 @@
             connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
 
   writer_->Reset();
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout);
   connection_.GetPingAlarm()->Fire();
 
@@ -9110,7 +9153,11 @@
 
   // RTO fires, verify a PING packet gets sent because there is no data to send.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   clock_.AdvanceTime(retransmission_time - clock_.Now());
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(1u, connection_.GetStats().tlp_count);
@@ -9330,7 +9377,11 @@
                                ? QuicPacketNumber(2)
                                : QuicPacketNumber(3),
                            _, _));
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(1u, connection_.GetStats().pto_count);
   EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count);
@@ -9627,7 +9678,11 @@
   // Fires TLP, verify a PING gets sent because packet 3 is marked
   // RTO_RETRANSMITTED.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(70), _, _));
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   connection_.GetRetransmissionAlarm()->Fire();
 }
 
@@ -10218,7 +10273,11 @@
   // PTO fires, verify a PING packet gets sent because there is no data to
   // send.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(1u, connection_.GetStats().pto_count);
   EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
@@ -11003,7 +11062,11 @@
   EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
       .WillRepeatedly(Return(false));
   // Verify PING does not get sent.
-  EXPECT_CALL(visitor_, SendPing()).Times(0);
+  if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  } else {
+    EXPECT_CALL(visitor_, SendPing()).Times(0);
+  }
   connection_.GetPingAlarm()->Fire();
 }
 
@@ -11581,6 +11644,10 @@
     if (!GetQuicReloadableFlag(quic_fix_missing_initial_keys2)) {
       EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
     }
+  } else if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    if (!GetQuicReloadableFlag(quic_fix_missing_initial_keys2)) {
+      EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    }
   } else {
     EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(0);
     EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
@@ -11592,10 +11659,15 @@
     // Verify a handshake packet gets PTOed and 1-RTT packet gets coalesced.
     EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
   } else {
-    // Verify an 1-RTT PING gets sent because there is nothing to PTO, bummer,
-    // since this 1-RTT PING cannot be processed by peer and there is a
-    // deadlock.
-    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+    if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+      // Verify PING is sent in the right encryption level.
+      EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
+    } else {
+      // Verify an 1-RTT PING gets sent because there is nothing to PTO, bummer,
+      // since this 1-RTT PING cannot be processed by peer and there is a
+      // deadlock.
+      EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+    }
     EXPECT_FALSE(writer_->ping_frames().empty());
   }
 }
@@ -11684,7 +11756,11 @@
   EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 
   // Fire retransmission alarm.
-  EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); }));
+  if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) {
+    EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+      SendPing();
+    }));
+  }
   connection_.GetRetransmissionAlarm()->Fire();
 
   QuicFrames frames1;