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