Skip to content

Commit

Permalink
quiche: make flow control configurable (envoyproxy#15865)
Browse files Browse the repository at this point in the history
Commit Message: Add initial stream and connection level flow control windows to envoy.config.core.v3.QuicProtocolOptions which is be used in QUIC listener config and Http3 upstream cluster config.

Risk Level: low
Testing: re-enable more Http3 downstream protocol test.

Part of envoyproxy#2557 envoyproxy#12930 envoyproxy#14829

Signed-off-by: Dan Zhang <danzh@google.com>
Co-authored-by: Dan Zhang <danzh@google.com>
Signed-off-by: Gokul Nair <gnair@twitter.com>
  • Loading branch information
2 people authored and Gokul Nair committed May 6, 2021
1 parent 6ace0e0 commit 7bf71a4
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 10 deletions.
1 change: 1 addition & 0 deletions source/common/quic/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ envoy_cc_library(
"//source/common/network:socket_option_factory_lib",
"//source/common/quic:quic_io_handle_wrapper_lib",
"//source/extensions/transport_sockets:well_known_names",
"@com_googlesource_quiche//:quic_core_config_lib",
"@com_googlesource_quiche//:quic_core_http_header_list_lib",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
"@envoy_api//envoy/config/listener/v3:pkg_cc_proto",
Expand Down
2 changes: 1 addition & 1 deletion source/common/quic/client_connection_factory_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ createQuicNetworkConnection(Http::PersistentQuicInfo& info, Event::Dispatcher& d
auto ret = std::make_unique<EnvoyQuicClientSession>(
info_impl->quic_config_, info_impl->supported_versions_, std::move(connection),
info_impl->server_id_, info_impl->crypto_config_.get(), &static_info.push_promise_index_,
dispatcher, 0);
dispatcher, /*send_buffer_limit=*/0);
return ret;
}

Expand Down
6 changes: 0 additions & 6 deletions source/common/quic/envoy_quic_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ std::unique_ptr<quic::QuicSession> EnvoyQuicDispatcher::CreateQuicSession(
const quic::QuicSocketAddress& peer_address, absl::string_view alpn,
const quic::ParsedQuicVersion& version, absl::string_view sni) {
quic::QuicConfig quic_config = config();
// TODO(danzh) setup flow control window via config.
quic_config.SetInitialStreamFlowControlWindowToSend(
Http2::Utility::OptionsLimits::MIN_INITIAL_STREAM_WINDOW_SIZE);
quic_config.SetInitialSessionFlowControlWindowToSend(
1.5 * Http2::Utility::OptionsLimits::MIN_INITIAL_STREAM_WINDOW_SIZE);

Network::ConnectionSocketPtr connection_socket = createServerConnectionSocket(
listen_socket_.ioHandle(), self_address, peer_address, std::string(sni), alpn);
const Network::FilterChain* filter_chain =
Expand Down
26 changes: 26 additions & 0 deletions source/common/quic/envoy_quic_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -244,5 +244,31 @@ createServerConnectionSocket(Network::IoHandle& io_handle,
return connection_socket;
}

void configQuicInitialFlowControlWindow(const envoy::config::core::v3::QuicProtocolOptions& config,
quic::QuicConfig& quic_config) {
size_t stream_flow_control_window_to_send = PROTOBUF_GET_WRAPPED_OR_DEFAULT(
config, initial_stream_window_size,
Http3::Utility::OptionsLimits::DEFAULT_INITIAL_STREAM_WINDOW_SIZE);
if (stream_flow_control_window_to_send < quic::kMinimumFlowControlSendWindow) {
// If the configured value is smaller than 16kB, only use it for IETF QUIC, because Google QUIC
// requires minimum 16kB stream flow control window. The QUICHE default 16kB will be used for
// Google QUIC connections.
quic_config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
stream_flow_control_window_to_send);
} else {
// Both Google QUIC and IETF Quic can be configured from this.
quic_config.SetInitialStreamFlowControlWindowToSend(stream_flow_control_window_to_send);
}

uint32_t session_flow_control_window_to_send = PROTOBUF_GET_WRAPPED_OR_DEFAULT(
config, initial_connection_window_size,
Http3::Utility::OptionsLimits::DEFAULT_INITIAL_CONNECTION_WINDOW_SIZE);
// Config connection level flow control window shouldn't be smaller than the minimum flow control
// window supported in QUICHE which is 16kB.
quic_config.SetInitialSessionFlowControlWindowToSend(
std::max(quic::kMinimumFlowControlSendWindow,
static_cast<quic::QuicByteCount>(session_flow_control_window_to_send)));
}

} // namespace Quic
} // namespace Envoy
4 changes: 4 additions & 0 deletions source/common/quic/envoy_quic_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,9 @@ createServerConnectionSocket(Network::IoHandle& io_handle,
const quic::QuicSocketAddress& peer_address,
const std::string& hostname, absl::string_view alpn);

// Set initial flow control windows in quic_config according to the given Envoy config.
void configQuicInitialFlowControlWindow(const envoy::config::core::v3::QuicProtocolOptions& config,
quic::QuicConfig& quic_config);

} // namespace Quic
} // namespace Envoy
10 changes: 10 additions & 0 deletions test/common/quic/envoy_quic_client_stream_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,16 @@ TEST_P(EnvoyQuicClientStreamTest, CloseConnectionDuringDecodingTrailer) {
}
}

TEST_P(EnvoyQuicClientStreamTest, MetadataNotSupported) {
Http::MetadataMap metadata_map = {{"key", "value"}};
Http::MetadataMapPtr metadata_map_ptr = std::make_unique<Http::MetadataMap>(metadata_map);
Http::MetadataMapVector metadata_map_vector;
metadata_map_vector.push_back(std::move(metadata_map_ptr));
quic_stream_->encodeMetadata(metadata_map_vector);
EXPECT_EQ(1, TestUtility::findCounter(scope_, "http3.metadata_not_supported_error")->value());
EXPECT_CALL(stream_callbacks_, onResetStream(_, _));
}

// Tests that posted stream block callback won't cause use-after-free crash.
TEST_P(EnvoyQuicClientStreamTest, ReadDisabledBeforeClose) {
const auto result = quic_stream_->encodeHeaders(request_headers_, /*end_stream=*/true);
Expand Down
2 changes: 0 additions & 2 deletions test/integration/multiplexed_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ TEST_P(Http2IntegrationTest, FlowControlOnAndGiantBodyWithContentLength) {
}

TEST_P(Http2IntegrationTest, LargeFlowControlOnAndGiantBodyWithContentLength) {
// https://github.com/envoyproxy/envoy/issues/16335
EXCLUDE_DOWNSTREAM_HTTP3;
config_helper_.addConfigModifier(ConfigHelper::adjustUpstreamTimeoutForTsan);
config_helper_.setBufferLimits(128 * 1024,
128 * 1024); // Set buffer limits upstream and downstream.
Expand Down
2 changes: 1 addition & 1 deletion test/integration/quic_http_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ TEST_P(QuicHttpIntegrationTest, UpstreamReadDisabledOnGiantResponseBody) {
}

TEST_P(QuicHttpIntegrationTest, DownstreamReadDisabledOnGiantPost) {
config_helper_.addConfigModifier(setUpstreamTimeout);
config_helper_.addConfigModifier(ConfigHelper::adjustUpstreamTimeoutForTsan);
config_helper_.setBufferLimits(/*upstream_buffer_limit=*/1024, /*downstream_buffer_limit=*/1024);
testRouterRequestAndResponseWithBody(/*request_size=*/10 * 1024 * 1024, /*response_size=*/1024,
false);
Expand Down

0 comments on commit 7bf71a4

Please sign in to comment.