Reset alternative path state after migrating to that path.

Protected by existing flag --quic_reloadable_flag_quic_pass_path_response_to_validator.

PiperOrigin-RevId: 351447513
Change-Id: I0932ec20dd4e7016c9a950275f9f93e6a4453058
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 67177a5..8de03d2 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1095,6 +1095,10 @@
     // probing, restart the path degrading and blackhole detection.
     OnForwardProgressMade();
   }
+  if (IsMostRecentAlternativePath(self_address_, effective_peer_address_)) {
+    // Reset alternative path state even if it is still under validation.
+    most_recent_alternative_path_.Clear();
+  }
   // TODO(b/159074035): notify SentPacketManger with RTT sample from probing and
   // reset cwnd if this is a successful network migration.
 }
@@ -5653,5 +5657,13 @@
          most_recent_alternative_path_.self_address == self_address;
 }
 
+void QuicConnection::AlternativePathState::Clear() {
+  self_address = QuicSocketAddress();
+  peer_address = QuicSocketAddress();
+  validated = false;
+  bytes_received_before_address_validation_ = 0;
+  bytes_sent_before_address_validation_ = 0;
+}
+
 #undef ENDPOINT  // undef for jumbo builds
 }  // namespace quic
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 64e83b0..600e882 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -1277,6 +1277,9 @@
         : self_address(alternative_self_address),
           peer_address(alternative_peer_address) {}
 
+    // Reset all the members.
+    void Clear();
+
     QuicSocketAddress self_address;
     // The actual peer address behind the proxy if there is any.
     QuicSocketAddress peer_address;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 609f28c..620f5f0 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -12745,6 +12745,34 @@
   EXPECT_FALSE(connection_.IsPathDegrading());
 }
 
+TEST_P(QuicConnectionTest, MigrateToNewPathDuringValidation) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_TRUE(QuicConnectionPeer::IsMostRecentAlternativePath(
+      &connection_, kNewSelfAddress, connection_.peer_address()));
+
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, /*owns_writer=*/false);
+  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_FALSE(QuicConnectionPeer::IsMostRecentAlternativePath(
+      &connection_, kNewSelfAddress, connection_.peer_address()));
+}
+
 TEST_P(QuicConnectionTest, SingleAckInPacket) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc
index 4989612..c446da3 100644
--- a/quic/test_tools/quic_connection_peer.cc
+++ b/quic/test_tools/quic_connection_peer.cc
@@ -426,5 +426,13 @@
       .bytes_sent_before_address_validation_;
 }
 
+// static
+bool QuicConnectionPeer::IsMostRecentAlternativePath(
+    QuicConnection* connection,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) {
+  return connection->IsMostRecentAlternativePath(self_address, peer_address);
+}
+
 }  // namespace test
 }  // namespace quic
diff --git a/quic/test_tools/quic_connection_peer.h b/quic/test_tools/quic_connection_peer.h
index 2795531..ad8a5ce 100644
--- a/quic/test_tools/quic_connection_peer.h
+++ b/quic/test_tools/quic_connection_peer.h
@@ -176,6 +176,11 @@
 
   static QuicByteCount BytesReceivedOnMostRecentAlternativePath(
       QuicConnection* connection);
+
+  static bool IsMostRecentAlternativePath(
+      QuicConnection* connection,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address);
 };
 
 }  // namespace test