Make time wait list aware of original server connection ID. Also, encrypt INITIAL termination packet with crypter using original server connection ID.

Protected by FLAGS_quic_reloadable_flag_quic_consider_original_connection_id_as_active_pre_handshake.

PiperOrigin-RevId: 448574254
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index 019409d..37e302e 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -4796,14 +4796,8 @@
 // Regression test for b/116200989.
 TEST_P(EndToEndTest,
        SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
-  // TODO(b/232285861)
-  // This test should probably work when the server issues a new connection ID
-  // during the handshake. When the bug is fixed, remove the check below to
-  // allow it to run when the client provides a 16B connection ID.
-  if (override_server_connection_id_length_ > -1) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
+  SetQuicReloadableFlag(
+      quic_consider_original_connection_id_as_active_pre_handshake, true);
   connect_to_server_on_initialize_ = false;
   ASSERT_TRUE(Initialize());
 
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 1e458c6..49681b7 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -6940,11 +6940,38 @@
 
 std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
     const {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+  std::vector<QuicConnectionId> result;
   if (self_issued_cid_manager_ == nullptr) {
-    return {default_path_.server_connection_id};
+    result.push_back(default_path_.server_connection_id);
+  } else {
+    QUICHE_DCHECK(version().HasIetfQuicFrames());
+    result = self_issued_cid_manager_->GetUnretiredConnectionIds();
   }
-  QUICHE_DCHECK(version().HasIetfQuicFrames());
-  return self_issued_cid_manager_->GetUnretiredConnectionIds();
+  if (GetQuicReloadableFlag(
+          quic_consider_original_connection_id_as_active_pre_handshake)) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_consider_original_connection_id_as_active_pre_handshake);
+    if (!IsHandshakeComplete() &&
+        original_destination_connection_id_.has_value()) {
+      // Consider original_destination_connection_id_ as active before handshake
+      // completes.
+      if (std::find(result.begin(), result.end(),
+                    original_destination_connection_id_.value()) !=
+          result.end()) {
+        QUIC_BUG(quic_unexpected_original_destination_connection_id)
+            << "original_destination_connection_id: "
+            << original_destination_connection_id_.value()
+            << " is unexpectedly in active "
+               "list";
+      } else {
+        result.insert(result.end(),
+                      original_destination_connection_id_.value());
+      }
+      QUIC_CODE_COUNT(quic_active_original_connection_id_pre_handshake);
+    }
+  }
+  return result;
 }
 
 void QuicConnection::CreateConnectionIdManager() {
diff --git a/quiche/quic/core/quic_dispatcher.cc b/quiche/quic/core/quic_dispatcher.cc
index 281b584..9166a93 100644
--- a/quiche/quic/core/quic_dispatcher.cc
+++ b/quiche/quic/core/quic_dispatcher.cc
@@ -148,6 +148,7 @@
 class StatelessConnectionTerminator {
  public:
   StatelessConnectionTerminator(QuicConnectionId server_connection_id,
+                                QuicConnectionId original_server_connection_id,
                                 const ParsedQuicVersion version,
                                 QuicConnectionHelperInterface* helper,
                                 QuicTimeWaitListManager* time_wait_list_manager)
@@ -159,7 +160,8 @@
         creator_(server_connection_id, &framer_, &collector_),
         time_wait_list_manager_(time_wait_list_manager) {
     framer_.set_data_producer(&collector_);
-    framer_.SetInitialObfuscators(server_connection_id);
+    // Always set encrypter with original_server_connection_id.
+    framer_.SetInitialObfuscators(original_server_connection_id);
   }
 
   ~StatelessConnectionTerminator() {
@@ -902,8 +904,9 @@
       // This serializes a connection close termination packet and adds the
       // connection to the time wait list.
       StatelessConnectionTerminator terminator(
-          server_connection_id, connection->version(), helper_.get(),
-          time_wait_list_manager_.get());
+          server_connection_id,
+          connection->GetOriginalDestinationConnectionId(),
+          connection->version(), helper_.get(), time_wait_list_manager_.get());
       terminator.CloseConnection(
           QUIC_HANDSHAKE_FAILED,
           "Connection is closed by server before handshake confirmed",
@@ -1138,9 +1141,9 @@
         << version << ", error_code:" << error_code
         << ", error_details:" << error_details;
 
-    StatelessConnectionTerminator terminator(server_connection_id, version,
-                                             helper_.get(),
-                                             time_wait_list_manager_.get());
+    StatelessConnectionTerminator terminator(
+        server_connection_id, server_connection_id, version, helper_.get(),
+        time_wait_list_manager_.get());
     // This also adds the connection to time wait list.
     terminator.CloseConnection(
         error_code, error_details, format != GOOGLE_QUIC_PACKET,
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
index 688d0a8..ab90711 100644
--- a/quiche/quic/core/quic_flags_list.h
+++ b/quiche/quic/core/quic_flags_list.h
@@ -31,6 +31,8 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true)
 // If true, close read side but not write side in QuicSpdyStream::OnStreamReset().
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_on_stream_reset, true)
+// If true, consider original connection ID as active before handshake completes.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_consider_original_connection_id_as_active_pre_handshake, false)
 // If true, consolidate more logic into SetRetransmissionAlarm to ensure the logic is applied consistently.
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_simplify_set_retransmission_alarm, true)
 // If true, default-enable 5RTO blachole detection.