Set last_packet_destination_connection_id_ to replacement CID chosen by server when last packet destination CID is the original CID chosen by client.

Protected by FLAGS_quic_reloadable_flag_quic_use_connection_id_on_default_path_v2.

PiperOrigin-RevId: 370937331
Change-Id: I17684f75c2362adfade99596c1e6fe13b52318af
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 1aaeae1..f15b0bf 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1031,6 +1031,7 @@
   QUICHE_DCHECK(!original_destination_connection_id_.has_value())
       << original_destination_connection_id_.value();
   original_destination_connection_id_ = original_destination_connection_id;
+  original_destination_connection_id_replacement_ = ServerConnectionId();
 }
 
 QuicConnectionId QuicConnection::GetOriginalDestinationConnectionId() {
@@ -1043,6 +1044,19 @@
 bool QuicConnection::OnUnauthenticatedPublicHeader(
     const QuicPacketHeader& header) {
   last_packet_destination_connection_id_ = header.destination_connection_id;
+  // If last packet destination connection ID is the original server
+  // connection ID chosen by client, replaces it with the connection ID chosen
+  // by server.
+  if (use_connection_id_on_default_path_ &&
+      perspective_ == Perspective::IS_SERVER &&
+      original_destination_connection_id_.has_value() &&
+      last_packet_destination_connection_id_ ==
+          *original_destination_connection_id_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_connection_id_on_default_path_v2, 3,
+                                 3);
+    last_packet_destination_connection_id_ =
+        original_destination_connection_id_replacement_;
+  }
 
   // As soon as we receive an initial we start ignoring subsequent retries.
   if (header.version_flag && header.long_packet_type == INITIAL) {
@@ -2926,7 +2940,8 @@
 void QuicConnection::SetServerConnectionId(
     const QuicConnectionId& server_connection_id) {
   if (use_connection_id_on_default_path_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_connection_id_on_default_path, 2, 2);
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_connection_id_on_default_path_v2, 2,
+                                 3);
     default_path_.server_connection_id = server_connection_id;
   } else {
     server_connection_id_ = server_connection_id;
@@ -6149,7 +6164,8 @@
     return;
   }
   if (use_connection_id_on_default_path_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_connection_id_on_default_path, 1, 2);
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_connection_id_on_default_path_v2, 1,
+                                 3);
     default_path_.client_connection_id = client_connection_id;
   } else {
     client_connection_id_ = client_connection_id;
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 21555a8..d4d7e3d 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -2028,7 +2028,10 @@
   // Source address of the last received packet.
   QuicSocketAddress last_packet_source_address_;
 
-  // Destination connection id of the last received packet.
+  // Destination connection ID of the last received packet. If this ID is the
+  // original server connection ID chosen by client and server replaces it with
+  // a different ID, last_packet_destination_connection_id_ is set to the
+  // replacement connection ID on the server side.
   QuicConnectionId last_packet_destination_connection_id_;
 
   // Set to false if the connection should not send truncated connection IDs to
@@ -2151,6 +2154,9 @@
   // |original_destination_connection_id_| for validation.
   absl::optional<QuicConnectionId> original_destination_connection_id_;
 
+  // The connection ID that replaces original_destination_connection_id_.
+  QuicConnectionId original_destination_connection_id_replacement_;
+
   // After we receive a RETRY packet, |retry_source_connection_id_| contains
   // the source connection ID from that packet.
   absl::optional<QuicConnectionId> retry_source_connection_id_;
@@ -2265,7 +2271,7 @@
       GetQuicReloadableFlag(quic_donot_write_mid_packet_processing);
 
   bool use_connection_id_on_default_path_ =
-      GetQuicReloadableFlag(quic_use_connection_id_on_default_path);
+      GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2);
 
   // Indicates whether we should proactively validate peer address on a
   // PATH_CHALLENGE received.
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index b0ded03..741f2da 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -14431,7 +14431,7 @@
 TEST_P(QuicConnectionTest,
        CloseConnectionAfterReceiveRetireConnectionIdWhenNoCIDIssued) {
   if (!version().HasIetfQuicFrames() ||
-      GetQuicReloadableFlag(quic_use_connection_id_on_default_path)) {
+      GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2)) {
     return;
   }
   QuicConnectionPeer::EnableMultipleConnectionIdSupport(&connection_);
@@ -14452,7 +14452,7 @@
 
 TEST_P(QuicConnectionTest, RetireConnectionIdFrameResultsInError) {
   if (!version().HasIetfQuicFrames() ||
-      GetQuicReloadableFlag(quic_use_connection_id_on_default_path)) {
+      GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2)) {
     return;
   }
   QuicConnectionPeer::EnableMultipleConnectionIdSupport(&connection_);
@@ -14489,15 +14489,15 @@
   QuicConnectionId cid0 = connection_id_;
   QuicRetireConnectionIdFrame frame;
   frame.sequence_number = 0u;
-  if (!GetQuicReloadableFlag(quic_use_connection_id_on_default_path)) {
+  if (!GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2)) {
     EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_)).Times(2);
     EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
   }
   EXPECT_TRUE(connection_.OnRetireConnectionIdFrame(frame));
-  if (!GetQuicReloadableFlag(quic_use_connection_id_on_default_path)) {
+  if (!GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2)) {
     ASSERT_TRUE(retire_self_issued_cid_alarm->IsSet());
     // cid0 is retired when the retire CID alarm fires.
-    if (!GetQuicReloadableFlag(quic_use_connection_id_on_default_path))
+    if (!GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2))
       EXPECT_CALL(visitor_, OnServerConnectionIdRetired(cid0));
     retire_self_issued_cid_alarm->Fire();
   }
@@ -14505,7 +14505,7 @@
 
 TEST_P(QuicConnectionTest, ServerRetireSelfIssuedConnectionId) {
   if (!version().HasIetfQuicFrames() ||
-      GetQuicReloadableFlag(quic_use_connection_id_on_default_path)) {
+      GetQuicReloadableFlag(quic_use_connection_id_on_default_path_v2)) {
     return;
   }
   QuicConnectionPeer::EnableMultipleConnectionIdSupport(&connection_);
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 4ed13ff..12fb98e 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -64,7 +64,7 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, false)
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_connection_id_on_default_path, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_connection_id_on_default_path_v2, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_encryption_level_context, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_write_or_buffer_data_at_level, false)
 QUIC_FLAG(FLAGS_quic_restart_flag_dont_fetch_quic_private_keys_from_leto, false)