Internal change

PiperOrigin-RevId: 483743653
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 565419d..b16c933 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -2728,7 +2728,7 @@
        sent_packet_manager_.GetLargestObserved() >
            highest_packet_sent_before_effective_peer_migration_)) {
     if (perspective_ == Perspective::IS_SERVER) {
-      OnEffectivePeerMigrationValidated();
+      OnEffectivePeerMigrationValidated(/*is_migration_linkable=*/true);
     }
   }
 
@@ -5077,7 +5077,8 @@
   QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
 }
 
-void QuicConnection::OnEffectivePeerMigrationValidated() {
+void QuicConnection::OnEffectivePeerMigrationValidated(
+    bool /*is_migration_linkable*/) {
   if (active_effective_peer_migration_type_ == NO_CHANGE) {
     QUIC_BUG(quic_bug_10511_33) << "No migration underway.";
     return;
@@ -5275,7 +5276,9 @@
       // validation.
       ++stats_.num_peer_migration_to_proactively_validated_address;
     }
-    OnEffectivePeerMigrationValidated();
+    OnEffectivePeerMigrationValidated(
+        default_path_.server_connection_id ==
+        previous_default_path.server_connection_id);
     return;
   }
 
@@ -7053,7 +7056,9 @@
           " Connection is connected: ", connection_->connected_);
       QUIC_BUG(quic_bug_10511_43) << error_detail;
     }
-    connection_->OnEffectivePeerMigrationValidated();
+    connection_->OnEffectivePeerMigrationValidated(
+        connection_->alternative_path_.server_connection_id ==
+        connection_->default_path_.server_connection_id);
   } else {
     QUICHE_DCHECK(connection_->IsAlternativePath(
         context->self_address(), context->effective_peer_address()));
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index 61e66cc..ece0b29 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -1284,7 +1284,7 @@
   void StartEffectivePeerMigration(AddressChangeType type);
 
   // Called when a effective peer address migration is validated.
-  virtual void OnEffectivePeerMigrationValidated();
+  virtual void OnEffectivePeerMigrationValidated(bool is_migration_linkable);
 
   // Get the effective peer address from the packet being processed. For proxied
   // connections, effective peer address is the address of the endpoint behind
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 3a4e7a9..04e9d0e 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -210,6 +210,23 @@
 
   MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket packet), (override));
 
+  void OnEffectivePeerMigrationValidated(bool is_migration_linkable) override {
+    QuicConnection::OnEffectivePeerMigrationValidated(is_migration_linkable);
+    if (is_migration_linkable) {
+      num_linkable_client_migration_++;
+    } else {
+      num_unlinkable_client_migration_++;
+    }
+  }
+
+  uint32_t num_unlinkable_client_migration() const {
+    return num_unlinkable_client_migration_;
+  }
+
+  uint32_t num_linkable_client_migration() const {
+    return num_linkable_client_migration_;
+  }
+
   void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
     QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
   }
@@ -541,6 +558,10 @@
   std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_;
 
   QuicSocketAddress self_address_on_default_path_while_sending_packet_;
+
+  uint32_t num_unlinkable_client_migration_ = 0;
+
+  uint32_t num_linkable_client_migration_ = 0;
 };
 
 enum class AckResponse { kDefer, kImmediate };
@@ -1714,6 +1735,7 @@
   if (connection_.validate_client_address()) {
     EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
     EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+    EXPECT_EQ(1u, connection_.num_linkable_client_migration());
   }
 }
 
@@ -1855,6 +1877,7 @@
   // than the anti-amplification limit.
   connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
   EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+  EXPECT_EQ(1u, connection_.num_linkable_client_migration());
 }
 
 TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServerWithMissingConnectionId) {
@@ -1994,6 +2017,7 @@
   if (connection_.validate_client_address()) {
     EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
     EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+    EXPECT_EQ(1u, connection_.num_linkable_client_migration());
   }
 
   // Process another packet with a different direct peer address and the same
@@ -13434,6 +13458,7 @@
       .WillRepeatedly(Return(QuicBandwidth::Zero()));
   connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
   EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+  EXPECT_EQ(1u, connection_.num_unlinkable_client_migration());
 }
 
 TEST_P(QuicConnectionTest,