gfe-relnote: Check handshake timeout before idle timeout in QuicConnection. Protected by --gfe2_reloadable_flag_quic_check_handshake_timeout_before_idle_timeout.

This is an attempt to deflake the PreSharedKey* tests in third_party/quic/core/http:end_to_end_test.

PiperOrigin-RevId: 292436192
Change-Id: I1a45df8a29913e295bfc5b06805cbdeae245d44b
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 027a2b2..873a893 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -3733,6 +3733,7 @@
 }
 
 TEST_P(EndToEndTest, PreSharedKey) {
+  SetQuicReloadableFlag(quic_check_handshake_timeout_before_idle_timeout, true);
   client_config_.set_max_time_before_crypto_handshake(
       QuicTime::Delta::FromSeconds(1));
   client_config_.set_max_idle_time_before_crypto_handshake(
@@ -3747,6 +3748,7 @@
 
 // TODO: reenable once we have a way to make this run faster.
 TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
+  SetQuicReloadableFlag(quic_check_handshake_timeout_before_idle_timeout, true);
   client_config_.set_max_time_before_crypto_handshake(
       QuicTime::Delta::FromSeconds(1));
   client_config_.set_max_idle_time_before_crypto_handshake(
@@ -3766,6 +3768,7 @@
 
 // TODO: reenable once we have a way to make this run faster.
 TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
+  SetQuicReloadableFlag(quic_check_handshake_timeout_before_idle_timeout, true);
   client_config_.set_max_time_before_crypto_handshake(
       QuicTime::Delta::FromSeconds(1));
   client_config_.set_max_idle_time_before_crypto_handshake(
@@ -3778,6 +3781,7 @@
 
 // TODO: reenable once we have a way to make this run faster.
 TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
+  SetQuicReloadableFlag(quic_check_handshake_timeout_before_idle_timeout, true);
   client_config_.set_max_time_before_crypto_handshake(
       QuicTime::Delta::FromSeconds(1));
   client_config_.set_max_idle_time_before_crypto_handshake(
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 9a12311..09820f3 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -335,7 +335,9 @@
       address_validated_(false),
       use_handshake_delegate_(
           GetQuicReloadableFlag(quic_use_handshaker_delegate2) ||
-          version().handshake_protocol == PROTOCOL_TLS1_3) {
+          version().handshake_protocol == PROTOCOL_TLS1_3),
+      check_handshake_timeout_before_idle_timeout_(GetQuicReloadableFlag(
+          quic_check_handshake_timeout_before_idle_timeout)) {
   QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
                   << server_connection_id
                   << " and version: " << ParsedQuicVersionToString(version());
@@ -349,6 +351,11 @@
     QUIC_RELOADABLE_FLAG_COUNT(quic_use_handshaker_delegate2);
   }
 
+  if (check_handshake_timeout_before_idle_timeout_) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_check_handshake_timeout_before_idle_timeout);
+  }
+
   framer_.set_visitor(this);
   stats_.connection_creation_time = clock_->ApproximateNow();
   // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
@@ -3058,6 +3065,25 @@
 
 void QuicConnection::CheckForTimeout() {
   QuicTime now = clock_->ApproximateNow();
+  if (check_handshake_timeout_before_idle_timeout_ &&
+      !handshake_timeout_.IsInfinite()) {
+    QuicTime::Delta connected_duration = now - stats_.connection_creation_time;
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "connection time: " << connected_duration.ToMicroseconds()
+                  << " handshake timeout: "
+                  << handshake_timeout_.ToMicroseconds();
+    if (connected_duration >= handshake_timeout_) {
+      const std::string error_details = quiche::QuicheStrCat(
+          "Handshake timeout expired after ",
+          connected_duration.ToDebuggingValue(),
+          ". Timeout:", handshake_timeout_.ToDebuggingValue());
+      QUIC_DVLOG(1) << ENDPOINT << error_details;
+      CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+  }
+
   QuicTime time_of_last_packet =
       std::max(time_of_last_received_packet_,
                time_of_first_packet_sent_after_receiving_);
@@ -3089,7 +3115,8 @@
     return;
   }
 
-  if (!handshake_timeout_.IsInfinite()) {
+  if (!check_handshake_timeout_before_idle_timeout_ &&
+      !handshake_timeout_.IsInfinite()) {
     QuicTime::Delta connected_duration = now - stats_.connection_creation_time;
     QUIC_DVLOG(1) << ENDPOINT
                   << "connection time: " << connected_duration.ToMicroseconds()
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 5bb3589..bcedee0 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -1517,6 +1517,9 @@
 
   // Latched value of quic_use_handshaker_delegate2.
   const bool use_handshake_delegate_;
+
+  // Latched value of quic_check_handshake_timeout_before_idle_timeout.
+  const bool check_handshake_timeout_before_idle_timeout_;
 };
 
 }  // namespace quic