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