1
#pragma once
2

            
3
#include "envoy/buffer/buffer.h"
4
#include "envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.pb.h"
5
#include "envoy/http/filter.h"
6
#include "envoy/http/header_evaluator.h"
7
#include "envoy/http/request_id_extension.h"
8
#include "envoy/stream_info/stream_info.h"
9
#include "envoy/tcp/conn_pool.h"
10
#include "envoy/upstream/upstream.h"
11

            
12
#include "source/common/router/router.h"
13

            
14
namespace Envoy {
15

            
16
namespace Upstream {
17
class LoadBalancerContext;
18
class ThreadLocalCluster;
19
} // namespace Upstream
20

            
21
namespace TcpProxy {
22

            
23
class GenericConnectionPoolCallbacks;
24
class GenericUpstream;
25

            
26
/**
27
 * A configuration for an individual tunneling TCP over HTTP protocols.
28
 */
29
class TunnelingConfigHelper {
30
public:
31
835
  virtual ~TunnelingConfigHelper() = default;
32

            
33
  // The host name of the tunneling upstream HTTP request.
34
  // This function evaluates command operators if specified. Otherwise it returns host name as is.
35
  virtual std::string host(const StreamInfo::StreamInfo& stream_info) const PURE;
36

            
37
  // The method of the upstream HTTP request. True if using POST method, CONNECT otherwise.
38
  virtual bool usePost() const PURE;
39

            
40
  // The path used for POST method.
41
  virtual const std::string& postPath() const PURE;
42

            
43
  // The evaluator to add additional HTTP request headers to the upstream request.
44
  virtual Envoy::Http::HeaderEvaluator& headerEvaluator() const PURE;
45

            
46
  // The request ID extension used for generation/validation when tunneling.
47
  virtual const Envoy::Http::RequestIDExtensionSharedPtr& requestIDExtension() const PURE;
48

            
49
  // Optional request header name used to emit the generated request ID on the tunneling request.
50
  // If empty, the default header name "x-request-id" is used.
51
  virtual const std::string& requestIDHeader() const PURE;
52

            
53
  // Optional dynamic metadata key used to store the generated request ID under the TCP proxy
54
  // namespace. If empty, the default key "tunnel_request_id" is used.
55
  virtual const std::string& requestIDMetadataKey() const PURE;
56

            
57
  // Save HTTP response headers to the downstream filter state.
58
  virtual void
59
  propagateResponseHeaders(Http::ResponseHeaderMapPtr&& headers,
60
                           const StreamInfo::FilterStateSharedPtr& filter_state) const PURE;
61

            
62
  // Save HTTP response trailers to the downstream filter state.
63
  virtual void
64
  propagateResponseTrailers(Http::ResponseTrailerMapPtr&& trailers,
65
                            const StreamInfo::FilterStateSharedPtr& filter_state) const PURE;
66
  virtual const Envoy::Router::FilterConfig& routerFilterConfig() const PURE;
67
  virtual Server::Configuration::ServerFactoryContext& serverFactoryContext() const PURE;
68
};
69

            
70
using TunnelingConfigHelperOptConstRef = OptRef<const TunnelingConfigHelper>;
71

            
72
// An API for wrapping either a TCP or an HTTP connection pool.
73
class GenericConnPool : public Event::DeferredDeletable,
74
                        public Logger::Loggable<Logger::Id::router> {
75
public:
76
2592
  ~GenericConnPool() override = default;
77

            
78
  /**
79
   * Called to create a TCP connection or HTTP stream for "CONNECT" streams.
80
   *
81
   * The implementation is then responsible for calling either onGenericPoolReady or
82
   * onGenericPoolFailure on the supplied GenericConnectionPoolCallbacks.
83
   *
84
   * @param callbacks callbacks to communicate stream failure or creation on.
85
   */
86
  virtual void newStream(GenericConnectionPoolCallbacks& callbacks) PURE;
87
};
88

            
89
// An API for the UpstreamRequest to get callbacks from either an HTTP or TCP
90
// connection pool.
91
class GenericConnectionPoolCallbacks {
92
public:
93
2521
  virtual ~GenericConnectionPoolCallbacks() = default;
94

            
95
  /**
96
   * Called when GenericConnPool::newStream has established a new stream.
97
   *
98
   * @param info supplies the stream info object associated with the upstream connection.
99
   * @param upstream supplies the generic upstream for the stream.
100
   * @param host supplies the description of the host that will carry the request.
101
   * @param address_provider supplies the address provider of the upstream connection.
102
   * @param ssl_info supplies the ssl information of the upstream connection.
103
   */
104
  virtual void onGenericPoolReady(StreamInfo::StreamInfo* info,
105
                                  std::unique_ptr<GenericUpstream>&& upstream,
106
                                  Upstream::HostDescriptionConstSharedPtr& host,
107
                                  const Network::ConnectionInfoProvider& address_provider,
108
                                  Ssl::ConnectionInfoConstSharedPtr ssl_info) PURE;
109

            
110
  /**
111
   * Called to indicate a failure for GenericConnPool::newStream to establish a stream.
112
   *
113
   * @param reason supplies the failure reason.
114
   * @param failure_reason failure reason string (Note: it is expected that the caller will provide
115
   * matching `reason` and `failure_reason`).
116
   * @param host supplies the description of the host that caused the failure. This may be nullptr
117
   *             if no host was involved in the failure (for example overflow).
118
   */
119
  virtual void onGenericPoolFailure(ConnectionPool::PoolFailureReason reason,
120
                                    absl::string_view failure_reason,
121
                                    Upstream::HostDescriptionConstSharedPtr host) PURE;
122
};
123

            
124
// Interface for a generic Upstream, which can communicate with a TCP or HTTP
125
// upstream.
126
class GenericUpstream : public Event::DeferredDeletable {
127
public:
128
2538
  ~GenericUpstream() override = default;
129

            
130
  /**
131
   * Enable/disable further data from this stream.
132
   *
133
   * @param disable true if the stream should be read disabled, false otherwise.
134
   * @return returns true if the disable is performed, false otherwise
135
   *         (e.g. if the connection is closed)
136
   */
137
  virtual bool readDisable(bool disable) PURE;
138

            
139
  /**
140
   * Encodes data upstream.
141
   * @param data supplies the data to encode. The data may be moved by the encoder.
142
   * @param end_stream supplies whether this is the last data to encode.
143
   */
144
  virtual void encodeData(Buffer::Instance& data, bool end_stream) PURE;
145

            
146
  /**
147
   * Adds a callback to be called when the data is sent to the kernel.
148
   * @param cb supplies the callback to be called
149
   */
150
  virtual void addBytesSentCallback(Network::Connection::BytesSentCb cb) PURE;
151

            
152
  /**
153
   * Called when an event is received on the downstream connection
154
   * @param event supplies the event which occurred.
155
   * @param details supplies the details of the event, e.g. the local close reason.
156
   * @return the underlying ConnectionData if the event is not "Connected" and draining
157
             is supported for this upstream.
158
   */
159
  virtual Tcp::ConnectionPool::ConnectionData*
160
  onDownstreamEvent(Network::ConnectionEvent event, absl::string_view details = "") PURE;
161

            
162
  /* Called to convert underlying transport socket from non-secure mode
163
   * to secure mode. Implemented only by start_tls transport socket.
164
   */
165
  virtual bool startUpstreamSecureTransport() PURE;
166

            
167
  /**
168
   * Called when upstream starttls socket is converted to tls and upstream ssl info
169
   * needs to be set in the connection's stream_info.
170
   * @return the const SSL connection data of upstream.
171
   */
172
  virtual Ssl::ConnectionInfoConstSharedPtr getUpstreamConnectionSslInfo() PURE;
173

            
174
  /**
175
   * Called when upstream connection is closed.
176
   * @return the detected close type from socket.
177
   */
178
  virtual StreamInfo::DetectedCloseType detectedCloseType() const PURE;
179

            
180
  /**
181
   * @return the failure reason of the local close.
182
   */
183
564
  virtual absl::string_view localCloseReason() const { return ""; }
184
};
185

            
186
using GenericConnPoolPtr = std::unique_ptr<GenericConnPool>;
187
/*
188
 * A factory for creating generic connection pools.
189
 */
190
class GenericConnPoolFactory : public Envoy::Config::TypedFactory {
191
public:
192
12
  ~GenericConnPoolFactory() override = default;
193

            
194
  /*
195
   * @param host the host to connect to
196
   * @param thread_local_cluster the thread local cluster to use for conn pool creation.
197
   * @param config the tunneling config, if doing connect tunneling.
198
   * @param context the load balancing context for this connection.
199
   * @param upstream_callbacks the callbacks to provide to the connection if successfully created.
200
   * @param downstream_info is the downstream connection stream info.
201
   * @return may be null if there is no cluster with the given name.
202
   */
203
  virtual GenericConnPoolPtr createGenericConnPool(
204
      Upstream::HostConstSharedPtr host, Upstream::ThreadLocalCluster& thread_local_cluster,
205
      TunnelingConfigHelperOptConstRef config, Upstream::LoadBalancerContext* context,
206
      Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks,
207
      Http::StreamDecoderFilterCallbacks& stream_decoder_callbacks,
208
      StreamInfo::StreamInfo& downstream_info) const PURE;
209
};
210

            
211
using GenericConnPoolFactoryPtr = std::unique_ptr<GenericConnPoolFactory>;
212

            
213
} // namespace TcpProxy
214
} // namespace Envoy