From 2fb53f1858988fc9800f2d735043582a3fb78cde Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 25 Aug 2017 17:29:05 -0700 Subject: [PATCH 01/41] listener_impl: Refactor for listener filters. Network::ListenerImpl class implements an libevent socket listener. Factor out all functionality that is not directly libevent related to ConnectionHandlerImpl, which both reduces overall complexity and makes it possible to refactor configurable listener behavior to a new class of listener filters in the following patches. This patch also reduces the special handling for SSL connections by introducing a new dispatcher member for creating server connections. This is used by the refactored code as the connection creation is now shifted from Network::Listener to the connection handler. To further simplify the resulting code, this patch removes Network::ListenerOptions class, as the only option that now needs to be passed to Network::Listener is the "bind to port" boolean, which is now passed in explicitly. All other listener options are handled by passing along Server::Listener instead. Signed-off-by: Jarno Rajahalme --- include/envoy/event/dispatcher.h | 32 +-- include/envoy/network/BUILD | 1 + include/envoy/network/connection_handler.h | 28 +-- include/envoy/network/listen_socket.h | 55 ++++ include/envoy/network/listener.h | 35 +-- include/envoy/server/listener_manager.h | 2 +- source/common/event/dispatcher_impl.cc | 34 +-- source/common/event/dispatcher_impl.h | 12 +- source/common/network/BUILD | 30 ++- source/common/network/listen_socket_impl.h | 41 +++ source/common/network/listener_impl.cc | 107 ++------ source/common/network/listener_impl.h | 46 +--- source/common/network/proxy_protocol.cc | 43 ++-- source/common/network/proxy_protocol.h | 13 +- source/server/BUILD | 3 + source/server/config_validation/dispatcher.cc | 14 +- source/server/config_validation/dispatcher.h | 8 +- source/server/connection_handler_impl.cc | 138 ++++++++--- source/server/connection_handler_impl.h | 60 +++-- source/server/http/BUILD | 1 + source/server/http/admin.cc | 5 +- source/server/http/admin.h | 32 ++- source/server/listener_manager_impl.h | 2 +- source/server/server.cc | 8 +- source/server/server.h | 1 - source/server/worker_impl.cc | 21 +- source/server/worker_impl.h | 1 - test/common/http/codec_client_test.cc | 11 +- test/common/network/BUILD | 1 + test/common/network/connection_impl_test.cc | 41 ++- test/common/network/dns_impl_test.cc | 18 +- test/common/network/listener_impl_test.cc | 234 ++---------------- test/common/network/proxy_protocol_test.cc | 99 +++++--- test/common/ssl/ssl_socket_test.cc | 120 ++++++--- test/integration/fake_upstream.cc | 10 +- test/integration/fake_upstream.h | 24 ++ test/mocks/event/mocks.h | 37 +-- test/mocks/network/BUILD | 1 + test/mocks/network/mocks.cc | 1 + test/mocks/network/mocks.h | 28 ++- test/mocks/server/mocks.h | 2 +- test/server/connection_handler_test.cc | 137 +++++----- test/server/http/admin_test.cc | 11 +- test/server/worker_impl_test.cc | 26 +- 44 files changed, 783 insertions(+), 791 deletions(-) diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 99a563a95aba8..6181ff0326fe5 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -38,6 +38,16 @@ class Dispatcher { */ virtual void clearDeferredDeleteList() PURE; + /** + * Create a server connection. + * @param accept_socket supplies a socket with an open file descriptor and connection metadata + * to use for the connection. Takes ownership of the accept_socket. + * @param ssl_ctx supplies the SSL context to use, if not nullptr. + * @return Network::ConnectionPtr a client connection that is owned by the caller. + */ + virtual Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, + Ssl::Context* ssl_ctx) PURE; + /** * Create a client connection. * @param address supplies the address to connect to. @@ -85,25 +95,9 @@ class Dispatcher { * @param listener_options listener configuration options. * @return Network::ListenerPtr a new listener that is owned by the caller. */ - virtual Network::ListenerPtr - createListener(Network::ConnectionHandler& conn_handler, Network::ListenSocket& socket, - Network::ListenerCallbacks& cb, Stats::Scope& scope, - const Network::ListenerOptions& listener_options) PURE; - - /** - * Create a listener on a specific port. - * @param conn_handler supplies the handler for connections received by the listener - * @param ssl_ctx supplies the SSL context to use. - * @param socket supplies the socket to listen on. - * @param cb supplies the callbacks to invoke for listener events. - * @param scope supplies the Stats::Scope to use. - * @param listener_options listener configuration options. - * @return Network::ListenerPtr a new listener that is owned by the caller. - */ - virtual Network::ListenerPtr - createSslListener(Network::ConnectionHandler& conn_handler, Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - Stats::Scope& scope, const Network::ListenerOptions& listener_options) PURE; + virtual Network::ListenerPtr createListener(Network::ListenSocket& socket, + Network::ListenerCallbacks& cb, + bool bind_to_port) PURE; /** * Allocate a timer. @see Event::Timer for docs on how to use the timer. diff --git a/include/envoy/network/BUILD b/include/envoy/network/BUILD index 57e1c57d564e2..bf2e6982c04c9 100644 --- a/include/envoy/network/BUILD +++ b/include/envoy/network/BUILD @@ -73,6 +73,7 @@ envoy_cc_library( envoy_cc_library( name = "listener_interface", hdrs = ["listener.h"], + deps = ["//include/envoy/network:listen_socket_interface"], ) envoy_cc_library( diff --git a/include/envoy/network/connection_handler.h b/include/envoy/network/connection_handler.h index 354304baf2905..254dcd49f8b36 100644 --- a/include/envoy/network/connection_handler.h +++ b/include/envoy/network/connection_handler.h @@ -10,6 +10,11 @@ #include "envoy/ssl/context.h" namespace Envoy { + +namespace Server { +class Listener; +} +// XXX: Move to Server namespace? namespace Network { /** @@ -26,28 +31,9 @@ class ConnectionHandler { /** * Adds listener to the handler. - * @param factory supplies the configuration factory for new connections. - * @param socket supplies the already bound socket to listen on. - * @param scope supplies the stats scope to use for listener specific stats. - * @param listener_tag supplies an opaque tag that can be used to stop or remove the listener. - * @param listener_options listener configuration options. - */ - virtual void addListener(Network::FilterChainFactory& factory, Network::ListenSocket& socket, - Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options) PURE; - - /** - * Adds listener to the handler. - * @param factory supplies the configuration factory for new connections. - * @param socket supplies the already bound socket to listen on. - * @param scope supplies the stats scope to use for listener specific stats. - * @param listener_tag supplies an opaque tag that can be used to stop or remove the listener. - * @param listener_options listener configuration options. + * @param config listener configuration options. */ - virtual void addSslListener(Network::FilterChainFactory& factory, Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Stats::Scope& scope, - uint64_t listener_tag, - const Network::ListenerOptions& listener_options) PURE; + virtual void addListener(Server::Listener& config) PURE; /** * Find a listener based on the provided listener address value. diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 2d0cb689f79ca..5a4ae27dea9d6 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -34,5 +34,60 @@ class ListenSocket { typedef std::unique_ptr ListenSocketPtr; typedef std::shared_ptr ListenSocketSharedPtr; +/** + * An abstract accept socket. + */ +class AcceptSocket { +public: + virtual ~AcceptSocket() {} + + /** + * @return the address that the socket was received at, or an original destination address if + * applicable. + */ + virtual Address::InstanceConstSharedPtr localAddress() const PURE; + + /** + * Reset the original destination address of the socket to a different address than the one + * the socket was accepted at. + */ + virtual void resetLocalAddress(Address::InstanceConstSharedPtr& local_address) PURE; + + /** + * @return true if the local address has been reset. + */ + virtual bool localAddressReset() const PURE; + + /** + * @return the address that the socket was received from, or an original source address if + * applicable. + */ + virtual Address::InstanceConstSharedPtr remoteAddress() const PURE; + + /** + * Set the original source address of the socket + */ + virtual void resetRemoteAddress(Address::InstanceConstSharedPtr& remote_address) PURE; + + /** + * @return fd the accept socket's file descriptor. + */ + virtual int fd() const PURE; + + /** + * Transfer ownership of the file descriptor to the caller, so that the underlying socket will + * not be closed on delete. + */ + virtual int takeFd() PURE; + + /** + * Close the underlying socket. + */ + virtual void close() PURE; +}; + +typedef std::unique_ptr AcceptSocketPtr; +typedef std::shared_ptr AcceptSocketSharedPtr; + } // namespace Network } // namespace Envoy diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index be0cecdbdcb24..22e6d78054c83 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -6,38 +6,11 @@ #include "envoy/common/exception.h" #include "envoy/network/connection.h" +#include "envoy/network/listen_socket.h" namespace Envoy { namespace Network { -/** - * Listener configurations options. - */ -struct ListenerOptions { - // Specifies if the listener should actually bind to the port. A listener that doesn't bind can - // only receive connections redirected from other listeners that set use_origin_dst_ to true. - bool bind_to_port_; - // Whether to use the PROXY Protocol V1 - // (http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) - bool use_proxy_proto_; - // If a connection was redirected to this port using iptables, allow the listener to hand it off - // to the listener associated to the original port. - bool use_original_dst_; - // Soft limit on size of the listener's new connection read and write buffers. - uint32_t per_connection_buffer_limit_bytes_; - - /** - * Factory for ListenerOptions with bind_to_port_ set. - * @return ListenerOptions object initialized with bind_to_port_ set. - */ - static ListenerOptions listenerOptionsWithBindToPort() { - return {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0}; - } -}; - /** * Callbacks invoked by a listener. */ @@ -45,6 +18,12 @@ class ListenerCallbacks { public: virtual ~ListenerCallbacks() {} + /** + * Called when a new connection is accepted. + * @param socket supplies the socket that is moved into the callee. + */ + virtual void onAccept(AcceptSocketPtr&& socket) PURE; + /** * Called when a new connection is accepted. * @param new_connection supplies the new connection that is moved into the callee. diff --git a/include/envoy/server/listener_manager.h b/include/envoy/server/listener_manager.h index 2277658309dce..4183bcaeedcd2 100644 --- a/include/envoy/server/listener_manager.h +++ b/include/envoy/server/listener_manager.h @@ -109,7 +109,7 @@ class Listener { /** * @return uint64_t the tag the listener should use for connection handler tracking. */ - virtual uint64_t listenerTag() PURE; + virtual uint64_t listenerTag() const PURE; /** * @return const std::string& the listener's name. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index 9a217fc576939..92a1d35fbc804 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -68,6 +68,19 @@ void DispatcherImpl::clearDeferredDeleteList() { deferred_deleting_ = false; } +Network::ConnectionPtr DispatcherImpl::createConnection(Network::AcceptSocketPtr&& socket, + Ssl::Context* ssl_ctx) { + ASSERT(isThreadSafe()); + return Network::ConnectionPtr{ + ssl_ctx ? new Ssl::ConnectionImpl( + *this, socket->takeFd(), socket->remoteAddress(), socket->localAddress(), + Network::Address::InstanceConstSharedPtr(), socket->localAddressReset(), true, + *ssl_ctx, Ssl::InitialState::Server) + : new Network::ConnectionImpl( + *this, socket->takeFd(), socket->remoteAddress(), socket->localAddress(), + Network::Address::InstanceConstSharedPtr(), socket->localAddressReset(), true)}; +} + Network::ClientConnectionPtr DispatcherImpl::createClientConnection(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, @@ -94,24 +107,11 @@ Filesystem::WatcherPtr DispatcherImpl::createFilesystemWatcher() { return Filesystem::WatcherPtr{new Filesystem::WatcherImpl(*this)}; } -Network::ListenerPtr -DispatcherImpl::createListener(Network::ConnectionHandler& conn_handler, - Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - Stats::Scope& scope, - const Network::ListenerOptions& listener_options) { - ASSERT(isThreadSafe()); - return Network::ListenerPtr{ - new Network::ListenerImpl(conn_handler, *this, socket, cb, scope, listener_options)}; -} - -Network::ListenerPtr -DispatcherImpl::createSslListener(Network::ConnectionHandler& conn_handler, - Ssl::ServerContext& ssl_ctx, Network::ListenSocket& socket, - Network::ListenerCallbacks& cb, Stats::Scope& scope, - const Network::ListenerOptions& listener_options) { +Network::ListenerPtr DispatcherImpl::createListener(Network::ListenSocket& socket, + Network::ListenerCallbacks& cb, + bool bind_to_port) { ASSERT(isThreadSafe()); - return Network::ListenerPtr{new Network::SslListenerImpl(conn_handler, *this, ssl_ctx, socket, cb, - scope, listener_options)}; + return Network::ListenerPtr{new Network::ListenerImpl(*this, socket, cb, bind_to_port)}; } TimerPtr DispatcherImpl::createTimer(TimerCb cb) { diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index eeb2b08a25a98..027e34e1eed9a 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -33,6 +33,8 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { // Event::Dispatcher void clearDeferredDeleteList() override; + Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, + Ssl::Context* ssl_ctx) override; Network::ClientConnectionPtr createClientConnection(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, @@ -42,14 +44,8 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { FileEventPtr createFileEvent(int fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) override; Filesystem::WatcherPtr createFilesystemWatcher() override; - Network::ListenerPtr createListener(Network::ConnectionHandler& conn_handler, - Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - Stats::Scope& scope, - const Network::ListenerOptions& listener_options) override; - Network::ListenerPtr createSslListener(Network::ConnectionHandler& conn_handler, - Ssl::ServerContext& ssl_ctx, Network::ListenSocket& socket, - Network::ListenerCallbacks& cb, Stats::Scope& scope, - const Network::ListenerOptions& listener_options) override; + Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, + bool bind_to_port) override; TimerPtr createTimer(TimerCb cb) override; void deferredDelete(DeferredDeletablePtr&& to_delete) override; void exit() override; diff --git a/source/common/network/BUILD b/source/common/network/BUILD index d0d845ec8a6f8..d2bd87e2cabac 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -107,33 +107,49 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "proxy_protocol_lib", + srcs = [ + "proxy_protocol.cc", + ], + hdrs = [ + "proxy_protocol.h", + ], + deps = [ + ":address_lib", + ":listen_socket_lib", + "//include/envoy/event:dispatcher_interface", + "//include/envoy/event:file_event_interface", + "//include/envoy/stats:stats_interface", + "//include/envoy/stats:stats_macros", + "//source/common/common:empty_string", + "//source/common/common:linked_object", + "//source/common/event:dispatcher_includes", + "//source/common/event:libevent_lib", + ], +) + envoy_cc_library( name = "listener_lib", srcs = [ "listener_impl.cc", - "proxy_protocol.cc", ], hdrs = [ "listener_impl.h", - "proxy_protocol.h", ], deps = [ ":address_lib", - ":connection_lib", ":listen_socket_lib", - ":utility_lib", "//include/envoy/event:dispatcher_interface", "//include/envoy/event:file_event_interface", - "//include/envoy/network:connection_handler_interface", "//include/envoy/network:listener_interface", "//include/envoy/stats:stats_interface", "//include/envoy/stats:stats_macros", + "//source/common/common:assert_lib", "//source/common/common:empty_string", "//source/common/common:linked_object", - "//source/common/common:utility_lib", "//source/common/event:dispatcher_includes", "//source/common/event:libevent_lib", - "//source/common/ssl:connection_lib", ], ) diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index e525b17e0c872..cd811c67392d3 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -50,5 +50,46 @@ class UdsListenSocket : public ListenSocketImpl { UdsListenSocket(const std::string& uds_path); }; +class AcceptSocketImpl : public AcceptSocket { +public: + AcceptSocketImpl(int fd, Address::InstanceConstSharedPtr&& local_address, + Address::InstanceConstSharedPtr&& remote_address) + : fd_(fd), local_address_reset_(false), local_address_(std::move(local_address)), + remote_address_(std::move(remote_address)) {} + ~AcceptSocketImpl() { close(); } + + // Network::AcceptSocket + Address::InstanceConstSharedPtr localAddress() const override { return local_address_; } + void resetLocalAddress(Address::InstanceConstSharedPtr& local_address) override { + local_address_ = local_address; + local_address_reset_ = true; + } + bool localAddressReset() const override { return local_address_reset_; } + Address::InstanceConstSharedPtr remoteAddress() const override { return remote_address_; } + void resetRemoteAddress(Address::InstanceConstSharedPtr& remote_address) override { + remote_address_ = remote_address; + } + int fd() const override { return fd_; } + + int takeFd() override { + int fd = fd_; + fd_ = -1; + return fd; + } + + void close() override { + if (fd_ != -1) { + ::close(fd_); + fd_ = -1; + } + } + +protected: + int fd_; + bool local_address_reset_; + Address::InstanceConstSharedPtr local_address_; + Address::InstanceConstSharedPtr remote_address_; +}; + } // namespace Network } // namespace Envoy diff --git a/source/common/network/listener_impl.cc b/source/common/network/listener_impl.cc index a3a9e395c4456..c8ff51384736f 100644 --- a/source/common/network/listener_impl.cc +++ b/source/common/network/listener_impl.cc @@ -3,15 +3,12 @@ #include #include "envoy/common/exception.h" -#include "envoy/network/connection_handler.h" +#include "common/common/assert.h" #include "common/common/empty_string.h" #include "common/event/dispatcher_impl.h" #include "common/event/file_event_impl.h" #include "common/network/address_impl.h" -#include "common/network/connection_impl.h" -#include "common/network/utility.h" -#include "common/ssl/connection_impl.h" #include "event2/listener.h" #include "fmt/format.h" @@ -23,77 +20,39 @@ Address::InstanceConstSharedPtr ListenerImpl::getLocalAddress(int fd) { return Address::addressFromFd(fd); } -Address::InstanceConstSharedPtr ListenerImpl::getOriginalDst(int fd) { - return Utility::getOriginalDst(fd); -} - void ListenerImpl::listenCallback(evconnlistener*, evutil_socket_t fd, sockaddr* remote_addr, int remote_addr_len, void* arg) { ListenerImpl* listener = static_cast(arg); - Address::InstanceConstSharedPtr final_local_address = listener->socket_.localAddress(); - bool using_original_dst = false; - - // Get the local address from the new socket if the listener is listening on the all hosts - // address (e.g., 0.0.0.0 for IPv4). - auto ip = final_local_address->ip(); - if (ip && ip->isAnyAddress()) { - final_local_address = listener->getLocalAddress(fd); - } - - if (listener->options_.use_original_dst_ && final_local_address->type() == Address::Type::Ip) { - Address::InstanceConstSharedPtr original_local_address = listener->getOriginalDst(fd); - - // A listener that has the use_original_dst flag set to true can still receive - // connections that are NOT redirected using iptables. If a connection was not redirected, - // the address returned by getOriginalDst() matches the local address of the new socket. - // In this case the listener handles the connection directly and does not hand it off. - if (original_local_address && (*original_local_address != *final_local_address)) { - final_local_address = original_local_address; - using_original_dst = true; - - // Hands off redirected connections (from iptables) to the listener associated with the - // original destination address. If there is no listener associated with the original - // destination address, the connection is handled by the listener that receives it. - ListenerImpl* new_listener = dynamic_cast( - listener->connection_handler_.findListenerByAddress(*original_local_address)); - - if (new_listener != nullptr) { - listener = new_listener; - } - } - } - - if (listener->options_.use_proxy_proto_) { - listener->proxy_protocol_.newConnection(listener->dispatcher_, fd, *listener); - } else { - Address::InstanceConstSharedPtr final_remote_address; - if (remote_addr->sa_family == AF_UNIX) { + AcceptSocketPtr socket(new AcceptSocketImpl( + fd, + // Get the local address from the new socket if the listener is listening on the all hosts + // address (e.g., 0.0.0.0 for IPv4). + !listener->local_address_ ? listener->getLocalAddress(fd) : listener->local_address_, // The accept() call that filled in remote_addr doesn't fill in more than the sa_family field // for Unix domain sockets; apparently there isn't a mechanism in the kernel to get the // sockaddr_un associated with the client socket when starting from the server socket. // We work around this by using our own name for the socket in this case. - final_remote_address = Address::peerAddressFromFd(fd); - } else { - final_remote_address = Address::addressFromSockAddr( - *reinterpret_cast(remote_addr), remote_addr_len); - } - // TODO(jamessynge): We need to keep per-family stats. BUT, should it be based on the original - // family or the local family? Probably local family, as the original proxy can take care of - // stats for the original family. - listener->newConnection(fd, final_remote_address, final_local_address, using_original_dst); - } + (remote_addr->sa_family == AF_UNIX) + ? Address::peerAddressFromFd(fd) + : Address::addressFromSockAddr(*reinterpret_cast(remote_addr), + remote_addr_len))); + listener->cb_.onAccept(std::move(socket)); } -ListenerImpl::ListenerImpl(Network::ConnectionHandler& conn_handler, - Event::DispatcherImpl& dispatcher, ListenSocket& socket, - ListenerCallbacks& cb, Stats::Scope& scope, - const Network::ListenerOptions& listener_options) - : connection_handler_(conn_handler), dispatcher_(dispatcher), socket_(socket), cb_(cb), - proxy_protocol_(scope), options_(listener_options), listener_(nullptr) { +ListenerImpl::ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, + ListenerCallbacks& cb, bool bind_to_port) + : local_address_(nullptr), cb_(cb), listener_(nullptr) { + auto ip = socket.localAddress()->ip(); + + // Only use the listen socket's local address for new connections if it is not the all hosts + // address (e.g., 0.0.0.0 for IPv4). + if (!(ip && ip->isAnyAddress())) { + local_address_ = socket.localAddress(); + } - if (options_.bind_to_port_) { + if (bind_to_port) { listener_.reset( - evconnlistener_new(&dispatcher_.base(), listenCallback, this, 0, -1, socket.fd())); + evconnlistener_new(&dispatcher.base(), listenCallback, this, 0, -1, socket.fd())); if (!listener_) { throw CreateListenerException( @@ -110,25 +69,5 @@ void ListenerImpl::errorCallback(evconnlistener*, void*) { PANIC(fmt::format("listener accept failure: {}", strerror(errno))); } -void ListenerImpl::newConnection(int fd, Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - bool using_original_dst) { - ConnectionPtr new_connection(new ConnectionImpl(dispatcher_, fd, remote_address, local_address, - Network::Address::InstanceConstSharedPtr(), - using_original_dst, true)); - new_connection->setBufferLimits(options_.per_connection_buffer_limit_bytes_); - cb_.onNewConnection(std::move(new_connection)); -} - -void SslListenerImpl::newConnection(int fd, Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - bool using_original_dst) { - ConnectionPtr new_connection(new Ssl::ConnectionImpl( - dispatcher_, fd, remote_address, local_address, Network::Address::InstanceConstSharedPtr(), - using_original_dst, true, ssl_ctx_, Ssl::InitialState::Server)); - new_connection->setBufferLimits(options_.per_connection_buffer_limit_bytes_); - cb_.onNewConnection(std::move(new_connection)); -} - } // namespace Network } // namespace Envoy diff --git a/source/common/network/listener_impl.h b/source/common/network/listener_impl.h index e46dfcd99e341..1c931d9b8a465 100644 --- a/source/common/network/listener_impl.h +++ b/source/common/network/listener_impl.h @@ -1,12 +1,10 @@ #pragma once -#include "envoy/network/connection_handler.h" #include "envoy/network/listener.h" #include "common/event/dispatcher_impl.h" #include "common/event/libevent.h" #include "common/network/listen_socket_impl.h" -#include "common/network/proxy_protocol.h" #include "event2/event.h" @@ -18,35 +16,14 @@ namespace Network { */ class ListenerImpl : public Listener { public: - ListenerImpl(Network::ConnectionHandler& conn_handler, Event::DispatcherImpl& dispatcher, - ListenSocket& socket, ListenerCallbacks& cb, Stats::Scope& scope, - const ListenerOptions& listener_options); - - /** - * Accept/process a new connection. - * @param fd supplies the new connection's fd. - * @param remote_address supplies the remote address for the new connection. - * @param local_address supplies the local address for the new connection. - */ - virtual void newConnection(int fd, Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - bool using_original_dst); - - /** - * @return the socket supplied to the listener at construction time - */ - ListenSocket& socket() { return socket_; } + ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, + bool bind_to_port); protected: virtual Address::InstanceConstSharedPtr getLocalAddress(int fd); - virtual Address::InstanceConstSharedPtr getOriginalDst(int fd); - Network::ConnectionHandler& connection_handler_; - Event::DispatcherImpl& dispatcher_; - ListenSocket& socket_; + Address::InstanceConstSharedPtr local_address_; ListenerCallbacks& cb_; - ProxyProtocol proxy_protocol_; - const ListenerOptions options_; private: static void errorCallback(evconnlistener* listener, void* context); @@ -56,22 +33,5 @@ class ListenerImpl : public Listener { Event::Libevent::ListenerPtr listener_; }; -class SslListenerImpl : public ListenerImpl { -public: - SslListenerImpl(Network::ConnectionHandler& conn_handler, Event::DispatcherImpl& dispatcher, - Ssl::Context& ssl_ctx, ListenSocket& socket, ListenerCallbacks& cb, - Stats::Scope& scope, const Network::ListenerOptions& listener_options) - : ListenerImpl(conn_handler, dispatcher, socket, cb, scope, listener_options), - ssl_ctx_(ssl_ctx) {} - - // ListenerImpl - void newConnection(int fd, Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - bool using_original_dst) override; - -private: - Ssl::Context& ssl_ctx_; -}; - } // namespace Network } // namespace Envoy diff --git a/source/common/network/proxy_protocol.cc b/source/common/network/proxy_protocol.cc index 2809982b8bed0..9116816b57684 100644 --- a/source/common/network/proxy_protocol.cc +++ b/source/common/network/proxy_protocol.cc @@ -14,7 +14,6 @@ #include "common/common/empty_string.h" #include "common/common/utility.h" #include "common/network/address_impl.h" -#include "common/network/listener_impl.h" #include "common/network/utility.h" namespace Envoy { @@ -23,17 +22,21 @@ namespace Network { ProxyProtocol::ProxyProtocol(Stats::Scope& scope) : stats_{ALL_PROXY_PROTOCOL_STATS(POOL_COUNTER(scope))} {} -void ProxyProtocol::newConnection(Event::Dispatcher& dispatcher, int fd, ListenerImpl& listener) { - std::unique_ptr p{new ActiveConnection(*this, dispatcher, fd, listener)}; +void ProxyProtocol::newConnection(Event::Dispatcher& dispatcher, AcceptSocketPtr&& socket, + ProxyProtocolCompletion newConnectionCb) { + std::unique_ptr p{ + new ActiveConnection(*this, dispatcher, std::move(socket), newConnectionCb)}; p->moveIntoList(std::move(p), connections_); } ProxyProtocol::ActiveConnection::ActiveConnection(ProxyProtocol& parent, - Event::Dispatcher& dispatcher, int fd, - ListenerImpl& listener) - : parent_(parent), fd_(fd), listener_(listener), search_index_(1) { + Event::Dispatcher& dispatcher, + AcceptSocketPtr&& socket, + ProxyProtocolCompletion newConnectionCb) + : parent_(parent), socket_(std::move(socket)), newConnectionCb_(newConnectionCb), + search_index_(1) { file_event_ = - dispatcher.createFileEvent(fd, + dispatcher.createFileEvent(socket_->fd(), [this](uint32_t events) { ASSERT(events == Event::FileReadyType::Read); UNREFERENCED_PARAMETER(events); @@ -42,11 +45,7 @@ ProxyProtocol::ActiveConnection::ActiveConnection(ProxyProtocol& parent, Event::FileTriggerType::Edge, Event::FileReadyType::Read); } -ProxyProtocol::ActiveConnection::~ActiveConnection() { - if (fd_ != -1) { - ::close(fd_); - } -} +ProxyProtocol::ActiveConnection::~ActiveConnection() {} void ProxyProtocol::ActiveConnection::onRead() { try { @@ -59,7 +58,7 @@ void ProxyProtocol::ActiveConnection::onRead() { void ProxyProtocol::ActiveConnection::onReadWorker() { std::string proxy_line; - if (!readLine(fd_, proxy_line)) { + if (!readLine(socket_->fd(), proxy_line)) { return; } @@ -77,7 +76,7 @@ void ProxyProtocol::ActiveConnection::onReadWorker() { if (line_parts[1] == "UNKNOWN") { // At this point we know it's a proxy protocol line, so we can remove it from the socket // and continue. - Address::InstanceConstSharedPtr local_address = Envoy::Network::Address::addressFromFd(fd_); + Address::InstanceConstSharedPtr local_address = Envoy::Network::Address::addressFromFd(socket_->fd()); Address::InstanceConstSharedPtr remote_address; // The remote address not known. if (local_address->ip()->version() == Address::IpVersion::v4) { @@ -130,20 +129,20 @@ void ProxyProtocol::ActiveConnection::onReadWorker() { void ProxyProtocol::ActiveConnection::finishConnection( Address::InstanceConstSharedPtr remote_address, Address::InstanceConstSharedPtr local_address) { - - ListenerImpl& listener = listener_; - int fd = fd_; - fd_ = -1; - + socket_->resetLocalAddress(local_address); + socket_->resetRemoteAddress(remote_address); + ProxyProtocolCompletion newConnectionCb = newConnectionCb_; + AcceptSocketPtr socket(std::move(socket_)); removeFromList(parent_.connections_); - listener.newConnection(fd, remote_address, local_address, true); + newConnectionCb(std::move(socket), true); } void ProxyProtocol::ActiveConnection::close() { - ::close(fd_); - fd_ = -1; + ProxyProtocolCompletion newConnectionCb = newConnectionCb_; + AcceptSocketPtr&& socket(std::move(socket_)); removeFromList(parent_.connections_); + newConnectionCb(std::move(socket), false); } bool ProxyProtocol::ActiveConnection::readLine(int fd, std::string& s) { diff --git a/source/common/network/proxy_protocol.h b/source/common/network/proxy_protocol.h index 1780f792c19d3..4b63835867180 100644 --- a/source/common/network/proxy_protocol.h +++ b/source/common/network/proxy_protocol.h @@ -12,7 +12,7 @@ namespace Envoy { namespace Network { -class ListenerImpl; +typedef std::function ProxyProtocolCompletion; /** * All stats for the proxy protocol. @see stats_macros.h @@ -37,8 +37,8 @@ class ProxyProtocol { public: class ActiveConnection : public LinkedObject { public: - ActiveConnection(ProxyProtocol& parent, Event::Dispatcher& dispatcher, int fd, - ListenerImpl& listener); + ActiveConnection(ProxyProtocol& parent, Event::Dispatcher& dispatcher, AcceptSocketPtr&& socket, + ProxyProtocolCompletion newConnectionCb); ~ActiveConnection(); private: @@ -62,8 +62,8 @@ class ProxyProtocol { Address::InstanceConstSharedPtr local_address); ProxyProtocol& parent_; - int fd_; - ListenerImpl& listener_; + AcceptSocketPtr socket_; + ProxyProtocolCompletion newConnectionCb_; Event::FileEventPtr file_event_; // The offset in buf_ that has been fully read @@ -78,7 +78,8 @@ class ProxyProtocol { ProxyProtocol(Stats::Scope& scope); - void newConnection(Event::Dispatcher& dispatcher, int fd, ListenerImpl& listener); + void newConnection(Event::Dispatcher& dispatcher, AcceptSocketPtr&& socket, + ProxyProtocolCompletion newConnectionCb); private: ProxyProtocolStats stats_; diff --git a/source/server/BUILD b/source/server/BUILD index d2bea25d768aa..a32f37f870489 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -63,9 +63,12 @@ envoy_cc_library( "//include/envoy/network:filter_interface", "//include/envoy/network:listen_socket_interface", "//include/envoy/network:listener_interface", + "//include/envoy/server:listener_manager_interface", "//include/envoy/stats:timespan", "//source/common/common:linked_object", "//source/common/common:non_copyable", + "//source/common/network:connection_lib", + "//source/common/network:proxy_protocol_lib", ], ) diff --git a/source/server/config_validation/dispatcher.cc b/source/server/config_validation/dispatcher.cc index 08920e8184a54..f9445c8b7671b 100644 --- a/source/server/config_validation/dispatcher.cc +++ b/source/server/config_validation/dispatcher.cc @@ -17,18 +17,8 @@ Network::DnsResolverSharedPtr ValidationDispatcher::createDnsResolver( NOT_IMPLEMENTED; } -Network::ListenerPtr ValidationDispatcher::createListener(Network::ConnectionHandler&, - Network::ListenSocket&, - Network::ListenerCallbacks&, - Stats::Scope&, - const Network::ListenerOptions&) { - NOT_IMPLEMENTED; -} - -Network::ListenerPtr -ValidationDispatcher::createSslListener(Network::ConnectionHandler&, Ssl::ServerContext&, - Network::ListenSocket&, Network::ListenerCallbacks&, - Stats::Scope&, const Network::ListenerOptions&) { +Network::ListenerPtr ValidationDispatcher::createListener(Network::ListenSocket&, + Network::ListenerCallbacks&, bool) { NOT_IMPLEMENTED; } diff --git a/source/server/config_validation/dispatcher.h b/source/server/config_validation/dispatcher.h index b9639b0a9ade4..2480eaae4b9e1 100644 --- a/source/server/config_validation/dispatcher.h +++ b/source/server/config_validation/dispatcher.h @@ -19,12 +19,8 @@ class ValidationDispatcher : public DispatcherImpl { Network::TransportSocketPtr&&) override; Network::DnsResolverSharedPtr createDnsResolver( const std::vector& resolvers) override; - Network::ListenerPtr createListener(Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks&, Stats::Scope&, - const Network::ListenerOptions&) override; - Network::ListenerPtr createSslListener(Network::ConnectionHandler&, Ssl::ServerContext&, - Network::ListenSocket&, Network::ListenerCallbacks&, - Stats::Scope&, const Network::ListenerOptions&) override; + Network::ListenerPtr createListener(Network::ListenSocket&, Network::ListenerCallbacks&, + bool bind_to_port) override; }; } // namespace Event diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index de960b426c7d8..00a838baa366a 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -5,29 +5,18 @@ #include "envoy/network/filter.h" #include "envoy/stats/timespan.h" +#include "common/network/connection_impl.h" +#include "common/network/utility.h" + namespace Envoy { namespace Server { ConnectionHandlerImpl::ConnectionHandlerImpl(spdlog::logger& logger, Event::Dispatcher& dispatcher) : logger_(logger), dispatcher_(dispatcher) {} -void ConnectionHandlerImpl::addListener(Network::FilterChainFactory& factory, - Network::ListenSocket& socket, Stats::Scope& scope, - uint64_t listener_tag, - const Network::ListenerOptions& listener_options) { - ActiveListenerPtr l( - new ActiveListener(*this, socket, factory, scope, listener_tag, listener_options)); - listeners_.emplace_back(socket.localAddress(), std::move(l)); -} - -void ConnectionHandlerImpl::addSslListener(Network::FilterChainFactory& factory, - Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Stats::Scope& scope, - uint64_t listener_tag, - const Network::ListenerOptions& listener_options) { - ActiveListenerPtr l(new SslActiveListener(*this, ssl_ctx, socket, factory, scope, listener_tag, - listener_options)); - listeners_.emplace_back(socket.localAddress(), std::move(l)); +void ConnectionHandlerImpl::addListener(Listener& config) { + ActiveListenerPtr l(new ActiveListener(*this, config)); + listeners_.emplace_back(config.socket().localAddress(), std::move(l)); } void ConnectionHandlerImpl::removeListeners(uint64_t listener_tag) { @@ -63,22 +52,26 @@ void ConnectionHandlerImpl::ActiveListener::removeConnection(ActiveConnection& c parent_.num_connections_--; } -ConnectionHandlerImpl::ActiveListener::ActiveListener( - ConnectionHandlerImpl& parent, Network::ListenSocket& socket, - Network::FilterChainFactory& factory, Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options) - : ActiveListener( - parent, parent.dispatcher_.createListener(parent, socket, *this, scope, listener_options), - factory, scope, listener_tag) {} +ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& parent, + Listener& config) + : ActiveListener(parent, + parent.dispatcher_.createListener(config.socket(), *this, config.bindToPort()), + config) {} ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& parent, Network::ListenerPtr&& listener, - Network::FilterChainFactory& factory, - Stats::Scope& scope, uint64_t listener_tag) - : parent_(parent), factory_(factory), listener_(std::move(listener)), - stats_(generateStats(scope)), listener_tag_(listener_tag) {} + Listener& config) + : parent_(parent), listener_(std::move(listener)), + stats_(generateStats(config.listenerScope())), listener_tag_(config.listenerTag()), + proxy_protocol_(config.listenerScope()), config_(config) {} ConnectionHandlerImpl::ActiveListener::~ActiveListener() { + while (!sockets_.empty()) { + ActiveSocketPtr removed = sockets_.front()->removeFromList(sockets_); + removed->socket_->close(); + parent_.dispatcher_.deferredDelete(std::move(removed)); + } + while (!connections_.empty()) { connections_.front()->connection_->close(Network::ConnectionCloseType::NoFlush); } @@ -86,17 +79,14 @@ ConnectionHandlerImpl::ActiveListener::~ActiveListener() { parent_.dispatcher_.clearDeferredDeleteList(); } -ConnectionHandlerImpl::SslActiveListener::SslActiveListener( - ConnectionHandlerImpl& parent, Ssl::ServerContext& ssl_ctx, Network::ListenSocket& socket, - Network::FilterChainFactory& factory, Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options) - : ActiveListener(parent, - parent.dispatcher_.createSslListener(parent, ssl_ctx, socket, *this, scope, - listener_options), - factory, scope, listener_tag) {} - Network::Listener* ConnectionHandlerImpl::findListenerByAddress(const Network::Address::Instance& address) { + ActiveListener* listener = findActiveListenerByAddress(address); + return listener ? listener->listener_.get() : nullptr; +} + +ConnectionHandlerImpl::ActiveListener* +ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Instance& address) { // This is a linear operation, may need to add a map to improve performance. // However, linear performance might be adequate since the number of listeners is small. // We do not return stopped listeners. @@ -109,7 +99,7 @@ ConnectionHandlerImpl::findListenerByAddress(const Network::Address::Instance& a // If there is exact address match, return the corresponding listener. if (listener != listeners_.end()) { - return listener->second->listener_.get(); + return listener->second.get(); } // Otherwise, we need to look for the wild card match, i.e., 0.0.0.0:[address_port]. @@ -121,13 +111,81 @@ ConnectionHandlerImpl::findListenerByAddress(const Network::Address::Instance& a return p.second->listener_ != nullptr && p.first->type() == Network::Address::Type::Ip && p.first->ip()->port() == address.ip()->port() && p.first->ip()->isAnyAddress(); }); - return (listener != listeners_.end()) ? listener->second->listener_.get() : nullptr; + return (listener != listeners_.end()) ? listener->second.get() : nullptr; +} + +Network::Address::InstanceConstSharedPtr +ConnectionHandlerImpl::ActiveListener::getOriginalDst(int fd) { + return Network::Utility::getOriginalDst(fd); +} + +void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptSocketPtr&& accept_socket) { + Network::AcceptSocket* socket = accept_socket.get(); + Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); + ActiveSocketPtr active_socket(new ActiveSocket(*this, std::move(accept_socket))); + +#if 0 + /* Not needed yet. */ + active_socket->moveIntoList(std::move(active_socket), sockets_); +#endif + + // This logic will move to Original Dst Filter + if (config_.useOriginalDst() && local_address->type() == Network::Address::Type::Ip) { + Network::Address::InstanceConstSharedPtr original_local_address = getOriginalDst(socket->fd()); + + // A listener that has the use_original_dst flag set to true can still receive + // connections that are NOT redirected using iptables. If a connection was not redirected, + // the address returned by getOriginalDst() matches the local address of the new socket. + // In this case the listener handles the connection directly and does not hand it off. + if (original_local_address && (*original_local_address != *local_address)) { + socket->resetLocalAddress(original_local_address); + local_address = original_local_address; + + // Hands off redirected connections (from iptables) to the listener associated with the + // original destination address. If there is no listener associated with the original + // destination address, the connection is handled by the listener that receives it. + ActiveListener* new_listener = parent_.findActiveListenerByAddress(*original_local_address); + + if (new_listener != nullptr) { + active_socket->listener_ = new_listener; + } + } + } + + // 'this' may not be the listener any more, must use 'active_socket->listener_'. + + // This logic will move to Proxy Protocol Filter + // XXX: Race if listener is removed while proxy protocol is waiting for more data? + // Seems this race affects the existing implementation in master as well. + if (active_socket->listener_->config_.useProxyProto()) { + ActiveListener* listener = active_socket->listener_; + listener->proxy_protocol_.newConnection( + listener->parent_.dispatcher_, std::move(active_socket->socket_), + [listener](Network::AcceptSocketPtr&& socketPtr, bool success) mutable { + if (success) { + listener->newConnection(std::move(socketPtr)); + } + }); + } else { + // TODO(jamessynge): We need to keep per-family stats. BUT, should it be based on the original + // family or the local family? Probably local family, as the original proxy can take care of + // stats for the original family. + active_socket->listener_->newConnection(std::move(active_socket->socket_)); + } +} + +void ConnectionHandlerImpl::ActiveListener::newConnection( + Network::AcceptSocketPtr&& accept_socket) { + Network::ConnectionPtr new_connection = + parent_.dispatcher_.createConnection(std::move(accept_socket), config_.defaultSslContext()); + new_connection->setBufferLimits(config_.perConnectionBufferLimitBytes()); + onNewConnection(std::move(new_connection)); } void ConnectionHandlerImpl::ActiveListener::onNewConnection( Network::ConnectionPtr&& new_connection) { ENVOY_CONN_LOG_TO_LOGGER(parent_.logger_, debug, "new connection", *new_connection); - bool empty_filter_chain = !factory_.createFilterChain(*new_connection); + bool empty_filter_chain = !config_.filterChainFactory().createFilterChain(*new_connection); // If the connection is already closed, we can just let this connection immediately die. if (new_connection->state() != Network::Connection::State::Closed) { diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index 55c740ee05ef4..facba7148ed52 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -12,10 +12,12 @@ #include "envoy/network/filter.h" #include "envoy/network/listen_socket.h" #include "envoy/network/listener.h" +#include "envoy/server/listener_manager.h" #include "envoy/stats/timespan.h" #include "common/common/linked_object.h" #include "common/common/non_copyable.h" +#include "common/network/proxy_protocol.h" #include "spdlog/spdlog.h" @@ -47,35 +49,39 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { // Network::ConnectionHandler uint64_t numConnections() override { return num_connections_; } - void addListener(Network::FilterChainFactory& factory, Network::ListenSocket& socket, - Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options) override; - void addSslListener(Network::FilterChainFactory& factory, Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options) override; - Network::Listener* findListenerByAddress(const Network::Address::Instance& address) override; + void addListener(Listener& config) override; void removeListeners(uint64_t listener_tag) override; void stopListeners(uint64_t listener_tag) override; void stopListeners() override; + Network::Listener* findListenerByAddress(const Network::Address::Instance& address) override; + private: + struct ActiveListener; + ActiveListener* findActiveListenerByAddress(const Network::Address::Instance& address); + struct ActiveConnection; typedef std::unique_ptr ActiveConnectionPtr; + struct ActiveSocket; + typedef std::unique_ptr ActiveSocketPtr; /** * Wrapper for an active listener owned by this handler. */ struct ActiveListener : public Network::ListenerCallbacks { - ActiveListener(ConnectionHandlerImpl& parent, Network::ListenSocket& socket, - Network::FilterChainFactory& factory, Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options); + ActiveListener(ConnectionHandlerImpl& parent, Listener& config); ActiveListener(ConnectionHandlerImpl& parent, Network::ListenerPtr&& listener, - Network::FilterChainFactory& factory, Stats::Scope& scope, - uint64_t listener_tag); + Listener& config); ~ActiveListener(); + /** + * Fires when a new connection is received from the listener. + * @param socket supplies the accepted socket to take control of. + */ + void onAccept(Network::AcceptSocketPtr&& socket) override; + /** * Fires when a new connection is received from the listener. * @param new_connection supplies the connection to take control of. @@ -88,19 +94,21 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { */ void removeConnection(ActiveConnection& connection); + /** + * Create a new connection from a socket accepted by the listener. + */ + void newConnection(Network::AcceptSocketPtr&& accept_socket); + + virtual Network::Address::InstanceConstSharedPtr getOriginalDst(int fd); + ConnectionHandlerImpl& parent_; - Network::FilterChainFactory& factory_; Network::ListenerPtr listener_; ListenerStats stats_; + std::list sockets_; std::list connections_; const uint64_t listener_tag_; - }; - - struct SslActiveListener : public ActiveListener { - SslActiveListener(ConnectionHandlerImpl& parent, Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Network::FilterChainFactory& factory, - Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options); + Network::ProxyProtocol proxy_protocol_; + Listener& config_; }; typedef std::unique_ptr ActiveListenerPtr; @@ -130,6 +138,18 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { Stats::TimespanPtr conn_length_; }; + /** + * Wrapper for an active accept socket owned by this handler. + */ + struct ActiveSocket : LinkedObject, public Event::DeferredDeletable { + ActiveSocket(ActiveListener& listener, Network::AcceptSocketPtr&& socket) + : listener_(&listener), socket_(std::move(socket)) {} + ~ActiveSocket() {} + + ActiveListener* listener_; + Network::AcceptSocketPtr socket_; + }; + static ListenerStats generateStats(Stats::Scope& scope); spdlog::logger& logger_; diff --git a/source/server/http/BUILD b/source/server/http/BUILD index f6a188b1794ec..4d29d6612b6b1 100644 --- a/source/server/http/BUILD +++ b/source/server/http/BUILD @@ -19,6 +19,7 @@ envoy_cc_library( "//include/envoy/server:admin_interface", "//include/envoy/server:hot_restart_interface", "//include/envoy/server:instance_interface", + "//include/envoy/server:listener_manager_interface", "//include/envoy/server:options_interface", "//include/envoy/stats:stats_interface", "//include/envoy/upstream:cluster_manager_interface", diff --git a/source/server/http/admin.cc b/source/server/http/admin.cc index 7d3680bd3f6f4..e3ad18401f3d6 100644 --- a/source/server/http/admin.cc +++ b/source/server/http/admin.cc @@ -536,7 +536,7 @@ AdminImpl::NullRouteConfigProvider::NullRouteConfigProvider() AdminImpl::AdminImpl(const std::string& access_log_path, const std::string& profile_path, const std::string& address_out_path, Network::Address::InstanceConstSharedPtr address, Server::Instance& server, - Stats::Scope& listener_scope) + Stats::ScopePtr&& listener_scope) : server_(server), profile_path_(profile_path), socket_(new Network::TcpListenSocket(address, true)), stats_(Http::ConnectionManagerImpl::generateStats("http.admin.", server_.stats())), @@ -568,8 +568,7 @@ AdminImpl::AdminImpl(const std::string& access_log_path, const std::string& prof {"/stats", "print server stats", MAKE_ADMIN_HANDLER(handlerStats), false, false}, {"/listeners", "print listener addresses", MAKE_ADMIN_HANDLER(handlerListenerInfo), false, false}}, - listener_stats_( - Http::ConnectionManagerImpl::generateListenerStats("http.admin.", listener_scope)) { + listener_(*this, std::move(listener_scope)) { if (!address_out_path.empty()) { std::ofstream address_out_file(address_out_path); diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 07c7e6956fd87..4ce562e9743ec 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -8,6 +8,7 @@ #include "envoy/network/listen_socket.h" #include "envoy/server/admin.h" #include "envoy/server/instance.h" +#include "envoy/server/listener_manager.h" #include "envoy/upstream/outlier_detection.h" #include "envoy/upstream/resource_manager.h" @@ -33,12 +34,13 @@ class AdminImpl : public Admin, public: AdminImpl(const std::string& access_log_path, const std::string& profiler_path, const std::string& address_out_path, Network::Address::InstanceConstSharedPtr address, - Server::Instance& server, Stats::Scope& listener_scope); + Server::Instance& server, Stats::ScopePtr&& listener_scope); Http::Code runCallback(const std::string& path_and_query, Http::HeaderMap& response_headers, Buffer::Instance& response); const Network::ListenSocket& socket() override { return *socket_; } Network::ListenSocket& mutable_socket() { return *socket_; } + Server::Listener& listener() { return listener_; } // Server::Admin bool addHandler(const std::string& prefix, const std::string& help_text, HandlerCb callback, @@ -77,7 +79,7 @@ class AdminImpl : public Admin, const Network::Address::Instance& localAddress() override; const Optional& userAgent() override { return user_agent_; } const Http::TracingConnectionManagerConfig* tracingConfig() override { return nullptr; } - Http::ConnectionManagerListenerStats& listenerStats() override { return listener_stats_; } + Http::ConnectionManagerListenerStats& listenerStats() override { return listener_.stats_; } private: /** @@ -153,6 +155,30 @@ class AdminImpl : public Admin, Http::Code handlerStats(const std::string& path_and_query, Http::HeaderMap& response_headers, Buffer::Instance& response); + class AdminListener : public Server::Listener { + public: + AdminListener(AdminImpl& parent, Stats::ScopePtr&& listener_scope) : parent_(parent), + name_("admin"), scope_(std::move(listener_scope)), + stats_(Http::ConnectionManagerImpl::generateListenerStats("http.admin.", *scope_)) {} + + // Server::Listener + Network::FilterChainFactory& filterChainFactory() override { return parent_; } + Network::ListenSocket& socket() override { return parent_.mutable_socket(); } + Ssl::ServerContext* defaultSslContext() override { return nullptr; } + bool useProxyProto() override { return false; } + bool bindToPort() override { return true; } + bool useOriginalDst() override { return false; } + uint32_t perConnectionBufferLimitBytes() override { return 0; } + Stats::Scope& listenerScope() override { return *scope_; } + uint64_t listenerTag() const override { return 0; } + const std::string& name() const override { return name_; } + + AdminImpl& parent_; + std::string name_; + Stats::ScopePtr scope_; + Http::ConnectionManagerListenerStats stats_; + }; + Server::Instance& server_; std::list access_logs_; const std::string profile_path_; @@ -165,7 +191,7 @@ class AdminImpl : public Admin, Optional user_agent_; Http::SlowDateProviderImpl date_provider_; std::vector set_current_client_cert_details_; - Http::ConnectionManagerListenerStats listener_stats_; + AdminListener listener_; }; /** diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index 971c4b0f17957..4699c71a56f62 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -207,7 +207,7 @@ class ListenerImpl : public Listener, bool useOriginalDst() override { return use_original_dst_; } uint32_t perConnectionBufferLimitBytes() override { return per_connection_buffer_limit_bytes_; } Stats::Scope& listenerScope() override { return *listener_scope_; } - uint64_t listenerTag() override { return listener_tag_; } + uint64_t listenerTag() const override { return listener_tag_; } const std::string& name() const override { return name_; } // Server::Configuration::FactoryContext diff --git a/source/server/server.cc b/source/server/server.cc index c4d2f6122f30b..3246768410aa5 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -217,13 +217,11 @@ void InstanceImpl::initialize(Options& options, info.original_start_time_ = original_start_time_; restarter_.shutdownParentAdmin(info); original_start_time_ = info.original_start_time_; - admin_scope_ = stats_store_.createScope("listener.admin."); admin_.reset(new AdminImpl(initial_config.admin().accessLogPath(), initial_config.admin().profilePath(), options.adminAddressPath(), - initial_config.admin().address(), *this, *admin_scope_)); - - handler_->addListener(*admin_, admin_->mutable_socket(), *admin_scope_, 0, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + initial_config.admin().address(), *this, + stats_store_.createScope("listener.admin."))); + handler_->addListener(admin_->listener()); loadServerFlags(initial_config.flagsPath()); diff --git a/source/server/server.h b/source/server/server.h index 4e6e4be2d00ce..dad0e4ce8bf4d 100644 --- a/source/server/server.h +++ b/source/server/server.h @@ -192,7 +192,6 @@ class InstanceImpl : Logger::Loggable, public Instance { ProdWorkerFactory worker_factory_; std::unique_ptr listener_manager_; std::unique_ptr config_; - Stats::ScopePtr admin_scope_; Network::DnsResolverSharedPtr dns_resolver_; Event::TimerPtr stat_flush_timer_; LocalInfo::LocalInfoPtr local_info_; diff --git a/source/server/worker_impl.cc b/source/server/worker_impl.cc index 660d3cd0c3e11..1ef7cbd830322 100644 --- a/source/server/worker_impl.cc +++ b/source/server/worker_impl.cc @@ -34,7 +34,8 @@ void WorkerImpl::addListener(Listener& listener, AddListenerCompletion completio // to surface this. dispatcher_->post([this, &listener, completion]() -> void { try { - addListenerWorker(listener); + handler_->addListener(listener); + hooks_.onWorkerListenerAdded(); completion(true); } catch (const Network::CreateListenerException& e) { completion(false); @@ -42,24 +43,6 @@ void WorkerImpl::addListener(Listener& listener, AddListenerCompletion completio }); } -void WorkerImpl::addListenerWorker(Listener& listener) { - const Network::ListenerOptions listener_options = {.bind_to_port_ = listener.bindToPort(), - .use_proxy_proto_ = listener.useProxyProto(), - .use_original_dst_ = listener.useOriginalDst(), - .per_connection_buffer_limit_bytes_ = - listener.perConnectionBufferLimitBytes()}; - if (listener.defaultSslContext()) { - handler_->addSslListener(listener.filterChainFactory(), *listener.defaultSslContext(), - listener.socket(), listener.listenerScope(), listener.listenerTag(), - listener_options); - } else { - handler_->addListener(listener.filterChainFactory(), listener.socket(), - listener.listenerScope(), listener.listenerTag(), listener_options); - } - - hooks_.onWorkerListenerAdded(); -} - uint64_t WorkerImpl::numConnections() { uint64_t ret = 0; if (handler_) { diff --git a/source/server/worker_impl.h b/source/server/worker_impl.h index badb1e3faed82..553eb82550ba6 100644 --- a/source/server/worker_impl.h +++ b/source/server/worker_impl.h @@ -50,7 +50,6 @@ class WorkerImpl : public Worker, Logger::Loggable { void stopListeners() override; private: - void addListenerWorker(Listener& listener); void threadRoutine(GuardDog& guard_dog); ThreadLocal::Instance& tls_; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index a774420349ad9..f26849651261e 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -179,9 +179,7 @@ class CodecNetworkTest : public testing::TestWithParamcreateListener(connection_handler_, socket_, listener_callbacks_, stats_store_, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + upstream_listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket()); client_connection_ = client_connection.get(); @@ -190,6 +188,13 @@ class CodecNetworkTest : public testing::TestWithParam void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), nullptr); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); + int expected_callbacks = 2; EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) diff --git a/test/common/network/BUILD b/test/common/network/BUILD index ca42e6c7149ab..4791c032ce660 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -133,6 +133,7 @@ envoy_cc_test( "//source/common/network:listener_lib", "//source/common/network:utility_lib", "//source/common/stats:stats_lib", + "//source/server:connection_handler_lib", "//test/mocks/buffer:buffer_mocks", "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index f168e32bb0129..64fc96fa895ef 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -83,9 +83,7 @@ class ConnectionImplTest : public testing::TestWithParam { if (dispatcher_.get() == nullptr) { dispatcher_.reset(new Event::DispatcherImpl); } - listener_ = - dispatcher_->createListener(connection_handler_, socket_, listener_callbacks_, stats_store_, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); client_connection_ = dispatcher_->createClientConnection( socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket()); @@ -100,6 +98,12 @@ class ConnectionImplTest : public testing::TestWithParam { int expected_callbacks = 2; client_connection_->connect(); read_filter_.reset(new NiceMock()); + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), nullptr); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); @@ -188,6 +192,13 @@ TEST_P(ConnectionImplTest, CloseDuringConnectCallback) { EXPECT_CALL(client_callbacks_, onEvent(ConnectionEvent::LocalClose)); read_filter_.reset(new NiceMock()); + + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), nullptr); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); @@ -236,6 +247,12 @@ TEST_P(ConnectionImplTest, ConnectionStats) { read_filter_.reset(new NiceMock()); MockConnectionStats server_connection_stats; + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), nullptr); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); @@ -561,9 +578,7 @@ TEST_P(ConnectionImplTest, BindFailureTest) { new Network::Address::Ipv6Instance(address_string, 0)}; } dispatcher_.reset(new Event::DispatcherImpl); - listener_ = - dispatcher_->createListener(connection_handler_, socket_, listener_callbacks_, stats_store_, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); client_connection_ = dispatcher_->createClientConnection(socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket()); @@ -740,12 +755,7 @@ class ReadBufferLimitTest : public ConnectionImplTest { void readBufferLimitTest(uint32_t read_buffer_limit, uint32_t expected_chunk_size) { const uint32_t buffer_size = 256 * 1024; dispatcher_.reset(new Event::DispatcherImpl); - listener_ = - dispatcher_->createListener(connection_handler_, socket_, listener_callbacks_, stats_store_, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = read_buffer_limit}); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); client_connection_ = dispatcher_->createClientConnection( socket_.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -754,6 +764,13 @@ class ReadBufferLimitTest : public ConnectionImplTest { client_connection_->connect(); read_filter_.reset(new NiceMock()); + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), nullptr); + new_connection->setBufferLimits(read_buffer_limit); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 8f775eef0fe77..57b1e14db40e9 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -198,6 +198,14 @@ class TestDnsServerQuery { class TestDnsServer : public ListenerCallbacks { public: + TestDnsServer(Event::DispatcherImpl& dispatcher) : dispatcher_(dispatcher) {} + + void onAccept(AcceptSocketPtr&& socket) override { + Network::ConnectionPtr new_connection = + dispatcher_.createConnection(std::move(socket), nullptr); + onNewConnection(std::move(new_connection)); + } + void onNewConnection(ConnectionPtr&& new_connection) override { TestDnsServerQuery* query = new TestDnsServerQuery(std::move(new_connection), hosts_A_, hosts_AAAA_); @@ -213,6 +221,8 @@ class TestDnsServer : public ListenerCallbacks { } private: + Event::DispatcherImpl& dispatcher_; + HostMap hosts_A_; HostMap hosts_AAAA_; // All queries are tracked so we can do resource reclamation when the test is @@ -276,14 +286,10 @@ class DnsImplTest : public testing::TestWithParam { resolver_ = dispatcher_.createDnsResolver({}); // Instantiate TestDnsServer and listen on a random port on the loopback address. - server_.reset(new TestDnsServer()); + server_.reset(new TestDnsServer(dispatcher_)); socket_.reset( new Network::TcpListenSocket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true)); - listener_ = dispatcher_.createListener(connection_handler_, *socket_, *server_, stats_store_, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0}); + listener_ = dispatcher_.createListener(*socket_, *server_, true); // Point c-ares at the listener with no search domains and TCP-only. peer_.reset(new DnsResolverImplPeer(dynamic_cast(resolver_.get()))); diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index ad3f3a65873ac..b06ad3328bd36 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -11,8 +11,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -using testing::ByRef; -using testing::Eq; using testing::Invoke; using testing::Return; using testing::_; @@ -29,18 +27,19 @@ static void errorCallbackTest(Address::IpVersion version) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), true); Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = - dispatcher.createListener(connection_handler, socket, listener_callbacks, stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0}); + Network::ListenerPtr listener = dispatcher.createListener(socket, listener_callbacks, true); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket()); client_connection->connect(); + EXPECT_CALL(listener_callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), nullptr); + listener_callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { client_connection->close(ConnectionCloseType::NoFlush); @@ -61,25 +60,11 @@ TEST_P(ListenerImplDeathTest, ErrorCallback) { class TestListenerImpl : public ListenerImpl { public: - TestListenerImpl(Network::ConnectionHandler& conn_handler, Event::DispatcherImpl& dispatcher, - ListenSocket& socket, ListenerCallbacks& cb, Stats::Store& stats_store, - const Network::ListenerOptions& listener_options) - : ListenerImpl(conn_handler, dispatcher, socket, cb, stats_store, listener_options) { - ON_CALL(*this, newConnection(_, _, _, _)) - .WillByDefault(Invoke( - [this](int fd, Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, bool using_original_dst) -> void { - ListenerImpl::newConnection(fd, remote_address, local_address, using_original_dst); - } - - )); - } + TestListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, + bool bind_to_port) + : ListenerImpl(dispatcher, socket, cb, bind_to_port) {} MOCK_METHOD1(getLocalAddress, Address::InstanceConstSharedPtr(int fd)); - MOCK_METHOD1(getOriginalDst, Address::InstanceConstSharedPtr(int fd)); - MOCK_METHOD4(newConnection, - void(int fd, Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, bool using_original_dst)); }; class ListenerImplTest : public testing::TestWithParam { @@ -95,167 +80,6 @@ class ListenerImplTest : public testing::TestWithParam { INSTANTIATE_TEST_CASE_P(IpVersions, ListenerImplTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest())); -TEST_P(ListenerImplTest, NormalRedirect) { - Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; - Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version_), true); - Network::TcpListenSocket socketDst(alt_address_, false); - Network::MockListenerCallbacks listener_callbacks1; - Network::MockConnectionHandler connection_handler; - // The traffic should redirect from binding listener to the virtual listener. - Network::TestListenerImpl listener(connection_handler, dispatcher, socket, listener_callbacks1, - stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = true, - .per_connection_buffer_limit_bytes_ = 0}); - Network::MockListenerCallbacks listener_callbacks2; - Network::TestListenerImpl listenerDst(connection_handler, dispatcher, socketDst, - listener_callbacks2, stats_store, - Network::ListenerOptions()); - - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( - socket.localAddress(), Network::Address::InstanceConstSharedPtr(), - Network::Test::createRawBufferSocket()); - client_connection->connect(); - - EXPECT_CALL(listener, getLocalAddress(_)).Times(0); - EXPECT_CALL(listener, getOriginalDst(_)).WillOnce(Return(alt_address_)); - EXPECT_CALL(connection_handler, findListenerByAddress(Eq(ByRef(*alt_address_)))) - .WillOnce(Return(&listenerDst)); - - EXPECT_CALL(listener, newConnection(_, _, _, _)).Times(0); - EXPECT_CALL(listenerDst, newConnection(_, _, _, _)); - EXPECT_CALL(listener_callbacks2, onNewConnection_(_)) - .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { - EXPECT_EQ(*alt_address_, *conn->localAddress()); - client_connection->close(ConnectionCloseType::NoFlush); - conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); - })); - - dispatcher.run(Event::Dispatcher::RunType::Block); -} - -TEST_P(ListenerImplTest, FallbackToWildcardListener) { - Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; - Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version_), true); - Network::TcpListenSocket socketDst(Network::Test::getAnyAddress(version_), false); - Network::MockListenerCallbacks listener_callbacks1; - Network::MockConnectionHandler connection_handler; - // The virtual listener of exact address does not exist, fall back to wild card virtual listener. - Network::TestListenerImpl listener(connection_handler, dispatcher, socket, listener_callbacks1, - stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = true, - .per_connection_buffer_limit_bytes_ = 0}); - Network::MockListenerCallbacks listener_callbacks2; - Network::TestListenerImpl listenerDst(connection_handler, dispatcher, socketDst, - listener_callbacks2, stats_store, - Network::ListenerOptions()); - - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( - socket.localAddress(), Network::Address::InstanceConstSharedPtr(), - Network::Test::createRawBufferSocket()); - client_connection->connect(); - - EXPECT_CALL(listener, getLocalAddress(_)).Times(0); - EXPECT_CALL(listener, getOriginalDst(_)).WillOnce(Return(alt_address_)); - EXPECT_CALL(connection_handler, findListenerByAddress(Eq(ByRef(*alt_address_)))) - .WillOnce(Return(&listenerDst)); - - EXPECT_CALL(listener, newConnection(_, _, _, _)).Times(0); - EXPECT_CALL(listenerDst, newConnection(_, _, _, _)); - EXPECT_CALL(listener_callbacks2, onNewConnection_(_)) - .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { - EXPECT_EQ(*alt_address_, *conn->localAddress()); - EXPECT_FALSE(*socketDst.localAddress() == *conn->localAddress()); - client_connection->close(ConnectionCloseType::NoFlush); - conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); - })); - - dispatcher.run(Event::Dispatcher::RunType::Block); -} - -TEST_P(ListenerImplTest, WildcardListenerWithOriginalDst) { - Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; - Network::TcpListenSocket socket(Network::Test::getAnyAddress(version_), true); - Network::MockListenerCallbacks listener_callbacks; - Network::MockConnectionHandler connection_handler; - // The virtual listener of exact address does not exist, fall back to the wild card listener. - Network::TestListenerImpl listener(connection_handler, dispatcher, socket, listener_callbacks, - stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = true, - .per_connection_buffer_limit_bytes_ = 0}); - - auto local_dst_address = Network::Utility::getAddressWithPort( - *Network::Test::getCanonicalLoopbackAddress(version_), socket.localAddress()->ip()->port()); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( - local_dst_address, Network::Address::InstanceConstSharedPtr(), - Network::Test::createRawBufferSocket()); - client_connection->connect(); - - EXPECT_CALL(listener, getLocalAddress(_)).WillOnce(Return(local_dst_address)); - EXPECT_CALL(listener, getOriginalDst(_)).WillOnce(Return(alt_address_)); - EXPECT_CALL(connection_handler, findListenerByAddress(Eq(ByRef(*alt_address_)))) - .WillOnce(Return(&listener)); - - EXPECT_CALL(listener, newConnection(_, _, _, _)); - EXPECT_CALL(listener_callbacks, onNewConnection_(_)) - .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { - EXPECT_EQ(*conn->localAddress(), *alt_address_); - client_connection->close(ConnectionCloseType::NoFlush); - conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); - })); - - dispatcher.run(Event::Dispatcher::RunType::Block); -} - -TEST_P(ListenerImplTest, WildcardListenerNoOriginalDst) { - Stats::IsolatedStoreImpl stats_store; - Event::DispatcherImpl dispatcher; - Network::TcpListenSocket socket(Network::Test::getAnyAddress(version_), true); - Network::MockListenerCallbacks listener_callbacks; - Network::MockConnectionHandler connection_handler; - // The virtual listener of exact address does not exist, fall back to the wild card listener. - Network::TestListenerImpl listener(connection_handler, dispatcher, socket, listener_callbacks, - stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = true, - .per_connection_buffer_limit_bytes_ = 0}); - - auto local_dst_address = Network::Utility::getAddressWithPort( - *Network::Test::getCanonicalLoopbackAddress(version_), socket.localAddress()->ip()->port()); - Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( - local_dst_address, Network::Address::InstanceConstSharedPtr(), - Network::Test::createRawBufferSocket()); - client_connection->connect(); - - EXPECT_CALL(listener, getLocalAddress(_)).WillOnce(Return(local_dst_address)); - // getOriginalDst() returns the same address as the connections destination. - EXPECT_CALL(listener, getOriginalDst(_)).WillOnce(Return(local_dst_address)); - EXPECT_CALL(connection_handler, findListenerByAddress(_)).Times(0); - - EXPECT_CALL(listener, newConnection(_, _, _, _)); - EXPECT_CALL(listener_callbacks, onNewConnection_(_)) - .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { - EXPECT_EQ(*conn->localAddress(), *local_dst_address); - client_connection->close(ConnectionCloseType::NoFlush); - conn->close(ConnectionCloseType::NoFlush); - dispatcher.exit(); - })); - - dispatcher.run(Event::Dispatcher::RunType::Block); -} - TEST_P(ListenerImplTest, UseActualDst) { Stats::IsolatedStoreImpl stats_store; Event::DispatcherImpl dispatcher; @@ -264,16 +88,9 @@ TEST_P(ListenerImplTest, UseActualDst) { Network::MockListenerCallbacks listener_callbacks1; Network::MockConnectionHandler connection_handler; // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(connection_handler, dispatcher, socket, listener_callbacks1, - stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0}); + Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks1, true); Network::MockListenerCallbacks listener_callbacks2; - Network::TestListenerImpl listenerDst(connection_handler, dispatcher, socketDst, - listener_callbacks2, stats_store, - Network::ListenerOptions()); + Network::TestListenerImpl listenerDst(dispatcher, socketDst, listener_callbacks2, false); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -281,11 +98,14 @@ TEST_P(ListenerImplTest, UseActualDst) { client_connection->connect(); EXPECT_CALL(listener, getLocalAddress(_)).Times(0); - EXPECT_CALL(listener, getOriginalDst(_)).Times(0); - EXPECT_CALL(connection_handler, findListenerByAddress(_)).Times(0); - EXPECT_CALL(listener, newConnection(_, _, _, _)).Times(1); - EXPECT_CALL(listenerDst, newConnection(_, _, _, _)).Times(0); + EXPECT_CALL(listener_callbacks2, onAccept_(_)).Times(0); + EXPECT_CALL(listener_callbacks1, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), nullptr); + listener_callbacks1.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks1, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { EXPECT_EQ(*conn->localAddress(), *socket.localAddress()); @@ -304,12 +124,7 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(connection_handler, dispatcher, socket, listener_callbacks, - stats_store, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0}); + Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks, true); auto local_dst_address = Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(version_), socket.localAddress()->ip()->port()); @@ -319,10 +134,13 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { client_connection->connect(); EXPECT_CALL(listener, getLocalAddress(_)).WillOnce(Return(local_dst_address)); - EXPECT_CALL(listener, getOriginalDst(_)).Times(0); - EXPECT_CALL(connection_handler, findListenerByAddress(_)).Times(0); - EXPECT_CALL(listener, newConnection(_, _, _, _)).Times(1); + EXPECT_CALL(listener_callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), nullptr); + listener_callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { EXPECT_EQ(*conn->localAddress(), *local_dst_address); diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index 9d3574119ddfd..035d81060908d 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -9,6 +9,8 @@ #include "common/network/utility.h" #include "common/stats/stats_impl.h" +#include "server/connection_handler_impl.h" + #include "test/mocks/buffer/mocks.h" #include "test/mocks/network/mocks.h" #include "test/mocks/server/mocks.h" @@ -26,33 +28,47 @@ using testing::_; namespace Envoy { namespace Network { -class ProxyProtocolTest : public testing::TestWithParam { +// Build again on the basis of the connection_handler_test.cc + +class ProxyProtocolTest : public testing::TestWithParam, + public Server::Listener, + protected Logger::Loggable { public: ProxyProtocolTest() : socket_(Network::Test::getCanonicalLoopbackAddress(GetParam()), true), - listener_(dispatcher_.createListener(connection_handler_, socket_, callbacks_, stats_store_, - {.bind_to_port_ = true, - .use_proxy_proto_ = true, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0})) { + connection_handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)), + name_("proxy") { + connection_handler_->addListener(*this); conn_ = dispatcher_.createClientConnection(socket_.localAddress(), Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket()); conn_->addConnectionCallbacks(connection_callbacks_); } + // Listener + Network::FilterChainFactory& filterChainFactory() override { return factory_; } + Network::ListenSocket& socket() override { return socket_; } + Ssl::ServerContext* defaultSslContext() override { return nullptr; } + bool useProxyProto() override { return true; } + bool bindToPort() override { return true; } + bool useOriginalDst() override { return false; } + uint32_t perConnectionBufferLimitBytes() override { return 0; } + Stats::Scope& listenerScope() override { return stats_store_; } + uint64_t listenerTag() const override { return 1; } + const std::string& name() const override { return name_; } + void connect() { conn_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(callbacks_, onNewConnection_(_)) - .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { - server_connection_ = std::move(conn); - server_connection_->addConnectionCallbacks(server_callbacks_); - server_connection_->addReadFilter(read_filter_); + EXPECT_CALL(factory_, createFilterChain(_)) + .WillOnce(Invoke([&](Connection& connection) -> bool { + server_connection_ = &connection; + connection.addConnectionCallbacks(server_callbacks_); + connection.addReadFilter(read_filter_); + return true; })); EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); - dispatcher_.run(Event::Dispatcher::RunType::Block); } @@ -90,14 +106,14 @@ class ProxyProtocolTest : public testing::TestWithParam { Event::DispatcherImpl dispatcher_; TcpListenSocket socket_; Stats::IsolatedStoreImpl stats_store_; - MockListenerCallbacks callbacks_; - Network::MockConnectionHandler connection_handler_; - Network::ListenerPtr listener_; + Network::ConnectionHandlerPtr connection_handler_; + Network::MockFilterChainFactory factory_; ClientConnectionPtr conn_; NiceMock connection_callbacks_; - Network::ConnectionPtr server_connection_; + Network::Connection* server_connection_; Network::MockConnectionCallbacks server_callbacks_; std::shared_ptr read_filter_; + std::string name_; }; // Parameterize the listener socket address version. @@ -152,9 +168,9 @@ TEST_P(ProxyProtocolTest, Fragmented) { dispatcher_.run(Event::Dispatcher::RunType::NonBlock); - disconnect(); - EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "254.254.254.254"); + + disconnect(); } TEST_P(ProxyProtocolTest, PartialRead) { @@ -171,9 +187,9 @@ TEST_P(ProxyProtocolTest, PartialRead) { dispatcher_.run(Event::Dispatcher::RunType::NonBlock); - disconnect(); - EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "254.254.254.254"); + + disconnect(); } TEST_P(ProxyProtocolTest, MalformedProxyLine) { @@ -283,32 +299,45 @@ TEST_P(ProxyProtocolTest, ClosedEmpty) { dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } -class WildcardProxyProtocolTest : public testing::TestWithParam { +class WildcardProxyProtocolTest : public testing::TestWithParam, + public Server::Listener, + protected Logger::Loggable { public: WildcardProxyProtocolTest() : socket_(Network::Test::getAnyAddress(GetParam()), true), local_dst_address_(Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(GetParam()), socket_.localAddress()->ip()->port())), - listener_(dispatcher_.createListener(connection_handler_, socket_, callbacks_, stats_store_, - {.bind_to_port_ = true, - .use_proxy_proto_ = true, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = 0})) { + connection_handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)), + name_("proxy") { + connection_handler_->addListener(*this); conn_ = dispatcher_.createClientConnection(local_dst_address_, Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket()); conn_->addConnectionCallbacks(connection_callbacks_); } + // Server::Listener + Network::FilterChainFactory& filterChainFactory() override { return factory_; } + Network::ListenSocket& socket() override { return socket_; } + Ssl::ServerContext* defaultSslContext() override { return nullptr; } + bool useProxyProto() override { return true; } + bool bindToPort() override { return true; } + bool useOriginalDst() override { return false; } + uint32_t perConnectionBufferLimitBytes() override { return 0; } + Stats::Scope& listenerScope() override { return stats_store_; } + uint64_t listenerTag() const override { return 1; } + const std::string& name() const override { return name_; } + void connect() { conn_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(callbacks_, onNewConnection_(_)) - .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { - server_connection_ = std::move(conn); - server_connection_->addConnectionCallbacks(server_callbacks_); - server_connection_->addReadFilter(read_filter_); + EXPECT_CALL(factory_, createFilterChain(_)) + .WillOnce(Invoke([&](Connection& connection) -> bool { + server_connection_ = &connection; + connection.addConnectionCallbacks(server_callbacks_); + connection.addReadFilter(read_filter_); + return true; })); EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); @@ -333,14 +362,14 @@ class WildcardProxyProtocolTest : public testing::TestWithParam connection_callbacks_; - Network::ConnectionPtr server_connection_; + Network::Connection* server_connection_; Network::MockConnectionCallbacks server_callbacks_; std::shared_ptr read_filter_; + std::string name_; }; // Parameterize the listener socket address version. diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index a2a69f9daabb7..b7137b00b0dd8 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -57,9 +57,7 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = - dispatcher.createSslListener(connection_handler, *server_ctx, socket, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); Json::ObjectSharedPtr client_ctx_loader = TestEnvironment::jsonLoadFromString(client_ctx_json); ClientContextConfigImpl client_ctx_config(*client_ctx_loader); @@ -71,6 +69,12 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), server_ctx.get()); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); @@ -143,9 +147,7 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createSslListener( - connection_handler, *server_contexts[0], socket, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); ClientContextConfigImpl client_ctx_config(client_ctx_proto); ClientSslSocketFactory ssl_socket_factory(client_ctx_config, manager, stats_store); @@ -169,6 +171,12 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), server_contexts[0].get()); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); @@ -517,9 +525,7 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = - dispatcher.createSslListener(connection_handler, *server_ctx, socket, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -530,6 +536,12 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), server_ctx.get()); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); @@ -569,9 +581,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = - dispatcher.createSslListener(connection_handler, *server_ctx, socket, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); std::string client_ctx_json = R"EOF( { @@ -602,6 +612,12 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), server_ctx.get()); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); @@ -646,12 +662,8 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, Network::TcpListenSocket socket2(Network::Test::getCanonicalLoopbackAddress(ip_version), true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener1 = dispatcher.createSslListener( - connection_handler, *server_ctx1, socket1, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); - Network::ListenerPtr listener2 = dispatcher.createSslListener( - connection_handler, *server_ctx2, socket2, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true); + Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true); Json::ObjectSharedPtr client_ctx_loader = TestEnvironment::jsonLoadFromString(client_ctx_json); ClientContextConfigImpl client_ctx_config(*client_ctx_loader); @@ -666,6 +678,13 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, SSL_SESSION* ssl_session = nullptr; Network::ConnectionPtr server_connection; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillRepeatedly(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + ServerContext* ctx = socket->localAddress() == socket1.localAddress() ? server_ctx1.get() + : server_ctx2.get(); + Network::ConnectionPtr new_connection = dispatcher.createConnection(std::move(socket), ctx); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke( [&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); })); @@ -931,12 +950,8 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { Network::TcpListenSocket socket2(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = - dispatcher.createSslListener(connection_handler, *server_ctx, socket, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); - Network::ListenerPtr listener2 = dispatcher.createSslListener( - connection_handler, *server2_ctx, socket2, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); + Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true); std::string client_ctx_json = R"EOF( { @@ -959,6 +974,15 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { SSL_SESSION* ssl_session = nullptr; Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillRepeatedly(Invoke([&](Network::AcceptSocketPtr& accept_socket) -> void { + ServerContext* ctx = accept_socket->localAddress() == socket.localAddress() + ? server_ctx.get() + : server2_ctx.get(); + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(accept_socket), ctx); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); @@ -1031,9 +1055,7 @@ TEST_P(SslSocketTest, SslError) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = - dispatcher.createSslListener(connection_handler, *server_ctx, socket, callbacks, stats_store, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -1044,6 +1066,12 @@ TEST_P(SslSocketTest, SslError) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; + EXPECT_CALL(callbacks, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher.createConnection(std::move(socket), server_ctx.get()); + callbacks.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(callbacks, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection = std::move(conn); @@ -1624,18 +1652,13 @@ TEST_P(SslSocketTest, SniProtocolVersions) { class SslReadBufferLimitTest : public SslCertsTest, public testing::WithParamInterface { public: - void initialize(uint32_t read_buffer_limit) { + void initialize() { server_ctx_loader_ = TestEnvironment::jsonLoadFromString(server_ctx_json_); server_ctx_config_.reset(new ServerContextConfigImpl(*server_ctx_loader_)); manager_.reset(new ContextManagerImpl(runtime_)); server_ctx_ = manager_->createSslServerContext("", {}, stats_store_, *server_ctx_config_, true); - listener_ = dispatcher_->createSslListener( - connection_handler_, *server_ctx_, socket_, listener_callbacks_, stats_store_, - {.bind_to_port_ = true, - .use_proxy_proto_ = false, - .use_original_dst_ = false, - .per_connection_buffer_limit_bytes_ = read_buffer_limit}); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); client_ctx_loader_ = TestEnvironment::jsonLoadFromString(client_ctx_json_); client_ctx_config_.reset(new ClientContextConfigImpl(*client_ctx_loader_)); @@ -1652,8 +1675,15 @@ class SslReadBufferLimitTest : public SslCertsTest, void readBufferLimitTest(uint32_t read_buffer_limit, uint32_t expected_chunk_size, uint32_t write_size, uint32_t num_writes, bool reserve_write_space) { - initialize(read_buffer_limit); - + initialize(); + + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), server_ctx_.get()); + new_connection->setBufferLimits(read_buffer_limit); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); @@ -1725,11 +1755,18 @@ class SslReadBufferLimitTest : public SslCertsTest, return new Buffer::WatermarkBuffer(below_low, above_high); })); - initialize(read_buffer_limit); + initialize(); EXPECT_CALL(client_callbacks_, onEvent(Network::ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), server_ctx_.get()); + new_connection->setBufferLimits(read_buffer_limit); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); @@ -1838,8 +1875,15 @@ TEST_P(SslReadBufferLimitTest, TestBind) { new Network::Address::Ipv6Instance(address_string, 0)}; } - initialize(0); + initialize(); + EXPECT_CALL(listener_callbacks_, onAccept_(_)) + .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + Network::ConnectionPtr new_connection = + dispatcher_->createConnection(std::move(socket), server_ctx_.get()); + new_connection->setBufferLimits(0); + listener_callbacks_.onNewConnection(std::move(new_connection)); + })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) .WillOnce(Invoke([&](Network::ConnectionPtr& conn) -> void { server_connection_ = std::move(conn); diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 28f428aba0aea..9cffadb41db8e 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -263,7 +263,7 @@ FakeUpstream::FakeUpstream(Ssl::ServerContext* ssl_ctx, Network::ListenSocketPtr api_(new Api::Impl(std::chrono::milliseconds(10000))), dispatcher_(api_->allocateDispatcher()), handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), - allow_unexpected_disconnects_(false) { + allow_unexpected_disconnects_(false), listener_(*this) { thread_.reset(new Thread::Thread([this]() -> void { threadRoutine(); })); server_initialized_.waitReady(); } @@ -288,13 +288,7 @@ bool FakeUpstream::createFilterChain(Network::Connection& connection) { } void FakeUpstream::threadRoutine() { - if (ssl_ctx_) { - handler_->addSslListener(*this, *ssl_ctx_, *socket_, stats_store_, 0, - Network::ListenerOptions::listenerOptionsWithBindToPort()); - } else { - handler_->addListener(*this, *socket_, stats_store_, 0, - Network::ListenerOptions::listenerOptionsWithBindToPort()); - } + handler_->addListener(listener_); server_initialized_.setReady(); dispatcher_->run(Event::Dispatcher::RunType::Block); diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index 71e81243b6520..ed74e65a78a20 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -14,6 +14,7 @@ #include "envoy/network/connection_handler.h" #include "envoy/network/filter.h" #include "envoy/server/configuration.h" +#include "envoy/server/listener_manager.h" #include "common/buffer/buffer_impl.h" #include "common/buffer/zero_copy_input_stream_impl.h" @@ -303,6 +304,28 @@ class FakeUpstream : Logger::Loggable, public Network::Filt private: FakeUpstream(Ssl::ServerContext* ssl_ctx, Network::ListenSocketPtr&& connection, FakeHttpConnection::Type type); + + class FakeListener : public Server::Listener { + public: + FakeListener(FakeUpstream& parent) : parent_(parent), name_("fake_upstream") {} + + private: + // Server::Listener + Network::FilterChainFactory& filterChainFactory() override { return parent_; } + Network::ListenSocket& socket() override { return *parent_.socket_; } + Ssl::ServerContext* defaultSslContext() override { return parent_.ssl_ctx_; } + bool useProxyProto() override { return false; } + bool bindToPort() override { return true; } + bool useOriginalDst() override { return false; } + uint32_t perConnectionBufferLimitBytes() override { return 0; } + Stats::Scope& listenerScope() override { return parent_.stats_store_; } + uint64_t listenerTag() const override { return 0; } + const std::string& name() const override { return name_; } + + FakeUpstream& parent_; + std::string name_; + }; + void threadRoutine(); Ssl::ServerContext* ssl_ctx_{}; @@ -318,5 +341,6 @@ class FakeUpstream : Logger::Loggable, public Network::Filt Network::ConnectionHandlerPtr handler_; std::list new_connections_; // Guarded by lock_ bool allow_unexpected_disconnects_; + FakeListener listener_; }; } // namespace Envoy diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index d27ae7e1d82ff..3473b06b31799 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -29,6 +29,11 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); + Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, + Ssl::Context* ssl_ctx) { + return Network::ConnectionPtr{createConnection_(accept_socket.get(), ssl_ctx)}; + } + Network::ClientConnectionPtr createClientConnection(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, @@ -46,20 +51,9 @@ class MockDispatcher : public Dispatcher { return Filesystem::WatcherPtr{createFilesystemWatcher_()}; } - Network::ListenerPtr createListener(Network::ConnectionHandler& conn_handler, - Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - Stats::Scope& scope, - const Network::ListenerOptions& listener_options) override { - return Network::ListenerPtr{createListener_(conn_handler, socket, cb, scope, listener_options)}; - } - - Network::ListenerPtr - createSslListener(Network::ConnectionHandler& conn_handler, Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - Stats::Scope& scope, - const Network::ListenerOptions& listener_options) override { - return Network::ListenerPtr{ - createSslListener_(conn_handler, ssl_ctx, socket, cb, scope, listener_options)}; + Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, + bool bind_to_port) override { + return Network::ListenerPtr{createListener_(socket, cb, bind_to_port)}; } TimerPtr createTimer(TimerCb cb) override { return TimerPtr{createTimer_(cb)}; } @@ -77,6 +71,8 @@ class MockDispatcher : public Dispatcher { // Event::Dispatcher MOCK_METHOD0(clearDeferredDeleteList, void()); + MOCK_METHOD2(createConnection_, + Network::Connection*(Network::AcceptSocket* accept_socket, Ssl::Context* ssl_ctx)); MOCK_METHOD3(createClientConnection_, Network::ClientConnection*(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, @@ -87,16 +83,9 @@ class MockDispatcher : public Dispatcher { MOCK_METHOD4(createFileEvent_, FileEvent*(int fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events)); MOCK_METHOD0(createFilesystemWatcher_, Filesystem::Watcher*()); - MOCK_METHOD5(createListener_, - Network::Listener*(Network::ConnectionHandler& conn_handler, - Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - Stats::Scope& scope, - const Network::ListenerOptions& listener_options)); - MOCK_METHOD6(createSslListener_, - Network::Listener*(Network::ConnectionHandler& conn_handler, - Ssl::ServerContext& ssl_ctx, Network::ListenSocket& socket, - Network::ListenerCallbacks& cb, Stats::Scope& scope, - const Network::ListenerOptions& listener_options)); + MOCK_METHOD3(createListener_, + Network::Listener*(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, + bool bind_to_port)); MOCK_METHOD1(createTimer_, Timer*(TimerCb cb)); MOCK_METHOD1(deferredDelete_, void(DeferredDeletablePtr& to_delete)); MOCK_METHOD0(exit, void()); diff --git a/test/mocks/network/BUILD b/test/mocks/network/BUILD index dbcfac52c0eaf..5cc4100695b20 100644 --- a/test/mocks/network/BUILD +++ b/test/mocks/network/BUILD @@ -18,6 +18,7 @@ envoy_cc_mock( "//include/envoy/network:drain_decision_interface", "//include/envoy/network:filter_interface", "//include/envoy/network:transport_socket_interface", + "//include/envoy/server:listener_manager_interface", "//source/common/network:address_lib", "//source/common/network:utility_lib", "//test/mocks/event:event_mocks", diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index d555022782373..0e37be779ab6a 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -3,6 +3,7 @@ #include #include "envoy/buffer/buffer.h" +#include "envoy/server/listener_manager.h" #include "common/network/address_impl.h" #include "common/network/utility.h" diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index ed30eb6343533..1d63bd4b565fd 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -193,8 +193,10 @@ class MockListenerCallbacks : public ListenerCallbacks { MockListenerCallbacks(); ~MockListenerCallbacks(); + void onAccept(AcceptSocketPtr&& socket) override { onAccept_(socket); } void onNewConnection(ConnectionPtr&& conn) override { onNewConnection_(conn); } + MOCK_METHOD1(onAccept_, void(AcceptSocketPtr& socket)); MOCK_METHOD1(onNewConnection_, void(ConnectionPtr& conn)); }; @@ -226,6 +228,23 @@ class MockListenSocket : public ListenSocket { Address::InstanceConstSharedPtr local_address_; }; +class MockAcceptSocket : public AcceptSocket { +public: + MockAcceptSocket(); + ~MockAcceptSocket(); + + MOCK_CONST_METHOD0(localAddress, Address::InstanceConstSharedPtr()); + MOCK_METHOD1(resetLocalAddress, void(Address::InstanceConstSharedPtr&)); + MOCK_CONST_METHOD0(localAddressReset, bool()); + MOCK_CONST_METHOD0(remoteAddress, Address::InstanceConstSharedPtr()); + MOCK_METHOD1(resetRemoteAddress, void(Address::InstanceConstSharedPtr&)); + MOCK_CONST_METHOD0(fd, int()); + MOCK_METHOD0(takeFd, int()); + MOCK_METHOD0(close, void()); + + Address::InstanceConstSharedPtr local_address_; +}; + class MockListener : public Listener { public: MockListener(); @@ -240,14 +259,7 @@ class MockConnectionHandler : public ConnectionHandler { ~MockConnectionHandler(); MOCK_METHOD0(numConnections, uint64_t()); - MOCK_METHOD5(addListener, - void(Network::FilterChainFactory& factory, Network::ListenSocket& socket, - Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options)); - MOCK_METHOD6(addSslListener, - void(Network::FilterChainFactory& factory, Ssl::ServerContext& ssl_ctx, - Network::ListenSocket& socket, Stats::Scope& scope, uint64_t listener_tag, - const Network::ListenerOptions& listener_options)); + MOCK_METHOD1(addListener, void(Server::Listener& config)); MOCK_METHOD1(findListenerByAddress, Network::Listener*(const Network::Address::Instance& address)); MOCK_METHOD1(removeListeners, void(uint64_t listener_tag)); diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 4f80b9ae0c2c1..78d8aafae5325 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -186,7 +186,7 @@ class MockListener : public Listener { MOCK_METHOD0(useOriginalDst, bool()); MOCK_METHOD0(perConnectionBufferLimitBytes, uint32_t()); MOCK_METHOD0(listenerScope, Stats::Scope&()); - MOCK_METHOD0(listenerTag, uint64_t()); + MOCK_CONST_METHOD0(listenerTag, uint64_t()); MOCK_CONST_METHOD0(name, const std::string&()); testing::NiceMock filter_chain_factory_; diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index b10dafe9ed83a..7d5884f772379 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -20,15 +20,33 @@ using testing::_; namespace Envoy { namespace Server { -class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable { +class ConnectionHandlerTest : public testing::Test, + public Listener, + protected Logger::Loggable { public: - ConnectionHandlerTest() : handler_(new ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)) {} + ConnectionHandlerTest() + : handler_(new ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)), name_("test_listener"), + socket2_(nullptr) {} + + // Listener + Network::FilterChainFactory& filterChainFactory() override { return factory_; } + Network::ListenSocket& socket() override { return socket2_ ? *socket2_ : socket_; } + Ssl::ServerContext* defaultSslContext() override { return nullptr; } + bool useProxyProto() override { return false; } + bool bindToPort() override { return true; } + bool useOriginalDst() override { return false; } + uint32_t perConnectionBufferLimitBytes() override { return 0; } + Stats::Scope& listenerScope() override { return stats_store_; } + uint64_t listenerTag() const override { return socket2_ ? 2 : 1; } + const std::string& name() const override { return name_; } Stats::IsolatedStoreImpl stats_store_; NiceMock dispatcher_; Network::ConnectionHandlerPtr handler_; Network::MockFilterChainFactory factory_; NiceMock socket_; + std::string name_; + Network::MockListenSocket* socket2_; }; TEST_F(ConnectionHandlerTest, RemoveListener) { @@ -36,16 +54,14 @@ TEST_F(ConnectionHandlerTest, RemoveListener) { Network::MockListener* listener = new NiceMock(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; - })); - handler_->addListener(factory_, socket_, stats_store_, 1, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + })); + handler_->addListener(*this); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(_)).WillOnce(Return(true)); @@ -74,16 +90,14 @@ TEST_F(ConnectionHandlerTest, DestroyCloseConnections) { Network::MockListener* listener = new NiceMock(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; - })); - handler_->addListener(factory_, socket_, stats_store_, 1, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + })); + handler_->addListener(*this); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(_)).WillOnce(Return(true)); @@ -101,16 +115,14 @@ TEST_F(ConnectionHandlerTest, CloseDuringFilterChainCreate) { Network::MockListener* listener = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; - })); - handler_->addListener(factory_, socket_, stats_store_, 1, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + })); + handler_->addListener(*this); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(_)); @@ -127,16 +139,14 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { Network::MockListener* listener = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; - })); - handler_->addListener(factory_, socket_, stats_store_, 1, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + })); + handler_->addListener(*this); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(_)).WillOnce(Return(false)); @@ -154,16 +164,14 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { Network::MockListener* listener = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; - })); - handler_->addListener(factory_, socket_, stats_store_, 1, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + })); + handler_->addListener(*this); EXPECT_EQ(listener, handler_->findListenerByAddress(ByRef(*alt_address))); @@ -175,16 +183,15 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { EXPECT_CALL(socket2, localAddress()).WillRepeatedly(Return(alt_address2)); Network::MockListener* listener2 = new Network::MockListener(); - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener2; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener2; - })); - handler_->addListener(factory_, socket2, stats_store_, 2, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + })); + socket2_ = &socket2; + handler_->addListener(*this); EXPECT_EQ(listener, handler_->findListenerByAddress(ByRef(*alt_address))); EXPECT_EQ(listener2, handler_->findListenerByAddress(ByRef(*alt_address2))); @@ -198,16 +205,14 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { handler_->stopListeners(2); Network::MockListener* listener3 = new Network::MockListener(); - EXPECT_CALL(dispatcher_, createListener_(_, _, _, _, _)) - .WillOnce(Invoke([&](Network::ConnectionHandler&, Network::ListenSocket&, - Network::ListenerCallbacks& cb, Stats::Scope&, - const Network::ListenerOptions&) -> Network::Listener* { - listener_callbacks = &cb; - return listener3; - - })); - handler_->addListener(factory_, socket2, stats_store_, 2, - Network::ListenerOptions::listenerOptionsWithBindToPort()); + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener3; + + })); + handler_->addListener(*this); EXPECT_EQ(listener3, handler_->findListenerByAddress(ByRef(*alt_address2))); EXPECT_EQ(listener3, handler_->findListenerByAddress(ByRef(*alt_address3))); diff --git a/test/server/http/admin_test.cc b/test/server/http/admin_test.cc index 27d2c302eb2ee..e04a2f0e0f4e5 100644 --- a/test/server/http/admin_test.cc +++ b/test/server/http/admin_test.cc @@ -26,7 +26,8 @@ class AdminFilterTest : public testing::TestWithParam listener; - ON_CALL(listener, listenerTag()).WillByDefault(Return(1)); - EXPECT_CALL(*handler_, addListener(_, _, _, 1, _)) - .WillOnce(InvokeWithoutArgs([current_thread_id]() -> void { + ON_CALL(listener, listenerTag()).WillByDefault(Return(1UL)); + EXPECT_CALL(*handler_, addListener(_)) + .WillOnce(Invoke([current_thread_id](Listener& config) -> void { + EXPECT_EQ(config.listenerTag(), 1UL); EXPECT_NE(current_thread_id, std::this_thread::get_id()); })); worker_.addListener(listener, [&ci](bool success) -> void { @@ -60,9 +62,10 @@ TEST_F(WorkerImplTest, BasicFlow) { // After a worker is started adding/stopping/removing a listener happens on the worker thread. NiceMock listener2; - ON_CALL(listener2, listenerTag()).WillByDefault(Return(2)); - EXPECT_CALL(*handler_, addListener(_, _, _, 2, _)) - .WillOnce(InvokeWithoutArgs([current_thread_id]() -> void { + ON_CALL(listener2, listenerTag()).WillByDefault(Return(2UL)); + EXPECT_CALL(*handler_, addListener(_)) + .WillOnce(Invoke([current_thread_id](Listener& config) -> void { + EXPECT_EQ(config.listenerTag(), 2UL); EXPECT_NE(current_thread_id, std::this_thread::get_id()); })); worker_.addListener(listener2, [&ci](bool success) -> void { @@ -91,9 +94,10 @@ TEST_F(WorkerImplTest, BasicFlow) { // Now test adding and removing a listener without stopping it first. NiceMock listener3; - ON_CALL(listener3, listenerTag()).WillByDefault(Return(3)); - EXPECT_CALL(*handler_, addListener(_, _, _, 3, _)) - .WillOnce(InvokeWithoutArgs([current_thread_id]() -> void { + ON_CALL(listener3, listenerTag()).WillByDefault(Return(3UL)); + EXPECT_CALL(*handler_, addListener(_)) + .WillOnce(Invoke([current_thread_id](Listener& config) -> void { + EXPECT_EQ(config.listenerTag(), 3UL); EXPECT_NE(current_thread_id, std::this_thread::get_id()); })); worker_.addListener(listener3, [&ci](bool success) -> void { @@ -117,8 +121,8 @@ TEST_F(WorkerImplTest, ListenerException) { InSequence s; NiceMock listener; - ON_CALL(listener, listenerTag()).WillByDefault(Return(1)); - EXPECT_CALL(*handler_, addListener(_, _, _, 1, _)) + ON_CALL(listener, listenerTag()).WillByDefault(Return(1UL)); + EXPECT_CALL(*handler_, addListener(_)) .WillOnce(Throw(Network::CreateListenerException("failed"))); worker_.addListener(listener, [](bool success) -> void { EXPECT_FALSE(success); }); From 11766c40111fc553c301e2938ba7a831062c7ee1 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 25 Aug 2017 15:12:13 -0700 Subject: [PATCH 02/41] listener: Add filter framework. Add support for listener filters and refactor listener original dst and proxy protocol features as listener filters. Existing use_proxy_protocol and use_original_dst listener flags are still supported by internally converting them to listener filters. As a further step we could remoe the legacy flags from the v2 APIs. Signed-off-by: Jarno Rajahalme --- bazel/repository_locations.bzl | 4 +- .../original-dst-cluster/proxy_config.json | 5 +- include/envoy/network/filter.h | 70 ++++ include/envoy/network/listen_socket.h | 5 + include/envoy/server/filter_config.h | 56 +++ include/envoy/server/listener_manager.h | 12 +- source/common/config/lds_json.cc | 20 ++ source/common/config/well_known_names.h | 19 + source/common/filter/BUILD | 30 ++ source/common/filter/original_dst.cc | 36 ++ source/common/filter/original_dst.h | 22 ++ source/common/filter/proxy_protocol.cc | 174 +++++++++ source/common/filter/proxy_protocol.h | 87 +++++ source/common/json/config_schemas.cc | 13 + source/common/network/BUILD | 22 -- source/common/network/listen_socket_impl.h | 2 + source/common/network/proxy_protocol.cc | 186 ---------- source/common/network/proxy_protocol.h | 90 ----- source/exe/BUILD | 2 + source/server/BUILD | 3 +- source/server/config/network/BUILD | 22 ++ source/server/config/network/original_dst.cc | 36 ++ .../server/config/network/proxy_protocol.cc | 40 +++ source/server/config_validation/server.h | 5 + source/server/configuration_impl.cc | 9 + source/server/configuration_impl.h | 7 + source/server/connection_handler_impl.cc | 121 ++++--- source/server/connection_handler_impl.h | 31 +- source/server/http/admin.h | 1 + source/server/listener_manager_impl.cc | 48 +++ source/server/listener_manager_impl.h | 16 +- test/common/network/proxy_protocol_test.cc | 14 +- test/config_test/config_test.cc | 7 + test/integration/BUILD | 2 + test/integration/autonomous_upstream.cc | 2 + test/integration/autonomous_upstream.h | 1 + test/integration/fake_upstream.cc | 2 + test/integration/fake_upstream.h | 1 + test/mocks/network/mocks.cc | 11 +- test/mocks/network/mocks.h | 2 + test/mocks/server/mocks.h | 4 + test/server/connection_handler_test.cc | 333 +++++++++++++++--- test/server/listener_manager_impl_test.cc | 7 + 43 files changed, 1155 insertions(+), 425 deletions(-) create mode 100644 source/common/filter/original_dst.cc create mode 100644 source/common/filter/original_dst.h create mode 100644 source/common/filter/proxy_protocol.cc create mode 100644 source/common/filter/proxy_protocol.h delete mode 100644 source/common/network/proxy_protocol.cc delete mode 100644 source/common/network/proxy_protocol.h create mode 100644 source/server/config/network/original_dst.cc create mode 100644 source/server/config/network/proxy_protocol.cc diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 06f7a3ef351db..6ae3d4c12112f 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -71,8 +71,8 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/google/protobuf/archive/v3.5.0.tar.gz"], ), envoy_api = dict( - commit = "b796da4964af6c332bd7d29ae4f08d0a98bf5352", - remote = "https://github.com/envoyproxy/data-plane-api", + commit = "071ddd950fb391f5778799396b449254d228f764", + remote = "https://github.com/jrajahalme/envoy-api", ), grpc_httpjson_transcoding = dict( commit = "e4f58aa07b9002befa493a0a82e10f2e98b51fc6", diff --git a/configs/original-dst-cluster/proxy_config.json b/configs/original-dst-cluster/proxy_config.json index c6b2627074d2c..793f5c6be0ce5 100644 --- a/configs/original-dst-cluster/proxy_config.json +++ b/configs/original-dst-cluster/proxy_config.json @@ -1,7 +1,10 @@ { "listeners": [{ "address": "tcp://0.0.0.0:10000", - "use_original_dst": true, + "listener_filters": [{ + "name": "original_dst", + "config": {} + }], "filters": [{ "name": "http_connection_manager", "config": { diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index 1114f77bdb4dc..fb1787e57d2d6 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -9,6 +9,7 @@ namespace Envoy { namespace Network { class Connection; +class AcceptSocket; /** * Status codes returned by filters that can cause future filters to not get iterated to. @@ -147,6 +148,67 @@ class FilterManager { virtual bool initializeReadFilters() PURE; }; +/** + * Callbacks used by individual listener filter instances to communicate with the listener filter + * manager. + */ +class ListenerFilterCallbacks { +public: + virtual ~ListenerFilterCallbacks() {} + + /** + * @return the AcceptSocket that owns this manager and the managed filters. + */ + virtual AcceptSocket& socket() PURE; + + /** + * @return the Dispatcher for this manager. + */ + virtual Event::Dispatcher& dispatcher() PURE; + + /** + * If an filter stopped filter iteration by returning FilterStatus::StopIteration, + * the filter should call continueFilterChain(true) when complete to continue the filter chain, + * or continueFilterChain(false) if the filter execution failed and the connection musrt be + * closed. + * @param success boolean telling whether the filter execution was successful or not. + */ + virtual void continueFilterChain(bool success) PURE; +}; + +/** + * Listener Filter + */ +class ListenerFilter { +public: + virtual ~ListenerFilter() {} + + /** + * Called when a new connection is accepted, but before a Connection is created. + * Filter chain iteration can be stopped if needed. + * @param cb the callbacks the filter instance can use to communicate with the filter chain. + * @return status used by the filter manager to manage further filter iteration. + */ + virtual FilterStatus onAccept(ListenerFilterCallbacks& cb) PURE; +}; + +typedef std::shared_ptr ListenerFilterSharedPtr; + +/** + * Interface for filter callbacks and adding listener filters to a manager. + */ +class ListenerFilterManager { +public: + virtual ~ListenerFilterManager() {} + + /** + * Add a filter to the listener. Filters are invoked in FIFO order (the filter added + * first is called first). + * @param filter supplies the filter being added. + */ + virtual void addAcceptFilter(ListenerFilterSharedPtr filter) PURE; +}; + /** * Creates a chain of network filters for a new connection. */ @@ -161,6 +223,14 @@ class FilterChainFactory { * false, e.g. filter chain is empty. */ virtual bool createFilterChain(Connection& connection) PURE; + + /** + * Called to create the listener filter chain. + * @param listener supplies the listener to create the chain on. + * @return true if filter chain was created successfully. Otherwise + * false. + */ + virtual bool createFilterChain(ListenerFilterManager& listener) PURE; }; } // namespace Network diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 5a4ae27dea9d6..4d975f0a35999 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -80,6 +80,11 @@ class AcceptSocket { */ virtual int takeFd() PURE; + /** + * Clear 'reset' state so that the socket can be used again with a new listener. + */ + virtual void clearReset() PURE; + /** * Close the underlying socket. */ diff --git a/include/envoy/server/filter_config.h b/include/envoy/server/filter_config.h index 459c668c98266..427e26fc176a9 100644 --- a/include/envoy/server/filter_config.h +++ b/include/envoy/server/filter_config.h @@ -123,6 +123,62 @@ class FactoryContext { virtual Stats::Scope& listenerScope() PURE; }; +/** + * This function is used to wrap the creation of a listener filter chain for new sockets as they are + * created. Filter factories create the lambda at configuration initialization time, and then they + * are used at runtime. + * @param filter_manager supplies the filter manager for the listener to install filters to. + * Typically the function will install a single filter, but it's technically possibly to install + * more than one if desired. + */ +typedef std::function ListenerFilterFactoryCb; + +/** + * Implemented by each listener filter and registered via Registry::registerFactory() + * or the convenience class RegisterFactory. + */ +class NamedListenerFilterConfigFactory { +public: + virtual ~NamedListenerFilterConfigFactory() {} + + /** + * Create a particular listener filter factory implementation. If the implementation is unable to + * produce a factory with the provided parameters, it should throw an EnvoyException in the case + * of general error or a Json::Exception if the json configuration is erroneous. The returned + * callback should always be initialized. + * @param config supplies the general json configuration for the filter + * @param context supplies the filter's context. + * @return ListenerFilterFactoryCb the factory creation function. + */ + virtual ListenerFilterFactoryCb createFilterFactory(const Json::Object& config, + FactoryContext& context) PURE; + + /** + * v2 variant of createFilterFactory(..), where filter configs are specified as proto. This may be + * optionally implemented today, but will in the future become compulsory once v1 is deprecated. + */ + virtual ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) { + UNREFERENCED_PARAMETER(config); + UNREFERENCED_PARAMETER(context); + NOT_IMPLEMENTED; + } + + /** + * @return ProtobufTypes::MessagePtr create empty config proto message for v2. The filter + * config, which arrives in an opaque google.protobuf.Struct message, will be converted to + * JSON and then parsed into this empty proto. Optional today, will be compulsory when v1 + * is deprecated. + */ + virtual ProtobufTypes::MessagePtr createEmptyConfigProto() { return nullptr; } + + /** + * @return std::string the identifying name for a particular implementation of a listener filter + * produced by the factory. + */ + virtual std::string name() PURE; +}; + /** * This function is used to wrap the creation of a network filter chain for new connections as * they come in. Filter factories create the lambda at configuration initialization time, and then diff --git a/include/envoy/server/listener_manager.h b/include/envoy/server/listener_manager.h index 4183bcaeedcd2..3c67c39c53690 100644 --- a/include/envoy/server/listener_manager.h +++ b/include/envoy/server/listener_manager.h @@ -40,6 +40,16 @@ class ListenerComponentFactory { createFilterFactoryList(const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context) PURE; + /** + * Creates a list of listener filter factories. + * @param filters supplies the JSON configuration. + * @param context supplies the factory creation context. + * @return std::vector the list of filter factories. + */ + virtual std::vector + createListenerFilterFactoryList(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) PURE; + /** * @return DrainManagerPtr a new drain manager. * @param drain_type supplies the type of draining to do for the owning listener. @@ -169,7 +179,7 @@ class ListenerManager { virtual void startWorkers(GuardDog& guard_dog) PURE; /** - * Stop all listeners from accepting new connections without actually removing any of them. This + * Stop all listeners from accepting new connectins without actually removing any of them. This * is used for server draining. */ virtual void stopListeners() PURE; diff --git a/source/common/config/lds_json.cc b/source/common/config/lds_json.cc index 76860398bbeae..62d57e560c402 100644 --- a/source/common/config/lds_json.cc +++ b/source/common/config/lds_json.cc @@ -57,6 +57,26 @@ void LdsJson::translateListener(const Json::Object& json_listener, JSON_UTIL_SET_BOOL(json_listener, listener, use_original_dst); JSON_UTIL_SET_BOOL(json_listener, *listener.mutable_deprecated_v1(), bind_to_port); JSON_UTIL_SET_INTEGER(json_listener, listener, per_connection_buffer_limit_bytes); + + if (json_listener.hasObject("listener_filters")) { + for (const auto& json_filter : json_listener.getObjectArray("listener_filters", true)) { + auto* filter = listener.mutable_listener_filters()->Add(); + + // Translate v1 name to v2 name. + filter->set_name(Config::NetworkFilterNames::get().v1_converter_.getV2Name( + json_filter->getString("name"))); + JSON_UTIL_SET_STRING(*json_filter, *filter->mutable_deprecated_v1(), type); + + const std::string json_config = "{\"deprecated_v1\": true, \"value\": " + + json_filter->getObject("config")->asJsonString() + "}"; + + const auto status = + Protobuf::util::JsonStringToMessage(json_config, filter->mutable_config()); + // JSON schema has already validated that this is a valid JSON object. + ASSERT(status.ok()); + UNREFERENCED_PARAMETER(status); + } + } } } // namespace Config diff --git a/source/common/config/well_known_names.h b/source/common/config/well_known_names.h index 40756b131972c..c3aefd88aab5b 100644 --- a/source/common/config/well_known_names.h +++ b/source/common/config/well_known_names.h @@ -47,6 +47,25 @@ class V1Converter { std::unordered_map v1_to_v2_names_; }; +/** + * Well-known network filter names. + */ +class ListenerFilterNameValues { +public: + // Original destination listener filter + const std::string ORIGINAL_DST = "envoy.original_dst"; + // Proxy Protocol listener filter + const std::string PROXY_PROTOCOL = "envoy.proxy_protocol"; + + // Converts names from v1 to v2 + const V1Converter v1_converter_; + + ListenerFilterNameValues() + : v1_converter_({ORIGINAL_DST, PROXY_PROTOCOL}) {} +}; + +typedef ConstSingleton ListenerFilterNames; + /** * Well-known network filter names. */ diff --git a/source/common/filter/BUILD b/source/common/filter/BUILD index f1eddee693ad9..28356dac86a73 100644 --- a/source/common/filter/BUILD +++ b/source/common/filter/BUILD @@ -21,6 +21,36 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "original_dst_lib", + srcs = ["original_dst.cc"], + hdrs = ["original_dst.h"], + deps = [ + "//include/envoy/network:filter_interface", + "//include/envoy/network:listen_socket_interface", + "//source/common/common:assert_lib", + "//source/common/common:logger_lib", + "//source/common/network:utility_lib", + ], +) + +envoy_cc_library( + name = "proxy_protocol_lib", + srcs = ["proxy_protocol.cc"], + hdrs = ["proxy_protocol.h"], + deps = [ + "//include/envoy/event:dispatcher_interface", + "//include/envoy/network:filter_interface", + "//include/envoy/network:listen_socket_interface", + "//source/common/common:assert_lib", + "//source/common/common:empty_string", + "//source/common/common:logger_lib", + "//source/common/common:utility_lib", + "//source/common/network:address_lib", + "//source/common/network:utility_lib", + ], +) + envoy_cc_library( name = "ratelimit_lib", srcs = ["ratelimit.cc"], diff --git a/source/common/filter/original_dst.cc b/source/common/filter/original_dst.cc new file mode 100644 index 0000000000000..b85f03dd5cb0e --- /dev/null +++ b/source/common/filter/original_dst.cc @@ -0,0 +1,36 @@ +#include "common/filter/original_dst.h" + +#include "envoy/network/listen_socket.h" + +#include "common/common/assert.h" +#include "common/network/utility.h" + +namespace Envoy { +namespace Filter { + +Network::Address::InstanceConstSharedPtr OriginalDst::getOriginalDst(int fd) { + return Network::Utility::getOriginalDst(fd); +} + +Network::FilterStatus OriginalDst::onAccept(Network::ListenerFilterCallbacks& cb) { + ENVOY_LOG(info, "original_dst: New connection accepted"); + Network::AcceptSocket& socket = cb.socket(); + Network::Address::InstanceConstSharedPtr local_address = socket.localAddress(); + + if (local_address->type() == Network::Address::Type::Ip) { + Network::Address::InstanceConstSharedPtr original_local_address = getOriginalDst(socket.fd()); + + // A listener that has the use_original_dst flag set to true can still receive + // connections that are NOT redirected using iptables. If a connection was not redirected, + // the address returned by getOriginalDst() matches the local address of the new socket. + // In this case the listener handles the connection directly and does not hand it off. + if (original_local_address && (*original_local_address != *local_address)) { + socket.resetLocalAddress(original_local_address); + } + } + + return Network::FilterStatus::Continue; +} + +} // namespace Filter +} // namespace Envoy diff --git a/source/common/filter/original_dst.h b/source/common/filter/original_dst.h new file mode 100644 index 0000000000000..2104deee2c6bb --- /dev/null +++ b/source/common/filter/original_dst.h @@ -0,0 +1,22 @@ +#pragma once + +#include "envoy/network/filter.h" + +#include "common/common/logger.h" + +namespace Envoy { +namespace Filter { + +/** + * Implementation of an original destination listener filter. + */ +class OriginalDst : public Network::ListenerFilter, Logger::Loggable { +public: + // Network::ListenerFilter + Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override; + + virtual Network::Address::InstanceConstSharedPtr getOriginalDst(int fd); +}; + +} // namespace Filter +} // namespace Envoy diff --git a/source/common/filter/proxy_protocol.cc b/source/common/filter/proxy_protocol.cc new file mode 100644 index 0000000000000..0ce181df17938 --- /dev/null +++ b/source/common/filter/proxy_protocol.cc @@ -0,0 +1,174 @@ +#include "common/filter/proxy_protocol.h" + +#include + +#include +#include +#include + +#include "envoy/common/exception.h" +#include "envoy/event/dispatcher.h" +#include "envoy/network/listen_socket.h" +#include "envoy/stats/stats.h" + +#include "common/common/assert.h" +#include "common/common/empty_string.h" +#include "common/common/utility.h" +#include "common/network/address_impl.h" +#include "common/network/utility.h" + +namespace Envoy { +namespace Filter { +namespace ProxyProtocol { + +Config::Config(Stats::Scope& scope) : stats_{ALL_PROXY_PROTOCOL_STATS(POOL_COUNTER(scope))} {} + +Network::FilterStatus Instance::onAccept(Network::ListenerFilterCallbacks& cb) { + ENVOY_LOG(info, "proxy_protocol: New connection accepted"); + Network::AcceptSocket& socket = cb.socket(); + ASSERT(file_event_.get() == nullptr); + file_event_ = + cb.dispatcher().createFileEvent(socket.fd(), + [this](uint32_t events) { + ASSERT(events == Event::FileReadyType::Read); + UNREFERENCED_PARAMETER(events); + onRead(); + }, + Event::FileTriggerType::Edge, Event::FileReadyType::Read); + cb_ = &cb; + return Network::FilterStatus::StopIteration; +} + +void Instance::onRead() { + try { + onReadWorker(); + } catch (const EnvoyException& ee) { + config_->stats_.downstream_cx_proxy_proto_error_.inc(); + cb_->continueFilterChain(false); + } +} + +void Instance::onReadWorker() { + Network::AcceptSocket& socket = cb_->socket(); + std::string proxy_line; + if (!readLine(socket.fd(), proxy_line)) { + return; + } + + // Remove the line feed at the end + StringUtil::rtrim(proxy_line); + + // Parse proxy protocol line with format: PROXY TCP4/TCP6/UNKNOWN SOURCE_ADDRESS + // DESTINATION_ADDRESS SOURCE_PORT DESTINATION_PORT. + const auto line_parts = StringUtil::split(proxy_line, " ", true); + + if (line_parts.size() < 2 || line_parts[0] != "PROXY") { + throw EnvoyException("failed to read proxy protocol"); + } + + if (line_parts[1] == "UNKNOWN") { + // At this point we know it's a proxy protocol line, so we can remove it from the socket + // and continue. + Network::Address::InstanceConstSharedPtr local_address = Envoy::Network::Address::addressFromFd(socket.fd()); + Network::Address::InstanceConstSharedPtr remote_address; + // The remote address not known. + if (local_address->ip()->version() == Network::Address::IpVersion::v4) { + remote_address = std::make_shared(Network::Address::Ipv4Instance("0.0.0.0")); + } else { + remote_address = std::make_shared(Network::Address::Ipv6Instance("::")); + } + finishConnection(remote_address, local_address); + return; + } + + // If protocol not UNKNOWN, src and dst adresses have to be present. + if (line_parts.size() != 6) { + throw EnvoyException("failed to read proxy protocol"); + } + + Network::Address::IpVersion protocol_version; + Network::Address::InstanceConstSharedPtr remote_address; + Network::Address::InstanceConstSharedPtr local_address; + if (line_parts[1] == "TCP4") { + protocol_version = Network::Address::IpVersion::v4; + remote_address = + Network::Utility::parseInternetAddressAndPort(line_parts[2] + ":" + line_parts[4]); + local_address = + Network::Utility::parseInternetAddressAndPort(line_parts[3] + ":" + line_parts[5]); + } else if (line_parts[1] == "TCP6") { + protocol_version = Network::Address::IpVersion::v6; + remote_address = + Network::Utility::parseInternetAddressAndPort("[" + line_parts[2] + "]:" + line_parts[4]); + local_address = + Network::Utility::parseInternetAddressAndPort("[" + line_parts[3] + "]:" + line_parts[5]); + } else { + throw EnvoyException("failed to read proxy protocol"); + } + + // Error check the source and destination fields. Most errors are cought by the address + // parsing above, but a malformed IPv6 address may combine with a malformed port and parse as + // an IPv6 address when parsing for an IPv4 address. Remote address refers to the source + // address. + const auto remote_version = remote_address->ip()->version(); + const auto local_version = local_address->ip()->version(); + if (remote_version != protocol_version || local_version != protocol_version) { + throw EnvoyException("failed to read proxy protocol"); + } + // Check that both addresses are valid unicast addresses, as required for TCP + if (!remote_address->ip()->isUnicastAddress() || !local_address->ip()->isUnicastAddress()) { + throw EnvoyException("failed to read proxy protocol"); + } + + finishConnection(remote_address, local_address); +} + +void Instance::finishConnection(Network::Address::InstanceConstSharedPtr remote_address, + Network::Address::InstanceConstSharedPtr local_address) { + Network::AcceptSocket& socket = cb_->socket(); + + socket.resetLocalAddress(local_address); + socket.resetRemoteAddress(remote_address); + + cb_->continueFilterChain(true); +} + +bool Instance::readLine(int fd, std::string& s) { + while (buf_off_ < MAX_PROXY_PROTO_LEN) { + ssize_t nread = recv(fd, buf_ + buf_off_, MAX_PROXY_PROTO_LEN - buf_off_, MSG_PEEK); + + if (nread == -1 && errno == EAGAIN) { + return false; + } else if (nread < 1) { + throw EnvoyException("failed to read proxy protocol"); + } + + bool found = false; + // continue searching buf_ from where we left off + for (; search_index_ < buf_off_ + nread; search_index_++) { + if (buf_[search_index_] == '\n' && buf_[search_index_ - 1] == '\r') { + search_index_++; + found = true; + break; + } + } + + // Read the data upto and including the line feed, if available, but not past it. + // This should never fail, as search_index_ - buf_off_ <= nread, so we're asking + // only for bytes we have already seen. + nread = recv(fd, buf_ + buf_off_, search_index_ - buf_off_, 0); + ASSERT(size_t(nread) == search_index_ - buf_off_); + + buf_off_ += nread; + + if (found) { + s.assign(buf_, buf_off_); + return true; + } + } + + throw EnvoyException("failed to read proxy protocol"); +} + +} // namespace ProxyProtocol +} // namespace Filter +} // namespace Envoy diff --git a/source/common/filter/proxy_protocol.h b/source/common/filter/proxy_protocol.h new file mode 100644 index 0000000000000..cc86deaca6471 --- /dev/null +++ b/source/common/filter/proxy_protocol.h @@ -0,0 +1,87 @@ +#pragma once + +#include "envoy/event/file_event.h" +#include "envoy/network/filter.h" +#include "envoy/stats/stats_macros.h" + +#include "common/common/logger.h" + +namespace Envoy { +namespace Filter { +namespace ProxyProtocol { + +/** + * All stats for the proxy protocol. @see stats_macros.h + */ +// clang-format off +#define ALL_PROXY_PROTOCOL_STATS(COUNTER) \ + COUNTER(downstream_cx_proxy_proto_error) +// clang-format on + +/** + * Definition of all stats for the proxy protocol. @see stats_macros.h + */ +struct ProxyProtocolStats { + ALL_PROXY_PROTOCOL_STATS(GENERATE_COUNTER_STRUCT) +}; + +/** + * Global configuration for Proxy Protocol listener filter. + */ +class Config { +public: + Config(Stats::Scope& scope); + + ProxyProtocolStats stats_; +}; + +typedef std::shared_ptr ConfigSharedPtr; + +/** + * Implementation the PROXY Protocol V1 listener filter + * (http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) + */ +class Instance : public Network::ListenerFilter, Logger::Loggable { +public: + Instance(ConfigSharedPtr config) : search_index_(1), config_(config) {} + + // Network::ListenerFilter + Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override; + +private: + static const size_t MAX_PROXY_PROTO_LEN = 108; + + void onRead(); + void onReadWorker(); + + /** + * Helper function that replaces the current connection with the specified one. + */ + void finishConnection(Network::Address::InstanceConstSharedPtr remote_address, + Network::Address::InstanceConstSharedPtr local_address); + + /** + * Helper function that attempts to read a line (delimited by '\r\n') from the socket. + * throws EnvoyException on any socket errors. + * @return bool true if a line should be read, false if more data is needed. + */ + bool readLine(int fd, std::string& s); + + Network::ListenerFilterCallbacks* cb_; + Event::FileEventPtr file_event_; + + // The offset in buf_ that has been fully read + size_t buf_off_{}; + + // The index in buf_ where the search for '\r\n' should continue from + size_t search_index_; + + // Stores the portion of the first line that has been read so far. + char buf_[MAX_PROXY_PROTO_LEN]; + + ConfigSharedPtr config_; +}; + +} // namespace ProxyProtocol +} // namespace Filter +} // namespace Envoy diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index f887d8e121d6d..457dfffeec8d7 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -161,6 +161,15 @@ const std::string Json::Schema::LISTENER_SCHEMA(R"EOF( "required": ["cert_chain_file", "private_key_file"], "additionalProperties": false }, + "listener_filters" : { + "type" : "object", + "properties" : { + "name" : { "type": "string" }, + "config": {"type" : "object"} + }, + "required": ["name", "config"], + "additionalProperties": false + }, "filters" : { "type" : "object", "properties" : { @@ -178,6 +187,10 @@ const std::string Json::Schema::LISTENER_SCHEMA(R"EOF( "properties": { "name": {"type": "string"}, "address": {"type": "string"}, + "listener_filters" : { + "type" : "array", + "items": {"$ref" : "#/definitions/listener_filters"} + }, "filters" : { "type" : "array", "items": {"$ref" : "#/definitions/filters"} diff --git a/source/common/network/BUILD b/source/common/network/BUILD index d2bd87e2cabac..1250aa5b9c514 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -107,28 +107,6 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "proxy_protocol_lib", - srcs = [ - "proxy_protocol.cc", - ], - hdrs = [ - "proxy_protocol.h", - ], - deps = [ - ":address_lib", - ":listen_socket_lib", - "//include/envoy/event:dispatcher_interface", - "//include/envoy/event:file_event_interface", - "//include/envoy/stats:stats_interface", - "//include/envoy/stats:stats_macros", - "//source/common/common:empty_string", - "//source/common/common:linked_object", - "//source/common/event:dispatcher_includes", - "//source/common/event:libevent_lib", - ], -) - envoy_cc_library( name = "listener_lib", srcs = [ diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index cd811c67392d3..7af93e3cf297f 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -77,6 +77,8 @@ class AcceptSocketImpl : public AcceptSocket { return fd; } + void clearReset() override { local_address_reset_ = false; } + void close() override { if (fd_ != -1) { ::close(fd_); diff --git a/source/common/network/proxy_protocol.cc b/source/common/network/proxy_protocol.cc deleted file mode 100644 index 9116816b57684..0000000000000 --- a/source/common/network/proxy_protocol.cc +++ /dev/null @@ -1,186 +0,0 @@ -#include "common/network/proxy_protocol.h" - -#include - -#include -#include -#include - -#include "envoy/common/exception.h" -#include "envoy/event/dispatcher.h" -#include "envoy/event/file_event.h" -#include "envoy/stats/stats.h" - -#include "common/common/empty_string.h" -#include "common/common/utility.h" -#include "common/network/address_impl.h" -#include "common/network/utility.h" - -namespace Envoy { -namespace Network { - -ProxyProtocol::ProxyProtocol(Stats::Scope& scope) - : stats_{ALL_PROXY_PROTOCOL_STATS(POOL_COUNTER(scope))} {} - -void ProxyProtocol::newConnection(Event::Dispatcher& dispatcher, AcceptSocketPtr&& socket, - ProxyProtocolCompletion newConnectionCb) { - std::unique_ptr p{ - new ActiveConnection(*this, dispatcher, std::move(socket), newConnectionCb)}; - p->moveIntoList(std::move(p), connections_); -} - -ProxyProtocol::ActiveConnection::ActiveConnection(ProxyProtocol& parent, - Event::Dispatcher& dispatcher, - AcceptSocketPtr&& socket, - ProxyProtocolCompletion newConnectionCb) - : parent_(parent), socket_(std::move(socket)), newConnectionCb_(newConnectionCb), - search_index_(1) { - file_event_ = - dispatcher.createFileEvent(socket_->fd(), - [this](uint32_t events) { - ASSERT(events == Event::FileReadyType::Read); - UNREFERENCED_PARAMETER(events); - onRead(); - }, - Event::FileTriggerType::Edge, Event::FileReadyType::Read); -} - -ProxyProtocol::ActiveConnection::~ActiveConnection() {} - -void ProxyProtocol::ActiveConnection::onRead() { - try { - onReadWorker(); - } catch (const EnvoyException& ee) { - parent_.stats_.downstream_cx_proxy_proto_error_.inc(); - close(); - } -} - -void ProxyProtocol::ActiveConnection::onReadWorker() { - std::string proxy_line; - if (!readLine(socket_->fd(), proxy_line)) { - return; - } - - // Remove the line feed at the end - StringUtil::rtrim(proxy_line); - - // Parse proxy protocol line with format: PROXY TCP4/TCP6/UNKNOWN SOURCE_ADDRESS - // DESTINATION_ADDRESS SOURCE_PORT DESTINATION_PORT. - const auto line_parts = StringUtil::split(proxy_line, " ", true); - - if (line_parts.size() < 2 || line_parts[0] != "PROXY") { - throw EnvoyException("failed to read proxy protocol"); - } - - if (line_parts[1] == "UNKNOWN") { - // At this point we know it's a proxy protocol line, so we can remove it from the socket - // and continue. - Address::InstanceConstSharedPtr local_address = Envoy::Network::Address::addressFromFd(socket_->fd()); - Address::InstanceConstSharedPtr remote_address; - // The remote address not known. - if (local_address->ip()->version() == Address::IpVersion::v4) { - remote_address = std::make_shared(Address::Ipv4Instance("0.0.0.0")); - } else { - remote_address = std::make_shared(Address::Ipv6Instance("::")); - } - finishConnection(remote_address, local_address); - return; - } - - // If protocol not UNKNOWN, src and dst adresses have to be present. - if (line_parts.size() != 6) { - throw EnvoyException("failed to read proxy protocol"); - } - - Address::IpVersion protocol_version; - Address::InstanceConstSharedPtr remote_address; - Address::InstanceConstSharedPtr local_address; - if (line_parts[1] == "TCP4") { - protocol_version = Address::IpVersion::v4; - remote_address = Utility::parseInternetAddressAndPort(line_parts[2] + ":" + line_parts[4]); - local_address = Utility::parseInternetAddressAndPort(line_parts[3] + ":" + line_parts[5]); - } else if (line_parts[1] == "TCP6") { - protocol_version = Address::IpVersion::v6; - remote_address = - Utility::parseInternetAddressAndPort("[" + line_parts[2] + "]:" + line_parts[4]); - local_address = - Utility::parseInternetAddressAndPort("[" + line_parts[3] + "]:" + line_parts[5]); - } else { - throw EnvoyException("failed to read proxy protocol"); - } - - // Error check the source and destination fields. Most errors are cought by the address - // parsing above, but a malformed IPv6 address may combine with a malformed port and parse as - // an IPv6 address when parsing for an IPv4 address. Remote address refers to the source - // address. - const auto remote_version = remote_address->ip()->version(); - const auto local_version = local_address->ip()->version(); - if (remote_version != protocol_version || local_version != protocol_version) { - throw EnvoyException("failed to read proxy protocol"); - } - // Check that both addresses are valid unicast addresses, as required for TCP - if (!remote_address->ip()->isUnicastAddress() || !local_address->ip()->isUnicastAddress()) { - throw EnvoyException("failed to read proxy protocol"); - } - - finishConnection(remote_address, local_address); -} - -void ProxyProtocol::ActiveConnection::finishConnection( - Address::InstanceConstSharedPtr remote_address, Address::InstanceConstSharedPtr local_address) { - socket_->resetLocalAddress(local_address); - socket_->resetRemoteAddress(remote_address); - ProxyProtocolCompletion newConnectionCb = newConnectionCb_; - AcceptSocketPtr socket(std::move(socket_)); - removeFromList(parent_.connections_); - - newConnectionCb(std::move(socket), true); -} - -void ProxyProtocol::ActiveConnection::close() { - ProxyProtocolCompletion newConnectionCb = newConnectionCb_; - AcceptSocketPtr&& socket(std::move(socket_)); - removeFromList(parent_.connections_); - newConnectionCb(std::move(socket), false); -} - -bool ProxyProtocol::ActiveConnection::readLine(int fd, std::string& s) { - while (buf_off_ < MAX_PROXY_PROTO_LEN) { - ssize_t nread = recv(fd, buf_ + buf_off_, MAX_PROXY_PROTO_LEN - buf_off_, MSG_PEEK); - - if (nread == -1 && errno == EAGAIN) { - return false; - } else if (nread < 1) { - throw EnvoyException("failed to read proxy protocol"); - } - - bool found = false; - // continue searching buf_ from where we left off - for (; search_index_ < buf_off_ + nread; search_index_++) { - if (buf_[search_index_] == '\n' && buf_[search_index_ - 1] == '\r') { - search_index_++; - found = true; - break; - } - } - - // Read the data upto and including the line feed, if available, but not past it. - // This should never fail, as search_index_ - buf_off_ <= nread, so we're asking - // only for bytes we have already seen. - nread = recv(fd, buf_ + buf_off_, search_index_ - buf_off_, 0); - ASSERT(size_t(nread) == search_index_ - buf_off_); - - buf_off_ += nread; - - if (found) { - s.assign(buf_, buf_off_); - return true; - } - } - - throw EnvoyException("failed to read proxy protocol"); -} - -} // namespace Network -} // namespace Envoy diff --git a/source/common/network/proxy_protocol.h b/source/common/network/proxy_protocol.h deleted file mode 100644 index 4b63835867180..0000000000000 --- a/source/common/network/proxy_protocol.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "envoy/event/dispatcher.h" -#include "envoy/stats/stats_macros.h" - -#include "common/common/linked_object.h" - -namespace Envoy { -namespace Network { - -typedef std::function ProxyProtocolCompletion; - -/** - * All stats for the proxy protocol. @see stats_macros.h - */ -// clang-format off -#define ALL_PROXY_PROTOCOL_STATS(COUNTER) \ - COUNTER(downstream_cx_proxy_proto_error) -// clang-format on - -/** - * Definition of all stats for the proxy protocol. @see stats_macros.h - */ -struct ProxyProtocolStats { - ALL_PROXY_PROTOCOL_STATS(GENERATE_COUNTER_STRUCT) -}; - -/** - * Implementation the PROXY Protocol V1 - * (http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) - */ -class ProxyProtocol { -public: - class ActiveConnection : public LinkedObject { - public: - ActiveConnection(ProxyProtocol& parent, Event::Dispatcher& dispatcher, AcceptSocketPtr&& socket, - ProxyProtocolCompletion newConnectionCb); - ~ActiveConnection(); - - private: - static const size_t MAX_PROXY_PROTO_LEN = 108; - - void onRead(); - void onReadWorker(); - - /** - * Helper function that attempts to read a line (delimited by '\r\n') from the socket. - * throws EnvoyException on any socket errors. - * @return bool true if a line should be read, false if more data is needed. - */ - bool readLine(int fd, std::string& s); - void close(); - - /** - * Helper function that replaces the current connection with the specified one. - */ - void finishConnection(Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address); - - ProxyProtocol& parent_; - AcceptSocketPtr socket_; - ProxyProtocolCompletion newConnectionCb_; - Event::FileEventPtr file_event_; - - // The offset in buf_ that has been fully read - size_t buf_off_{}; - - // The index in buf_ where the search for '\r\n' should continue from - size_t search_index_; - - // Stores the portion of the first line that has been read so far. - char buf_[MAX_PROXY_PROTO_LEN]; - }; - - ProxyProtocol(Stats::Scope& scope); - - void newConnection(Event::Dispatcher& dispatcher, AcceptSocketPtr&& socket, - ProxyProtocolCompletion newConnectionCb); - -private: - ProxyProtocolStats stats_; - std::list> connections_; -}; - -} // namespace Network -} // namespace Envoy diff --git a/source/exe/BUILD b/source/exe/BUILD index 0fba8d2f9c690..73fe39b701195 100644 --- a/source/exe/BUILD +++ b/source/exe/BUILD @@ -48,6 +48,8 @@ envoy_cc_library( "//source/server/config/network:client_ssl_auth_lib", "//source/server/config/network:echo_lib", "//source/server/config/network:http_connection_manager_lib", + "//source/server/config/network:original_dst_lib", + "//source/server/config/network:proxy_protocol_lib", "//source/server/config/network:ratelimit_lib", "//source/server/config/network:raw_buffer_socket_lib", "//source/server/config/network:redis_proxy_lib", diff --git a/source/server/BUILD b/source/server/BUILD index a32f37f870489..39c0e350a79f7 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -67,8 +67,9 @@ envoy_cc_library( "//include/envoy/stats:timespan", "//source/common/common:linked_object", "//source/common/common:non_copyable", + "//source/common/filter:original_dst_lib", + "//source/common/filter:proxy_protocol_lib", "//source/common/network:connection_lib", - "//source/common/network:proxy_protocol_lib", ], ) diff --git a/source/server/config/network/BUILD b/source/server/config/network/BUILD index 949b589c4262b..e7aa6f0d5de81 100644 --- a/source/server/config/network/BUILD +++ b/source/server/config/network/BUILD @@ -32,6 +32,28 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "original_dst_lib", + srcs = ["original_dst.cc"], + deps = [ + "//include/envoy/registry", + "//include/envoy/server:filter_config_interface", + "//source/common/config:well_known_names", + "//source/common/filter:original_dst_lib", + ], +) + +envoy_cc_library( + name = "proxy_protocol_lib", + srcs = ["proxy_protocol.cc"], + deps = [ + "//include/envoy/registry", + "//include/envoy/server:filter_config_interface", + "//source/common/config:well_known_names", + "//source/common/filter:proxy_protocol_lib", + ], +) + envoy_cc_library( name = "http_connection_manager_lib", srcs = ["http_connection_manager.cc"], diff --git a/source/server/config/network/original_dst.cc b/source/server/config/network/original_dst.cc new file mode 100644 index 0000000000000..8ee7e55129abe --- /dev/null +++ b/source/server/config/network/original_dst.cc @@ -0,0 +1,36 @@ +#include + +#include "envoy/registry/registry.h" +#include "envoy/server/filter_config.h" + +#include "common/config/well_known_names.h" +#include "common/filter/original_dst.h" + +namespace Envoy { +namespace Server { +namespace Configuration { + +/** + * Config registration for the original dst filter. @see NamedNetworkFilterConfigFactory. + */ +class OriginalDstConfigFactory : public NamedListenerFilterConfigFactory { +public: + // NamedListenerFilterConfigFactory + ListenerFilterFactoryCb createFilterFactory(const Json::Object&, FactoryContext&) override { + return [](Network::ListenerFilterManager& filter_manager) -> void { + filter_manager.addAcceptFilter(Network::ListenerFilterSharedPtr{new Filter::OriginalDst()}); + }; + } + + std::string name() override { return Config::ListenerFilterNames::get().ORIGINAL_DST; } +}; + +/** + * Static registration for the original dst filter. @see RegisterFactory. + */ +static Registry::RegisterFactory + registered_; + +} // namespace Configuration +} // namespace Server +} // namespace Envoy diff --git a/source/server/config/network/proxy_protocol.cc b/source/server/config/network/proxy_protocol.cc new file mode 100644 index 0000000000000..99e6c71280125 --- /dev/null +++ b/source/server/config/network/proxy_protocol.cc @@ -0,0 +1,40 @@ +#include + +#include "envoy/registry/registry.h" +#include "envoy/server/filter_config.h" + +#include "common/config/well_known_names.h" +#include "common/filter/proxy_protocol.h" + +namespace Envoy { +namespace Server { +namespace Configuration { + +/** + * Config registration for the proxy protocol filter. @see NamedNetworkFilterConfigFactory. + */ +class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { +public: + // NamedListenerFilterConfigFactory + ListenerFilterFactoryCb createFilterFactory(const Json::Object&, + FactoryContext& context) override { + Filter::ProxyProtocol::ConfigSharedPtr config( + new Filter::ProxyProtocol::Config(context.scope())); + return [config](Network::ListenerFilterManager& filter_manager) -> void { + filter_manager.addAcceptFilter( + Network::ListenerFilterSharedPtr{new Filter::ProxyProtocol::Instance(config)}); + }; + } + + std::string name() override { return Config::ListenerFilterNames::get().PROXY_PROTOCOL; } +}; + +/** + * Static registration for the proxy protocol filter. @see RegisterFactory. + */ +static Registry::RegisterFactory + registered_; + +} // namespace Configuration +} // namespace Server +} // namespace Envoy diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index cf3a8e3b6548f..fef5d2e2d2021 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -94,6 +94,11 @@ class ValidationInstance : Logger::Loggable, Configuration::FactoryContext& context) override { return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); } + std::vector + createListenerFilterFactoryList(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) override { + return ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, context); + } Network::ListenSocketSharedPtr createListenSocket(Network::Address::InstanceConstSharedPtr, bool) override { // Returned sockets are not currently used so we can return nothing here safely vs. a diff --git a/source/server/configuration_impl.cc b/source/server/configuration_impl.cc index 24ea15eaac401..ce82b233a9142 100644 --- a/source/server/configuration_impl.cc +++ b/source/server/configuration_impl.cc @@ -36,6 +36,15 @@ bool FilterChainUtility::buildFilterChain(Network::FilterManager& filter_manager return filter_manager.initializeReadFilters(); } +bool FilterChainUtility::buildFilterChain(Network::ListenerFilterManager& filter_manager, + const std::vector& factories) { + for (const ListenerFilterFactoryCb& factory : factories) { + factory(filter_manager); + } + + return true; +} + void MainImpl::initialize(const envoy::api::v2::Bootstrap& bootstrap, Instance& server, Upstream::ClusterManagerFactory& cluster_manager_factory) { cluster_manager_ = cluster_manager_factory.clusterManagerFromProto( diff --git a/source/server/configuration_impl.h b/source/server/configuration_impl.h index 3dafe282a6b3e..862f9dd495b93 100644 --- a/source/server/configuration_impl.h +++ b/source/server/configuration_impl.h @@ -99,6 +99,13 @@ class FilterChainUtility { */ static bool buildFilterChain(Network::FilterManager& filter_manager, const std::vector& factories); + + /** + * Given an accept socket and a list of factories, create a new filter chain. Chain creation will + * exit early if any filters immediately close the connection. + */ + static bool buildFilterChain(Network::ListenerFilterManager& filter_manager, + const std::vector& factories); }; /** diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 00a838baa366a..3e61c015a2c1f 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -5,6 +5,8 @@ #include "envoy/network/filter.h" #include "envoy/stats/timespan.h" +#include "common/filter/original_dst.h" +#include "common/filter/proxy_protocol.h" #include "common/network/connection_impl.h" #include "common/network/utility.h" @@ -63,7 +65,7 @@ ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& par Listener& config) : parent_(parent), listener_(std::move(listener)), stats_(generateStats(config.listenerScope())), listener_tag_(config.listenerTag()), - proxy_protocol_(config.listenerScope()), config_(config) {} + config_(config), legacy_stats_(new Filter::ProxyProtocol::Config(config.listenerScope())) {} ConnectionHandlerImpl::ActiveListener::~ActiveListener() { while (!sockets_.empty()) { @@ -90,7 +92,7 @@ ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Insta // This is a linear operation, may need to add a map to improve performance. // However, linear performance might be adequate since the number of listeners is small. // We do not return stopped listeners. - auto listener = std::find_if( + auto iter = std::find_if( listeners_.begin(), listeners_.end(), [&address](const std::pair& p) { return p.second->listener_ != nullptr && p.first->type() == Network::Address::Type::Ip && @@ -98,80 +100,83 @@ ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Insta }); // If there is exact address match, return the corresponding listener. - if (listener != listeners_.end()) { - return listener->second.get(); + if (iter != listeners_.end()) { + return iter->second.get(); } // Otherwise, we need to look for the wild card match, i.e., 0.0.0.0:[address_port]. // We do not return stopped listeners. // TODO(wattli): consolidate with previous search for more efficiency. - listener = std::find_if( + iter = std::find_if( listeners_.begin(), listeners_.end(), [&address](const std::pair& p) { return p.second->listener_ != nullptr && p.first->type() == Network::Address::Type::Ip && p.first->ip()->port() == address.ip()->port() && p.first->ip()->isAnyAddress(); }); - return (listener != listeners_.end()) ? listener->second.get() : nullptr; + return (iter != listeners_.end()) ? iter->second.get() : nullptr; } -Network::Address::InstanceConstSharedPtr -ConnectionHandlerImpl::ActiveListener::getOriginalDst(int fd) { - return Network::Utility::getOriginalDst(fd); -} +void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { + if (success) { + if (iter_ == accept_filters_.end()) { + iter_ = accept_filters_.begin(); + } else { + iter_ = std::next(iter_); + } -void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptSocketPtr&& accept_socket) { - Network::AcceptSocket* socket = accept_socket.get(); - Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); - ActiveSocketPtr active_socket(new ActiveSocket(*this, std::move(accept_socket))); - -#if 0 - /* Not needed yet. */ - active_socket->moveIntoList(std::move(active_socket), sockets_); -#endif - - // This logic will move to Original Dst Filter - if (config_.useOriginalDst() && local_address->type() == Network::Address::Type::Ip) { - Network::Address::InstanceConstSharedPtr original_local_address = getOriginalDst(socket->fd()); - - // A listener that has the use_original_dst flag set to true can still receive - // connections that are NOT redirected using iptables. If a connection was not redirected, - // the address returned by getOriginalDst() matches the local address of the new socket. - // In this case the listener handles the connection directly and does not hand it off. - if (original_local_address && (*original_local_address != *local_address)) { - socket->resetLocalAddress(original_local_address); - local_address = original_local_address; - - // Hands off redirected connections (from iptables) to the listener associated with the - // original destination address. If there is no listener associated with the original - // destination address, the connection is handled by the listener that receives it. - ActiveListener* new_listener = parent_.findActiveListenerByAddress(*original_local_address); - - if (new_listener != nullptr) { - active_socket->listener_ = new_listener; + for (; iter_ != accept_filters_.end(); iter_++) { + Network::FilterStatus status = (*iter_)->onAccept(*this); + if (status == Network::FilterStatus::StopIteration) { + return; + } + // Check if another listener may have to be used. + if (socket_->localAddressReset()) { + // Hands off redirected connections (from iptables) to the listener associated with the + // original destination address. If there is no listener associated with the original + // destination address, the connection is handled by the listener that receives it. + ActiveListener* new_listener = + listener_->parent_.findActiveListenerByAddress(*socket_->localAddress()); + + if (new_listener != nullptr) { + // Reset the accept socket transiet state and hand it to the new listener. + socket_->clearReset(); + new_listener->onAccept(std::move(socket_)); + goto out; + } } } + // Successfully ran all the accept filters, create a new connection. + listener_->newConnection(std::move(socket_)); + } else { + // current filter failed, connection must be abandoned. + socket_->close(); } +out: + // Filter execution concluded, clear state. + iter_ = accept_filters_.end(); + ActiveSocketPtr removed = removeFromList(listener_->sockets_); + listener_->parent_.dispatcher_.deferredDelete(std::move(removed)); +} - // 'this' may not be the listener any more, must use 'active_socket->listener_'. - - // This logic will move to Proxy Protocol Filter - // XXX: Race if listener is removed while proxy protocol is waiting for more data? - // Seems this race affects the existing implementation in master as well. - if (active_socket->listener_->config_.useProxyProto()) { - ActiveListener* listener = active_socket->listener_; - listener->proxy_protocol_.newConnection( - listener->parent_.dispatcher_, std::move(active_socket->socket_), - [listener](Network::AcceptSocketPtr&& socketPtr, bool success) mutable { - if (success) { - listener->newConnection(std::move(socketPtr)); - } - }); - } else { - // TODO(jamessynge): We need to keep per-family stats. BUT, should it be based on the original - // family or the local family? Probably local family, as the original proxy can take care of - // stats for the original family. - active_socket->listener_->newConnection(std::move(active_socket->socket_)); +void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptSocketPtr&& accept_socket) { + Network::Address::InstanceConstSharedPtr local_address = accept_socket->localAddress(); + ActiveSocket* active_socket(new ActiveSocket(*this, std::move(accept_socket))); + + // Implicitly add legacy filters + if (config_.useOriginalDst()) { + active_socket->accept_filters_.emplace_back( + Network::ListenerFilterSharedPtr{new Filter::OriginalDst()}); + } + if (config_.useProxyProto()) { + active_socket->accept_filters_.emplace_back( + Network::ListenerFilterSharedPtr{new Filter::ProxyProtocol::Instance(legacy_stats_)}); } + + // Create and run the filters + config_.filterChainFactory().createFilterChain(*active_socket); + ActiveSocketPtr as(active_socket); + as->moveIntoListBack(std::move(as), sockets_); + active_socket->continueFilterChain(true); } void ConnectionHandlerImpl::ActiveListener::newConnection( diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index facba7148ed52..f5b4fcd64c486 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -17,7 +17,7 @@ #include "common/common/linked_object.h" #include "common/common/non_copyable.h" -#include "common/network/proxy_protocol.h" +#include "common/filter/proxy_protocol.h" #include "spdlog/spdlog.h" @@ -76,6 +76,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ~ActiveListener(); + // Network::ListenerCallbacks /** * Fires when a new connection is received from the listener. * @param socket supplies the accepted socket to take control of. @@ -99,16 +100,14 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { */ void newConnection(Network::AcceptSocketPtr&& accept_socket); - virtual Network::Address::InstanceConstSharedPtr getOriginalDst(int fd); - ConnectionHandlerImpl& parent_; Network::ListenerPtr listener_; ListenerStats stats_; std::list sockets_; std::list connections_; const uint64_t listener_tag_; - Network::ProxyProtocol proxy_protocol_; Listener& config_; + Filter::ProxyProtocol::ConfigSharedPtr legacy_stats_; }; typedef std::unique_ptr ActiveListenerPtr; @@ -141,13 +140,31 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { /** * Wrapper for an active accept socket owned by this handler. */ - struct ActiveSocket : LinkedObject, public Event::DeferredDeletable { + struct ActiveSocket : public Network::ListenerFilterManager, + public Network::ListenerFilterCallbacks, + LinkedObject, + public Event::DeferredDeletable { ActiveSocket(ActiveListener& listener, Network::AcceptSocketPtr&& socket) - : listener_(&listener), socket_(std::move(socket)) {} - ~ActiveSocket() {} + : listener_(&listener), socket_(std::move(socket)), iter_(accept_filters_.end()) {} + ~ActiveSocket() { + ASSERT(iter_ == accept_filters_.end()); + accept_filters_.clear(); + } + + // Network::ListenerFilterManager + void addAcceptFilter(Network::ListenerFilterSharedPtr filter) override { + accept_filters_.emplace_back(filter); + } + + // Network::ListenerFilterCallbacks + Network::AcceptSocket& socket() override { return *socket_.get(); } + Event::Dispatcher& dispatcher() override { return listener_->parent_.dispatcher_; } + void continueFilterChain(bool success) override; ActiveListener* listener_; Network::AcceptSocketPtr socket_; + std::list accept_filters_; + std::list::iterator iter_; }; static ListenerStats generateStats(Stats::Scope& scope); diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 4ce562e9743ec..3a0aa20dea3cf 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -49,6 +49,7 @@ class AdminImpl : public Admin, // Network::FilterChainFactory bool createFilterChain(Network::Connection& connection) override; + bool createFilterChain(Network::ListenerFilterManager&) override { return true; } // Http::FilterChainFactory void createFilterChain(Http::FilterChainFactoryCallbacks& callbacks) override; diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index 77a201e092903..86fe57f5fcb9c 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -48,6 +48,45 @@ ProdListenerComponentFactory::createFilterFactoryList_( return ret; } +// Use a template to reduce code duplication from above? +std::vector +ProdListenerComponentFactory::createListenerFilterFactoryList_( + const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) { + std::vector ret; + for (ssize_t i = 0; i < filters.size(); i++) { + const std::string string_type = filters[i].deprecated_v1().type(); + const std::string string_name = filters[i].name(); + const auto& proto_config = filters[i].config(); + ENVOY_LOG(info, " listener filter #{}:", i); + ENVOY_LOG(info, " name: {}", string_name); + const Json::ObjectSharedPtr filter_config = MessageUtil::getJsonObjectFromMessage(proto_config); + + // Now see if there is a factory that will accept the config. + Configuration::NamedListenerFilterConfigFactory* factory = + Registry::FactoryRegistry::getFactory( + string_name); + if (factory != nullptr) { + Configuration::ListenerFilterFactoryCb callback; + if (filter_config->getBoolean("deprecated_v1", false)) { + callback = factory->createFilterFactory(*filter_config->getObject("value", true), context); + } else { + auto message = factory->createEmptyConfigProto(); + if (!message) { + throw EnvoyException( + fmt::format("Filter factory for '{}' has unexpected proto config", string_name)); + } + MessageUtil::loadFromJson(filter_config->asJsonString(), *message); + callback = factory->createFilterFactoryFromProto(*message, context); + } + ret.push_back(callback); + } else { + throw EnvoyException(fmt::format("unable to create filter factory for '{}'", string_name)); + } + } + return ret; +} + Network::ListenSocketSharedPtr ProdListenerComponentFactory::createListenSocket(Network::Address::InstanceConstSharedPtr address, bool bind_to_port) { @@ -96,6 +135,11 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag // filter chain #1308. ASSERT(config.filter_chains().size() >= 1); + if (config.listener_filters().size()) { + listener_filter_factories_ = + parent_.factory_.createListenerFilterFactoryList(config.listener_filters(), *this); + } + // Skip lookup and update of the SSL Context if there is only one filter chain // and it doesn't enforce any SNI restrictions. const bool skip_context_update = @@ -153,6 +197,10 @@ bool ListenerImpl::createFilterChain(Network::Connection& connection) { return Configuration::FilterChainUtility::buildFilterChain(connection, filter_factories_); } +bool ListenerImpl::createFilterChain(Network::ListenerFilterManager& manager) { + return Configuration::FilterChainUtility::buildFilterChain(manager, listener_filter_factories_); +} + bool ListenerImpl::drainClose() const { // When a listener is draining, the "drain close" decision is the union of the per-listener drain // manager and the server wide drain manager. This allows individual listeners to be drained and diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index 4699c71a56f62..d9ad445ecc0da 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -30,13 +30,25 @@ class ProdListenerComponentFactory : public ListenerComponentFactory, static std::vector createFilterFactoryList_(const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context); + /** + * Static worker for createListenerFilterFactoryList() that can be used directly in tests. + */ + static std::vector createListenerFilterFactoryList_( + const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context); - // Server::ListenSocketFactory + // Server::ListenerComponentFactory std::vector createFilterFactoryList(const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context) override { return createFilterFactoryList_(filters, context); } + std::vector + createListenerFilterFactoryList(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) override { + return createListenerFilterFactoryList_(filters, context); + } + Network::ListenSocketSharedPtr createListenSocket(Network::Address::InstanceConstSharedPtr address, bool bind_to_port) override; DrainManagerPtr createDrainManager(envoy::api::v2::Listener::DrainType drain_type) override; @@ -237,6 +249,7 @@ class ListenerImpl : public Listener, // Network::FilterChainFactory bool createFilterChain(Network::Connection& connection) override; + bool createFilterChain(Network::ListenerFilterManager& manager) override; private: ListenerManagerImpl& parent_; @@ -257,6 +270,7 @@ class ListenerImpl : public Listener, InitManagerImpl dynamic_init_manager_; bool initialize_canceled_{}; std::vector filter_factories_; + std::vector listener_filter_factories_; DrainManagerPtr local_drain_manager_; bool saw_listener_create_failure_{}; }; diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index 035d81060908d..35afad353b467 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -21,8 +21,10 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +using testing::A; using testing::Invoke; using testing::NiceMock; +using testing::Return; using testing::_; namespace Envoy { @@ -43,6 +45,8 @@ class ProxyProtocolTest : public testing::TestWithParam, Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket()); conn_->addConnectionCallbacks(connection_callbacks_); + + ON_CALL(factory_, createFilterChain(A())).WillByDefault(Return(true)); } // Listener @@ -60,7 +64,9 @@ class ProxyProtocolTest : public testing::TestWithParam, void connect() { conn_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createFilterChain(_)) + EXPECT_CALL(factory_, createFilterChain(A())) + .WillOnce(Invoke([&](ListenerFilterManager&) -> bool { return true; })); + EXPECT_CALL(factory_, createFilterChain(A())) .WillOnce(Invoke([&](Connection& connection) -> bool { server_connection_ = &connection; connection.addConnectionCallbacks(server_callbacks_); @@ -74,6 +80,7 @@ class ProxyProtocolTest : public testing::TestWithParam, void connectNoRead() { conn_->connect(); + EXPECT_CALL(factory_, createFilterChain(A())); EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); dispatcher_.run(Event::Dispatcher::RunType::Block); @@ -295,6 +302,7 @@ TEST_P(ProxyProtocolTest, Closed) { TEST_P(ProxyProtocolTest, ClosedEmpty) { conn_->connect(); + EXPECT_CALL(factory_, createFilterChain(A())); conn_->close(ConnectionCloseType::NoFlush); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } @@ -332,7 +340,9 @@ class WildcardProxyProtocolTest : public testing::TestWithParamconnect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createFilterChain(_)) + EXPECT_CALL(factory_, createFilterChain(A())) + .WillOnce(Invoke([&](ListenerFilterManager&) -> bool { return true; })); + EXPECT_CALL(factory_, createFilterChain(A())) .WillOnce(Invoke([&](Connection& connection) -> bool { server_connection_ = &connection; connection.addConnectionCallbacks(server_callbacks_); diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index bb3fa3048ad5a..99bf7609d52f9 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -53,6 +53,13 @@ class ConfigTest { -> std::vector { return Server::ProdListenerComponentFactory::createFilterFactoryList_(filters, context); })); + ON_CALL(component_factory_, createListenerFilterFactoryList(_, _)) + .WillByDefault(Invoke([&](const Protobuf::RepeatedPtrField& filters, + Server::Configuration::FactoryContext& context) + -> std::vector { + return Server::ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, + context); + })); try { main_config.initialize(bootstrap, server_, *cluster_manager_factory_); diff --git a/test/integration/BUILD b/test/integration/BUILD index eb186a779dce5..dda1f26595dd3 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -272,6 +272,8 @@ envoy_cc_test_library( "//source/server/config/network:echo_lib", "//source/server/config/network:http_connection_manager_lib", "//source/server/config/network:mongo_proxy_lib", + "//source/server/config/network:original_dst_lib", + "//source/server/config/network:proxy_protocol_lib", "//source/server/config/network:ratelimit_lib", "//source/server/config/network:raw_buffer_socket_lib", "//source/server/config/network:redis_proxy_lib", diff --git a/test/integration/autonomous_upstream.cc b/test/integration/autonomous_upstream.cc index 6e86339e1ead3..7eda68f396aca 100644 --- a/test/integration/autonomous_upstream.cc +++ b/test/integration/autonomous_upstream.cc @@ -75,4 +75,6 @@ bool AutonomousUpstream::createFilterChain(Network::Connection& connection) { return true; } +bool AutonomousUpstream::createFilterChain(Network::ListenerFilterManager&) { return true; } + } // namespace Envoy diff --git a/test/integration/autonomous_upstream.h b/test/integration/autonomous_upstream.h index 592888cc12dd7..48a5d6355cc70 100644 --- a/test/integration/autonomous_upstream.h +++ b/test/integration/autonomous_upstream.h @@ -49,6 +49,7 @@ class AutonomousUpstream : public FakeUpstream { : FakeUpstream(port, type, version) {} ~AutonomousUpstream(); bool createFilterChain(Network::Connection& connection) override; + bool createFilterChain(Network::ListenerFilterManager& listener) override; private: std::vector http_connections_; diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 9cffadb41db8e..360a7a2431128 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -287,6 +287,8 @@ bool FakeUpstream::createFilterChain(Network::Connection& connection) { return true; } +bool FakeUpstream::createFilterChain(Network::ListenerFilterManager&) { return true; } + void FakeUpstream::threadRoutine() { handler_->addListener(listener_); diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index ed74e65a78a20..100bca956c6b2 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -294,6 +294,7 @@ class FakeUpstream : Logger::Loggable, public Network::Filt // Network::FilterChainFactory bool createFilterChain(Network::Connection& connection) override; + bool createFilterChain(Network::ListenerFilterManager& listener) override; void set_allow_unexpected_disconnects(bool value) { allow_unexpected_disconnects_ = value; } protected: diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index 0e37be779ab6a..63e7e9ef27bfd 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -13,6 +13,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +using testing::A; using testing::Invoke; using testing::Return; using testing::ReturnPointee; @@ -143,7 +144,9 @@ MockListenerCallbacks::~MockListenerCallbacks() {} MockDrainDecision::MockDrainDecision() {} MockDrainDecision::~MockDrainDecision() {} -MockFilterChainFactory::MockFilterChainFactory() {} +MockFilterChainFactory::MockFilterChainFactory() { + ON_CALL(*this, createFilterChain(A())).WillByDefault(Return(true)); +} MockFilterChainFactory::~MockFilterChainFactory() {} MockListenSocket::MockListenSocket() : local_address_(new Address::Ipv4Instance(80)) { @@ -152,6 +155,12 @@ MockListenSocket::MockListenSocket() : local_address_(new Address::Ipv4Instance( MockListenSocket::~MockListenSocket() {} +MockAcceptSocket::MockAcceptSocket() : local_address_(new Address::Ipv4Instance(80)) { + ON_CALL(*this, localAddress()).WillByDefault(Return(local_address_)); +} + +MockAcceptSocket::~MockAcceptSocket() {} + MockListener::MockListener() {} MockListener::~MockListener() { onDestroy(); } diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 1d63bd4b565fd..f2e93b166c1c6 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -214,6 +214,7 @@ class MockFilterChainFactory : public FilterChainFactory { ~MockFilterChainFactory(); MOCK_METHOD1(createFilterChain, bool(Connection& connection)); + MOCK_METHOD1(createFilterChain, bool(ListenerFilterManager& listener)); }; class MockListenSocket : public ListenSocket { @@ -240,6 +241,7 @@ class MockAcceptSocket : public AcceptSocket { MOCK_METHOD1(resetRemoteAddress, void(Address::InstanceConstSharedPtr&)); MOCK_CONST_METHOD0(fd, int()); MOCK_METHOD0(takeFd, int()); + MOCK_METHOD0(clearReset, void()); MOCK_METHOD0(close, void()); Address::InstanceConstSharedPtr local_address_; diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 78d8aafae5325..8bd93152e71be 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -150,6 +150,10 @@ class MockListenerComponentFactory : public ListenerComponentFactory { std::vector( const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context)); + MOCK_METHOD2(createListenerFilterFactoryList, + std::vector( + const Protobuf::RepeatedPtrField&, + Configuration::FactoryContext& context)); MOCK_METHOD2(createListenSocket, Network::ListenSocketSharedPtr(Network::Address::InstanceConstSharedPtr address, bool bind_to_port)); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 7d5884f772379..6c2639694b8c8 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -10,6 +10,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +using testing::A; using testing::ByRef; using testing::InSequence; using testing::Invoke; @@ -20,33 +21,51 @@ using testing::_; namespace Envoy { namespace Server { -class ConnectionHandlerTest : public testing::Test, - public Listener, - protected Logger::Loggable { +class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable { public: - ConnectionHandlerTest() - : handler_(new ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)), name_("test_listener"), - socket2_(nullptr) {} + ConnectionHandlerTest() : handler_(new ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)) {} // Listener - Network::FilterChainFactory& filterChainFactory() override { return factory_; } - Network::ListenSocket& socket() override { return socket2_ ? *socket2_ : socket_; } - Ssl::ServerContext* defaultSslContext() override { return nullptr; } - bool useProxyProto() override { return false; } - bool bindToPort() override { return true; } - bool useOriginalDst() override { return false; } - uint32_t perConnectionBufferLimitBytes() override { return 0; } - Stats::Scope& listenerScope() override { return stats_store_; } - uint64_t listenerTag() const override { return socket2_ ? 2 : 1; } - const std::string& name() const override { return name_; } + class TestListener : public Listener, public LinkedObject { + public: + TestListener(ConnectionHandlerTest& parent, uint64_t tag, bool bind_to_port, + bool use_original_dst, const std::string& name) + : parent_(parent), tag_(tag), bind_to_port_(bind_to_port), + use_original_dst_(use_original_dst), name_(name) {} + + Network::FilterChainFactory& filterChainFactory() override { return parent_.factory_; } + Network::ListenSocket& socket() override { return socket_; } + Ssl::ServerContext* defaultSslContext() override { return nullptr; } + bool useProxyProto() override { return false; } + bool bindToPort() override { return bind_to_port_; } + bool useOriginalDst() override { return use_original_dst_; } + uint32_t perConnectionBufferLimitBytes() override { return 0; } + Stats::Scope& listenerScope() override { return parent_.stats_store_; } + uint64_t listenerTag() const override { return tag_; } + const std::string& name() const override { return name_; } + + ConnectionHandlerTest& parent_; + Network::MockListenSocket socket_; + uint64_t tag_; + bool bind_to_port_; + bool use_original_dst_; + const std::string name_; + }; + + typedef std::unique_ptr TestListenerPtr; + + TestListener* addListener(uint64_t tag, bool bind_to_port, bool use_original_dst, + const std::string& name) { + TestListener* listener = new TestListener(*this, tag, bind_to_port, use_original_dst, name); + listener->moveIntoListBack(TestListenerPtr{listener}, listeners_); + return listener; + } Stats::IsolatedStoreImpl stats_store_; NiceMock dispatcher_; Network::ConnectionHandlerPtr handler_; - Network::MockFilterChainFactory factory_; - NiceMock socket_; - std::string name_; - Network::MockListenSocket* socket2_; + NiceMock factory_; + std::list listeners_; }; TEST_F(ConnectionHandlerTest, RemoveListener) { @@ -61,10 +80,12 @@ TEST_F(ConnectionHandlerTest, RemoveListener) { return listener; })); - handler_->addListener(*this); + TestListener* test_listener = addListener(1, true, false, "test_listener"); + EXPECT_CALL(test_listener->socket_, localAddress()); + handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(_)).WillOnce(Return(true)); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -97,10 +118,12 @@ TEST_F(ConnectionHandlerTest, DestroyCloseConnections) { return listener; })); - handler_->addListener(*this); + TestListener* test_listener = addListener(1, true, false, "test_listener"); + EXPECT_CALL(test_listener->socket_, localAddress()); + handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(_)).WillOnce(Return(true)); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -122,10 +145,12 @@ TEST_F(ConnectionHandlerTest, CloseDuringFilterChainCreate) { return listener; })); - handler_->addListener(*this); + TestListener* test_listener = addListener(1, true, false, "test_listener"); + EXPECT_CALL(test_listener->socket_, localAddress()); + handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(_)); + EXPECT_CALL(factory_, createFilterChain(A())); EXPECT_CALL(*connection, state()).WillOnce(Return(Network::Connection::State::Closed)); EXPECT_CALL(*connection, addConnectionCallbacks(_)).Times(0); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); @@ -146,10 +171,12 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { return listener; })); - handler_->addListener(*this); + TestListener* test_listener = addListener(1, true, false, "test_listener"); + EXPECT_CALL(test_listener->socket_, localAddress()); + handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(_)).WillOnce(Return(false)); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(false)); EXPECT_CALL(*connection, close(Network::ConnectionCloseType::NoFlush)); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); EXPECT_EQ(0UL, handler_->numConnections()); @@ -158,40 +185,31 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { } TEST_F(ConnectionHandlerTest, FindListenerByAddress) { + TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); Network::Address::InstanceConstSharedPtr alt_address( new Network::Address::Ipv4Instance("127.0.0.1", 10001)); - EXPECT_CALL(socket_, localAddress()).WillRepeatedly(Return(alt_address)); Network::MockListener* listener = new Network::MockListener(); - Network::ListenerCallbacks* listener_callbacks; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener; - - })); - handler_->addListener(*this); + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, + bool) -> Network::Listener* { return listener; })); + EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(alt_address)); + handler_->addListener(*test_listener1); EXPECT_EQ(listener, handler_->findListenerByAddress(ByRef(*alt_address))); - Network::MockListenSocket socket2; + TestListener* test_listener2 = addListener(2, true, false, "test_listener2"); Network::Address::InstanceConstSharedPtr alt_address2( new Network::Address::Ipv4Instance("0.0.0.0", 10001)); Network::Address::InstanceConstSharedPtr alt_address3( new Network::Address::Ipv4Instance("127.0.0.2", 10001)); - EXPECT_CALL(socket2, localAddress()).WillRepeatedly(Return(alt_address2)); Network::MockListener* listener2 = new Network::MockListener(); EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener2; - - })); - socket2_ = &socket2; - handler_->addListener(*this); + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, + bool) -> Network::Listener* { return listener2; })); + EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(alt_address2)); + handler_->addListener(*test_listener2); EXPECT_EQ(listener, handler_->findListenerByAddress(ByRef(*alt_address))); EXPECT_EQ(listener2, handler_->findListenerByAddress(ByRef(*alt_address2))); @@ -205,19 +223,228 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { handler_->stopListeners(2); Network::MockListener* listener3 = new Network::MockListener(); + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, + bool) -> Network::Listener* { return listener3; })); + handler_->addListener(*test_listener2); + + EXPECT_EQ(listener3, handler_->findListenerByAddress(ByRef(*alt_address2))); + EXPECT_EQ(listener3, handler_->findListenerByAddress(ByRef(*alt_address3))); + + EXPECT_CALL(*listener3, onDestroy()); +} + +class TestFilter : public Network::ListenerFilter { +public: + MOCK_METHOD1(onAccept, Network::FilterStatus(Network::ListenerFilterCallbacks&)); +}; + +TEST_F(ConnectionHandlerTest, NormalRedirect) { + // 'false' for use_original_dst since we add a mock filter manually below. + TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + Network::MockListener* listener1 = new Network::MockListener(); + Network::ListenerCallbacks* listener_callbacks1; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) .WillOnce(Invoke( [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener3; + listener_callbacks1 = &cb; + return listener1; + })); + Network::Address::InstanceConstSharedPtr normal_address( + new Network::Address::Ipv4Instance("127.0.0.1", 10001)); + EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(normal_address)); + handler_->addListener(*test_listener1); + TestListener* test_listener2 = addListener(1, false, false, "test_listener2"); + Network::MockListener* listener2 = new Network::MockListener(); + Network::ListenerCallbacks* listener_callbacks2; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks2 = &cb; + return listener2; })); - handler_->addListener(*this); + Network::Address::InstanceConstSharedPtr alt_address( + new Network::Address::Ipv4Instance("127.0.0.2", 20002)); + EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(alt_address)); + handler_->addListener(*test_listener2); + + TestFilter* test_filter = new TestFilter(); + Network::MockAcceptSocket* accept_socket = new NiceMock(); + bool redirected = false; + EXPECT_CALL(factory_, createFilterChain(A())) + .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { + // Insert the Mock filter. + if (!redirected) { + manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + redirected = true; + } + return true; + })); + EXPECT_CALL(*test_filter, onAccept(_)) + .WillOnce(Invoke([&](Network::ListenerFilterCallbacks& cb) -> Network::FilterStatus { + cb.socket().resetLocalAddress(alt_address); + return Network::FilterStatus::Continue; + })); + EXPECT_CALL(*accept_socket, resetLocalAddress(alt_address)); + EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(alt_address)); + EXPECT_CALL(*accept_socket, clearReset()); + Network::MockConnection* connection = new NiceMock(); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + EXPECT_EQ(1UL, handler_->numConnections()); - EXPECT_EQ(listener3, handler_->findListenerByAddress(ByRef(*alt_address2))); - EXPECT_EQ(listener3, handler_->findListenerByAddress(ByRef(*alt_address3))); + EXPECT_CALL(*listener2, onDestroy()); + EXPECT_CALL(*listener1, onDestroy()); +} - EXPECT_CALL(*listener3, onDestroy()); +TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { + // 'false' for use_original_dst since we add a mock filter manually below. + TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + Network::MockListener* listener1 = new Network::MockListener(); + Network::ListenerCallbacks* listener_callbacks1; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); + Network::Address::InstanceConstSharedPtr normal_address( + new Network::Address::Ipv4Instance("127.0.0.1", 10001)); + EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(normal_address)); + handler_->addListener(*test_listener1); + + TestListener* test_listener2 = addListener(1, false, false, "test_listener2"); + Network::MockListener* listener2 = new Network::MockListener(); + Network::ListenerCallbacks* listener_callbacks2; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks2 = &cb; + return listener2; + })); + Network::Address::InstanceConstSharedPtr any_address = Network::Utility::getIpv4AnyAddress(); + EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(any_address)); + handler_->addListener(*test_listener2); + + TestFilter* test_filter = new TestFilter(); + Network::MockAcceptSocket* accept_socket = new NiceMock(); + bool redirected = false; + EXPECT_CALL(factory_, createFilterChain(A())) + .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { + // Insert the Mock filter. + if (!redirected) { + manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + redirected = true; + } + return true; + })); + // Zero port to match the port of AnyAddress + Network::Address::InstanceConstSharedPtr alt_address( + new Network::Address::Ipv4Instance("127.0.0.2", 0)); + EXPECT_CALL(*test_filter, onAccept(_)) + .WillOnce(Invoke([&](Network::ListenerFilterCallbacks& cb) -> Network::FilterStatus { + cb.socket().resetLocalAddress(alt_address); + return Network::FilterStatus::Continue; + })); + EXPECT_CALL(*accept_socket, resetLocalAddress(alt_address)); + EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(alt_address)); + EXPECT_CALL(*accept_socket, clearReset()); + Network::MockConnection* connection = new NiceMock(); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + EXPECT_EQ(1UL, handler_->numConnections()); + + EXPECT_CALL(*listener2, onDestroy()); + EXPECT_CALL(*listener1, onDestroy()); +} + +TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { + // 'false' for use_original_dst since we add a mock filter manually below. + TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + Network::MockListener* listener1 = new Network::MockListener(); + Network::ListenerCallbacks* listener_callbacks1; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); + Network::Address::InstanceConstSharedPtr normal_address( + new Network::Address::Ipv4Instance("127.0.0.1", 80)); + // Original dst address nor port number match that of the listener's address. + Network::Address::InstanceConstSharedPtr original_dst_address( + new Network::Address::Ipv4Instance("127.0.0.2", 8080)); + Network::Address::InstanceConstSharedPtr any_address = Network::Utility::getAddressWithPort( + *Network::Utility::getIpv4AnyAddress(), normal_address->ip()->port()); + EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(any_address)); + handler_->addListener(*test_listener1); + + TestFilter* test_filter = new TestFilter(); + Network::MockAcceptSocket* accept_socket = new NiceMock(); + EXPECT_CALL(factory_, createFilterChain(A())) + .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { + // Insert the Mock filter. + manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + return true; + })); + EXPECT_CALL(*test_filter, onAccept(_)) + .WillOnce(Invoke([&](Network::ListenerFilterCallbacks& cb) -> Network::FilterStatus { + cb.socket().resetLocalAddress(original_dst_address); + return Network::FilterStatus::Continue; + })); + EXPECT_CALL(*accept_socket, resetLocalAddress(original_dst_address)); + EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(original_dst_address)); + Network::MockConnection* connection = new NiceMock(); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + EXPECT_EQ(1UL, handler_->numConnections()); + + EXPECT_CALL(*listener1, onDestroy()); +} + +TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { + // 'false' for use_original_dst since we add a mock filter manually below. + TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + Network::MockListener* listener1 = new Network::MockListener(); + Network::ListenerCallbacks* listener_callbacks1; + EXPECT_CALL(dispatcher_, createListener_(_, _, _)) + .WillOnce(Invoke( + [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); + Network::Address::InstanceConstSharedPtr normal_address( + new Network::Address::Ipv4Instance("127.0.0.1", 80)); + Network::Address::InstanceConstSharedPtr any_address = Network::Utility::getAddressWithPort( + *Network::Utility::getIpv4AnyAddress(), normal_address->ip()->port()); + EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(any_address)); + handler_->addListener(*test_listener1); + + TestFilter* test_filter = new TestFilter(); + Network::MockAcceptSocket* accept_socket = new NiceMock(); + EXPECT_CALL(factory_, createFilterChain(A())) + .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { + // Insert the Mock filter. + manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + return true; + })); + EXPECT_CALL(*test_filter, onAccept(_)).WillOnce(Return(Network::FilterStatus::Continue)); + EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(false)); + EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(normal_address)); + Network::MockConnection* connection = new NiceMock(); + EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + EXPECT_EQ(1UL, handler_->numConnections()); + + EXPECT_CALL(*listener1, onDestroy()); } } // namespace Server diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 42decc20025c2..14f9b53c34521 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -101,6 +101,13 @@ class ListenerManagerImplWithRealFiltersTest : public ListenerManagerImplTest { -> std::vector { return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); })); + ON_CALL(listener_factory_, createListenerFilterFactoryList(_, _)) + .WillByDefault(Invoke([this]( + const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) + -> std::vector { + return ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, context); + })); } }; From 6874568468fab7a15c70a46d4216aff9415be15d Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 11 Jan 2018 11:44:51 -0800 Subject: [PATCH 03/41] Style fixes. Signed-off-by: Jarno Rajahalme --- include/envoy/server/filter_config.h | 4 ++-- source/common/config/well_known_names.h | 5 ++--- source/common/filter/proxy_protocol.cc | 11 +++++++---- source/server/http/admin.h | 6 +++--- source/server/listener_manager_impl.cc | 2 +- source/server/server.cc | 2 +- test/server/http/admin_test.cc | 10 +++++----- test/server/worker_impl_test.cc | 2 +- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/envoy/server/filter_config.h b/include/envoy/server/filter_config.h index 427e26fc176a9..8a38c3c69b024 100644 --- a/include/envoy/server/filter_config.h +++ b/include/envoy/server/filter_config.h @@ -142,9 +142,9 @@ class NamedListenerFilterConfigFactory { virtual ~NamedListenerFilterConfigFactory() {} /** - * Create a particular listener filter factory implementation. If the implementation is unable to + * Create a particular listener filter factory implementation. If the implementation is unable to * produce a factory with the provided parameters, it should throw an EnvoyException in the case - * of general error or a Json::Exception if the json configuration is erroneous. The returned + * of general error or a Json::Exception if the json configuration is erroneous. The returned * callback should always be initialized. * @param config supplies the general json configuration for the filter * @param context supplies the filter's context. diff --git a/source/common/config/well_known_names.h b/source/common/config/well_known_names.h index c3aefd88aab5b..68558de41ac75 100644 --- a/source/common/config/well_known_names.h +++ b/source/common/config/well_known_names.h @@ -60,12 +60,11 @@ class ListenerFilterNameValues { // Converts names from v1 to v2 const V1Converter v1_converter_; - ListenerFilterNameValues() - : v1_converter_({ORIGINAL_DST, PROXY_PROTOCOL}) {} + ListenerFilterNameValues() : v1_converter_({ORIGINAL_DST, PROXY_PROTOCOL}) {} }; typedef ConstSingleton ListenerFilterNames; - + /** * Well-known network filter names. */ diff --git a/source/common/filter/proxy_protocol.cc b/source/common/filter/proxy_protocol.cc index 0ce181df17938..b4baaad91ff07 100644 --- a/source/common/filter/proxy_protocol.cc +++ b/source/common/filter/proxy_protocol.cc @@ -69,13 +69,16 @@ void Instance::onReadWorker() { if (line_parts[1] == "UNKNOWN") { // At this point we know it's a proxy protocol line, so we can remove it from the socket // and continue. - Network::Address::InstanceConstSharedPtr local_address = Envoy::Network::Address::addressFromFd(socket.fd()); + Network::Address::InstanceConstSharedPtr local_address = + Envoy::Network::Address::addressFromFd(socket.fd()); Network::Address::InstanceConstSharedPtr remote_address; // The remote address not known. if (local_address->ip()->version() == Network::Address::IpVersion::v4) { - remote_address = std::make_shared(Network::Address::Ipv4Instance("0.0.0.0")); + remote_address = std::make_shared( + Network::Address::Ipv4Instance("0.0.0.0")); } else { - remote_address = std::make_shared(Network::Address::Ipv6Instance("::")); + remote_address = + std::make_shared(Network::Address::Ipv6Instance("::")); } finishConnection(remote_address, local_address); return; @@ -123,7 +126,7 @@ void Instance::onReadWorker() { } void Instance::finishConnection(Network::Address::InstanceConstSharedPtr remote_address, - Network::Address::InstanceConstSharedPtr local_address) { + Network::Address::InstanceConstSharedPtr local_address) { Network::AcceptSocket& socket = cb_->socket(); socket.resetLocalAddress(local_address); diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 3a0aa20dea3cf..6e12dcb2f3794 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -158,9 +158,9 @@ class AdminImpl : public Admin, class AdminListener : public Server::Listener { public: - AdminListener(AdminImpl& parent, Stats::ScopePtr&& listener_scope) : parent_(parent), - name_("admin"), scope_(std::move(listener_scope)), - stats_(Http::ConnectionManagerImpl::generateListenerStats("http.admin.", *scope_)) {} + AdminListener(AdminImpl& parent, Stats::ScopePtr&& listener_scope) + : parent_(parent), name_("admin"), scope_(std::move(listener_scope)), + stats_(Http::ConnectionManagerImpl::generateListenerStats("http.admin.", *scope_)) {} // Server::Listener Network::FilterChainFactory& filterChainFactory() override { return parent_; } diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index 86fe57f5fcb9c..86a3abb2f2558 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -137,7 +137,7 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag if (config.listener_filters().size()) { listener_filter_factories_ = - parent_.factory_.createListenerFilterFactoryList(config.listener_filters(), *this); + parent_.factory_.createListenerFilterFactoryList(config.listener_filters(), *this); } // Skip lookup and update of the SSL Context if there is only one filter chain diff --git a/source/server/server.cc b/source/server/server.cc index 3246768410aa5..516ee3f6b2c6f 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -219,7 +219,7 @@ void InstanceImpl::initialize(Options& options, original_start_time_ = info.original_start_time_; admin_.reset(new AdminImpl(initial_config.admin().accessLogPath(), initial_config.admin().profilePath(), options.adminAddressPath(), - initial_config.admin().address(), *this, + initial_config.admin().address(), *this, stats_store_.createScope("listener.admin."))); handler_->addListener(admin_->listener()); diff --git a/test/server/http/admin_test.cc b/test/server/http/admin_test.cc index e04a2f0e0f4e5..e4d7a4a213701 100644 --- a/test/server/http/admin_test.cc +++ b/test/server/http/admin_test.cc @@ -70,7 +70,7 @@ class AdminInstanceTest : public testing::TestWithParam Date: Thu, 11 Jan 2018 12:28:47 -0800 Subject: [PATCH 04/41] test: Add missing 'override' keyword. Signed-off-by: Jarno Rajahalme --- test/mocks/event/mocks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 3473b06b31799..8eff048a0939f 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -30,7 +30,7 @@ class MockDispatcher : public Dispatcher { ~MockDispatcher(); Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, - Ssl::Context* ssl_ctx) { + Ssl::Context* ssl_ctx) override { return Network::ConnectionPtr{createConnection_(accept_socket.get(), ssl_ctx)}; } From 0a8fd6f36c013f7f8e537a65004628556cfe682e Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 11 Jan 2018 13:03:29 -0800 Subject: [PATCH 05/41] test: Remove unused 'this' lambda capture. Signed-off-by: Jarno Rajahalme --- test/server/listener_manager_impl_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 14f9b53c34521..443212c975438 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -102,7 +102,7 @@ class ListenerManagerImplWithRealFiltersTest : public ListenerManagerImplTest { return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); })); ON_CALL(listener_factory_, createListenerFilterFactoryList(_, _)) - .WillByDefault(Invoke([this]( + .WillByDefault(Invoke([]( const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context) -> std::vector { From da0c39b5141f9d3e9fcf9f72841fbb874924fcf6 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 11 Jan 2018 14:33:29 -0800 Subject: [PATCH 06/41] test: Fix format. Signed-off-by: Jarno Rajahalme --- test/server/listener_manager_impl_test.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 443212c975438..6981c58207622 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -102,9 +102,8 @@ class ListenerManagerImplWithRealFiltersTest : public ListenerManagerImplTest { return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); })); ON_CALL(listener_factory_, createListenerFilterFactoryList(_, _)) - .WillByDefault(Invoke([]( - const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) + .WillByDefault(Invoke([](const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) -> std::vector { return ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, context); })); From 044a089e43326ca6b37b0a2e4c6573045f642850 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 11 Jan 2018 19:58:19 -0800 Subject: [PATCH 07/41] filter/original_dst: Increase log level. Change info to debubg level. Signed-off-by: Jarno Rajahalme --- source/common/filter/original_dst.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common/filter/original_dst.cc b/source/common/filter/original_dst.cc index b85f03dd5cb0e..01e6ea951ecac 100644 --- a/source/common/filter/original_dst.cc +++ b/source/common/filter/original_dst.cc @@ -13,7 +13,7 @@ Network::Address::InstanceConstSharedPtr OriginalDst::getOriginalDst(int fd) { } Network::FilterStatus OriginalDst::onAccept(Network::ListenerFilterCallbacks& cb) { - ENVOY_LOG(info, "original_dst: New connection accepted"); + ENVOY_LOG(debug, "original_dst: New connection accepted"); Network::AcceptSocket& socket = cb.socket(); Network::Address::InstanceConstSharedPtr local_address = socket.localAddress(); From d97257adb4bf5586cd62e71da1f65f3c9586b16f Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 11 Jan 2018 20:00:31 -0800 Subject: [PATCH 08/41] listener filters: Implement proto initializers. Signed-off-by: Jarno Rajahalme --- source/server/config/network/original_dst.cc | 11 +++++++++++ source/server/config/network/proxy_protocol.cc | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/source/server/config/network/original_dst.cc b/source/server/config/network/original_dst.cc index 8ee7e55129abe..28d92437d9a96 100644 --- a/source/server/config/network/original_dst.cc +++ b/source/server/config/network/original_dst.cc @@ -22,6 +22,17 @@ class OriginalDstConfigFactory : public NamedListenerFilterConfigFactory { }; } + ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, + FactoryContext&) override { + return [](Network::ListenerFilterManager& filter_manager) -> void { + filter_manager.addAcceptFilter(Network::ListenerFilterSharedPtr{new Filter::OriginalDst()}); + }; + } + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + } + std::string name() override { return Config::ListenerFilterNames::get().ORIGINAL_DST; } }; diff --git a/source/server/config/network/proxy_protocol.cc b/source/server/config/network/proxy_protocol.cc index 99e6c71280125..dcc70a165d855 100644 --- a/source/server/config/network/proxy_protocol.cc +++ b/source/server/config/network/proxy_protocol.cc @@ -26,6 +26,20 @@ class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { }; } + ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, + FactoryContext& context) override { + Filter::ProxyProtocol::ConfigSharedPtr config( + new Filter::ProxyProtocol::Config(context.scope())); + return [config](Network::ListenerFilterManager& filter_manager) -> void { + filter_manager.addAcceptFilter( + Network::ListenerFilterSharedPtr{new Filter::ProxyProtocol::Instance(config)}); + }; + } + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + } + std::string name() override { return Config::ListenerFilterNames::get().PROXY_PROTOCOL; } }; From c6f4fb228a6c3c080092900de83ac76397f04aca Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 17:46:35 -0800 Subject: [PATCH 09/41] test: Add Listener filter mocks. Signed-off-by: Jarno Rajahalme --- test/mocks/network/mocks.cc | 9 +++++++++ test/mocks/network/mocks.h | 26 ++++++++++++++++++++++++++ test/server/connection_handler_test.cc | 13 ++++--------- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index 63e7e9ef27bfd..a2ec909a4453e 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -144,6 +144,15 @@ MockListenerCallbacks::~MockListenerCallbacks() {} MockDrainDecision::MockDrainDecision() {} MockDrainDecision::~MockDrainDecision() {} +MockListenerFilter::MockListenerFilter() {} +MockListenerFilter::~MockListenerFilter() {} + +MockListenerFilterCallbacks::MockListenerFilterCallbacks() {} +MockListenerFilterCallbacks::~MockListenerFilterCallbacks() {} + +MockListenerFilterManager::MockListenerFilterManager() {} +MockListenerFilterManager::~MockListenerFilterManager() {} + MockFilterChainFactory::MockFilterChainFactory() { ON_CALL(*this, createFilterChain(A())).WillByDefault(Return(true)); } diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index f2e93b166c1c6..857844366167f 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -208,6 +208,32 @@ class MockDrainDecision : public DrainDecision { MOCK_CONST_METHOD0(drainClose, bool()); }; +class MockListenerFilter : public Network::ListenerFilter { +public: + MockListenerFilter(); + ~MockListenerFilter(); + + MOCK_METHOD1(onAccept, Network::FilterStatus(Network::ListenerFilterCallbacks&)); +}; + +class MockListenerFilterCallbacks : public ListenerFilterCallbacks { +public: + MockListenerFilterCallbacks(); + ~MockListenerFilterCallbacks(); + + MOCK_METHOD0(socket, AcceptSocket&()); + MOCK_METHOD0(dispatcher, Event::Dispatcher&()); + MOCK_METHOD1(continueFilterChain, void(bool)); +}; + +class MockListenerFilterManager : public ListenerFilterManager { +public: + MockListenerFilterManager(); + ~MockListenerFilterManager(); + + MOCK_METHOD1(addAcceptFilter, void(Network::ListenerFilterSharedPtr)); +}; + class MockFilterChainFactory : public FilterChainFactory { public: MockFilterChainFactory(); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 6c2639694b8c8..d89194b272d12 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -234,11 +234,6 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { EXPECT_CALL(*listener3, onDestroy()); } -class TestFilter : public Network::ListenerFilter { -public: - MOCK_METHOD1(onAccept, Network::FilterStatus(Network::ListenerFilterCallbacks&)); -}; - TEST_F(ConnectionHandlerTest, NormalRedirect) { // 'false' for use_original_dst since we add a mock filter manually below. TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); @@ -269,7 +264,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(alt_address)); handler_->addListener(*test_listener2); - TestFilter* test_filter = new TestFilter(); + Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptSocket* accept_socket = new NiceMock(); bool redirected = false; EXPECT_CALL(factory_, createFilterChain(A())) @@ -329,7 +324,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(any_address)); handler_->addListener(*test_listener2); - TestFilter* test_filter = new TestFilter(); + Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptSocket* accept_socket = new NiceMock(); bool redirected = false; EXPECT_CALL(factory_, createFilterChain(A())) @@ -384,7 +379,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(any_address)); handler_->addListener(*test_listener1); - TestFilter* test_filter = new TestFilter(); + Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptSocket* accept_socket = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { @@ -427,7 +422,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(any_address)); handler_->addListener(*test_listener1); - TestFilter* test_filter = new TestFilter(); + Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptSocket* accept_socket = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { From a7845dba689e4e8e59049c8a7ae6dc1e24828799 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 23:28:50 -0800 Subject: [PATCH 10/41] listener: Use ListenerFilter type, drop v1 support. Sync with the API change to a separate ListenerFilter type. Drop API v1 support. Signed-off-by: Jarno Rajahalme --- .../original-dst-cluster/proxy_config.json | 5 +-- include/envoy/server/filter_config.h | 17 ++------ include/envoy/server/listener_manager.h | 6 +-- source/common/config/lds_json.cc | 20 ---------- source/common/config/well_known_names.h | 5 --- source/common/json/config_schemas.cc | 9 ----- source/server/config/network/original_dst.cc | 6 --- .../server/config/network/proxy_protocol.cc | 10 ----- source/server/config_validation/server.h | 6 +-- source/server/listener_manager_impl.cc | 39 ++++++------------- source/server/listener_manager_impl.h | 8 ++-- test/config_test/config_test.cc | 13 ++++--- test/mocks/server/mocks.h | 2 +- test/server/listener_manager_impl_test.cc | 12 +++--- 14 files changed, 41 insertions(+), 117 deletions(-) diff --git a/configs/original-dst-cluster/proxy_config.json b/configs/original-dst-cluster/proxy_config.json index 793f5c6be0ce5..c6b2627074d2c 100644 --- a/configs/original-dst-cluster/proxy_config.json +++ b/configs/original-dst-cluster/proxy_config.json @@ -1,10 +1,7 @@ { "listeners": [{ "address": "tcp://0.0.0.0:10000", - "listener_filters": [{ - "name": "original_dst", - "config": {} - }], + "use_original_dst": true, "filters": [{ "name": "http_connection_manager", "config": { diff --git a/include/envoy/server/filter_config.h b/include/envoy/server/filter_config.h index 8a38c3c69b024..c3c09b28af9b6 100644 --- a/include/envoy/server/filter_config.h +++ b/include/envoy/server/filter_config.h @@ -146,23 +146,12 @@ class NamedListenerFilterConfigFactory { * produce a factory with the provided parameters, it should throw an EnvoyException in the case * of general error or a Json::Exception if the json configuration is erroneous. The returned * callback should always be initialized. - * @param config supplies the general json configuration for the filter + * @param config supplies the general protobuf configuration for the filter * @param context supplies the filter's context. * @return ListenerFilterFactoryCb the factory creation function. */ - virtual ListenerFilterFactoryCb createFilterFactory(const Json::Object& config, - FactoryContext& context) PURE; - - /** - * v2 variant of createFilterFactory(..), where filter configs are specified as proto. This may be - * optionally implemented today, but will in the future become compulsory once v1 is deprecated. - */ virtual ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message& config, - FactoryContext& context) { - UNREFERENCED_PARAMETER(config); - UNREFERENCED_PARAMETER(context); - NOT_IMPLEMENTED; - } + FactoryContext& context) PURE; /** * @return ProtobufTypes::MessagePtr create empty config proto message for v2. The filter @@ -170,7 +159,7 @@ class NamedListenerFilterConfigFactory { * JSON and then parsed into this empty proto. Optional today, will be compulsory when v1 * is deprecated. */ - virtual ProtobufTypes::MessagePtr createEmptyConfigProto() { return nullptr; } + virtual ProtobufTypes::MessagePtr createEmptyConfigProto() PURE; /** * @return std::string the identifying name for a particular implementation of a listener filter diff --git a/include/envoy/server/listener_manager.h b/include/envoy/server/listener_manager.h index 3c67c39c53690..02e271aa40a9b 100644 --- a/include/envoy/server/listener_manager.h +++ b/include/envoy/server/listener_manager.h @@ -46,9 +46,9 @@ class ListenerComponentFactory { * @param context supplies the factory creation context. * @return std::vector the list of filter factories. */ - virtual std::vector - createListenerFilterFactoryList(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) PURE; + virtual std::vector createListenerFilterFactoryList( + const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) PURE; /** * @return DrainManagerPtr a new drain manager. diff --git a/source/common/config/lds_json.cc b/source/common/config/lds_json.cc index 62d57e560c402..76860398bbeae 100644 --- a/source/common/config/lds_json.cc +++ b/source/common/config/lds_json.cc @@ -57,26 +57,6 @@ void LdsJson::translateListener(const Json::Object& json_listener, JSON_UTIL_SET_BOOL(json_listener, listener, use_original_dst); JSON_UTIL_SET_BOOL(json_listener, *listener.mutable_deprecated_v1(), bind_to_port); JSON_UTIL_SET_INTEGER(json_listener, listener, per_connection_buffer_limit_bytes); - - if (json_listener.hasObject("listener_filters")) { - for (const auto& json_filter : json_listener.getObjectArray("listener_filters", true)) { - auto* filter = listener.mutable_listener_filters()->Add(); - - // Translate v1 name to v2 name. - filter->set_name(Config::NetworkFilterNames::get().v1_converter_.getV2Name( - json_filter->getString("name"))); - JSON_UTIL_SET_STRING(*json_filter, *filter->mutable_deprecated_v1(), type); - - const std::string json_config = "{\"deprecated_v1\": true, \"value\": " + - json_filter->getObject("config")->asJsonString() + "}"; - - const auto status = - Protobuf::util::JsonStringToMessage(json_config, filter->mutable_config()); - // JSON schema has already validated that this is a valid JSON object. - ASSERT(status.ok()); - UNREFERENCED_PARAMETER(status); - } - } } } // namespace Config diff --git a/source/common/config/well_known_names.h b/source/common/config/well_known_names.h index 68558de41ac75..cffeaae654598 100644 --- a/source/common/config/well_known_names.h +++ b/source/common/config/well_known_names.h @@ -56,11 +56,6 @@ class ListenerFilterNameValues { const std::string ORIGINAL_DST = "envoy.original_dst"; // Proxy Protocol listener filter const std::string PROXY_PROTOCOL = "envoy.proxy_protocol"; - - // Converts names from v1 to v2 - const V1Converter v1_converter_; - - ListenerFilterNameValues() : v1_converter_({ORIGINAL_DST, PROXY_PROTOCOL}) {} }; typedef ConstSingleton ListenerFilterNames; diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index 457dfffeec8d7..1159922b949e2 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -161,15 +161,6 @@ const std::string Json::Schema::LISTENER_SCHEMA(R"EOF( "required": ["cert_chain_file", "private_key_file"], "additionalProperties": false }, - "listener_filters" : { - "type" : "object", - "properties" : { - "name" : { "type": "string" }, - "config": {"type" : "object"} - }, - "required": ["name", "config"], - "additionalProperties": false - }, "filters" : { "type" : "object", "properties" : { diff --git a/source/server/config/network/original_dst.cc b/source/server/config/network/original_dst.cc index 28d92437d9a96..44bbb1aad5055 100644 --- a/source/server/config/network/original_dst.cc +++ b/source/server/config/network/original_dst.cc @@ -16,12 +16,6 @@ namespace Configuration { class OriginalDstConfigFactory : public NamedListenerFilterConfigFactory { public: // NamedListenerFilterConfigFactory - ListenerFilterFactoryCb createFilterFactory(const Json::Object&, FactoryContext&) override { - return [](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(Network::ListenerFilterSharedPtr{new Filter::OriginalDst()}); - }; - } - ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext&) override { return [](Network::ListenerFilterManager& filter_manager) -> void { diff --git a/source/server/config/network/proxy_protocol.cc b/source/server/config/network/proxy_protocol.cc index dcc70a165d855..89adc3cd521f6 100644 --- a/source/server/config/network/proxy_protocol.cc +++ b/source/server/config/network/proxy_protocol.cc @@ -16,16 +16,6 @@ namespace Configuration { class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { public: // NamedListenerFilterConfigFactory - ListenerFilterFactoryCb createFilterFactory(const Json::Object&, - FactoryContext& context) override { - Filter::ProxyProtocol::ConfigSharedPtr config( - new Filter::ProxyProtocol::Config(context.scope())); - return [config](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter( - Network::ListenerFilterSharedPtr{new Filter::ProxyProtocol::Instance(config)}); - }; - } - ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext& context) override { Filter::ProxyProtocol::ConfigSharedPtr config( diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index fef5d2e2d2021..a069eb9f6a8f0 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -94,9 +94,9 @@ class ValidationInstance : Logger::Loggable, Configuration::FactoryContext& context) override { return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); } - std::vector - createListenerFilterFactoryList(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) override { + std::vector createListenerFilterFactoryList( + const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) override { return ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, context); } Network::ListenSocketSharedPtr createListenSocket(Network::Address::InstanceConstSharedPtr, diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index 86a3abb2f2558..da119e0c0c066 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -48,41 +48,26 @@ ProdListenerComponentFactory::createFilterFactoryList_( return ret; } -// Use a template to reduce code duplication from above? std::vector ProdListenerComponentFactory::createListenerFilterFactoryList_( - const Protobuf::RepeatedPtrField& filters, + const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context) { std::vector ret; for (ssize_t i = 0; i < filters.size(); i++) { - const std::string string_type = filters[i].deprecated_v1().type(); - const std::string string_name = filters[i].name(); - const auto& proto_config = filters[i].config(); - ENVOY_LOG(info, " listener filter #{}:", i); - ENVOY_LOG(info, " name: {}", string_name); - const Json::ObjectSharedPtr filter_config = MessageUtil::getJsonObjectFromMessage(proto_config); + const auto& proto_config = filters[i]; + const ProtobufTypes::String string_name = proto_config.name(); + ENVOY_LOG(debug, " filter #{}:", i); + ENVOY_LOG(debug, " name: {}", string_name); + const Json::ObjectSharedPtr filter_config = + MessageUtil::getJsonObjectFromMessage(proto_config.config()); + ENVOY_LOG(debug, " config: {}", filter_config->asJsonString()); // Now see if there is a factory that will accept the config. - Configuration::NamedListenerFilterConfigFactory* factory = - Registry::FactoryRegistry::getFactory( + auto& factory = + Config::Utility::getAndCheckFactory( string_name); - if (factory != nullptr) { - Configuration::ListenerFilterFactoryCb callback; - if (filter_config->getBoolean("deprecated_v1", false)) { - callback = factory->createFilterFactory(*filter_config->getObject("value", true), context); - } else { - auto message = factory->createEmptyConfigProto(); - if (!message) { - throw EnvoyException( - fmt::format("Filter factory for '{}' has unexpected proto config", string_name)); - } - MessageUtil::loadFromJson(filter_config->asJsonString(), *message); - callback = factory->createFilterFactoryFromProto(*message, context); - } - ret.push_back(callback); - } else { - throw EnvoyException(fmt::format("unable to create filter factory for '{}'", string_name)); - } + auto message = Config::Utility::translateToFactoryConfig(proto_config, factory); + ret.push_back(factory.createFilterFactoryFromProto(*message, context)); } return ret; } diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index d9ad445ecc0da..41a5704ba374d 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -34,7 +34,7 @@ class ProdListenerComponentFactory : public ListenerComponentFactory, * Static worker for createListenerFilterFactoryList() that can be used directly in tests. */ static std::vector createListenerFilterFactoryList_( - const Protobuf::RepeatedPtrField& filters, + const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context); // Server::ListenerComponentFactory @@ -43,9 +43,9 @@ class ProdListenerComponentFactory : public ListenerComponentFactory, Configuration::FactoryContext& context) override { return createFilterFactoryList_(filters, context); } - std::vector - createListenerFilterFactoryList(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) override { + std::vector createListenerFilterFactoryList( + const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) override { return createListenerFilterFactoryList_(filters, context); } diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index 99bf7609d52f9..d982ff8059438 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -54,12 +54,13 @@ class ConfigTest { return Server::ProdListenerComponentFactory::createFilterFactoryList_(filters, context); })); ON_CALL(component_factory_, createListenerFilterFactoryList(_, _)) - .WillByDefault(Invoke([&](const Protobuf::RepeatedPtrField& filters, - Server::Configuration::FactoryContext& context) - -> std::vector { - return Server::ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, - context); - })); + .WillByDefault( + Invoke([&](const Protobuf::RepeatedPtrField& filters, + Server::Configuration::FactoryContext& context) + -> std::vector { + return Server::ProdListenerComponentFactory::createListenerFilterFactoryList_( + filters, context); + })); try { main_config.initialize(bootstrap, server_, *cluster_manager_factory_); diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 8bd93152e71be..265d9cbbfe85c 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -152,7 +152,7 @@ class MockListenerComponentFactory : public ListenerComponentFactory { Configuration::FactoryContext& context)); MOCK_METHOD2(createListenerFilterFactoryList, std::vector( - const Protobuf::RepeatedPtrField&, + const Protobuf::RepeatedPtrField&, Configuration::FactoryContext& context)); MOCK_METHOD2(createListenSocket, Network::ListenSocketSharedPtr(Network::Address::InstanceConstSharedPtr address, diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 6981c58207622..76e56fc9fb260 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -102,11 +102,13 @@ class ListenerManagerImplWithRealFiltersTest : public ListenerManagerImplTest { return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); })); ON_CALL(listener_factory_, createListenerFilterFactoryList(_, _)) - .WillByDefault(Invoke([](const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) - -> std::vector { - return ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, context); - })); + .WillByDefault( + Invoke([](const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) + -> std::vector { + return ProdListenerComponentFactory::createListenerFilterFactoryList_(filters, + context); + })); } }; From f9c56504df3bac85e7414a24a780fb8754aadc3f Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 20:13:23 -0800 Subject: [PATCH 11/41] include: Fix comments. Signed-off-by: Jarno Rajahalme --- include/envoy/event/dispatcher.h | 6 ++---- include/envoy/network/filter.h | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 6181ff0326fe5..889a57aa0dc49 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -43,7 +43,7 @@ class Dispatcher { * @param accept_socket supplies a socket with an open file descriptor and connection metadata * to use for the connection. Takes ownership of the accept_socket. * @param ssl_ctx supplies the SSL context to use, if not nullptr. - * @return Network::ConnectionPtr a client connection that is owned by the caller. + * @return Network::ConnectionPtr a server connection that is owned by the caller. */ virtual Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, Ssl::Context* ssl_ctx) PURE; @@ -88,11 +88,9 @@ class Dispatcher { /** * Create a listener on a specific port. - * @param conn_handler supplies the handler for connections received by the listener * @param socket supplies the socket to listen on. * @param cb supplies the callbacks to invoke for listener events. - * @param scope supplies the Stats::Scope to use. - * @param listener_options listener configuration options. + * @param bind_to_port controls whether the listener binds to a transport port or not. * @return Network::ListenerPtr a new listener that is owned by the caller. */ virtual Network::ListenerPtr createListener(Network::ListenSocket& socket, diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index fb1787e57d2d6..45112acd45948 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -167,9 +167,9 @@ class ListenerFilterCallbacks { virtual Event::Dispatcher& dispatcher() PURE; /** - * If an filter stopped filter iteration by returning FilterStatus::StopIteration, + * If a filter stopped filter iteration by returning FilterStatus::StopIteration, * the filter should call continueFilterChain(true) when complete to continue the filter chain, - * or continueFilterChain(false) if the filter execution failed and the connection musrt be + * or continueFilterChain(false) if the filter execution failed and the connection must be * closed. * @param success boolean telling whether the filter execution was successful or not. */ From d42ce02183efb7e7b93839cc8b4e1854fcba75df Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 20:44:03 -0800 Subject: [PATCH 12/41] dispatcher: Rename createConnection() as createServerConnection(). Rename createConnection() as createServerConnection(), rhymes with createClientConnection(). Requested-by: Matt Klein Signed-off-by: Jarno Rajahalme --- include/envoy/event/dispatcher.h | 4 ++-- source/common/event/dispatcher_impl.cc | 4 ++-- source/common/event/dispatcher_impl.h | 4 ++-- source/server/connection_handler_impl.cc | 4 ++-- test/common/http/codec_client_test.cc | 2 +- test/common/network/connection_impl_test.cc | 8 ++++---- test/common/network/dns_impl_test.cc | 2 +- test/common/network/listener_impl_test.cc | 6 +++--- test/common/ssl/ssl_socket_test.cc | 21 +++++++++++---------- test/mocks/event/mocks.h | 8 ++++---- test/server/connection_handler_test.cc | 8 ++++---- 11 files changed, 36 insertions(+), 35 deletions(-) diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 889a57aa0dc49..a4ac9d239adc5 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -45,8 +45,8 @@ class Dispatcher { * @param ssl_ctx supplies the SSL context to use, if not nullptr. * @return Network::ConnectionPtr a server connection that is owned by the caller. */ - virtual Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, - Ssl::Context* ssl_ctx) PURE; + virtual Network::ConnectionPtr createServerConnection(Network::AcceptSocketPtr&& accept_socket, + Ssl::Context* ssl_ctx) PURE; /** * Create a client connection. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index a070b0d91e7fa..ca0718cc335d8 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -73,8 +73,8 @@ void DispatcherImpl::clearDeferredDeleteList() { deferred_deleting_ = false; } -Network::ConnectionPtr DispatcherImpl::createConnection(Network::AcceptSocketPtr&& socket, - Ssl::Context* ssl_ctx) { +Network::ConnectionPtr DispatcherImpl::createServerConnection(Network::AcceptSocketPtr&& socket, + Ssl::Context* ssl_ctx) { ASSERT(isThreadSafe()); return Network::ConnectionPtr{ ssl_ctx ? new Ssl::ConnectionImpl( diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 027e34e1eed9a..36ea8f3fdd311 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -33,8 +33,8 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { // Event::Dispatcher void clearDeferredDeleteList() override; - Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, - Ssl::Context* ssl_ctx) override; + Network::ConnectionPtr createServerConnection(Network::AcceptSocketPtr&& accept_socket, + Ssl::Context* ssl_ctx) override; Network::ClientConnectionPtr createClientConnection(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 3e61c015a2c1f..58012f58577e3 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -181,8 +181,8 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptSocketPtr&& void ConnectionHandlerImpl::ActiveListener::newConnection( Network::AcceptSocketPtr&& accept_socket) { - Network::ConnectionPtr new_connection = - parent_.dispatcher_.createConnection(std::move(accept_socket), config_.defaultSslContext()); + Network::ConnectionPtr new_connection = parent_.dispatcher_.createServerConnection( + std::move(accept_socket), config_.defaultSslContext()); new_connection->setBufferLimits(config_.perConnectionBufferLimitBytes()); onNewConnection(std::move(new_connection)); } diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index f26849651261e..db811b181008f 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -191,7 +191,7 @@ class CodecNetworkTest : public testing::TestWithParam void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), nullptr); + dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); })); diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index 64fc96fa895ef..01889b51747d1 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -101,7 +101,7 @@ class ConnectionImplTest : public testing::TestWithParam { EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), nullptr); + dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) @@ -196,7 +196,7 @@ TEST_P(ConnectionImplTest, CloseDuringConnectCallback) { EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), nullptr); + dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) @@ -250,7 +250,7 @@ TEST_P(ConnectionImplTest, ConnectionStats) { EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), nullptr); + dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(listener_callbacks_, onNewConnection_(_)) @@ -767,7 +767,7 @@ class ReadBufferLimitTest : public ConnectionImplTest { EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), nullptr); + dispatcher_->createServerConnection(std::move(socket), nullptr); new_connection->setBufferLimits(read_buffer_limit); listener_callbacks_.onNewConnection(std::move(new_connection)); })); diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 57b1e14db40e9..15ab1a66e52d4 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -202,7 +202,7 @@ class TestDnsServer : public ListenerCallbacks { void onAccept(AcceptSocketPtr&& socket) override { Network::ConnectionPtr new_connection = - dispatcher_.createConnection(std::move(socket), nullptr); + dispatcher_.createServerConnection(std::move(socket), nullptr); onNewConnection(std::move(new_connection)); } diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index b06ad3328bd36..3869825d5e865 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -37,7 +37,7 @@ static void errorCallbackTest(Address::IpVersion version) { EXPECT_CALL(listener_callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), nullptr); + dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(listener_callbacks, onNewConnection_(_)) @@ -103,7 +103,7 @@ TEST_P(ListenerImplTest, UseActualDst) { EXPECT_CALL(listener_callbacks1, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), nullptr); + dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks1.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(listener_callbacks1, onNewConnection_(_)) @@ -138,7 +138,7 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { EXPECT_CALL(listener_callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), nullptr); + dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(listener_callbacks, onNewConnection_(_)) diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index b7137b00b0dd8..0e73327a1957c 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -72,7 +72,7 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ EXPECT_CALL(callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), server_ctx.get()); + dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -174,7 +174,7 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, EXPECT_CALL(callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), server_contexts[0].get()); + dispatcher.createServerConnection(std::move(socket), server_contexts[0].get()); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -539,7 +539,7 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { EXPECT_CALL(callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), server_ctx.get()); + dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -615,7 +615,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { EXPECT_CALL(callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), server_ctx.get()); + dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -682,7 +682,8 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, .WillRepeatedly(Invoke([&](Network::AcceptSocketPtr& socket) -> void { ServerContext* ctx = socket->localAddress() == socket1.localAddress() ? server_ctx1.get() : server_ctx2.get(); - Network::ConnectionPtr new_connection = dispatcher.createConnection(std::move(socket), ctx); + Network::ConnectionPtr new_connection = + dispatcher.createServerConnection(std::move(socket), ctx); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -980,7 +981,7 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { ? server_ctx.get() : server2_ctx.get(); Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(accept_socket), ctx); + dispatcher.createServerConnection(std::move(accept_socket), ctx); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -1069,7 +1070,7 @@ TEST_P(SslSocketTest, SslError) { EXPECT_CALL(callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher.createConnection(std::move(socket), server_ctx.get()); + dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -1680,7 +1681,7 @@ class SslReadBufferLimitTest : public SslCertsTest, EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), server_ctx_.get()); + dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); listener_callbacks_.onNewConnection(std::move(new_connection)); })); @@ -1763,7 +1764,7 @@ class SslReadBufferLimitTest : public SslCertsTest, EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), server_ctx_.get()); + dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); listener_callbacks_.onNewConnection(std::move(new_connection)); })); @@ -1880,7 +1881,7 @@ TEST_P(SslReadBufferLimitTest, TestBind) { EXPECT_CALL(listener_callbacks_, onAccept_(_)) .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = - dispatcher_->createConnection(std::move(socket), server_ctx_.get()); + dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(0); listener_callbacks_.onNewConnection(std::move(new_connection)); })); diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 8eff048a0939f..b15694785a5f3 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -29,9 +29,9 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); - Network::ConnectionPtr createConnection(Network::AcceptSocketPtr&& accept_socket, - Ssl::Context* ssl_ctx) override { - return Network::ConnectionPtr{createConnection_(accept_socket.get(), ssl_ctx)}; + Network::ConnectionPtr createServerConnection(Network::AcceptSocketPtr&& accept_socket, + Ssl::Context* ssl_ctx) override { + return Network::ConnectionPtr{createServerConnection_(accept_socket.get(), ssl_ctx)}; } Network::ClientConnectionPtr @@ -71,7 +71,7 @@ class MockDispatcher : public Dispatcher { // Event::Dispatcher MOCK_METHOD0(clearDeferredDeleteList, void()); - MOCK_METHOD2(createConnection_, + MOCK_METHOD2(createServerConnection_, Network::Connection*(Network::AcceptSocket* accept_socket, Ssl::Context* ssl_ctx)); MOCK_METHOD3(createClientConnection_, Network::ClientConnection*(Network::Address::InstanceConstSharedPtr address, diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index d89194b272d12..26ec9d14ccf07 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -287,7 +287,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { EXPECT_CALL(*accept_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); - EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -350,7 +350,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { EXPECT_CALL(*accept_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); - EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -397,7 +397,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(original_dst_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); - EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -435,7 +435,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(normal_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); - EXPECT_CALL(dispatcher_, createConnection_(_, _)).WillOnce(Return(connection)); + EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); EXPECT_EQ(1UL, handler_->numConnections()); From aa813334f6120567c87bc2aa89a148a154374ceb Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 20:51:00 -0800 Subject: [PATCH 13/41] Listener: Rename AcceptSocket class as AcceptedSocket Requested-by: Matt Klein Signed-off-by: Jarno Rajahalme --- include/envoy/event/dispatcher.h | 6 +-- include/envoy/network/filter.h | 6 +-- include/envoy/network/listen_socket.h | 12 +++--- include/envoy/network/listener.h | 4 +- source/common/event/dispatcher_impl.cc | 2 +- source/common/event/dispatcher_impl.h | 2 +- source/common/filter/original_dst.cc | 2 +- source/common/filter/proxy_protocol.cc | 6 +-- source/common/network/listen_socket_impl.h | 10 ++--- source/common/network/listener_impl.cc | 2 +- source/server/configuration_impl.h | 4 +- source/server/connection_handler_impl.cc | 15 ++++---- source/server/connection_handler_impl.h | 12 +++--- test/common/http/codec_client_test.cc | 2 +- test/common/network/connection_impl_test.cc | 8 ++-- test/common/network/dns_impl_test.cc | 2 +- test/common/network/listener_impl_test.cc | 6 +-- test/common/ssl/ssl_socket_test.cc | 24 ++++++------ test/mocks/event/mocks.h | 6 +-- test/mocks/network/mocks.cc | 4 +- test/mocks/network/mocks.h | 12 +++--- test/server/connection_handler_test.cc | 42 ++++++++++----------- 22 files changed, 94 insertions(+), 95 deletions(-) diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index a4ac9d239adc5..85f69448cf514 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -40,12 +40,12 @@ class Dispatcher { /** * Create a server connection. - * @param accept_socket supplies a socket with an open file descriptor and connection metadata - * to use for the connection. Takes ownership of the accept_socket. + * @param socket supplies an accepted socket with an open file descriptor and connection metadata + * to use for the connection. Takes ownership of the socket. * @param ssl_ctx supplies the SSL context to use, if not nullptr. * @return Network::ConnectionPtr a server connection that is owned by the caller. */ - virtual Network::ConnectionPtr createServerConnection(Network::AcceptSocketPtr&& accept_socket, + virtual Network::ConnectionPtr createServerConnection(Network::AcceptedSocketPtr&& socket, Ssl::Context* ssl_ctx) PURE; /** diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index 45112acd45948..1963031d9d707 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -9,7 +9,7 @@ namespace Envoy { namespace Network { class Connection; -class AcceptSocket; +class AcceptedSocket; /** * Status codes returned by filters that can cause future filters to not get iterated to. @@ -157,9 +157,9 @@ class ListenerFilterCallbacks { virtual ~ListenerFilterCallbacks() {} /** - * @return the AcceptSocket that owns this manager and the managed filters. + * @return the AcceptedSocket that owns this manager and the managed filters. */ - virtual AcceptSocket& socket() PURE; + virtual AcceptedSocket& socket() PURE; /** * @return the Dispatcher for this manager. diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 4d975f0a35999..ff0b911b7f8f7 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -35,11 +35,11 @@ typedef std::unique_ptr ListenSocketPtr; typedef std::shared_ptr ListenSocketSharedPtr; /** - * An abstract accept socket. + * An abstract accepted socket. */ -class AcceptSocket { +class AcceptedSocket { public: - virtual ~AcceptSocket() {} + virtual ~AcceptedSocket() {} /** * @return the address that the socket was received at, or an original destination address if @@ -70,7 +70,7 @@ class AcceptSocket { virtual void resetRemoteAddress(Address::InstanceConstSharedPtr& remote_address) PURE; /** - * @return fd the accept socket's file descriptor. + * @return fd the accepted socket's file descriptor. */ virtual int fd() const PURE; @@ -91,8 +91,8 @@ class AcceptSocket { virtual void close() PURE; }; -typedef std::unique_ptr AcceptSocketPtr; -typedef std::shared_ptr AcceptSocketSharedPtr; +typedef std::unique_ptr AcceptedSocketPtr; +typedef std::shared_ptr AcceptedSocketSharedPtr; } // namespace Network } // namespace Envoy diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 22e6d78054c83..13ff25a1c1390 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -20,9 +20,9 @@ class ListenerCallbacks { /** * Called when a new connection is accepted. - * @param socket supplies the socket that is moved into the callee. + * @param socket supplies the accepted socket that is moved into the callee. */ - virtual void onAccept(AcceptSocketPtr&& socket) PURE; + virtual void onAccept(AcceptedSocketPtr&& socket) PURE; /** * Called when a new connection is accepted. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index ca0718cc335d8..8e2690eb8e92b 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -73,7 +73,7 @@ void DispatcherImpl::clearDeferredDeleteList() { deferred_deleting_ = false; } -Network::ConnectionPtr DispatcherImpl::createServerConnection(Network::AcceptSocketPtr&& socket, +Network::ConnectionPtr DispatcherImpl::createServerConnection(Network::AcceptedSocketPtr&& socket, Ssl::Context* ssl_ctx) { ASSERT(isThreadSafe()); return Network::ConnectionPtr{ diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 36ea8f3fdd311..98e34a8e7af02 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -33,7 +33,7 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { // Event::Dispatcher void clearDeferredDeleteList() override; - Network::ConnectionPtr createServerConnection(Network::AcceptSocketPtr&& accept_socket, + Network::ConnectionPtr createServerConnection(Network::AcceptedSocketPtr&& socket, Ssl::Context* ssl_ctx) override; Network::ClientConnectionPtr createClientConnection(Network::Address::InstanceConstSharedPtr address, diff --git a/source/common/filter/original_dst.cc b/source/common/filter/original_dst.cc index 01e6ea951ecac..3c574c4de59d4 100644 --- a/source/common/filter/original_dst.cc +++ b/source/common/filter/original_dst.cc @@ -14,7 +14,7 @@ Network::Address::InstanceConstSharedPtr OriginalDst::getOriginalDst(int fd) { Network::FilterStatus OriginalDst::onAccept(Network::ListenerFilterCallbacks& cb) { ENVOY_LOG(debug, "original_dst: New connection accepted"); - Network::AcceptSocket& socket = cb.socket(); + Network::AcceptedSocket& socket = cb.socket(); Network::Address::InstanceConstSharedPtr local_address = socket.localAddress(); if (local_address->type() == Network::Address::Type::Ip) { diff --git a/source/common/filter/proxy_protocol.cc b/source/common/filter/proxy_protocol.cc index b4baaad91ff07..27e3f6d44a757 100644 --- a/source/common/filter/proxy_protocol.cc +++ b/source/common/filter/proxy_protocol.cc @@ -25,7 +25,7 @@ Config::Config(Stats::Scope& scope) : stats_{ALL_PROXY_PROTOCOL_STATS(POOL_COUNT Network::FilterStatus Instance::onAccept(Network::ListenerFilterCallbacks& cb) { ENVOY_LOG(info, "proxy_protocol: New connection accepted"); - Network::AcceptSocket& socket = cb.socket(); + Network::AcceptedSocket& socket = cb.socket(); ASSERT(file_event_.get() == nullptr); file_event_ = cb.dispatcher().createFileEvent(socket.fd(), @@ -49,7 +49,7 @@ void Instance::onRead() { } void Instance::onReadWorker() { - Network::AcceptSocket& socket = cb_->socket(); + Network::AcceptedSocket& socket = cb_->socket(); std::string proxy_line; if (!readLine(socket.fd(), proxy_line)) { return; @@ -127,7 +127,7 @@ void Instance::onReadWorker() { void Instance::finishConnection(Network::Address::InstanceConstSharedPtr remote_address, Network::Address::InstanceConstSharedPtr local_address) { - Network::AcceptSocket& socket = cb_->socket(); + Network::AcceptedSocket& socket = cb_->socket(); socket.resetLocalAddress(local_address); socket.resetRemoteAddress(remote_address); diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index 7af93e3cf297f..6121534b6e6ef 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -50,15 +50,15 @@ class UdsListenSocket : public ListenSocketImpl { UdsListenSocket(const std::string& uds_path); }; -class AcceptSocketImpl : public AcceptSocket { +class AcceptedSocketImpl : public AcceptedSocket { public: - AcceptSocketImpl(int fd, Address::InstanceConstSharedPtr&& local_address, - Address::InstanceConstSharedPtr&& remote_address) + AcceptedSocketImpl(int fd, Address::InstanceConstSharedPtr&& local_address, + Address::InstanceConstSharedPtr&& remote_address) : fd_(fd), local_address_reset_(false), local_address_(std::move(local_address)), remote_address_(std::move(remote_address)) {} - ~AcceptSocketImpl() { close(); } + ~AcceptedSocketImpl() { close(); } - // Network::AcceptSocket + // Network::AcceptedSocket Address::InstanceConstSharedPtr localAddress() const override { return local_address_; } void resetLocalAddress(Address::InstanceConstSharedPtr& local_address) override { local_address_ = local_address; diff --git a/source/common/network/listener_impl.cc b/source/common/network/listener_impl.cc index c8ff51384736f..58181b56c7415 100644 --- a/source/common/network/listener_impl.cc +++ b/source/common/network/listener_impl.cc @@ -23,7 +23,7 @@ Address::InstanceConstSharedPtr ListenerImpl::getLocalAddress(int fd) { void ListenerImpl::listenCallback(evconnlistener*, evutil_socket_t fd, sockaddr* remote_addr, int remote_addr_len, void* arg) { ListenerImpl* listener = static_cast(arg); - AcceptSocketPtr socket(new AcceptSocketImpl( + AcceptedSocketPtr socket(new AcceptedSocketImpl( fd, // Get the local address from the new socket if the listener is listening on the all hosts // address (e.g., 0.0.0.0 for IPv4). diff --git a/source/server/configuration_impl.h b/source/server/configuration_impl.h index 862f9dd495b93..2ba943f429754 100644 --- a/source/server/configuration_impl.h +++ b/source/server/configuration_impl.h @@ -101,8 +101,8 @@ class FilterChainUtility { const std::vector& factories); /** - * Given an accept socket and a list of factories, create a new filter chain. Chain creation will - * exit early if any filters immediately close the connection. + * Given a ListenerFilterManager and a list of factories, create a new filter chain. Chain + * creation will exit early if any filters immediately close the connection. */ static bool buildFilterChain(Network::ListenerFilterManager& filter_manager, const std::vector& factories); diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 58012f58577e3..f8a2b04378b6a 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -138,7 +138,7 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { listener_->parent_.findActiveListenerByAddress(*socket_->localAddress()); if (new_listener != nullptr) { - // Reset the accept socket transiet state and hand it to the new listener. + // Reset the accepted socket transient state and hand it to the new listener. socket_->clearReset(); new_listener->onAccept(std::move(socket_)); goto out; @@ -158,9 +158,9 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { listener_->parent_.dispatcher_.deferredDelete(std::move(removed)); } -void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptSocketPtr&& accept_socket) { - Network::Address::InstanceConstSharedPtr local_address = accept_socket->localAddress(); - ActiveSocket* active_socket(new ActiveSocket(*this, std::move(accept_socket))); +void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr&& socket) { + Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); + ActiveSocket* active_socket(new ActiveSocket(*this, std::move(socket))); // Implicitly add legacy filters if (config_.useOriginalDst()) { @@ -179,10 +179,9 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptSocketPtr&& active_socket->continueFilterChain(true); } -void ConnectionHandlerImpl::ActiveListener::newConnection( - Network::AcceptSocketPtr&& accept_socket) { - Network::ConnectionPtr new_connection = parent_.dispatcher_.createServerConnection( - std::move(accept_socket), config_.defaultSslContext()); +void ConnectionHandlerImpl::ActiveListener::newConnection(Network::AcceptedSocketPtr&& socket) { + Network::ConnectionPtr new_connection = + parent_.dispatcher_.createServerConnection(std::move(socket), config_.defaultSslContext()); new_connection->setBufferLimits(config_.perConnectionBufferLimitBytes()); onNewConnection(std::move(new_connection)); } diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index f5b4fcd64c486..68a66506610eb 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -81,7 +81,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { * Fires when a new connection is received from the listener. * @param socket supplies the accepted socket to take control of. */ - void onAccept(Network::AcceptSocketPtr&& socket) override; + void onAccept(Network::AcceptedSocketPtr&& socket) override; /** * Fires when a new connection is received from the listener. @@ -98,7 +98,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { /** * Create a new connection from a socket accepted by the listener. */ - void newConnection(Network::AcceptSocketPtr&& accept_socket); + void newConnection(Network::AcceptedSocketPtr&& socket); ConnectionHandlerImpl& parent_; Network::ListenerPtr listener_; @@ -138,13 +138,13 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { }; /** - * Wrapper for an active accept socket owned by this handler. + * Wrapper for an active accepted socket owned by this handler. */ struct ActiveSocket : public Network::ListenerFilterManager, public Network::ListenerFilterCallbacks, LinkedObject, public Event::DeferredDeletable { - ActiveSocket(ActiveListener& listener, Network::AcceptSocketPtr&& socket) + ActiveSocket(ActiveListener& listener, Network::AcceptedSocketPtr&& socket) : listener_(&listener), socket_(std::move(socket)), iter_(accept_filters_.end()) {} ~ActiveSocket() { ASSERT(iter_ == accept_filters_.end()); @@ -157,12 +157,12 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { } // Network::ListenerFilterCallbacks - Network::AcceptSocket& socket() override { return *socket_.get(); } + Network::AcceptedSocket& socket() override { return *socket_.get(); } Event::Dispatcher& dispatcher() override { return listener_->parent_.dispatcher_; } void continueFilterChain(bool success) override; ActiveListener* listener_; - Network::AcceptSocketPtr socket_; + Network::AcceptedSocketPtr socket_; std::list accept_filters_; std::list::iterator iter_; }; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index db811b181008f..8d01bd5098244 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -189,7 +189,7 @@ class CodecNetworkTest : public testing::TestWithParam void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index 01889b51747d1..5c115bf8fef71 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -99,7 +99,7 @@ class ConnectionImplTest : public testing::TestWithParam { client_connection_->connect(); read_filter_.reset(new NiceMock()); EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -194,7 +194,7 @@ TEST_P(ConnectionImplTest, CloseDuringConnectCallback) { read_filter_.reset(new NiceMock()); EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -248,7 +248,7 @@ TEST_P(ConnectionImplTest, ConnectionStats) { read_filter_.reset(new NiceMock()); MockConnectionStats server_connection_stats; EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -765,7 +765,7 @@ class ReadBufferLimitTest : public ConnectionImplTest { read_filter_.reset(new NiceMock()); EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); new_connection->setBufferLimits(read_buffer_limit); diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 15ab1a66e52d4..fd6a0706bce26 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -200,7 +200,7 @@ class TestDnsServer : public ListenerCallbacks { public: TestDnsServer(Event::DispatcherImpl& dispatcher) : dispatcher_(dispatcher) {} - void onAccept(AcceptSocketPtr&& socket) override { + void onAccept(AcceptedSocketPtr&& socket) override { Network::ConnectionPtr new_connection = dispatcher_.createServerConnection(std::move(socket), nullptr); onNewConnection(std::move(new_connection)); diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index 3869825d5e865..a0252e0579a77 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -35,7 +35,7 @@ static void errorCallbackTest(Address::IpVersion version) { client_connection->connect(); EXPECT_CALL(listener_callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); @@ -101,7 +101,7 @@ TEST_P(ListenerImplTest, UseActualDst) { EXPECT_CALL(listener_callbacks2, onAccept_(_)).Times(0); EXPECT_CALL(listener_callbacks1, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks1.onNewConnection(std::move(new_connection)); @@ -136,7 +136,7 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { EXPECT_CALL(listener, getLocalAddress(_)).WillOnce(Return(local_dst_address)); EXPECT_CALL(listener_callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 0e73327a1957c..386a49f662af7 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -70,7 +70,7 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -172,7 +172,7 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_contexts[0].get()); callbacks.onNewConnection(std::move(new_connection)); @@ -537,7 +537,7 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -613,7 +613,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -679,7 +679,7 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, SSL_SESSION* ssl_session = nullptr; Network::ConnectionPtr server_connection; EXPECT_CALL(callbacks, onAccept_(_)) - .WillRepeatedly(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { ServerContext* ctx = socket->localAddress() == socket1.localAddress() ? server_ctx1.get() : server_ctx2.get(); Network::ConnectionPtr new_connection = @@ -976,12 +976,12 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_)) - .WillRepeatedly(Invoke([&](Network::AcceptSocketPtr& accept_socket) -> void { - ServerContext* ctx = accept_socket->localAddress() == socket.localAddress() + .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& accepted_socket) -> void { + ServerContext* ctx = accepted_socket->localAddress() == socket.localAddress() ? server_ctx.get() : server2_ctx.get(); Network::ConnectionPtr new_connection = - dispatcher.createServerConnection(std::move(accept_socket), ctx); + dispatcher.createServerConnection(std::move(accepted_socket), ctx); callbacks.onNewConnection(std::move(new_connection)); })); EXPECT_CALL(callbacks, onNewConnection_(_)) @@ -1068,7 +1068,7 @@ TEST_P(SslSocketTest, SslError) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -1679,7 +1679,7 @@ class SslReadBufferLimitTest : public SslCertsTest, initialize(); EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); @@ -1762,7 +1762,7 @@ class SslReadBufferLimitTest : public SslCertsTest, .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); @@ -1879,7 +1879,7 @@ TEST_P(SslReadBufferLimitTest, TestBind) { initialize(); EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptSocketPtr& socket) -> void { + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(0); diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index b15694785a5f3..bf66e232f5fe4 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -29,9 +29,9 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); - Network::ConnectionPtr createServerConnection(Network::AcceptSocketPtr&& accept_socket, + Network::ConnectionPtr createServerConnection(Network::AcceptedSocketPtr&& socket, Ssl::Context* ssl_ctx) override { - return Network::ConnectionPtr{createServerConnection_(accept_socket.get(), ssl_ctx)}; + return Network::ConnectionPtr{createServerConnection_(socket.get(), ssl_ctx)}; } Network::ClientConnectionPtr @@ -72,7 +72,7 @@ class MockDispatcher : public Dispatcher { // Event::Dispatcher MOCK_METHOD0(clearDeferredDeleteList, void()); MOCK_METHOD2(createServerConnection_, - Network::Connection*(Network::AcceptSocket* accept_socket, Ssl::Context* ssl_ctx)); + Network::Connection*(Network::AcceptedSocket* socket, Ssl::Context* ssl_ctx)); MOCK_METHOD3(createClientConnection_, Network::ClientConnection*(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index a2ec909a4453e..e8ba8da9fcc93 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -164,11 +164,11 @@ MockListenSocket::MockListenSocket() : local_address_(new Address::Ipv4Instance( MockListenSocket::~MockListenSocket() {} -MockAcceptSocket::MockAcceptSocket() : local_address_(new Address::Ipv4Instance(80)) { +MockAcceptedSocket::MockAcceptedSocket() : local_address_(new Address::Ipv4Instance(80)) { ON_CALL(*this, localAddress()).WillByDefault(Return(local_address_)); } -MockAcceptSocket::~MockAcceptSocket() {} +MockAcceptedSocket::~MockAcceptedSocket() {} MockListener::MockListener() {} MockListener::~MockListener() { onDestroy(); } diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 857844366167f..0f6fe41cc4d5b 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -193,10 +193,10 @@ class MockListenerCallbacks : public ListenerCallbacks { MockListenerCallbacks(); ~MockListenerCallbacks(); - void onAccept(AcceptSocketPtr&& socket) override { onAccept_(socket); } + void onAccept(AcceptedSocketPtr&& socket) override { onAccept_(socket); } void onNewConnection(ConnectionPtr&& conn) override { onNewConnection_(conn); } - MOCK_METHOD1(onAccept_, void(AcceptSocketPtr& socket)); + MOCK_METHOD1(onAccept_, void(AcceptedSocketPtr& socket)); MOCK_METHOD1(onNewConnection_, void(ConnectionPtr& conn)); }; @@ -221,7 +221,7 @@ class MockListenerFilterCallbacks : public ListenerFilterCallbacks { MockListenerFilterCallbacks(); ~MockListenerFilterCallbacks(); - MOCK_METHOD0(socket, AcceptSocket&()); + MOCK_METHOD0(socket, AcceptedSocket&()); MOCK_METHOD0(dispatcher, Event::Dispatcher&()); MOCK_METHOD1(continueFilterChain, void(bool)); }; @@ -255,10 +255,10 @@ class MockListenSocket : public ListenSocket { Address::InstanceConstSharedPtr local_address_; }; -class MockAcceptSocket : public AcceptSocket { +class MockAcceptedSocket : public AcceptedSocket { public: - MockAcceptSocket(); - ~MockAcceptSocket(); + MockAcceptedSocket(); + ~MockAcceptedSocket(); MOCK_CONST_METHOD0(localAddress, Address::InstanceConstSharedPtr()); MOCK_METHOD1(resetLocalAddress, void(Address::InstanceConstSharedPtr&)); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 26ec9d14ccf07..1d28e7f9e95fe 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -265,7 +265,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { handler_->addListener(*test_listener2); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptSocket* accept_socket = new NiceMock(); + Network::MockAcceptedSocket* accepted_socket = new NiceMock(); bool redirected = false; EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { @@ -281,14 +281,14 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { cb.socket().resetLocalAddress(alt_address); return Network::FilterStatus::Continue; })); - EXPECT_CALL(*accept_socket, resetLocalAddress(alt_address)); - EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(true)); - EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(alt_address)); - EXPECT_CALL(*accept_socket, clearReset()); + EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); + EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); + EXPECT_CALL(*accepted_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -325,7 +325,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { handler_->addListener(*test_listener2); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptSocket* accept_socket = new NiceMock(); + Network::MockAcceptedSocket* accepted_socket = new NiceMock(); bool redirected = false; EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { @@ -344,14 +344,14 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { cb.socket().resetLocalAddress(alt_address); return Network::FilterStatus::Continue; })); - EXPECT_CALL(*accept_socket, resetLocalAddress(alt_address)); - EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(true)); - EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(alt_address)); - EXPECT_CALL(*accept_socket, clearReset()); + EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); + EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); + EXPECT_CALL(*accepted_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -380,7 +380,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { handler_->addListener(*test_listener1); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptSocket* accept_socket = new NiceMock(); + Network::MockAcceptedSocket* accepted_socket = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. @@ -392,13 +392,13 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { cb.socket().resetLocalAddress(original_dst_address); return Network::FilterStatus::Continue; })); - EXPECT_CALL(*accept_socket, resetLocalAddress(original_dst_address)); - EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(true)); - EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(original_dst_address)); + EXPECT_CALL(*accepted_socket, resetLocalAddress(original_dst_address)); + EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(original_dst_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); @@ -423,7 +423,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { handler_->addListener(*test_listener1); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptSocket* accept_socket = new NiceMock(); + Network::MockAcceptedSocket* accepted_socket = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. @@ -431,12 +431,12 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { return true; })); EXPECT_CALL(*test_filter, onAccept(_)).WillOnce(Return(Network::FilterStatus::Continue)); - EXPECT_CALL(*accept_socket, localAddressReset()).WillOnce(Return(false)); - EXPECT_CALL(*accept_socket, localAddress()).WillRepeatedly(Return(normal_address)); + EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(false)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(normal_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptSocketPtr{accept_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); From add8512e9c464668dfcacace304bc53d487c0007 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 22:28:04 -0800 Subject: [PATCH 14/41] Review fixes. Signed-off-by: Jarno Rajahalme --- include/envoy/network/listen_socket.h | 4 ++-- include/envoy/server/listener_manager.h | 2 +- source/common/network/listen_socket_impl.h | 4 ++-- test/mocks/network/mocks.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index ff0b911b7f8f7..3c3c74e466520 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -51,7 +51,7 @@ class AcceptedSocket { * Reset the original destination address of the socket to a different address than the one * the socket was accepted at. */ - virtual void resetLocalAddress(Address::InstanceConstSharedPtr& local_address) PURE; + virtual void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; /** * @return true if the local address has been reset. @@ -67,7 +67,7 @@ class AcceptedSocket { /** * Set the original source address of the socket */ - virtual void resetRemoteAddress(Address::InstanceConstSharedPtr& remote_address) PURE; + virtual void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE; /** * @return fd the accepted socket's file descriptor. diff --git a/include/envoy/server/listener_manager.h b/include/envoy/server/listener_manager.h index 02e271aa40a9b..95483958bc277 100644 --- a/include/envoy/server/listener_manager.h +++ b/include/envoy/server/listener_manager.h @@ -179,7 +179,7 @@ class ListenerManager { virtual void startWorkers(GuardDog& guard_dog) PURE; /** - * Stop all listeners from accepting new connectins without actually removing any of them. This + * Stop all listeners from accepting new connections without actually removing any of them. This * is used for server draining. */ virtual void stopListeners() PURE; diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index 6121534b6e6ef..1943cdf7cda01 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -60,13 +60,13 @@ class AcceptedSocketImpl : public AcceptedSocket { // Network::AcceptedSocket Address::InstanceConstSharedPtr localAddress() const override { return local_address_; } - void resetLocalAddress(Address::InstanceConstSharedPtr& local_address) override { + void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) override { local_address_ = local_address; local_address_reset_ = true; } bool localAddressReset() const override { return local_address_reset_; } Address::InstanceConstSharedPtr remoteAddress() const override { return remote_address_; } - void resetRemoteAddress(Address::InstanceConstSharedPtr& remote_address) override { + void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) override { remote_address_ = remote_address; } int fd() const override { return fd_; } diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 0f6fe41cc4d5b..bc6893b179ae4 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -261,10 +261,10 @@ class MockAcceptedSocket : public AcceptedSocket { ~MockAcceptedSocket(); MOCK_CONST_METHOD0(localAddress, Address::InstanceConstSharedPtr()); - MOCK_METHOD1(resetLocalAddress, void(Address::InstanceConstSharedPtr&)); + MOCK_METHOD1(resetLocalAddress, void(const Address::InstanceConstSharedPtr&)); MOCK_CONST_METHOD0(localAddressReset, bool()); MOCK_CONST_METHOD0(remoteAddress, Address::InstanceConstSharedPtr()); - MOCK_METHOD1(resetRemoteAddress, void(Address::InstanceConstSharedPtr&)); + MOCK_METHOD1(resetRemoteAddress, void(const Address::InstanceConstSharedPtr&)); MOCK_CONST_METHOD0(fd, int()); MOCK_METHOD0(takeFd, int()); MOCK_METHOD0(clearReset, void()); From c32fcaaa788a5dc0ae7d261551b867543c7bdbd3 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 21:20:41 -0800 Subject: [PATCH 15/41] listener: Use unique_ptr for listener filters. Signed-off-by: Jarno Rajahalme --- include/envoy/network/filter.h | 4 ++-- source/server/config/network/original_dst.cc | 2 +- source/server/config/network/proxy_protocol.cc | 3 +-- source/server/connection_handler_impl.cc | 6 ++---- source/server/connection_handler_impl.h | 6 +++--- test/mocks/network/mocks.h | 2 +- test/server/connection_handler_test.cc | 8 ++++---- 7 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index 1963031d9d707..6f2e7f2fb47e3 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -192,7 +192,7 @@ class ListenerFilter { virtual FilterStatus onAccept(ListenerFilterCallbacks& cb) PURE; }; -typedef std::shared_ptr ListenerFilterSharedPtr; +typedef std::unique_ptr ListenerFilterPtr; /** * Interface for filter callbacks and adding listener filters to a manager. @@ -206,7 +206,7 @@ class ListenerFilterManager { * first is called first). * @param filter supplies the filter being added. */ - virtual void addAcceptFilter(ListenerFilterSharedPtr filter) PURE; + virtual void addAcceptFilter(ListenerFilter* filter) PURE; }; /** diff --git a/source/server/config/network/original_dst.cc b/source/server/config/network/original_dst.cc index 44bbb1aad5055..7ce16417cb1ea 100644 --- a/source/server/config/network/original_dst.cc +++ b/source/server/config/network/original_dst.cc @@ -19,7 +19,7 @@ class OriginalDstConfigFactory : public NamedListenerFilterConfigFactory { ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext&) override { return [](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(Network::ListenerFilterSharedPtr{new Filter::OriginalDst()}); + filter_manager.addAcceptFilter(new Filter::OriginalDst()); }; } diff --git a/source/server/config/network/proxy_protocol.cc b/source/server/config/network/proxy_protocol.cc index 89adc3cd521f6..8f469b0eb36c6 100644 --- a/source/server/config/network/proxy_protocol.cc +++ b/source/server/config/network/proxy_protocol.cc @@ -21,8 +21,7 @@ class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { Filter::ProxyProtocol::ConfigSharedPtr config( new Filter::ProxyProtocol::Config(context.scope())); return [config](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter( - Network::ListenerFilterSharedPtr{new Filter::ProxyProtocol::Instance(config)}); + filter_manager.addAcceptFilter(new Filter::ProxyProtocol::Instance(config)); }; } diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index f8a2b04378b6a..22f5aa4c54aa4 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -164,12 +164,10 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr& // Implicitly add legacy filters if (config_.useOriginalDst()) { - active_socket->accept_filters_.emplace_back( - Network::ListenerFilterSharedPtr{new Filter::OriginalDst()}); + active_socket->accept_filters_.emplace_back(new Filter::OriginalDst()); } if (config_.useProxyProto()) { - active_socket->accept_filters_.emplace_back( - Network::ListenerFilterSharedPtr{new Filter::ProxyProtocol::Instance(legacy_stats_)}); + active_socket->accept_filters_.emplace_back(new Filter::ProxyProtocol::Instance(legacy_stats_)); } // Create and run the filters diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index 68a66506610eb..d79683c592c52 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -152,7 +152,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { } // Network::ListenerFilterManager - void addAcceptFilter(Network::ListenerFilterSharedPtr filter) override { + void addAcceptFilter(Network::ListenerFilter* filter) override { accept_filters_.emplace_back(filter); } @@ -163,8 +163,8 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ActiveListener* listener_; Network::AcceptedSocketPtr socket_; - std::list accept_filters_; - std::list::iterator iter_; + std::list accept_filters_; + std::list::iterator iter_; }; static ListenerStats generateStats(Stats::Scope& scope); diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index bc6893b179ae4..b5858d20b1e4d 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -231,7 +231,7 @@ class MockListenerFilterManager : public ListenerFilterManager { MockListenerFilterManager(); ~MockListenerFilterManager(); - MOCK_METHOD1(addAcceptFilter, void(Network::ListenerFilterSharedPtr)); + MOCK_METHOD1(addAcceptFilter, void(Network::ListenerFilter*)); }; class MockFilterChainFactory : public FilterChainFactory { diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 1d28e7f9e95fe..1b4225d73f6c6 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -271,7 +271,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. if (!redirected) { - manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + manager.addAcceptFilter(test_filter); redirected = true; } return true; @@ -331,7 +331,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. if (!redirected) { - manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + manager.addAcceptFilter(test_filter); redirected = true; } return true; @@ -384,7 +384,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. - manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + manager.addAcceptFilter(test_filter); return true; })); EXPECT_CALL(*test_filter, onAccept(_)) @@ -427,7 +427,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { EXPECT_CALL(factory_, createFilterChain(A())) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. - manager.addAcceptFilter(Network::ListenerFilterSharedPtr{test_filter}); + manager.addAcceptFilter(test_filter); return true; })); EXPECT_CALL(*test_filter, onAccept(_)).WillOnce(Return(Network::FilterStatus::Continue)); From 818858af584d463c0d1b01d90345194733545919 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 23:05:46 -0800 Subject: [PATCH 16/41] network: Use "Network" in function names for network filters. Clear confusion between listener and network filters by clearly using "Listener" and "Network" in function names, respectively. Suggested-by: Lizan Zhou Signed-off-by: Jarno Rajahalme --- include/envoy/network/filter.h | 4 ++-- include/envoy/server/listener_manager.h | 4 ++-- source/server/config_validation/server.h | 6 +++--- source/server/connection_handler_impl.cc | 4 ++-- source/server/http/admin.cc | 2 +- source/server/http/admin.h | 4 ++-- source/server/listener_manager_impl.cc | 9 ++++---- source/server/listener_manager_impl.h | 16 +++++++------- test/common/network/proxy_protocol_test.cc | 15 ++++++------- test/config_test/config_test.cc | 5 +++-- test/integration/autonomous_upstream.cc | 4 ++-- test/integration/autonomous_upstream.h | 4 ++-- test/integration/fake_upstream.cc | 4 ++-- test/integration/fake_upstream.h | 4 ++-- test/mocks/network/mocks.cc | 3 +-- test/mocks/network/mocks.h | 4 ++-- test/mocks/server/mocks.h | 2 +- test/server/connection_handler_test.cc | 25 +++++++++++----------- test/server/listener_manager_impl_test.cc | 6 +++--- 19 files changed, 62 insertions(+), 63 deletions(-) diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index 6f2e7f2fb47e3..032d2207b450a 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -222,7 +222,7 @@ class FilterChainFactory { * @return true if filter chain was created successfully. Otherwise * false, e.g. filter chain is empty. */ - virtual bool createFilterChain(Connection& connection) PURE; + virtual bool createNetworkFilterChain(Connection& connection) PURE; /** * Called to create the listener filter chain. @@ -230,7 +230,7 @@ class FilterChainFactory { * @return true if filter chain was created successfully. Otherwise * false. */ - virtual bool createFilterChain(ListenerFilterManager& listener) PURE; + virtual bool createListenerFilterChain(ListenerFilterManager& listener) PURE; }; } // namespace Network diff --git a/include/envoy/server/listener_manager.h b/include/envoy/server/listener_manager.h index 95483958bc277..efc9685eff507 100644 --- a/include/envoy/server/listener_manager.h +++ b/include/envoy/server/listener_manager.h @@ -37,8 +37,8 @@ class ListenerComponentFactory { * @return std::vector the list of filter factories. */ virtual std::vector - createFilterFactoryList(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) PURE; + createNetworkFilterFactoryList(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) PURE; /** * Creates a list of listener filter factories. diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index a069eb9f6a8f0..0fec1abae67f5 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -90,9 +90,9 @@ class ValidationInstance : Logger::Loggable, // Server::ListenerComponentFactory std::vector - createFilterFactoryList(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) override { - return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); + createNetworkFilterFactoryList(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) override { + return ProdListenerComponentFactory::createNetworkFilterFactoryList_(filters, context); } std::vector createListenerFilterFactoryList( const Protobuf::RepeatedPtrField& filters, diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 22f5aa4c54aa4..6bf1fbde0111d 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -171,7 +171,7 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr& } // Create and run the filters - config_.filterChainFactory().createFilterChain(*active_socket); + config_.filterChainFactory().createListenerFilterChain(*active_socket); ActiveSocketPtr as(active_socket); as->moveIntoListBack(std::move(as), sockets_); active_socket->continueFilterChain(true); @@ -187,7 +187,7 @@ void ConnectionHandlerImpl::ActiveListener::newConnection(Network::AcceptedSocke void ConnectionHandlerImpl::ActiveListener::onNewConnection( Network::ConnectionPtr&& new_connection) { ENVOY_CONN_LOG_TO_LOGGER(parent_.logger_, debug, "new connection", *new_connection); - bool empty_filter_chain = !config_.filterChainFactory().createFilterChain(*new_connection); + bool empty_filter_chain = !config_.filterChainFactory().createNetworkFilterChain(*new_connection); // If the connection is already closed, we can just let this connection immediately die. if (new_connection->state() != Network::Connection::State::Closed) { diff --git a/source/server/http/admin.cc b/source/server/http/admin.cc index e52d8c47cd5c4..08c732b9ee09d 100644 --- a/source/server/http/admin.cc +++ b/source/server/http/admin.cc @@ -666,7 +666,7 @@ Http::ServerConnectionPtr AdminImpl::createCodec(Network::Connection& connection new Http::Http1::ServerConnectionImpl(connection, callbacks, Http::Http1Settings())}; } -bool AdminImpl::createFilterChain(Network::Connection& connection) { +bool AdminImpl::createNetworkFilterChain(Network::Connection& connection) { connection.addReadFilter(Network::ReadFilterSharedPtr{new Http::ConnectionManagerImpl( *this, server_.drainManager(), server_.random(), server_.httpTracer(), server_.runtime(), server_.localInfo(), server_.clusterManager())}); diff --git a/source/server/http/admin.h b/source/server/http/admin.h index eb7e52638811d..70bed6f633829 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -52,8 +52,8 @@ class AdminImpl : public Admin, bool removeHandler(const std::string& prefix) override; // Network::FilterChainFactory - bool createFilterChain(Network::Connection& connection) override; - bool createFilterChain(Network::ListenerFilterManager&) override { return true; } + bool createNetworkFilterChain(Network::Connection& connection) override; + bool createListenerFilterChain(Network::ListenerFilterManager&) override { return true; } // Http::FilterChainFactory void createFilterChain(Http::FilterChainFactoryCallbacks& callbacks) override; diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index da119e0c0c066..1178ed4bed8d5 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -18,7 +18,7 @@ namespace Envoy { namespace Server { std::vector -ProdListenerComponentFactory::createFilterFactoryList_( +ProdListenerComponentFactory::createNetworkFilterFactoryList_( const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context) { std::vector ret; @@ -139,7 +139,8 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag filter_chain.filter_chain_match().sni_domains().end()); if (!filters_hash.valid()) { filters_hash.value(RepeatedPtrUtil::hash(filter_chain.filters())); - filter_factories_ = parent_.factory_.createFilterFactoryList(filter_chain.filters(), *this); + filter_factories_ = + parent_.factory_.createNetworkFilterFactoryList(filter_chain.filters(), *this); } else if (filters_hash.value() != RepeatedPtrUtil::hash(filter_chain.filters())) { throw EnvoyException(fmt::format("error adding listener '{}': use of different filter chains " "is currently not supported", @@ -178,11 +179,11 @@ ListenerImpl::~ListenerImpl() { filter_factories_.clear(); } -bool ListenerImpl::createFilterChain(Network::Connection& connection) { +bool ListenerImpl::createNetworkFilterChain(Network::Connection& connection) { return Configuration::FilterChainUtility::buildFilterChain(connection, filter_factories_); } -bool ListenerImpl::createFilterChain(Network::ListenerFilterManager& manager) { +bool ListenerImpl::createListenerFilterChain(Network::ListenerFilterManager& manager) { return Configuration::FilterChainUtility::buildFilterChain(manager, listener_filter_factories_); } diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index 41a5704ba374d..bfea0db10db7e 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -25,11 +25,11 @@ class ProdListenerComponentFactory : public ListenerComponentFactory, ProdListenerComponentFactory(Instance& server) : server_(server) {} /** - * Static worker for createFilterFactoryList() that can be used directly in tests. + * Static worker for createNetworkFilterFactoryList() that can be used directly in tests. */ static std::vector - createFilterFactoryList_(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context); + createNetworkFilterFactoryList_(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context); /** * Static worker for createListenerFilterFactoryList() that can be used directly in tests. */ @@ -39,9 +39,9 @@ class ProdListenerComponentFactory : public ListenerComponentFactory, // Server::ListenerComponentFactory std::vector - createFilterFactoryList(const Protobuf::RepeatedPtrField& filters, - Configuration::FactoryContext& context) override { - return createFilterFactoryList_(filters, context); + createNetworkFilterFactoryList(const Protobuf::RepeatedPtrField& filters, + Configuration::FactoryContext& context) override { + return createNetworkFilterFactoryList_(filters, context); } std::vector createListenerFilterFactoryList( const Protobuf::RepeatedPtrField& filters, @@ -248,8 +248,8 @@ class ListenerImpl : public Listener, bool drainClose() const override; // Network::FilterChainFactory - bool createFilterChain(Network::Connection& connection) override; - bool createFilterChain(Network::ListenerFilterManager& manager) override; + bool createNetworkFilterChain(Network::Connection& connection) override; + bool createListenerFilterChain(Network::ListenerFilterManager& manager) override; private: ListenerManagerImpl& parent_; diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index 35afad353b467..80493db68301b 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -21,7 +21,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -using testing::A; using testing::Invoke; using testing::NiceMock; using testing::Return; @@ -46,7 +45,7 @@ class ProxyProtocolTest : public testing::TestWithParam, Network::Test::createRawBufferSocket()); conn_->addConnectionCallbacks(connection_callbacks_); - ON_CALL(factory_, createFilterChain(A())).WillByDefault(Return(true)); + ON_CALL(factory_, createListenerFilterChain(_)).WillByDefault(Return(true)); } // Listener @@ -64,9 +63,9 @@ class ProxyProtocolTest : public testing::TestWithParam, void connect() { conn_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillOnce(Invoke([&](ListenerFilterManager&) -> bool { return true; })); - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createNetworkFilterChain(_)) .WillOnce(Invoke([&](Connection& connection) -> bool { server_connection_ = &connection; connection.addConnectionCallbacks(server_callbacks_); @@ -80,7 +79,7 @@ class ProxyProtocolTest : public testing::TestWithParam, void connectNoRead() { conn_->connect(); - EXPECT_CALL(factory_, createFilterChain(A())); + EXPECT_CALL(factory_, createListenerFilterChain(_)); EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); dispatcher_.run(Event::Dispatcher::RunType::Block); @@ -302,7 +301,7 @@ TEST_P(ProxyProtocolTest, Closed) { TEST_P(ProxyProtocolTest, ClosedEmpty) { conn_->connect(); - EXPECT_CALL(factory_, createFilterChain(A())); + EXPECT_CALL(factory_, createListenerFilterChain(_)); conn_->close(ConnectionCloseType::NoFlush); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } @@ -340,9 +339,9 @@ class WildcardProxyProtocolTest : public testing::TestWithParamconnect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillOnce(Invoke([&](ListenerFilterManager&) -> bool { return true; })); - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createNetworkFilterChain(_)) .WillOnce(Invoke([&](Connection& connection) -> bool { server_connection_ = &connection; connection.addConnectionCallbacks(server_callbacks_); diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index d982ff8059438..ff844b79842d8 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -47,11 +47,12 @@ class ConfigTest { return main_config.clusterManager(); })); ON_CALL(server_, listenerManager()).WillByDefault(ReturnRef(listener_manager_)); - ON_CALL(component_factory_, createFilterFactoryList(_, _)) + ON_CALL(component_factory_, createNetworkFilterFactoryList(_, _)) .WillByDefault(Invoke([&](const Protobuf::RepeatedPtrField& filters, Server::Configuration::FactoryContext& context) -> std::vector { - return Server::ProdListenerComponentFactory::createFilterFactoryList_(filters, context); + return Server::ProdListenerComponentFactory::createNetworkFilterFactoryList_(filters, + context); })); ON_CALL(component_factory_, createListenerFilterFactoryList(_, _)) .WillByDefault( diff --git a/test/integration/autonomous_upstream.cc b/test/integration/autonomous_upstream.cc index 7eda68f396aca..c601a1642ad83 100644 --- a/test/integration/autonomous_upstream.cc +++ b/test/integration/autonomous_upstream.cc @@ -66,7 +66,7 @@ AutonomousUpstream::~AutonomousUpstream() { http_connections_.clear(); } -bool AutonomousUpstream::createFilterChain(Network::Connection& connection) { +bool AutonomousUpstream::createNetworkFilterChain(Network::Connection& connection) { AutonomousHttpConnectionPtr http_connection(new AutonomousHttpConnection( QueuedConnectionWrapperPtr{new QueuedConnectionWrapper(connection, true)}, stats_store_, http_type_)); @@ -75,6 +75,6 @@ bool AutonomousUpstream::createFilterChain(Network::Connection& connection) { return true; } -bool AutonomousUpstream::createFilterChain(Network::ListenerFilterManager&) { return true; } +bool AutonomousUpstream::createListenerFilterChain(Network::ListenerFilterManager&) { return true; } } // namespace Envoy diff --git a/test/integration/autonomous_upstream.h b/test/integration/autonomous_upstream.h index 48a5d6355cc70..c6137070b40ef 100644 --- a/test/integration/autonomous_upstream.h +++ b/test/integration/autonomous_upstream.h @@ -48,8 +48,8 @@ class AutonomousUpstream : public FakeUpstream { Network::Address::IpVersion version) : FakeUpstream(port, type, version) {} ~AutonomousUpstream(); - bool createFilterChain(Network::Connection& connection) override; - bool createFilterChain(Network::ListenerFilterManager& listener) override; + bool createNetworkFilterChain(Network::Connection& connection) override; + bool createListenerFilterChain(Network::ListenerFilterManager& listener) override; private: std::vector http_connections_; diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 360a7a2431128..5b76d1d4d0cdf 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -278,7 +278,7 @@ void FakeUpstream::cleanUp() { } } -bool FakeUpstream::createFilterChain(Network::Connection& connection) { +bool FakeUpstream::createNetworkFilterChain(Network::Connection& connection) { std::unique_lock lock(lock_); connection.readDisable(true); new_connections_.emplace_back( @@ -287,7 +287,7 @@ bool FakeUpstream::createFilterChain(Network::Connection& connection) { return true; } -bool FakeUpstream::createFilterChain(Network::ListenerFilterManager&) { return true; } +bool FakeUpstream::createListenerFilterChain(Network::ListenerFilterManager&) { return true; } void FakeUpstream::threadRoutine() { handler_->addListener(listener_); diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index 100bca956c6b2..272c6ed1e35c2 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -293,8 +293,8 @@ class FakeUpstream : Logger::Loggable, public Network::Filt std::vector>& upstreams); // Network::FilterChainFactory - bool createFilterChain(Network::Connection& connection) override; - bool createFilterChain(Network::ListenerFilterManager& listener) override; + bool createNetworkFilterChain(Network::Connection& connection) override; + bool createListenerFilterChain(Network::ListenerFilterManager& listener) override; void set_allow_unexpected_disconnects(bool value) { allow_unexpected_disconnects_ = value; } protected: diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index e8ba8da9fcc93..614291072ce52 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -13,7 +13,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -using testing::A; using testing::Invoke; using testing::Return; using testing::ReturnPointee; @@ -154,7 +153,7 @@ MockListenerFilterManager::MockListenerFilterManager() {} MockListenerFilterManager::~MockListenerFilterManager() {} MockFilterChainFactory::MockFilterChainFactory() { - ON_CALL(*this, createFilterChain(A())).WillByDefault(Return(true)); + ON_CALL(*this, createListenerFilterChain(_)).WillByDefault(Return(true)); } MockFilterChainFactory::~MockFilterChainFactory() {} diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index b5858d20b1e4d..f60b83e15415b 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -239,8 +239,8 @@ class MockFilterChainFactory : public FilterChainFactory { MockFilterChainFactory(); ~MockFilterChainFactory(); - MOCK_METHOD1(createFilterChain, bool(Connection& connection)); - MOCK_METHOD1(createFilterChain, bool(ListenerFilterManager& listener)); + MOCK_METHOD1(createNetworkFilterChain, bool(Connection& connection)); + MOCK_METHOD1(createListenerFilterChain, bool(ListenerFilterManager& listener)); }; class MockListenSocket : public ListenSocket { diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index 265d9cbbfe85c..2ada7dedaa150 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -146,7 +146,7 @@ class MockListenerComponentFactory : public ListenerComponentFactory { return DrainManagerPtr{createDrainManager_(drain_type)}; } - MOCK_METHOD2(createFilterFactoryList, + MOCK_METHOD2(createNetworkFilterFactoryList, std::vector( const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context)); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 1b4225d73f6c6..ef414931ed604 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -10,7 +10,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -using testing::A; using testing::ByRef; using testing::InSequence; using testing::Invoke; @@ -85,7 +84,7 @@ TEST_F(ConnectionHandlerTest, RemoveListener) { handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -123,7 +122,7 @@ TEST_F(ConnectionHandlerTest, DestroyCloseConnections) { handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -150,7 +149,7 @@ TEST_F(ConnectionHandlerTest, CloseDuringFilterChainCreate) { handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())); + EXPECT_CALL(factory_, createNetworkFilterChain(_)); EXPECT_CALL(*connection, state()).WillOnce(Return(Network::Connection::State::Closed)); EXPECT_CALL(*connection, addConnectionCallbacks(_)).Times(0); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); @@ -176,7 +175,7 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { handler_->addListener(*test_listener); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(false)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(false)); EXPECT_CALL(*connection, close(Network::ConnectionCloseType::NoFlush)); listener_callbacks->onNewConnection(Network::ConnectionPtr{connection}); EXPECT_EQ(0UL, handler_->numConnections()); @@ -267,7 +266,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptedSocket* accepted_socket = new NiceMock(); bool redirected = false; - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. if (!redirected) { @@ -286,7 +285,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); EXPECT_CALL(*accepted_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -327,7 +326,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptedSocket* accepted_socket = new NiceMock(); bool redirected = false; - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. if (!redirected) { @@ -349,7 +348,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); EXPECT_CALL(*accepted_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -381,7 +380,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptedSocket* accepted_socket = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. manager.addAcceptFilter(test_filter); @@ -396,7 +395,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(original_dst_address)); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); @@ -424,7 +423,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); Network::MockAcceptedSocket* accepted_socket = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())) + EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. manager.addAcceptFilter(test_filter); @@ -434,7 +433,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(false)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(normal_address)); Network::MockConnection* connection = new NiceMock(); - EXPECT_CALL(factory_, createFilterChain(A())).WillOnce(Return(true)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); EXPECT_EQ(1UL, handler_->numConnections()); diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 76e56fc9fb260..b1e24a553d044 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -54,7 +54,7 @@ class ListenerManagerImplTest : public testing::Test { ListenerHandle* raw_listener = new ListenerHandle(); EXPECT_CALL(listener_factory_, createDrainManager_(drain_type)) .WillOnce(Return(raw_listener->drain_manager_)); - EXPECT_CALL(listener_factory_, createFilterFactoryList(_, _)) + EXPECT_CALL(listener_factory_, createNetworkFilterFactoryList(_, _)) .WillOnce(Invoke( [raw_listener, need_init](const Protobuf::RepeatedPtrField&, Configuration::FactoryContext& context) @@ -95,11 +95,11 @@ class ListenerManagerImplWithRealFiltersTest : public ListenerManagerImplTest { public: ListenerManagerImplWithRealFiltersTest() { // Use real filter loading by default. - ON_CALL(listener_factory_, createFilterFactoryList(_, _)) + ON_CALL(listener_factory_, createNetworkFilterFactoryList(_, _)) .WillByDefault(Invoke([](const Protobuf::RepeatedPtrField& filters, Configuration::FactoryContext& context) -> std::vector { - return ProdListenerComponentFactory::createFilterFactoryList_(filters, context); + return ProdListenerComponentFactory::createNetworkFilterFactoryList_(filters, context); })); ON_CALL(listener_factory_, createListenerFilterFactoryList(_, _)) .WillByDefault( From 228ac19c8aeccf58f10ae204cf7dcc31732c25c1 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 17:54:51 -0800 Subject: [PATCH 17/41] listener_manager_impl_test: Add OriginalDstFilter test to increase code coverage. Coverage of the new original destination filter was poor, add a test to cover most of it. Signed-off-by: Jarno Rajahalme --- test/server/BUILD | 2 + test/server/listener_manager_impl_test.cc | 121 ++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/test/server/BUILD b/test/server/BUILD index b4ba8aee130f9..88ac0e8b70c4f 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -122,8 +122,10 @@ envoy_cc_test( data = ["//test/common/ssl/test_data:certs"], deps = [ ":utility_lib", + "//source/common/network:listen_socket_lib", "//source/server:listener_manager_lib", "//source/server/config/network:http_connection_manager_lib", + "//source/server/config/network:original_dst_lib", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", ], diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index b1e24a553d044..1f4c9b450d2d2 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1,6 +1,9 @@ #include "envoy/registry/registry.h" +#include "envoy/server/filter_config.h" +#include "common/filter/original_dst.h" #include "common/network/address_impl.h" +#include "common/network/listen_socket_impl.h" #include "server/configuration_impl.h" #include "server/listener_manager_impl.h" @@ -1050,5 +1053,123 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, SniWithTwoDifferentFilterChains) "chains is currently not supported"); } +TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1111 } + filter_chains: {} + listener_filters: + - name: "envoy.original_dst" + config: {} + )EOF", // " + Network::Address::IpVersion::v4); + + EXPECT_CALL(server_.random_, uuid()); + EXPECT_CALL(listener_factory_, createListenSocket(_, true)); + manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true); + EXPECT_EQ(1U, manager_->listeners().size()); + + Server::Listener& listener = manager_->listeners().back().get(); + + Network::FilterChainFactory& filterChainFactory = listener.filterChainFactory(); + Network::MockListenerFilterManager manager; + + NiceMock callbacks; + Network::AcceptedSocketImpl socket(-1, + Network::Address::InstanceConstSharedPtr{ + new Network::Address::Ipv4Instance("127.0.0.1", 1234)}, + Network::Address::InstanceConstSharedPtr{ + new Network::Address::Ipv4Instance("127.0.0.1", 5678)}); + + EXPECT_CALL(callbacks, socket()).WillOnce(Invoke([&]() -> Network::AcceptedSocket& { + return socket; + })); + + EXPECT_CALL(manager, addAcceptFilter(_)) + .WillOnce(Invoke([&](Network::ListenerFilter* filter) -> void { + EXPECT_EQ(Network::FilterStatus::Continue, filter->onAccept(callbacks)); + delete filter; + })); + + EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); +} + +class OriginalDstTest : public Filter::OriginalDst { + Network::Address::InstanceConstSharedPtr getOriginalDst(int) override { + return Network::Address::InstanceConstSharedPtr{ + new Network::Address::Ipv4Instance("127.0.0.2", 2345)}; + } +}; + +namespace Configuration { + +class OriginalDstTestConfigFactory : public NamedListenerFilterConfigFactory { +public: + // NamedListenerFilterConfigFactory + ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, + FactoryContext&) override { + return [](Network::ListenerFilterManager& filter_manager) -> void { + filter_manager.addAcceptFilter(new OriginalDstTest()); + }; + } + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + } + + std::string name() override { return "test.original_dst"; } +}; + +/** + * Static registration for the original dst filter. @see RegisterFactory. + */ +static Registry::RegisterFactory + registered_; + +} // namespace Configuration + +TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstTestFilter) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1111 } + filter_chains: {} + listener_filters: + - name: "test.original_dst" + config: {} + )EOF", // " + Network::Address::IpVersion::v4); + + EXPECT_CALL(server_.random_, uuid()); + EXPECT_CALL(listener_factory_, createListenSocket(_, true)); + manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), true); + EXPECT_EQ(1U, manager_->listeners().size()); + + Server::Listener& listener = manager_->listeners().back().get(); + + Network::FilterChainFactory& filterChainFactory = listener.filterChainFactory(); + Network::MockListenerFilterManager manager; + + NiceMock callbacks; + Network::AcceptedSocketImpl socket(-1, + Network::Address::InstanceConstSharedPtr{ + new Network::Address::Ipv4Instance("127.0.0.1", 1234)}, + Network::Address::InstanceConstSharedPtr{ + new Network::Address::Ipv4Instance("127.0.0.1", 5678)}); + + EXPECT_CALL(callbacks, socket()).WillOnce(Invoke([&]() -> Network::AcceptedSocket& { + return socket; + })); + + EXPECT_CALL(manager, addAcceptFilter(_)) + .WillOnce(Invoke([&](Network::ListenerFilter* filter) -> void { + EXPECT_EQ(Network::FilterStatus::Continue, filter->onAccept(callbacks)); + delete filter; + })); + + EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); + EXPECT_TRUE(socket.localAddressReset()); + EXPECT_EQ("127.0.0.2:2345", socket.localAddress()->asString()); +} + } // namespace Server } // namespace Envoy From 0703eccfa864b735eb2fc21034b7787da0f78368 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Jan 2018 23:45:16 -0800 Subject: [PATCH 18/41] connection_handler_impl: Fix doc comments. Make the docs more specific to avoid repetition. Signed-off-by: Jarno Rajahalme --- source/server/connection_handler_impl.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index d79683c592c52..157a208906d19 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -78,13 +78,14 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { // Network::ListenerCallbacks /** - * Fires when a new connection is received from the listener. + * Fires when a new accepted socket is received from the listener. * @param socket supplies the accepted socket to take control of. */ void onAccept(Network::AcceptedSocketPtr&& socket) override; /** - * Fires when a new connection is received from the listener. + * Fires when a new connection is received from the listener, after listener filters have + * been executed. * @param new_connection supplies the connection to take control of. */ void onNewConnection(Network::ConnectionPtr&& new_connection) override; From 84854b2334138d354756e1135d1b6a499d8191d6 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 15 Jan 2018 10:18:09 -0800 Subject: [PATCH 19/41] test: Fix format. Signed-off-by: Jarno Rajahalme --- test/server/listener_manager_impl_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 1f4c9b450d2d2..99c01fa9e5c5f 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1088,7 +1088,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { EXPECT_CALL(manager, addAcceptFilter(_)) .WillOnce(Invoke([&](Network::ListenerFilter* filter) -> void { EXPECT_EQ(Network::FilterStatus::Continue, filter->onAccept(callbacks)); - delete filter; + delete filter; })); EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); @@ -1097,7 +1097,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { class OriginalDstTest : public Filter::OriginalDst { Network::Address::InstanceConstSharedPtr getOriginalDst(int) override { return Network::Address::InstanceConstSharedPtr{ - new Network::Address::Ipv4Instance("127.0.0.2", 2345)}; + new Network::Address::Ipv4Instance("127.0.0.2", 2345)}; } }; @@ -1163,7 +1163,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstTestFilter) { EXPECT_CALL(manager, addAcceptFilter(_)) .WillOnce(Invoke([&](Network::ListenerFilter* filter) -> void { EXPECT_EQ(Network::FilterStatus::Continue, filter->onAccept(callbacks)); - delete filter; + delete filter; })); EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); From d4b2140a4fadf77c60d11eb09eb31bde00ddb038 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 15 Jan 2018 15:27:10 -0800 Subject: [PATCH 20/41] listen_socket_impl: Check if local address really changed. Check if the new local address is really different from the old one before flagging it as changed. This removes subtle behavior changes that could have been introduced otherwise. Signed-off-by: Jarno Rajahalme --- source/common/network/listen_socket_impl.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index 1943cdf7cda01..fa4bcd0d42dbc 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -61,8 +61,10 @@ class AcceptedSocketImpl : public AcceptedSocket { // Network::AcceptedSocket Address::InstanceConstSharedPtr localAddress() const override { return local_address_; } void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) override { - local_address_ = local_address; - local_address_reset_ = true; + if (*local_address != *local_address_) { + local_address_ = local_address; + local_address_reset_ = true; + } } bool localAddressReset() const override { return local_address_reset_; } Address::InstanceConstSharedPtr remoteAddress() const override { return remote_address_; } From 597d05adf96ec4ee0b34944cb489b6d48e01f268 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 15 Jan 2018 15:20:01 -0800 Subject: [PATCH 21/41] connection_handler: Check for local address reset after all listener filters have been run. Check for the need to redirect after all the filters have been run. This also fixes the problem of the last filter having stopped iteration, and then continuing, in which case the redirect check was never executed. Signed-off-by: Jarno Rajahalme --- source/server/connection_handler_impl.cc | 37 ++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 6bf1fbde0111d..036092a79d15f 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -118,6 +118,8 @@ ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Insta void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { if (success) { + ActiveListener* new_listener = nullptr; + if (iter_ == accept_filters_.end()) { iter_ = accept_filters_.begin(); } else { @@ -129,29 +131,28 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { if (status == Network::FilterStatus::StopIteration) { return; } - // Check if another listener may have to be used. - if (socket_->localAddressReset()) { - // Hands off redirected connections (from iptables) to the listener associated with the - // original destination address. If there is no listener associated with the original - // destination address, the connection is handled by the listener that receives it. - ActiveListener* new_listener = - listener_->parent_.findActiveListenerByAddress(*socket_->localAddress()); - - if (new_listener != nullptr) { - // Reset the accepted socket transient state and hand it to the new listener. - socket_->clearReset(); - new_listener->onAccept(std::move(socket_)); - goto out; - } - } } - // Successfully ran all the accept filters, create a new connection. - listener_->newConnection(std::move(socket_)); + // Successfully ran all the accept filters. + + // Check if the socket may need to be redirected to another listener. + if (socket_->localAddressReset()) { + // Find a listener associated with the original destination address. + new_listener = listener_->parent_.findActiveListenerByAddress(*socket_->localAddress()); + } + if (new_listener != nullptr) { + // Reset the accepted socket transient state and hand it to the new listener. + socket_->clearReset(); + // Hands off connections redirecrted by iptables to the listener associated with the + // original destination address. Pass 'redirected' as true to prevent further redirection. + new_listener->onAccept(std::move(socket_)); + } else { + // Create a new connection on this listener. + listener_->newConnection(std::move(socket_)); + } } else { // current filter failed, connection must be abandoned. socket_->close(); } -out: // Filter execution concluded, clear state. iter_ = accept_filters_.end(); ActiveSocketPtr removed = removeFromList(listener_->sockets_); From 1ad7886c1a67212f3be455d7b87e94b071f54754 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 15 Jan 2018 14:58:41 -0800 Subject: [PATCH 22/41] listen_socket: Remove explicit close(). Signed-off-by: Jarno Rajahalme --- include/envoy/network/listen_socket.h | 5 ----- source/common/network/listen_socket_impl.h | 13 +++++-------- source/server/connection_handler_impl.cc | 4 ---- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 3c3c74e466520..37b6e826ce4f2 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -84,11 +84,6 @@ class AcceptedSocket { * Clear 'reset' state so that the socket can be used again with a new listener. */ virtual void clearReset() PURE; - - /** - * Close the underlying socket. - */ - virtual void close() PURE; }; typedef std::unique_ptr AcceptedSocketPtr; diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index fa4bcd0d42dbc..c2342fb71a6af 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -56,7 +56,11 @@ class AcceptedSocketImpl : public AcceptedSocket { Address::InstanceConstSharedPtr&& remote_address) : fd_(fd), local_address_reset_(false), local_address_(std::move(local_address)), remote_address_(std::move(remote_address)) {} - ~AcceptedSocketImpl() { close(); } + ~AcceptedSocketImpl() { + if (fd_ != -1) { + ::close(fd_); + } + } // Network::AcceptedSocket Address::InstanceConstSharedPtr localAddress() const override { return local_address_; } @@ -81,13 +85,6 @@ class AcceptedSocketImpl : public AcceptedSocket { void clearReset() override { local_address_reset_ = false; } - void close() override { - if (fd_ != -1) { - ::close(fd_); - fd_ = -1; - } - } - protected: int fd_; bool local_address_reset_; diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 036092a79d15f..492959db4d3dc 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -70,7 +70,6 @@ ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& par ConnectionHandlerImpl::ActiveListener::~ActiveListener() { while (!sockets_.empty()) { ActiveSocketPtr removed = sockets_.front()->removeFromList(sockets_); - removed->socket_->close(); parent_.dispatcher_.deferredDelete(std::move(removed)); } @@ -149,9 +148,6 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { // Create a new connection on this listener. listener_->newConnection(std::move(socket_)); } - } else { - // current filter failed, connection must be abandoned. - socket_->close(); } // Filter execution concluded, clear state. iter_ = accept_filters_.end(); From 8bd512fca7a6e4c13d6ac28e6e5a33bf02080ea5 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 15 Jan 2018 15:17:33 -0800 Subject: [PATCH 23/41] proxy_protocol: Do not reset addresses when "UNKNOWN" According to the proxy protocol spec (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt): "If the announced transport protocol is "UNKNOWN", then the receiver knows that the sender speaks the correct PROXY protocol with the appropriate version, and SHOULD accept the connection and use the real connection's parameters as if there were no PROXY protocol header on the wire." AcceptedSocket already has the socket's local and remote addresses, so we should not set them in this case. Signed-off-by: Jarno Rajahalme --- source/common/filter/proxy_protocol.cc | 23 +++-------------------- source/common/filter/proxy_protocol.h | 6 ------ 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/source/common/filter/proxy_protocol.cc b/source/common/filter/proxy_protocol.cc index 27e3f6d44a757..cb38a66b3b2e6 100644 --- a/source/common/filter/proxy_protocol.cc +++ b/source/common/filter/proxy_protocol.cc @@ -69,18 +69,9 @@ void Instance::onReadWorker() { if (line_parts[1] == "UNKNOWN") { // At this point we know it's a proxy protocol line, so we can remove it from the socket // and continue. - Network::Address::InstanceConstSharedPtr local_address = - Envoy::Network::Address::addressFromFd(socket.fd()); - Network::Address::InstanceConstSharedPtr remote_address; - // The remote address not known. - if (local_address->ip()->version() == Network::Address::IpVersion::v4) { - remote_address = std::make_shared( - Network::Address::Ipv4Instance("0.0.0.0")); - } else { - remote_address = - std::make_shared(Network::Address::Ipv6Instance("::")); - } - finishConnection(remote_address, local_address); + // According to spec "real connection's parameters" should be used, so we should NOT + // reset the addresses in this case. + cb_->continueFilterChain(true); return; } @@ -122,16 +113,8 @@ void Instance::onReadWorker() { throw EnvoyException("failed to read proxy protocol"); } - finishConnection(remote_address, local_address); -} - -void Instance::finishConnection(Network::Address::InstanceConstSharedPtr remote_address, - Network::Address::InstanceConstSharedPtr local_address) { - Network::AcceptedSocket& socket = cb_->socket(); - socket.resetLocalAddress(local_address); socket.resetRemoteAddress(remote_address); - cb_->continueFilterChain(true); } diff --git a/source/common/filter/proxy_protocol.h b/source/common/filter/proxy_protocol.h index cc86deaca6471..52639de387682 100644 --- a/source/common/filter/proxy_protocol.h +++ b/source/common/filter/proxy_protocol.h @@ -54,12 +54,6 @@ class Instance : public Network::ListenerFilter, Logger::Loggable Date: Mon, 15 Jan 2018 13:46:16 -0800 Subject: [PATCH 24/41] listen_socket: Remove clearReset() member from AcceptedSocket Remove clearReset() member by refactoring filter processing. Signed-off-by: Jarno Rajahalme --- include/envoy/network/listen_socket.h | 11 ++---- include/envoy/network/listener.h | 5 ++- source/common/network/listen_socket_impl.h | 2 -- source/server/connection_handler_impl.cc | 14 ++++---- source/server/connection_handler_impl.h | 18 +++------- test/common/http/codec_client_test.cc | 4 +-- test/common/network/connection_impl_test.cc | 16 ++++----- test/common/network/dns_impl_test.cc | 2 +- test/common/network/listener_impl_test.cc | 14 ++++---- test/common/ssl/ssl_socket_test.cc | 40 ++++++++++----------- test/mocks/network/mocks.h | 6 ++-- test/server/connection_handler_test.cc | 10 +++--- 12 files changed, 66 insertions(+), 76 deletions(-) diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 37b6e826ce4f2..f4f4cb5cb3add 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -48,7 +48,7 @@ class AcceptedSocket { virtual Address::InstanceConstSharedPtr localAddress() const PURE; /** - * Reset the original destination address of the socket to a different address than the one + * Reset the destination address of the socket to a different address than the one * the socket was accepted at. */ virtual void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; @@ -65,7 +65,8 @@ class AcceptedSocket { virtual Address::InstanceConstSharedPtr remoteAddress() const PURE; /** - * Set the original source address of the socket + * Reset the source address of the socket to a different address than the one + * the socket was accepted at. */ virtual void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE; @@ -79,15 +80,9 @@ class AcceptedSocket { * not be closed on delete. */ virtual int takeFd() PURE; - - /** - * Clear 'reset' state so that the socket can be used again with a new listener. - */ - virtual void clearReset() PURE; }; typedef std::unique_ptr AcceptedSocketPtr; -typedef std::shared_ptr AcceptedSocketSharedPtr; } // namespace Network } // namespace Envoy diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 13ff25a1c1390..3545fba6a8ed8 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -21,8 +21,11 @@ class ListenerCallbacks { /** * Called when a new connection is accepted. * @param socket supplies the accepted socket that is moved into the callee. + * @param redirected is true when the socket was first accepted by another listener + * and is redirected to a new listener. The recipient should not redirect + * the socket any further. */ - virtual void onAccept(AcceptedSocketPtr&& socket) PURE; + virtual void onAccept(AcceptedSocketPtr&& socket, bool redirected = false) PURE; /** * Called when a new connection is accepted. diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index c2342fb71a6af..9a608e64fbee9 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -83,8 +83,6 @@ class AcceptedSocketImpl : public AcceptedSocket { return fd; } - void clearReset() override { local_address_reset_ = false; } - protected: int fd_; bool local_address_reset_; diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 492959db4d3dc..f921c4e6f8924 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -128,36 +128,38 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { for (; iter_ != accept_filters_.end(); iter_++) { Network::FilterStatus status = (*iter_)->onAccept(*this); if (status == Network::FilterStatus::StopIteration) { + // The filter is responsible for calling us again at a later time to continue the filter + // chain from the next filter. return; } } // Successfully ran all the accept filters. // Check if the socket may need to be redirected to another listener. - if (socket_->localAddressReset()) { + if (!redirected_ && socket_->localAddressReset()) { // Find a listener associated with the original destination address. new_listener = listener_->parent_.findActiveListenerByAddress(*socket_->localAddress()); } if (new_listener != nullptr) { - // Reset the accepted socket transient state and hand it to the new listener. - socket_->clearReset(); // Hands off connections redirecrted by iptables to the listener associated with the // original destination address. Pass 'redirected' as true to prevent further redirection. - new_listener->onAccept(std::move(socket_)); + new_listener->onAccept(std::move(socket_), true); } else { // Create a new connection on this listener. listener_->newConnection(std::move(socket_)); } } + // Filter execution concluded, clear state. iter_ = accept_filters_.end(); ActiveSocketPtr removed = removeFromList(listener_->sockets_); listener_->parent_.dispatcher_.deferredDelete(std::move(removed)); } -void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr&& socket) { +void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr&& socket, + bool redirected) { Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); - ActiveSocket* active_socket(new ActiveSocket(*this, std::move(socket))); + ActiveSocket* active_socket(new ActiveSocket(*this, std::move(socket), redirected)); // Implicitly add legacy filters if (config_.useOriginalDst()) { diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index 157a208906d19..6747be2742589 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -77,17 +77,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ~ActiveListener(); // Network::ListenerCallbacks - /** - * Fires when a new accepted socket is received from the listener. - * @param socket supplies the accepted socket to take control of. - */ - void onAccept(Network::AcceptedSocketPtr&& socket) override; - - /** - * Fires when a new connection is received from the listener, after listener filters have - * been executed. - * @param new_connection supplies the connection to take control of. - */ + void onAccept(Network::AcceptedSocketPtr&& socket, bool redirected) override; void onNewConnection(Network::ConnectionPtr&& new_connection) override; /** @@ -145,8 +135,9 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { public Network::ListenerFilterCallbacks, LinkedObject, public Event::DeferredDeletable { - ActiveSocket(ActiveListener& listener, Network::AcceptedSocketPtr&& socket) - : listener_(&listener), socket_(std::move(socket)), iter_(accept_filters_.end()) {} + ActiveSocket(ActiveListener& listener, Network::AcceptedSocketPtr&& socket, bool redirected) + : listener_(&listener), socket_(std::move(socket)), redirected_(redirected), + iter_(accept_filters_.end()) {} ~ActiveSocket() { ASSERT(iter_ == accept_filters_.end()); accept_filters_.clear(); @@ -164,6 +155,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ActiveListener* listener_; Network::AcceptedSocketPtr socket_; + bool redirected_; std::list accept_filters_; std::list::iterator iter_; }; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 8d01bd5098244..f9f9bbee28fe5 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -188,8 +188,8 @@ class CodecNetworkTest : public testing::TestWithParam void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index 5c115bf8fef71..581c018108f2e 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -98,8 +98,8 @@ class ConnectionImplTest : public testing::TestWithParam { int expected_callbacks = 2; client_connection_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -193,8 +193,8 @@ TEST_P(ConnectionImplTest, CloseDuringConnectCallback) { read_filter_.reset(new NiceMock()); - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -247,8 +247,8 @@ TEST_P(ConnectionImplTest, ConnectionStats) { read_filter_.reset(new NiceMock()); MockConnectionStats server_connection_stats; - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -764,8 +764,8 @@ class ReadBufferLimitTest : public ConnectionImplTest { client_connection_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); new_connection->setBufferLimits(read_buffer_limit); diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index fd6a0706bce26..dbaf6dcd59d2a 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -200,7 +200,7 @@ class TestDnsServer : public ListenerCallbacks { public: TestDnsServer(Event::DispatcherImpl& dispatcher) : dispatcher_(dispatcher) {} - void onAccept(AcceptedSocketPtr&& socket) override { + void onAccept(AcceptedSocketPtr&& socket, bool) override { Network::ConnectionPtr new_connection = dispatcher_.createServerConnection(std::move(socket), nullptr); onNewConnection(std::move(new_connection)); diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index a0252e0579a77..a35c0787e8554 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -34,8 +34,8 @@ static void errorCallbackTest(Address::IpVersion version) { Network::Test::createRawBufferSocket()); client_connection->connect(); - EXPECT_CALL(listener_callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); @@ -99,9 +99,9 @@ TEST_P(ListenerImplTest, UseActualDst) { EXPECT_CALL(listener, getLocalAddress(_)).Times(0); - EXPECT_CALL(listener_callbacks2, onAccept_(_)).Times(0); - EXPECT_CALL(listener_callbacks1, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks2, onAccept_(_, _)).Times(0); + EXPECT_CALL(listener_callbacks1, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks1.onNewConnection(std::move(new_connection)); @@ -135,8 +135,8 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { EXPECT_CALL(listener, getLocalAddress(_)).WillOnce(Return(local_dst_address)); - EXPECT_CALL(listener_callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 386a49f662af7..355ef5b7e0eb8 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -69,8 +69,8 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -171,8 +171,8 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_contexts[0].get()); callbacks.onNewConnection(std::move(new_connection)); @@ -536,8 +536,8 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -612,8 +612,8 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -678,8 +678,8 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, SSL_SESSION* ssl_session = nullptr; Network::ConnectionPtr server_connection; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { ServerContext* ctx = socket->localAddress() == socket1.localAddress() ? server_ctx1.get() : server_ctx2.get(); Network::ConnectionPtr new_connection = @@ -975,8 +975,8 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { SSL_SESSION* ssl_session = nullptr; Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& accepted_socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& accepted_socket, bool) -> void { ServerContext* ctx = accepted_socket->localAddress() == socket.localAddress() ? server_ctx.get() : server2_ctx.get(); @@ -1067,8 +1067,8 @@ TEST_P(SslSocketTest, SslError) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; - EXPECT_CALL(callbacks, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(callbacks, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -1678,8 +1678,8 @@ class SslReadBufferLimitTest : public SslCertsTest, uint32_t write_size, uint32_t num_writes, bool reserve_write_space) { initialize(); - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); @@ -1761,8 +1761,8 @@ class SslReadBufferLimitTest : public SslCertsTest, EXPECT_CALL(client_callbacks_, onEvent(Network::ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); @@ -1878,8 +1878,8 @@ TEST_P(SslReadBufferLimitTest, TestBind) { initialize(); - EXPECT_CALL(listener_callbacks_, onAccept_(_)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket) -> void { + EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) + .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(0); diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index f60b83e15415b..e964e028934c4 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -193,10 +193,12 @@ class MockListenerCallbacks : public ListenerCallbacks { MockListenerCallbacks(); ~MockListenerCallbacks(); - void onAccept(AcceptedSocketPtr&& socket) override { onAccept_(socket); } + void onAccept(AcceptedSocketPtr&& socket, bool redirected) override { + onAccept_(socket, redirected); + } void onNewConnection(ConnectionPtr&& conn) override { onNewConnection_(conn); } - MOCK_METHOD1(onAccept_, void(AcceptedSocketPtr& socket)); + MOCK_METHOD2(onAccept_, void(AcceptedSocketPtr& socket, bool redirected)); MOCK_METHOD1(onNewConnection_, void(ConnectionPtr& conn)); }; diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index ef414931ed604..d9f11e27f8a75 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -283,11 +283,10 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); - EXPECT_CALL(*accepted_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -346,11 +345,10 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); - EXPECT_CALL(*accepted_socket, clearReset()); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -397,7 +395,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); @@ -435,7 +433,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}); + listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); From d0ad3d5548267b953344b92af6a7fe55c76e9d45 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 16 Jan 2018 18:43:12 -0800 Subject: [PATCH 25/41] filter: Move listener filters to 'listener' subdirectory. Move listener filters, and the corresponding config objects, to 'listener' subdirectories to help st them aside from network filters. Signed-off-by: Jarno Rajahalme --- source/common/filter/BUILD | 30 -------------- source/common/filter/listener/BUILD | 39 +++++++++++++++++++ .../filter/{ => listener}/original_dst.cc | 2 +- .../filter/{ => listener}/original_dst.h | 0 .../filter/{ => listener}/proxy_protocol.cc | 2 +- .../filter/{ => listener}/proxy_protocol.h | 0 source/exe/BUILD | 4 +- source/server/BUILD | 4 +- source/server/config/listener/BUILD | 31 +++++++++++++++ .../{network => listener}/original_dst.cc | 2 +- .../{network => listener}/proxy_protocol.cc | 2 +- source/server/config/network/BUILD | 22 ----------- source/server/connection_handler_impl.cc | 4 +- source/server/connection_handler_impl.h | 2 +- test/integration/BUILD | 4 +- test/server/BUILD | 2 +- test/server/listener_manager_impl_test.cc | 2 +- 17 files changed, 85 insertions(+), 67 deletions(-) create mode 100644 source/common/filter/listener/BUILD rename source/common/filter/{ => listener}/original_dst.cc (96%) rename source/common/filter/{ => listener}/original_dst.h (100%) rename source/common/filter/{ => listener}/proxy_protocol.cc (99%) rename source/common/filter/{ => listener}/proxy_protocol.h (100%) create mode 100644 source/server/config/listener/BUILD rename source/server/config/{network => listener}/original_dst.cc (96%) rename source/server/config/{network => listener}/proxy_protocol.cc (96%) diff --git a/source/common/filter/BUILD b/source/common/filter/BUILD index 28356dac86a73..f1eddee693ad9 100644 --- a/source/common/filter/BUILD +++ b/source/common/filter/BUILD @@ -21,36 +21,6 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "original_dst_lib", - srcs = ["original_dst.cc"], - hdrs = ["original_dst.h"], - deps = [ - "//include/envoy/network:filter_interface", - "//include/envoy/network:listen_socket_interface", - "//source/common/common:assert_lib", - "//source/common/common:logger_lib", - "//source/common/network:utility_lib", - ], -) - -envoy_cc_library( - name = "proxy_protocol_lib", - srcs = ["proxy_protocol.cc"], - hdrs = ["proxy_protocol.h"], - deps = [ - "//include/envoy/event:dispatcher_interface", - "//include/envoy/network:filter_interface", - "//include/envoy/network:listen_socket_interface", - "//source/common/common:assert_lib", - "//source/common/common:empty_string", - "//source/common/common:logger_lib", - "//source/common/common:utility_lib", - "//source/common/network:address_lib", - "//source/common/network:utility_lib", - ], -) - envoy_cc_library( name = "ratelimit_lib", srcs = ["ratelimit.cc"], diff --git a/source/common/filter/listener/BUILD b/source/common/filter/listener/BUILD new file mode 100644 index 0000000000000..059df357bc086 --- /dev/null +++ b/source/common/filter/listener/BUILD @@ -0,0 +1,39 @@ +licenses(["notice"]) # Apache 2 + +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_package", +) + +envoy_package() + +envoy_cc_library( + name = "original_dst_lib", + srcs = ["original_dst.cc"], + hdrs = ["original_dst.h"], + deps = [ + "//include/envoy/network:filter_interface", + "//include/envoy/network:listen_socket_interface", + "//source/common/common:assert_lib", + "//source/common/common:logger_lib", + "//source/common/network:utility_lib", + ], +) + +envoy_cc_library( + name = "proxy_protocol_lib", + srcs = ["proxy_protocol.cc"], + hdrs = ["proxy_protocol.h"], + deps = [ + "//include/envoy/event:dispatcher_interface", + "//include/envoy/network:filter_interface", + "//include/envoy/network:listen_socket_interface", + "//source/common/common:assert_lib", + "//source/common/common:empty_string", + "//source/common/common:logger_lib", + "//source/common/common:utility_lib", + "//source/common/network:address_lib", + "//source/common/network:utility_lib", + ], +) diff --git a/source/common/filter/original_dst.cc b/source/common/filter/listener/original_dst.cc similarity index 96% rename from source/common/filter/original_dst.cc rename to source/common/filter/listener/original_dst.cc index 3c574c4de59d4..a87cf79a48f9b 100644 --- a/source/common/filter/original_dst.cc +++ b/source/common/filter/listener/original_dst.cc @@ -1,4 +1,4 @@ -#include "common/filter/original_dst.h" +#include "common/filter/listener/original_dst.h" #include "envoy/network/listen_socket.h" diff --git a/source/common/filter/original_dst.h b/source/common/filter/listener/original_dst.h similarity index 100% rename from source/common/filter/original_dst.h rename to source/common/filter/listener/original_dst.h diff --git a/source/common/filter/proxy_protocol.cc b/source/common/filter/listener/proxy_protocol.cc similarity index 99% rename from source/common/filter/proxy_protocol.cc rename to source/common/filter/listener/proxy_protocol.cc index cb38a66b3b2e6..3c0df6b0cfa81 100644 --- a/source/common/filter/proxy_protocol.cc +++ b/source/common/filter/listener/proxy_protocol.cc @@ -1,4 +1,4 @@ -#include "common/filter/proxy_protocol.h" +#include "common/filter/listener/proxy_protocol.h" #include diff --git a/source/common/filter/proxy_protocol.h b/source/common/filter/listener/proxy_protocol.h similarity index 100% rename from source/common/filter/proxy_protocol.h rename to source/common/filter/listener/proxy_protocol.h diff --git a/source/exe/BUILD b/source/exe/BUILD index 0e8f96f105be0..8747827d67409 100644 --- a/source/exe/BUILD +++ b/source/exe/BUILD @@ -45,11 +45,11 @@ envoy_cc_library( "//source/server/config/http:lua_lib", "//source/server/config/http:ratelimit_lib", "//source/server/config/http:router_lib", + "//source/server/config/listener:original_dst_lib", + "//source/server/config/listener:proxy_protocol_lib", "//source/server/config/network:client_ssl_auth_lib", "//source/server/config/network:echo_lib", "//source/server/config/network:http_connection_manager_lib", - "//source/server/config/network:original_dst_lib", - "//source/server/config/network:proxy_protocol_lib", "//source/server/config/network:ratelimit_lib", "//source/server/config/network:raw_buffer_socket_lib", "//source/server/config/network:redis_proxy_lib", diff --git a/source/server/BUILD b/source/server/BUILD index 39c0e350a79f7..d6988d0afdaef 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -67,8 +67,8 @@ envoy_cc_library( "//include/envoy/stats:timespan", "//source/common/common:linked_object", "//source/common/common:non_copyable", - "//source/common/filter:original_dst_lib", - "//source/common/filter:proxy_protocol_lib", + "//source/common/filter/listener:original_dst_lib", + "//source/common/filter/listener:proxy_protocol_lib", "//source/common/network:connection_lib", ], ) diff --git a/source/server/config/listener/BUILD b/source/server/config/listener/BUILD new file mode 100644 index 0000000000000..2409d444272f8 --- /dev/null +++ b/source/server/config/listener/BUILD @@ -0,0 +1,31 @@ +licenses(["notice"]) # Apache 2 + +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_package", +) + +envoy_package() + +envoy_cc_library( + name = "original_dst_lib", + srcs = ["original_dst.cc"], + deps = [ + "//include/envoy/registry", + "//include/envoy/server:filter_config_interface", + "//source/common/config:well_known_names", + "//source/common/filter/listener:original_dst_lib", + ], +) + +envoy_cc_library( + name = "proxy_protocol_lib", + srcs = ["proxy_protocol.cc"], + deps = [ + "//include/envoy/registry", + "//include/envoy/server:filter_config_interface", + "//source/common/config:well_known_names", + "//source/common/filter/listener:proxy_protocol_lib", + ], +) diff --git a/source/server/config/network/original_dst.cc b/source/server/config/listener/original_dst.cc similarity index 96% rename from source/server/config/network/original_dst.cc rename to source/server/config/listener/original_dst.cc index 7ce16417cb1ea..a80523e3ad5b0 100644 --- a/source/server/config/network/original_dst.cc +++ b/source/server/config/listener/original_dst.cc @@ -4,7 +4,7 @@ #include "envoy/server/filter_config.h" #include "common/config/well_known_names.h" -#include "common/filter/original_dst.h" +#include "common/filter/listener/original_dst.h" namespace Envoy { namespace Server { diff --git a/source/server/config/network/proxy_protocol.cc b/source/server/config/listener/proxy_protocol.cc similarity index 96% rename from source/server/config/network/proxy_protocol.cc rename to source/server/config/listener/proxy_protocol.cc index 8f469b0eb36c6..fa83d46887c5f 100644 --- a/source/server/config/network/proxy_protocol.cc +++ b/source/server/config/listener/proxy_protocol.cc @@ -4,7 +4,7 @@ #include "envoy/server/filter_config.h" #include "common/config/well_known_names.h" -#include "common/filter/proxy_protocol.h" +#include "common/filter/listener/proxy_protocol.h" namespace Envoy { namespace Server { diff --git a/source/server/config/network/BUILD b/source/server/config/network/BUILD index e7aa6f0d5de81..949b589c4262b 100644 --- a/source/server/config/network/BUILD +++ b/source/server/config/network/BUILD @@ -32,28 +32,6 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "original_dst_lib", - srcs = ["original_dst.cc"], - deps = [ - "//include/envoy/registry", - "//include/envoy/server:filter_config_interface", - "//source/common/config:well_known_names", - "//source/common/filter:original_dst_lib", - ], -) - -envoy_cc_library( - name = "proxy_protocol_lib", - srcs = ["proxy_protocol.cc"], - deps = [ - "//include/envoy/registry", - "//include/envoy/server:filter_config_interface", - "//source/common/config:well_known_names", - "//source/common/filter:proxy_protocol_lib", - ], -) - envoy_cc_library( name = "http_connection_manager_lib", srcs = ["http_connection_manager.cc"], diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 301a44ab6f09a..9ec6de58d0338 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -5,8 +5,8 @@ #include "envoy/network/filter.h" #include "envoy/stats/timespan.h" -#include "common/filter/original_dst.h" -#include "common/filter/proxy_protocol.h" +#include "common/filter/listener/original_dst.h" +#include "common/filter/listener/proxy_protocol.h" #include "common/network/connection_impl.h" #include "common/network/utility.h" diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index 3d4322967271c..a3fa2b5ea877a 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -17,7 +17,7 @@ #include "common/common/linked_object.h" #include "common/common/non_copyable.h" -#include "common/filter/proxy_protocol.h" +#include "common/filter/listener/proxy_protocol.h" #include "spdlog/spdlog.h" diff --git a/test/integration/BUILD b/test/integration/BUILD index d2324ae614a41..ab5527c451509 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -262,12 +262,12 @@ envoy_cc_test_library( "//source/server/config/http:ratelimit_lib", "//source/server/config/http:router_lib", "//source/server/config/http:zipkin_lib", + "//source/server/config/listener:original_dst_lib", + "//source/server/config/listener:proxy_protocol_lib", "//source/server/config/network:client_ssl_auth_lib", "//source/server/config/network:echo_lib", "//source/server/config/network:http_connection_manager_lib", "//source/server/config/network:mongo_proxy_lib", - "//source/server/config/network:original_dst_lib", - "//source/server/config/network:proxy_protocol_lib", "//source/server/config/network:ratelimit_lib", "//source/server/config/network:raw_buffer_socket_lib", "//source/server/config/network:redis_proxy_lib", diff --git a/test/server/BUILD b/test/server/BUILD index 88ac0e8b70c4f..f192020135c3e 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -124,8 +124,8 @@ envoy_cc_test( ":utility_lib", "//source/common/network:listen_socket_lib", "//source/server:listener_manager_lib", + "//source/server/config/listener:original_dst_lib", "//source/server/config/network:http_connection_manager_lib", - "//source/server/config/network:original_dst_lib", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", ], diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 68e7f76d0591f..f0967c5dcdf72 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1,7 +1,7 @@ #include "envoy/registry/registry.h" #include "envoy/server/filter_config.h" -#include "common/filter/original_dst.h" +#include "common/filter/listener/original_dst.h" #include "common/network/address_impl.h" #include "common/network/listen_socket_impl.h" From 7f77eb0e283c0a915fb708fcf54dd6e250d03795 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 16 Jan 2018 18:52:29 -0800 Subject: [PATCH 26/41] filter: Move listener filters to 'Filter::Listener' namespace Suggested-by: Matt Klein Signed-off-by: Jarno Rajahalme --- source/common/filter/listener/original_dst.cc | 2 ++ source/common/filter/listener/original_dst.h | 2 ++ source/common/filter/listener/proxy_protocol.cc | 2 ++ source/common/filter/listener/proxy_protocol.h | 2 ++ source/server/config/listener/original_dst.cc | 2 +- source/server/config/listener/proxy_protocol.cc | 6 +++--- source/server/connection_handler_impl.cc | 8 +++++--- source/server/connection_handler_impl.h | 2 +- test/server/listener_manager_impl_test.cc | 2 +- 9 files changed, 19 insertions(+), 9 deletions(-) diff --git a/source/common/filter/listener/original_dst.cc b/source/common/filter/listener/original_dst.cc index a87cf79a48f9b..29e2231ec3c66 100644 --- a/source/common/filter/listener/original_dst.cc +++ b/source/common/filter/listener/original_dst.cc @@ -7,6 +7,7 @@ namespace Envoy { namespace Filter { +namespace Listener { Network::Address::InstanceConstSharedPtr OriginalDst::getOriginalDst(int fd) { return Network::Utility::getOriginalDst(fd); @@ -32,5 +33,6 @@ Network::FilterStatus OriginalDst::onAccept(Network::ListenerFilterCallbacks& cb return Network::FilterStatus::Continue; } +} // namespace Listener } // namespace Filter } // namespace Envoy diff --git a/source/common/filter/listener/original_dst.h b/source/common/filter/listener/original_dst.h index 2104deee2c6bb..009316c842add 100644 --- a/source/common/filter/listener/original_dst.h +++ b/source/common/filter/listener/original_dst.h @@ -6,6 +6,7 @@ namespace Envoy { namespace Filter { +namespace Listener { /** * Implementation of an original destination listener filter. @@ -18,5 +19,6 @@ class OriginalDst : public Network::ListenerFilter, Logger::Loggable void { - filter_manager.addAcceptFilter(new Filter::OriginalDst()); + filter_manager.addAcceptFilter(new Filter::Listener::OriginalDst()); }; } diff --git a/source/server/config/listener/proxy_protocol.cc b/source/server/config/listener/proxy_protocol.cc index fa83d46887c5f..4dcdd060eb902 100644 --- a/source/server/config/listener/proxy_protocol.cc +++ b/source/server/config/listener/proxy_protocol.cc @@ -18,10 +18,10 @@ class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { // NamedListenerFilterConfigFactory ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext& context) override { - Filter::ProxyProtocol::ConfigSharedPtr config( - new Filter::ProxyProtocol::Config(context.scope())); + Filter::Listener::ProxyProtocol::ConfigSharedPtr config( + new Filter::Listener::ProxyProtocol::Config(context.scope())); return [config](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(new Filter::ProxyProtocol::Instance(config)); + filter_manager.addAcceptFilter(new Filter::Listener::ProxyProtocol::Instance(config)); }; } diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 9ec6de58d0338..e33b22d59389f 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -71,7 +71,8 @@ ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& par Network::ListenerConfig& config) : parent_(parent), listener_(std::move(listener)), stats_(generateStats(config.listenerScope())), listener_tag_(config.listenerTag()), - config_(config), legacy_stats_(new Filter::ProxyProtocol::Config(config.listenerScope())) {} + config_(config), + legacy_stats_(new Filter::Listener::ProxyProtocol::Config(config.listenerScope())) {} ConnectionHandlerImpl::ActiveListener::~ActiveListener() { while (!sockets_.empty()) { @@ -169,10 +170,11 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr& // Implicitly add legacy filters if (config_.useOriginalDst()) { - active_socket->accept_filters_.emplace_back(new Filter::OriginalDst()); + active_socket->accept_filters_.emplace_back(new Filter::Listener::OriginalDst()); } if (config_.useProxyProto()) { - active_socket->accept_filters_.emplace_back(new Filter::ProxyProtocol::Instance(legacy_stats_)); + active_socket->accept_filters_.emplace_back( + new Filter::Listener::ProxyProtocol::Instance(legacy_stats_)); } // Create and run the filters diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index a3fa2b5ea877a..feba76180e0a0 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -98,7 +98,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { std::list connections_; const uint64_t listener_tag_; Network::ListenerConfig& config_; - Filter::ProxyProtocol::ConfigSharedPtr legacy_stats_; + Filter::Listener::ProxyProtocol::ConfigSharedPtr legacy_stats_; }; typedef std::unique_ptr ActiveListenerPtr; diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index f0967c5dcdf72..72fb886878f13 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1094,7 +1094,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); } -class OriginalDstTest : public Filter::OriginalDst { +class OriginalDstTest : public Filter::Listener::OriginalDst { Network::Address::InstanceConstSharedPtr getOriginalDst(int) override { return Network::Address::InstanceConstSharedPtr{ new Network::Address::Ipv4Instance("127.0.0.2", 2345)}; From 4d72b93f0c98160064020e282c77ee6765dbd59c Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 16 Jan 2018 22:59:54 -0800 Subject: [PATCH 27/41] connection_impl: Take ConnectionSocket as an argument. Many of ConnectionImpl constructor arguments originate from AcceptedSocket. Pass it as an argument instead of it's members, which also allows clean transfer of ownership of the file descriptor from an AcceptSocket to a Connection. Requested-by: Matt Klein Signed-off-by: Jarno Rajahalme --- include/envoy/network/listen_socket.h | 57 ++++--- include/envoy/network/transport_socket.h | 2 +- source/common/event/dispatcher_impl.cc | 12 +- source/common/network/BUILD | 1 + source/common/network/connection_impl.cc | 155 +++++++++----------- source/common/network/connection_impl.h | 45 +++--- source/common/network/listen_socket_impl.h | 58 +++++--- source/common/ssl/connection_impl.cc | 13 +- source/common/ssl/connection_impl.h | 5 +- test/common/network/connection_impl_test.cc | 15 +- test/mocks/network/mocks.cc | 2 +- test/mocks/network/mocks.h | 6 +- test/server/connection_handler_test.cc | 9 +- 13 files changed, 187 insertions(+), 193 deletions(-) diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index f4f4cb5cb3add..3b31342d65279 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -35,23 +35,21 @@ typedef std::unique_ptr ListenSocketPtr; typedef std::shared_ptr ListenSocketSharedPtr; /** - * An abstract accepted socket. + * A socket passed to a connection. */ -class AcceptedSocket { +class ConnectionSocket { public: - virtual ~AcceptedSocket() {} + virtual ~ConnectionSocket() {} /** - * @return the address that the socket was received at, or an original destination address if - * applicable. + * @return the local address of the socket. */ - virtual Address::InstanceConstSharedPtr localAddress() const PURE; + virtual const Address::InstanceConstSharedPtr& localAddress() const PURE; /** - * Reset the destination address of the socket to a different address than the one - * the socket was accepted at. + * @return the remote address of the socket. */ - virtual void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; + virtual const Address::InstanceConstSharedPtr& remoteAddress() const PURE; /** * @return true if the local address has been reset. @@ -59,30 +57,49 @@ class AcceptedSocket { virtual bool localAddressReset() const PURE; /** - * @return the address that the socket was received from, or an original source address if - * applicable. + * @return fd the socket's file descriptor. */ - virtual Address::InstanceConstSharedPtr remoteAddress() const PURE; + virtual int fd() const PURE; /** - * Reset the source address of the socket to a different address than the one - * the socket was accepted at. + * Close the underlying socket. */ - virtual void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE; + virtual void close() PURE; +}; + +typedef std::unique_ptr ConnectionSocketPtr; + +/** + * An abstract accepted socket. + */ +class AcceptedSocket : virtual public ConnectionSocket { +public: + virtual ~AcceptedSocket() {} /** - * @return fd the accepted socket's file descriptor. + * Reset the destination address of the socket to a different address than the one + * the socket was accepted at. */ - virtual int fd() const PURE; + virtual void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; /** - * Transfer ownership of the file descriptor to the caller, so that the underlying socket will - * not be closed on delete. + * Reset the source address of the socket to a different address than the one + * the socket was accepted at. */ - virtual int takeFd() PURE; + virtual void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE; }; typedef std::unique_ptr AcceptedSocketPtr; +class ClientSocket : virtual public ConnectionSocket { +public: + virtual ~ClientSocket() {} + + /** + * Set the local address of the socket. + */ + virtual void setLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; +}; + } // namespace Network } // namespace Envoy diff --git a/include/envoy/network/transport_socket.h b/include/envoy/network/transport_socket.h index e7c5438d2e33c..7a2216c6d82f4 100644 --- a/include/envoy/network/transport_socket.h +++ b/include/envoy/network/transport_socket.h @@ -40,7 +40,7 @@ class TransportSocketCallbacks { /** * @return int the file descriptor associated with the connection. */ - virtual int fd() PURE; + virtual int fd() const PURE; /** * @return Network::Connection& the connection interface. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index 8e2690eb8e92b..c1c4c86c63ad6 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -76,14 +76,10 @@ void DispatcherImpl::clearDeferredDeleteList() { Network::ConnectionPtr DispatcherImpl::createServerConnection(Network::AcceptedSocketPtr&& socket, Ssl::Context* ssl_ctx) { ASSERT(isThreadSafe()); - return Network::ConnectionPtr{ - ssl_ctx ? new Ssl::ConnectionImpl( - *this, socket->takeFd(), socket->remoteAddress(), socket->localAddress(), - Network::Address::InstanceConstSharedPtr(), socket->localAddressReset(), true, - *ssl_ctx, Ssl::InitialState::Server) - : new Network::ConnectionImpl( - *this, socket->takeFd(), socket->remoteAddress(), socket->localAddress(), - Network::Address::InstanceConstSharedPtr(), socket->localAddressReset(), true)}; + return Network::ConnectionPtr{ssl_ctx + ? new Ssl::ConnectionImpl(*this, std::move(socket), true, + *ssl_ctx, Ssl::InitialState::Server) + : new Network::ConnectionImpl(*this, std::move(socket), true)}; } Network::ClientConnectionPtr diff --git a/source/common/network/BUILD b/source/common/network/BUILD index 1250aa5b9c514..4b5ea38dce1c9 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -57,6 +57,7 @@ envoy_cc_library( "//source/common/common:enum_to_int", "//source/common/common:logger_lib", "//source/common/event:libevent_lib", + "//source/common/network:listen_socket_lib", "//source/common/ssl:ssl_socket_lib", ], ) diff --git a/source/common/network/connection_impl.cc b/source/common/network/connection_impl.cc index 5e69e56626a74..2e3159d7425c4 100644 --- a/source/common/network/connection_impl.cc +++ b/source/common/network/connection_impl.cc @@ -16,22 +16,13 @@ #include "common/common/empty_string.h" #include "common/common/enum_to_int.h" #include "common/network/address_impl.h" +#include "common/network/listen_socket_impl.h" #include "common/network/raw_buffer_socket.h" #include "common/network/utility.h" namespace Envoy { namespace Network { -namespace { -Address::InstanceConstSharedPtr getNullLocalAddress(const Address::Instance& address) { - if (address.type() == Address::Type::Ip && address.ip()->version() == Address::IpVersion::v6) { - return Utility::getIpv6AnyAddress(); - } - // Default to IPv4 any address. - return Utility::getIpv4AnyAddress(); -} -} // namespace - void ConnectionImplUtility::updateBufferStats(uint64_t delta, uint64_t new_total, uint64_t& previous_total, Stats::Counter& stat_total, Stats::Gauge& stat_current) { @@ -52,34 +43,22 @@ void ConnectionImplUtility::updateBufferStats(uint64_t delta, uint64_t new_total std::atomic ConnectionImpl::next_global_id_; -ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, int fd, - Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - Address::InstanceConstSharedPtr bind_to_address, - bool using_original_dst, bool connected) - : ConnectionImpl(dispatcher, fd, remote_address, local_address, bind_to_address, - TransportSocketPtr{new RawBufferSocket}, using_original_dst, connected) {} - -ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, int fd, - Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - Address::InstanceConstSharedPtr bind_to_address, - TransportSocketPtr&& transport_socket, bool using_original_dst, +ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket, bool connected) - : transport_socket_(std::move(transport_socket)), filter_manager_(*this, *this), - remote_address_(remote_address), - local_address_((local_address == nullptr) ? getNullLocalAddress(*remote_address) - : local_address), + : ConnectionImpl(dispatcher, std::move(socket), TransportSocketPtr{new RawBufferSocket}, + connected) {} - write_buffer_( - dispatcher.getWatermarkFactory().create([this]() -> void { this->onLowWatermark(); }, - [this]() -> void { this->onHighWatermark(); })), - dispatcher_(dispatcher), fd_(fd), id_(++next_global_id_), - using_original_dst_(using_original_dst) { +ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket, + TransportSocketPtr&& transport_socket, bool connected) + : transport_socket_(std::move(transport_socket)), filter_manager_(*this, *this), + socket_(std::move(socket)), write_buffer_(dispatcher.getWatermarkFactory().create( + [this]() -> void { this->onLowWatermark(); }, + [this]() -> void { this->onHighWatermark(); })), + dispatcher_(dispatcher), id_(++next_global_id_) { // Treat the lack of a valid fd (which in practice only happens if we run out of FDs) as an OOM // condition and just crash. - RELEASE_ASSERT(fd_ != -1); + RELEASE_ASSERT(fd() != -1); if (!connected) { connecting_ = true; @@ -88,28 +67,14 @@ ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, int fd, // We never ask for both early close and read at the same time. If we are reading, we want to // consume all available data. file_event_ = dispatcher_.createFileEvent( - fd_, [this](uint32_t events) -> void { onFileEvent(events); }, Event::FileTriggerType::Edge, + fd(), [this](uint32_t events) -> void { onFileEvent(events); }, Event::FileTriggerType::Edge, Event::FileReadyType::Read | Event::FileReadyType::Write); - if (bind_to_address != nullptr) { - int rc = bind_to_address->bind(fd); - if (rc < 0) { - ENVOY_LOG_MISC(debug, "Bind failure. Failed to bind to {}: {}", bind_to_address->asString(), - strerror(errno)); - // Set a special error state to ensure asynchronous close to give the owner of the - // ConnectionImpl a chance to add callbacks and detect the "disconnect" - bind_error_ = true; - - // Trigger a write event to close this connection out-of-band. - file_event_->activate(Event::FileReadyType::Write); - } - } - transport_socket_->setTransportSocketCallbacks(*this); } ConnectionImpl::~ConnectionImpl() { - ASSERT(fd_ == -1); + ASSERT(fd() == -1); // In general we assume that owning code has called close() previously to the destructor being // run. This generally must be done so that callbacks run in the correct context (vs. deferred @@ -131,7 +96,7 @@ void ConnectionImpl::addReadFilter(ReadFilterSharedPtr filter) { bool ConnectionImpl::initializeReadFilters() { return filter_manager_.initializeReadFilters(); } void ConnectionImpl::close(ConnectionCloseType type) { - if (fd_ == -1) { + if (fd() == -1) { return; } @@ -156,7 +121,7 @@ void ConnectionImpl::close(ConnectionCloseType type) { } Connection::State ConnectionImpl::state() const { - if (fd_ == -1) { + if (fd() == -1) { return State::Closed; } else if (close_with_flush_) { return State::Closing; @@ -166,7 +131,7 @@ Connection::State ConnectionImpl::state() const { } void ConnectionImpl::closeSocket(ConnectionEvent close_type) { - if (fd_ == -1) { + if (fd() == -1) { return; } @@ -179,8 +144,7 @@ void ConnectionImpl::closeSocket(ConnectionEvent close_type) { connection_stats_.reset(); file_event_.reset(); - ::close(fd_); - fd_ = -1; + socket_->close(); raiseEvent(close_type); } @@ -195,14 +159,14 @@ void ConnectionImpl::noDelay(bool enable) { // invalid. For this call instead of plumbing through logic that will immediately indicate that a // connect failed, we will just ignore the noDelay() call if the socket is invalid since error is // going to be raised shortly anyway and it makes the calling code simpler. - if (fd_ == -1) { + if (fd() == -1) { return; } // Don't set NODELAY for unix domain sockets sockaddr addr; socklen_t len = sizeof(addr); - int rc = getsockname(fd_, &addr, &len); + int rc = getsockname(fd(), &addr, &len); RELEASE_ASSERT(rc == 0); if (addr.sa_family == AF_UNIX) { @@ -211,7 +175,7 @@ void ConnectionImpl::noDelay(bool enable) { // Set NODELAY int new_value = enable; - rc = setsockopt(fd_, IPPROTO_TCP, TCP_NODELAY, &new_value, sizeof(new_value)); + rc = setsockopt(fd(), IPPROTO_TCP, TCP_NODELAY, &new_value, sizeof(new_value)); #ifdef __APPLE__ if (-1 == rc && errno == EINVAL) { // Sometimes occurs when the connection is not yet fully formed. Empirically, TCP_NODELAY is @@ -409,7 +373,7 @@ void ConnectionImpl::onFileEvent(uint32_t events) { // It's possible for a write event callback to close the socket (which will cause fd_ to be -1). // In this case ignore write event processing. - if (fd_ != -1 && (events & Event::FileReadyType::Read)) { + if (fd() != -1 && (events & Event::FileReadyType::Read)) { onReadReady(); } } @@ -441,7 +405,7 @@ void ConnectionImpl::onWriteReady() { if (connecting_) { int error; socklen_t error_size = sizeof(error); - int rc = getsockopt(fd_, SOL_SOCKET, SO_ERROR, &error, &error_size); + int rc = getsockopt(fd(), SOL_SOCKET, SO_ERROR, &error, &error_size); ASSERT(0 == rc); UNREFERENCED_PARAMETER(rc); @@ -478,39 +442,13 @@ void ConnectionImpl::onWriteReady() { cb(result.bytes_processed_); // If a callback closes the socket, stop iterating. - if (fd_ == -1) { + if (fd() == -1) { return; } } } } -void ConnectionImpl::doConnect() { - ENVOY_CONN_LOG(debug, "connecting to {}", *this, remote_address_->asString()); - int rc = remote_address_->connect(fd_); - if (rc == 0) { - // write will become ready. - ASSERT(connecting_); - } else { - ASSERT(rc == -1); - if (errno == EINPROGRESS) { - ASSERT(connecting_); - ENVOY_CONN_LOG(debug, "connection in progress", *this); - } else { - // read/write will become ready. - immediate_connection_error_ = true; - connecting_ = false; - ENVOY_CONN_LOG(debug, "immediate connection error: {}", *this, errno); - } - } - - // The local address can only be retrieved for IP connections. Other - // types, such as UDS, don't have a notion of a local address. - if (remote_address_->type() == Address::Type::Ip) { - local_address_ = Address::addressFromFd(fd_); - } -} - void ConnectionImpl::setConnectionStats(const ConnectionStats& stats) { ASSERT(!connection_stats_); connection_stats_.reset(new ConnectionStats(stats)); @@ -540,9 +478,48 @@ ClientConnectionImpl::ClientConnectionImpl( Event::Dispatcher& dispatcher, const Address::InstanceConstSharedPtr& remote_address, const Network::Address::InstanceConstSharedPtr& source_address, Network::TransportSocketPtr&& transport_socket) - : ConnectionImpl(dispatcher, remote_address->socket(Address::SocketType::Stream), - remote_address, nullptr, source_address, std::move(transport_socket), false, - false) {} + : ConnectionImpl(dispatcher, ConnectionSocketPtr{new ClientSocketImpl(remote_address)}, + std::move(transport_socket), false) { + if (source_address != nullptr) { + int rc = source_address->bind(fd()); + if (rc < 0) { + ENVOY_LOG_MISC(debug, "Bind failure. Failed to bind to {}: {}", source_address->asString(), + strerror(errno)); + // Set a special error state to ensure asynchronous close to give the owner of the + // ConnectionImpl a chance to add callbacks and detect the "disconnect" + bind_error_ = true; + + // Trigger a write event to close this connection out-of-band. + file_event_->activate(Event::FileReadyType::Write); + } + } +} + +void ClientConnectionImpl::connect() { + ENVOY_CONN_LOG(debug, "connecting to {}", *this, socket_->remoteAddress()->asString()); + int rc = socket_->remoteAddress()->connect(fd()); + if (rc == 0) { + // write will become ready. + ASSERT(connecting_); + } else { + ASSERT(rc == -1); + if (errno == EINPROGRESS) { + ASSERT(connecting_); + ENVOY_CONN_LOG(debug, "connection in progress", *this); + } else { + // read/write will become ready. + immediate_connection_error_ = true; + connecting_ = false; + ENVOY_CONN_LOG(debug, "immediate connection error: {}", *this, errno); + } + } + + // The local address can only be retrieved for IP connections. Other + // types, such as UDS, don't have a notion of a local address. + if (socket_->remoteAddress()->type() == Address::Type::Ip) { + dynamic_cast(socket_.get())->setLocalAddress(Address::addressFromFd(fd())); + } +} } // namespace Network } // namespace Envoy diff --git a/source/common/network/connection_impl.h b/source/common/network/connection_impl.h index b9c0963f411a1..b3182270eba73 100644 --- a/source/common/network/connection_impl.h +++ b/source/common/network/connection_impl.h @@ -48,17 +48,10 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable { public: // TODO(lizan): Remove the old style constructor when factory is ready. - ConnectionImpl(Event::Dispatcher& dispatcher, int fd, - Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - Address::InstanceConstSharedPtr bind_to_address, bool using_original_dst, - bool connected); - - ConnectionImpl(Event::Dispatcher& dispatcher, int fd, - Address::InstanceConstSharedPtr remote_address, - Address::InstanceConstSharedPtr local_address, - Address::InstanceConstSharedPtr bind_to_address, - TransportSocketPtr&& transport_socket, bool using_original_dst, bool connected); + ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket, bool connected); + + ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket, + TransportSocketPtr&& transport_socket, bool connected); ~ConnectionImpl(); @@ -79,8 +72,12 @@ class ConnectionImpl : public virtual Connection, void readDisable(bool disable) override; void detectEarlyCloseWhenReadDisabled(bool value) override { detect_early_close_ = value; } bool readEnabled() const override; - const Address::InstanceConstSharedPtr& remoteAddress() const override { return remote_address_; } - const Address::InstanceConstSharedPtr& localAddress() const override { return local_address_; } + const Address::InstanceConstSharedPtr& remoteAddress() const override { + return socket_->remoteAddress(); + } + const Address::InstanceConstSharedPtr& localAddress() const override { + return socket_->localAddress(); + } void setConnectionStats(const ConnectionStats& stats) override; Ssl::Connection* ssl() override { return transport_socket_->ssl(); } const Ssl::Connection* ssl() const override { return transport_socket_->ssl(); } @@ -88,7 +85,7 @@ class ConnectionImpl : public virtual Connection, void write(Buffer::Instance& data) override; void setBufferLimits(uint32_t limit) override; uint32_t bufferLimit() const override { return read_buffer_limit_; } - bool usingOriginalDst() const override { return using_original_dst_; } + bool usingOriginalDst() const override { return socket_->localAddressReset(); } bool aboveHighWatermark() const override { return above_high_watermark_; } // Network::BufferSource @@ -96,7 +93,7 @@ class ConnectionImpl : public virtual Connection, Buffer::Instance& getWriteBuffer() override { return *current_write_buffer_; } // Network::TransportSocketCallbacks - int fd() override { return fd_; } + int fd() const override { return socket_->fd(); } Connection& connection() override { return *this; } void raiseEvent(ConnectionEvent event) override; // Should the read buffer be drained? @@ -112,21 +109,25 @@ class ConnectionImpl : public virtual Connection, protected: void closeSocket(ConnectionEvent close_type); - void doConnect(); void onLowWatermark(); void onHighWatermark(); TransportSocketPtr transport_socket_; FilterManagerImpl filter_manager_; - Address::InstanceConstSharedPtr remote_address_; - Address::InstanceConstSharedPtr local_address_; + ConnectionSocketPtr socket_; Buffer::OwnedImpl read_buffer_; // This must be a WatermarkBuffer, but as it is created by a factory the ConnectionImpl only has // a generic pointer. Buffer::InstancePtr write_buffer_; uint32_t read_buffer_limit_ = 0; +protected: + bool connecting_{false}; + bool immediate_connection_error_{false}; + bool bind_error_{false}; + Event::FileEventPtr file_event_; + private: void onFileEvent(uint32_t events); void onRead(uint64_t read_buffer_size); @@ -138,17 +139,11 @@ class ConnectionImpl : public virtual Connection, static std::atomic next_global_id_; Event::Dispatcher& dispatcher_; - int fd_{-1}; - Event::FileEventPtr file_event_; const uint64_t id_; std::list callbacks_; std::list bytes_sent_callbacks_; bool read_enabled_{true}; - bool connecting_{false}; bool close_with_flush_{false}; - bool immediate_connection_error_{false}; - bool bind_error_{false}; - const bool using_original_dst_; bool above_high_watermark_{false}; bool detect_early_close_{true}; Buffer::Instance* current_write_buffer_{}; @@ -172,7 +167,7 @@ class ClientConnectionImpl : public ConnectionImpl, virtual public ClientConnect Network::TransportSocketPtr&& transport_socket); // Network::ClientConnection - void connect() override { doConnect(); } + void connect() override; }; } // namespace Network diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index 9a608e64fbee9..540c2a70aefbf 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -50,44 +50,62 @@ class UdsListenSocket : public ListenSocketImpl { UdsListenSocket(const std::string& uds_path); }; -class AcceptedSocketImpl : public AcceptedSocket { +class ConnectionSocketImpl : virtual public ConnectionSocket { public: - AcceptedSocketImpl(int fd, Address::InstanceConstSharedPtr&& local_address, - Address::InstanceConstSharedPtr&& remote_address) - : fd_(fd), local_address_reset_(false), local_address_(std::move(local_address)), - remote_address_(std::move(remote_address)) {} - ~AcceptedSocketImpl() { + ConnectionSocketImpl(int fd, const Address::InstanceConstSharedPtr& local_address, + const Address::InstanceConstSharedPtr& remote_address) + : fd_(fd), local_address_(local_address), remote_address_(remote_address) {} + ~ConnectionSocketImpl() { close(); } + + // Network::ConnectionSocket + const Address::InstanceConstSharedPtr& localAddress() const override { return local_address_; } + const Address::InstanceConstSharedPtr& remoteAddress() const override { return remote_address_; } + bool localAddressReset() const override { return local_address_reset_; } + int fd() const override { return fd_; } + void close() override { if (fd_ != -1) { ::close(fd_); + fd_ = -1; } } +protected: + int fd_; + Address::InstanceConstSharedPtr local_address_; + Address::InstanceConstSharedPtr remote_address_; + bool local_address_reset_{false}; +}; + +class AcceptedSocketImpl : public AcceptedSocket, public ConnectionSocketImpl { +public: + AcceptedSocketImpl(int fd, const Address::InstanceConstSharedPtr& local_address, + const Address::InstanceConstSharedPtr& remote_address) + : ConnectionSocketImpl(fd, local_address, remote_address) {} + ~AcceptedSocketImpl() {} + // Network::AcceptedSocket - Address::InstanceConstSharedPtr localAddress() const override { return local_address_; } void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) override { if (*local_address != *local_address_) { local_address_ = local_address; local_address_reset_ = true; } } - bool localAddressReset() const override { return local_address_reset_; } - Address::InstanceConstSharedPtr remoteAddress() const override { return remote_address_; } void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) override { remote_address_ = remote_address; } - int fd() const override { return fd_; } +}; - int takeFd() override { - int fd = fd_; - fd_ = -1; - return fd; +class ClientSocketImpl : public ClientSocket, public ConnectionSocketImpl { +public: + ClientSocketImpl(const Address::InstanceConstSharedPtr& remote_address) + : ConnectionSocketImpl(remote_address->socket(Address::SocketType::Stream), nullptr, + remote_address) {} + ~ClientSocketImpl() {} + + // ClientSocket + void setLocalAddress(const Address::InstanceConstSharedPtr& local_address) override { + local_address_ = local_address; } - -protected: - int fd_; - bool local_address_reset_; - Address::InstanceConstSharedPtr local_address_; - Address::InstanceConstSharedPtr remote_address_; }; } // namespace Network diff --git a/source/common/ssl/connection_impl.cc b/source/common/ssl/connection_impl.cc index b0eb524fb7b41..41e706976465b 100644 --- a/source/common/ssl/connection_impl.cc +++ b/source/common/ssl/connection_impl.cc @@ -3,15 +3,10 @@ namespace Envoy { namespace Ssl { -ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, int fd, - Network::Address::InstanceConstSharedPtr remote_address, - Network::Address::InstanceConstSharedPtr local_address, - Network::Address::InstanceConstSharedPtr bind_to_address, - bool using_original_dst, bool connected, Context& ctx, - InitialState state) - : Network::ConnectionImpl(dispatcher, fd, remote_address, local_address, bind_to_address, - Network::TransportSocketPtr{new SslSocket(ctx, state)}, - using_original_dst, connected) {} +ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, Network::ConnectionSocketPtr&& socket, + bool connected, Context& ctx, InitialState state) + : Network::ConnectionImpl(dispatcher, std::move(socket), + Network::TransportSocketPtr{new SslSocket(ctx, state)}, connected) {} } // namespace Ssl } // namespace Envoy diff --git a/source/common/ssl/connection_impl.h b/source/common/ssl/connection_impl.h index 28e6d54b0f925..58052d60987fb 100644 --- a/source/common/ssl/connection_impl.h +++ b/source/common/ssl/connection_impl.h @@ -17,10 +17,7 @@ namespace Ssl { // TODO(lizan): Remove Ssl::ConnectionImpl entirely when factory of TransportSocket is ready. class ConnectionImpl : public Network::ConnectionImpl { public: - ConnectionImpl(Event::Dispatcher& dispatcher, int fd, - Network::Address::InstanceConstSharedPtr remote_address, - Network::Address::InstanceConstSharedPtr local_address, - Network::Address::InstanceConstSharedPtr bind_to_address, bool using_original_dst, + ConnectionImpl(Event::Dispatcher& dispatcher, Network::ConnectionSocketPtr&& socket, bool connected, Context& ctx, InitialState state); }; diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index 581c018108f2e..1f5e819469f25 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -70,11 +70,10 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ConnectionImplDeathTest, TEST_P(ConnectionImplDeathTest, BadFd) { Event::DispatcherImpl dispatcher; - EXPECT_DEATH(ConnectionImpl(dispatcher, -1, - Network::Test::getCanonicalLoopbackAddress(GetParam()), - Network::Test::getCanonicalLoopbackAddress(GetParam()), - Network::Address::InstanceConstSharedPtr(), false, false), - ".*assert failure: fd_ != -1.*"); + EXPECT_DEATH(ConnectionImpl(dispatcher, + ConnectionSocketPtr{new ConnectionSocketImpl(-1, nullptr, nullptr)}, + false), + ".*assert failure: fd\\(\\) != -1.*"); } class ConnectionImplTest : public testing::TestWithParam { @@ -655,10 +654,8 @@ class ConnectionImplBytesSentTest : public testing::Test { .WillOnce(DoAll(SaveArg<1>(&file_ready_cb_), Return(new Event::MockFileEvent))); transport_socket_ = new NiceMock; connection_.reset(new ConnectionImpl( - dispatcher_, 0, Network::Test::getCanonicalLoopbackAddress(Address::IpVersion::v4), - Network::Test::getCanonicalLoopbackAddress(Address::IpVersion::v4), - Network::Address::InstanceConstSharedPtr(), TransportSocketPtr(transport_socket_), false, - true)); + dispatcher_, ConnectionSocketPtr{new ConnectionSocketImpl(0, nullptr, nullptr)}, + TransportSocketPtr(transport_socket_), true)); connection_->addConnectionCallbacks(callbacks_); } diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index e1479d81b8897..d4824792b272f 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -172,7 +172,7 @@ MockListenSocket::MockListenSocket() : local_address_(new Address::Ipv4Instance( MockListenSocket::~MockListenSocket() {} MockAcceptedSocket::MockAcceptedSocket() : local_address_(new Address::Ipv4Instance(80)) { - ON_CALL(*this, localAddress()).WillByDefault(Return(local_address_)); + ON_CALL(*this, localAddress()).WillByDefault(ReturnRef(local_address_)); } MockAcceptedSocket::~MockAcceptedSocket() {} diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 59bb80dca13b6..85d89d508a8a4 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -264,13 +264,13 @@ class MockAcceptedSocket : public AcceptedSocket { MockAcceptedSocket(); ~MockAcceptedSocket(); - MOCK_CONST_METHOD0(localAddress, Address::InstanceConstSharedPtr()); + MOCK_CONST_METHOD0(localAddress, const Address::InstanceConstSharedPtr&()); MOCK_METHOD1(resetLocalAddress, void(const Address::InstanceConstSharedPtr&)); MOCK_CONST_METHOD0(localAddressReset, bool()); - MOCK_CONST_METHOD0(remoteAddress, Address::InstanceConstSharedPtr()); + MOCK_CONST_METHOD0(remoteAddress, const Address::InstanceConstSharedPtr&()); MOCK_METHOD1(resetRemoteAddress, void(const Address::InstanceConstSharedPtr&)); MOCK_CONST_METHOD0(fd, int()); - MOCK_METHOD0(takeFd, int()); + MOCK_METHOD0(close, void()); Address::InstanceConstSharedPtr local_address_; }; diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index a1e0b695de8f7..0d3a227a3fc53 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -15,6 +15,7 @@ using testing::InSequence; using testing::Invoke; using testing::NiceMock; using testing::Return; +using testing::ReturnRef; using testing::_; namespace Envoy { @@ -282,7 +283,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { })); EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); - EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(alt_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); @@ -344,7 +345,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { })); EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); - EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(alt_address)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(alt_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); @@ -391,7 +392,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { })); EXPECT_CALL(*accepted_socket, resetLocalAddress(original_dst_address)); EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); - EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(original_dst_address)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(original_dst_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); @@ -429,7 +430,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { })); EXPECT_CALL(*test_filter, onAccept(_)).WillOnce(Return(Network::FilterStatus::Continue)); EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(false)); - EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(Return(normal_address)); + EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(normal_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); From 07629cbda19db5dc64c044c8945e0fb8d295ba95 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 16 Jan 2018 23:27:51 -0800 Subject: [PATCH 28/41] filter: Avoid using bare pointer. Use unique_ptr instead of a bare pointer in addAcceptFilter() listener filter callback. Signed-off-by: Jarno Rajahalme --- include/envoy/network/filter.h | 2 +- source/server/config/listener/original_dst.cc | 3 ++- source/server/config/listener/proxy_protocol.cc | 3 ++- source/server/connection_handler_impl.h | 4 ++-- test/mocks/network/mocks.h | 4 +++- test/server/connection_handler_test.cc | 8 ++++---- test/server/listener_manager_impl_test.cc | 12 +++++------- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index 032d2207b450a..cea55616bf27c 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -206,7 +206,7 @@ class ListenerFilterManager { * first is called first). * @param filter supplies the filter being added. */ - virtual void addAcceptFilter(ListenerFilter* filter) PURE; + virtual void addAcceptFilter(ListenerFilterPtr&& filter) PURE; }; /** diff --git a/source/server/config/listener/original_dst.cc b/source/server/config/listener/original_dst.cc index 37eef2b779a5b..9693f18db60ca 100644 --- a/source/server/config/listener/original_dst.cc +++ b/source/server/config/listener/original_dst.cc @@ -19,7 +19,8 @@ class OriginalDstConfigFactory : public NamedListenerFilterConfigFactory { ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext&) override { return [](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(new Filter::Listener::OriginalDst()); + filter_manager.addAcceptFilter( + Network::ListenerFilterPtr{new Filter::Listener::OriginalDst()}); }; } diff --git a/source/server/config/listener/proxy_protocol.cc b/source/server/config/listener/proxy_protocol.cc index 4dcdd060eb902..6cec00a94ebe9 100644 --- a/source/server/config/listener/proxy_protocol.cc +++ b/source/server/config/listener/proxy_protocol.cc @@ -21,7 +21,8 @@ class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { Filter::Listener::ProxyProtocol::ConfigSharedPtr config( new Filter::Listener::ProxyProtocol::Config(context.scope())); return [config](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(new Filter::Listener::ProxyProtocol::Instance(config)); + filter_manager.addAcceptFilter( + Network::ListenerFilterPtr{new Filter::Listener::ProxyProtocol::Instance(config)}); }; } diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index feba76180e0a0..f0aafeabd6ff1 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -144,8 +144,8 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { } // Network::ListenerFilterManager - void addAcceptFilter(Network::ListenerFilter* filter) override { - accept_filters_.emplace_back(filter); + void addAcceptFilter(Network::ListenerFilterPtr&& filter) override { + accept_filters_.emplace_back(std::move(filter)); } // Network::ListenerFilterCallbacks diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 85d89d508a8a4..eb39a0b3c5570 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -235,7 +235,9 @@ class MockListenerFilterManager : public ListenerFilterManager { MockListenerFilterManager(); ~MockListenerFilterManager(); - MOCK_METHOD1(addAcceptFilter, void(Network::ListenerFilter*)); + void addAcceptFilter(Network::ListenerFilterPtr&& filter) override { addAcceptFilter_(filter); } + + MOCK_METHOD1(addAcceptFilter_, void(Network::ListenerFilterPtr&)); }; class MockFilterChainFactory : public FilterChainFactory { diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 0d3a227a3fc53..d8ed9357bef40 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -271,7 +271,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. if (!redirected) { - manager.addAcceptFilter(test_filter); + manager.addAcceptFilter(Network::ListenerFilterPtr{test_filter}); redirected = true; } return true; @@ -330,7 +330,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. if (!redirected) { - manager.addAcceptFilter(test_filter); + manager.addAcceptFilter(Network::ListenerFilterPtr{test_filter}); redirected = true; } return true; @@ -382,7 +382,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. - manager.addAcceptFilter(test_filter); + manager.addAcceptFilter(Network::ListenerFilterPtr{test_filter}); return true; })); EXPECT_CALL(*test_filter, onAccept(_)) @@ -425,7 +425,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. - manager.addAcceptFilter(test_filter); + manager.addAcceptFilter(Network::ListenerFilterPtr{test_filter}); return true; })); EXPECT_CALL(*test_filter, onAccept(_)).WillOnce(Return(Network::FilterStatus::Continue)); diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 72fb886878f13..17cb420fd5570 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1085,10 +1085,9 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { return socket; })); - EXPECT_CALL(manager, addAcceptFilter(_)) - .WillOnce(Invoke([&](Network::ListenerFilter* filter) -> void { + EXPECT_CALL(manager, addAcceptFilter_(_)) + .WillOnce(Invoke([&](Network::ListenerFilterPtr& filter) -> void { EXPECT_EQ(Network::FilterStatus::Continue, filter->onAccept(callbacks)); - delete filter; })); EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); @@ -1109,7 +1108,7 @@ class OriginalDstTestConfigFactory : public NamedListenerFilterConfigFactory { ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext&) override { return [](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(new OriginalDstTest()); + filter_manager.addAcceptFilter(Network::ListenerFilterPtr{new OriginalDstTest()}); }; } @@ -1160,10 +1159,9 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstTestFilter) { return socket; })); - EXPECT_CALL(manager, addAcceptFilter(_)) - .WillOnce(Invoke([&](Network::ListenerFilter* filter) -> void { + EXPECT_CALL(manager, addAcceptFilter_(_)) + .WillOnce(Invoke([&](Network::ListenerFilterPtr& filter) -> void { EXPECT_EQ(Network::FilterStatus::Continue, filter->onAccept(callbacks)); - delete filter; })); EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); From de46c3bdf891440bd4a6147e7fd6bb72466b9022 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 16 Jan 2018 23:41:01 -0800 Subject: [PATCH 29/41] Fix comments, add TODO. Signed-off-by: Jarno Rajahalme --- include/envoy/network/filter.h | 5 ++--- include/envoy/network/listen_socket.h | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index cea55616bf27c..c437f3a75059e 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -217,7 +217,7 @@ class FilterChainFactory { virtual ~FilterChainFactory() {} /** - * Called to create the filter chain. + * Called to create the network filter chain. * @param connection supplies the connection to create the chain on. * @return true if filter chain was created successfully. Otherwise * false, e.g. filter chain is empty. @@ -227,8 +227,7 @@ class FilterChainFactory { /** * Called to create the listener filter chain. * @param listener supplies the listener to create the chain on. - * @return true if filter chain was created successfully. Otherwise - * false. + * @return true if filter chain was created successfully. Otherwise false. */ virtual bool createListenerFilterChain(ListenerFilterManager& listener) PURE; }; diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 3b31342d65279..89dd3d2e422fd 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -71,6 +71,9 @@ typedef std::unique_ptr ConnectionSocketPtr; /** * An abstract accepted socket. + * + * TODO(jrajahalme): Hide internals (e.g., fd) from the filters by providing callbacks filters + * may need (set/getsockopt(), peek(), recv(), etc.) */ class AcceptedSocket : virtual public ConnectionSocket { public: From 13cba7216a99e7bbc8d9abe034cb208feb61f69c Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Wed, 17 Jan 2018 13:34:00 -0800 Subject: [PATCH 30/41] listen_socket: Add comment on ClientSocket. Signed-off-by: Jarno Rajahalme --- include/envoy/network/listen_socket.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 89dd3d2e422fd..12e9013cbf60e 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -94,6 +94,9 @@ class AcceptedSocket : virtual public ConnectionSocket { typedef std::unique_ptr AcceptedSocketPtr; +/** + * An abstract client socket used with ClientConnections. + */ class ClientSocket : virtual public ConnectionSocket { public: virtual ~ClientSocket() {} From 7d82bbe2e20ac5331adf69beabf9a1afd0429374 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Wed, 17 Jan 2018 13:34:53 -0800 Subject: [PATCH 31/41] config_schemas: Revert remaining v1 changes for listener filters. Signed-off-by: Jarno Rajahalme --- source/common/json/config_schemas.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index 1159922b949e2..f887d8e121d6d 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -178,10 +178,6 @@ const std::string Json::Schema::LISTENER_SCHEMA(R"EOF( "properties": { "name": {"type": "string"}, "address": {"type": "string"}, - "listener_filters" : { - "type" : "array", - "items": {"$ref" : "#/definitions/listener_filters"} - }, "filters" : { "type" : "array", "items": {"$ref" : "#/definitions/filters"} From 61da63ff38a96ca9f9ba1bd2c15a0b630bafc1a2 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Wed, 17 Jan 2018 17:51:48 -0800 Subject: [PATCH 32/41] Review fixes. Revamp the AcceptedSocket abstract class hierarchy, now using ConnectionSocket instead of AcceptedSocket. The instance is still created as AcceptedSocketImpl. Signed-off-by: Jarno Rajahalme --- include/envoy/event/dispatcher.h | 6 +- include/envoy/network/connection.h | 6 +- include/envoy/network/filter.h | 8 +-- include/envoy/network/listen_socket.h | 67 ++++++++----------- include/envoy/network/listener.h | 4 +- source/common/config/well_known_names.h | 6 +- source/common/event/dispatcher_impl.cc | 2 +- source/common/event/dispatcher_impl.h | 2 +- source/common/filter/listener/original_dst.cc | 11 +-- source/common/filter/listener/original_dst.h | 4 +- .../common/filter/listener/proxy_protocol.cc | 8 +-- .../common/filter/listener/proxy_protocol.h | 2 +- source/common/network/connection_impl.cc | 6 +- source/common/network/connection_impl.h | 2 +- source/common/network/listen_socket_impl.h | 36 ++++------ source/common/network/listener_impl.cc | 8 +-- source/common/ssl/connection_impl.cc | 2 +- .../common/upstream/original_dst_cluster.cc | 4 +- source/server/config/listener/original_dst.cc | 5 +- .../server/config/listener/proxy_protocol.cc | 4 +- source/server/connection_handler_impl.cc | 39 ++++++----- source/server/connection_handler_impl.h | 16 ++--- source/server/http/admin.h | 2 +- test/common/http/codec_client_test.cc | 2 +- test/common/network/connection_impl_test.cc | 19 +++--- test/common/network/dns_impl_test.cc | 2 +- test/common/network/listener_impl_test.cc | 6 +- test/common/ssl/ssl_socket_test.cc | 20 +++--- .../upstream/original_dst_cluster_test.cc | 14 ++-- test/mocks/event/mocks.h | 4 +- test/mocks/network/mocks.cc | 4 +- test/mocks/network/mocks.h | 22 +++--- test/server/connection_handler_test.cc | 36 +++++----- test/server/listener_manager_impl_test.cc | 24 +++---- 34 files changed, 194 insertions(+), 209 deletions(-) diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 85f69448cf514..ed9aecd211b61 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -40,12 +40,12 @@ class Dispatcher { /** * Create a server connection. - * @param socket supplies an accepted socket with an open file descriptor and connection metadata - * to use for the connection. Takes ownership of the socket. + * @param socket supplies an open file descriptor and connection metadata to use for the + * connection. Takes ownership of the socket. * @param ssl_ctx supplies the SSL context to use, if not nullptr. * @return Network::ConnectionPtr a server connection that is owned by the caller. */ - virtual Network::ConnectionPtr createServerConnection(Network::AcceptedSocketPtr&& socket, + virtual Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, Ssl::Context* ssl_ctx) PURE; /** diff --git a/include/envoy/network/connection.h b/include/envoy/network/connection.h index 35ce5ca4f44e9..f7e5d074b8b90 100644 --- a/include/envoy/network/connection.h +++ b/include/envoy/network/connection.h @@ -207,10 +207,10 @@ class Connection : public Event::DeferredDeletable, public FilterManager { virtual uint32_t bufferLimit() const PURE; /** - * @return boolean telling if the connection's local address is an original destination address, - * rather than the listener's address. + * @return boolean telling if the connection's local address has been restored to an original + * destination address, rather than the address the connection was accepted at. */ - virtual bool usingOriginalDst() const PURE; + virtual bool localAddressRestored() const PURE; /** * @return boolean telling if the connection is currently above the high watermark. diff --git a/include/envoy/network/filter.h b/include/envoy/network/filter.h index c437f3a75059e..202b16b51804f 100644 --- a/include/envoy/network/filter.h +++ b/include/envoy/network/filter.h @@ -9,7 +9,7 @@ namespace Envoy { namespace Network { class Connection; -class AcceptedSocket; +class ConnectionSocket; /** * Status codes returned by filters that can cause future filters to not get iterated to. @@ -157,12 +157,12 @@ class ListenerFilterCallbacks { virtual ~ListenerFilterCallbacks() {} /** - * @return the AcceptedSocket that owns this manager and the managed filters. + * @return ConnectionSocket the socket the filter is operating on. */ - virtual AcceptedSocket& socket() PURE; + virtual ConnectionSocket& socket() PURE; /** - * @return the Dispatcher for this manager. + * @return the Dispatcher for issuing events. */ virtual Event::Dispatcher& dispatcher() PURE; diff --git a/include/envoy/network/listen_socket.h b/include/envoy/network/listen_socket.h index 12e9013cbf60e..9ccd3b9124c53 100644 --- a/include/envoy/network/listen_socket.h +++ b/include/envoy/network/listen_socket.h @@ -35,7 +35,11 @@ typedef std::unique_ptr ListenSocketPtr; typedef std::shared_ptr ListenSocketSharedPtr; /** - * A socket passed to a connection. + * A socket passed to a connection. For server connections this represents the accepted socket, and + * for client connections this represents the socket being connected to a remote address. + * + * TODO(jrajahalme): Hide internals (e.g., fd) from listener filters by providing callbacks filters + * may need (set/getsockopt(), peek(), recv(), etc.) */ class ConnectionSocket { public: @@ -52,60 +56,43 @@ class ConnectionSocket { virtual const Address::InstanceConstSharedPtr& remoteAddress() const PURE; /** - * @return true if the local address has been reset. + * Set the local address of the socket. On accepted sockets the local address defaults to the + * one at which the connection was received at, which is the same as the listener's address, if + * the listener is bound to a specific address. + * + * @param local_address the new local address. + * @param restored a flag marking the local address as being restored to a value that is + * different from the one the socket was initially accepted at. This should only be set + * to 'true' when restoring the original destination address of a connection redirected + * by iptables REDIRECT. The caller is responsible for making sure the new address is + * actually different when passing restored as 'true'. */ - virtual bool localAddressReset() const PURE; + virtual void setLocalAddress(const Address::InstanceConstSharedPtr& local_address, + bool restored = false) PURE; /** - * @return fd the socket's file descriptor. + * Set the remote address of the socket. */ - virtual int fd() const PURE; + virtual void setRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE; /** - * Close the underlying socket. + * @return true if the local address has been restored to a value that is different from the + * address the socket was initially accepted at. */ - virtual void close() PURE; -}; - -typedef std::unique_ptr ConnectionSocketPtr; - -/** - * An abstract accepted socket. - * - * TODO(jrajahalme): Hide internals (e.g., fd) from the filters by providing callbacks filters - * may need (set/getsockopt(), peek(), recv(), etc.) - */ -class AcceptedSocket : virtual public ConnectionSocket { -public: - virtual ~AcceptedSocket() {} + virtual bool localAddressRestored() const PURE; /** - * Reset the destination address of the socket to a different address than the one - * the socket was accepted at. + * @return fd the socket's file descriptor. */ - virtual void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; + virtual int fd() const PURE; /** - * Reset the source address of the socket to a different address than the one - * the socket was accepted at. + * Close the underlying socket. */ - virtual void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE; + virtual void close() PURE; }; -typedef std::unique_ptr AcceptedSocketPtr; - -/** - * An abstract client socket used with ClientConnections. - */ -class ClientSocket : virtual public ConnectionSocket { -public: - virtual ~ClientSocket() {} - - /** - * Set the local address of the socket. - */ - virtual void setLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE; -}; +typedef std::unique_ptr ConnectionSocketPtr; } // namespace Network } // namespace Envoy diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 23979b69c1665..6ef4a04c11543 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -86,12 +86,12 @@ class ListenerCallbacks { /** * Called when a new connection is accepted. - * @param socket supplies the accepted socket that is moved into the callee. + * @param socket supplies the socket that is moved into the callee. * @param redirected is true when the socket was first accepted by another listener * and is redirected to a new listener. The recipient should not redirect * the socket any further. */ - virtual void onAccept(AcceptedSocketPtr&& socket, bool redirected = false) PURE; + virtual void onAccept(ConnectionSocketPtr&& socket, bool redirected = false) PURE; /** * Called when a new connection is accepted. diff --git a/source/common/config/well_known_names.h b/source/common/config/well_known_names.h index fb02c7cad9745..d5e34f2532a0c 100644 --- a/source/common/config/well_known_names.h +++ b/source/common/config/well_known_names.h @@ -48,14 +48,14 @@ class V1Converter { }; /** - * Well-known network filter names. + * Well-known listener filter names. */ class ListenerFilterNameValues { public: // Original destination listener filter - const std::string ORIGINAL_DST = "envoy.original_dst"; + const std::string ORIGINAL_DST = "envoy.listener.original_dst"; // Proxy Protocol listener filter - const std::string PROXY_PROTOCOL = "envoy.proxy_protocol"; + const std::string PROXY_PROTOCOL = "envoy.listener.proxy_protocol"; }; typedef ConstSingleton ListenerFilterNames; diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index c1c4c86c63ad6..9f6d95f23a65b 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -73,7 +73,7 @@ void DispatcherImpl::clearDeferredDeleteList() { deferred_deleting_ = false; } -Network::ConnectionPtr DispatcherImpl::createServerConnection(Network::AcceptedSocketPtr&& socket, +Network::ConnectionPtr DispatcherImpl::createServerConnection(Network::ConnectionSocketPtr&& socket, Ssl::Context* ssl_ctx) { ASSERT(isThreadSafe()); return Network::ConnectionPtr{ssl_ctx diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 98e34a8e7af02..885ce556dd491 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -33,7 +33,7 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { // Event::Dispatcher void clearDeferredDeleteList() override; - Network::ConnectionPtr createServerConnection(Network::AcceptedSocketPtr&& socket, + Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, Ssl::Context* ssl_ctx) override; Network::ClientConnectionPtr createClientConnection(Network::Address::InstanceConstSharedPtr address, diff --git a/source/common/filter/listener/original_dst.cc b/source/common/filter/listener/original_dst.cc index 29e2231ec3c66..70c7e90b895d2 100644 --- a/source/common/filter/listener/original_dst.cc +++ b/source/common/filter/listener/original_dst.cc @@ -15,18 +15,19 @@ Network::Address::InstanceConstSharedPtr OriginalDst::getOriginalDst(int fd) { Network::FilterStatus OriginalDst::onAccept(Network::ListenerFilterCallbacks& cb) { ENVOY_LOG(debug, "original_dst: New connection accepted"); - Network::AcceptedSocket& socket = cb.socket(); - Network::Address::InstanceConstSharedPtr local_address = socket.localAddress(); + Network::ConnectionSocket& socket = cb.socket(); + const Network::Address::Instance& local_address = *socket.localAddress(); - if (local_address->type() == Network::Address::Type::Ip) { + if (local_address.type() == Network::Address::Type::Ip) { Network::Address::InstanceConstSharedPtr original_local_address = getOriginalDst(socket.fd()); // A listener that has the use_original_dst flag set to true can still receive // connections that are NOT redirected using iptables. If a connection was not redirected, // the address returned by getOriginalDst() matches the local address of the new socket. // In this case the listener handles the connection directly and does not hand it off. - if (original_local_address && (*original_local_address != *local_address)) { - socket.resetLocalAddress(original_local_address); + if (original_local_address && (*original_local_address != local_address)) { + // Restore the local address to the original one. + socket.setLocalAddress(original_local_address, true); } } diff --git a/source/common/filter/listener/original_dst.h b/source/common/filter/listener/original_dst.h index 009316c842add..0cd83157ab6e2 100644 --- a/source/common/filter/listener/original_dst.h +++ b/source/common/filter/listener/original_dst.h @@ -13,10 +13,10 @@ namespace Listener { */ class OriginalDst : public Network::ListenerFilter, Logger::Loggable { public: + virtual Network::Address::InstanceConstSharedPtr getOriginalDst(int fd); + // Network::ListenerFilter Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override; - - virtual Network::Address::InstanceConstSharedPtr getOriginalDst(int fd); }; } // namespace Listener diff --git a/source/common/filter/listener/proxy_protocol.cc b/source/common/filter/listener/proxy_protocol.cc index e6d1c295e4467..098954ab03e2e 100644 --- a/source/common/filter/listener/proxy_protocol.cc +++ b/source/common/filter/listener/proxy_protocol.cc @@ -26,7 +26,7 @@ Config::Config(Stats::Scope& scope) : stats_{ALL_PROXY_PROTOCOL_STATS(POOL_COUNT Network::FilterStatus Instance::onAccept(Network::ListenerFilterCallbacks& cb) { ENVOY_LOG(info, "proxy_protocol: New connection accepted"); - Network::AcceptedSocket& socket = cb.socket(); + Network::ConnectionSocket& socket = cb.socket(); ASSERT(file_event_.get() == nullptr); file_event_ = cb.dispatcher().createFileEvent(socket.fd(), @@ -50,7 +50,7 @@ void Instance::onRead() { } void Instance::onReadWorker() { - Network::AcceptedSocket& socket = cb_->socket(); + Network::ConnectionSocket& socket = cb_->socket(); std::string proxy_line; if (!readLine(socket.fd(), proxy_line)) { return; @@ -115,8 +115,8 @@ void Instance::onReadWorker() { throw EnvoyException("failed to read proxy protocol"); } - socket.resetLocalAddress(local_address); - socket.resetRemoteAddress(remote_address); + socket.setLocalAddress(local_address); + socket.setRemoteAddress(remote_address); cb_->continueFilterChain(true); } diff --git a/source/common/filter/listener/proxy_protocol.h b/source/common/filter/listener/proxy_protocol.h index 522411bd88f43..e938d12c2be0f 100644 --- a/source/common/filter/listener/proxy_protocol.h +++ b/source/common/filter/listener/proxy_protocol.h @@ -44,7 +44,7 @@ typedef std::shared_ptr ConfigSharedPtr; */ class Instance : public Network::ListenerFilter, Logger::Loggable { public: - Instance(ConfigSharedPtr config) : search_index_(1), config_(config) {} + Instance(const ConfigSharedPtr& config) : search_index_(1), config_(config) {} // Network::ListenerFilter Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override; diff --git a/source/common/network/connection_impl.cc b/source/common/network/connection_impl.cc index 2e3159d7425c4..b530510947ff0 100644 --- a/source/common/network/connection_impl.cc +++ b/source/common/network/connection_impl.cc @@ -45,7 +45,7 @@ std::atomic ConnectionImpl::next_global_id_; ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket, bool connected) - : ConnectionImpl(dispatcher, std::move(socket), TransportSocketPtr{new RawBufferSocket}, + : ConnectionImpl(dispatcher, std::move(socket), std::make_unique(), connected) {} ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket, @@ -478,7 +478,7 @@ ClientConnectionImpl::ClientConnectionImpl( Event::Dispatcher& dispatcher, const Address::InstanceConstSharedPtr& remote_address, const Network::Address::InstanceConstSharedPtr& source_address, Network::TransportSocketPtr&& transport_socket) - : ConnectionImpl(dispatcher, ConnectionSocketPtr{new ClientSocketImpl(remote_address)}, + : ConnectionImpl(dispatcher, std::make_unique(remote_address), std::move(transport_socket), false) { if (source_address != nullptr) { int rc = source_address->bind(fd()); @@ -517,7 +517,7 @@ void ClientConnectionImpl::connect() { // The local address can only be retrieved for IP connections. Other // types, such as UDS, don't have a notion of a local address. if (socket_->remoteAddress()->type() == Address::Type::Ip) { - dynamic_cast(socket_.get())->setLocalAddress(Address::addressFromFd(fd())); + socket_->setLocalAddress(Address::addressFromFd(fd())); } } diff --git a/source/common/network/connection_impl.h b/source/common/network/connection_impl.h index b3182270eba73..7cbd9f500e716 100644 --- a/source/common/network/connection_impl.h +++ b/source/common/network/connection_impl.h @@ -85,7 +85,7 @@ class ConnectionImpl : public virtual Connection, void write(Buffer::Instance& data) override; void setBufferLimits(uint32_t limit) override; uint32_t bufferLimit() const override { return read_buffer_limit_; } - bool usingOriginalDst() const override { return socket_->localAddressReset(); } + bool localAddressRestored() const override { return socket_->localAddressRestored(); } bool aboveHighWatermark() const override { return above_high_watermark_; } // Network::BufferSource diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index 540c2a70aefbf..82b2d118acd7c 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -60,7 +60,15 @@ class ConnectionSocketImpl : virtual public ConnectionSocket { // Network::ConnectionSocket const Address::InstanceConstSharedPtr& localAddress() const override { return local_address_; } const Address::InstanceConstSharedPtr& remoteAddress() const override { return remote_address_; } - bool localAddressReset() const override { return local_address_reset_; } + void setLocalAddress(const Address::InstanceConstSharedPtr& local_address, + bool restored) override { + local_address_ = local_address; + local_address_restored_ = restored; + } + void setRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) override { + remote_address_ = remote_address; + } + bool localAddressRestored() const override { return local_address_restored_; } int fd() const override { return fd_; } void close() override { if (fd_ != -1) { @@ -73,39 +81,23 @@ class ConnectionSocketImpl : virtual public ConnectionSocket { int fd_; Address::InstanceConstSharedPtr local_address_; Address::InstanceConstSharedPtr remote_address_; - bool local_address_reset_{false}; + bool local_address_restored_{false}; }; -class AcceptedSocketImpl : public AcceptedSocket, public ConnectionSocketImpl { +// ConnectionSocket used with server connections. +class AcceptedSocketImpl : public ConnectionSocketImpl { public: AcceptedSocketImpl(int fd, const Address::InstanceConstSharedPtr& local_address, const Address::InstanceConstSharedPtr& remote_address) : ConnectionSocketImpl(fd, local_address, remote_address) {} - ~AcceptedSocketImpl() {} - - // Network::AcceptedSocket - void resetLocalAddress(const Address::InstanceConstSharedPtr& local_address) override { - if (*local_address != *local_address_) { - local_address_ = local_address; - local_address_reset_ = true; - } - } - void resetRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) override { - remote_address_ = remote_address; - } }; -class ClientSocketImpl : public ClientSocket, public ConnectionSocketImpl { +// ConnectionSocket used with client connections. +class ClientSocketImpl : public ConnectionSocketImpl { public: ClientSocketImpl(const Address::InstanceConstSharedPtr& remote_address) : ConnectionSocketImpl(remote_address->socket(Address::SocketType::Stream), nullptr, remote_address) {} - ~ClientSocketImpl() {} - - // ClientSocket - void setLocalAddress(const Address::InstanceConstSharedPtr& local_address) override { - local_address_ = local_address; - } }; } // namespace Network diff --git a/source/common/network/listener_impl.cc b/source/common/network/listener_impl.cc index 58181b56c7415..dc750aa412ec7 100644 --- a/source/common/network/listener_impl.cc +++ b/source/common/network/listener_impl.cc @@ -23,10 +23,10 @@ Address::InstanceConstSharedPtr ListenerImpl::getLocalAddress(int fd) { void ListenerImpl::listenCallback(evconnlistener*, evutil_socket_t fd, sockaddr* remote_addr, int remote_addr_len, void* arg) { ListenerImpl* listener = static_cast(arg); - AcceptedSocketPtr socket(new AcceptedSocketImpl( + ConnectionSocketPtr socket(new AcceptedSocketImpl( fd, - // Get the local address from the new socket if the listener is listening on the all hosts - // address (e.g., 0.0.0.0 for IPv4). + // Get the local address from the new socket if the listener is listening on IP ANY + // (e.g., 0.0.0.0 for IPv4) (local_address_ is nullptr in this case). !listener->local_address_ ? listener->getLocalAddress(fd) : listener->local_address_, // The accept() call that filled in remote_addr doesn't fill in more than the sa_family field // for Unix domain sockets; apparently there isn't a mechanism in the kernel to get the @@ -42,7 +42,7 @@ void ListenerImpl::listenCallback(evconnlistener*, evutil_socket_t fd, sockaddr* ListenerImpl::ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, bool bind_to_port) : local_address_(nullptr), cb_(cb), listener_(nullptr) { - auto ip = socket.localAddress()->ip(); + const auto ip = socket.localAddress()->ip(); // Only use the listen socket's local address for new connections if it is not the all hosts // address (e.g., 0.0.0.0 for IPv4). diff --git a/source/common/ssl/connection_impl.cc b/source/common/ssl/connection_impl.cc index 41e706976465b..7df4f5d2a8f7a 100644 --- a/source/common/ssl/connection_impl.cc +++ b/source/common/ssl/connection_impl.cc @@ -6,7 +6,7 @@ namespace Ssl { ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, Network::ConnectionSocketPtr&& socket, bool connected, Context& ctx, InitialState state) : Network::ConnectionImpl(dispatcher, std::move(socket), - Network::TransportSocketPtr{new SslSocket(ctx, state)}, connected) {} + std::make_unique(ctx, state), connected) {} } // namespace Ssl } // namespace Envoy diff --git a/source/common/upstream/original_dst_cluster.cc b/source/common/upstream/original_dst_cluster.cc index 93f41b28e80b0..0c8ae80f7cad3 100644 --- a/source/common/upstream/original_dst_cluster.cc +++ b/source/common/upstream/original_dst_cluster.cc @@ -43,8 +43,8 @@ HostConstSharedPtr OriginalDstCluster::LoadBalancer::chooseHost(LoadBalancerCont const Network::Connection* connection = context->downstreamConnection(); // The local address of the downstream connection is the original destination address, - // if usingOriginalDst() returns 'true'. - if (connection && connection->usingOriginalDst()) { + // if localAddressRestored() returns 'true'. + if (connection && connection->localAddressRestored()) { const Network::Address::Instance& dst_addr = *connection->localAddress(); // Check if a host with the destination address is already in the host set. diff --git a/source/server/config/listener/original_dst.cc b/source/server/config/listener/original_dst.cc index 9693f18db60ca..33adae73253fa 100644 --- a/source/server/config/listener/original_dst.cc +++ b/source/server/config/listener/original_dst.cc @@ -19,13 +19,12 @@ class OriginalDstConfigFactory : public NamedListenerFilterConfigFactory { ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext&) override { return [](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter( - Network::ListenerFilterPtr{new Filter::Listener::OriginalDst()}); + filter_manager.addAcceptFilter(std::make_unique()); }; } ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + return std::make_unique(); } std::string name() override { return Config::ListenerFilterNames::get().ORIGINAL_DST; } diff --git a/source/server/config/listener/proxy_protocol.cc b/source/server/config/listener/proxy_protocol.cc index 6cec00a94ebe9..3c983ab9b2109 100644 --- a/source/server/config/listener/proxy_protocol.cc +++ b/source/server/config/listener/proxy_protocol.cc @@ -22,12 +22,12 @@ class ProxyProtocolConfigFactory : public NamedListenerFilterConfigFactory { new Filter::Listener::ProxyProtocol::Config(context.scope())); return [config](Network::ListenerFilterManager& filter_manager) -> void { filter_manager.addAcceptFilter( - Network::ListenerFilterPtr{new Filter::Listener::ProxyProtocol::Instance(config)}); + std::make_unique(config)); }; } ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + return std::make_unique(); } std::string name() override { return Config::ListenerFilterNames::get().PROXY_PROTOCOL; } diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index e33b22d59389f..25028c3791e6b 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -75,6 +75,8 @@ ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& par legacy_stats_(new Filter::Listener::ProxyProtocol::Config(config.listenerScope())) {} ConnectionHandlerImpl::ActiveListener::~ActiveListener() { + // Purge sockets that have not progressed to connections. This should only happen when + // a listener filter stops iteration and never resumes. while (!sockets_.empty()) { ActiveSocketPtr removed = sockets_.front()->removeFromList(sockets_); parent_.dispatcher_.deferredDelete(std::move(removed)); @@ -98,7 +100,7 @@ ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Insta // This is a linear operation, may need to add a map to improve performance. // However, linear performance might be adequate since the number of listeners is small. // We do not return stopped listeners. - auto iter = std::find_if( + auto listener_it = std::find_if( listeners_.begin(), listeners_.end(), [&address](const std::pair& p) { return p.second->listener_ != nullptr && p.first->type() == Network::Address::Type::Ip && @@ -106,20 +108,20 @@ ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Insta }); // If there is exact address match, return the corresponding listener. - if (iter != listeners_.end()) { - return iter->second.get(); + if (listener_it != listeners_.end()) { + return listener_it->second.get(); } // Otherwise, we need to look for the wild card match, i.e., 0.0.0.0:[address_port]. // We do not return stopped listeners. // TODO(wattli): consolidate with previous search for more efficiency. - iter = std::find_if( + listener_it = std::find_if( listeners_.begin(), listeners_.end(), [&address](const std::pair& p) { return p.second->listener_ != nullptr && p.first->type() == Network::Address::Type::Ip && p.first->ip()->port() == address.ip()->port() && p.first->ip()->isAnyAddress(); }); - return (iter != listeners_.end()) ? iter->second.get() : nullptr; + return (listener_it != listeners_.end()) ? listener_it->second.get() : nullptr; } void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { @@ -143,9 +145,9 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { // Successfully ran all the accept filters. // Check if the socket may need to be redirected to another listener. - if (!redirected_ && socket_->localAddressReset()) { + if (!redirected_ && socket_->localAddressRestored()) { // Find a listener associated with the original destination address. - new_listener = listener_->parent_.findActiveListenerByAddress(*socket_->localAddress()); + new_listener = listener_.parent_.findActiveListenerByAddress(*socket_->localAddress()); } if (new_listener != nullptr) { // Hands off connections redirecrted by iptables to the listener associated with the @@ -153,20 +155,23 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { new_listener->onAccept(std::move(socket_), true); } else { // Create a new connection on this listener. - listener_->newConnection(std::move(socket_)); + listener_.newConnection(std::move(socket_)); } } // Filter execution concluded, clear state. iter_ = accept_filters_.end(); - ActiveSocketPtr removed = removeFromList(listener_->sockets_); - listener_->parent_.dispatcher_.deferredDelete(std::move(removed)); + // Unlink and delete this ActiveSocket if it was linked. + if (inserted()) { + ActiveSocketPtr removed = removeFromList(listener_.sockets_); + listener_.parent_.dispatcher_.deferredDelete(std::move(removed)); + } } -void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr&& socket, +void ConnectionHandlerImpl::ActiveListener::onAccept(Network::ConnectionSocketPtr&& socket, bool redirected) { Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); - ActiveSocket* active_socket(new ActiveSocket(*this, std::move(socket), redirected)); + auto active_socket = std::make_unique(*this, std::move(socket), redirected); // Implicitly add legacy filters if (config_.useOriginalDst()) { @@ -179,12 +184,16 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::AcceptedSocketPtr& // Create and run the filters config_.filterChainFactory().createListenerFilterChain(*active_socket); - ActiveSocketPtr as(active_socket); - as->moveIntoListBack(std::move(as), sockets_); active_socket->continueFilterChain(true); + + // Move active_socket to the sockets_ list if filter iteration needs to continue later. + // Otherwise we let active_socket be destructed when it goes out of scope. + if (active_socket->iter_ != active_socket->accept_filters_.end()) { + active_socket->moveIntoListBack(std::move(active_socket), sockets_); + } } -void ConnectionHandlerImpl::ActiveListener::newConnection(Network::AcceptedSocketPtr&& socket) { +void ConnectionHandlerImpl::ActiveListener::newConnection(Network::ConnectionSocketPtr&& socket) { Network::ConnectionPtr new_connection = parent_.dispatcher_.createServerConnection(std::move(socket), config_.defaultSslContext()); new_connection->setBufferLimits(config_.perConnectionBufferLimitBytes()); diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index f0aafeabd6ff1..3efe04dba9e40 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -77,7 +77,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ~ActiveListener(); // Network::ListenerCallbacks - void onAccept(Network::AcceptedSocketPtr&& socket, bool redirected) override; + void onAccept(Network::ConnectionSocketPtr&& socket, bool redirected) override; void onNewConnection(Network::ConnectionPtr&& new_connection) override; /** @@ -89,7 +89,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { /** * Create a new connection from a socket accepted by the listener. */ - void newConnection(Network::AcceptedSocketPtr&& socket); + void newConnection(Network::ConnectionSocketPtr&& socket); ConnectionHandlerImpl& parent_; Network::ListenerPtr listener_; @@ -135,8 +135,8 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { public Network::ListenerFilterCallbacks, LinkedObject, public Event::DeferredDeletable { - ActiveSocket(ActiveListener& listener, Network::AcceptedSocketPtr&& socket, bool redirected) - : listener_(&listener), socket_(std::move(socket)), redirected_(redirected), + ActiveSocket(ActiveListener& listener, Network::ConnectionSocketPtr&& socket, bool redirected) + : listener_(listener), socket_(std::move(socket)), redirected_(redirected), iter_(accept_filters_.end()) {} ~ActiveSocket() { ASSERT(iter_ == accept_filters_.end()); @@ -149,12 +149,12 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { } // Network::ListenerFilterCallbacks - Network::AcceptedSocket& socket() override { return *socket_.get(); } - Event::Dispatcher& dispatcher() override { return listener_->parent_.dispatcher_; } + Network::ConnectionSocket& socket() override { return *socket_.get(); } + Event::Dispatcher& dispatcher() override { return listener_.parent_.dispatcher_; } void continueFilterChain(bool success) override; - ActiveListener* listener_; - Network::AcceptedSocketPtr socket_; + ActiveListener& listener_; + Network::ConnectionSocketPtr socket_; bool redirected_; std::list accept_filters_; std::list::iterator iter_; diff --git a/source/server/http/admin.h b/source/server/http/admin.h index adc8ab35b9e52..021ec302ce63a 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -184,7 +184,7 @@ class AdminImpl : public Admin, const std::string& name() const override { return name_; } AdminImpl& parent_; - std::string name_; + const std::string name_; Stats::ScopePtr scope_; Http::ConnectionManagerListenerStats stats_; }; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index f9f9bbee28fe5..4bafdd6fd3235 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -189,7 +189,7 @@ class CodecNetworkTest : public testing::TestWithParam void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index 1f5e819469f25..d0a6783095d12 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -71,8 +71,7 @@ INSTANTIATE_TEST_CASE_P(IpVersions, ConnectionImplDeathTest, TEST_P(ConnectionImplDeathTest, BadFd) { Event::DispatcherImpl dispatcher; EXPECT_DEATH(ConnectionImpl(dispatcher, - ConnectionSocketPtr{new ConnectionSocketImpl(-1, nullptr, nullptr)}, - false), + std::make_unique(-1, nullptr, nullptr), false), ".*assert failure: fd\\(\\) != -1.*"); } @@ -90,7 +89,7 @@ class ConnectionImplTest : public testing::TestWithParam { EXPECT_EQ(nullptr, client_connection_->ssl()); const Network::ClientConnection& const_connection = *client_connection_; EXPECT_EQ(nullptr, const_connection.ssl()); - EXPECT_FALSE(client_connection_->usingOriginalDst()); + EXPECT_FALSE(client_connection_->localAddressRestored()); } void connect() { @@ -98,7 +97,7 @@ class ConnectionImplTest : public testing::TestWithParam { client_connection_->connect(); read_filter_.reset(new NiceMock()); EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -193,7 +192,7 @@ TEST_P(ConnectionImplTest, CloseDuringConnectCallback) { read_filter_.reset(new NiceMock()); EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -247,7 +246,7 @@ TEST_P(ConnectionImplTest, ConnectionStats) { read_filter_.reset(new NiceMock()); MockConnectionStats server_connection_stats; EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); listener_callbacks_.onNewConnection(std::move(new_connection)); @@ -653,9 +652,9 @@ class ConnectionImplBytesSentTest : public testing::Test { EXPECT_CALL(dispatcher_, createFileEvent_(0, _, _, _)) .WillOnce(DoAll(SaveArg<1>(&file_ready_cb_), Return(new Event::MockFileEvent))); transport_socket_ = new NiceMock; - connection_.reset(new ConnectionImpl( - dispatcher_, ConnectionSocketPtr{new ConnectionSocketImpl(0, nullptr, nullptr)}, - TransportSocketPtr(transport_socket_), true)); + connection_.reset( + new ConnectionImpl(dispatcher_, std::make_unique(0, nullptr, nullptr), + TransportSocketPtr(transport_socket_), true)); connection_->addConnectionCallbacks(callbacks_); } @@ -762,7 +761,7 @@ class ReadBufferLimitTest : public ConnectionImplTest { read_filter_.reset(new NiceMock()); EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), nullptr); new_connection->setBufferLimits(read_buffer_limit); diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index dbaf6dcd59d2a..0911b266a79e4 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -200,7 +200,7 @@ class TestDnsServer : public ListenerCallbacks { public: TestDnsServer(Event::DispatcherImpl& dispatcher) : dispatcher_(dispatcher) {} - void onAccept(AcceptedSocketPtr&& socket, bool) override { + void onAccept(ConnectionSocketPtr&& socket, bool) override { Network::ConnectionPtr new_connection = dispatcher_.createServerConnection(std::move(socket), nullptr); onNewConnection(std::move(new_connection)); diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index a35c0787e8554..f0ffa5818c6df 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -35,7 +35,7 @@ static void errorCallbackTest(Address::IpVersion version) { client_connection->connect(); EXPECT_CALL(listener_callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); @@ -101,7 +101,7 @@ TEST_P(ListenerImplTest, UseActualDst) { EXPECT_CALL(listener_callbacks2, onAccept_(_, _)).Times(0); EXPECT_CALL(listener_callbacks1, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks1.onNewConnection(std::move(new_connection)); @@ -136,7 +136,7 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { EXPECT_CALL(listener, getLocalAddress(_)).WillOnce(Return(local_dst_address)); EXPECT_CALL(listener_callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), nullptr); listener_callbacks.onNewConnection(std::move(new_connection)); diff --git a/test/common/ssl/ssl_socket_test.cc b/test/common/ssl/ssl_socket_test.cc index 355ef5b7e0eb8..7fd57b2ef9cc7 100644 --- a/test/common/ssl/ssl_socket_test.cc +++ b/test/common/ssl/ssl_socket_test.cc @@ -70,7 +70,7 @@ void testUtil(const std::string& client_ctx_json, const std::string& server_ctx_ Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -172,7 +172,7 @@ const std::string testUtilV2(const envoy::api::v2::Listener& server_proto, Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_contexts[0].get()); callbacks.onNewConnection(std::move(new_connection)); @@ -537,7 +537,7 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -613,7 +613,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -679,7 +679,7 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, SSL_SESSION* ssl_session = nullptr; Network::ConnectionPtr server_connection; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillRepeatedly(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { ServerContext* ctx = socket->localAddress() == socket1.localAddress() ? server_ctx1.get() : server_ctx2.get(); Network::ConnectionPtr new_connection = @@ -976,7 +976,7 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillRepeatedly(Invoke([&](Network::AcceptedSocketPtr& accepted_socket, bool) -> void { + .WillRepeatedly(Invoke([&](Network::ConnectionSocketPtr& accepted_socket, bool) -> void { ServerContext* ctx = accepted_socket->localAddress() == socket.localAddress() ? server_ctx.get() : server2_ctx.get(); @@ -1068,7 +1068,7 @@ TEST_P(SslSocketTest, SslError) { Network::ConnectionPtr server_connection; Network::MockConnectionCallbacks server_connection_callbacks; EXPECT_CALL(callbacks, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher.createServerConnection(std::move(socket), server_ctx.get()); callbacks.onNewConnection(std::move(new_connection)); @@ -1679,7 +1679,7 @@ class SslReadBufferLimitTest : public SslCertsTest, initialize(); EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); @@ -1762,7 +1762,7 @@ class SslReadBufferLimitTest : public SslCertsTest, .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_->exit(); })); EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(read_buffer_limit); @@ -1879,7 +1879,7 @@ TEST_P(SslReadBufferLimitTest, TestBind) { initialize(); EXPECT_CALL(listener_callbacks_, onAccept_(_, _)) - .WillOnce(Invoke([&](Network::AcceptedSocketPtr& socket, bool) -> void { + .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket, bool) -> void { Network::ConnectionPtr new_connection = dispatcher_->createServerConnection(std::move(socket), server_ctx_.get()); new_connection->setBufferLimits(0); diff --git a/test/common/upstream/original_dst_cluster_test.cc b/test/common/upstream/original_dst_cluster_test.cc index 22b24fb80a6f2..f676de9b640ea 100644 --- a/test/common/upstream/original_dst_cluster_test.cc +++ b/test/common/upstream/original_dst_cluster_test.cc @@ -154,7 +154,7 @@ TEST_F(OriginalDstClusterTest, NoContext) { NiceMock connection; TestLoadBalancerContext lb_context(&connection); - EXPECT_CALL(connection, usingOriginalDst()).WillOnce(Return(false)); + EXPECT_CALL(connection, localAddressRestored()).WillOnce(Return(false)); // First argument is normally the reference to the ThreadLocalCluster's HostSet, but in these // tests we do not have the thread local clusters, so we pass a reference to the HostSet of the // primary cluster. The implementation handles both cases the same. @@ -169,7 +169,7 @@ TEST_F(OriginalDstClusterTest, NoContext) { NiceMock connection; TestLoadBalancerContext lb_context(&connection); connection.local_address_ = std::make_shared("unix://foo"); - EXPECT_CALL(connection, usingOriginalDst()).WillRepeatedly(Return(true)); + EXPECT_CALL(connection, localAddressRestored()).WillRepeatedly(Return(true)); OriginalDstCluster::LoadBalancer lb(cluster_->prioritySet(), cluster_); EXPECT_CALL(dispatcher_, post(_)).Times(0); @@ -205,7 +205,7 @@ TEST_F(OriginalDstClusterTest, Membership) { NiceMock connection; TestLoadBalancerContext lb_context(&connection); connection.local_address_ = std::make_shared("10.10.11.11"); - EXPECT_CALL(connection, usingOriginalDst()).WillRepeatedly(Return(true)); + EXPECT_CALL(connection, localAddressRestored()).WillRepeatedly(Return(true)); OriginalDstCluster::LoadBalancer lb(cluster_->prioritySet(), cluster_); Event::PostCb post_cb; @@ -292,12 +292,12 @@ TEST_F(OriginalDstClusterTest, Membership2) { NiceMock connection1; TestLoadBalancerContext lb_context1(&connection1); connection1.local_address_ = std::make_shared("10.10.11.11"); - EXPECT_CALL(connection1, usingOriginalDst()).WillRepeatedly(Return(true)); + EXPECT_CALL(connection1, localAddressRestored()).WillRepeatedly(Return(true)); NiceMock connection2; TestLoadBalancerContext lb_context2(&connection2); connection2.local_address_ = std::make_shared("10.10.11.12"); - EXPECT_CALL(connection2, usingOriginalDst()).WillRepeatedly(Return(true)); + EXPECT_CALL(connection2, localAddressRestored()).WillRepeatedly(Return(true)); OriginalDstCluster::LoadBalancer lb(cluster_->prioritySet(), cluster_); @@ -382,7 +382,7 @@ TEST_F(OriginalDstClusterTest, Connection) { NiceMock connection; TestLoadBalancerContext lb_context(&connection); connection.local_address_ = std::make_shared("FD00::1"); - EXPECT_CALL(connection, usingOriginalDst()).WillRepeatedly(Return(true)); + EXPECT_CALL(connection, localAddressRestored()).WillRepeatedly(Return(true)); OriginalDstCluster::LoadBalancer lb(cluster_->prioritySet(), cluster_); Event::PostCb post_cb; @@ -431,7 +431,7 @@ TEST_F(OriginalDstClusterTest, MultipleClusters) { NiceMock connection; TestLoadBalancerContext lb_context(&connection); connection.local_address_ = std::make_shared("FD00::1"); - EXPECT_CALL(connection, usingOriginalDst()).WillRepeatedly(Return(true)); + EXPECT_CALL(connection, localAddressRestored()).WillRepeatedly(Return(true)); OriginalDstCluster::LoadBalancer lb1(cluster_->prioritySet(), cluster_); OriginalDstCluster::LoadBalancer lb2(second, cluster_); diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index bf66e232f5fe4..d084f23b80be7 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -29,7 +29,7 @@ class MockDispatcher : public Dispatcher { MockDispatcher(); ~MockDispatcher(); - Network::ConnectionPtr createServerConnection(Network::AcceptedSocketPtr&& socket, + Network::ConnectionPtr createServerConnection(Network::ConnectionSocketPtr&& socket, Ssl::Context* ssl_ctx) override { return Network::ConnectionPtr{createServerConnection_(socket.get(), ssl_ctx)}; } @@ -72,7 +72,7 @@ class MockDispatcher : public Dispatcher { // Event::Dispatcher MOCK_METHOD0(clearDeferredDeleteList, void()); MOCK_METHOD2(createServerConnection_, - Network::Connection*(Network::AcceptedSocket* socket, Ssl::Context* ssl_ctx)); + Network::Connection*(Network::ConnectionSocket* socket, Ssl::Context* ssl_ctx)); MOCK_METHOD3(createClientConnection_, Network::ClientConnection*(Network::Address::InstanceConstSharedPtr address, Network::Address::InstanceConstSharedPtr source_address, diff --git a/test/mocks/network/mocks.cc b/test/mocks/network/mocks.cc index d4824792b272f..dad3a38bdbc03 100644 --- a/test/mocks/network/mocks.cc +++ b/test/mocks/network/mocks.cc @@ -171,11 +171,11 @@ MockListenSocket::MockListenSocket() : local_address_(new Address::Ipv4Instance( MockListenSocket::~MockListenSocket() {} -MockAcceptedSocket::MockAcceptedSocket() : local_address_(new Address::Ipv4Instance(80)) { +MockConnectionSocket::MockConnectionSocket() : local_address_(new Address::Ipv4Instance(80)) { ON_CALL(*this, localAddress()).WillByDefault(ReturnRef(local_address_)); } -MockAcceptedSocket::~MockAcceptedSocket() {} +MockConnectionSocket::~MockConnectionSocket() {} MockListener::MockListener() {} MockListener::~MockListener() { onDestroy(); } diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index eb39a0b3c5570..5b22b77fd443d 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -78,7 +78,7 @@ class MockConnection : public Connection, public MockConnectionBase { MOCK_METHOD1(write, void(Buffer::Instance& data)); MOCK_METHOD1(setBufferLimits, void(uint32_t limit)); MOCK_CONST_METHOD0(bufferLimit, uint32_t()); - MOCK_CONST_METHOD0(usingOriginalDst, bool()); + MOCK_CONST_METHOD0(localAddressRestored, bool()); MOCK_CONST_METHOD0(aboveHighWatermark, bool()); }; @@ -115,7 +115,7 @@ class MockClientConnection : public ClientConnection, public MockConnectionBase MOCK_METHOD1(write, void(Buffer::Instance& data)); MOCK_METHOD1(setBufferLimits, void(uint32_t limit)); MOCK_CONST_METHOD0(bufferLimit, uint32_t()); - MOCK_CONST_METHOD0(usingOriginalDst, bool()); + MOCK_CONST_METHOD0(localAddressRestored, bool()); MOCK_CONST_METHOD0(aboveHighWatermark, bool()); // Network::ClientConnection @@ -195,12 +195,12 @@ class MockListenerCallbacks : public ListenerCallbacks { MockListenerCallbacks(); ~MockListenerCallbacks(); - void onAccept(AcceptedSocketPtr&& socket, bool redirected) override { + void onAccept(ConnectionSocketPtr&& socket, bool redirected) override { onAccept_(socket, redirected); } void onNewConnection(ConnectionPtr&& conn) override { onNewConnection_(conn); } - MOCK_METHOD2(onAccept_, void(AcceptedSocketPtr& socket, bool redirected)); + MOCK_METHOD2(onAccept_, void(ConnectionSocketPtr& socket, bool redirected)); MOCK_METHOD1(onNewConnection_, void(ConnectionPtr& conn)); }; @@ -225,7 +225,7 @@ class MockListenerFilterCallbacks : public ListenerFilterCallbacks { MockListenerFilterCallbacks(); ~MockListenerFilterCallbacks(); - MOCK_METHOD0(socket, AcceptedSocket&()); + MOCK_METHOD0(socket, ConnectionSocket&()); MOCK_METHOD0(dispatcher, Event::Dispatcher&()); MOCK_METHOD1(continueFilterChain, void(bool)); }; @@ -261,16 +261,16 @@ class MockListenSocket : public ListenSocket { Address::InstanceConstSharedPtr local_address_; }; -class MockAcceptedSocket : public AcceptedSocket { +class MockConnectionSocket : public ConnectionSocket { public: - MockAcceptedSocket(); - ~MockAcceptedSocket(); + MockConnectionSocket(); + ~MockConnectionSocket(); MOCK_CONST_METHOD0(localAddress, const Address::InstanceConstSharedPtr&()); - MOCK_METHOD1(resetLocalAddress, void(const Address::InstanceConstSharedPtr&)); - MOCK_CONST_METHOD0(localAddressReset, bool()); + MOCK_METHOD2(setLocalAddress, void(const Address::InstanceConstSharedPtr&, bool)); + MOCK_CONST_METHOD0(localAddressRestored, bool()); MOCK_CONST_METHOD0(remoteAddress, const Address::InstanceConstSharedPtr&()); - MOCK_METHOD1(resetRemoteAddress, void(const Address::InstanceConstSharedPtr&)); + MOCK_METHOD1(setRemoteAddress, void(const Address::InstanceConstSharedPtr&)); MOCK_CONST_METHOD0(fd, int()); MOCK_METHOD0(close, void()); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index d8ed9357bef40..5f5e2b0662ddf 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -265,7 +265,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { handler_->addListener(*test_listener2); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptedSocket* accepted_socket = new NiceMock(); + Network::MockConnectionSocket* accepted_socket = new NiceMock(); bool redirected = false; EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { @@ -278,16 +278,16 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { })); EXPECT_CALL(*test_filter, onAccept(_)) .WillOnce(Invoke([&](Network::ListenerFilterCallbacks& cb) -> Network::FilterStatus { - cb.socket().resetLocalAddress(alt_address); + cb.socket().setLocalAddress(alt_address, true); return Network::FilterStatus::Continue; })); - EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); - EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accepted_socket, setLocalAddress(alt_address, true)); + EXPECT_CALL(*accepted_socket, localAddressRestored()).WillOnce(Return(true)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(alt_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -324,7 +324,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { handler_->addListener(*test_listener2); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptedSocket* accepted_socket = new NiceMock(); + Network::MockConnectionSocket* accepted_socket = new NiceMock(); bool redirected = false; EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { @@ -340,16 +340,16 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { new Network::Address::Ipv4Instance("127.0.0.2", 0)); EXPECT_CALL(*test_filter, onAccept(_)) .WillOnce(Invoke([&](Network::ListenerFilterCallbacks& cb) -> Network::FilterStatus { - cb.socket().resetLocalAddress(alt_address); + cb.socket().setLocalAddress(alt_address, true); return Network::FilterStatus::Continue; })); - EXPECT_CALL(*accepted_socket, resetLocalAddress(alt_address)); - EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accepted_socket, setLocalAddress(alt_address, true)); + EXPECT_CALL(*accepted_socket, localAddressRestored()).WillOnce(Return(true)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(alt_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -378,7 +378,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { handler_->addListener(*test_listener1); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptedSocket* accepted_socket = new NiceMock(); + Network::MockConnectionSocket* accepted_socket = new NiceMock(); EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. @@ -387,16 +387,16 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { })); EXPECT_CALL(*test_filter, onAccept(_)) .WillOnce(Invoke([&](Network::ListenerFilterCallbacks& cb) -> Network::FilterStatus { - cb.socket().resetLocalAddress(original_dst_address); + cb.socket().setLocalAddress(original_dst_address, true); return Network::FilterStatus::Continue; })); - EXPECT_CALL(*accepted_socket, resetLocalAddress(original_dst_address)); - EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(true)); + EXPECT_CALL(*accepted_socket, setLocalAddress(original_dst_address, true)); + EXPECT_CALL(*accepted_socket, localAddressRestored()).WillOnce(Return(true)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(original_dst_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); @@ -421,7 +421,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { handler_->addListener(*test_listener1); Network::MockListenerFilter* test_filter = new Network::MockListenerFilter(); - Network::MockAcceptedSocket* accepted_socket = new NiceMock(); + Network::MockConnectionSocket* accepted_socket = new NiceMock(); EXPECT_CALL(factory_, createListenerFilterChain(_)) .WillRepeatedly(Invoke([&](Network::ListenerFilterManager& manager) -> bool { // Insert the Mock filter. @@ -429,12 +429,12 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { return true; })); EXPECT_CALL(*test_filter, onAccept(_)).WillOnce(Return(Network::FilterStatus::Continue)); - EXPECT_CALL(*accepted_socket, localAddressReset()).WillOnce(Return(false)); + EXPECT_CALL(*accepted_socket, localAddressRestored()).WillOnce(Return(false)); EXPECT_CALL(*accepted_socket, localAddress()).WillRepeatedly(ReturnRef(normal_address)); Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::AcceptedSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 17cb420fd5570..c9dc6f7c1d078 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -1059,7 +1059,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { socket_address: { address: 127.0.0.1, port_value: 1111 } filter_chains: {} listener_filters: - - name: "envoy.original_dst" + - name: "envoy.listener.original_dst" config: {} )EOF", // " Network::Address::IpVersion::v4); @@ -1081,7 +1081,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstFilter) { Network::Address::InstanceConstSharedPtr{ new Network::Address::Ipv4Instance("127.0.0.1", 5678)}); - EXPECT_CALL(callbacks, socket()).WillOnce(Invoke([&]() -> Network::AcceptedSocket& { + EXPECT_CALL(callbacks, socket()).WillOnce(Invoke([&]() -> Network::ConnectionSocket& { return socket; })); @@ -1108,15 +1108,15 @@ class OriginalDstTestConfigFactory : public NamedListenerFilterConfigFactory { ListenerFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, FactoryContext&) override { return [](Network::ListenerFilterManager& filter_manager) -> void { - filter_manager.addAcceptFilter(Network::ListenerFilterPtr{new OriginalDstTest()}); + filter_manager.addAcceptFilter(std::make_unique()); }; } ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + return std::make_unique(); } - std::string name() override { return "test.original_dst"; } + std::string name() override { return "test.listener.original_dst"; } }; /** @@ -1133,7 +1133,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstTestFilter) { socket_address: { address: 127.0.0.1, port_value: 1111 } filter_chains: {} listener_filters: - - name: "test.original_dst" + - name: "test.listener.original_dst" config: {} )EOF", // " Network::Address::IpVersion::v4); @@ -1149,13 +1149,11 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstTestFilter) { Network::MockListenerFilterManager manager; NiceMock callbacks; - Network::AcceptedSocketImpl socket(-1, - Network::Address::InstanceConstSharedPtr{ - new Network::Address::Ipv4Instance("127.0.0.1", 1234)}, - Network::Address::InstanceConstSharedPtr{ - new Network::Address::Ipv4Instance("127.0.0.1", 5678)}); + Network::AcceptedSocketImpl socket( + -1, std::make_unique("127.0.0.1", 1234), + std::make_unique("127.0.0.1", 5678)); - EXPECT_CALL(callbacks, socket()).WillOnce(Invoke([&]() -> Network::AcceptedSocket& { + EXPECT_CALL(callbacks, socket()).WillOnce(Invoke([&]() -> Network::ConnectionSocket& { return socket; })); @@ -1165,7 +1163,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, OriginalDstTestFilter) { })); EXPECT_TRUE(filterChainFactory.createListenerFilterChain(manager)); - EXPECT_TRUE(socket.localAddressReset()); + EXPECT_TRUE(socket.localAddressRestored()); EXPECT_EQ("127.0.0.2:2345", socket.localAddress()->asString()); } From 350357911c9f8102ab4a9c867df5b5c99b6cfd97 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 18 Jan 2018 15:48:22 -0800 Subject: [PATCH 33/41] listener_manager: Translate legacy flags to listener filters. Translate legacy flags for proxy protocol and original dst to listener filters to simplify code. Suggested-by: Matt Klein Signed-off-by: Jarno Rajahalme --- include/envoy/network/listener.h | 12 ------- source/server/BUILD | 5 +-- source/server/connection_handler_impl.cc | 14 +------- source/server/connection_handler_impl.h | 2 -- source/server/http/admin.h | 2 -- source/server/listener_manager_impl.cc | 23 ++++++++++-- source/server/listener_manager_impl.h | 4 --- test/common/network/BUILD | 1 + test/common/network/proxy_protocol_test.cc | 29 +++++++++------ test/integration/BUILD | 2 -- test/integration/fake_upstream.h | 2 -- test/mocks/network/mocks.h | 2 -- test/server/connection_handler_test.cc | 41 +++++++++------------- 13 files changed, 59 insertions(+), 80 deletions(-) diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 6ef4a04c11543..c3e744386ebb2 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -36,12 +36,6 @@ class ListenerConfig { */ virtual Ssl::ServerContext* defaultSslContext() PURE; - /** - * @return bool whether to use the PROXY Protocol V1 - * (http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) - */ - virtual bool useProxyProto() PURE; - /** * @return bool specifies whether the listener should actually listen on the port. * A listener that doesn't listen on a port can only receive connections @@ -49,12 +43,6 @@ class ListenerConfig { */ virtual bool bindToPort() PURE; - /** - * @return bool if a connection was redirected to this listener address using iptables, - * allow the listener to hand it off to the listener associated to the original address - */ - virtual bool useOriginalDst() PURE; - /** * @return uint32_t providing a soft limit on size of the listener's new connection read and write * buffers. diff --git a/source/server/BUILD b/source/server/BUILD index d6988d0afdaef..1dafe2ec7f736 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -67,8 +67,6 @@ envoy_cc_library( "//include/envoy/stats:timespan", "//source/common/common:linked_object", "//source/common/common:non_copyable", - "//source/common/filter/listener:original_dst_lib", - "//source/common/filter/listener:proxy_protocol_lib", "//source/common/network:connection_lib", ], ) @@ -205,10 +203,13 @@ envoy_cc_library( "//include/envoy/server:listener_manager_interface", "//include/envoy/server:worker_interface", "//source/common/config:utility_lib", + "//source/common/config:well_known_names", "//source/common/network:listen_socket_lib", "//source/common/network:utility_lib", "//source/common/protobuf:utility_lib", "//source/common/ssl:context_config_lib", + "//source/server/config/listener:original_dst_lib", + "//source/server/config/listener:proxy_protocol_lib", ], ) diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 25028c3791e6b..fb756249e1816 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -5,8 +5,6 @@ #include "envoy/network/filter.h" #include "envoy/stats/timespan.h" -#include "common/filter/listener/original_dst.h" -#include "common/filter/listener/proxy_protocol.h" #include "common/network/connection_impl.h" #include "common/network/utility.h" @@ -71,8 +69,7 @@ ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& par Network::ListenerConfig& config) : parent_(parent), listener_(std::move(listener)), stats_(generateStats(config.listenerScope())), listener_tag_(config.listenerTag()), - config_(config), - legacy_stats_(new Filter::Listener::ProxyProtocol::Config(config.listenerScope())) {} + config_(config) {} ConnectionHandlerImpl::ActiveListener::~ActiveListener() { // Purge sockets that have not progressed to connections. This should only happen when @@ -173,15 +170,6 @@ void ConnectionHandlerImpl::ActiveListener::onAccept(Network::ConnectionSocketPt Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); auto active_socket = std::make_unique(*this, std::move(socket), redirected); - // Implicitly add legacy filters - if (config_.useOriginalDst()) { - active_socket->accept_filters_.emplace_back(new Filter::Listener::OriginalDst()); - } - if (config_.useProxyProto()) { - active_socket->accept_filters_.emplace_back( - new Filter::Listener::ProxyProtocol::Instance(legacy_stats_)); - } - // Create and run the filters config_.filterChainFactory().createListenerFilterChain(*active_socket); active_socket->continueFilterChain(true); diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index 3efe04dba9e40..2039edebe9f89 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -17,7 +17,6 @@ #include "common/common/linked_object.h" #include "common/common/non_copyable.h" -#include "common/filter/listener/proxy_protocol.h" #include "spdlog/spdlog.h" @@ -98,7 +97,6 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { std::list connections_; const uint64_t listener_tag_; Network::ListenerConfig& config_; - Filter::Listener::ProxyProtocol::ConfigSharedPtr legacy_stats_; }; typedef std::unique_ptr ActiveListenerPtr; diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 021ec302ce63a..698a6d4e6b2c7 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -175,9 +175,7 @@ class AdminImpl : public Admin, Network::FilterChainFactory& filterChainFactory() override { return parent_; } Network::ListenSocket& socket() override { return parent_.mutable_socket(); } Ssl::ServerContext* defaultSslContext() override { return nullptr; } - bool useProxyProto() override { return false; } bool bindToPort() override { return true; } - bool useOriginalDst() override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return *scope_; } uint64_t listenerTag() const override { return 0; } diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index a62f77444851d..c77c6b562ec46 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -4,6 +4,7 @@ #include "common/common/assert.h" #include "common/config/utility.h" +#include "common/config/well_known_names.h" #include "common/network/listen_socket_impl.h" #include "common/network/utility.h" #include "common/protobuf/utility.h" @@ -108,9 +109,6 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag listener_scope_( parent_.server_.stats().createScope(fmt::format("listener.{}.", address_->asString()))), bind_to_port_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.deprecated_v1(), bind_to_port, true)), - use_proxy_proto_( - PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.filter_chains()[0], use_proxy_proto, false)), - use_original_dst_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, use_original_dst, false)), per_connection_buffer_limit_bytes_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, per_connection_buffer_limit_bytes, 1024 * 1024)), listener_tag_(parent_.factory_.nextListenerTag()), name_(name), modifiable_(modifiable), @@ -124,6 +122,25 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag listener_filter_factories_ = parent_.factory_.createListenerFilterFactoryList(config.listener_filters(), *this); } + // Add original dst listener filter if 'use_original_dst' flag is set. + if (PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, use_original_dst, false)) { + auto& factory = + Config::Utility::getAndCheckFactory( + Config::ListenerFilterNames::get().ORIGINAL_DST); + listener_filter_factories_.push_back( + factory.createFilterFactoryFromProto(Envoy::ProtobufWkt::Empty(), *this)); + } + // Add proxy protocol listener filter if 'use_proxy_proto' flag is set. + // TODO(jrajahalme): This is the last listener filter on purpose. When filter chain matching + // is implemented, this needs to be run after the filter chain has been + // selected. + if (PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.filter_chains()[0], use_proxy_proto, false)) { + auto& factory = + Config::Utility::getAndCheckFactory( + Config::ListenerFilterNames::get().PROXY_PROTOCOL); + listener_filter_factories_.push_back( + factory.createFilterFactoryFromProto(Envoy::ProtobufWkt::Empty(), *this)); + } // Skip lookup and update of the SSL Context if there is only one filter chain // and it doesn't enforce any SNI restrictions. diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index 4b8de231595c3..3ffa0507ffc3b 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -215,8 +215,6 @@ class ListenerImpl : public Network::ListenerConfig, Ssl::ServerContext* defaultSslContext() override { return tls_contexts_.empty() ? nullptr : tls_contexts_[0].get(); } - bool useProxyProto() override { return use_proxy_proto_; } - bool useOriginalDst() override { return use_original_dst_; } uint32_t perConnectionBufferLimitBytes() override { return per_connection_buffer_limit_bytes_; } Stats::Scope& listenerScope() override { return *listener_scope_; } uint64_t listenerTag() const override { return listener_tag_; } @@ -259,8 +257,6 @@ class ListenerImpl : public Network::ListenerConfig, Stats::ScopePtr listener_scope_; // Stats with listener named scope. std::vector tls_contexts_; const bool bind_to_port_; - const bool use_proxy_proto_; - const bool use_original_dst_; const uint32_t per_connection_buffer_limit_bytes_; const uint64_t listener_tag_; const std::string name_; diff --git a/test/common/network/BUILD b/test/common/network/BUILD index 4791c032ce660..bd69afa4c05d5 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -130,6 +130,7 @@ envoy_cc_test( "//source/common/buffer:buffer_lib", "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", + "//source/common/filter/listener:proxy_protocol_lib", "//source/common/network:listener_lib", "//source/common/network:utility_lib", "//source/common/stats:stats_lib", diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index cad8bd8dd2235..b4bfdede5c114 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -4,6 +4,7 @@ #include "common/buffer/buffer_impl.h" #include "common/event/dispatcher_impl.h" +#include "common/filter/listener/proxy_protocol.h" #include "common/network/listen_socket_impl.h" #include "common/network/listener_impl.h" #include "common/network/utility.h" @@ -45,16 +46,21 @@ class ProxyProtocolTest : public testing::TestWithParam, Network::Test::createRawBufferSocket()); conn_->addConnectionCallbacks(connection_callbacks_); - ON_CALL(factory_, createListenerFilterChain(_)).WillByDefault(Return(true)); + EXPECT_CALL(factory_, createListenerFilterChain(_)) + .WillOnce(Invoke([&](ListenerFilterManager& filter_manager) -> bool { + filter_manager.addAcceptFilter( + std::make_unique( + std::make_shared( + listenerScope()))); + return true; + })); } // Listener Network::FilterChainFactory& filterChainFactory() override { return factory_; } Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } - bool useProxyProto() override { return true; } bool bindToPort() override { return true; } - bool useOriginalDst() override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return stats_store_; } uint64_t listenerTag() const override { return 1; } @@ -63,8 +69,6 @@ class ProxyProtocolTest : public testing::TestWithParam, void connect() { conn_->connect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createListenerFilterChain(_)) - .WillOnce(Invoke([&](ListenerFilterManager&) -> bool { return true; })); EXPECT_CALL(factory_, createNetworkFilterChain(_)) .WillOnce(Invoke([&](Connection& connection) -> bool { server_connection_ = &connection; @@ -79,7 +83,6 @@ class ProxyProtocolTest : public testing::TestWithParam, void connectNoRead() { conn_->connect(); - EXPECT_CALL(factory_, createListenerFilterChain(_)); EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); dispatcher_.run(Event::Dispatcher::RunType::Block); @@ -301,7 +304,6 @@ TEST_P(ProxyProtocolTest, Closed) { TEST_P(ProxyProtocolTest, ClosedEmpty) { conn_->connect(); - EXPECT_CALL(factory_, createListenerFilterChain(_)); conn_->close(ConnectionCloseType::NoFlush); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); } @@ -322,15 +324,22 @@ class WildcardProxyProtocolTest : public testing::TestWithParamaddConnectionCallbacks(connection_callbacks_); + + EXPECT_CALL(factory_, createListenerFilterChain(_)) + .WillOnce(Invoke([&](ListenerFilterManager& filter_manager) -> bool { + filter_manager.addAcceptFilter( + std::make_unique( + std::make_shared( + listenerScope()))); + return true; + })); } // Network::ListenerConfig Network::FilterChainFactory& filterChainFactory() override { return factory_; } Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } - bool useProxyProto() override { return true; } bool bindToPort() override { return true; } - bool useOriginalDst() override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return stats_store_; } uint64_t listenerTag() const override { return 1; } @@ -339,8 +348,6 @@ class WildcardProxyProtocolTest : public testing::TestWithParamconnect(); read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createListenerFilterChain(_)) - .WillOnce(Invoke([&](ListenerFilterManager&) -> bool { return true; })); EXPECT_CALL(factory_, createNetworkFilterChain(_)) .WillOnce(Invoke([&](Connection& connection) -> bool { server_connection_ = &connection; diff --git a/test/integration/BUILD b/test/integration/BUILD index ab5527c451509..6082e5a3cab5d 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -262,8 +262,6 @@ envoy_cc_test_library( "//source/server/config/http:ratelimit_lib", "//source/server/config/http:router_lib", "//source/server/config/http:zipkin_lib", - "//source/server/config/listener:original_dst_lib", - "//source/server/config/listener:proxy_protocol_lib", "//source/server/config/network:client_ssl_auth_lib", "//source/server/config/network:echo_lib", "//source/server/config/network:http_connection_manager_lib", diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index 09ab8a28cbdef..2a13eaa35f8c0 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -315,9 +315,7 @@ class FakeUpstream : Logger::Loggable, public Network::Filt Network::FilterChainFactory& filterChainFactory() override { return parent_; } Network::ListenSocket& socket() override { return *parent_.socket_; } Ssl::ServerContext* defaultSslContext() override { return parent_.ssl_ctx_; } - bool useProxyProto() override { return false; } bool bindToPort() override { return true; } - bool useOriginalDst() override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return parent_.stats_store_; } uint64_t listenerTag() const override { return 0; } diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 5b22b77fd443d..ff49289e7bad8 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -285,9 +285,7 @@ class MockListenerConfig : public ListenerConfig { MOCK_METHOD0(filterChainFactory, FilterChainFactory&()); MOCK_METHOD0(socket, ListenSocket&()); MOCK_METHOD0(defaultSslContext, Ssl::ServerContext*()); - MOCK_METHOD0(useProxyProto, bool()); MOCK_METHOD0(bindToPort, bool()); - MOCK_METHOD0(useOriginalDst, bool()); MOCK_METHOD0(perConnectionBufferLimitBytes, uint32_t()); MOCK_METHOD0(listenerScope, Stats::Scope&()); MOCK_CONST_METHOD0(listenerTag, uint64_t()); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 5f5e2b0662ddf..0494b685848e2 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -29,16 +29,13 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable { public: TestListener(ConnectionHandlerTest& parent, uint64_t tag, bool bind_to_port, - bool use_original_dst, const std::string& name) - : parent_(parent), tag_(tag), bind_to_port_(bind_to_port), - use_original_dst_(use_original_dst), name_(name) {} + const std::string& name) + : parent_(parent), tag_(tag), bind_to_port_(bind_to_port), name_(name) {} Network::FilterChainFactory& filterChainFactory() override { return parent_.factory_; } Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } - bool useProxyProto() override { return false; } bool bindToPort() override { return bind_to_port_; } - bool useOriginalDst() override { return use_original_dst_; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return parent_.stats_store_; } uint64_t listenerTag() const override { return tag_; } @@ -48,15 +45,13 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable TestListenerPtr; - TestListener* addListener(uint64_t tag, bool bind_to_port, bool use_original_dst, - const std::string& name) { - TestListener* listener = new TestListener(*this, tag, bind_to_port, use_original_dst, name); + TestListener* addListener(uint64_t tag, bool bind_to_port, const std::string& name) { + TestListener* listener = new TestListener(*this, tag, bind_to_port, name); listener->moveIntoListBack(TestListenerPtr{listener}, listeners_); return listener; } @@ -80,7 +75,7 @@ TEST_F(ConnectionHandlerTest, RemoveListener) { return listener; })); - TestListener* test_listener = addListener(1, true, false, "test_listener"); + TestListener* test_listener = addListener(1, true, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -118,7 +113,7 @@ TEST_F(ConnectionHandlerTest, DestroyCloseConnections) { return listener; })); - TestListener* test_listener = addListener(1, true, false, "test_listener"); + TestListener* test_listener = addListener(1, true, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -145,7 +140,7 @@ TEST_F(ConnectionHandlerTest, CloseDuringFilterChainCreate) { return listener; })); - TestListener* test_listener = addListener(1, true, false, "test_listener"); + TestListener* test_listener = addListener(1, true, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -171,7 +166,7 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { return listener; })); - TestListener* test_listener = addListener(1, true, false, "test_listener"); + TestListener* test_listener = addListener(1, true, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -185,7 +180,7 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { } TEST_F(ConnectionHandlerTest, FindListenerByAddress) { - TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, "test_listener1"); Network::Address::InstanceConstSharedPtr alt_address( new Network::Address::Ipv4Instance("127.0.0.1", 10001)); @@ -198,7 +193,7 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { EXPECT_EQ(listener, handler_->findListenerByAddress(ByRef(*alt_address))); - TestListener* test_listener2 = addListener(2, true, false, "test_listener2"); + TestListener* test_listener2 = addListener(2, true, "test_listener2"); Network::Address::InstanceConstSharedPtr alt_address2( new Network::Address::Ipv4Instance("0.0.0.0", 10001)); Network::Address::InstanceConstSharedPtr alt_address3( @@ -235,8 +230,7 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { } TEST_F(ConnectionHandlerTest, NormalRedirect) { - // 'false' for use_original_dst since we add a mock filter manually below. - TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) @@ -250,7 +244,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(normal_address)); handler_->addListener(*test_listener1); - TestListener* test_listener2 = addListener(1, false, false, "test_listener2"); + TestListener* test_listener2 = addListener(1, false, "test_listener2"); Network::MockListener* listener2 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks2; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) @@ -295,8 +289,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { } TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { - // 'false' for use_original_dst since we add a mock filter manually below. - TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) @@ -310,7 +303,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(normal_address)); handler_->addListener(*test_listener1); - TestListener* test_listener2 = addListener(1, false, false, "test_listener2"); + TestListener* test_listener2 = addListener(1, false, "test_listener2"); Network::MockListener* listener2 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks2; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) @@ -357,8 +350,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { } TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { - // 'false' for use_original_dst since we add a mock filter manually below. - TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) @@ -403,8 +395,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { } TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { - // 'false' for use_original_dst since we add a mock filter manually below. - TestListener* test_listener1 = addListener(1, true, false, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; EXPECT_CALL(dispatcher_, createListener_(_, _, _)) From b7e16d3f6fd8ce097ba52aea08a9e467a9d95ea5 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 18 Jan 2018 16:51:30 -0800 Subject: [PATCH 34/41] proxy_protocol: Reduce logging level. Change 'info' level to 'debug' for debugging output. Signed-off-by: Jarno Rajahalme --- source/common/filter/listener/proxy_protocol.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common/filter/listener/proxy_protocol.cc b/source/common/filter/listener/proxy_protocol.cc index 098954ab03e2e..3142567eb5f44 100644 --- a/source/common/filter/listener/proxy_protocol.cc +++ b/source/common/filter/listener/proxy_protocol.cc @@ -25,7 +25,7 @@ namespace ProxyProtocol { Config::Config(Stats::Scope& scope) : stats_{ALL_PROXY_PROTOCOL_STATS(POOL_COUNTER(scope))} {} Network::FilterStatus Instance::onAccept(Network::ListenerFilterCallbacks& cb) { - ENVOY_LOG(info, "proxy_protocol: New connection accepted"); + ENVOY_LOG(debug, "proxy_protocol: New connection accepted"); Network::ConnectionSocket& socket = cb.socket(); ASSERT(file_event_.get() == nullptr); file_event_ = From e75f50ddc2892cf193bec5c09851bb94a93e0fba Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 19 Jan 2018 16:54:11 -0800 Subject: [PATCH 35/41] connection_handler: Do not assert for listener filter completion. Listener filter iterator is already at the end when all the filters have concluded, so there is no need to set the iterator to the end. Listener filter may not complete on a truncated connection, so do not assert for it in the destructor. Signed-off-by: Jarno Rajahalme --- source/server/connection_handler_impl.cc | 4 +--- source/server/connection_handler_impl.h | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index fb756249e1816..bcb2962f735c3 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -156,9 +156,7 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { } } - // Filter execution concluded, clear state. - iter_ = accept_filters_.end(); - // Unlink and delete this ActiveSocket if it was linked. + // Filter execution concluded, unlink and delete this ActiveSocket if it was linked. if (inserted()) { ActiveSocketPtr removed = removeFromList(listener_.sockets_); listener_.parent_.dispatcher_.deferredDelete(std::move(removed)); diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index 2039edebe9f89..a0bf9f9f533e2 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -136,10 +136,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ActiveSocket(ActiveListener& listener, Network::ConnectionSocketPtr&& socket, bool redirected) : listener_(listener), socket_(std::move(socket)), redirected_(redirected), iter_(accept_filters_.end()) {} - ~ActiveSocket() { - ASSERT(iter_ == accept_filters_.end()); - accept_filters_.clear(); - } + ~ActiveSocket() { accept_filters_.clear(); } // Network::ListenerFilterManager void addAcceptFilter(Network::ListenerFilterPtr&& filter) override { From 9a2c62a1909c2803811fb9014bd4c3e636290136 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 19 Jan 2018 16:49:59 -0800 Subject: [PATCH 36/41] proxy_protocol: Release file event when done. Filter destruction is postponed, which makes it possible for the file event of the proxy protocol filter to interfere with the file event of the connection object that is created right after the proxy protocol filter has successfully concluded. To fix this we explicitly destruct the file event before returning from the proxy protocol filter. Signed-off-by: Jarno Rajahalme --- .../common/filter/listener/proxy_protocol.cc | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/source/common/filter/listener/proxy_protocol.cc b/source/common/filter/listener/proxy_protocol.cc index 3142567eb5f44..d10415e3e7694 100644 --- a/source/common/filter/listener/proxy_protocol.cc +++ b/source/common/filter/listener/proxy_protocol.cc @@ -65,58 +65,57 @@ void Instance::onReadWorker() { throw EnvoyException("failed to read proxy protocol"); } - if (line_parts[1] == "UNKNOWN") { - // At this point we know it's a proxy protocol line, so we can remove it from the socket - // and continue. - // According to spec "real connection's parameters" should be used, so we should NOT - // reset the addresses in this case. - cb_->continueFilterChain(true); - return; - } + // If the line starts with UNKNOWN we know it's a proxy protocol line, so we can remove it from + // the socket and continue. According to spec "real connection's parameters" should be used, so + // we should NOT restore the addresses in this case. + if (line_parts[1] != "UNKNOWN") { + // If protocol not UNKNOWN, src and dst addresses have to be present. + if (line_parts.size() != 6) { + throw EnvoyException("failed to read proxy protocol"); + } - // If protocol not UNKNOWN, src and dst addresses have to be present. - if (line_parts.size() != 6) { - throw EnvoyException("failed to read proxy protocol"); - } + Network::Address::IpVersion protocol_version; + Network::Address::InstanceConstSharedPtr remote_address; + Network::Address::InstanceConstSharedPtr local_address; + + // TODO(gsagula): parseInternetAddressAndPort() could be modified to take two string_view + // arguments, so we can eliminate allocation here. + if (line_parts[1] == "TCP4") { + protocol_version = Network::Address::IpVersion::v4; + remote_address = Network::Utility::parseInternetAddressAndPort( + std::string{line_parts[2]} + ":" + std::string{line_parts[4]}); + local_address = Network::Utility::parseInternetAddressAndPort( + std::string{line_parts[3]} + ":" + std::string{line_parts[5]}); + } else if (line_parts[1] == "TCP6") { + protocol_version = Network::Address::IpVersion::v6; + remote_address = Network::Utility::parseInternetAddressAndPort( + "[" + std::string{line_parts[2]} + "]:" + std::string{line_parts[4]}); + local_address = Network::Utility::parseInternetAddressAndPort( + "[" + std::string{line_parts[3]} + "]:" + std::string{line_parts[5]}); + } else { + throw EnvoyException("failed to read proxy protocol"); + } - Network::Address::IpVersion protocol_version; - Network::Address::InstanceConstSharedPtr remote_address; - Network::Address::InstanceConstSharedPtr local_address; - - // TODO(gsagula): parseInternetAddressAndPort() could be modified to take two string_view - // arguments, so we can eliminate allocation here. - if (line_parts[1] == "TCP4") { - protocol_version = Network::Address::IpVersion::v4; - remote_address = Network::Utility::parseInternetAddressAndPort( - std::string{line_parts[2]} + ":" + std::string{line_parts[4]}); - local_address = Network::Utility::parseInternetAddressAndPort(std::string{line_parts[3]} + ":" + - std::string{line_parts[5]}); - } else if (line_parts[1] == "TCP6") { - protocol_version = Network::Address::IpVersion::v6; - remote_address = Network::Utility::parseInternetAddressAndPort( - "[" + std::string{line_parts[2]} + "]:" + std::string{line_parts[4]}); - local_address = Network::Utility::parseInternetAddressAndPort( - "[" + std::string{line_parts[3]} + "]:" + std::string{line_parts[5]}); - } else { - throw EnvoyException("failed to read proxy protocol"); - } + // Error check the source and destination fields. Most errors are caught by the address + // parsing above, but a malformed IPv6 address may combine with a malformed port and parse as + // an IPv6 address when parsing for an IPv4 address. Remote address refers to the source + // address. + const auto remote_version = remote_address->ip()->version(); + const auto local_version = local_address->ip()->version(); + if (remote_version != protocol_version || local_version != protocol_version) { + throw EnvoyException("failed to read proxy protocol"); + } + // Check that both addresses are valid unicast addresses, as required for TCP + if (!remote_address->ip()->isUnicastAddress() || !local_address->ip()->isUnicastAddress()) { + throw EnvoyException("failed to read proxy protocol"); + } - // Error check the source and destination fields. Most errors are caught by the address - // parsing above, but a malformed IPv6 address may combine with a malformed port and parse as - // an IPv6 address when parsing for an IPv4 address. Remote address refers to the source - // address. - const auto remote_version = remote_address->ip()->version(); - const auto local_version = local_address->ip()->version(); - if (remote_version != protocol_version || local_version != protocol_version) { - throw EnvoyException("failed to read proxy protocol"); - } - // Check that both addresses are valid unicast addresses, as required for TCP - if (!remote_address->ip()->isUnicastAddress() || !local_address->ip()->isUnicastAddress()) { - throw EnvoyException("failed to read proxy protocol"); + socket.setLocalAddress(local_address); + socket.setRemoteAddress(remote_address); } - socket.setLocalAddress(local_address); - socket.setRemoteAddress(remote_address); + // Release the file event so that we do not interfere with the connection read events. + file_event_.reset(); cb_->continueFilterChain(true); } From 94751c0abda0b879a2da605e63b0a64e6f54f4b6 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 19 Jan 2018 21:43:44 -0800 Subject: [PATCH 37/41] proxy_protocol_test: Make tests more robust. Some of the tests depended on the timing of data arraving to the socket read by the proxy protocol filter. Make all tests run the dispatcher in blocking mode, and stop the dispatcher when we know that the proxy protocol processing has finished. These changes allow these tests to pass on OSX, and also prevent spurious test failures on other platforms. Signed-off-by: Jarno Rajahalme --- test/common/network/proxy_protocol_test.cc | 161 ++++++++++----------- 1 file changed, 80 insertions(+), 81 deletions(-) diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index b4bfdede5c114..bd5a656663b18 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -22,6 +22,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +using testing::AtLeast; using testing::Invoke; using testing::NiceMock; using testing::Return; @@ -45,15 +46,6 @@ class ProxyProtocolTest : public testing::TestWithParam, Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket()); conn_->addConnectionCallbacks(connection_callbacks_); - - EXPECT_CALL(factory_, createListenerFilterChain(_)) - .WillOnce(Invoke([&](ListenerFilterManager& filter_manager) -> bool { - filter_manager.addAcceptFilter( - std::make_unique( - std::make_shared( - listenerScope()))); - return true; - })); } // Listener @@ -66,23 +58,26 @@ class ProxyProtocolTest : public testing::TestWithParam, uint64_t listenerTag() const override { return 1; } const std::string& name() const override { return name_; } - void connect() { - conn_->connect(); - read_filter_.reset(new NiceMock()); - EXPECT_CALL(factory_, createNetworkFilterChain(_)) - .WillOnce(Invoke([&](Connection& connection) -> bool { - server_connection_ = &connection; - connection.addConnectionCallbacks(server_callbacks_); - connection.addReadFilter(read_filter_); + void connect(bool read = true) { + EXPECT_CALL(factory_, createListenerFilterChain(_)) + .WillOnce(Invoke([&](ListenerFilterManager& filter_manager) -> bool { + filter_manager.addAcceptFilter( + std::make_unique( + std::make_shared( + listenerScope()))); return true; })); - EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) - .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); - dispatcher_.run(Event::Dispatcher::RunType::Block); - } - - void connectNoRead() { conn_->connect(); + if (read) { + read_filter_.reset(new NiceMock()); + EXPECT_CALL(factory_, createNetworkFilterChain(_)) + .WillOnce(Invoke([&](Connection& connection) -> bool { + server_connection_ = &connection; + connection.addConnectionCallbacks(server_callbacks_); + connection.addReadFilter(read_filter_); + return true; + })); + } EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::Connected)) .WillOnce(Invoke([&](Network::ConnectionEvent) -> void { dispatcher_.exit(); })); dispatcher_.run(Event::Dispatcher::RunType::Block); @@ -93,6 +88,19 @@ class ProxyProtocolTest : public testing::TestWithParam, conn_->write(buf); } + void expectData(std::string expected) { + EXPECT_CALL(*read_filter_, onNewConnection()); + EXPECT_CALL(*read_filter_, onData(_)) + .WillOnce(Invoke([&](Buffer::Instance& buffer) -> FilterStatus { + EXPECT_EQ(TestUtility::bufferToString(buffer), expected); + buffer.drain(expected.length()); + dispatcher_.exit(); + return Network::FilterStatus::Continue; + })); + + dispatcher_.run(Event::Dispatcher::RunType::Block); + } + void disconnect() { EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::LocalClose)); EXPECT_CALL(server_callbacks_, onEvent(ConnectionEvent::RemoteClose)) @@ -133,17 +141,9 @@ TEST_P(ProxyProtocolTest, Basic) { connect(); write("PROXY TCP4 1.2.3.4 253.253.253.253 65535 1234\r\nmore data"); - EXPECT_CALL(*read_filter_, onNewConnection()); - EXPECT_CALL(*read_filter_, onData(_)) - .WillOnce(Invoke([&](Buffer::Instance& buffer) -> FilterStatus { - EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "1.2.3.4"); + expectData("more data"); - EXPECT_EQ(TestUtility::bufferToString(buffer), "more data"); - buffer.drain(9); - return Network::FilterStatus::Continue; - })); - - dispatcher_.run(Event::Dispatcher::RunType::NonBlock); + EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "1.2.3.4"); disconnect(); } @@ -152,17 +152,9 @@ TEST_P(ProxyProtocolTest, BasicV6) { connect(); write("PROXY TCP6 1:2:3::4 5:6::7:8 65535 1234\r\nmore data"); - EXPECT_CALL(*read_filter_, onNewConnection()); - EXPECT_CALL(*read_filter_, onData(_)) - .WillOnce(Invoke([&](Buffer::Instance& buffer) -> FilterStatus { - EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "1:2:3::4"); + expectData("more data"); - EXPECT_EQ(TestUtility::bufferToString(buffer), "more data"); - buffer.drain(9); - return Network::FilterStatus::Continue; - })); - - dispatcher_.run(Event::Dispatcher::RunType::NonBlock); + EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "1:2:3::4"); disconnect(); } @@ -173,9 +165,13 @@ TEST_P(ProxyProtocolTest, Fragmented) { write(" 254.254.2"); write("54.254 1.2"); write(".3.4 65535"); - write(" 1234\r\n"); + write(" 1234\r\n..."); - dispatcher_.run(Event::Dispatcher::RunType::NonBlock); + // If there is no data after the PROXY line, the read filter does not receive even the + // onNewConnection() callback. We need this in order to run the dispatcher in blocking + // mode to make sure that proxy protocol processing is completed before we start testing + // the results. Since we must have data we might as well check that we get it. + expectData("..."); EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "254.254.254.254"); @@ -192,9 +188,9 @@ TEST_P(ProxyProtocolTest, PartialRead) { write("54.254 1.2"); write(".3.4 65535"); - write(" 1234\r\n"); + write(" 1234\r\n..."); - dispatcher_.run(Event::Dispatcher::RunType::NonBlock); + expectData("..."); EXPECT_EQ(server_connection_->remoteAddress()->ip()->addressAsString(), "254.254.254.254"); @@ -202,7 +198,7 @@ TEST_P(ProxyProtocolTest, PartialRead) { } TEST_P(ProxyProtocolTest, MalformedProxyLine) { - connectNoRead(); + connect(false); write("BOGUS\r"); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); @@ -212,74 +208,74 @@ TEST_P(ProxyProtocolTest, MalformedProxyLine) { } TEST_P(ProxyProtocolTest, ProxyLineTooLarge) { - connectNoRead(); + connect(false); write("012345678901234567890123456789012345678901234567890123456789" "012345678901234567890123456789012345678901234567890123456789"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, NotEnoughFields) { - connectNoRead(); + connect(false); write("PROXY TCP6 1:2:3::4 5:6::7:8 1234\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, UnsupportedProto) { - connectNoRead(); + connect(false); write("PROXY UDP6 1:2:3::4 5:6::7:8 1234 5678\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, InvalidSrcAddress) { - connectNoRead(); + connect(false); write("PROXY TCP4 230.0.0.1 10.1.1.3 1234 5678\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, InvalidDstAddress) { - connectNoRead(); + connect(false); write("PROXY TCP4 10.1.1.2 0.0.0.0 1234 5678\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, BadPort) { - connectNoRead(); + connect(false); write("PROXY TCP6 1:2:3::4 5:6::7:8 1234 abc\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, NegativePort) { - connectNoRead(); + connect(false); write("PROXY TCP6 1:2:3::4 5:6::7:8 -1 1234\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, PortOutOfRange) { - connectNoRead(); + connect(false); write("PROXY TCP6 1:2:3::4 5:6::7:8 66776 1234\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, BadAddress) { - connectNoRead(); + connect(false); write("PROXY TCP6 1::2:3::4 5:6::7:8 1234 5678\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, AddressVersionsNotMatch) { - connectNoRead(); + connect(false); write("PROXY TCP4 [1:2:3::4] 1.2.3.4 1234 5678\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, AddressVersionsNotMatch2) { - connectNoRead(); + connect(false); write("PROXY TCP4 1.2.3.4 [1:2:3: 1234 4]:5678\r\nmore data"); expectProxyProtoError(); } TEST_P(ProxyProtocolTest, Truncated) { - connectNoRead(); + connect(false); write("PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678"); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); @@ -291,7 +287,7 @@ TEST_P(ProxyProtocolTest, Truncated) { } TEST_P(ProxyProtocolTest, Closed) { - connectNoRead(); + connect(false); write("PROXY TCP4 1.2.3"); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); @@ -303,6 +299,9 @@ TEST_P(ProxyProtocolTest, Closed) { } TEST_P(ProxyProtocolTest, ClosedEmpty) { + // We may or may not get these, depending on the operating system timing. + EXPECT_CALL(factory_, createListenerFilterChain(_)).Times(AtLeast(0)); + EXPECT_CALL(factory_, createNetworkFilterChain(_)).Times(AtLeast(0)); conn_->connect(); conn_->close(ConnectionCloseType::NoFlush); dispatcher_.run(Event::Dispatcher::RunType::NonBlock); @@ -365,6 +364,19 @@ class WildcardProxyProtocolTest : public testing::TestWithParamwrite(buf); } + void expectData(std::string expected) { + EXPECT_CALL(*read_filter_, onNewConnection()); + EXPECT_CALL(*read_filter_, onData(_)) + .WillOnce(Invoke([&](Buffer::Instance& buffer) -> FilterStatus { + EXPECT_EQ(TestUtility::bufferToString(buffer), expected); + buffer.drain(expected.length()); + dispatcher_.exit(); + return Network::FilterStatus::Continue; + })); + + dispatcher_.run(Event::Dispatcher::RunType::Block); + } + void disconnect() { EXPECT_CALL(connection_callbacks_, onEvent(ConnectionEvent::LocalClose)); conn_->close(ConnectionCloseType::NoFlush); @@ -396,17 +408,11 @@ TEST_P(WildcardProxyProtocolTest, Basic) { connect(); write("PROXY TCP4 1.2.3.4 254.254.254.254 65535 1234\r\nmore data"); - EXPECT_CALL(*read_filter_, onNewConnection()); - EXPECT_CALL(*read_filter_, onData(_)) - .WillOnce(Invoke([&](Buffer::Instance& buffer) -> FilterStatus { - EXPECT_EQ(server_connection_->remoteAddress()->asString(), "1.2.3.4:65535"); - EXPECT_EQ(server_connection_->localAddress()->asString(), "254.254.254.254:1234"); + expectData("more data"); + + EXPECT_EQ(server_connection_->remoteAddress()->asString(), "1.2.3.4:65535"); + EXPECT_EQ(server_connection_->localAddress()->asString(), "254.254.254.254:1234"); - EXPECT_EQ(TestUtility::bufferToString(buffer), "more data"); - buffer.drain(9); - return Network::FilterStatus::Continue; - })); - dispatcher_.run(Event::Dispatcher::RunType::NonBlock); disconnect(); } @@ -414,18 +420,11 @@ TEST_P(WildcardProxyProtocolTest, BasicV6) { connect(); write("PROXY TCP6 1:2:3::4 5:6::7:8 65535 1234\r\nmore data"); - EXPECT_CALL(*read_filter_, onNewConnection()); - EXPECT_CALL(*read_filter_, onData(_)) - .WillOnce(Invoke([&](Buffer::Instance& buffer) -> FilterStatus { - EXPECT_EQ(server_connection_->remoteAddress()->asString(), "[1:2:3::4]:65535"); - EXPECT_EQ(server_connection_->localAddress()->asString(), "[5:6::7:8]:1234"); + expectData("more data"); - EXPECT_EQ(TestUtility::bufferToString(buffer), "more data"); - buffer.drain(9); - return Network::FilterStatus::Continue; - })); + EXPECT_EQ(server_connection_->remoteAddress()->asString(), "[1:2:3::4]:65535"); + EXPECT_EQ(server_connection_->localAddress()->asString(), "[5:6::7:8]:1234"); - dispatcher_.run(Event::Dispatcher::RunType::NonBlock); disconnect(); } From a3908867a3fb51f9063ece0a5eb5710caad0ef87 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 22 Jan 2018 17:46:19 -0800 Subject: [PATCH 38/41] listener: Deprecate 'use_proxy_protocol' boolean from the v2 LDS API Deprecate 'use_proxy_protocol' boolean from the v2 LDS API, as the corresponding functionality can be attained with listener filters and filter chain matching. Handing off from one listener to another is supported for v2 API only until 'use_proxy_protocol' flag is removed. After that v2 API users have to use filter chain matching to implement filter chain selection. Signed-off-by: Jarno Rajahalme --- DEPRECATED.md | 3 +- include/envoy/event/dispatcher.h | 6 +- include/envoy/network/listener.h | 11 +- source/common/event/dispatcher_impl.cc | 6 +- source/common/event/dispatcher_impl.h | 3 +- source/common/network/listener_impl.cc | 8 +- source/common/network/listener_impl.h | 3 +- source/server/config_validation/dispatcher.cc | 2 +- source/server/config_validation/dispatcher.h | 3 +- source/server/connection_handler_impl.cc | 21 +- source/server/connection_handler_impl.h | 11 +- source/server/http/admin.h | 1 + source/server/listener_manager_impl.cc | 2 + source/server/listener_manager_impl.h | 2 + test/common/http/codec_client_test.cc | 2 +- test/common/network/connection_impl_test.cc | 6 +- test/common/network/dns_impl_test.cc | 2 +- test/common/network/listener_impl_test.cc | 13 +- test/common/network/proxy_protocol_test.cc | 2 + test/common/ssl/ssl_socket_test.cc | 20 +- test/integration/fake_upstream.h | 1 + test/mocks/event/mocks.h | 10 +- test/mocks/network/mocks.h | 1 + test/server/connection_handler_test.cc | 185 +++++++++--------- 24 files changed, 183 insertions(+), 141 deletions(-) diff --git a/DEPRECATED.md b/DEPRECATED.md index c9b1e285bd56b..8e08bc7c8f14a 100644 --- a/DEPRECATED.md +++ b/DEPRECATED.md @@ -14,7 +14,8 @@ The following features have been DEPRECATED and will be removed in the specified instead. * gRPC service configuration via the `cluster_names` field in `ApiConfigSource` is deprecated. Use `grpc_services` instead. - +* 'use_original_dst' field in the v2 LDS API is deprecated. Use listerner filters and filter chain + matching instead. ## Version 1.5.0 diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index ed9aecd211b61..6f58cfa12e6c3 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -91,11 +91,13 @@ 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 hand_off_restored_destinations controls whether the listener searches for another + * listener after restoring the destination address of a new connection. * @return Network::ListenerPtr a new listener that is owned by the caller. */ virtual Network::ListenerPtr createListener(Network::ListenSocket& socket, - Network::ListenerCallbacks& cb, - bool bind_to_port) PURE; + Network::ListenerCallbacks& cb, bool bind_to_port, + bool hand_off_restored_destinations) PURE; /** * Allocate a timer. @see Event::Timer for docs on how to use the timer. diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index c3e744386ebb2..6f6be0561c11f 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -43,6 +43,14 @@ class ListenerConfig { */ virtual bool bindToPort() PURE; + /** + * @return bool if a connection should be handed off to another Listener after the original + * destination address has been restored. 'true' when 'use_original_dst' flag in listener + * configuration is set, false otherwise. Note that this flag will be removed from the v2 + * API. + */ + virtual bool handOffRestoredDestinations() const PURE; + /** * @return uint32_t providing a soft limit on size of the listener's new connection read and write * buffers. @@ -79,7 +87,8 @@ class ListenerCallbacks { * and is redirected to a new listener. The recipient should not redirect * the socket any further. */ - virtual void onAccept(ConnectionSocketPtr&& socket, bool redirected = false) PURE; + virtual void onAccept(ConnectionSocketPtr&& socket, + bool hand_off_restored_destinations = true) PURE; /** * Called when a new connection is accepted. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index 9f6d95f23a65b..40191b574f03b 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -110,9 +110,11 @@ Filesystem::WatcherPtr DispatcherImpl::createFilesystemWatcher() { Network::ListenerPtr DispatcherImpl::createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - bool bind_to_port) { + bool bind_to_port, + bool hand_off_restored_destinations) { ASSERT(isThreadSafe()); - return Network::ListenerPtr{new Network::ListenerImpl(*this, socket, cb, bind_to_port)}; + return Network::ListenerPtr{ + new Network::ListenerImpl(*this, socket, cb, bind_to_port, hand_off_restored_destinations)}; } TimerPtr DispatcherImpl::createTimer(TimerCb cb) { diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 885ce556dd491..8c54cb2ab3e2f 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -45,7 +45,8 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { uint32_t events) override; Filesystem::WatcherPtr createFilesystemWatcher() override; Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - bool bind_to_port) override; + bool bind_to_port, + bool hand_off_restored_destinations) override; TimerPtr createTimer(TimerCb cb) override; void deferredDelete(DeferredDeletablePtr&& to_delete) override; void exit() override; diff --git a/source/common/network/listener_impl.cc b/source/common/network/listener_impl.cc index dc750aa412ec7..f150071ebcac1 100644 --- a/source/common/network/listener_impl.cc +++ b/source/common/network/listener_impl.cc @@ -36,12 +36,14 @@ void ListenerImpl::listenCallback(evconnlistener*, evutil_socket_t fd, sockaddr* ? Address::peerAddressFromFd(fd) : Address::addressFromSockAddr(*reinterpret_cast(remote_addr), remote_addr_len))); - listener->cb_.onAccept(std::move(socket)); + listener->cb_.onAccept(std::move(socket), listener->hand_off_restored_destinations_); } ListenerImpl::ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, - ListenerCallbacks& cb, bool bind_to_port) - : local_address_(nullptr), cb_(cb), listener_(nullptr) { + ListenerCallbacks& cb, bool bind_to_port, + bool hand_off_restored_destinations) + : local_address_(nullptr), cb_(cb), + hand_off_restored_destinations_(hand_off_restored_destinations), listener_(nullptr) { const auto ip = socket.localAddress()->ip(); // Only use the listen socket's local address for new connections if it is not the all hosts diff --git a/source/common/network/listener_impl.h b/source/common/network/listener_impl.h index 1c931d9b8a465..f2c4706bf9b02 100644 --- a/source/common/network/listener_impl.h +++ b/source/common/network/listener_impl.h @@ -17,13 +17,14 @@ namespace Network { class ListenerImpl : public Listener { public: ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, - bool bind_to_port); + bool bind_to_port, bool hand_off_restored_destinations); protected: virtual Address::InstanceConstSharedPtr getLocalAddress(int fd); Address::InstanceConstSharedPtr local_address_; ListenerCallbacks& cb_; + bool hand_off_restored_destinations_; private: static void errorCallback(evconnlistener* listener, void* context); diff --git a/source/server/config_validation/dispatcher.cc b/source/server/config_validation/dispatcher.cc index f9445c8b7671b..d4c433a836f27 100644 --- a/source/server/config_validation/dispatcher.cc +++ b/source/server/config_validation/dispatcher.cc @@ -18,7 +18,7 @@ Network::DnsResolverSharedPtr ValidationDispatcher::createDnsResolver( } Network::ListenerPtr ValidationDispatcher::createListener(Network::ListenSocket&, - Network::ListenerCallbacks&, bool) { + Network::ListenerCallbacks&, bool, bool) { NOT_IMPLEMENTED; } diff --git a/source/server/config_validation/dispatcher.h b/source/server/config_validation/dispatcher.h index 2480eaae4b9e1..7470dab5027c5 100644 --- a/source/server/config_validation/dispatcher.h +++ b/source/server/config_validation/dispatcher.h @@ -20,7 +20,8 @@ class ValidationDispatcher : public DispatcherImpl { Network::DnsResolverSharedPtr createDnsResolver( const std::vector& resolvers) override; Network::ListenerPtr createListener(Network::ListenSocket&, Network::ListenerCallbacks&, - bool bind_to_port) override; + bool bind_to_port, + bool hand_off_restored_destinations) override; }; } // namespace Event diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index bcb2962f735c3..4e2b1793397ef 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -61,7 +61,8 @@ void ConnectionHandlerImpl::ActiveListener::removeConnection(ActiveConnection& c ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& parent, Network::ListenerConfig& config) : ActiveListener(parent, - parent.dispatcher_.createListener(config.socket(), *this, config.bindToPort()), + parent.dispatcher_.createListener(config.socket(), *this, config.bindToPort(), + config.handOffRestoredDestinations()), config) {} ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& parent, @@ -123,8 +124,6 @@ ConnectionHandlerImpl::findActiveListenerByAddress(const Network::Address::Insta void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { if (success) { - ActiveListener* new_listener = nullptr; - if (iter_ == accept_filters_.end()) { iter_ = accept_filters_.begin(); } else { @@ -142,14 +141,17 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { // Successfully ran all the accept filters. // Check if the socket may need to be redirected to another listener. - if (!redirected_ && socket_->localAddressRestored()) { + ActiveListener* new_listener = nullptr; + + if (hand_off_restored_destinations_ && socket_->localAddressRestored()) { // Find a listener associated with the original destination address. new_listener = listener_.parent_.findActiveListenerByAddress(*socket_->localAddress()); } if (new_listener != nullptr) { - // Hands off connections redirecrted by iptables to the listener associated with the - // original destination address. Pass 'redirected' as true to prevent further redirection. - new_listener->onAccept(std::move(socket_), true); + // Hands off connections redirected by iptables to the listener associated with the + // original destination address. Pass 'hand_off_restored_destionations' as false to + // prevent further redirection. + new_listener->onAccept(std::move(socket_), false); } else { // Create a new connection on this listener. listener_.newConnection(std::move(socket_)); @@ -164,9 +166,10 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { } void ConnectionHandlerImpl::ActiveListener::onAccept(Network::ConnectionSocketPtr&& socket, - bool redirected) { + bool hand_off_restored_destinations) { Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); - auto active_socket = std::make_unique(*this, std::move(socket), redirected); + auto active_socket = + std::make_unique(*this, std::move(socket), hand_off_restored_destinations); // Create and run the filters config_.filterChainFactory().createListenerFilterChain(*active_socket); diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index a0bf9f9f533e2..d3816663ccaa4 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -76,7 +76,8 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ~ActiveListener(); // Network::ListenerCallbacks - void onAccept(Network::ConnectionSocketPtr&& socket, bool redirected) override; + void onAccept(Network::ConnectionSocketPtr&& socket, + bool hand_off_restored_destinations) override; void onNewConnection(Network::ConnectionPtr&& new_connection) override; /** @@ -133,8 +134,10 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { public Network::ListenerFilterCallbacks, LinkedObject, public Event::DeferredDeletable { - ActiveSocket(ActiveListener& listener, Network::ConnectionSocketPtr&& socket, bool redirected) - : listener_(listener), socket_(std::move(socket)), redirected_(redirected), + ActiveSocket(ActiveListener& listener, Network::ConnectionSocketPtr&& socket, + bool hand_off_restored_destinations) + : listener_(listener), socket_(std::move(socket)), + hand_off_restored_destinations_(hand_off_restored_destinations), iter_(accept_filters_.end()) {} ~ActiveSocket() { accept_filters_.clear(); } @@ -150,7 +153,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ActiveListener& listener_; Network::ConnectionSocketPtr socket_; - bool redirected_; + bool hand_off_restored_destinations_; std::list accept_filters_; std::list::iterator iter_; }; diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 698a6d4e6b2c7..6e46f20f0fb0c 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -176,6 +176,7 @@ class AdminImpl : public Admin, Network::ListenSocket& socket() override { return parent_.mutable_socket(); } Ssl::ServerContext* defaultSslContext() override { return nullptr; } bool bindToPort() override { return true; } + bool handOffRestoredDestinations() const override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return *scope_; } uint64_t listenerTag() const override { return 0; } diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index c77c6b562ec46..b45716be5ec5b 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -109,6 +109,8 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag listener_scope_( parent_.server_.stats().createScope(fmt::format("listener.{}.", address_->asString()))), bind_to_port_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.deprecated_v1(), bind_to_port, true)), + hand_off_restored_destinations_( + PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, use_original_dst, false)), per_connection_buffer_limit_bytes_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, per_connection_buffer_limit_bytes, 1024 * 1024)), listener_tag_(parent_.factory_.nextListenerTag()), name_(name), modifiable_(modifiable), diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index 3ffa0507ffc3b..73372646427e3 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -212,6 +212,7 @@ class ListenerImpl : public Network::ListenerConfig, Network::FilterChainFactory& filterChainFactory() override { return *this; } Network::ListenSocket& socket() override { return *socket_; } bool bindToPort() override { return bind_to_port_; } + bool handOffRestoredDestinations() const override { return hand_off_restored_destinations_; } Ssl::ServerContext* defaultSslContext() override { return tls_contexts_.empty() ? nullptr : tls_contexts_[0].get(); } @@ -257,6 +258,7 @@ class ListenerImpl : public Network::ListenerConfig, Stats::ScopePtr listener_scope_; // Stats with listener named scope. std::vector tls_contexts_; const bool bind_to_port_; + const bool hand_off_restored_destinations_; const uint32_t per_connection_buffer_limit_bytes_; const uint64_t listener_tag_; const std::string name_; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 4bafdd6fd3235..20014cb3dfa6f 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -179,7 +179,7 @@ class CodecNetworkTest : public testing::TestWithParamcreateListener(socket_, listener_callbacks_, true); + upstream_listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket()); client_connection_ = client_connection.get(); diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index d0a6783095d12..ae869ca079ace 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -81,7 +81,7 @@ class ConnectionImplTest : public testing::TestWithParam { if (dispatcher_.get() == nullptr) { dispatcher_.reset(new Event::DispatcherImpl); } - listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); client_connection_ = dispatcher_->createClientConnection( socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket()); @@ -576,7 +576,7 @@ TEST_P(ConnectionImplTest, BindFailureTest) { new Network::Address::Ipv6Instance(address_string, 0)}; } dispatcher_.reset(new Event::DispatcherImpl); - listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); client_connection_ = dispatcher_->createClientConnection(socket_.localAddress(), source_address_, Network::Test::createRawBufferSocket()); @@ -751,7 +751,7 @@ class ReadBufferLimitTest : public ConnectionImplTest { void readBufferLimitTest(uint32_t read_buffer_limit, uint32_t expected_chunk_size) { const uint32_t buffer_size = 256 * 1024; dispatcher_.reset(new Event::DispatcherImpl); - listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); client_connection_ = dispatcher_->createClientConnection( socket_.localAddress(), Network::Address::InstanceConstSharedPtr(), diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 0911b266a79e4..28accb4de76bc 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -289,7 +289,7 @@ class DnsImplTest : public testing::TestWithParam { server_.reset(new TestDnsServer(dispatcher_)); socket_.reset( new Network::TcpListenSocket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true)); - listener_ = dispatcher_.createListener(*socket_, *server_, true); + listener_ = dispatcher_.createListener(*socket_, *server_, true, false); // Point c-ares at the listener with no search domains and TCP-only. peer_.reset(new DnsResolverImplPeer(dynamic_cast(resolver_.get()))); diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index f0ffa5818c6df..7431e6d1a4a43 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -27,7 +27,8 @@ static void errorCallbackTest(Address::IpVersion version) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), 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, false); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -61,8 +62,8 @@ TEST_P(ListenerImplDeathTest, ErrorCallback) { class TestListenerImpl : public ListenerImpl { public: TestListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, - bool bind_to_port) - : ListenerImpl(dispatcher, socket, cb, bind_to_port) {} + bool bind_to_port, bool hand_off_restored_destinations) + : ListenerImpl(dispatcher, socket, cb, bind_to_port, hand_off_restored_destinations) {} MOCK_METHOD1(getLocalAddress, Address::InstanceConstSharedPtr(int fd)); }; @@ -88,9 +89,9 @@ TEST_P(ListenerImplTest, UseActualDst) { Network::MockListenerCallbacks listener_callbacks1; Network::MockConnectionHandler connection_handler; // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks1, true); + Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks1, true, true); Network::MockListenerCallbacks listener_callbacks2; - Network::TestListenerImpl listenerDst(dispatcher, socketDst, listener_callbacks2, false); + Network::TestListenerImpl listenerDst(dispatcher, socketDst, listener_callbacks2, false, false); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -124,7 +125,7 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; // Do not redirect since use_original_dst is false. - Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks, true); + Network::TestListenerImpl listener(dispatcher, socket, listener_callbacks, true, true); auto local_dst_address = Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(version_), socket.localAddress()->ip()->port()); diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index bd5a656663b18..3326e9763da13 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -53,6 +53,7 @@ class ProxyProtocolTest : public testing::TestWithParam, Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } bool bindToPort() override { return true; } + bool handOffRestoredDestinations() const override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return stats_store_; } uint64_t listenerTag() const override { return 1; } @@ -339,6 +340,7 @@ class WildcardProxyProtocolTest : public testing::TestWithParam callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); ClientContextConfigImpl client_ctx_config(client_ctx_proto); ClientSslSocketFactory ssl_socket_factory(client_ctx_config, manager, stats_store); @@ -685,7 +685,7 @@ TEST_P(SslSocketTest, FlushCloseDuringHandshake) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -741,7 +741,7 @@ TEST_P(SslSocketTest, ClientAuthMultipleCAs) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); std::string client_ctx_json = R"EOF( { @@ -822,8 +822,8 @@ void testTicketSessionResumption(const std::string& server_ctx_json1, Network::TcpListenSocket socket2(Network::Test::getCanonicalLoopbackAddress(ip_version), true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true); - Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true); + Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true, false); + Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); Json::ObjectSharedPtr client_ctx_loader = TestEnvironment::jsonLoadFromString(client_ctx_json); ClientContextConfigImpl client_ctx_config(*client_ctx_loader); @@ -1143,8 +1143,8 @@ TEST_P(SslSocketTest, ClientAuthCrossListenerSessionResumption) { Network::TcpListenSocket socket2(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); - Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); + Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); std::string client_ctx_json = R"EOF( { @@ -1248,7 +1248,7 @@ TEST_P(SslSocketTest, SslError) { Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(GetParam()), true); Network::MockListenerCallbacks callbacks; Network::MockConnectionHandler connection_handler; - Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true); + Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -1851,7 +1851,7 @@ class SslReadBufferLimitTest : public SslCertsTest, manager_.reset(new ContextManagerImpl(runtime_)); server_ctx_ = manager_->createSslServerContext("", {}, stats_store_, *server_ctx_config_, true); - listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true); + listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); client_ctx_loader_ = TestEnvironment::jsonLoadFromString(client_ctx_json_); client_ctx_config_.reset(new ClientContextConfigImpl(*client_ctx_loader_)); diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index 2a13eaa35f8c0..8785f70d8ca19 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -316,6 +316,7 @@ class FakeUpstream : Logger::Loggable, public Network::Filt Network::ListenSocket& socket() override { return *parent_.socket_; } Ssl::ServerContext* defaultSslContext() override { return parent_.ssl_ctx_; } bool bindToPort() override { return true; } + bool handOffRestoredDestinations() const override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return parent_.stats_store_; } uint64_t listenerTag() const override { return 0; } diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index d084f23b80be7..00c548f77381c 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -52,8 +52,10 @@ class MockDispatcher : public Dispatcher { } Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - bool bind_to_port) override { - return Network::ListenerPtr{createListener_(socket, cb, bind_to_port)}; + bool bind_to_port, + bool hand_off_restored_destinations) override { + return Network::ListenerPtr{ + createListener_(socket, cb, bind_to_port, hand_off_restored_destinations)}; } TimerPtr createTimer(TimerCb cb) override { return TimerPtr{createTimer_(cb)}; } @@ -83,9 +85,9 @@ class MockDispatcher : public Dispatcher { MOCK_METHOD4(createFileEvent_, FileEvent*(int fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events)); MOCK_METHOD0(createFilesystemWatcher_, Filesystem::Watcher*()); - MOCK_METHOD3(createListener_, + MOCK_METHOD4(createListener_, Network::Listener*(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - bool bind_to_port)); + bool bind_to_port, bool hand_off_restored_destinations)); MOCK_METHOD1(createTimer_, Timer*(TimerCb cb)); MOCK_METHOD1(deferredDelete_, void(DeferredDeletablePtr& to_delete)); MOCK_METHOD0(exit, void()); diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index ff49289e7bad8..417e44615e1fb 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -286,6 +286,7 @@ class MockListenerConfig : public ListenerConfig { MOCK_METHOD0(socket, ListenSocket&()); MOCK_METHOD0(defaultSslContext, Ssl::ServerContext*()); MOCK_METHOD0(bindToPort, bool()); + MOCK_CONST_METHOD0(handOffRestoredDestinations, bool()); MOCK_METHOD0(perConnectionBufferLimitBytes, uint32_t()); MOCK_METHOD0(listenerScope, Stats::Scope&()); MOCK_CONST_METHOD0(listenerTag, uint64_t()); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index 0494b685848e2..a52271f0ad91a 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -29,13 +29,15 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable { public: TestListener(ConnectionHandlerTest& parent, uint64_t tag, bool bind_to_port, - const std::string& name) - : parent_(parent), tag_(tag), bind_to_port_(bind_to_port), name_(name) {} + bool hand_off_restored_destinations, const std::string& name) + : parent_(parent), tag_(tag), bind_to_port_(bind_to_port), + hand_off_restored_destinations_(hand_off_restored_destinations), name_(name) {} Network::FilterChainFactory& filterChainFactory() override { return parent_.factory_; } Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } bool bindToPort() override { return bind_to_port_; } + bool handOffRestoredDestinations() const override { return hand_off_restored_destinations_; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return parent_.stats_store_; } uint64_t listenerTag() const override { return tag_; } @@ -45,13 +47,16 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable TestListenerPtr; - TestListener* addListener(uint64_t tag, bool bind_to_port, const std::string& name) { - TestListener* listener = new TestListener(*this, tag, bind_to_port, name); + TestListener* addListener(uint64_t tag, bool bind_to_port, bool hand_off_restored_destinations, + const std::string& name) { + TestListener* listener = + new TestListener(*this, tag, bind_to_port, hand_off_restored_destinations, name); listener->moveIntoListBack(TestListenerPtr{listener}, listeners_); return listener; } @@ -68,14 +73,14 @@ TEST_F(ConnectionHandlerTest, RemoveListener) { Network::MockListener* listener = new NiceMock(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener; - - })); - TestListener* test_listener = addListener(1, true, "test_listener"); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, false)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; + + })); + TestListener* test_listener = addListener(1, true, false, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -106,14 +111,14 @@ TEST_F(ConnectionHandlerTest, DestroyCloseConnections) { Network::MockListener* listener = new NiceMock(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener; - - })); - TestListener* test_listener = addListener(1, true, "test_listener"); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, _)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; + + })); + TestListener* test_listener = addListener(1, true, false, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -133,14 +138,14 @@ TEST_F(ConnectionHandlerTest, CloseDuringFilterChainCreate) { Network::MockListener* listener = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener; - - })); - TestListener* test_listener = addListener(1, true, "test_listener"); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, _)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; + + })); + TestListener* test_listener = addListener(1, true, false, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -159,14 +164,14 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { Network::MockListener* listener = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks = &cb; - return listener; - - })); - TestListener* test_listener = addListener(1, true, "test_listener"); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, _)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks = &cb; + return listener; + + })); + TestListener* test_listener = addListener(1, true, false, "test_listener"); EXPECT_CALL(test_listener->socket_, localAddress()); handler_->addListener(*test_listener); @@ -180,28 +185,28 @@ TEST_F(ConnectionHandlerTest, CloseConnectionOnEmptyFilterChain) { } TEST_F(ConnectionHandlerTest, FindListenerByAddress) { - TestListener* test_listener1 = addListener(1, true, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, true, "test_listener1"); Network::Address::InstanceConstSharedPtr alt_address( new Network::Address::Ipv4Instance("127.0.0.1", 10001)); Network::MockListener* listener = new Network::MockListener(); - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, + EXPECT_CALL(dispatcher_, createListener_(_, _, _, true)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, bool, bool) -> Network::Listener* { return listener; })); EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(alt_address)); handler_->addListener(*test_listener1); EXPECT_EQ(listener, handler_->findListenerByAddress(ByRef(*alt_address))); - TestListener* test_listener2 = addListener(2, true, "test_listener2"); + TestListener* test_listener2 = addListener(2, true, false, "test_listener2"); Network::Address::InstanceConstSharedPtr alt_address2( new Network::Address::Ipv4Instance("0.0.0.0", 10001)); Network::Address::InstanceConstSharedPtr alt_address3( new Network::Address::Ipv4Instance("127.0.0.2", 10001)); Network::MockListener* listener2 = new Network::MockListener(); - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, + EXPECT_CALL(dispatcher_, createListener_(_, _, _, false)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, bool, bool) -> Network::Listener* { return listener2; })); EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(alt_address2)); handler_->addListener(*test_listener2); @@ -218,8 +223,8 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { handler_->stopListeners(2); Network::MockListener* listener3 = new Network::MockListener(); - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, + EXPECT_CALL(dispatcher_, createListener_(_, _, _, _)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks&, bool, bool) -> Network::Listener* { return listener3; })); handler_->addListener(*test_listener2); @@ -230,29 +235,29 @@ TEST_F(ConnectionHandlerTest, FindListenerByAddress) { } TEST_F(ConnectionHandlerTest, NormalRedirect) { - TestListener* test_listener1 = addListener(1, true, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks1 = &cb; - return listener1; - })); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, true)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); Network::Address::InstanceConstSharedPtr normal_address( new Network::Address::Ipv4Instance("127.0.0.1", 10001)); EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(normal_address)); handler_->addListener(*test_listener1); - TestListener* test_listener2 = addListener(1, false, "test_listener2"); + TestListener* test_listener2 = addListener(1, false, false, "test_listener2"); Network::MockListener* listener2 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks2; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks2 = &cb; - return listener2; - })); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, false)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks2 = &cb; + return listener2; + })); Network::Address::InstanceConstSharedPtr alt_address( new Network::Address::Ipv4Instance("127.0.0.2", 20002)); EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(alt_address)); @@ -281,7 +286,7 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, true); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -289,29 +294,29 @@ TEST_F(ConnectionHandlerTest, NormalRedirect) { } TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { - TestListener* test_listener1 = addListener(1, true, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks1 = &cb; - return listener1; - })); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, true)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); Network::Address::InstanceConstSharedPtr normal_address( new Network::Address::Ipv4Instance("127.0.0.1", 10001)); EXPECT_CALL(test_listener1->socket_, localAddress()).WillRepeatedly(Return(normal_address)); handler_->addListener(*test_listener1); - TestListener* test_listener2 = addListener(1, false, "test_listener2"); + TestListener* test_listener2 = addListener(1, false, false, "test_listener2"); Network::MockListener* listener2 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks2; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks2 = &cb; - return listener2; - })); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, false)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks2 = &cb; + return listener2; + })); Network::Address::InstanceConstSharedPtr any_address = Network::Utility::getIpv4AnyAddress(); EXPECT_CALL(test_listener2->socket_, localAddress()).WillRepeatedly(Return(any_address)); handler_->addListener(*test_listener2); @@ -342,7 +347,7 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, true); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener2, onDestroy()); @@ -350,15 +355,15 @@ TEST_F(ConnectionHandlerTest, FallbackToWildcardListener) { } TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { - TestListener* test_listener1 = addListener(1, true, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks1 = &cb; - return listener1; - })); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, true)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); Network::Address::InstanceConstSharedPtr normal_address( new Network::Address::Ipv4Instance("127.0.0.1", 80)); // Original dst address nor port number match that of the listener's address. @@ -388,22 +393,22 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithOriginalDst) { Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, true); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); } TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { - TestListener* test_listener1 = addListener(1, true, "test_listener1"); + TestListener* test_listener1 = addListener(1, true, true, "test_listener1"); Network::MockListener* listener1 = new Network::MockListener(); Network::ListenerCallbacks* listener_callbacks1; - EXPECT_CALL(dispatcher_, createListener_(_, _, _)) - .WillOnce(Invoke( - [&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool) -> Network::Listener* { - listener_callbacks1 = &cb; - return listener1; - })); + EXPECT_CALL(dispatcher_, createListener_(_, _, _, true)) + .WillOnce(Invoke([&](Network::ListenSocket&, Network::ListenerCallbacks& cb, bool, + bool) -> Network::Listener* { + listener_callbacks1 = &cb; + return listener1; + })); Network::Address::InstanceConstSharedPtr normal_address( new Network::Address::Ipv4Instance("127.0.0.1", 80)); Network::Address::InstanceConstSharedPtr any_address = Network::Utility::getAddressWithPort( @@ -425,7 +430,7 @@ TEST_F(ConnectionHandlerTest, WildcardListenerWithNoOriginalDst) { Network::MockConnection* connection = new NiceMock(); EXPECT_CALL(factory_, createNetworkFilterChain(_)).WillOnce(Return(true)); EXPECT_CALL(dispatcher_, createServerConnection_(_, _)).WillOnce(Return(connection)); - listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, false); + listener_callbacks1->onAccept(Network::ConnectionSocketPtr{accepted_socket}, true); EXPECT_EQ(1UL, handler_->numConnections()); EXPECT_CALL(*listener1, onDestroy()); From ae07e0fc979e92f85b047afe04cd8e758d997135 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 22 Jan 2018 18:03:01 -0800 Subject: [PATCH 39/41] Review fixes. Signed-off-by: Jarno Rajahalme --- source/common/filter/listener/proxy_protocol.h | 6 +++--- source/common/network/connection_impl.cc | 4 ++-- source/common/network/listen_socket_impl.h | 2 ++ source/server/connection_handler_impl.h | 2 +- source/server/listener_manager_impl.cc | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/common/filter/listener/proxy_protocol.h b/source/common/filter/listener/proxy_protocol.h index e938d12c2be0f..98a4b6defbfc3 100644 --- a/source/common/filter/listener/proxy_protocol.h +++ b/source/common/filter/listener/proxy_protocol.h @@ -44,7 +44,7 @@ typedef std::shared_ptr ConfigSharedPtr; */ class Instance : public Network::ListenerFilter, Logger::Loggable { public: - Instance(const ConfigSharedPtr& config) : search_index_(1), config_(config) {} + Instance(const ConfigSharedPtr& config) : config_(config) {} // Network::ListenerFilter Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override; @@ -62,14 +62,14 @@ class Instance : public Network::ListenerFilter, Logger::Loggable(remote_address), std::move(transport_socket), false) { if (source_address != nullptr) { - int rc = source_address->bind(fd()); + const int rc = source_address->bind(fd()); if (rc < 0) { ENVOY_LOG_MISC(debug, "Bind failure. Failed to bind to {}: {}", source_address->asString(), strerror(errno)); @@ -497,7 +497,7 @@ ClientConnectionImpl::ClientConnectionImpl( void ClientConnectionImpl::connect() { ENVOY_CONN_LOG(debug, "connecting to {}", *this, socket_->remoteAddress()->asString()); - int rc = socket_->remoteAddress()->connect(fd()); + const int rc = socket_->remoteAddress()->connect(fd()); if (rc == 0) { // write will become ready. ASSERT(connecting_); diff --git a/source/common/network/listen_socket_impl.h b/source/common/network/listen_socket_impl.h index 82b2d118acd7c..660f674b7ebb7 100644 --- a/source/common/network/listen_socket_impl.h +++ b/source/common/network/listen_socket_impl.h @@ -7,6 +7,7 @@ #include "envoy/network/listen_socket.h" +#include "common/common/assert.h" #include "common/ssl/context_impl.h" namespace Envoy { @@ -62,6 +63,7 @@ class ConnectionSocketImpl : virtual public ConnectionSocket { const Address::InstanceConstSharedPtr& remoteAddress() const override { return remote_address_; } void setLocalAddress(const Address::InstanceConstSharedPtr& local_address, bool restored) override { + ASSERT(!restored || *local_address != *local_address_); local_address_ = local_address; local_address_restored_ = restored; } diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index d3816663ccaa4..a0186550b06e2 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -153,7 +153,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ActiveListener& listener_; Network::ConnectionSocketPtr socket_; - bool hand_off_restored_destinations_; + const bool hand_off_restored_destinations_; std::list accept_filters_; std::list::iterator iter_; }; diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index b45716be5ec5b..808b0518cba75 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -120,7 +120,7 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag // filter chain #1308. ASSERT(config.filter_chains().size() >= 1); - if (config.listener_filters().size()) { + if (!config.listener_filters().empty()) { listener_filter_factories_ = parent_.factory_.createListenerFilterFactoryList(config.listener_filters(), *this); } From f5c19a97aa2bcd73f16b42fc262461332a720ee7 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 23 Jan 2018 12:19:04 -0800 Subject: [PATCH 40/41] Last nits. Signed-off-by: Jarno Rajahalme --- include/envoy/network/listener.h | 4 ++-- source/common/network/listener_impl.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 6f6be0561c11f..29937e034c4ef 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -46,8 +46,8 @@ class ListenerConfig { /** * @return bool if a connection should be handed off to another Listener after the original * destination address has been restored. 'true' when 'use_original_dst' flag in listener - * configuration is set, false otherwise. Note that this flag will be removed from the v2 - * API. + * configuration is set, false otherwise. Note that this flag is deprecated and will be + * removed from the v2 API. */ virtual bool handOffRestoredDestinations() const PURE; diff --git a/source/common/network/listener_impl.h b/source/common/network/listener_impl.h index f2c4706bf9b02..112dd91d632b6 100644 --- a/source/common/network/listener_impl.h +++ b/source/common/network/listener_impl.h @@ -24,7 +24,7 @@ class ListenerImpl : public Listener { Address::InstanceConstSharedPtr local_address_; ListenerCallbacks& cb_; - bool hand_off_restored_destinations_; + const bool hand_off_restored_destinations_; private: static void errorCallback(evconnlistener* listener, void* context); From 6b3e81d897d3f36847fb82e03d94db32841ef7e2 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Tue, 23 Jan 2018 13:59:15 -0800 Subject: [PATCH 41/41] Remame handOffRestoredDestinations() as handOffRestoredDestinationConnections(). Remame handOffRestoredDestinations() as handOffRestoredDestinationConnections(). Corresponding rename for parameter and member variable names, too. Constify the 'bool hand_off_restored_destination_connections_' member variable in tests. Suggested-by: Matt Klein Signed-off-by: Jarno Rajahalme --- include/envoy/event/dispatcher.h | 6 +++--- include/envoy/network/listener.h | 4 ++-- source/common/event/dispatcher_impl.cc | 11 +++++------ source/common/event/dispatcher_impl.h | 2 +- source/common/network/listener_impl.cc | 7 ++++--- source/common/network/listener_impl.h | 4 ++-- source/server/config_validation/dispatcher.h | 2 +- source/server/connection_handler_impl.cc | 19 ++++++++++--------- source/server/connection_handler_impl.h | 8 ++++---- source/server/http/admin.h | 2 +- source/server/listener_manager_impl.cc | 2 +- source/server/listener_manager_impl.h | 6 ++++-- test/common/network/listener_impl_test.cc | 5 +++-- test/common/network/proxy_protocol_test.cc | 4 ++-- test/integration/fake_upstream.h | 2 +- test/mocks/event/mocks.h | 7 ++++--- test/mocks/network/mocks.h | 2 +- test/server/connection_handler_test.cc | 16 ++++++++++------ 18 files changed, 59 insertions(+), 50 deletions(-) diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 6f58cfa12e6c3..5e0587eca9158 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -91,13 +91,13 @@ 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 hand_off_restored_destinations controls whether the listener searches for another - * listener after restoring the destination address of a new connection. + * @param hand_off_restored_destination_connections controls whether the listener searches for + * another listener after restoring the destination address of a new connection. * @return Network::ListenerPtr a new listener that is owned by the caller. */ virtual Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, bool bind_to_port, - bool hand_off_restored_destinations) PURE; + bool hand_off_restored_destination_connections) PURE; /** * Allocate a timer. @see Event::Timer for docs on how to use the timer. diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 29937e034c4ef..16e1327840e09 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -49,7 +49,7 @@ class ListenerConfig { * configuration is set, false otherwise. Note that this flag is deprecated and will be * removed from the v2 API. */ - virtual bool handOffRestoredDestinations() const PURE; + virtual bool handOffRestoredDestinationConnections() const PURE; /** * @return uint32_t providing a soft limit on size of the listener's new connection read and write @@ -88,7 +88,7 @@ class ListenerCallbacks { * the socket any further. */ virtual void onAccept(ConnectionSocketPtr&& socket, - bool hand_off_restored_destinations = true) PURE; + bool hand_off_restored_destination_connections = true) PURE; /** * Called when a new connection is accepted. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index 40191b574f03b..46377f5794baa 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -108,13 +108,12 @@ Filesystem::WatcherPtr DispatcherImpl::createFilesystemWatcher() { return Filesystem::WatcherPtr{new Filesystem::WatcherImpl(*this)}; } -Network::ListenerPtr DispatcherImpl::createListener(Network::ListenSocket& socket, - Network::ListenerCallbacks& cb, - bool bind_to_port, - bool hand_off_restored_destinations) { +Network::ListenerPtr +DispatcherImpl::createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, + bool bind_to_port, bool hand_off_restored_destination_connections) { ASSERT(isThreadSafe()); - return Network::ListenerPtr{ - new Network::ListenerImpl(*this, socket, cb, bind_to_port, hand_off_restored_destinations)}; + return Network::ListenerPtr{new Network::ListenerImpl(*this, socket, cb, bind_to_port, + hand_off_restored_destination_connections)}; } TimerPtr DispatcherImpl::createTimer(TimerCb cb) { diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 8c54cb2ab3e2f..6aa4342aece43 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -46,7 +46,7 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { Filesystem::WatcherPtr createFilesystemWatcher() override; Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, bool bind_to_port, - bool hand_off_restored_destinations) override; + bool hand_off_restored_destination_connections) override; TimerPtr createTimer(TimerCb cb) override; void deferredDelete(DeferredDeletablePtr&& to_delete) override; void exit() override; diff --git a/source/common/network/listener_impl.cc b/source/common/network/listener_impl.cc index f150071ebcac1..f5fa515d31625 100644 --- a/source/common/network/listener_impl.cc +++ b/source/common/network/listener_impl.cc @@ -36,14 +36,15 @@ void ListenerImpl::listenCallback(evconnlistener*, evutil_socket_t fd, sockaddr* ? Address::peerAddressFromFd(fd) : Address::addressFromSockAddr(*reinterpret_cast(remote_addr), remote_addr_len))); - listener->cb_.onAccept(std::move(socket), listener->hand_off_restored_destinations_); + listener->cb_.onAccept(std::move(socket), listener->hand_off_restored_destination_connections_); } ListenerImpl::ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, bool bind_to_port, - bool hand_off_restored_destinations) + bool hand_off_restored_destination_connections) : local_address_(nullptr), cb_(cb), - hand_off_restored_destinations_(hand_off_restored_destinations), listener_(nullptr) { + hand_off_restored_destination_connections_(hand_off_restored_destination_connections), + listener_(nullptr) { const auto ip = socket.localAddress()->ip(); // Only use the listen socket's local address for new connections if it is not the all hosts diff --git a/source/common/network/listener_impl.h b/source/common/network/listener_impl.h index 112dd91d632b6..8ff0bcdbccb4e 100644 --- a/source/common/network/listener_impl.h +++ b/source/common/network/listener_impl.h @@ -17,14 +17,14 @@ namespace Network { class ListenerImpl : public Listener { public: ListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, - bool bind_to_port, bool hand_off_restored_destinations); + bool bind_to_port, bool hand_off_restored_destination_connections); protected: virtual Address::InstanceConstSharedPtr getLocalAddress(int fd); Address::InstanceConstSharedPtr local_address_; ListenerCallbacks& cb_; - const bool hand_off_restored_destinations_; + const bool hand_off_restored_destination_connections_; private: static void errorCallback(evconnlistener* listener, void* context); diff --git a/source/server/config_validation/dispatcher.h b/source/server/config_validation/dispatcher.h index 7470dab5027c5..eeb647460bf23 100644 --- a/source/server/config_validation/dispatcher.h +++ b/source/server/config_validation/dispatcher.h @@ -21,7 +21,7 @@ class ValidationDispatcher : public DispatcherImpl { const std::vector& resolvers) override; Network::ListenerPtr createListener(Network::ListenSocket&, Network::ListenerCallbacks&, bool bind_to_port, - bool hand_off_restored_destinations) override; + bool hand_off_restored_destination_connections) override; }; } // namespace Event diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index 4e2b1793397ef..444bf40fae606 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -60,10 +60,11 @@ void ConnectionHandlerImpl::ActiveListener::removeConnection(ActiveConnection& c ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& parent, Network::ListenerConfig& config) - : ActiveListener(parent, - parent.dispatcher_.createListener(config.socket(), *this, config.bindToPort(), - config.handOffRestoredDestinations()), - config) {} + : ActiveListener( + parent, + parent.dispatcher_.createListener(config.socket(), *this, config.bindToPort(), + config.handOffRestoredDestinationConnections()), + config) {} ConnectionHandlerImpl::ActiveListener::ActiveListener(ConnectionHandlerImpl& parent, Network::ListenerPtr&& listener, @@ -143,7 +144,7 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { // Check if the socket may need to be redirected to another listener. ActiveListener* new_listener = nullptr; - if (hand_off_restored_destinations_ && socket_->localAddressRestored()) { + if (hand_off_restored_destination_connections_ && socket_->localAddressRestored()) { // Find a listener associated with the original destination address. new_listener = listener_.parent_.findActiveListenerByAddress(*socket_->localAddress()); } @@ -165,11 +166,11 @@ void ConnectionHandlerImpl::ActiveSocket::continueFilterChain(bool success) { } } -void ConnectionHandlerImpl::ActiveListener::onAccept(Network::ConnectionSocketPtr&& socket, - bool hand_off_restored_destinations) { +void ConnectionHandlerImpl::ActiveListener::onAccept( + Network::ConnectionSocketPtr&& socket, bool hand_off_restored_destination_connections) { Network::Address::InstanceConstSharedPtr local_address = socket->localAddress(); - auto active_socket = - std::make_unique(*this, std::move(socket), hand_off_restored_destinations); + auto active_socket = std::make_unique(*this, std::move(socket), + hand_off_restored_destination_connections); // Create and run the filters config_.filterChainFactory().createListenerFilterChain(*active_socket); diff --git a/source/server/connection_handler_impl.h b/source/server/connection_handler_impl.h index a0186550b06e2..86be964968ecb 100644 --- a/source/server/connection_handler_impl.h +++ b/source/server/connection_handler_impl.h @@ -77,7 +77,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { // Network::ListenerCallbacks void onAccept(Network::ConnectionSocketPtr&& socket, - bool hand_off_restored_destinations) override; + bool hand_off_restored_destination_connections) override; void onNewConnection(Network::ConnectionPtr&& new_connection) override; /** @@ -135,9 +135,9 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { LinkedObject, public Event::DeferredDeletable { ActiveSocket(ActiveListener& listener, Network::ConnectionSocketPtr&& socket, - bool hand_off_restored_destinations) + bool hand_off_restored_destination_connections) : listener_(listener), socket_(std::move(socket)), - hand_off_restored_destinations_(hand_off_restored_destinations), + hand_off_restored_destination_connections_(hand_off_restored_destination_connections), iter_(accept_filters_.end()) {} ~ActiveSocket() { accept_filters_.clear(); } @@ -153,7 +153,7 @@ class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable { ActiveListener& listener_; Network::ConnectionSocketPtr socket_; - const bool hand_off_restored_destinations_; + const bool hand_off_restored_destination_connections_; std::list accept_filters_; std::list::iterator iter_; }; diff --git a/source/server/http/admin.h b/source/server/http/admin.h index 6e46f20f0fb0c..c329993faae0b 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -176,7 +176,7 @@ class AdminImpl : public Admin, Network::ListenSocket& socket() override { return parent_.mutable_socket(); } Ssl::ServerContext* defaultSslContext() override { return nullptr; } bool bindToPort() override { return true; } - bool handOffRestoredDestinations() const override { return false; } + bool handOffRestoredDestinationConnections() const override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return *scope_; } uint64_t listenerTag() const override { return 0; } diff --git a/source/server/listener_manager_impl.cc b/source/server/listener_manager_impl.cc index 808b0518cba75..736681d04fd53 100644 --- a/source/server/listener_manager_impl.cc +++ b/source/server/listener_manager_impl.cc @@ -109,7 +109,7 @@ ListenerImpl::ListenerImpl(const envoy::api::v2::Listener& config, ListenerManag listener_scope_( parent_.server_.stats().createScope(fmt::format("listener.{}.", address_->asString()))), bind_to_port_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.deprecated_v1(), bind_to_port, true)), - hand_off_restored_destinations_( + hand_off_restored_destination_connections_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, use_original_dst, false)), per_connection_buffer_limit_bytes_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, per_connection_buffer_limit_bytes, 1024 * 1024)), diff --git a/source/server/listener_manager_impl.h b/source/server/listener_manager_impl.h index 73372646427e3..e3e5c78e7d732 100644 --- a/source/server/listener_manager_impl.h +++ b/source/server/listener_manager_impl.h @@ -212,7 +212,9 @@ class ListenerImpl : public Network::ListenerConfig, Network::FilterChainFactory& filterChainFactory() override { return *this; } Network::ListenSocket& socket() override { return *socket_; } bool bindToPort() override { return bind_to_port_; } - bool handOffRestoredDestinations() const override { return hand_off_restored_destinations_; } + bool handOffRestoredDestinationConnections() const override { + return hand_off_restored_destination_connections_; + } Ssl::ServerContext* defaultSslContext() override { return tls_contexts_.empty() ? nullptr : tls_contexts_[0].get(); } @@ -258,7 +260,7 @@ class ListenerImpl : public Network::ListenerConfig, Stats::ScopePtr listener_scope_; // Stats with listener named scope. std::vector tls_contexts_; const bool bind_to_port_; - const bool hand_off_restored_destinations_; + const bool hand_off_restored_destination_connections_; const uint32_t per_connection_buffer_limit_bytes_; const uint64_t listener_tag_; const std::string name_; diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index 7431e6d1a4a43..7048954f216a2 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -62,8 +62,9 @@ TEST_P(ListenerImplDeathTest, ErrorCallback) { class TestListenerImpl : public ListenerImpl { public: TestListenerImpl(Event::DispatcherImpl& dispatcher, ListenSocket& socket, ListenerCallbacks& cb, - bool bind_to_port, bool hand_off_restored_destinations) - : ListenerImpl(dispatcher, socket, cb, bind_to_port, hand_off_restored_destinations) {} + bool bind_to_port, bool hand_off_restored_destination_connections) + : ListenerImpl(dispatcher, socket, cb, bind_to_port, + hand_off_restored_destination_connections) {} MOCK_METHOD1(getLocalAddress, Address::InstanceConstSharedPtr(int fd)); }; diff --git a/test/common/network/proxy_protocol_test.cc b/test/common/network/proxy_protocol_test.cc index 3326e9763da13..040d704fceca8 100644 --- a/test/common/network/proxy_protocol_test.cc +++ b/test/common/network/proxy_protocol_test.cc @@ -53,7 +53,7 @@ class ProxyProtocolTest : public testing::TestWithParam, Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } bool bindToPort() override { return true; } - bool handOffRestoredDestinations() const override { return false; } + bool handOffRestoredDestinationConnections() const override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return stats_store_; } uint64_t listenerTag() const override { return 1; } @@ -340,7 +340,7 @@ class WildcardProxyProtocolTest : public testing::TestWithParam, public Network::Filt Network::ListenSocket& socket() override { return *parent_.socket_; } Ssl::ServerContext* defaultSslContext() override { return parent_.ssl_ctx_; } bool bindToPort() override { return true; } - bool handOffRestoredDestinations() const override { return false; } + bool handOffRestoredDestinationConnections() const override { return false; } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return parent_.stats_store_; } uint64_t listenerTag() const override { return 0; } diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 00c548f77381c..6998cff846d51 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -53,9 +53,9 @@ class MockDispatcher : public Dispatcher { Network::ListenerPtr createListener(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, bool bind_to_port, - bool hand_off_restored_destinations) override { + bool hand_off_restored_destination_connections) override { return Network::ListenerPtr{ - createListener_(socket, cb, bind_to_port, hand_off_restored_destinations)}; + createListener_(socket, cb, bind_to_port, hand_off_restored_destination_connections)}; } TimerPtr createTimer(TimerCb cb) override { return TimerPtr{createTimer_(cb)}; } @@ -87,7 +87,8 @@ class MockDispatcher : public Dispatcher { MOCK_METHOD0(createFilesystemWatcher_, Filesystem::Watcher*()); MOCK_METHOD4(createListener_, Network::Listener*(Network::ListenSocket& socket, Network::ListenerCallbacks& cb, - bool bind_to_port, bool hand_off_restored_destinations)); + bool bind_to_port, + bool hand_off_restored_destination_connections)); MOCK_METHOD1(createTimer_, Timer*(TimerCb cb)); MOCK_METHOD1(deferredDelete_, void(DeferredDeletablePtr& to_delete)); MOCK_METHOD0(exit, void()); diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 417e44615e1fb..e6e178f8919b2 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -286,7 +286,7 @@ class MockListenerConfig : public ListenerConfig { MOCK_METHOD0(socket, ListenSocket&()); MOCK_METHOD0(defaultSslContext, Ssl::ServerContext*()); MOCK_METHOD0(bindToPort, bool()); - MOCK_CONST_METHOD0(handOffRestoredDestinations, bool()); + MOCK_CONST_METHOD0(handOffRestoredDestinationConnections, bool()); MOCK_METHOD0(perConnectionBufferLimitBytes, uint32_t()); MOCK_METHOD0(listenerScope, Stats::Scope&()); MOCK_CONST_METHOD0(listenerTag, uint64_t()); diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index a52271f0ad91a..44710fc8c9bfe 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -29,15 +29,18 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable { public: TestListener(ConnectionHandlerTest& parent, uint64_t tag, bool bind_to_port, - bool hand_off_restored_destinations, const std::string& name) + bool hand_off_restored_destination_connections, const std::string& name) : parent_(parent), tag_(tag), bind_to_port_(bind_to_port), - hand_off_restored_destinations_(hand_off_restored_destinations), name_(name) {} + hand_off_restored_destination_connections_(hand_off_restored_destination_connections), + name_(name) {} Network::FilterChainFactory& filterChainFactory() override { return parent_.factory_; } Network::ListenSocket& socket() override { return socket_; } Ssl::ServerContext* defaultSslContext() override { return nullptr; } bool bindToPort() override { return bind_to_port_; } - bool handOffRestoredDestinations() const override { return hand_off_restored_destinations_; } + bool handOffRestoredDestinationConnections() const override { + return hand_off_restored_destination_connections_; + } uint32_t perConnectionBufferLimitBytes() override { return 0; } Stats::Scope& listenerScope() override { return parent_.stats_store_; } uint64_t listenerTag() const override { return tag_; } @@ -47,16 +50,17 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable TestListenerPtr; - TestListener* addListener(uint64_t tag, bool bind_to_port, bool hand_off_restored_destinations, + TestListener* addListener(uint64_t tag, bool bind_to_port, + bool hand_off_restored_destination_connections, const std::string& name) { TestListener* listener = - new TestListener(*this, tag, bind_to_port, hand_off_restored_destinations, name); + new TestListener(*this, tag, bind_to_port, hand_off_restored_destination_connections, name); listener->moveIntoListBack(TestListenerPtr{listener}, listeners_); return listener; }