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

network: add tcp listener backlog config #12625

Merged
merged 2 commits into from
Aug 13, 2020
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/listener/v3/listener.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ message ListenerCollection {
udpa.core.v1.CollectionEntry entries = 1;
}

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

Expand Down Expand Up @@ -259,4 +259,8 @@ message Listener {
// If not present, treat it as "udp_default_writer".
// [#not-implemented-hide:]
core.v3.TypedExtensionConfig udp_writer_config = 23;

// The maximum length a tcp listener's pending connections queue can grow to. If no value is
// provided net.core.somaxconn will be used on Linux and 128 otherwise.
google.protobuf.UInt32Value tcp_backlog_size = 24;
}
6 changes: 5 additions & 1 deletion api/envoy/config/listener/v4alpha/listener.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion generated_api_shadow/envoy/config/listener/v3/listener.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions include/envoy/common/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,11 @@ struct mmsghdr {
#undef SUPPORTS_PTHREAD_NAMING
#define SUPPORTS_PTHREAD_NAMING 1
#endif // defined(__ANDROID_API__)

#if defined(__linux__)
// On Linux, default listen backlog size to net.core.somaxconn which is runtime configurable
#define ENVOY_TCP_BACKLOG_SIZE -1
#else
// On non-Linux platforms use 128 which is libevent listener default
#define ENVOY_TCP_BACKLOG_SIZE 128
#endif
5 changes: 3 additions & 2 deletions include/envoy/event/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,12 @@ class Dispatcher {
* @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 backlog_size controls listener pending connections backlog
* @return Network::ListenerPtr a new listener that is owned by the caller.
*/
virtual Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket,
Network::ListenerCallbacks& cb,
bool bind_to_port) PURE;
Network::ListenerCallbacks& cb, bool bind_to_port,
uint32_t backlog_size) PURE;

/**
* Creates a logical udp listener on a specific port.
Expand Down
5 changes: 5 additions & 0 deletions include/envoy/network/listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ class ListenerConfig {
* @return std::vector<AccessLog::InstanceSharedPtr> access logs emitted by the listener.
*/
virtual const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const PURE;

/**
* @return pending connection backlog for TCP listeners.
*/
virtual uint32_t tcpBacklogSize() const PURE;
};

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

Network::ListenerPtr DispatcherImpl::createListener(Network::SocketSharedPtr&& socket,
Network::ListenerCallbacks& cb,
bool bind_to_port) {
bool bind_to_port, uint32_t backlog_size) {
ASSERT(isThreadSafe());
return std::make_unique<Network::ListenerImpl>(*this, std::move(socket), cb, bind_to_port);
return std::make_unique<Network::ListenerImpl>(*this, std::move(socket), cb, bind_to_port,
backlog_size);
}

Network::UdpListenerPtr DispatcherImpl::createUdpListener(Network::SocketSharedPtr&& socket,
Expand Down
3 changes: 2 additions & 1 deletion source/common/event/dispatcher_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>,
uint32_t events) override;
Filesystem::WatcherPtr createFilesystemWatcher() override;
Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket,
Network::ListenerCallbacks& cb, bool bind_to_port) override;
Network::ListenerCallbacks& cb, bool bind_to_port,
uint32_t backlog_size) override;
Network::UdpListenerPtr createUdpListener(Network::SocketSharedPtr&& socket,
Network::UdpListenerCallbacks& cb) override;
TimerPtr createTimer(TimerCb cb) override;
Expand Down
8 changes: 3 additions & 5 deletions source/common/network/listener_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ void ListenerImpl::onSocketEvent(short flags) {
}

void ListenerImpl::setupServerSocket(Event::DispatcherImpl& dispatcher, Socket& socket) {
// TODO(fcoras): make listen backlog configurable. For now use 128, which is what libevent
// defaults to for listeners configured with a negative (unspecified) backlog
socket.ioHandle().listen(128);
socket.ioHandle().listen(backlog_size_);

// Although onSocketEvent drains to completion, use level triggered mode to avoid potential
// loss of the trigger due to transient accept errors.
Expand All @@ -109,8 +107,8 @@ void ListenerImpl::setupServerSocket(Event::DispatcherImpl& dispatcher, Socket&
}

ListenerImpl::ListenerImpl(Event::DispatcherImpl& dispatcher, SocketSharedPtr socket,
ListenerCallbacks& cb, bool bind_to_port)
: BaseListenerImpl(dispatcher, std::move(socket)), cb_(cb) {
ListenerCallbacks& cb, bool bind_to_port, uint32_t backlog_size)
: BaseListenerImpl(dispatcher, std::move(socket)), cb_(cb), backlog_size_(backlog_size) {
if (bind_to_port) {
setupServerSocket(dispatcher, *socket_);
}
Expand Down
3 changes: 2 additions & 1 deletion source/common/network/listener_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Network {
class ListenerImpl : public BaseListenerImpl {
public:
ListenerImpl(Event::DispatcherImpl& dispatcher, SocketSharedPtr socket, ListenerCallbacks& cb,
bool bind_to_port);
bool bind_to_port, uint32_t backlog_size);
void disable() override;
void enable() override;

Expand All @@ -25,6 +25,7 @@ class ListenerImpl : public BaseListenerImpl {
void setupServerSocket(Event::DispatcherImpl& dispatcher, Socket& socket);

ListenerCallbacks& cb_;
const uint32_t backlog_size_;

private:
void onSocketEvent(short flags);
Expand Down
1 change: 1 addition & 0 deletions source/server/admin/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ class AdminImpl : public Admin,
const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const override {
return empty_access_logs_;
}
uint32_t tcpBacklogSize() const override { return ENVOY_TCP_BACKLOG_SIZE; }

AdminImpl& parent_;
const std::string name_;
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 @@ -22,7 +22,8 @@ Network::DnsResolverSharedPtr ValidationDispatcher::createDnsResolver(
}

Network::ListenerPtr ValidationDispatcher::createListener(Network::SocketSharedPtr&&,
Network::ListenerCallbacks&, bool) {
Network::ListenerCallbacks&, bool,
uint32_t) {
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 @@ -27,7 +27,7 @@ class ValidationDispatcher : public DispatcherImpl {
createDnsResolver(const std::vector<Network::Address::InstanceConstSharedPtr>& resolvers,
const bool use_tcp_for_dns_lookups) override;
Network::ListenerPtr createListener(Network::SocketSharedPtr&&, Network::ListenerCallbacks&,
bool bind_to_port) override;
bool bind_to_port, uint32_t backlog_size) override;

protected:
std::shared_ptr<Network::ValidationDnsResolver> dns_resolver_{
Expand Down
2 changes: 1 addition & 1 deletion source/server/connection_handler_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ ConnectionHandlerImpl::ActiveTcpListener::ActiveTcpListener(ConnectionHandlerImp
: ActiveTcpListener(
parent,
parent.dispatcher_.createListener(config.listenSocketFactory().getListenSocket(), *this,
config.bindToPort()),
config.bindToPort(), config.tcpBacklogSize()),
config) {}

ConnectionHandlerImpl::ActiveTcpListener::ActiveTcpListener(ConnectionHandlerImpl& parent,
Expand Down
4 changes: 4 additions & 0 deletions source/server/listener_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ ListenerImpl::ListenerImpl(const envoy::config::listener::v3::Listener& config,
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, per_connection_buffer_limit_bytes, 1024 * 1024)),
listener_tag_(parent_.factory_.nextListenerTag()), name_(name), added_via_api_(added_via_api),
workers_started_(workers_started), hash_(hash),
tcp_backlog_size_(
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, tcp_backlog_size, ENVOY_TCP_BACKLOG_SIZE)),
validation_visitor_(
added_via_api_ ? parent_.server_.messageValidationContext().dynamicValidationVisitor()
: parent_.server_.messageValidationContext().staticValidationVisitor()),
Expand Down Expand Up @@ -310,6 +312,8 @@ ListenerImpl::ListenerImpl(ListenerImpl& origin,
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, per_connection_buffer_limit_bytes, 1024 * 1024)),
listener_tag_(origin.listener_tag_), name_(name), added_via_api_(added_via_api),
workers_started_(workers_started), hash_(hash),
tcp_backlog_size_(
PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, tcp_backlog_size, ENVOY_TCP_BACKLOG_SIZE)),
validation_visitor_(
added_via_api_ ? parent_.server_.messageValidationContext().dynamicValidationVisitor()
: parent_.server_.messageValidationContext().staticValidationVisitor()),
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 @@ -311,6 +311,7 @@ class ListenerImpl final : public Network::ListenerConfig,
const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const override {
return access_logs_;
}
uint32_t tcpBacklogSize() const override { return tcp_backlog_size_; }
Init::Manager& initManager();
envoy::config::core::v3::TrafficDirection direction() const override {
return config().traffic_direction();
Expand Down Expand Up @@ -371,6 +372,7 @@ class ListenerImpl final : public Network::ListenerConfig,
const bool added_via_api_;
const bool workers_started_;
const uint64_t hash_;
const uint32_t tcp_backlog_size_;
ProtobufMessage::ValidationVisitor& validation_visitor_;

// A target is added to Server's InitManager if workers_started_ is false.
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 @@ -286,7 +286,8 @@ class CodecNetworkTest : public testing::TestWithParam<Network::Address::IpVersi
Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true);
Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection(
socket->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,
ENVOY_TCP_BACKLOG_SIZE);
client_connection_ = client_connection.get();
client_connection_->addConnectionCallbacks(client_callbacks_);

Expand Down
9 changes: 6 additions & 3 deletions test/common/network/connection_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ class ConnectionImplTest : public testing::TestWithParam<Address::IpVersion> {
}
socket_ = std::make_shared<Network::TcpListenSocket>(
Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true);
listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true);
listener_ =
dispatcher_->createListener(socket_, listener_callbacks_, true, ENVOY_TCP_BACKLOG_SIZE);
client_connection_ = std::make_unique<Network::TestClientConnectionImpl>(
*dispatcher_, socket_->localAddress(), source_address_,
Network::Test::createRawBufferSocket(), socket_options_);
Expand Down Expand Up @@ -1132,7 +1133,8 @@ TEST_P(ConnectionImplTest, BindFailureTest) {
dispatcher_ = api_->allocateDispatcher("test_thread");
socket_ = std::make_shared<Network::TcpListenSocket>(
Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true);
listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true);
listener_ =
dispatcher_->createListener(socket_, listener_callbacks_, true, ENVOY_TCP_BACKLOG_SIZE);

client_connection_ = dispatcher_->createClientConnection(
socket_->localAddress(), source_address_, Network::Test::createRawBufferSocket(), nullptr);
Expand Down Expand Up @@ -2238,7 +2240,8 @@ class ReadBufferLimitTest : public ConnectionImplTest {
dispatcher_ = api_->allocateDispatcher("test_thread");
socket_ = std::make_shared<Network::TcpListenSocket>(
Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true);
listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true);
listener_ =
dispatcher_->createListener(socket_, listener_callbacks_, true, ENVOY_TCP_BACKLOG_SIZE);

client_connection_ = dispatcher_->createClientConnection(
socket_->localAddress(), Network::Address::InstanceConstSharedPtr(),
Expand Down
2 changes: 1 addition & 1 deletion test/common/network/dns_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ class DnsImplTest : public testing::TestWithParam<Address::IpVersion> {
server_ = std::make_unique<TestDnsServer>(*dispatcher_);
socket_ = std::make_shared<Network::TcpListenSocket>(
Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true);
listener_ = dispatcher_->createListener(socket_, *server_, true);
listener_ = dispatcher_->createListener(socket_, *server_, true, ENVOY_TCP_BACKLOG_SIZE);

// Point c-ares at the listener with no search domains and TCP-only.
peer_ = std::make_unique<DnsResolverImplPeer>(dynamic_cast<DnsResolverImpl*>(resolver_.get()));
Expand Down
10 changes: 6 additions & 4 deletions test/common/network/listener_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ static void errorCallbackTest(Address::IpVersion version) {
Network::Test::getCanonicalLoopbackAddress(version), nullptr, true);
Network::MockListenerCallbacks listener_callbacks;
Network::MockConnectionHandler connection_handler;
Network::ListenerPtr listener = dispatcher->createListener(socket, listener_callbacks, true);
Network::ListenerPtr listener =
dispatcher->createListener(socket, listener_callbacks, true, ENVOY_TCP_BACKLOG_SIZE);

Network::ClientConnectionPtr client_connection = dispatcher->createClientConnection(
socket->localAddress(), Network::Address::InstanceConstSharedPtr(),
Expand Down Expand Up @@ -65,8 +66,8 @@ TEST_P(ListenerImplDeathTest, ErrorCallback) {
class TestListenerImpl : public ListenerImpl {
public:
TestListenerImpl(Event::DispatcherImpl& dispatcher, SocketSharedPtr socket, ListenerCallbacks& cb,
bool bind_to_port)
: ListenerImpl(dispatcher, std::move(socket), cb, bind_to_port) {}
bool bind_to_port, uint32_t tcp_backlog = ENVOY_TCP_BACKLOG_SIZE)
: ListenerImpl(dispatcher, std::move(socket), cb, bind_to_port, tcp_backlog) {}

MOCK_METHOD(Address::InstanceConstSharedPtr, getLocalAddress, (os_fd_t fd));
};
Expand Down Expand Up @@ -150,7 +151,8 @@ TEST_P(ListenerImplTest, GlobalConnectionLimitEnforcement) {
Network::Test::getCanonicalLoopbackAddress(version_), nullptr, true);
Network::MockListenerCallbacks listener_callbacks;
Network::MockConnectionHandler connection_handler;
Network::ListenerPtr listener = dispatcher_->createListener(socket, listener_callbacks, true);
Network::ListenerPtr listener =
dispatcher_->createListener(socket, listener_callbacks, true, ENVOY_TCP_BACKLOG_SIZE);

std::vector<Network::ClientConnectionPtr> client_connections;
std::vector<Network::ConnectionPtr> server_connections;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ProxyProtocolRegressionTest : public testing::TestWithParam<Network::Addre
const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const override {
return empty_access_logs_;
}
uint32_t tcpBacklogSize() const override { return ENVOY_TCP_BACKLOG_SIZE; }

// Network::FilterChainManager
const Network::FilterChain* findFilterChain(const Network::ConnectionSocket&) const override {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class ProxyProtocolTest : public testing::TestWithParam<Network::Address::IpVers
const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const override {
return empty_access_logs_;
}
uint32_t tcpBacklogSize() const override { return ENVOY_TCP_BACKLOG_SIZE; }

// Network::FilterChainManager
const Network::FilterChain* findFilterChain(const Network::ConnectionSocket&) const override {
Expand Down Expand Up @@ -1291,6 +1292,7 @@ class WildcardProxyProtocolTest : public testing::TestWithParam<Network::Address
const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const override {
return empty_access_logs_;
}
uint32_t tcpBacklogSize() const override { return ENVOY_TCP_BACKLOG_SIZE; }

// Network::FilterChainManager
const Network::FilterChain* findFilterChain(const Network::ConnectionSocket&) const override {
Expand Down
Loading