From 11b24e7b7df8a8ca104a9d5643397a58882f50ff Mon Sep 17 00:00:00 2001 From: Renjie Tang Date: Mon, 26 Jul 2021 14:48:28 -0700 Subject: [PATCH 1/2] add QUIC upstream stream reset error stats Signed-off-by: Renjie Tang --- .../common/quic/envoy_quic_client_session.cc | 14 ++++++++++ .../common/quic/envoy_quic_client_session.h | 3 +++ .../quic/envoy_quic_client_session_test.cc | 27 ++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/source/common/quic/envoy_quic_client_session.cc b/source/common/quic/envoy_quic_client_session.cc index e300b820f873e..2bf290113682f 100644 --- a/source/common/quic/envoy_quic_client_session.cc +++ b/source/common/quic/envoy_quic_client_session.cc @@ -77,6 +77,20 @@ void EnvoyQuicClientSession::OnHttp3GoAway(uint64_t stream_id) { } } +void EnvoyQuicClientSession::MaybeSendRstStreamFrame(quic::QuicStreamId id, + quic::QuicRstStreamErrorCode error, + quic::QuicStreamOffset bytes_written) { + QuicSpdyClientSession::MaybeSendRstStreamFrame(id, error, bytes_written); + quic_stat_names_.chargeQuicResetStreamErrorStats(scope_, error, /*from_self*/ true, + /*is_upstream*/ true); +} + +void EnvoyQuicClientSession::OnRstStream(const quic::QuicRstStreamFrame& frame) { + QuicSpdyClientSession::OnRstStream(frame); + quic_stat_names_.chargeQuicResetStreamErrorStats(scope_, frame.error_code, + /*from_self*/ false, /*is_upstream*/ true); +} + void EnvoyQuicClientSession::SetDefaultEncryptionLevel(quic::EncryptionLevel level) { quic::QuicSpdyClientSession::SetDefaultEncryptionLevel(level); if (level == quic::ENCRYPTION_FORWARD_SECURE) { diff --git a/source/common/quic/envoy_quic_client_session.h b/source/common/quic/envoy_quic_client_session.h index 307a191e36225..7239e51850a41 100644 --- a/source/common/quic/envoy_quic_client_session.h +++ b/source/common/quic/envoy_quic_client_session.h @@ -71,6 +71,9 @@ class EnvoyQuicClientSession : public QuicFilterManagerConnectionImpl, quic::QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin, const spdy::SpdyStreamPrecedence& precedence, quic::QuicReferenceCountedPointer ack_listener) override; + void MaybeSendRstStreamFrame(quic::QuicStreamId id, quic::QuicRstStreamErrorCode error, + quic::QuicStreamOffset bytes_written) override; + void OnRstStream(const quic::QuicRstStreamFrame& frame) override; // quic::QuicSpdyClientSessionBase void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override; diff --git a/test/common/quic/envoy_quic_client_session_test.cc b/test/common/quic/envoy_quic_client_session_test.cc index 812818016fe2f..76bb3ebb73bb5 100644 --- a/test/common/quic/envoy_quic_client_session_test.cc +++ b/test/common/quic/envoy_quic_client_session_test.cc @@ -232,7 +232,29 @@ TEST_P(EnvoyQuicClientSessionTest, OnResetFrame) { quic::QuicRstStreamFrame rst1(/*control_frame_id=*/1u, stream_id, quic::QUIC_ERROR_PROCESSING_STREAM, /*bytes_written=*/0u); EXPECT_CALL(stream_callbacks, onResetStream(Http::StreamResetReason::RemoteReset, _)); - stream.OnStreamReset(rst1); + envoy_quic_session_.OnRstStream(rst1); + + EXPECT_EQ( + 1U, TestUtility::findCounter( + store_, "http3.upstream.rx.quic_reset_stream_error_code_QUIC_ERROR_PROCESSING_STREAM") + ->value()); +} + +TEST_P(EnvoyQuicClientSessionTest, SendResetFrame) { + Http::MockResponseDecoder response_decoder; + Http::MockStreamCallbacks stream_callbacks; + EnvoyQuicClientStream& stream = sendGetRequest(response_decoder, stream_callbacks); + + // G-QUIC or IETF bi-directional stream. + quic::QuicStreamId stream_id = stream.id(); + EXPECT_CALL(stream_callbacks, onResetStream(Http::StreamResetReason::LocalReset, _)); + EXPECT_CALL(*quic_connection_, SendControlFrame(_)); + envoy_quic_session_.ResetStream(stream_id, quic::QUIC_ERROR_PROCESSING_STREAM); + + EXPECT_EQ( + 1U, TestUtility::findCounter( + store_, "http3.upstream.tx.quic_reset_stream_error_code_QUIC_ERROR_PROCESSING_STREAM") + ->value()); } TEST_P(EnvoyQuicClientSessionTest, OnGoAwayFrame) { @@ -277,6 +299,9 @@ TEST_P(EnvoyQuicClientSessionTest, ConnectionCloseWithActiveStream) { envoy_quic_session_.close(Network::ConnectionCloseType::NoFlush); EXPECT_EQ(Network::Connection::State::Closed, envoy_quic_session_.state()); EXPECT_TRUE(stream.write_side_closed() && stream.reading_stopped()); + EXPECT_EQ(1U, TestUtility::findCounter( + store_, "http3.upstream.tx.quic_connection_close_error_code_QUIC_NO_ERROR") + ->value()); } class EnvoyQuicClientSessionAllQuicVersionTest From 0af988c93556b18a533921c0b55cb08628f5aa59 Mon Sep 17 00:00:00 2001 From: Renjie Tang Date: Mon, 26 Jul 2021 14:54:31 -0700 Subject: [PATCH 2/2] add doc Signed-off-by: Renjie Tang --- .../configuration/upstream/cluster_manager/cluster_stats.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/root/configuration/upstream/cluster_manager/cluster_stats.rst b/docs/root/configuration/upstream/cluster_manager/cluster_stats.rst index 17b5e2da387ce..a7914866c29d6 100644 --- a/docs/root/configuration/upstream/cluster_manager/cluster_stats.rst +++ b/docs/root/configuration/upstream/cluster_manager/cluster_stats.rst @@ -114,7 +114,8 @@ HTTP/3 protocol stats are global with the following statistics: :header: Name, Type, Description :widths: 1, 1, 2 - .quic_connection_close_error_code_, Counter, A collection of counters that are lazily initialized to record each QUIC connection close's error code. + upstream..quic_connection_close_error_code_, Counter, A collection of counters that are lazily initialized to record each QUIC connection close's error code. + upstream..quic_reset_stream_error_code_, Counter, A collection of counters that are lazily initialized to record each QUIC stream reset error code. Health check statistics