LCOV - code coverage report
Current view: top level - source/common/network - multi_connection_base_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 12 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <atomic>
       4             : #include <cstdint>
       5             : #include <list>
       6             : #include <memory>
       7             : #include <string>
       8             : 
       9             : #include "envoy/common/scope_tracker.h"
      10             : #include "envoy/network/connection.h"
      11             : #include "envoy/network/transport_socket.h"
      12             : 
      13             : #include "source/common/network/connection_impl.h"
      14             : 
      15             : #include "absl/types/optional.h"
      16             : 
      17             : namespace Envoy {
      18             : namespace Network {
      19             : 
      20             : /**
      21             :  * An abstract class for providing next ClientConnectionPtr that can should used by
      22             :  * the HappyEyeballsConnectionImpl. Classes can inherit this class to provide
      23             :  * different kinds of connection creation strategies.
      24             :  */
      25             : class ConnectionProvider {
      26             : public:
      27           0 :   virtual ~ConnectionProvider() = default;
      28             : 
      29             :   /**
      30             :    * Whether there's still next connection to try.
      31             :    */
      32             :   virtual bool hasNextConnection() PURE;
      33             : 
      34             :   /**
      35             :    * Create next client connection.
      36             :    */
      37             :   virtual ClientConnectionPtr createNextConnection(const uint64_t id) PURE;
      38             : 
      39             :   /**
      40             :    * Return the index for the next connection.
      41             :    *
      42             :    */
      43             :   virtual size_t nextConnection() PURE;
      44             : 
      45             :   /**
      46             :    * Return the total count of connections the connection provider will make.
      47             :    *
      48             :    */
      49             :   virtual size_t totalConnections() PURE;
      50             : };
      51             : 
      52             : using ConnectionProviderPtr = std::unique_ptr<ConnectionProvider>;
      53             : 
      54             : /**
      55             :  * Implementation of ClientConnection which transparently attempts connections
      56             :  * provided by a ConnectionProvider, and uses the first connection that succeeds.
      57             :  * After a connection is established, all methods simply delegate to the
      58             :  * underlying connection. However, before the connection is established
      59             :  * their behavior depends on their semantics. For anything which can result
      60             :  * in up-call (e.g. filter registration) or which must only happen once (e.g.
      61             :  * writing data) the context is saved in until the connection completes, at
      62             :  * which point they are replayed to the underlying connection. For simple methods
      63             :  * they are applied to each open connection and applied when creating new ones.
      64             :  *
      65             :  * This is originally a part of the `HapppyEyeballsConnectionImpl` but split for
      66             :  * broader use cases.
      67             :  */
      68             : class MultiConnectionBaseImpl : public ClientConnection,
      69             :                                 Logger::Loggable<Logger::Id::multi_connection> {
      70             : public:
      71             :   MultiConnectionBaseImpl(Event::Dispatcher& dispatcher, ConnectionProviderPtr connection_provider);
      72             : 
      73             :   ~MultiConnectionBaseImpl() override;
      74             : 
      75             :   // Network::ClientConnection
      76             :   void connect() override;
      77             : 
      78             :   // Methods which defer action until the final connection has been determined.
      79             :   void addWriteFilter(WriteFilterSharedPtr filter) override;
      80             :   void addFilter(FilterSharedPtr filter) override;
      81             :   void addReadFilter(ReadFilterSharedPtr filter) override;
      82             :   void removeReadFilter(ReadFilterSharedPtr filter) override;
      83             :   bool initializeReadFilters() override;
      84             :   void addBytesSentCallback(BytesSentCb cb) override;
      85             :   void write(Buffer::Instance& data, bool end_stream) override;
      86             :   void addConnectionCallbacks(ConnectionCallbacks& cb) override;
      87             :   void removeConnectionCallbacks(ConnectionCallbacks& cb) override;
      88             : 
      89             :   // Methods which are applied to each connection attempt.
      90             :   void enableHalfClose(bool enabled) override;
      91             :   void noDelay(bool enable) override;
      92             :   ReadDisableStatus readDisable(bool disable) override;
      93             :   void detectEarlyCloseWhenReadDisabled(bool value) override;
      94             :   void setConnectionStats(const ConnectionStats& stats) override;
      95             :   void setDelayedCloseTimeout(std::chrono::milliseconds timeout) override;
      96             :   void setBufferLimits(uint32_t limit) override;
      97             :   bool startSecureTransport() override;
      98             :   absl::optional<std::chrono::milliseconds> lastRoundTripTime() const override;
      99           0 :   void configureInitialCongestionWindow(uint64_t, std::chrono::microseconds) override {}
     100             :   absl::optional<uint64_t> congestionWindowInBytes() const override;
     101             : 
     102             :   // Simple getters which always delegate to the first connection in connections_.
     103             :   bool isHalfCloseEnabled() const override;
     104             :   std::string nextProtocol() const override;
     105             :   // Note, this might change before connect finishes.
     106             :   ConnectionInfoSetter& connectionInfoSetter() override;
     107             :   // Note, this might change before connect finishes.
     108             :   const ConnectionInfoProvider& connectionInfoProvider() const override;
     109             :   // Note, this might change before connect finishes.
     110             :   ConnectionInfoProviderSharedPtr connectionInfoProviderSharedPtr() const override;
     111             :   // Note, this might change before connect finishes.
     112             :   absl::optional<UnixDomainSocketPeerCredentials> unixSocketPeerCredentials() const override;
     113             :   // Note, this might change before connect finishes.
     114             :   Ssl::ConnectionInfoConstSharedPtr ssl() const override;
     115             :   State state() const override;
     116             :   bool connecting() const override;
     117             :   uint32_t bufferLimit() const override;
     118             :   const ConnectionSocket::OptionsSharedPtr& socketOptions() const override;
     119             :   absl::string_view requestedServerName() const override;
     120             :   StreamInfo::StreamInfo& streamInfo() override;
     121             :   const StreamInfo::StreamInfo& streamInfo() const override;
     122             :   absl::string_view transportFailureReason() const override;
     123             :   absl::string_view localCloseReason() const override;
     124             : 
     125             :   // Methods implemented largely by this class itself.
     126             :   uint64_t id() const override;
     127             :   Event::Dispatcher& dispatcher() const override;
     128           0 :   void close(ConnectionCloseType type) override { close(type, ""); }
     129             :   void close(ConnectionCloseType type, absl::string_view details) override;
     130             :   DetectedCloseType detectedCloseType() const override;
     131             :   bool readEnabled() const override;
     132             :   bool aboveHighWatermark() const override;
     133             :   void hashKey(std::vector<uint8_t>& hash_key) const override;
     134             :   void dumpState(std::ostream& os, int indent_level) const override;
     135             : 
     136             : private:
     137             :   // ConnectionCallbacks which will be set on an ClientConnection which
     138             :   // sends connection events back to the MultiConnectionBaseImpl.
     139             :   class ConnectionCallbacksWrapper : public ConnectionCallbacks {
     140             :   public:
     141             :     ConnectionCallbacksWrapper(MultiConnectionBaseImpl& parent, ClientConnection& connection)
     142           0 :         : parent_(parent), connection_(connection) {}
     143             : 
     144           0 :     void onEvent(ConnectionEvent event) override { parent_.onEvent(event, this); }
     145             : 
     146           0 :     void onAboveWriteBufferHighWatermark() override {
     147             :       // No data will be written to the connection while the wrapper is associated with it,
     148             :       // so the write buffer should never hit the high watermark.
     149           0 :       IS_ENVOY_BUG("Unexpected data written to MultiConnectionBaseImpl");
     150           0 :     }
     151             : 
     152           0 :     void onBelowWriteBufferLowWatermark() override {
     153             :       // No data will be written to the connection while the wrapper is associated with it,
     154             :       // so the write buffer should never hit the high watermark.
     155           0 :       IS_ENVOY_BUG("Unexpected data drained from MultiConnectionBaseImpl");
     156           0 :     }
     157             : 
     158           0 :     ClientConnection& connection() { return connection_; }
     159             : 
     160             :   private:
     161             :     MultiConnectionBaseImpl& parent_;
     162             :     ClientConnection& connection_;
     163             :   };
     164             : 
     165             :   // Creates a connection to the next address in address_list_ and applies
     166             :   // any settings from per_connection_state_ to the newly created connection.
     167             :   ClientConnectionPtr createNextConnection();
     168             : 
     169             :   // Create a new connection, connects it and scheduled a timer to start another
     170             :   // connection attempt if there are more addresses to connect to.
     171             :   void tryAnotherConnection();
     172             : 
     173             :   // Schedules another connection attempt if there are mode address to connect to.
     174             :   void maybeScheduleNextAttempt();
     175             : 
     176             :   // Called by the wrapper when the wrapped connection raises the specified event.
     177             :   void onEvent(ConnectionEvent event, ConnectionCallbacksWrapper* wrapper);
     178             : 
     179             :   // Called to bind the final connection. All other connections will be closed, and
     180             :   // and deferred operations will be replayed.
     181             :   void setUpFinalConnection(ConnectionEvent event, ConnectionCallbacksWrapper* wrapper);
     182             : 
     183             :   // Called by the write buffer containing pending writes if it goes below the
     184             :   // low water mark.
     185             :   void onWriteBufferLowWatermark();
     186             : 
     187             :   // Called by the write buffer containing pending writes if it goes above the
     188             :   // high water mark.
     189             :   void onWriteBufferHighWatermark();
     190             : 
     191             :   // Cleans up all state for the connection associated with wrapper. Called when the
     192             :   // connection is no longer needed.
     193             :   void cleanupWrapperAndConnection(ConnectionCallbacksWrapper* wrapper);
     194             : 
     195             :   // State which needs to be applied to every connection attempt.
     196             :   struct PerConnectionState {
     197             :     absl::optional<bool> detect_early_close_when_read_disabled_;
     198             :     absl::optional<bool> no_delay_;
     199             :     absl::optional<bool> enable_half_close_;
     200             :     std::unique_ptr<ConnectionStats> connection_stats_;
     201             :     absl::optional<uint32_t> buffer_limits_;
     202             :     absl::optional<bool> start_secure_transport_;
     203             :     absl::optional<std::chrono::milliseconds> delayed_close_timeout_;
     204             :   };
     205             : 
     206             :   // State which needs to be saved and applied only to the final connection
     207             :   // attempt.
     208             :   struct PostConnectState {
     209             :     std::vector<ConnectionCallbacks*> connection_callbacks_;
     210             :     std::vector<Connection::BytesSentCb> bytes_sent_callbacks_;
     211             :     std::vector<ReadFilterSharedPtr> read_filters_;
     212             :     std::vector<WriteFilterSharedPtr> write_filters_;
     213             :     std::vector<FilterSharedPtr> filters_;
     214             :     absl::optional<Buffer::InstancePtr> write_buffer_;
     215             :     absl::optional<int> read_disable_count_;
     216             :     absl::optional<bool> end_stream_;
     217             :     absl::optional<bool> initialize_read_filters_;
     218             :   };
     219             : 
     220             :   // State which is needed to construct a new connection.
     221             :   struct ConnectionConstructionState {
     222             :     Address::InstanceConstSharedPtr source_address_;
     223             :     UpstreamTransportSocketFactory& socket_factory_;
     224             :     TransportSocketOptionsConstSharedPtr transport_socket_options_;
     225             :     const ConnectionSocket::OptionsSharedPtr options_;
     226             :   };
     227             : 
     228             :   // ID for this connection which is distinct from the ID of the underlying connections.
     229             :   const uint64_t id_;
     230             : 
     231             :   Event::Dispatcher& dispatcher_;
     232             : 
     233             :   ConnectionProviderPtr connection_provider_;
     234             : 
     235             :   PerConnectionState per_connection_state_;
     236             :   PostConnectState post_connect_state_;
     237             : 
     238             :   // Set of active connections.
     239             :   std::vector<ClientConnectionPtr> connections_;
     240             :   std::vector<std::unique_ptr<ConnectionCallbacksWrapper>> callbacks_wrappers_;
     241             : 
     242             :   // True when connect() has finished, either success or failure.
     243             :   bool connect_finished_ = false;
     244             :   Event::TimerPtr next_attempt_timer_;
     245             : };
     246             : 
     247             : } // namespace Network
     248             : } // namespace Envoy

Generated by: LCOV version 1.15