In QuicConnection, cancel the previous path validation request before starting a new one.
Protected by FLAGS_quic_reloadable_flag_quic_pass_path_response_to_validator.
PiperOrigin-RevId: 351886493
Change-Id: If1ff60fc9cc423780a64edd8382232182c7df8cf
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index ac8b22d..86872de 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -5561,6 +5561,10 @@
most_recent_alternative_path_ =
AlternativePathState(context->self_address(), context->peer_address());
}
+ if (path_validator_.HasPendingPathValidation()) {
+ // Cancel and fail any earlier validation.
+ path_validator_.CancelPathValidation();
+ }
path_validator_.StartPathValidation(std::move(context),
std::move(result_delegate));
}
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 8ad4214..29ad505 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -11316,6 +11316,55 @@
EXPECT_TRUE(success);
}
+TEST_P(QuicConnectionTest, NewPathValidationCancelsPreviousOne) {
+ 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(_, _, _, _, _))
+ .Times(AtLeast(1u))
+ .WillOnce(Invoke([&]() {
+ EXPECT_EQ(1u, new_writer.packets_write_attempts());
+ EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+ EXPECT_EQ(1u, new_writer.padding_frames().size());
+ EXPECT_EQ(kNewSelfAddress.host(),
+ new_writer.last_write_source_address());
+ }));
+ bool success = true;
+ connection_.ValidatePath(
+ std::make_unique<TestQuicPathValidationContext>(
+ kNewSelfAddress, connection_.peer_address(), &new_writer),
+ std::make_unique<TestValidationResultDelegate>(
+ kNewSelfAddress, connection_.peer_address(), &success));
+ EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+ // Start another path validation request.
+ const QuicSocketAddress kNewSelfAddress2(QuicIpAddress::Any4(), 12346);
+ EXPECT_NE(kNewSelfAddress2, connection_.self_address());
+ TestPacketWriter new_writer2(version(), &clock_, Perspective::IS_CLIENT);
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .Times(AtLeast(1u))
+ .WillOnce(Invoke([&]() {
+ EXPECT_EQ(1u, new_writer2.packets_write_attempts());
+ EXPECT_EQ(1u, new_writer2.path_challenge_frames().size());
+ EXPECT_EQ(1u, new_writer2.padding_frames().size());
+ EXPECT_EQ(kNewSelfAddress2.host(),
+ new_writer2.last_write_source_address());
+ }));
+ bool success2 = false;
+ connection_.ValidatePath(
+ std::make_unique<TestQuicPathValidationContext>(
+ kNewSelfAddress2, connection_.peer_address(), &new_writer2),
+ std::make_unique<TestValidationResultDelegate>(
+ kNewSelfAddress2, connection_.peer_address(), &success2));
+ EXPECT_FALSE(success);
+ EXPECT_TRUE(connection_.HasPendingPathValidation());
+}
+
TEST_P(QuicConnectionTest, PathValidationReceivesStatelessReset) {
if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
!connection_.use_path_validator()) {