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

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "source/common/http/conn_pool_base.h"
       4             : #include "source/common/http/http3/conn_pool.h"
       5             : #include "source/common/http/http_server_properties_cache_impl.h"
       6             : #include "source/common/quic/quic_stat_names.h"
       7             : 
       8             : #include "absl/container/flat_hash_map.h"
       9             : 
      10             : namespace Envoy {
      11             : namespace Http {
      12             : 
      13             : // An HTTP connection pool which will handle the connectivity grid of
      14             : // [WiFi / cellular] [ipv4 / ipv6] [QUIC / TCP].
      15             : // Currently only [QUIC / TCP are handled]
      16             : class ConnectivityGrid : public ConnectionPool::Instance,
      17             :                          public Http3::PoolConnectResultCallback,
      18             :                          protected Logger::Loggable<Logger::Id::pool> {
      19             : public:
      20             :   struct ConnectivityOptions {
      21             :     explicit ConnectivityOptions(const std::vector<Http::Protocol>& protocols)
      22           0 :         : protocols_(protocols) {}
      23             :     std::vector<Http::Protocol> protocols_;
      24             :   };
      25             : 
      26             :   enum class StreamCreationResult {
      27             :     ImmediateResult,
      28             :     StreamCreationPending,
      29             :   };
      30             : 
      31             :   using PoolIterator = std::list<ConnectionPool::InstancePtr>::iterator;
      32             : 
      33             :   // This is a class which wraps a caller's connection pool callbacks to
      34             :   // auto-retry pools in the case of connection failure.
      35             :   //
      36             :   // It also relays cancellation calls between the original caller and the
      37             :   // current connection attempts.
      38             :   class WrapperCallbacks : public ConnectionPool::Cancellable,
      39             :                            public LinkedObject<WrapperCallbacks> {
      40             :   public:
      41             :     WrapperCallbacks(ConnectivityGrid& grid, Http::ResponseDecoder& decoder, PoolIterator pool_it,
      42             :                      ConnectionPool::Callbacks& callbacks, const Instance::StreamOptions& options);
      43             : 
      44             :     // This holds state for a single connection attempt to a specific pool.
      45             :     class ConnectionAttemptCallbacks : public ConnectionPool::Callbacks,
      46             :                                        public LinkedObject<ConnectionAttemptCallbacks> {
      47             :     public:
      48             :       ConnectionAttemptCallbacks(WrapperCallbacks& parent, PoolIterator it);
      49             :       ~ConnectionAttemptCallbacks() override;
      50             : 
      51             :       StreamCreationResult newStream();
      52             : 
      53             :       // ConnectionPool::Callbacks
      54             :       void onPoolFailure(ConnectionPool::PoolFailureReason reason,
      55             :                          absl::string_view transport_failure_reason,
      56             :                          Upstream::HostDescriptionConstSharedPtr host) override;
      57             :       void onPoolReady(RequestEncoder& encoder, Upstream::HostDescriptionConstSharedPtr host,
      58             :                        StreamInfo::StreamInfo& info,
      59             :                        absl::optional<Http::Protocol> protocol) override;
      60             : 
      61           0 :       ConnectionPool::Instance& pool() { return **pool_it_; }
      62             : 
      63             :       void cancel(Envoy::ConnectionPool::CancelPolicy cancel_policy);
      64             : 
      65             :     private:
      66             :       // A pointer back up to the parent.
      67             :       WrapperCallbacks& parent_;
      68             :       // The pool for this connection attempt.
      69             :       const PoolIterator pool_it_;
      70             :       // The handle to cancel this connection attempt.
      71             :       // This is owned by the pool which created it.
      72             :       Cancellable* cancellable_{nullptr};
      73             :     };
      74             :     using ConnectionAttemptCallbacksPtr = std::unique_ptr<ConnectionAttemptCallbacks>;
      75             : 
      76             :     // ConnectionPool::Cancellable
      77             :     void cancel(Envoy::ConnectionPool::CancelPolicy cancel_policy) override;
      78             : 
      79             :     // Attempt to create a new stream for pool().
      80             :     StreamCreationResult newStream();
      81             : 
      82             :     // Called on pool failure or timeout to kick off another connection attempt.
      83             :     // Returns true if there is a failover pool and a connection has been
      84             :     // attempted, false if all pools have been tried.
      85             :     bool tryAnotherConnection();
      86             : 
      87             :     // Called by a ConnectionAttempt when the underlying pool fails.
      88             :     void onConnectionAttemptFailed(ConnectionAttemptCallbacks* attempt,
      89             :                                    ConnectionPool::PoolFailureReason reason,
      90             :                                    absl::string_view transport_failure_reason,
      91             :                                    Upstream::HostDescriptionConstSharedPtr host);
      92             : 
      93             :     // Called by a ConnectionAttempt when the underlying pool is ready.
      94             :     void onConnectionAttemptReady(ConnectionAttemptCallbacks* attempt, RequestEncoder& encoder,
      95             :                                   Upstream::HostDescriptionConstSharedPtr host,
      96             :                                   StreamInfo::StreamInfo& info,
      97             :                                   absl::optional<Http::Protocol> protocol);
      98             : 
      99             :   private:
     100             :     // Removes this from the owning list, deleting it.
     101             :     void deleteThis();
     102             : 
     103             :     // Marks HTTP/3 broken if the HTTP/3 attempt failed but a TCP attempt succeeded.
     104             :     // While HTTP/3 is broken the grid will not attempt to make new HTTP/3 connections.
     105             :     void maybeMarkHttp3Broken();
     106             : 
     107             :     // Cancels any pending attempts and deletes them.
     108             :     void cancelAllPendingAttempts(Envoy::ConnectionPool::CancelPolicy cancel_policy);
     109             : 
     110             :     // Tracks all the connection attempts which currently in flight.
     111             :     std::list<ConnectionAttemptCallbacksPtr> connection_attempts_;
     112             : 
     113             :     // The owning grid.
     114             :     ConnectivityGrid& grid_;
     115             :     // The decoder for the original newStream, needed to create streams on subsequent pools.
     116             :     Http::ResponseDecoder& decoder_;
     117             :     // The callbacks from the original caller, which must get onPoolFailure or
     118             :     // onPoolReady unless there is call to cancel(). Will be nullptr if the caller
     119             :     // has been notified while attempts are still pending.
     120             :     ConnectionPool::Callbacks* inner_callbacks_;
     121             :     // The timer which tracks when new connections should be attempted.
     122             :     Event::TimerPtr next_attempt_timer_;
     123             :     // The iterator to the last pool which had a connection attempt.
     124             :     PoolIterator current_;
     125             :     // True if the HTTP/3 attempt failed.
     126             :     bool http3_attempt_failed_{};
     127             :     // True if the TCP attempt succeeded.
     128             :     bool tcp_attempt_succeeded_{};
     129             :     // Latch the passed-in stream options.
     130             :     const Instance::StreamOptions stream_options_{};
     131             :   };
     132             :   using WrapperCallbacksPtr = std::unique_ptr<WrapperCallbacks>;
     133             : 
     134             :   ConnectivityGrid(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator,
     135             :                    Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority,
     136             :                    const Network::ConnectionSocket::OptionsSharedPtr& options,
     137             :                    const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
     138             :                    Upstream::ClusterConnectivityState& state, TimeSource& time_source,
     139             :                    HttpServerPropertiesCacheSharedPtr alternate_protocols,
     140             :                    ConnectivityOptions connectivity_options, Quic::QuicStatNames& quic_stat_names,
     141             :                    Stats::Scope& scope, Http::PersistentQuicInfo& quic_info);
     142             :   ~ConnectivityGrid() override;
     143             : 
     144             :   // Event::DeferredDeletable
     145             :   void deleteIsPending() override;
     146             : 
     147             :   // Http::ConnPool::Instance
     148             :   bool hasActiveConnections() const override;
     149             :   ConnectionPool::Cancellable* newStream(Http::ResponseDecoder& response_decoder,
     150             :                                          ConnectionPool::Callbacks& callbacks,
     151             :                                          const Instance::StreamOptions& options) override;
     152             :   void addIdleCallback(IdleCb cb) override;
     153             :   bool isIdle() const override;
     154             :   void drainConnections(Envoy::ConnectionPool::DrainBehavior drain_behavior) override;
     155             :   Upstream::HostDescriptionConstSharedPtr host() const override;
     156             :   bool maybePreconnect(float preconnect_ratio) override;
     157           0 :   absl::string_view protocolDescription() const override { return "connection grid"; }
     158             : 
     159             :   // Returns the next pool in the ordered priority list.
     160             :   absl::optional<PoolIterator> nextPool(PoolIterator pool_it);
     161             : 
     162             :   // Returns true if pool is the grid's HTTP/3 connection pool.
     163             :   bool isPoolHttp3(const ConnectionPool::Instance& pool);
     164             : 
     165             :   // Returns true if HTTP/3 is currently broken. While HTTP/3 is broken the grid will not
     166             :   // attempt to make new HTTP/3 connections.
     167             :   bool isHttp3Broken() const;
     168             : 
     169             :   // Marks HTTP/3 broken for a period of time subject to exponential backoff. While HTTP/3
     170             :   // is broken the grid will not attempt to make new HTTP/3 connections.
     171             :   void markHttp3Broken();
     172             : 
     173             :   // Marks that HTTP/3 is working, which resets the exponential backoff counter in the
     174             :   // event that HTTP/3 is marked broken again.
     175             :   void markHttp3Confirmed();
     176             : 
     177             :   // Http3::PoolConnectResultCallback
     178             :   void onHandshakeComplete() override;
     179             :   void onZeroRttHandshakeFailed() override;
     180             : 
     181             : protected:
     182             :   // Set the required idle callback on the pool.
     183             :   void setupPool(ConnectionPool::Instance& pool);
     184             : 
     185             : private:
     186             :   friend class ConnectivityGridForTest;
     187             : 
     188             :   // Return origin of the remote host. If the host doesn't have an IP address,
     189             :   // the port of the origin will be 0.
     190             :   HttpServerPropertiesCache::Http3StatusTracker& getHttp3StatusTracker() const;
     191             : 
     192             :   // Called by each pool as it idles. The grid is responsible for calling
     193             :   // idle_callbacks_ once all pools have idled.
     194             :   void onIdleReceived();
     195             : 
     196             :   // Returns true if HTTP/3 should be attempted because there is an alternate protocol
     197             :   // that specifies HTTP/3 and HTTP/3 is not broken.
     198             :   bool shouldAttemptHttp3();
     199             : 
     200             :   // Creates the next pool in the priority list, or absl::nullopt if all pools
     201             :   // have been created.
     202             :   virtual absl::optional<PoolIterator> createNextPool();
     203             : 
     204             :   // This batch of member variables are latched objects required for pool creation.
     205             :   Event::Dispatcher& dispatcher_;
     206             :   Random::RandomGenerator& random_generator_;
     207             :   Upstream::HostConstSharedPtr host_;
     208             :   Upstream::ResourcePriority priority_;
     209             :   const Network::ConnectionSocket::OptionsSharedPtr options_;
     210             :   const Network::TransportSocketOptionsConstSharedPtr transport_socket_options_;
     211             :   Upstream::ClusterConnectivityState& state_;
     212             :   std::chrono::milliseconds next_attempt_duration_;
     213             :   TimeSource& time_source_;
     214             :   HttpServerPropertiesCacheSharedPtr alternate_protocols_;
     215             : 
     216             :   // True iff this pool is draining. No new streams or connections should be created
     217             :   // in this state.
     218             :   bool draining_{false};
     219             : 
     220             :   // Tracks the callbacks to be called on drain completion.
     221             :   std::list<Instance::IdleCb> idle_callbacks_;
     222             : 
     223             :   // The connection pools to use to create new streams, ordered in the order of
     224             :   // desired use.
     225             :   std::list<ConnectionPool::InstancePtr> pools_;
     226             : 
     227             :   // True iff under the stack of the destructor, to avoid calling drain
     228             :   // callbacks on deletion.
     229             :   bool destroying_{};
     230             : 
     231             :   // True iff this pool is being being defer deleted.
     232             :   bool deferred_deleting_{};
     233             : 
     234             :   // Wrapped callbacks are stashed in the wrapped_callbacks_ for ownership.
     235             :   std::list<WrapperCallbacksPtr> wrapped_callbacks_;
     236             : 
     237             :   Quic::QuicStatNames& quic_stat_names_;
     238             :   Stats::Scope& scope_;
     239             :   // The origin for this pool.
     240             :   // Note the host name here is based off of the host name used for SNI, which
     241             :   // may be from the cluster config, or the request headers for auto-sni.
     242             :   HttpServerPropertiesCache::Origin origin_;
     243             :   Http::PersistentQuicInfo& quic_info_;
     244             : };
     245             : 
     246             : } // namespace Http
     247             : } // namespace Envoy

Generated by: LCOV version 1.15