Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion api/envoy/config/bootstrap/v3/bootstrap.proto
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ message Bootstrap {

// Administration interface :ref:`operations documentation
// <operations_admin_interface>`.
// [#next-free-field: 6]
// [#next-free-field: 7]
message Admin {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Admin";

Expand All @@ -355,6 +355,10 @@ message Admin {
// Additional socket options that may not be present in Envoy source code or
// precompiled binaries.
repeated core.v3.SocketOption socket_options = 4;

// Indicates whether :ref:`global_downstream_max_connections <config_overload_manager_limiting_connections>`
// should apply to the admin interface or not.
bool ignore_global_conn_limit = 6;
}

// Cluster manager :ref:`architecture overview <arch_overview_cluster_manager>`.
Expand Down
6 changes: 5 additions & 1 deletion api/envoy/config/listener/v3/listener.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ message ListenerCollection {
repeated xds.core.v3.CollectionEntry entries = 1;
}

// [#next-free-field: 31]
// [#next-free-field: 32]
message Listener {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener";

Expand Down Expand Up @@ -318,4 +318,8 @@ message Listener {
// Enable MPTCP (multi-path TCP) on this listener. Clients will be allowed to establish
// MPTCP connections. Non-MPTCP clients will fall back to regular TCP.
bool enable_mptcp = 30;

// Whether the listener should limit connections based upon the value of
// :ref:`global_downstream_max_connections <config_overload_manager_limiting_connections>`.
bool ignore_global_conn_limit = 31;
}
2 changes: 1 addition & 1 deletion ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ The `./ci/run_envoy_docker.sh './ci/do_ci.sh <TARGET>'` targets are:
* `bazel.clang_tidy <files>` &mdash; build and run clang-tidy specified source files, if no files specified, runs against the diff with the last GitHub commit.
* `check_format`&mdash; run `clang-format` and `buildifier` on entire source tree.
* `fix_format`&mdash; run and enforce `clang-format` and `buildifier` on entire source tree.
* `check_spelling_pedantic`&mdash; run `aspell` on C++ and proto comments.
* `format_pre`&mdash; run validation and linting tools.
* `docs`&mdash; build documentation tree in `generated/docs`.

## On Windows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ Note in the example that the minimum idle time is specified as an absolute durat
would be computed based on the maximum (specified elsewhere). So if ``idle_timeout`` is
again 600 seconds, then the minimum timer value would be :math:`10\% \cdot 600s = 60s`.

.. _config_overload_manager_limiting_connections:

Limiting Active Connections
---------------------------

Expand All @@ -155,6 +157,13 @@ If the value is unspecified, there is no global limit on the number of active do
and Envoy will emit a warning indicating this at startup. To disable the warning without setting a
limit on the number of active downstream connections, the runtime value may be set to a very large
limit (~2e9).
Listeners can opt out of this global connection limit by setting
:ref:`Listener.ignore_global_conn_limit <envoy_v3_api_field_config.listener.v3.Listener.ignore_global_conn_limit>`
to true. Similarly, you can opt out the admin listener by setting
:ref:`Admin.ignore_global_conn_limit <envoy_v3_api_field_config.bootstrap.v3.Admin.ignore_global_conn_limit>`.
You may want to opt out a listener to be able to probe Envoy or collect stats while it is otherwise at its
connection limit. Note that connections to listeners that opt out are still tracked and count towards the
global limit.

If it is desired to only limit the number of downstream connections for a particular listener,
per-listener limits can be set via the :ref:`listener configuration <config_listeners>`.
Expand Down
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ New Features
* http: added support for :ref:`retriable health check status codes <envoy_v3_api_field_config.core.v3.HealthCheck.HttpHealthCheck.retriable_statuses>`.
* listener: added API for extensions to access :ref:`typed_filter_metadata <envoy_v3_api_field_config.core.v3.Metadata.typed_filter_metadata>` configured in the listener's :ref:`metadata <envoy_v3_api_field_config.listener.v3.Listener.metadata>` field.
* listener: added support for :ref:`MPTCP <envoy_v3_api_field_config.listener.v3.Listener.enable_mptcp>` (multipath TCP).
* listener: added support for opting out listeners from the globally set downstream connection limit via :ref:`ignore_global_conn_limit <envoy_v3_api_field_config.listener.v3.Listener.ignore_global_conn_limit>`.
* oauth filter: added :ref:`cookie_names <envoy_v3_api_field_extensions.filters.http.oauth2.v3.OAuth2Credentials.cookie_names>` to allow overriding (default) cookie names (``BearerToken``, ``OauthHMAC``, and ``OauthExpires``) set by the filter.
* oauth filter: setting IdToken and RefreshToken cookies if they are provided by Identity provider along with AccessToken.
* tcp: added a :ref:`FilterState <envoy_v3_api_msg_type.v3.HashPolicy.FilterState>` :ref:`hash policy <envoy_v3_api_msg_type.v3.HashPolicy>`, used by :ref:`TCP proxy <envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.hash_policy>` to allow hashing load balancer algorithms to hash on objects in filter state.
Expand Down
6 changes: 4 additions & 2 deletions envoy/event/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,13 @@ class Dispatcher : public DispatcherBase, public ScopeTracker {
* @param socket supplies the socket to listen on.
* @param cb supplies the callbacks to invoke for listener events.
* @param bind_to_port controls whether the listener binds to a transport port or not.
* @param ignore_global_conn_limit controls whether the listener is limited by the global
* connection limit.
* @return Network::ListenerPtr a new listener that is owned by the caller.
*/
virtual Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket,
Network::TcpListenerCallbacks& cb,
bool bind_to_port) PURE;
Network::TcpListenerCallbacks& cb, bool bind_to_port,
bool ignore_global_conn_limit) PURE;

/**
* Creates a logical udp listener on a specific port.
Expand Down
6 changes: 6 additions & 0 deletions envoy/network/listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ class ListenerConfig {
* @return init manager of the listener.
*/
virtual Init::Manager& initManager() PURE;

/**
* @return bool whether the listener should avoid blocking connections based on the globally set
* limit.
*/
virtual bool ignoreGlobalConnLimit() const PURE;
};

/**
Expand Down
6 changes: 6 additions & 0 deletions envoy/server/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ class Admin {
* @return Network::Address::OptionsSharedPtr the list of listener socket options.
*/
virtual Network::Socket::OptionsSharedPtr socketOptions() PURE;

/**
* @return bool whether the listener should avoid blocking connections based on the globally set
* limit.
*/
virtual bool ignoreGlobalConnLimit() const PURE;
};

/**
Expand Down
7 changes: 4 additions & 3 deletions source/common/event/dispatcher_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,11 @@ Filesystem::WatcherPtr DispatcherImpl::createFilesystemWatcher() {

Network::ListenerPtr DispatcherImpl::createListener(Network::SocketSharedPtr&& socket,
Network::TcpListenerCallbacks& cb,
bool bind_to_port) {
bool bind_to_port,
bool ignore_global_conn_limit) {
ASSERT(isThreadSafe());
return std::make_unique<Network::TcpListenerImpl>(*this, api_.randomGenerator(),
std::move(socket), cb, bind_to_port);
return std::make_unique<Network::TcpListenerImpl>(
*this, api_.randomGenerator(), std::move(socket), cb, bind_to_port, ignore_global_conn_limit);
}

Network::UdpListenerPtr
Expand Down
4 changes: 2 additions & 2 deletions source/common/event/dispatcher_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>,
uint32_t events) override;
Filesystem::WatcherPtr createFilesystemWatcher() override;
Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket,
Network::TcpListenerCallbacks& cb,
bool bind_to_port) override;
Network::TcpListenerCallbacks& cb, bool bind_to_port,
bool ignore_global_conn_limit) override;
Network::UdpListenerPtr
createUdpListener(Network::SocketSharedPtr socket, Network::UdpListenerCallbacks& cb,
const envoy::config::core::v3::UdpSocketConfig& config) override;
Expand Down
9 changes: 5 additions & 4 deletions source/common/network/tcp_listener_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ namespace Network {
const absl::string_view TcpListenerImpl::GlobalMaxCxRuntimeKey =
"overload.global_downstream_max_connections";

bool TcpListenerImpl::rejectCxOverGlobalLimit() {
bool TcpListenerImpl::rejectCxOverGlobalLimit() const {
// Enforce the global connection limit if necessary, immediately closing the accepted connection.
Runtime::Loader* runtime = Runtime::LoaderSingleton::getExisting();

if (runtime == nullptr) {
if (ignore_global_conn_limit_ || runtime == nullptr) {
// The runtime singleton won't exist in most unit tests that do not need global downstream limit
// enforcement. Therefore, there is no need to enforce limits if the singleton doesn't exist.
// TODO(tonya11en): Revisit this once runtime is made globally available.
Expand Down Expand Up @@ -98,9 +98,10 @@ void TcpListenerImpl::onSocketEvent(short flags) {

TcpListenerImpl::TcpListenerImpl(Event::DispatcherImpl& dispatcher, Random::RandomGenerator& random,
SocketSharedPtr socket, TcpListenerCallbacks& cb,
bool bind_to_port)
bool bind_to_port, bool ignore_global_conn_limit)
: BaseListenerImpl(dispatcher, std::move(socket)), cb_(cb), random_(random),
bind_to_port_(bind_to_port), reject_fraction_(0.0) {
bind_to_port_(bind_to_port), reject_fraction_(0.0),
ignore_global_conn_limit_(ignore_global_conn_limit) {
if (bind_to_port) {
// Although onSocketEvent drains to completion, use level triggered mode to avoid potential
// loss of the trigger due to transient accept errors.
Expand Down
6 changes: 4 additions & 2 deletions source/common/network/tcp_listener_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace Network {
class TcpListenerImpl : public BaseListenerImpl {
public:
TcpListenerImpl(Event::DispatcherImpl& dispatcher, Random::RandomGenerator& random,
SocketSharedPtr socket, TcpListenerCallbacks& cb, bool bind_to_port);
SocketSharedPtr socket, TcpListenerCallbacks& cb, bool bind_to_port,
bool ignore_global_conn_limit);
~TcpListenerImpl() override {
if (bind_to_port_) {
socket_->ioHandle().resetFileEvents();
Expand All @@ -37,11 +38,12 @@ class TcpListenerImpl : public BaseListenerImpl {

// Returns true if global connection limit has been reached and the accepted socket should be
// rejected/closed. If the accepted socket is to be admitted, false is returned.
static bool rejectCxOverGlobalLimit();
bool rejectCxOverGlobalLimit() const;

Random::RandomGenerator& random_;
bool bind_to_port_;
UnitFloat reject_fraction_;
const bool ignore_global_conn_limit_;
};

} // namespace Network
Expand Down
2 changes: 1 addition & 1 deletion source/server/active_tcp_listener.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ActiveTcpListener::ActiveTcpListener(Network::TcpConnectionHandler& parent,
: OwnedActiveStreamListenerBase(parent, parent.dispatcher(),
parent.dispatcher().createListener(
config.listenSocketFactory().getListenSocket(worker_index),
*this, config.bindToPort()),
*this, config.bindToPort(), config.ignoreGlobalConnLimit()),
config),
tcp_conn_handler_(parent) {
config.connectionBalancer().registerHandler(*this);
Expand Down
7 changes: 4 additions & 3 deletions source/server/admin/admin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ const char AdminHtmlEnd[] = R"(
</table>
</body>
)";

} // namespace

ConfigTracker& AdminImpl::getConfigTracker() { return config_tracker_; }
Expand Down Expand Up @@ -144,7 +143,8 @@ void AdminImpl::startHttpListener(const std::list<AccessLog::InstanceSharedPtr>&
}
}

AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server)
AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server,
bool ignore_global_conn_limit)
: server_(server),
request_id_extension_(Extensions::RequestId::UUIDRequestIDExtension::defaultInstance(
server_.api().randomGenerator())),
Expand Down Expand Up @@ -221,7 +221,8 @@ AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server)
},
date_provider_(server.dispatcher().timeSource()),
admin_filter_chain_(std::make_shared<AdminFilterChain>()),
local_reply_(LocalReply::Factory::createDefault()) {}
local_reply_(LocalReply::Factory::createDefault()),
ignore_global_conn_limit_(ignore_global_conn_limit) {}

Http::ServerConnectionPtr AdminImpl::createCodec(Network::Connection& connection,
const Buffer::Instance& data,
Expand Down
8 changes: 6 additions & 2 deletions source/server/admin/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class AdminImpl : public Admin,
public Http::ConnectionManagerConfig,
Logger::Loggable<Logger::Id::admin> {
public:
AdminImpl(const std::string& profile_path, Server::Instance& server);
AdminImpl(const std::string& profile_path, Server::Instance& server,
bool ignore_global_conn_limit);

Http::Code runCallback(absl::string_view path_and_query,
Http::ResponseHeaderMap& response_headers, Buffer::Instance& response,
Expand Down Expand Up @@ -340,7 +341,7 @@ class AdminImpl : public Admin,
AdminListener(AdminImpl& parent, Stats::ScopePtr&& listener_scope)
: parent_(parent), name_("admin"), scope_(std::move(listener_scope)),
stats_(Http::ConnectionManagerImpl::generateListenerStats("http.admin.", *scope_)),
init_manager_(nullptr) {}
init_manager_(nullptr), ignore_global_conn_limit_(parent.ignore_global_conn_limit_) {}

// Network::ListenerConfig
Network::FilterChainManager& filterChainManager() override { return parent_; }
Expand Down Expand Up @@ -369,6 +370,7 @@ class AdminImpl : public Admin,
}
uint32_t tcpBacklogSize() const override { return ENVOY_TCP_BACKLOG_SIZE; }
Init::Manager& initManager() override { return *init_manager_; }
bool ignoreGlobalConnLimit() const override { return ignore_global_conn_limit_; }

AdminImpl& parent_;
const std::string name_;
Expand All @@ -380,6 +382,7 @@ class AdminImpl : public Admin,
private:
const std::vector<AccessLog::InstanceSharedPtr> empty_access_logs_;
std::unique_ptr<Init::Manager> init_manager_;
const bool ignore_global_conn_limit_;
};
using AdminListenerPtr = std::unique_ptr<AdminListener>;

Expand Down Expand Up @@ -452,6 +455,7 @@ class AdminImpl : public Admin,
const LocalReply::LocalReplyPtr local_reply_;
const std::vector<Http::OriginalIPDetectionSharedPtr> detection_extensions_{};
const absl::optional<std::string> scheme_{};
const bool ignore_global_conn_limit_;
};

} // namespace Server
Expand Down
3 changes: 2 additions & 1 deletion source/server/config_validation/dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ Network::ClientConnectionPtr ValidationDispatcher::createClientConnection(
}

Network::ListenerPtr ValidationDispatcher::createListener(Network::SocketSharedPtr&&,
Network::TcpListenerCallbacks&, bool) {
Network::TcpListenerCallbacks&, bool,
bool) {
NOT_IMPLEMENTED_GCOVR_EXCL_LINE;
}

Expand Down
2 changes: 1 addition & 1 deletion source/server/config_validation/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ValidationDispatcher : public DispatcherImpl {
Network::Address::InstanceConstSharedPtr, Network::TransportSocketPtr&&,
const Network::ConnectionSocket::OptionsSharedPtr& options) override;
Network::ListenerPtr createListener(Network::SocketSharedPtr&&, Network::TcpListenerCallbacks&,
bool bind_to_port) override;
bool bind_to_port, bool ignore_global_conn_limit) override;
};

} // namespace Event
Expand Down
1 change: 1 addition & 0 deletions source/server/configuration_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ InitialImpl::InitialImpl(const envoy::config::bootstrap::v3::Bootstrap& bootstra
admin_.socket_options_,
Network::SocketOptionFactory::buildLiteralOptions(admin.socket_options()));
}
admin_.ignore_global_conn_limit_ = admin.ignore_global_conn_limit();

if (!bootstrap.flags_path().empty()) {
flags_path_ = bootstrap.flags_path();
Expand Down
2 changes: 2 additions & 0 deletions source/server/configuration_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,13 @@ class InitialImpl : public Initial {
Network::Address::InstanceConstSharedPtr address() override { return address_; }
Network::Socket::OptionsSharedPtr socketOptions() override { return socket_options_; }
std::list<AccessLog::InstanceSharedPtr> accessLogs() const override { return access_logs_; }
bool ignoreGlobalConnLimit() const override { return ignore_global_conn_limit_; }

std::string profile_path_;
std::list<AccessLog::InstanceSharedPtr> access_logs_;
Network::Address::InstanceConstSharedPtr address_;
Network::Socket::OptionsSharedPtr socket_options_;
bool ignore_global_conn_limit_;
};

AdminImpl admin_;
Expand Down
2 changes: 2 additions & 0 deletions source/server/listener_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ ListenerImpl::ListenerImpl(const envoy::config::listener::v3::Listener& config,
validation_visitor_(
added_via_api_ ? parent_.server_.messageValidationContext().dynamicValidationVisitor()
: parent_.server_.messageValidationContext().staticValidationVisitor()),
ignore_global_conn_limit_(config.ignore_global_conn_limit()),
listener_init_target_(fmt::format("Listener-init-target {}", name),
[this]() { dynamic_init_manager_->initialize(local_init_watcher_); }),
dynamic_init_manager_(std::make_unique<Init::ManagerImpl>(
Expand Down Expand Up @@ -394,6 +395,7 @@ ListenerImpl::ListenerImpl(ListenerImpl& origin,
validation_visitor_(
added_via_api_ ? parent_.server_.messageValidationContext().dynamicValidationVisitor()
: parent_.server_.messageValidationContext().staticValidationVisitor()),
ignore_global_conn_limit_(config.ignore_global_conn_limit()),
// listener_init_target_ is not used during in place update because we expect server started.
listener_init_target_("", nullptr),
dynamic_init_manager_(std::make_unique<Init::ManagerImpl>(
Expand Down
2 changes: 2 additions & 0 deletions source/server/listener_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ class ListenerImpl final : public Network::ListenerConfig,
}
uint32_t tcpBacklogSize() const override { return tcp_backlog_size_; }
Init::Manager& initManager() override;
bool ignoreGlobalConnLimit() const override { return ignore_global_conn_limit_; }
envoy::config::core::v3::TrafficDirection direction() const override {
return config().traffic_direction();
}
Expand Down Expand Up @@ -411,6 +412,7 @@ class ListenerImpl final : public Network::ListenerConfig,
const uint64_t hash_;
const uint32_t tcp_backlog_size_;
ProtobufMessage::ValidationVisitor& validation_visitor_;
const bool ignore_global_conn_limit_;

// A target is added to Server's InitManager if workers_started_ is false.
Init::TargetImpl listener_init_target_;
Expand Down
3 changes: 2 additions & 1 deletion source/server/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,8 @@ void InstanceImpl::initialize(Network::Address::InstanceConstSharedPtr local_add
// This is needed so that we don't read the value until runtime is fully initialized.
enable_reuse_port_default_ = ReusePortDefault::Runtime;
}
admin_ = std::make_unique<AdminImpl>(initial_config.admin().profilePath(), *this);
admin_ = std::make_unique<AdminImpl>(initial_config.admin().profilePath(), *this,
initial_config.admin().ignoreGlobalConnLimit());

loadServerFlags(initial_config.flagsPath());

Expand Down
3 changes: 2 additions & 1 deletion test/common/http/codec_client_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ class CodecNetworkTest : public Event::TestUsingSimulatedTime,
Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection(
socket->connectionInfoProvider().localAddress(), source_address_,
Network::Test::createRawBufferSocket(), nullptr);
upstream_listener_ = dispatcher_->createListener(std::move(socket), listener_callbacks_, true);
upstream_listener_ =
dispatcher_->createListener(std::move(socket), listener_callbacks_, true, false);
client_connection_ = client_connection.get();
client_connection_->addConnectionCallbacks(client_callbacks_);

Expand Down
Loading