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.cc b/quiche/quic/core/quic_connection.cc
index 998b134..de88ae6 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -1798,7 +1798,8 @@
default_path_.self_address, direct_peer_address_to_respond,
effective_peer_address_to_respond, this),
std::make_unique<ReversePathValidationResultDelegate>(
- this, peer_address()));
+ this, peer_address()),
+ PathValidationReason::kReversePathValidation);
}
has_path_challenge_in_current_packet_ = true;
MaybeUpdateAckTimeout();
@@ -3994,8 +3995,13 @@
void QuicConnection::MaybeCreateMultiPortPath() {
QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- QUIC_BUG_IF(quic_bug_12714_20, path_validator_.HasPendingPathValidation())
- << "Pending validation exists when multi-port path is created.";
+ if (path_validator_.HasPendingPathValidation()) {
+ QUIC_CLIENT_HISTOGRAM_ENUM("QuicConnection.MultiPortPathCreationCancelled",
+ path_validator_.GetPathValidationReason(),
+ PathValidationReason::kMaxValue,
+ "Reason for cancelled multi port path creation");
+ return;
+ }
if (multi_port_stats_->num_multi_port_paths_created >=
kMaxNumMultiPortPaths) {
return;
@@ -4010,7 +4016,8 @@
multi_port_path_context_ = nullptr;
multi_port_stats_->num_multi_port_paths_created++;
ValidatePath(std::move(path_context),
- std::move(multi_port_validation_result_delegate));
+ std::move(multi_port_validation_result_delegate),
+ PathValidationReason::kMultiPort);
}
void QuicConnection::SendOrQueuePacket(SerializedPacket packet) {
@@ -5291,7 +5298,8 @@
default_path_.self_address, peer_address(),
default_path_.peer_address, this),
std::make_unique<ReversePathValidationResultDelegate>(
- this, previous_direct_peer_address));
+ this, previous_direct_peer_address),
+ PathValidationReason::kReversePathValidation);
} else {
QUIC_DVLOG(1) << "Peer address " << default_path_.peer_address
<< " is already under validation, wait for result.";
@@ -6523,7 +6531,8 @@
void QuicConnection::ValidatePath(
std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
+ std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,
+ PathValidationReason reason) {
if (!connection_migration_use_new_cid_ &&
perspective_ == Perspective::IS_CLIENT &&
!IsDefaultPath(context->self_address(), context->peer_address())) {
@@ -6578,7 +6587,7 @@
server_connection_id, stateless_reset_token);
}
path_validator_.StartPathValidation(std::move(context),
- std::move(result_delegate));
+ std::move(result_delegate), reason);
if (perspective_ == Perspective::IS_CLIENT &&
IsValidatingServerPreferredAddress()) {
AddKnownServerAddress(server_preferred_address_);
@@ -7043,7 +7052,8 @@
std::make_unique<MultiPortPathValidationResultDelegate>(this);
path_validator_.StartPathValidation(
std::move(multi_port_path_context_),
- std::move(multi_port_validation_result_delegate));
+ std::move(multi_port_validation_result_delegate),
+ PathValidationReason::kMultiPort);
}
QuicConnection::MultiPortPathValidationResultDelegate::
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index 7f58c5e..7969a0e 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -1193,7 +1193,8 @@
// this one.
void ValidatePath(
std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
+ std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,
+ PathValidationReason reason);
bool can_receive_ack_frequency_frame() const {
return can_receive_ack_frequency_frame_;
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));
diff --git a/quiche/quic/core/quic_path_validator.cc b/quiche/quic/core/quic_path_validator.cc
index 6179fe5..da29fac 100644
--- a/quiche/quic/core/quic_path_validator.cc
+++ b/quiche/quic/core/quic_path_validator.cc
@@ -72,7 +72,8 @@
void QuicPathValidator::StartPathValidation(
std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<ResultDelegate> result_delegate) {
+ std::unique_ptr<ResultDelegate> result_delegate,
+ PathValidationReason reason) {
QUICHE_DCHECK(context);
QUIC_DLOG(INFO) << "Start validating path " << *context
<< " via writer: " << context->WriterToUse();
@@ -82,6 +83,7 @@
ResetPathValidation();
}
+ reason_ = reason;
path_context_ = std::move(context);
result_delegate_ = std::move(result_delegate);
SendPathChallengeAndSetAlarm();
@@ -92,6 +94,7 @@
result_delegate_ = nullptr;
retry_timer_->Cancel();
retry_count_ = 0;
+ reason_ = PathValidationReason::kReasonUnknown;
}
void QuicPathValidator::CancelPathValidation() {
diff --git a/quiche/quic/core/quic_path_validator.h b/quiche/quic/core/quic_path_validator.h
index 4b94892..6074fd8 100644
--- a/quiche/quic/core/quic_path_validator.h
+++ b/quiche/quic/core/quic_path_validator.h
@@ -29,6 +29,16 @@
class QuicConnection;
+enum class QUIC_EXPORT_PRIVATE PathValidationReason {
+ kReasonUnknown,
+ kMultiPort,
+ kReversePathValidation,
+ kServerPreferredAddressMigration,
+ kPortMigration,
+ kConnectionMigration,
+ kMaxValue,
+};
+
// Interface to provide the information of the path to be validated.
class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
public:
@@ -117,7 +127,8 @@
// Send PATH_CHALLENGE and start the retry timer.
void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<ResultDelegate> result_delegate);
+ std::unique_ptr<ResultDelegate> result_delegate,
+ PathValidationReason reason);
// Called when a PATH_RESPONSE frame has been received. Matches the received
// PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
@@ -132,6 +143,8 @@
QuicPathValidationContext* GetContext() const;
+ PathValidationReason GetPathValidationReason() const { return reason_; }
+
// Send another PATH_CHALLENGE on the same path. After retrying
// |kMaxRetryTimes| times, fail the current path validation.
void OnRetryTimeout();
@@ -168,6 +181,7 @@
std::unique_ptr<ResultDelegate> result_delegate_;
QuicArenaScopedPtr<QuicAlarm> retry_timer_;
size_t retry_count_;
+ PathValidationReason reason_ = PathValidationReason::kReasonUnknown;
};
} // namespace quic
diff --git a/quiche/quic/core/quic_path_validator_test.cc b/quiche/quic/core/quic_path_validator_test.cc
index f45cd26..6d0be9e 100644
--- a/quiche/quic/core/quic_path_validator_test.cc
+++ b/quiche/quic/core/quic_path_validator_test.cc
@@ -86,8 +86,11 @@
const QuicTime expected_start_time = clock_.Now();
path_validator_.StartPathValidation(
std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+ std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_),
+ PathValidationReason::kMultiPort);
EXPECT_TRUE(path_validator_.HasPendingPathValidation());
+ EXPECT_EQ(PathValidationReason::kMultiPort,
+ path_validator_.GetPathValidationReason());
EXPECT_TRUE(path_validator_.IsValidatingPeerAddress(effective_peer_address_));
EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_, _))
.WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context,
@@ -98,6 +101,8 @@
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(kInitialRttMs));
path_validator_.OnPathResponse(challenge_data, self_address_);
EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+ EXPECT_EQ(PathValidationReason::kReasonUnknown,
+ path_validator_.GetPathValidationReason());
}
TEST_F(QuicPathValidatorTest, RespondWithDifferentSelfAddress) {
@@ -115,7 +120,8 @@
const QuicTime expected_start_time = clock_.Now();
path_validator_.StartPathValidation(
std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+ std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_),
+ PathValidationReason::kMultiPort);
// Reception of a PATH_RESPONSE on a different self address should be ignored.
const QuicSocketAddress kAlternativeSelfAddress(QuicIpAddress::Any6(), 54321);
@@ -131,6 +137,8 @@
}));
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(kInitialRttMs));
path_validator_.OnPathResponse(challenge_data, self_address_);
+ EXPECT_EQ(PathValidationReason::kReasonUnknown,
+ path_validator_.GetPathValidationReason());
}
TEST_F(QuicPathValidatorTest, RespondAfter1stRetry) {
@@ -156,7 +164,8 @@
const QuicTime start_time = clock_.Now();
path_validator_.StartPathValidation(
std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+ std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_),
+ PathValidationReason::kMultiPort);
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
random_.ChangeValue();
@@ -191,7 +200,8 @@
.Times(2u);
path_validator_.StartPathValidation(
std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+ std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_),
+ PathValidationReason::kMultiPort);
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
const QuicTime start_time = clock_.Now();
@@ -215,7 +225,8 @@
.Times(3u);
path_validator_.StartPathValidation(
std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+ std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_),
+ PathValidationReason::kMultiPort);
QuicPathFrameBuffer challenge_data;
memset(challenge_data.data(), 'a', challenge_data.size());
@@ -232,6 +243,8 @@
alarm_factory_.FireAlarm(
QuicPathValidatorPeer::retry_timer(&path_validator_));
}
+ EXPECT_EQ(PathValidationReason::kReasonUnknown,
+ path_validator_.GetPathValidationReason());
}
TEST_F(QuicPathValidatorTest, SendPathChallengeError) {
@@ -251,9 +264,12 @@
EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_));
path_validator_.StartPathValidation(
std::unique_ptr<QuicPathValidationContext>(context_),
- std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+ std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_),
+ PathValidationReason::kMultiPort);
EXPECT_FALSE(path_validator_.HasPendingPathValidation());
EXPECT_FALSE(QuicPathValidatorPeer::retry_timer(&path_validator_)->IsSet());
+ EXPECT_EQ(PathValidationReason::kReasonUnknown,
+ path_validator_.GetPathValidationReason());
}
} // namespace test
diff --git a/quiche/quic/core/quic_session.cc b/quiche/quic/core/quic_session.cc
index 7aaa65b..a58e572 100644
--- a/quiche/quic/core/quic_session.cc
+++ b/quiche/quic/core/quic_session.cc
@@ -2658,8 +2658,10 @@
void QuicSession::ValidatePath(
std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
- connection_->ValidatePath(std::move(context), std::move(result_delegate));
+ std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,
+ PathValidationReason reason) {
+ connection_->ValidatePath(std::move(context), std::move(result_delegate),
+ reason);
}
bool QuicSession::HasPendingPathValidation() const {
diff --git a/quiche/quic/core/quic_session.h b/quiche/quic/core/quic_session.h
index ec52225..4ef5579 100644
--- a/quiche/quic/core/quic_session.h
+++ b/quiche/quic/core/quic_session.h
@@ -464,7 +464,8 @@
// };
void ValidatePath(
std::unique_ptr<QuicPathValidationContext> context,
- std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
+ std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,
+ PathValidationReason reason);
// Return true if there is a path being validated.
bool HasPendingPathValidation() const;
diff --git a/quiche/quic/tools/quic_client_base.cc b/quiche/quic/tools/quic_client_base.cc
index 02b56a4..4612be0 100644
--- a/quiche/quic/tools/quic_client_base.cc
+++ b/quiche/quic/tools/quic_client_base.cc
@@ -315,8 +315,8 @@
std::make_unique<PathMigrationContext>(
std::move(writer), network_helper_->GetLatestClientAddress(),
session_->peer_address()),
- std::make_unique<QuicClientSocketMigrationValidationResultDelegate>(
- this));
+ std::make_unique<QuicClientSocketMigrationValidationResultDelegate>(this),
+ PathValidationReason::kConnectionMigration);
return true;
}
@@ -519,7 +519,7 @@
std::make_unique<PathMigrationContext>(
std::move(writer), network_helper_->GetLatestClientAddress(),
session_->peer_address()),
- std::move(result_delegate));
+ std::move(result_delegate), PathValidationReason::kConnectionMigration);
}
void QuicClientBase::OnServerPreferredAddressAvailable(
@@ -538,7 +538,8 @@
std::make_unique<PathMigrationContext>(
std::unique_ptr<QuicPacketWriter>(writer),
network_helper_->GetLatestClientAddress(), server_preferred_address),
- std::make_unique<ServerPreferredAddressResultDelegateWithWriter>(this));
+ std::make_unique<ServerPreferredAddressResultDelegateWithWriter>(this),
+ PathValidationReason::kServerPreferredAddressMigration);
}
} // namespace quic