/proc/self/cwd/source/common/tcp_proxy/upstream.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "envoy/http/conn_pool.h" |
4 | | #include "envoy/network/connection.h" |
5 | | #include "envoy/tcp/conn_pool.h" |
6 | | #include "envoy/tcp/upstream.h" |
7 | | #include "envoy/upstream/load_balancer.h" |
8 | | #include "envoy/upstream/thread_local_cluster.h" |
9 | | #include "envoy/upstream/upstream.h" |
10 | | |
11 | | #include "source/common/common/dump_state_utils.h" |
12 | | #include "source/common/http/codec_client.h" |
13 | | #include "source/common/router/header_parser.h" |
14 | | |
15 | | namespace Envoy { |
16 | | namespace TcpProxy { |
17 | | |
18 | | constexpr absl::string_view DisableTunnelingFilterStateKey = "envoy.tcp_proxy.disable_tunneling"; |
19 | | |
20 | | class TcpConnPool : public GenericConnPool, public Tcp::ConnectionPool::Callbacks { |
21 | | public: |
22 | | TcpConnPool(Upstream::ThreadLocalCluster& thread_local_cluster, |
23 | | Upstream::LoadBalancerContext* context, |
24 | | Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks, |
25 | | StreamInfo::StreamInfo& downstream_info); |
26 | | ~TcpConnPool() override; |
27 | | |
28 | 0 | bool valid() const { return conn_pool_data_.has_value(); } |
29 | | |
30 | | // GenericConnPool |
31 | | void newStream(GenericConnectionPoolCallbacks& callbacks) override; |
32 | | |
33 | | // Tcp::ConnectionPool::Callbacks |
34 | | void onPoolFailure(ConnectionPool::PoolFailureReason reason, |
35 | | absl::string_view transport_failure_reason, |
36 | | Upstream::HostDescriptionConstSharedPtr host) override; |
37 | | void onPoolReady(Tcp::ConnectionPool::ConnectionDataPtr&& conn_data, |
38 | | Upstream::HostDescriptionConstSharedPtr host) override; |
39 | | |
40 | | private: |
41 | | absl::optional<Upstream::TcpPoolData> conn_pool_data_{}; |
42 | | Tcp::ConnectionPool::Cancellable* upstream_handle_{}; |
43 | | GenericConnectionPoolCallbacks* callbacks_{}; |
44 | | Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks_; |
45 | | StreamInfo::StreamInfo& downstream_info_; |
46 | | }; |
47 | | |
48 | | class HttpUpstream; |
49 | | |
50 | | class HttpConnPool : public GenericConnPool, public Http::ConnectionPool::Callbacks { |
51 | | public: |
52 | | HttpConnPool(Upstream::ThreadLocalCluster& thread_local_cluster, |
53 | | Upstream::LoadBalancerContext* context, const TunnelingConfigHelper& config, |
54 | | Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks, Http::CodecType type, |
55 | | StreamInfo::StreamInfo& downstream_info); |
56 | | ~HttpConnPool() override; |
57 | | |
58 | 0 | bool valid() const { return conn_pool_data_.has_value(); } |
59 | | |
60 | | // GenericConnPool |
61 | | void newStream(GenericConnectionPoolCallbacks& callbacks) override; |
62 | | |
63 | | // Http::ConnectionPool::Callbacks, |
64 | | void onPoolFailure(ConnectionPool::PoolFailureReason reason, |
65 | | absl::string_view transport_failure_reason, |
66 | | Upstream::HostDescriptionConstSharedPtr host) override; |
67 | | void onPoolReady(Http::RequestEncoder& request_encoder, |
68 | | Upstream::HostDescriptionConstSharedPtr host, StreamInfo::StreamInfo& info, |
69 | | absl::optional<Http::Protocol>) override; |
70 | | |
71 | | class Callbacks { |
72 | | public: |
73 | | Callbacks(HttpConnPool& conn_pool, Upstream::HostDescriptionConstSharedPtr host, |
74 | | Ssl::ConnectionInfoConstSharedPtr ssl_info) |
75 | 0 | : conn_pool_(&conn_pool), host_(host), ssl_info_(ssl_info) {} |
76 | 0 | virtual ~Callbacks() = default; |
77 | 0 | virtual void onSuccess(Http::RequestEncoder& request_encoder) { |
78 | 0 | ASSERT(conn_pool_ != nullptr); |
79 | 0 | conn_pool_->onGenericPoolReady(host_, request_encoder.getStream().connectionInfoProvider(), |
80 | 0 | ssl_info_); |
81 | 0 | } |
82 | 0 | virtual void onFailure() { |
83 | 0 | ASSERT(conn_pool_ != nullptr); |
84 | 0 | conn_pool_->callbacks_->onGenericPoolFailure( |
85 | 0 | ConnectionPool::PoolFailureReason::RemoteConnectionFailure, "", host_); |
86 | 0 | } |
87 | | |
88 | | protected: |
89 | | Callbacks() = default; |
90 | | |
91 | | private: |
92 | | HttpConnPool* conn_pool_{}; |
93 | | Upstream::HostDescriptionConstSharedPtr host_; |
94 | | Ssl::ConnectionInfoConstSharedPtr ssl_info_; |
95 | | }; |
96 | | |
97 | | private: |
98 | | void onGenericPoolReady(Upstream::HostDescriptionConstSharedPtr& host, |
99 | | const Network::ConnectionInfoProvider& address_provider, |
100 | | Ssl::ConnectionInfoConstSharedPtr ssl_info); |
101 | | const TunnelingConfigHelper& config_; |
102 | | Http::CodecType type_; |
103 | | absl::optional<Upstream::HttpPoolData> conn_pool_data_{}; |
104 | | Http::ConnectionPool::Cancellable* upstream_handle_{}; |
105 | | GenericConnectionPoolCallbacks* callbacks_{}; |
106 | | Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks_; |
107 | | std::unique_ptr<HttpUpstream> upstream_; |
108 | | StreamInfo::StreamInfo& downstream_info_; |
109 | | }; |
110 | | |
111 | | class TcpUpstream : public GenericUpstream { |
112 | | public: |
113 | | TcpUpstream(Tcp::ConnectionPool::ConnectionDataPtr&& data, |
114 | | Tcp::ConnectionPool::UpstreamCallbacks& callbacks); |
115 | | |
116 | | // GenericUpstream |
117 | | bool readDisable(bool disable) override; |
118 | | void encodeData(Buffer::Instance& data, bool end_stream) override; |
119 | | void addBytesSentCallback(Network::Connection::BytesSentCb cb) override; |
120 | | Tcp::ConnectionPool::ConnectionData* onDownstreamEvent(Network::ConnectionEvent event) override; |
121 | | bool startUpstreamSecureTransport() override; |
122 | | Ssl::ConnectionInfoConstSharedPtr getUpstreamConnectionSslInfo() override; |
123 | | |
124 | | private: |
125 | | Tcp::ConnectionPool::ConnectionDataPtr upstream_conn_data_; |
126 | | }; |
127 | | |
128 | | class HttpUpstream : public GenericUpstream, protected Http::StreamCallbacks { |
129 | | public: |
130 | | using TunnelingConfig = |
131 | | envoy::extensions::filters::network::tcp_proxy::v3::TcpProxy_TunnelingConfig; |
132 | | |
133 | | ~HttpUpstream() override; |
134 | | virtual bool isValidResponse(const Http::ResponseHeaderMap&) PURE; |
135 | | |
136 | | void doneReading(); |
137 | | void doneWriting(); |
138 | 0 | Http::ResponseDecoder& responseDecoder() { return response_decoder_; } |
139 | | |
140 | | // GenericUpstream |
141 | | bool readDisable(bool disable) override; |
142 | | void encodeData(Buffer::Instance& data, bool end_stream) override; |
143 | | void addBytesSentCallback(Network::Connection::BytesSentCb cb) override; |
144 | | Tcp::ConnectionPool::ConnectionData* onDownstreamEvent(Network::ConnectionEvent event) override; |
145 | | // HTTP upstream must not implement converting upstream transport |
146 | | // socket from non-secure to secure mode. |
147 | 0 | bool startUpstreamSecureTransport() override { return false; } |
148 | | |
149 | | // Http::StreamCallbacks |
150 | | void onResetStream(Http::StreamResetReason reason, |
151 | | absl::string_view transport_failure_reason) override; |
152 | | void onAboveWriteBufferHighWatermark() override; |
153 | | void onBelowWriteBufferLowWatermark() override; |
154 | | |
155 | | virtual void setRequestEncoder(Http::RequestEncoder& request_encoder, bool is_ssl) PURE; |
156 | 0 | void setConnPoolCallbacks(std::unique_ptr<HttpConnPool::Callbacks>&& callbacks) { |
157 | 0 | conn_pool_callbacks_ = std::move(callbacks); |
158 | 0 | } |
159 | 0 | Ssl::ConnectionInfoConstSharedPtr getUpstreamConnectionSslInfo() override { return nullptr; } |
160 | | |
161 | | protected: |
162 | | HttpUpstream(Tcp::ConnectionPool::UpstreamCallbacks& callbacks, |
163 | | const TunnelingConfigHelper& config, StreamInfo::StreamInfo& downstream_info); |
164 | | void resetEncoder(Network::ConnectionEvent event, bool inform_downstream = true); |
165 | | |
166 | | // The encoder offered by the upstream http client. |
167 | | Http::RequestEncoder* request_encoder_{}; |
168 | | // The config object that is owned by the downstream network filter chain factory. |
169 | | const TunnelingConfigHelper& config_; |
170 | | // The downstream info that is owned by the downstream connection. |
171 | | StreamInfo::StreamInfo& downstream_info_; |
172 | | |
173 | | private: |
174 | | class DecoderShim : public Http::ResponseDecoder { |
175 | | public: |
176 | 0 | DecoderShim(HttpUpstream& parent) : parent_(parent) {}Unexecuted instantiation: Envoy::TcpProxy::HttpUpstream::DecoderShim::DecoderShim(Envoy::TcpProxy::HttpUpstream&) Unexecuted instantiation: Envoy::TcpProxy::HttpUpstream::DecoderShim::DecoderShim(Envoy::TcpProxy::HttpUpstream&) |
177 | | // Http::ResponseDecoder |
178 | 0 | void decode1xxHeaders(Http::ResponseHeaderMapPtr&&) override {} |
179 | 0 | void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override { |
180 | 0 | bool is_valid_response = parent_.isValidResponse(*headers); |
181 | 0 | parent_.config_.propagateResponseHeaders(std::move(headers), |
182 | 0 | parent_.downstream_info_.filterState()); |
183 | 0 | if (!is_valid_response || end_stream) { |
184 | 0 | parent_.resetEncoder(Network::ConnectionEvent::LocalClose); |
185 | 0 | } else if (parent_.conn_pool_callbacks_ != nullptr) { |
186 | 0 | parent_.conn_pool_callbacks_->onSuccess(*parent_.request_encoder_); |
187 | 0 | parent_.conn_pool_callbacks_.reset(); |
188 | 0 | } |
189 | 0 | } |
190 | 0 | void decodeData(Buffer::Instance& data, bool end_stream) override { |
191 | 0 | parent_.upstream_callbacks_.onUpstreamData(data, end_stream); |
192 | 0 | if (end_stream) { |
193 | 0 | parent_.doneReading(); |
194 | 0 | } |
195 | 0 | } |
196 | 0 | void decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) override { |
197 | 0 | parent_.config_.propagateResponseTrailers(std::move(trailers), |
198 | 0 | parent_.downstream_info_.filterState()); |
199 | 0 | parent_.doneReading(); |
200 | 0 | } |
201 | 0 | void decodeMetadata(Http::MetadataMapPtr&&) override {} |
202 | 0 | void dumpState(std::ostream& os, int indent_level) const override { |
203 | 0 | DUMP_STATE_UNIMPLEMENTED(DecoderShim); |
204 | 0 | } |
205 | | |
206 | | private: |
207 | | HttpUpstream& parent_; |
208 | | }; |
209 | | DecoderShim response_decoder_; |
210 | | Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks_; |
211 | | bool read_half_closed_{}; |
212 | | bool write_half_closed_{}; |
213 | | |
214 | | // Used to defer onGenericPoolReady and onGenericPoolFailure to the reception |
215 | | // of the CONNECT response or the resetEncoder. |
216 | | std::unique_ptr<HttpConnPool::Callbacks> conn_pool_callbacks_; |
217 | | }; |
218 | | |
219 | | class Http1Upstream : public HttpUpstream { |
220 | | public: |
221 | | Http1Upstream(Tcp::ConnectionPool::UpstreamCallbacks& callbacks, |
222 | | const TunnelingConfigHelper& config, StreamInfo::StreamInfo& downstream_info); |
223 | | |
224 | | void encodeData(Buffer::Instance& data, bool end_stream) override; |
225 | | void setRequestEncoder(Http::RequestEncoder& request_encoder, bool is_ssl) override; |
226 | | bool isValidResponse(const Http::ResponseHeaderMap& headers) override; |
227 | | }; |
228 | | |
229 | | class Http2Upstream : public HttpUpstream { |
230 | | public: |
231 | | Http2Upstream(Tcp::ConnectionPool::UpstreamCallbacks& callbacks, |
232 | | const TunnelingConfigHelper& config, StreamInfo::StreamInfo& downstream_info); |
233 | | |
234 | | void setRequestEncoder(Http::RequestEncoder& request_encoder, bool is_ssl) override; |
235 | | bool isValidResponse(const Http::ResponseHeaderMap& headers) override; |
236 | | }; |
237 | | |
238 | | } // namespace TcpProxy |
239 | | } // namespace Envoy |