/proc/self/cwd/source/common/tcp/conn_pool.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <list> |
4 | | #include <memory> |
5 | | |
6 | | #include "envoy/event/deferred_deletable.h" |
7 | | #include "envoy/event/timer.h" |
8 | | #include "envoy/network/connection.h" |
9 | | #include "envoy/network/filter.h" |
10 | | #include "envoy/stats/timespan.h" |
11 | | #include "envoy/tcp/conn_pool.h" |
12 | | #include "envoy/upstream/upstream.h" |
13 | | |
14 | | #include "source/common/common/linked_object.h" |
15 | | #include "source/common/common/logger.h" |
16 | | #include "source/common/http/conn_pool_base.h" |
17 | | #include "source/common/network/filter_impl.h" |
18 | | #include "source/common/runtime/runtime_features.h" |
19 | | |
20 | | namespace Envoy { |
21 | | namespace Tcp { |
22 | | |
23 | | class ConnPoolImpl; |
24 | | |
25 | | struct TcpAttachContext : public Envoy::ConnectionPool::AttachContext { |
26 | 0 | TcpAttachContext(Tcp::ConnectionPool::Callbacks* callbacks) : callbacks_(callbacks) {} |
27 | | Tcp::ConnectionPool::Callbacks* callbacks_; |
28 | | }; |
29 | | |
30 | | class TcpPendingStream : public Envoy::ConnectionPool::PendingStream { |
31 | | public: |
32 | | TcpPendingStream(Envoy::ConnectionPool::ConnPoolImplBase& parent, bool can_send_early_data, |
33 | | TcpAttachContext& context) |
34 | 0 | : Envoy::ConnectionPool::PendingStream(parent, can_send_early_data), context_(context) {} |
35 | 0 | Envoy::ConnectionPool::AttachContext& context() override { return context_; } |
36 | | |
37 | | TcpAttachContext context_; |
38 | | }; |
39 | | |
40 | | class ActiveTcpClient : public Envoy::ConnectionPool::ActiveClient { |
41 | | public: |
42 | | struct ConnReadFilter : public Network::ReadFilterBaseImpl { |
43 | 0 | ConnReadFilter(ActiveTcpClient& parent) : parent_(parent) {} |
44 | | |
45 | | // Network::ReadFilter |
46 | 0 | Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override { |
47 | 0 | parent_.onUpstreamData(data, end_stream); |
48 | 0 | return Network::FilterStatus::StopIteration; |
49 | 0 | } |
50 | | ActiveTcpClient& parent_; |
51 | | }; |
52 | | |
53 | | // This acts as the bridge between the ActiveTcpClient and an individual TCP connection. |
54 | | class TcpConnectionData : public Envoy::Tcp::ConnectionPool::ConnectionData { |
55 | | public: |
56 | | TcpConnectionData(ActiveTcpClient& parent, Network::ClientConnection& connection) |
57 | 0 | : parent_(&parent), connection_(connection) { |
58 | 0 | parent_->tcp_connection_data_ = this; |
59 | 0 | } |
60 | 0 | ~TcpConnectionData() override { |
61 | | // Generally it is the case that TcpConnectionData will be destroyed before the |
62 | | // ActiveTcpClient. Because ordering on the deferred delete list is not guaranteed in the |
63 | | // case of a disconnect, make sure parent_ is valid before doing clean-up. |
64 | 0 | if (parent_) { |
65 | 0 | parent_->clearCallbacks(); |
66 | 0 | } |
67 | 0 | } |
68 | | |
69 | 0 | Network::ClientConnection& connection() override { return connection_; } |
70 | 0 | void setConnectionState(ConnectionPool::ConnectionStatePtr&& state) override { |
71 | 0 | parent_->connection_state_ = std::move(state); |
72 | 0 | } |
73 | | |
74 | 0 | void addUpstreamCallbacks(ConnectionPool::UpstreamCallbacks& callbacks) override { |
75 | 0 | parent_->callbacks_ = &callbacks; |
76 | 0 | } |
77 | 0 | void release() { parent_ = nullptr; } |
78 | | |
79 | | protected: |
80 | 0 | ConnectionPool::ConnectionState* connectionState() override { |
81 | 0 | return parent_->connection_state_.get(); |
82 | 0 | } |
83 | | |
84 | | private: |
85 | | ActiveTcpClient* parent_; |
86 | | Network::ClientConnection& connection_; |
87 | | }; |
88 | | |
89 | | ActiveTcpClient(Envoy::ConnectionPool::ConnPoolImplBase& parent, |
90 | | const Upstream::HostConstSharedPtr& host, uint64_t concurrent_stream_limit, |
91 | | absl::optional<std::chrono::milliseconds> idle_timeout); |
92 | | ~ActiveTcpClient() override; |
93 | | |
94 | | // Override the default's of Envoy::ConnectionPool::ActiveClient for class-specific functions. |
95 | | // Network::ConnectionCallbacks |
96 | | void onEvent(Network::ConnectionEvent event) override; |
97 | 0 | void onAboveWriteBufferHighWatermark() override { callbacks_->onAboveWriteBufferHighWatermark(); } |
98 | 0 | void onBelowWriteBufferLowWatermark() override { callbacks_->onBelowWriteBufferLowWatermark(); } |
99 | | |
100 | | // Undos the readDisable done in onEvent(Connected) |
101 | | void readEnableIfNew(); |
102 | | |
103 | 0 | void initializeReadFilters() override { connection_->initializeReadFilters(); } |
104 | 0 | absl::optional<Http::Protocol> protocol() const override { return {}; } |
105 | | void close() override; |
106 | 0 | uint32_t numActiveStreams() const override { return callbacks_ ? 1 : 0; } |
107 | 0 | bool closingWithIncompleteStream() const override { return false; } |
108 | 0 | uint64_t id() const override { return connection_->id(); } |
109 | | |
110 | 0 | void onUpstreamData(Buffer::Instance& data, bool end_stream) { |
111 | 0 | if (callbacks_) { |
112 | 0 | callbacks_->onUpstreamData(data, end_stream); |
113 | 0 | } else { |
114 | 0 | close(); |
115 | 0 | } |
116 | 0 | } |
117 | | virtual void clearCallbacks(); |
118 | | |
119 | | // Called if the underlying connection is idle over the cluster's tcpPoolIdleTimeout() |
120 | | void onIdleTimeout(); |
121 | | void disableIdleTimer(); |
122 | | void setIdleTimer(); |
123 | | |
124 | | std::shared_ptr<ConnReadFilter> read_filter_handle_; |
125 | | Envoy::ConnectionPool::ConnPoolImplBase& parent_; |
126 | | ConnectionPool::UpstreamCallbacks* callbacks_{}; |
127 | | Network::ClientConnectionPtr connection_; |
128 | | ConnectionPool::ConnectionStatePtr connection_state_; |
129 | | TcpConnectionData* tcp_connection_data_{}; |
130 | | bool associated_before_{}; |
131 | | absl::optional<std::chrono::milliseconds> idle_timeout_; |
132 | | Event::TimerPtr idle_timer_; |
133 | | }; |
134 | | |
135 | | class ConnPoolImpl : public Envoy::ConnectionPool::ConnPoolImplBase, |
136 | | public Tcp::ConnectionPool::Instance { |
137 | | public: |
138 | | ConnPoolImpl(Event::Dispatcher& dispatcher, Upstream::HostConstSharedPtr host, |
139 | | Upstream::ResourcePriority priority, |
140 | | const Network::ConnectionSocket::OptionsSharedPtr& options, |
141 | | Network::TransportSocketOptionsConstSharedPtr transport_socket_options, |
142 | | Upstream::ClusterConnectivityState& state, |
143 | | absl::optional<std::chrono::milliseconds> idle_timeout) |
144 | | : Envoy::ConnectionPool::ConnPoolImplBase(host, priority, dispatcher, options, |
145 | | transport_socket_options, state), |
146 | 0 | idle_timeout_(idle_timeout) {} |
147 | 0 | ~ConnPoolImpl() override { destructAllConnections(); } |
148 | | |
149 | | // Event::DeferredDeletable |
150 | 0 | void deleteIsPending() override { deleteIsPendingImpl(); } |
151 | | |
152 | 0 | void addIdleCallback(IdleCb cb) override { addIdleCallbackImpl(cb); } |
153 | 0 | bool isIdle() const override { return isIdleImpl(); } |
154 | | void drainConnections(Envoy::ConnectionPool::DrainBehavior drain_behavior) override; |
155 | | void closeConnections() override; |
156 | | ConnectionPool::Cancellable* newConnection(Tcp::ConnectionPool::Callbacks& callbacks) override; |
157 | 0 | bool maybePreconnect(float preconnect_ratio) override { |
158 | 0 | return maybePreconnectImpl(preconnect_ratio); |
159 | 0 | } |
160 | | ConnectionPool::Cancellable* newPendingStream(Envoy::ConnectionPool::AttachContext& context, |
161 | | bool can_send_early_data) override; |
162 | 0 | Upstream::HostDescriptionConstSharedPtr host() const override { |
163 | 0 | return Envoy::ConnectionPool::ConnPoolImplBase::host(); |
164 | 0 | } |
165 | | Envoy::ConnectionPool::ActiveClientPtr instantiateActiveClient() override; |
166 | | void onPoolReady(Envoy::ConnectionPool::ActiveClient& client, |
167 | | Envoy::ConnectionPool::AttachContext& context) override; |
168 | | void onPoolFailure(const Upstream::HostDescriptionConstSharedPtr& host_description, |
169 | | absl::string_view failure_reason, ConnectionPool::PoolFailureReason reason, |
170 | | Envoy::ConnectionPool::AttachContext& context) override; |
171 | 0 | bool enforceMaxRequests() const override { return false; } |
172 | | // These two functions exist for testing parity between old and new Tcp Connection Pools. |
173 | 0 | virtual void onConnReleased(Envoy::ConnectionPool::ActiveClient&) {} |
174 | 0 | virtual void onConnDestroyed() {} |
175 | | |
176 | | absl::optional<std::chrono::milliseconds> idle_timeout_; |
177 | | }; |
178 | | |
179 | | } // namespace Tcp |
180 | | } // namespace Envoy |