Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quic: Adding QUIC listener option to reject new connections #36070

Merged
merged 8 commits into from
Sep 17, 2024
Merged
7 changes: 6 additions & 1 deletion api/envoy/config/listener/v3/quic_config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: QUIC listener config]

// Configuration specific to the UDP QUIC listener.
// [#next-free-field: 13]
// [#next-free-field: 14]
message QuicProtocolOptions {
option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.listener.QuicProtocolOptions";
Expand Down Expand Up @@ -94,4 +94,9 @@ message QuicProtocolOptions {
// If not specified, no cmsg will be saved to QuicReceivedPacket.
repeated core.v3.SocketCmsgHeaders save_cmsg_config = 12
[(validate.rules).repeated = {max_items: 1}];

// If true, the listener will reject connection-establishing packets at the
// QUIC layer by replying with an empty version negotiation packet to the
// client.
bool reject_new_connections = 13;
}
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ new_features:
QUIC server and client support certificate compression, which can in some cases reduce the number of round trips
required to setup a connection. This change temporarily disabled by setting the runtime flag
``envoy.reloadable_features.quic_support_certificate_compression`` to ``false``.
- area: quic
change: |
Added QUIC protocol option :ref:`reject_new_connections
Rickyp marked this conversation as resolved.
Show resolved Hide resolved
<envoy_v3_api_field_config.listener.v3.QuicProtocolOptions.reject_new_connections>` to reject connection-establishing
packets at the QUIC layer.
- area: tls
change: |
Added an extension point :ref:`custom_tls_certificate_selector
Expand Down
11 changes: 7 additions & 4 deletions source/common/quic/active_quic_listener.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@ ActiveQuicListener::ActiveQuicListener(
EnvoyQuicCryptoServerStreamFactoryInterface& crypto_server_stream_factory,
EnvoyQuicProofSourceFactoryInterface& proof_source_factory,
QuicConnectionIdGeneratorPtr&& cid_generator, QuicConnectionIdWorkerSelector worker_selector,
EnvoyQuicConnectionDebugVisitorFactoryInterfaceOptRef debug_visitor_factory)
EnvoyQuicConnectionDebugVisitorFactoryInterfaceOptRef debug_visitor_factory,
bool reject_new_connections)
: Server::ActiveUdpListenerBase(
worker_index, concurrency, parent, *listen_socket,
std::make_unique<Network::UdpListenerImpl>(
dispatcher, listen_socket, *this, dispatcher.timeSource(),
listener_config.udpListenerConfig()->config().downstream_socket_config()),
&listener_config),
dispatcher_(dispatcher), version_manager_(quic::CurrentSupportedHttp3Versions()),
dispatcher_(dispatcher),
version_manager_(reject_new_connections ? quic::ParsedQuicVersionVector()
: quic::CurrentSupportedHttp3Versions()),
kernel_worker_routing_(kernel_worker_routing),
packets_to_read_to_connection_count_ratio_(packets_to_read_to_connection_count_ratio),
crypto_server_stream_factory_(crypto_server_stream_factory),
Expand Down Expand Up @@ -264,7 +267,7 @@ ActiveQuicListenerFactory::ActiveQuicListenerFactory(
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, packets_to_read_to_connection_count_ratio,
DEFAULT_PACKETS_TO_READ_PER_CONNECTION)),
receive_ecn_(Runtime::runtimeFeatureEnabled("envoy.reloadable_features.quic_receive_ecn")),
context_(context) {
context_(context), reject_new_connections_(config.reject_new_connections()) {
const int64_t idle_network_timeout_ms =
config.has_idle_timeout() ? DurationUtil::durationToMilliseconds(config.idle_timeout())
: 300000;
Expand Down Expand Up @@ -434,7 +437,7 @@ ActiveQuicListenerFactory::createActiveQuicListener(
listener_config, quic_config, kernel_worker_routing, enabled, quic_stat_names,
packets_to_read_to_connection_count_ratio, receive_ecn_, crypto_server_stream_factory,
proof_source_factory, std::move(cid_generator), worker_selector_,
connection_debug_visitor_factory_);
connection_debug_visitor_factory_, reject_new_connections_);
}

} // namespace Quic
Expand Down
4 changes: 3 additions & 1 deletion source/common/quic/active_quic_listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class ActiveQuicListener : public Envoy::Server::ActiveUdpListenerBase,
EnvoyQuicProofSourceFactoryInterface& proof_source_factory,
QuicConnectionIdGeneratorPtr&& cid_generator,
QuicConnectionIdWorkerSelector worker_selector,
EnvoyQuicConnectionDebugVisitorFactoryInterfaceOptRef debug_visitor_factory);
EnvoyQuicConnectionDebugVisitorFactoryInterfaceOptRef debug_visitor_factory,
bool reject_new_connections = false);

~ActiveQuicListener() override;

Expand Down Expand Up @@ -159,6 +160,7 @@ class ActiveQuicListenerFactory : public Network::ActiveUdpListenerFactory,
QuicConnectionIdWorkerSelector worker_selector_;
bool kernel_worker_routing_{};
Server::Configuration::ServerFactoryContext& context_;
bool reject_new_connections_{};

static bool disable_kernel_bpf_packet_routing_for_test_;
};
Expand Down
16 changes: 16 additions & 0 deletions test/integration/quic_http_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2380,6 +2380,22 @@ TEST_P(QuicHttpIntegrationTest, SendDisableActiveMigration) {
ASSERT_TRUE(response->complete());
}

TEST_P(QuicHttpIntegrationTest, RejectTraffic) {
config_helper_.addConfigModifier([=](envoy::config::bootstrap::v3::Bootstrap& bootstrap) -> void {
bootstrap.mutable_static_resources()
->mutable_listeners(0)
->mutable_udp_listener_config()
->mutable_quic_options()
->set_reject_new_connections(true);
});

initialize();
codec_client_ = makeRawHttpConnection(makeClientConnection(lookupPort("http")), absl::nullopt);
EXPECT_TRUE(codec_client_->disconnected());
EXPECT_EQ(quic::QUIC_INVALID_VERSION,
static_cast<EnvoyQuicClientSession*>(codec_client_->connection())->error());
}

// Validate that the transport parameter is not sent when `send_disable_active_migration` is
// unset.
TEST_P(QuicHttpIntegrationTest, UnsetSendDisableActiveMigration) {
Expand Down
Loading