Record stats when forward progress is made on a QUIC connection after
changing the flow label on PTO.
PiperOrigin-RevId: 691148078
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 21c7dad..7df6663 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -208,6 +208,7 @@
bundle_retransmittable_with_pto_ack_(false),
last_control_frame_id_(kInvalidControlFrameId),
is_path_degrading_(false),
+ flow_label_has_changed_(false),
processing_ack_frame_(false),
supports_release_time_(false),
release_time_into_future_(QuicTime::Delta::Zero()),
@@ -4205,6 +4206,8 @@
}
if (enable_black_hole_avoidance_via_flow_label_) {
GenerateNewOutgoingFlowLabel();
+ ++stats_.num_flow_label_changes;
+ flow_label_has_changed_ = true;
expect_peer_flow_label_change_ = true;
QUIC_CODE_COUNT(quic_generated_new_flow_label_on_pto);
}
@@ -6136,6 +6139,11 @@
stats_.num_forward_progress_after_path_degrading++;
is_path_degrading_ = false;
}
+ if (flow_label_has_changed_) {
+ visitor_->OnForwardProgressMadeAfterFlowLabelChange();
+ stats_.num_forward_progress_after_flow_label_change++;
+ flow_label_has_changed_ = false;
+ }
if (sent_packet_manager_.HasInFlightPackets()) {
// Restart detections if forward progress has been made.
blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index 9f647c8..305d1a9 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -166,6 +166,9 @@
// Called when forward progress made after path degrading.
virtual void OnForwardProgressMadeAfterPathDegrading() = 0;
+ // Called when forward progress made after flow label change
+ virtual void OnForwardProgressMadeAfterFlowLabelChange() = 0;
+
// Called when the connection sends ack after
// max_consecutive_num_packets_with_no_retransmittable_frames_ consecutive not
// retransmittable packets sent. To instigate an ack from peer, a
@@ -2410,6 +2413,9 @@
// True if the peer is unreachable on the current path.
bool is_path_degrading_;
+ // True if the outgoing flow label has changed since the last foward progress.
+ bool flow_label_has_changed_;
+
// True if an ack frame is being processed.
bool processing_ack_frame_;
diff --git a/quiche/quic/core/quic_connection_stats.h b/quiche/quic/core/quic_connection_stats.h
index 0a4a696..dfe9bab 100644
--- a/quiche/quic/core/quic_connection_stats.h
+++ b/quiche/quic/core/quic_connection_stats.h
@@ -232,6 +232,10 @@
size_t num_path_degrading = 0;
// Number of forward progress made after path degrading.
size_t num_forward_progress_after_path_degrading = 0;
+ // Number of path degrading.
+ size_t num_flow_label_changes = 0;
+ // Number of forward progress made after aflow label change.
+ size_t num_forward_progress_after_flow_label_change = 0;
bool server_preferred_address_validated = false;
bool failed_to_validate_server_preferred_address = false;
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 9d5a937..007f422 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -10043,6 +10043,14 @@
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
connection_.GetRetransmissionAlarm()->Fire();
EXPECT_NE(flow_label, connection_.outgoing_flow_label());
+ EXPECT_EQ(1, connection_.GetStats().num_flow_label_changes);
+
+ EXPECT_CALL(visitor_, OnForwardProgressMadeAfterFlowLabelChange());
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
+ QuicAckFrame frame = InitAckFrame(last_packet);
+ ProcessAckPacket(1, &frame);
+ EXPECT_EQ(
+ 1, connection_.GetStats().num_forward_progress_after_flow_label_change);
}
TEST_P(QuicConnectionTest, NewReceiveNewFlowLabelWithGapChangesFlowLabel) {
diff --git a/quiche/quic/core/quic_session.cc b/quiche/quic/core/quic_session.cc
index afdb44b..b83d773 100644
--- a/quiche/quic/core/quic_session.cc
+++ b/quiche/quic/core/quic_session.cc
@@ -645,6 +645,8 @@
void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
+void QuicSession::OnForwardProgressMadeAfterFlowLabelChange() {}
+
bool QuicSession::AllowSelfAddressChange() const { return false; }
void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
diff --git a/quiche/quic/core/quic_session.h b/quiche/quic/core/quic_session.h
index 8be519a..5ec9838 100644
--- a/quiche/quic/core/quic_session.h
+++ b/quiche/quic/core/quic_session.h
@@ -173,6 +173,7 @@
std::string GetStreamsInfoForLogging() const override;
void OnPathDegrading() override;
void OnForwardProgressMadeAfterPathDegrading() override;
+ void OnForwardProgressMadeAfterFlowLabelChange() override;
bool AllowSelfAddressChange() const override;
HandshakeState GetHandshakeState() const override;
bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h
index 7842c5a..f2fe5a5 100644
--- a/quiche/quic/test_tools/quic_test_utils.h
+++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -473,6 +473,7 @@
(override));
MOCK_METHOD(void, OnPathDegrading, (), (override));
MOCK_METHOD(void, OnForwardProgressMadeAfterPathDegrading, (), (override));
+ MOCK_METHOD(void, OnForwardProgressMadeAfterFlowLabelChange, (), (override));
MOCK_METHOD(bool, WillingAndAbleToWrite, (), (const, override));
MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
MOCK_METHOD(std::string, GetStreamsInfoForLogging, (), (const, override));
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint.h b/quiche/quic/test_tools/simulator/quic_endpoint.h
index 700bcd2..9f2650d 100644
--- a/quiche/quic/test_tools/simulator/quic_endpoint.h
+++ b/quiche/quic/test_tools/simulator/quic_endpoint.h
@@ -71,6 +71,7 @@
void OnConnectionMigration(AddressChangeType /*type*/) override {}
void OnPathDegrading() override {}
void OnForwardProgressMadeAfterPathDegrading() override {}
+ void OnForwardProgressMadeAfterFlowLabelChange() override {}
void OnAckNeedsRetransmittableFrame() override {}
void SendAckFrequency(const QuicAckFrequencyFrame& /*frame*/) override {}
void SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {