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 {