1
#pragma once
2

            
3
#include <chrono>
4
#include <cstdint>
5
#include <memory>
6
#include <string>
7

            
8
#include "envoy/buffer/buffer.h"
9
#include "envoy/common/pure.h"
10
#include "envoy/common/scope_tracker.h"
11
#include "envoy/event/deferred_deletable.h"
12
#include "envoy/network/address.h"
13
#include "envoy/network/filter.h"
14
#include "envoy/network/listen_socket.h"
15
#include "envoy/network/socket.h"
16
#include "envoy/ssl/connection.h"
17
#include "envoy/stream_info/stream_info.h"
18

            
19
namespace Envoy {
20
namespace Event {
21
class Dispatcher;
22
}
23

            
24
namespace Network {
25

            
26
/**
27
 * Events that occur on a connection.
28
 */
29
enum class ConnectionEvent {
30
  RemoteClose,
31
  LocalClose,
32
  Connected,
33
  ConnectedZeroRtt,
34
};
35

            
36
/**
37
 * Connections have both a read and write buffer.
38
 */
39
enum class ConnectionBufferType { Read, Write };
40

            
41
/**
42
 * Network level callbacks that happen on a connection.
43
 */
44
class ConnectionCallbacks {
45
public:
46
223001
  virtual ~ConnectionCallbacks() = default;
47

            
48
  /**
49
   * Callback for connection events.
50
   * @param events supplies the ConnectionEvent that occurred.
51
   */
52
  virtual void onEvent(ConnectionEvent event) PURE;
53

            
54
  /**
55
   * Called when the write buffer for a connection goes over its high watermark.
56
   */
57
  virtual void onAboveWriteBufferHighWatermark() PURE;
58

            
59
  /**
60
   * Called when the write buffer for a connection goes from over its high
61
   * watermark to under its low watermark.
62
   */
63
  virtual void onBelowWriteBufferLowWatermark() PURE;
64
};
65

            
66
/**
67
 * Type of connection close to perform.
68
 */
69
enum class ConnectionCloseType {
70
  FlushWrite, // Flush pending write data before raising ConnectionEvent::LocalClose
71
  NoFlush, // Do not flush any pending data. Write the pending data to buffer and then immediately
72
           // raise ConnectionEvent::LocalClose
73
  FlushWriteAndDelay, // Flush pending write data and delay raising a ConnectionEvent::LocalClose
74
                      // until the delayed_close_timeout expires
75
  Abort, // Do not write/flush any pending data and immediately raise ConnectionEvent::LocalClose
76
  AbortReset // Do not write/flush any pending data and immediately raise
77
             // ConnectionEvent::LocalClose. Envoy will try to close the connection with RST flag.
78
};
79

            
80
/**
81
 * Combines connection event and close type for connection close operations
82
 */
83
struct ConnectionCloseAction {
84
  ConnectionEvent event_;
85
  bool close_socket_;
86
  ConnectionCloseType type_;
87

            
88
  ConnectionCloseAction(ConnectionEvent event_type = ConnectionEvent::Connected,
89
                        bool close_socket = false,
90
                        ConnectionCloseType close_type = ConnectionCloseType::NoFlush)
91
67547
      : event_(event_type), close_socket_(close_socket), type_(close_type) {}
92

            
93
10
  bool operator==(const ConnectionCloseAction& other) const {
94
10
    return event_ == other.event_ && type_ == other.type_ && close_socket_ == other.close_socket_;
95
10
  }
96

            
97
  bool operator!=(const ConnectionCloseAction& other) const { return !(*this == other); }
98

            
99
67396
  bool closeSocket() const { return close_socket_; }
100
42
  bool isLocalClose() const { return event_ == ConnectionEvent::LocalClose; }
101
38
  bool isRemoteClose() const { return event_ == ConnectionEvent::RemoteClose; }
102
};
103

            
104
/**
105
 * An abstract raw connection. Free the connection or call close() to disconnect.
106
 */
107
class Connection : public Event::DeferredDeletable,
108
                   public FilterManager,
109
                   public ScopeTrackedObject {
110
public:
111
  enum class State { Open, Closing, Closed };
112

            
113
  enum class ReadDisableStatus {
114
    NoTransition,
115
    StillReadDisabled,
116
    TransitionedToReadEnabled,
117
    TransitionedToReadDisabled
118
  };
119

            
120
  /**
121
   * Callback function for when bytes have been sent by a connection.
122
   * @param bytes_sent supplies the number of bytes written to the connection.
123
   * @return indicates if callback should be called in the future. If true is returned
124
   * the callback will be called again in the future. If false is returned, the callback
125
   * will be removed from callback list.
126
   */
127
  using BytesSentCb = std::function<bool(uint64_t bytes_sent)>;
128

            
129
  struct ConnectionStats {
130
    Stats::Counter& read_total_;
131
    Stats::Gauge& read_current_;
132
    Stats::Counter& write_total_;
133
    Stats::Gauge& write_current_;
134
    // Counter* as this is an optional counter. Bind errors will not be tracked if this is nullptr.
135
    Stats::Counter* bind_errors_;
136
    // Optional counter. Delayed close timeouts will not be tracked if this is nullptr.
137
    Stats::Counter* delayed_close_timeouts_;
138
  };
139

            
140
122580
  ~Connection() override = default;
141

            
142
  /**
143
   * Register callbacks that fire when connection events occur.
144
   */
145
  virtual void addConnectionCallbacks(ConnectionCallbacks& cb) PURE;
146

            
147
  /**
148
   * Unregister callbacks which previously fired when connection events occur.
149
   */
150
  virtual void removeConnectionCallbacks(ConnectionCallbacks& cb) PURE;
151

            
152
  /**
153
   * Register for callback every time bytes are written to the underlying TransportSocket.
154
   */
155
  virtual void addBytesSentCallback(BytesSentCb cb) PURE;
156

            
157
  /**
158
   * Enable half-close semantics on this connection. Reading a remote half-close
159
   * will not fully close the connection. This is off by default.
160
   * @param enabled Whether to set half-close semantics as enabled or disabled.
161
   */
162
  virtual void enableHalfClose(bool enabled) PURE;
163

            
164
  /**
165
   * @return true if half-close semantics are enabled, false otherwise.
166
   */
167
  virtual bool isHalfCloseEnabled() const PURE;
168

            
169
  /**
170
   * Close the connection.
171
   * @param type the connection close type.
172
   */
173
  virtual void close(ConnectionCloseType type) PURE;
174

            
175
  /**
176
   * Close the connection.
177
   * @param type the connection close type.
178
   * @param details the reason the connection is being closed.
179
   */
180
  virtual void close(ConnectionCloseType type, absl::string_view details) PURE;
181

            
182
  /**
183
   * @return the detected close type from socket.
184
   */
185
  virtual StreamInfo::DetectedCloseType detectedCloseType() const PURE;
186

            
187
  /**
188
   * @return Event::Dispatcher& the dispatcher backing this connection.
189
   */
190
  virtual Event::Dispatcher& dispatcher() const PURE;
191

            
192
  /**
193
   * @return uint64_t the unique local ID of this connection.
194
   */
195
  virtual uint64_t id() const PURE;
196

            
197
  /**
198
   * @param vector of bytes to which the connection should append hash key data. Any data already in
199
   * the key vector must not be modified.
200
   */
201
  virtual void hashKey(std::vector<uint8_t>& hash) const PURE;
202

            
203
  /**
204
   * @return std::string the next protocol to use as selected by network level negotiation. (E.g.,
205
   *         ALPN). If network level negotiation is not supported by the connection or no protocol
206
   *         has been negotiated the empty string is returned.
207
   */
208
  virtual std::string nextProtocol() const PURE;
209

            
210
  /**
211
   * Enable/Disable TCP NO_DELAY on the connection.
212
   */
213
  virtual void noDelay(bool enable) PURE;
214

            
215
  /**
216
   * Disable socket reads on the connection, applying external back pressure. When reads are
217
   * enabled again if there is data still in the input buffer it will be re-dispatched through
218
   * the filter chain.
219
   * @param disable supplies TRUE is reads should be disabled, FALSE if they should be enabled.
220
   * @return status enum indicating the outcome of calling readDisable on the underlying socket.
221
   *
222
   * Note that this function reference counts calls. For example
223
   * readDisable(true);  // Disables data
224
   * readDisable(true);  // Notes the connection is blocked by two sources
225
   * readDisable(false);  // Notes the connection is blocked by one source
226
   * readDisable(false);  // Marks the connection as unblocked, so resumes reading.
227
   */
228
  virtual ReadDisableStatus readDisable(bool disable) PURE;
229

            
230
  /**
231
   * Set if Envoy should detect TCP connection close when readDisable(true) is called.
232
   * By default, this is true on newly created connections.
233
   *
234
   * @param should_detect supplies if disconnects should be detected when the connection has been
235
   * read disabled
236
   */
237
  virtual void detectEarlyCloseWhenReadDisabled(bool should_detect) PURE;
238

            
239
  /**
240
   * @return bool whether reading is enabled on the connection.
241
   */
242
  virtual bool readEnabled() const PURE;
243

            
244
  /**
245
   * @return the connection info provider backing this connection.
246
   */
247
  virtual ConnectionInfoSetter& connectionInfoSetter() PURE;
248
  virtual const ConnectionInfoProvider& connectionInfoProvider() const PURE;
249
  virtual ConnectionInfoProviderSharedPtr connectionInfoProviderSharedPtr() const PURE;
250

            
251
  /**
252
   * Credentials of the peer of a socket as decided by SO_PEERCRED.
253
   */
254
  struct UnixDomainSocketPeerCredentials {
255
    /**
256
     * The process id of the peer.
257
     */
258
    int32_t pid;
259
    /**
260
     * The user id of the peer.
261
     */
262
    uint32_t uid;
263
    /**
264
     * The group id of the peer.
265
     */
266
    uint32_t gid;
267
  };
268

            
269
  /**
270
   * @return The unix socket peer credentials of the remote client. Note that this is only
271
   * supported for unix socket connections.
272
   */
273
  virtual absl::optional<UnixDomainSocketPeerCredentials> unixSocketPeerCredentials() const PURE;
274

            
275
  /**
276
   * Set the stats to update for various connection state changes. Note that for performance reasons
277
   * these stats are eventually consistent and may not always accurately represent the connection
278
   * state at any given point in time.
279
   */
280
  virtual void setConnectionStats(const ConnectionStats& stats) PURE;
281

            
282
  /**
283
   * @return the const SSL connection data if this is an SSL connection, or nullptr if it is not.
284
   */
285
  // TODO(snowp): Remove this in favor of StreamInfo::downstreamSslConnection.
286
  virtual Ssl::ConnectionInfoConstSharedPtr ssl() const PURE;
287

            
288
  /**
289
   * @return requested server name (e.g. SNI in TLS), if any.
290
   */
291
  virtual absl::string_view requestedServerName() const PURE;
292

            
293
  /**
294
   * @return State the current state of the connection.
295
   */
296
  virtual State state() const PURE;
297

            
298
  /**
299
   * @return true if the connection has not completed connecting, false if the connection is
300
   * established.
301
   */
302
  virtual bool connecting() const PURE;
303

            
304
  /**
305
   * Write data to the connection. Will iterate through network filters with the buffer if any
306
   * are installed.
307
   * @param data Supplies the data to write to the connection.
308
   * @param end_stream If true, this indicates that this is the last write to the connection. If
309
   *        end_stream is true, the connection is half-closed. This may only be set to true if
310
   *        enableHalfClose(true) has been set on this connection.
311
   */
312
  virtual void write(Buffer::Instance& data, bool end_stream) PURE;
313

            
314
  /**
315
   * Set a soft limit on the size of buffers for the connection.
316
   * For the read buffer, this limits the bytes read prior to flushing to further stages in the
317
   * processing pipeline.
318
   * For the write buffer, it sets watermarks. When enough data is buffered it triggers a call to
319
   * onAboveWriteBufferHighWatermark, which allows subscribers to enforce flow control by disabling
320
   * reads on the socket funneling data to the write buffer. When enough data is drained from the
321
   * write buffer, onBelowWriteBufferHighWatermark is called which similarly allows subscribers
322
   * resuming reading.
323
   */
324
  virtual void setBufferLimits(uint32_t limit) PURE;
325

            
326
  /**
327
   * Set the timeout when connection will be closed due to buffer high watermark usage. This is used
328
   * to prevent the connection from staying above the buffer high watermark indefinitely due to slow
329
   * processing. By default, the timeout is not set.
330
   * @param timeout The timeout value in milliseconds
331
   */
332
  virtual void setBufferHighWatermarkTimeout(std::chrono::milliseconds timeout) PURE;
333

            
334
  /**
335
   * Get the value set with setBufferLimits.
336
   */
337
  virtual uint32_t bufferLimit() const PURE;
338

            
339
  /**
340
   * @return boolean telling if the connection is currently above the high watermark.
341
   */
342
  virtual bool aboveHighWatermark() const PURE;
343

            
344
  /**
345
   * @return const ConnectionSocketPtr& reference to the socket from current connection.
346
   */
347
  virtual const ConnectionSocketPtr& getSocket() const PURE;
348

            
349
  /**
350
   * Get the socket options set on this connection.
351
   */
352
  virtual const ConnectionSocket::OptionsSharedPtr& socketOptions() const PURE;
353

            
354
  /**
355
   * Set a socket option on the underlying socket(s) of this connection.
356
   * @param option The socket option to set.
357
   * @return boolean telling if the socket option was set successfully.
358
   */
359
  virtual bool setSocketOption(Network::SocketOptionName name, absl::Span<uint8_t> value) PURE;
360
  /**
361
   * The StreamInfo object associated with this connection. This is typically
362
   * used for logging purposes. Individual filters may add specific information
363
   * via the FilterState object within the StreamInfo object. The StreamInfo
364
   * object in this context is one per connection i.e. different than the one in
365
   * the http ConnectionManager implementation which is one per request.
366
   *
367
   * @return StreamInfo object associated with this connection.
368
   */
369
  virtual StreamInfo::StreamInfo& streamInfo() PURE;
370
  virtual const StreamInfo::StreamInfo& streamInfo() const PURE;
371

            
372
  /**
373
   * Set the timeout for delayed connection close()s.
374
   * This can only be called prior to issuing a close() on the connection.
375
   * @param timeout The timeout value in milliseconds
376
   */
377
  virtual void setDelayedCloseTimeout(std::chrono::milliseconds timeout) PURE;
378

            
379
  /**
380
   * @return absl::string_view the failure reason of the underlying transport socket, if no failure
381
   *         occurred an empty string view is returned.
382
   */
383
  virtual absl::string_view transportFailureReason() const PURE;
384

            
385
  /**
386
   * @return absl::string_view the local close reason of the underlying socket, if local close
387
   *         did not occur an empty string view is returned.
388
   */
389
  virtual absl::string_view localCloseReason() const PURE;
390

            
391
  /**
392
   * Instructs the connection to start using secure transport.
393
   * Note: Not all underlying transport sockets support such operation.
394
   * @return boolean telling if underlying transport socket was able to
395
             start secure transport.
396
   */
397
  virtual bool startSecureTransport() PURE;
398

            
399
  /**
400
   *  @return absl::optional<std::chrono::milliseconds> An optional of the most recent round-trip
401
   *  time of the connection. If the platform does not support this, then an empty optional is
402
   *  returned.
403
   */
404
  virtual absl::optional<std::chrono::milliseconds> lastRoundTripTime() const PURE;
405

            
406
  /**
407
   * Try to configure the connection's initial congestion window.
408
   * The operation is advisory - the connection may not support it, even if it's supported, it may
409
   * not do anything after the first few network round trips with the peer.
410
   * @param bandwidth_bits_per_sec The estimated bandwidth between the two endpoints of the
411
   * connection.
412
   * @param rtt The estimated round trip time between the two endpoints of the connection.
413
   *
414
   * @note Envoy does not provide an implementation for TCP connections because
415
   * there is no portable system api to do so. Applications can implement it
416
   * with a proprietary api in a customized TransportSocket.
417
   */
418
  virtual void configureInitialCongestionWindow(uint64_t bandwidth_bits_per_sec,
419
                                                std::chrono::microseconds rtt) PURE;
420

            
421
  /**
422
   * @return the current congestion window in bytes, or unset if not available or not
423
   * congestion-controlled.
424
   * @note some congestion controller's cwnd is measured in number of packets, in that case the
425
   * return value is cwnd(in packets) times the connection's MSS.
426
   */
427
  virtual absl::optional<uint64_t> congestionWindowInBytes() const PURE;
428
};
429

            
430
using ConnectionPtr = std::unique_ptr<Connection>;
431

            
432
/**
433
 * Connections servicing inbound connects.
434
 */
435
class ServerConnection : public virtual Connection {
436
public:
437
  /**
438
   * Set the amount of time allowed for the transport socket to report that a connection is
439
   * established. The provided timeout is relative to the current time. If this method is called
440
   * after a connection has already been established, it is a no-op.
441
   *
442
   * If a timeout occurs, `timeout_stat` will be incremented.
443
   */
444
  virtual void setTransportSocketConnectTimeout(std::chrono::milliseconds timeout,
445
                                                Stats::Counter& timeout_stat) PURE;
446
};
447

            
448
using ServerConnectionPtr = std::unique_ptr<ServerConnection>;
449

            
450
/**
451
 * Connections capable of outbound connects.
452
 */
453
class ClientConnection : public virtual Connection {
454
public:
455
  /**
456
   * Connect to a remote host. Errors or connection events are reported via the event callback
457
   * registered via addConnectionCallbacks().
458
   */
459
  virtual void connect() PURE;
460
};
461

            
462
using ClientConnectionPtr = std::unique_ptr<ClientConnection>;
463

            
464
} // namespace Network
465
} // namespace Envoy