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 1 commit
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 = ENVOY_TCP_BACKLOG_SIZE) PURE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not have a default param on this interface? I would prefer that we make sure we hit all call sites. How many other places need to change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely possible because the first version of the patch didn't use a default param :-). It's a decent amount of tests, but if you're okay with that, I can push an update.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


/**
* 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_;
uint32_t backlog_size_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


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
4 changes: 2 additions & 2 deletions test/common/network/listener_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,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
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
1 change: 1 addition & 0 deletions test/integration/fake_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ class FakeUpstream : Logger::Loggable<Logger::Id::testing>,
return empty_access_logs_;
}
ResourceLimit& openConnections() override { return connection_resource_; }
uint32_t tcpBacklogSize() const override { return ENVOY_TCP_BACKLOG_SIZE; }

void setMaxConnections(const uint32_t num_connections) {
connection_resource_.setMax(num_connections);
Expand Down
7 changes: 4 additions & 3 deletions test/mocks/event/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ class MockDispatcher : public Dispatcher {
}

Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket,
Network::ListenerCallbacks& cb, bool bind_to_port) override {
return Network::ListenerPtr{createListener_(std::move(socket), cb, bind_to_port)};
Network::ListenerCallbacks& cb, bool bind_to_port,
uint32_t backlog_size) override {
return Network::ListenerPtr{createListener_(std::move(socket), cb, bind_to_port, backlog_size)};
}

Network::UdpListenerPtr createUdpListener(Network::SocketSharedPtr&& socket,
Expand Down Expand Up @@ -115,7 +116,7 @@ class MockDispatcher : public Dispatcher {
MOCK_METHOD(Filesystem::Watcher*, createFilesystemWatcher_, ());
MOCK_METHOD(Network::Listener*, createListener_,
(Network::SocketSharedPtr && socket, Network::ListenerCallbacks& cb,
bool bind_to_port));
bool bind_to_port, uint32_t backlog_size));
MOCK_METHOD(Network::UdpListener*, createUdpListener_,
(Network::SocketSharedPtr && socket, Network::UdpListenerCallbacks& cb));
MOCK_METHOD(Timer*, createTimer_, (Event::TimerCb cb));
Expand Down
1 change: 1 addition & 0 deletions test/mocks/network/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ class MockListenerConfig : public ListenerConfig {
MOCK_METHOD(Network::UdpPacketWriterFactoryOptRef, udpPacketWriterFactory, ());
MOCK_METHOD(ConnectionBalancer&, connectionBalancer, ());
MOCK_METHOD(ResourceLimit&, openConnections, ());
MOCK_METHOD(uint32_t, tcpBacklogSize, (), (const));

envoy::config::core::v3::TrafficDirection direction() const override {
return envoy::config::core::v3::UNSPECIFIED;
Expand Down
Loading