LCOV - code coverage report
Current view: top level - envoy/network - listener.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 9 19 47.4 %
Date: 2024-01-05 06:35:25 Functions: 9 12 75.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : #include <memory>
       5             : #include <string>
       6             : 
       7             : #include "envoy/access_log/access_log.h"
       8             : #include "envoy/api/io_error.h"
       9             : #include "envoy/common/exception.h"
      10             : #include "envoy/common/resource.h"
      11             : #include "envoy/config/core/v3/base.pb.h"
      12             : #include "envoy/config/listener/v3/udp_listener_config.pb.h"
      13             : #include "envoy/config/typed_metadata.h"
      14             : #include "envoy/init/manager.h"
      15             : #include "envoy/network/address.h"
      16             : #include "envoy/network/connection.h"
      17             : #include "envoy/network/connection_balancer.h"
      18             : #include "envoy/network/listen_socket.h"
      19             : #include "envoy/network/udp_packet_writer_handler.h"
      20             : #include "envoy/server/overload/load_shed_point.h"
      21             : #include "envoy/stats/scope.h"
      22             : 
      23             : #include "source/common/common/interval_value.h"
      24             : 
      25             : namespace Envoy {
      26             : namespace Network {
      27             : 
      28             : // Set this to the maximum value which effectively accepts all connections.
      29             : constexpr uint32_t DefaultMaxConnectionsToAcceptPerSocketEvent = UINT32_MAX;
      30             : 
      31             : class ActiveUdpListenerFactory;
      32             : class UdpListenerWorkerRouter;
      33             : 
      34             : class ListenSocketFactory;
      35             : using ListenSocketFactoryPtr = std::unique_ptr<ListenSocketFactory>;
      36             : 
      37             : /**
      38             :  * ListenSocketFactory is a member of ListenConfig to provide listen socket.
      39             :  * Listeners created from the same ListenConfig instance have listening sockets
      40             :  * provided by the same ListenSocketFactory instance.
      41             :  */
      42             : class ListenSocketFactory {
      43             : public:
      44         639 :   virtual ~ListenSocketFactory() = default;
      45             : 
      46             :   /**
      47             :    * Called during actual listener creation.
      48             :    * @param worker_index supplies the worker index to get the socket for. All sockets are created
      49             :    *        ahead of time.
      50             :    * @return the socket to be used for a certain listener, which might be shared
      51             :    * with other listeners of the same config on other worker threads.
      52             :    */
      53             :   virtual SocketSharedPtr getListenSocket(uint32_t worker_index) PURE;
      54             : 
      55             :   /**
      56             :    * @return the type of the socket getListenSocket() returns.
      57             :    */
      58             :   virtual Socket::Type socketType() const PURE;
      59             : 
      60             :   /**
      61             :    * @return the listening address of the socket getListenSocket() returns. Before getListenSocket()
      62             :    * is called, the return value might has 0 as port number if the config doesn't specify it.
      63             :    */
      64             :   virtual const Address::InstanceConstSharedPtr& localAddress() const PURE;
      65             : 
      66             :   /**
      67             :    * Clone this socket factory so it can be used by a new listener (e.g., if the address is shared).
      68             :    */
      69             :   virtual ListenSocketFactoryPtr clone() const PURE;
      70             : 
      71             :   /**
      72             :    * Close all sockets. This is used during draining scenarios.
      73             :    */
      74             :   virtual void closeAllSockets() PURE;
      75             : 
      76             :   /**
      77             :    * Perform any initialization that must occur immediately prior to using the listen socket on
      78             :    * workers. For example, the actual listen() call, post listen socket options, etc. This is done
      79             :    * so that all error handling can occur on the main thread and the gap between performing these
      80             :    * actions and using the socket is minimized.
      81             :    */
      82             :   virtual void doFinalPreWorkerInit() PURE;
      83             : };
      84             : 
      85             : /**
      86             :  * Configuration for a UDP listener.
      87             :  */
      88             : class UdpListenerConfig {
      89             : public:
      90         126 :   virtual ~UdpListenerConfig() = default;
      91             : 
      92             :   /**
      93             :    * @return factory for creating a listener.
      94             :    */
      95             :   virtual ActiveUdpListenerFactory& listenerFactory() PURE;
      96             : 
      97             :   /**
      98             :    * @return factory for writing to a UDP socket.
      99             :    */
     100             :   virtual UdpPacketWriterFactory& packetWriterFactory() PURE;
     101             : 
     102             :   /**
     103             :    * @param address is used to query the address specific router.
     104             :    * @return the UdpListenerWorkerRouter for this listener.
     105             :    */
     106             :   virtual UdpListenerWorkerRouter&
     107             :   listenerWorkerRouter(const Network::Address::Instance& address) PURE;
     108             : 
     109             :   /**
     110             :    * @return the configuration for the listener.
     111             :    */
     112             :   virtual const envoy::config::listener::v3::UdpListenerConfig& config() PURE;
     113             : };
     114             : 
     115             : using UdpListenerConfigOptRef = OptRef<UdpListenerConfig>;
     116             : 
     117             : // Forward declare.
     118             : class InternalListenerRegistry;
     119             : 
     120             : /**
     121             :  * Configuration for an internal listener.
     122             :  */
     123             : class InternalListenerConfig {
     124             : public:
     125           0 :   virtual ~InternalListenerConfig() = default;
     126             : 
     127             :   /**
     128             :    * @return InternalListenerRegistry& The internal registry of this internal listener config. The
     129             :    *         registry outlives this listener config.
     130             :    */
     131             :   virtual InternalListenerRegistry& internalListenerRegistry() PURE;
     132             : };
     133             : 
     134             : using InternalListenerConfigOptRef = OptRef<InternalListenerConfig>;
     135             : 
     136             : /**
     137             :  * Description of the listener.
     138             :  */
     139             : class ListenerInfo {
     140             : public:
     141         781 :   virtual ~ListenerInfo() = default;
     142             : 
     143             :   /**
     144             :    * @return const envoy::config::core::v3::Metadata& the config metadata associated with this
     145             :    * listener.
     146             :    */
     147             :   virtual const envoy::config::core::v3::Metadata& metadata() const PURE;
     148             : 
     149             :   /**
     150             :    * @return const Envoy::Config::TypedMetadata& return the typed metadata provided in the config
     151             :    * for this listener.
     152             :    */
     153             :   virtual const Envoy::Config::TypedMetadata& typedMetadata() const PURE;
     154             : 
     155             :   /**
     156             :    * @return envoy::config::core::v3::TrafficDirection the direction of the traffic relative to
     157             :    * the local proxy.
     158             :    */
     159             :   virtual envoy::config::core::v3::TrafficDirection direction() const PURE;
     160             : 
     161             :   /**
     162             :    * @return whether the listener is a Quic listener.
     163             :    */
     164             :   virtual bool isQuic() const PURE;
     165             : };
     166             : 
     167             : using ListenerInfoConstSharedPtr = std::shared_ptr<const ListenerInfo>;
     168             : 
     169             : /**
     170             :  * A configuration for an individual listener.
     171             :  */
     172             : class ListenerConfig {
     173             : public:
     174         651 :   virtual ~ListenerConfig() = default;
     175             : 
     176             :   /**
     177             :    * @return FilterChainManager& the factory for adding and searching through configured
     178             :    *         filter chains.
     179             :    */
     180             :   virtual FilterChainManager& filterChainManager() PURE;
     181             : 
     182             :   /**
     183             :    * @return FilterChainFactory& the factory for setting up the filter chain on a new
     184             :    *         connection.
     185             :    */
     186             :   virtual FilterChainFactory& filterChainFactory() PURE;
     187             : 
     188             :   /**
     189             :    * @return std::vector<ListenSocketFactoryPtr>& the factories to create listen sockets.
     190             :    */
     191             :   virtual std::vector<ListenSocketFactoryPtr>& listenSocketFactories() PURE;
     192             : 
     193             :   /**
     194             :    * @return bool specifies whether the listener should actually listen on the port.
     195             :    *         A listener that doesn't listen on a port can only receive connections
     196             :    *         redirected from other listeners.
     197             :    */
     198             :   virtual bool bindToPort() const PURE;
     199             : 
     200             :   /**
     201             :    * @return bool if a connection should be handed off to another Listener after the original
     202             :    *         destination address has been restored. 'true' when 'use_original_dst' flag in listener
     203             :    *         configuration is set, false otherwise.
     204             :    */
     205             :   virtual bool handOffRestoredDestinationConnections() const PURE;
     206             : 
     207             :   /**
     208             :    * @return uint32_t providing a soft limit on size of the listener's new connection read and
     209             :    * write buffers.
     210             :    */
     211             :   virtual uint32_t perConnectionBufferLimitBytes() const PURE;
     212             : 
     213             :   /**
     214             :    * @return std::chrono::milliseconds the time to wait for all listener filters to complete
     215             :    *         operation. If the timeout is reached, the accepted socket is closed without a
     216             :    *         connection being created unless continueOnListenerFiltersTimeout() returns true.
     217             :    *         0 specifies a disabled timeout.
     218             :    */
     219             :   virtual std::chrono::milliseconds listenerFiltersTimeout() const PURE;
     220             : 
     221             :   /**
     222             :    * @return bool whether the listener should try to create a connection when listener filters
     223             :    *         time out.
     224             :    */
     225             :   virtual bool continueOnListenerFiltersTimeout() const PURE;
     226             : 
     227             :   /**
     228             :    * @return Stats::Scope& the stats scope to use for all listener specific stats.
     229             :    */
     230             :   virtual Stats::Scope& listenerScope() PURE;
     231             : 
     232             :   /**
     233             :    * @return uint64_t the tag the listener should use for connection handler tracking.
     234             :    */
     235             :   virtual uint64_t listenerTag() const PURE;
     236             : 
     237             :   /**
     238             :    * @return const std::string& the listener's name.
     239             :    */
     240             :   virtual const std::string& name() const PURE;
     241             : 
     242             :   /**
     243             :    * @return ListenerInfoConstSharedPtr& description of the listener.
     244             :    */
     245             :   virtual const ListenerInfoConstSharedPtr& listenerInfo() const PURE;
     246             : 
     247             :   /**
     248             :    * @return the UDP configuration for the listener IFF it is a UDP listener.
     249             :    */
     250             :   virtual UdpListenerConfigOptRef udpListenerConfig() PURE;
     251             : 
     252             :   /**
     253             :    * @return the internal configuration for the listener IFF it is an internal listener.
     254             :    */
     255             :   virtual InternalListenerConfigOptRef internalListenerConfig() PURE;
     256             : 
     257             :   /**
     258             :    * @param address is used for query the address specific connection balancer.
     259             :    * @return the connection balancer for this listener. All listeners have a connection balancer,
     260             :    *         though the implementation may be a NOP balancer.
     261             :    */
     262             :   virtual ConnectionBalancer& connectionBalancer(const Network::Address::Instance& address) PURE;
     263             : 
     264             :   /**
     265             :    * Open connection resources for this listener.
     266             :    */
     267             :   virtual ResourceLimit& openConnections() PURE;
     268             : 
     269             :   /**
     270             :    * @return std::vector<AccessLog::InstanceSharedPtr> access logs emitted by the listener.
     271             :    */
     272             :   virtual const std::vector<AccessLog::InstanceSharedPtr>& accessLogs() const PURE;
     273             : 
     274             :   /**
     275             :    * @return pending connection backlog for TCP listeners.
     276             :    */
     277             :   virtual uint32_t tcpBacklogSize() const PURE;
     278             : 
     279             :   /**
     280             :    * @return the maximum number of connections that will be accepted for a given socket event.
     281             :    */
     282             :   virtual uint32_t maxConnectionsToAcceptPerSocketEvent() const PURE;
     283             : 
     284             :   /**
     285             :    * @return init manager of the listener.
     286             :    */
     287             :   virtual Init::Manager& initManager() PURE;
     288             : 
     289             :   /**
     290             :    * @return bool whether the listener should avoid blocking connections based on the globally set
     291             :    * limit.
     292             :    */
     293             :   virtual bool ignoreGlobalConnLimit() const PURE;
     294             : };
     295             : 
     296             : /**
     297             :  * Callbacks invoked by a listener.
     298             :  */
     299             : class TcpListenerCallbacks {
     300             : public:
     301         607 :   virtual ~TcpListenerCallbacks() = default;
     302             : 
     303             :   /**
     304             :    * Called when a new connection is accepted.
     305             :    * @param socket supplies the socket that is moved into the callee.
     306             :    */
     307             :   virtual void onAccept(ConnectionSocketPtr&& socket) PURE;
     308             : 
     309             :   enum class RejectCause {
     310             :     GlobalCxLimit,
     311             :     OverloadAction,
     312             :   };
     313             :   /**
     314             :    * Called when a new connection is rejected.
     315             :    */
     316             :   virtual void onReject(RejectCause cause) PURE;
     317             : 
     318             :   /**
     319             :    * Called when the listener has finished accepting connections per socket
     320             :    * event.
     321             :    * @param connections_accepted number of connections accepted.
     322             :    */
     323             :   virtual void recordConnectionsAcceptedOnSocketEvent(uint32_t connections_accepted) PURE;
     324             : };
     325             : 
     326             : /**
     327             :  * Utility struct that encapsulates the information from a udp socket's recvmmsg call.
     328             :  */
     329             : struct UdpRecvData {
     330             :   struct LocalPeerAddresses {
     331           0 :     bool operator==(const LocalPeerAddresses& rhs) const {
     332           0 :       // TODO(mattklein123): Implement a hash directly on Address that does not use strings.
     333           0 :       return local_->asStringView() == rhs.local_->asStringView() &&
     334           0 :              peer_->asStringView() == rhs.peer_->asStringView();
     335           0 :     }
     336             : 
     337           0 :     template <typename H> friend H AbslHashValue(H h, const LocalPeerAddresses& addresses) {
     338             :       // TODO(mattklein123): Implement a hash directly on Address that does not use strings.
     339           0 :       return H::combine(std::move(h), addresses.local_->asStringView(),
     340           0 :                         addresses.peer_->asStringView());
     341           0 :     }
     342             : 
     343             :     Address::InstanceConstSharedPtr local_;
     344             :     Address::InstanceConstSharedPtr peer_;
     345             :   };
     346             : 
     347             :   LocalPeerAddresses addresses_;
     348             :   Buffer::InstancePtr buffer_;
     349             :   MonotonicTime receive_time_;
     350             : };
     351             : 
     352             : /**
     353             :  * Encapsulates the information needed to send a udp packet to a target
     354             :  */
     355             : struct UdpSendData {
     356             :   const Address::Ip* local_ip_;
     357             :   const Address::Instance& peer_address_;
     358             : 
     359             :   // The buffer is a reference so that it can be reused by the sender to send different
     360             :   // messages
     361             :   Buffer::Instance& buffer_;
     362             : };
     363             : 
     364             : /**
     365             :  * UDP listener callbacks.
     366             :  */
     367             : class UdpListenerCallbacks {
     368             : public:
     369          91 :   virtual ~UdpListenerCallbacks() = default;
     370             : 
     371             :   /**
     372             :    * Called whenever data is received by the underlying udp socket.
     373             :    * TODO(danzh2010): Consider returning a value to indicate if more work is to
     374             :    * be done in the next event loop due to a limit on how much processing is
     375             :    * allowed in each event loop.
     376             :    *
     377             :    * @param data UdpRecvData from the underlying socket.
     378             :    */
     379             :   virtual void onData(UdpRecvData&& data) PURE;
     380             : 
     381             :   /**
     382             :    * Called whenever datagrams are dropped due to overflow or truncation.
     383             :    * @param dropped supplies the number of dropped datagrams.
     384             :    */
     385             :   virtual void onDatagramsDropped(uint32_t dropped) PURE;
     386             : 
     387             :   /**
     388             :    * Called when the underlying socket is ready for read, before onData() is
     389             :    * called. Called only once per event loop, even if followed by multiple
     390             :    * onData() calls.
     391             :    *
     392             :    */
     393             :   virtual void onReadReady() PURE;
     394             : 
     395             :   /**
     396             :    * Called when the underlying socket is ready for write.
     397             :    *
     398             :    * @param socket Underlying server socket for the listener.
     399             :    *
     400             :    * TODO(conqerAtapple): Maybe we need a UdpWriter here instead of Socket.
     401             :    */
     402             :   virtual void onWriteReady(const Socket& socket) PURE;
     403             : 
     404             :   /**
     405             :    * Called when there is an error event in the receive data path.
     406             :    * The send side error is a return type on the send method.
     407             :    *
     408             :    * @param error_code supplies the received error on the listener.
     409             :    */
     410             :   virtual void onReceiveError(Api::IoError::IoErrorCode error_code) PURE;
     411             : 
     412             :   /**
     413             :    * Returns the pointer to the udp_packet_writer associated with the
     414             :    * UdpListenerCallback
     415             :    */
     416             :   virtual UdpPacketWriter& udpPacketWriter() PURE;
     417             : 
     418             :   /**
     419             :    * Returns the index of this worker, in the range of [0, concurrency).
     420             :    */
     421             :   virtual uint32_t workerIndex() const PURE;
     422             : 
     423             :   /**
     424             :    * Called whenever data is received on the underlying udp socket, on
     425             :    * the destination worker for the datagram according to ``destination()``.
     426             :    */
     427             :   virtual void onDataWorker(Network::UdpRecvData&& data) PURE;
     428             : 
     429             :   /**
     430             :    * Posts ``data`` to be delivered on this worker.
     431             :    */
     432             :   virtual void post(Network::UdpRecvData&& data) PURE;
     433             : 
     434             :   /**
     435             :    * An estimated number of UDP packets this callback expects to process in current read event.
     436             :    */
     437             :   virtual size_t numPacketsExpectedPerEventLoop() const PURE;
     438             : };
     439             : 
     440             : using UdpListenerCallbacksOptRef = absl::optional<std::reference_wrapper<UdpListenerCallbacks>>;
     441             : 
     442             : /**
     443             :  * An abstract socket listener. Free the listener to stop listening on the socket.
     444             :  */
     445             : class Listener {
     446             : public:
     447         698 :   virtual ~Listener() = default;
     448             : 
     449             :   /**
     450             :    * Temporarily disable accepting new connections.
     451             :    */
     452             :   virtual void disable() PURE;
     453             : 
     454             :   /**
     455             :    * Enable accepting new connections.
     456             :    */
     457             :   virtual void enable() PURE;
     458             : 
     459             :   /**
     460             :    * Set the fraction of incoming connections that will be closed immediately
     461             :    * after being opened.
     462             :    */
     463             :   virtual void setRejectFraction(UnitFloat reject_fraction) PURE;
     464             : 
     465             :   /**
     466             :    * Configures the LoadShedPoints for this listener.
     467             :    */
     468             :   virtual void
     469             :   configureLoadShedPoints(Server::LoadShedPointProvider& load_shed_point_provider) PURE;
     470             : };
     471             : 
     472             : using ListenerPtr = std::unique_ptr<Listener>;
     473             : 
     474             : /**
     475             :  * A UDP listener interface.
     476             :  */
     477             : class UdpListener : public virtual Listener {
     478             : public:
     479          91 :   ~UdpListener() override = default;
     480             : 
     481             :   /**
     482             :    * @return Event::Dispatcher& the dispatcher backing this listener.
     483             :    */
     484             :   virtual Event::Dispatcher& dispatcher() PURE;
     485             : 
     486             :   /**
     487             :    * @return the local address of the socket.
     488             :    */
     489             :   virtual const Network::Address::InstanceConstSharedPtr& localAddress() const PURE;
     490             : 
     491             :   /**
     492             :    * Send data through the underlying udp socket. If the send buffer of the socket FD is full, an
     493             :    * error code is returned.
     494             :    * TODO(sumukhs): We do not currently handle max MTU size of the datagram. Determine if we could
     495             :    * expose the path MTU information to the caller.
     496             :    *
     497             :    * @param data Supplies the data to send to a target using udp.
     498             :    * @return the error code of the underlying send api. On successfully sending 'n' bytes, the
     499             :    * underlying buffers in the data  are drained by 'n' bytes. The remaining can be retried by the
     500             :    * sender.
     501             :    */
     502             :   virtual Api::IoCallUint64Result send(const UdpSendData& data) PURE;
     503             : 
     504             :   /**
     505             :    * Flushes out remaining buffered data since last call of send().
     506             :    * This is a no-op if the implementation doesn't buffer data while sending.
     507             :    *
     508             :    * @return the error code of the underlying flush api.
     509             :    */
     510             :   virtual Api::IoCallUint64Result flush() PURE;
     511             : 
     512             :   /**
     513             :    * Make this listener readable at the beginning of the next event loop.
     514             :    */
     515             :   virtual void activateRead() PURE;
     516             : };
     517             : 
     518             : using UdpListenerPtr = std::unique_ptr<UdpListener>;
     519             : 
     520             : /**
     521             :  * Handles delivering datagrams to the correct worker.
     522             :  */
     523             : class UdpListenerWorkerRouter {
     524             : public:
     525         126 :   virtual ~UdpListenerWorkerRouter() = default;
     526             : 
     527             :   /**
     528             :    * Registers a worker's callbacks for this listener. This worker must accept
     529             :    * packets until it calls ``unregisterWorker``.
     530             :    */
     531             :   virtual void registerWorkerForListener(UdpListenerCallbacks& listener) PURE;
     532             : 
     533             :   /**
     534             :    * Unregisters a worker's callbacks for this listener.
     535             :    */
     536             :   virtual void unregisterWorkerForListener(UdpListenerCallbacks& listener) PURE;
     537             : 
     538             :   /**
     539             :    * Deliver ``data`` to the correct worker by calling ``onDataWorker()``
     540             :    * or ``post()`` on one of the registered workers.
     541             :    */
     542             :   virtual void deliver(uint32_t dest_worker_index, UdpRecvData&& data) PURE;
     543             : };
     544             : 
     545             : using UdpListenerWorkerRouterPtr = std::unique_ptr<UdpListenerWorkerRouter>;
     546             : 
     547             : /**
     548             :  * Base class for all listener typed metadata factories.
     549             :  */
     550             : class ListenerTypedMetadataFactory : public Envoy::Config::TypedMetadataFactory {};
     551             : 
     552             : } // namespace Network
     553             : } // namespace Envoy

Generated by: LCOV version 1.15