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: