Populate stats needed for multi-port. These stats will be logged by QuicConnectionLogger in Chrome. PiperOrigin-RevId: 473031102
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc index a3c0339..d359c28 100644 --- a/quiche/quic/core/quic_connection.cc +++ b/quiche/quic/core/quic_connection.cc
@@ -681,6 +681,9 @@ multi_port_enabled_ = connection_migration_use_new_cid_ && config.HasClientSentConnectionOption(kMPQC, perspective_); + if (multi_port_enabled_) { + multi_port_stats_ = std::make_unique<MultiPortStats>(); + } } void QuicConnection::EnableLegacyVersionEncapsulation( @@ -6237,6 +6240,9 @@ void QuicConnection::OnPathDegradingDetected() { is_path_degrading_ = true; + if (multi_port_stats_) { + multi_port_stats_->num_path_degrading++; + } visitor_->OnPathDegrading(); } @@ -6888,11 +6894,21 @@ return true; } -void QuicConnection::OnPathValidationFailureAtClient() { +void QuicConnection::OnPathValidationFailureAtClient(bool is_multi_port) { if (connection_migration_use_new_cid_) { QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT); alternative_path_.Clear(); } + + if (is_multi_port && multi_port_stats_ != nullptr) { + if (is_path_degrading_) { + multi_port_stats_->num_multi_port_probe_failures_when_path_degrading++; + } else { + multi_port_stats_ + ->num_multi_port_probe_failures_when_path_not_degrading++; + } + } + RetirePeerIssuedConnectionIdsOnPathValidationFailure(); } @@ -7111,10 +7127,20 @@ } void QuicConnection::OnMultiPortPathProbingSuccess( - std::unique_ptr<QuicPathValidationContext> context) { + std::unique_ptr<QuicPathValidationContext> context, QuicTime start_time) { multi_port_path_context_ = std::move(context); multi_port_probing_alarm_->Set(clock_->ApproximateNow() + multi_port_probing_interval_); + if (multi_port_stats_ != nullptr) { + auto now = clock_->Now(); + auto time_delta = now - start_time; + multi_port_stats_->rtt_stats.UpdateRtt(time_delta, QuicTime::Delta::Zero(), + now); + if (is_path_degrading_) { + multi_port_stats_->rtt_stats_when_default_path_degrading.UpdateRtt( + time_delta, QuicTime::Delta::Zero(), now); + } + } } void QuicConnection::ProbeMultiPortPath() { @@ -7141,14 +7167,14 @@ void QuicConnection::MultiPortPathValidationResultDelegate:: OnPathValidationSuccess(std::unique_ptr<QuicPathValidationContext> context, - QuicTime /*start_time*/) { - connection_->OnMultiPortPathProbingSuccess(std::move(context)); + QuicTime start_time) { + connection_->OnMultiPortPathProbingSuccess(std::move(context), start_time); } void QuicConnection::MultiPortPathValidationResultDelegate:: OnPathValidationFailure( std::unique_ptr<QuicPathValidationContext> /*context*/) { - connection_->OnPathValidationFailureAtClient(); + connection_->OnPathValidationFailureAtClient(/*is_multi_port=*/true); } QuicConnection::ReversePathValidationResultDelegate::
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h index fd4c420..de52154 100644 --- a/quiche/quic/core/quic_connection.h +++ b/quiche/quic/core/quic_connection.h
@@ -26,6 +26,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "quiche/quic/core/congestion_control/rtt_stats.h" #include "quiche/quic/core/crypto/quic_decrypter.h" #include "quiche/quic/core/crypto/quic_encrypter.h" #include "quiche/quic/core/crypto/transport_parameters.h" @@ -481,6 +482,19 @@ QuicConnection& operator=(const QuicConnection&) = delete; ~QuicConnection() override; + struct MultiPortStats { + // general rtt stats of the multi-port path. + RttStats rtt_stats; + // rtt stats for the multi-port path when the default path is degrading. + RttStats rtt_stats_when_default_path_degrading; + // number of path degrading triggered when multi-port is enabled. + size_t num_path_degrading = 0; + // number of multi-port probe failures when path is not degrading + size_t num_multi_port_probe_failures_when_path_not_degrading = 0; + // number of multi-port probe failure when path is degrading + size_t num_multi_port_probe_failures_when_path_degrading = 0; + }; + // Sets connection parameters from the supplied |config|. void SetFromConfig(const QuicConfig& config); @@ -748,7 +762,7 @@ // Called in multi-port QUIC when the alternative path validation succeeds. // Stores the path validation context and prepares for the next validation. void OnMultiPortPathProbingSuccess( - std::unique_ptr<QuicPathValidationContext> context); + std::unique_ptr<QuicPathValidationContext> context, QuicTime start_time); // Probe the existing alternative path. Does not create a new alternative // path. This method is the callback for |multi_port_probing_alarm_|. @@ -821,6 +835,10 @@ multi_port_probing_interval_ = probing_interval; } + const MultiPortStats* multi_port_stats() const { + return multi_port_stats_.get(); + } + // Called when the ping alarm fires. Causes a ping frame to be sent only // if the retransmission alarm is not running. void OnPingTimeout(); @@ -1210,7 +1228,7 @@ // Called to clear the alternative_path_ when path validation failed on the // client side. - void OnPathValidationFailureAtClient(); + void OnPathValidationFailureAtClient(bool is_multi_port); void SetSourceAddressTokenToSend(absl::string_view token); @@ -2286,6 +2304,8 @@ QuicTime::Delta multi_port_probing_interval_; + std::unique_ptr<MultiPortStats> multi_port_stats_; + RetransmittableOnWireBehavior retransmittable_on_wire_behavior_ = DEFAULT; bool only_send_probing_frames_on_alternative_path_ =
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc index b2da24e..73300f7 100644 --- a/quiche/quic/core/quic_connection_test.cc +++ b/quiche/quic/core/quic_connection_test.cc
@@ -2474,7 +2474,7 @@ EXPECT_EQ(expected_self_address_, context->self_address()); EXPECT_EQ(expected_peer_address_, context->peer_address()); if (connection_->perspective() == Perspective::IS_CLIENT) { - connection_->OnPathValidationFailureAtClient(); + connection_->OnPathValidationFailureAtClient(/*is_multi_port=*/false); } *success_ = false; } @@ -13003,6 +13003,9 @@ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); connection_.OnHandshakeComplete(); + EXPECT_CALL(visitor_, OnPathDegrading()); + connection_.OnPathDegradingDetected(); + auto self_address = connection_.self_address(); const QuicSocketAddress kNewSelfAddress(self_address.host(), self_address.port() + 1); @@ -13025,6 +13028,11 @@ EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath( &connection_, kNewSelfAddress, connection_.peer_address())); + // 30ms RTT. + const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30); + // Fake a response delay. + clock_.AdvanceTime(kTestRTT); + QuicFrames frames; frames.push_back(QuicFrame(QuicPathResponseFrame( 99, new_writer.path_challenge_frames().front().data_buffer))); @@ -13035,6 +13043,13 @@ EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath( &connection_, kNewSelfAddress, connection_.peer_address())); + auto stats = connection_.multi_port_stats(); + EXPECT_EQ(1, stats->num_path_degrading); + EXPECT_EQ(0, stats->num_multi_port_probe_failures_when_path_degrading); + EXPECT_EQ(kTestRTT, stats->rtt_stats.latest_rtt()); + EXPECT_EQ(kTestRTT, + stats->rtt_stats_when_default_path_degrading.latest_rtt()); + connection_.GetMultiPortProbingAlarm()->Fire(); EXPECT_TRUE(connection_.HasPendingPathValidation()); EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath( @@ -13050,6 +13065,9 @@ EXPECT_FALSE(connection_.HasPendingPathValidation()); EXPECT_FALSE(QuicConnectionPeer::IsAlternativePath( &connection_, kNewSelfAddress, connection_.peer_address())); + EXPECT_EQ(1, stats->num_path_degrading); + EXPECT_EQ(1, stats->num_multi_port_probe_failures_when_path_degrading); + EXPECT_EQ(0, stats->num_multi_port_probe_failures_when_path_not_degrading); } TEST_P(QuicConnectionTest, SingleAckInPacket) {
diff --git a/quiche/quic/tools/quic_client_base.cc b/quiche/quic/tools/quic_client_base.cc index 766aa57..9277913 100644 --- a/quiche/quic/tools/quic_client_base.cc +++ b/quiche/quic/tools/quic_client_base.cc
@@ -49,7 +49,8 @@ std::unique_ptr<QuicPathValidationContext> context) override { QUIC_LOG(WARNING) << "Fail to validate path " << *context << ", stop migrating."; - client_->session()->connection()->OnPathValidationFailureAtClient(); + client_->session()->connection()->OnPathValidationFailureAtClient( + /*is_multi_port=*/false); } private: @@ -464,7 +465,8 @@ std::unique_ptr<QuicPathValidationContext> context) override { QUIC_LOG(WARNING) << "Fail to validate path " << *context << ", stop migrating."; - client_->session()->connection()->OnPathValidationFailureAtClient(); + client_->session()->connection()->OnPathValidationFailureAtClient( + /*is_multi_port=*/false); } private: