Do not create a new multi-port path when there's pending path validation.
Also add logging on why there's an existing path validation.
Merge instruction: This CL adds a new parameter in ValidatePath(). For its callers, please pass in the corresponding reason into the method. I'll be happy to review.
PiperOrigin-RevId: 502708390
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index b7959dd..e0c92b1 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -2658,7 +2658,8 @@
connection_.self_address(), kNewPeerAddress, writer_.get()),
std::make_unique<TestValidationResultDelegate>(
&connection_, connection_.self_address(), kNewPeerAddress,
- &success));
+ &success),
+ PathValidationReason::kReasonUnknown);
}
EXPECT_EQ((connection_.validate_client_address() ? 2 : 3) * bytes_sent,
QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
@@ -8860,7 +8861,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
// Receiving a PATH_CHALLENGE on the alternative path. Response to this
// PATH_CHALLENGE should be sent via the alternative writer.
@@ -11625,7 +11627,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_EQ(0u, writer_->packets_write_attempts());
QuicFrames frames;
@@ -11658,7 +11661,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_EQ(0u, writer_->packets_write_attempts());
// Start another path validation request.
@@ -11682,7 +11686,8 @@
kNewSelfAddress2, connection_.peer_address(), &new_writer2),
std::make_unique<TestValidationResultDelegate>(
&connection_, kNewSelfAddress2, connection_.peer_address(),
- &success2));
+ &success2),
+ PathValidationReason::kReasonUnknown);
EXPECT_FALSE(success);
if (connection_.connection_migration_use_new_cid()) {
// There is no pening path validation as there is no available connection
@@ -11712,7 +11717,8 @@
connection_.peer_address(), writer_.get()),
std::make_unique<TestValidationResultDelegate>(
&connection_, connection_.self_address(),
- connection_.peer_address(), &success));
+ connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_EQ(1u, writer_->packets_write_attempts());
EXPECT_TRUE(connection_.HasPendingPathValidation());
@@ -11753,7 +11759,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_EQ(0u, writer_->packets_write_attempts());
EXPECT_TRUE(connection_.HasPendingPathValidation());
@@ -11798,7 +11805,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_EQ(0u, writer_->packets_write_attempts());
new_writer.SetWritable();
@@ -11860,7 +11868,8 @@
connection_.self_address(), kNewPeerAddress, writer_.get()),
std::make_unique<TestValidationResultDelegate>(
&connection_, connection_.self_address(), kNewPeerAddress,
- &success));
+ &success),
+ PathValidationReason::kReasonUnknown);
}
EXPECT_EQ(1u, writer_->packets_write_attempts());
@@ -11903,7 +11912,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
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());
@@ -11939,7 +11949,8 @@
connection_.peer_address(), writer_.get()),
std::make_unique<TestValidationResultDelegate>(
&connection_, connection_.self_address(),
- connection_.peer_address(), &success));
+ connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
}
EXPECT_EQ(1u, writer_->packets_write_attempts());
EXPECT_EQ(1u, writer_->path_challenge_frames().size());
@@ -11970,7 +11981,8 @@
std::make_unique<TestQuicPathValidationContext>(
connection_.self_address(), kNewPeerAddress, writer_.get()),
std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(), kNewPeerAddress, &success));
+ &connection_, connection_.self_address(), kNewPeerAddress, &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_EQ(1u, writer_->packets_write_attempts());
EXPECT_FALSE(connection_.HasPendingPathValidation());
@@ -12003,7 +12015,8 @@
std::make_unique<TestQuicPathValidationContext>(
connection_.self_address(), kNewPeerAddress, writer_.get()),
std::make_unique<TestValidationResultDelegate>(
- &connection_, connection_.self_address(), kNewPeerAddress, &success));
+ &connection_, connection_.self_address(), kNewPeerAddress, &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_TRUE(connection_.HasPendingPathValidation());
// Connection shouldn't be closed.
EXPECT_TRUE(connection_.connected());
@@ -13187,7 +13200,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), &new_writer),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_TRUE(connection_.HasPendingPathValidation());
EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath(
&connection_, kNewSelfAddress, connection_.peer_address()));
@@ -13241,6 +13255,14 @@
&connection_, kNewSelfAddress, connection_.peer_address()));
auto* alt_path = QuicConnectionPeer::GetAlternativePath(&connection_);
EXPECT_FALSE(alt_path->validated);
+ EXPECT_EQ(PathValidationReason::kMultiPort,
+ QuicConnectionPeer::path_validator(&connection_)
+ ->GetPathValidationReason());
+
+ // Suppose the server retransmits the NEW_CID frame, the client will receive
+ // the same frame again. It should be ignored.
+ // Regression test of crbug.com/1406762
+ connection_.OnNewConnectionIdFrame(frame);
// 30ms RTT.
const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
@@ -14198,7 +14220,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), writer_.get()),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
EXPECT_FALSE(success);
}
@@ -14250,7 +14273,8 @@
std::make_unique<TestQuicPathValidationContext>(
kSelfAddress1, connection_.peer_address(), writer_.get()),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kSelfAddress1, connection_.peer_address(), &success1));
+ &connection_, kSelfAddress1, connection_.peer_address(), &success1),
+ PathValidationReason::kReasonUnknown);
// Migrate upon 1st validation success.
TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
@@ -14291,7 +14315,8 @@
std::make_unique<TestQuicPathValidationContext>(
kSelfAddress2, connection_.peer_address(), writer_.get()),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kSelfAddress2, connection_.peer_address(), &success2));
+ &connection_, kSelfAddress2, connection_.peer_address(), &success2),
+ PathValidationReason::kReasonUnknown);
// Since server does not retire any client connection ID yet, 2nd validation
// would fail due to lack of client connection ID.
EXPECT_FALSE(success2);
@@ -14326,7 +14351,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, connection_.peer_address(), writer_.get()),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+ &connection_, kNewSelfAddress, connection_.peer_address(), &success),
+ PathValidationReason::kReasonUnknown);
auto* path_validator = QuicConnectionPeer::path_validator(&connection_);
path_validator->CancelPathValidation();
@@ -16104,7 +16130,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
connection_.OnHandshakeComplete();
EXPECT_TRUE(connection_.HasPendingPathValidation());
@@ -16183,7 +16210,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
connection_.OnHandshakeComplete();
EXPECT_TRUE(connection_.HasPendingPathValidation());
@@ -16250,7 +16278,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
connection_.OnHandshakeComplete();
EXPECT_TRUE(connection_.IsValidatingServerPreferredAddress());
@@ -16312,7 +16341,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
QuicConfig config;
config.SetClientConnectionOptions(QuicTagVector{kSPA2});
@@ -16349,7 +16379,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
QuicConfig config;
config.SetClientConnectionOptions(QuicTagVector{kSPA2});
@@ -16392,7 +16423,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
QuicConfig config;
config.SetClientConnectionOptions(QuicTagVector{kSPA2});
@@ -16445,7 +16477,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress, kServerPreferredAddress, &new_writer),
std::make_unique<ServerPreferredAddressTestResultDelegate>(
- &connection_));
+ &connection_),
+ PathValidationReason::kReasonUnknown);
}));
// The connection should start probing the preferred address after handshake
// confirmed.
@@ -16685,8 +16718,8 @@
std::make_unique<TestQuicPathValidationContext>(
kNewSelfAddress2, connection_.peer_address(), &new_writer2),
std::make_unique<TestValidationResultDelegate>(
- &connection_, kNewSelfAddress2, connection_.peer_address(),
- &success));
+ &connection_, kNewSelfAddress2, connection_.peer_address(), &success),
+ PathValidationReason::kServerPreferredAddressMigration);
EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath(
&connection_, kNewSelfAddress2, kServerPreferredAddress));