Skip to content

Commit

Permalink
UHV: Enable oghttp2 and UHV in HTTP/2 flood test (envoyproxy#27543)
Browse files Browse the repository at this point in the history
Enable oghttp2 and UHV in HTTP/2 flood test

Signed-off-by: Yan Avlasov <yavlasov@google.com>
Signed-off-by: Ryan Eskin <ryan.eskin89@protonmail.com>
  • Loading branch information
yanavlasov authored and reskin89 committed Jul 11, 2023
1 parent 8c0da6d commit 6732e5b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
1 change: 0 additions & 1 deletion source/common/http/codec_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ void CodecClient::ActiveRequest::decodeHeaders(ResponseHeaderMapPtr&& headers, b
.http3Options()
.override_stream_error_on_invalid_http_message()
.value())) {
parent_.host_->cluster().trafficStats()->upstream_cx_protocol_error_.inc();
parent_.protocol_error_ = true;
parent_.close();
} else {
Expand Down
38 changes: 27 additions & 11 deletions test/integration/http2_flood_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,18 @@ namespace {
const uint32_t ControlFrameFloodLimit = 100;
const uint32_t AllFrameFloodLimit = 1000;

bool deferredProcessing(std::tuple<Network::Address::IpVersion, bool, bool> params) {
bool deferredProcessing(std::tuple<Network::Address::IpVersion, Http2Impl, bool> params) {
return std::get<2>(params);
}

} // namespace

std::string testParamsToString(
const ::testing::TestParamInfo<std::tuple<Network::Address::IpVersion, bool, bool>> params) {
const bool http2_new_codec_wrapper = std::get<1>(params.param);
const ::testing::TestParamInfo<std::tuple<Network::Address::IpVersion, Http2Impl, bool>>
params) {
const Http2Impl http2_codec_impl = std::get<1>(params.param);
return absl::StrCat(TestUtility::ipVersionToString(std::get<0>(params.param)),
http2_new_codec_wrapper ? "WrappedHttp2" : "BareHttp2",
http2_codec_impl == Http2Impl::Oghttp2 ? "Oghttp2" : "Nghttp2",
deferredProcessing(params.param) ? "WithDeferredProcessing"
: "NoDeferredProcessing");
}
Expand All @@ -53,7 +54,7 @@ std::string testParamsToString(
// Http2FrameIntegrationTest destructor completes.
class Http2FloodMitigationTest
: public SocketInterfaceSwap,
public testing::TestWithParam<std::tuple<Network::Address::IpVersion, bool, bool>>,
public testing::TestWithParam<std::tuple<Network::Address::IpVersion, Http2Impl, bool>>,
public Http2RawFrameIntegrationTest {
public:
Http2FloodMitigationTest()
Expand All @@ -67,9 +68,7 @@ class Http2FloodMitigationTest
[](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
hcm) { hcm.mutable_delayed_close_timeout()->set_seconds(1); });
config_helper_.addConfigModifier(configureProxyStatus());
const bool enable_new_wrapper = std::get<1>(GetParam());
config_helper_.addRuntimeOverride("envoy.reloadable_features.http2_new_codec_wrapper",
enable_new_wrapper ? "true" : "false");
setupHttp2ImplOverrides(std::get<1>(GetParam()));
config_helper_.addRuntimeOverride(Runtime::defer_processing_backedup_streams,
deferredProcessing(GetParam()) ? "true" : "false");
}
Expand All @@ -92,7 +91,8 @@ class Http2FloodMitigationTest

INSTANTIATE_TEST_SUITE_P(
IpVersions, Http2FloodMitigationTest,
testing::Combine(testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), ::testing::Bool(),
testing::Combine(testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
testing::ValuesIn({Http2Impl::Nghttp2, Http2Impl::Oghttp2}),
::testing::Bool()),
testParamsToString);

Expand Down Expand Up @@ -680,6 +680,14 @@ TEST_P(Http2FloodMitigationTest, WindowUpdateOnLowWatermarkFlood) {

// Verify that the server can detect flood of RST_STREAM frames.
TEST_P(Http2FloodMitigationTest, RST_STREAM) {
#ifdef ENVOY_ENABLE_UHV
// TODO(#27541): the invalid frame that used to cause Envoy to send only RST_STREAM now causes
// Envoy to also send 400 in UHV mode (it is allowed by RFC). The test needs to be fixed to make
// server only send RST_STREAM.
if (std::get<1>(GetParam()) == Http2Impl::Oghttp2) {
return;
}
#endif
// Use invalid HTTP headers to trigger sending RST_STREAM frames.
config_helper_.addConfigModifier(
[](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
Expand Down Expand Up @@ -1120,13 +1128,21 @@ TEST_P(Http2FloodMitigationTest, ZerolenHeader) {
EXPECT_EQ(1, test_server_->counter("http2.rx_messaging_error")->value());
EXPECT_EQ(1,
test_server_->counter("http.config_test.downstream_cx_delayed_close_timeout")->value());
EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("http2.invalid.header.field"));
EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("header"));
// expect a downstream protocol error.
EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("DPE"));
}

// Verify that only the offending stream is terminated upon receiving invalid HEADERS frame.
TEST_P(Http2FloodMitigationTest, ZerolenHeaderAllowed) {
#ifdef ENVOY_ENABLE_UHV
// TODO(#27541): the invalid frame that used to cause Envoy to send only RST_STREAM now causes
// Envoy to also send 400 in UHV mode (it is allowed by RFC). The test needs to be fixed to make
// server only send RST_STREAM.
if (std::get<1>(GetParam()) == Http2Impl::Oghttp2) {
return;
}
#endif
useAccessLog("%RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS%");
config_helper_.addConfigModifier(
[](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
Expand Down Expand Up @@ -1161,7 +1177,7 @@ TEST_P(Http2FloodMitigationTest, ZerolenHeaderAllowed) {
EXPECT_EQ(0,
test_server_->counter("http.config_test.downstream_cx_delayed_close_timeout")->value());
// expect Downstream Protocol Error
EXPECT_THAT(waitForAccessLog(access_log_name_, 0, true), HasSubstr("http2.invalid.header.field"));
EXPECT_THAT(waitForAccessLog(access_log_name_, 0, true), HasSubstr("header"));
EXPECT_THAT(waitForAccessLog(access_log_name_, 0, true), HasSubstr("DPE"));
}

Expand Down

0 comments on commit 6732e5b

Please sign in to comment.