1
#pragma once
2

            
3
#include <memory>
4
#include <string>
5
#include <vector>
6

            
7
#include "envoy/common/optref.h"
8
#include "envoy/common/platform.h"
9
#include "envoy/common/pure.h"
10
#include "envoy/config/core/v3/base.pb.h"
11
#include "envoy/network/address.h"
12
#include "envoy/network/io_handle.h"
13
#include "envoy/ssl/connection.h"
14

            
15
#include "absl/strings/string_view.h"
16
#include "absl/types/optional.h"
17

            
18
namespace Envoy {
19
namespace Network {
20

            
21
// SocketOptionName is an optional value that captures the setsockopt(2)
22
// arguments. The idea here is that if a socket option is not supported
23
// on a platform, we can make this the empty value, which allows us to
24
// avoid #ifdef proliferation.
25
struct SocketOptionName {
26
30206
  SocketOptionName() = default;
27
  SocketOptionName(int level, int option, const std::string& name)
28
48194
      : value_(std::make_tuple(level, option, name)) {}
29

            
30
35131
  int level() const { return std::get<0>(value_.value()); }
31
35132
  int option() const { return std::get<1>(value_.value()); }
32
2
  const std::string& name() const { return std::get<2>(value_.value()); }
33

            
34
100527
  bool hasValue() const { return value_.has_value(); }
35
21
  bool operator==(const SocketOptionName& rhs) const { return value_ == rhs.value_; }
36

            
37
private:
38
  absl::optional<std::tuple<int, int, std::string>> value_;
39
};
40

            
41
// ENVOY_MAKE_SOCKET_OPTION_NAME is a helper macro to generate a
42
// SocketOptionName with a descriptive string name.
43
#define ENVOY_MAKE_SOCKET_OPTION_NAME(level, option)                                               \
44
47939
  ::Envoy::Network::SocketOptionName(level, option, #level "/" #option)
45

            
46
// Moved from source/common/network/socket_option_impl.h to avoid dependency loops.
47
#ifdef IP_TRANSPARENT
48
98
#define ENVOY_SOCKET_IP_TRANSPARENT ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_TRANSPARENT)
49
#else
50
#define ENVOY_SOCKET_IP_TRANSPARENT Network::SocketOptionName()
51
#endif
52

            
53
#ifdef IPV6_TRANSPARENT
54
69
#define ENVOY_SOCKET_IPV6_TRANSPARENT ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_TRANSPARENT)
55
#else
56
#define ENVOY_SOCKET_IPV6_TRANSPARENT Network::SocketOptionName()
57
#endif
58

            
59
#ifdef IP_FREEBIND
60
32
#define ENVOY_SOCKET_IP_FREEBIND ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_FREEBIND)
61
#else
62
#define ENVOY_SOCKET_IP_FREEBIND Network::SocketOptionName()
63
#endif
64

            
65
#ifdef IPV6_FREEBIND
66
27
#define ENVOY_SOCKET_IPV6_FREEBIND ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_FREEBIND)
67
#else
68
#define ENVOY_SOCKET_IPV6_FREEBIND Network::SocketOptionName()
69
#endif
70

            
71
#ifdef IP_RECVTOS
72
3128
#define ENVOY_SOCKET_IP_RECVTOS ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_RECVTOS)
73
#else
74
#define ENVOY_SOCKET_IP_RECVTOS Network::SocketOptionName()
75
#endif
76

            
77
#ifdef IPV6_RECVTCLASS
78
3128
#define ENVOY_SOCKET_IPV6_RECVTCLASS ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_RECVTCLASS)
79
#else
80
#define ENVOY_SOCKET_IPV6_RECVTCLASS Network::SocketOptionName()
81
#endif
82

            
83
#ifdef SO_KEEPALIVE
84
56
#define ENVOY_SOCKET_SO_KEEPALIVE ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_KEEPALIVE)
85
#else
86
#define ENVOY_SOCKET_SO_KEEPALIVE Network::SocketOptionName()
87
#endif
88

            
89
#ifdef SO_MARK
90
12
#define ENVOY_SOCKET_SO_MARK ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_MARK)
91
#else
92
#define ENVOY_SOCKET_SO_MARK Network::SocketOptionName()
93
#endif
94

            
95
#ifdef SO_NOSIGPIPE
96
#define ENVOY_SOCKET_SO_NOSIGPIPE ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_NOSIGPIPE)
97
#else
98
30100
#define ENVOY_SOCKET_SO_NOSIGPIPE Network::SocketOptionName()
99
#endif
100

            
101
#ifdef SO_REUSEPORT
102
10827
#define ENVOY_SOCKET_SO_REUSEPORT ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_REUSEPORT)
103
#else
104
#define ENVOY_SOCKET_SO_REUSEPORT Network::SocketOptionName()
105
#endif
106

            
107
#ifdef SO_ORIGINAL_DST
108
26
#define ENVOY_SOCKET_SO_ORIGINAL_DST ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_IP, SO_ORIGINAL_DST)
109
#else
110
#define ENVOY_SOCKET_SO_ORIGINAL_DST Network::SocketOptionName()
111
#endif
112

            
113
#ifdef IP6T_SO_ORIGINAL_DST
114
#define ENVOY_SOCKET_IP6T_SO_ORIGINAL_DST                                                          \
115
3
  ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_IPV6, IP6T_SO_ORIGINAL_DST)
116
#else
117
#define ENVOY_SOCKET_IP6T_SO_ORIGINAL_DST Network::SocketOptionName()
118
#endif
119

            
120
#ifdef UDP_GRO
121
4334
#define ENVOY_SOCKET_UDP_GRO ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_UDP, UDP_GRO)
122
#else
123
#define ENVOY_SOCKET_UDP_GRO Network::SocketOptionName()
124
#endif
125

            
126
#ifdef TCP_KEEPCNT
127
20
#define ENVOY_SOCKET_TCP_KEEPCNT ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPCNT)
128
#else
129
#define ENVOY_SOCKET_TCP_KEEPCNT Network::SocketOptionName()
130
#endif
131

            
132
#ifdef TCP_KEEPIDLE
133
19
#define ENVOY_SOCKET_TCP_KEEPIDLE ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPIDLE)
134
#elif TCP_KEEPALIVE // macOS uses a different name from Linux for just this option.
135
#define ENVOY_SOCKET_TCP_KEEPIDLE ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPALIVE)
136
#else
137
#define ENVOY_SOCKET_TCP_KEEPIDLE Network::SocketOptionName()
138
#endif
139

            
140
#ifdef TCP_KEEPINTVL
141
17
#define ENVOY_SOCKET_TCP_KEEPINTVL ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_KEEPINTVL)
142
#else
143
#define ENVOY_SOCKET_TCP_KEEPINTVL Network::SocketOptionName()
144
#endif
145

            
146
#ifdef TCP_FASTOPEN
147
7
#define ENVOY_SOCKET_TCP_FASTOPEN ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_TCP, TCP_FASTOPEN)
148
#else
149
#define ENVOY_SOCKET_TCP_FASTOPEN Network::SocketOptionName()
150
#endif
151

            
152
// Linux uses IP_PKTINFO for both sending source address and receiving destination
153
// address.
154
// FreeBSD uses IP_RECVDSTADDR for receiving destination address and IP_SENDSRCADDR for sending
155
// source address. And these two have same value for convenience purpose.
156
#ifdef IP_RECVDSTADDR
157
#ifdef IP_SENDSRCADDR
158
static_assert(IP_RECVDSTADDR == IP_SENDSRCADDR);
159
#endif
160
#define ENVOY_IP_PKTINFO IP_RECVDSTADDR
161
#elif IP_PKTINFO
162
8
#define ENVOY_IP_PKTINFO IP_PKTINFO
163
#endif
164

            
165
#ifdef IP_BIND_ADDRESS_NO_PORT
166
#define ENVOY_SOCKET_IP_BIND_ADDRESS_NO_PORT                                                       \
167
23
  ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT)
168
#else
169
#define ENVOY_SOCKET_IP_BIND_ADDRESS_NO_PORT Network::SocketOptionName()
170
#endif
171

            
172
5583
#define ENVOY_SELF_IP_ADDR ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, ENVOY_IP_PKTINFO)
173

            
174
// Both Linux and FreeBSD use IPV6_RECVPKTINFO for both sending source address and
175
// receiving destination address.
176
5583
#define ENVOY_SELF_IPV6_ADDR ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_RECVPKTINFO)
177

            
178
#ifdef SO_ATTACH_REUSEPORT_CBPF
179
#define ENVOY_ATTACH_REUSEPORT_CBPF                                                                \
180
13
  ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF)
181
#else
182
#define ENVOY_ATTACH_REUSEPORT_CBPF Network::SocketOptionName()
183
#endif
184

            
185
#if !defined(ANDROID) && defined(__APPLE__)
186
// Only include TargetConditionals after testing ANDROID as some Android builds
187
// on the Mac have this header available and it's not needed unless the target
188
// is really an Apple platform.
189
#include <TargetConditionals.h>
190
#if !defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE
191
// MAC_OS
192
#define ENVOY_IP_DONTFRAG ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_DONTFRAG)
193
#define ENVOY_IPV6_DONTFRAG ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_DONTFRAG)
194
#endif
195
#endif
196

            
197
#if !defined(ENVOY_IP_DONTFRAG) && defined(IP_PMTUDISC_DO)
198
4360
#define ENVOY_IP_MTU_DISCOVER ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IP, IP_MTU_DISCOVER)
199
4360
#define ENVOY_IP_MTU_DISCOVER_VALUE IP_PMTUDISC_DO
200
4359
#define ENVOY_IPV6_MTU_DISCOVER ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_MTU_DISCOVER)
201
4359
#define ENVOY_IPV6_MTU_DISCOVER_VALUE IPV6_PMTUDISC_DO
202
#endif
203

            
204
class FilterChainInfo;
205
class ListenerInfo;
206

            
207
using FilterChainInfoConstSharedPtr = std::shared_ptr<const FilterChainInfo>;
208

            
209
/**
210
 * Interfaces for providing a socket's various addresses. This is split into a getters interface
211
 * and a getters + setters interface. This is so that only the getters portion can be overridden
212
 * in certain cases.
213
 */
214
class ConnectionInfoProvider {
215
public:
216
282076
  virtual ~ConnectionInfoProvider() = default;
217

            
218
  /**
219
   * @return the local address of the socket.
220
   */
221
  virtual const Address::InstanceConstSharedPtr& localAddress() const PURE;
222

            
223
  /**
224
   * @return the direct local address of the socket. This is the listener address and it can not be
225
   * modified by listener filters.
226
   */
227
  virtual const Address::InstanceConstSharedPtr& directLocalAddress() const PURE;
228

            
229
  /**
230
   * @return true if the local address has been restored to a value that is different from the
231
   *         address the socket was initially accepted at.
232
   */
233
  virtual bool localAddressRestored() const PURE;
234

            
235
  /**
236
   * @return the remote address of the socket.
237
   */
238
  virtual const Address::InstanceConstSharedPtr& remoteAddress() const PURE;
239

            
240
  /**
241
   * @return the direct remote address of the socket. This is the address of the directly
242
   *         connected peer, and cannot be modified by listener filters.
243
   */
244
  virtual const Address::InstanceConstSharedPtr& directRemoteAddress() const PURE;
245

            
246
  /**
247
   * @return SNI value for downstream host.
248
   */
249
  virtual absl::string_view requestedServerName() const PURE;
250

            
251
  /**
252
   * @return requestedApplicationProtocols value for downstream host.
253
   */
254
  virtual const std::vector<std::string>& requestedApplicationProtocols() const PURE;
255

            
256
  /**
257
   * @return Connection ID of the downstream connection, or unset if not available.
258
   **/
259
  virtual absl::optional<uint64_t> connectionID() const PURE;
260

            
261
  /**
262
   * @return the name of the network interface used by local end of the connection, or unset if not
263
   *available.
264
   **/
265
  virtual absl::optional<absl::string_view> interfaceName() const PURE;
266

            
267
  /**
268
   * Dumps the state of the ConnectionInfoProvider to the given ostream.
269
   *
270
   * @param os the std::ostream to dump to.
271
   * @param indent_level the level of indentation.
272
   */
273
  virtual void dumpState(std::ostream& os, int indent_level) const PURE;
274

            
275
  /**
276
   * @return the downstream SSL connection. This will be nullptr if the downstream
277
   * connection does not use SSL.
278
   */
279
  virtual Ssl::ConnectionInfoConstSharedPtr sslConnection() const PURE;
280

            
281
  /**
282
   * @return ja3 fingerprint hash of the downstream connection, if any.
283
   */
284
  virtual absl::string_view ja3Hash() const PURE;
285

            
286
  /**
287
   * @return ja4 fingerprint hash of the downstream connection, if any.
288
   */
289
  virtual absl::string_view ja4Hash() const PURE;
290

            
291
  /**
292
   * @return roundTripTime of the connection
293
   */
294
  virtual const absl::optional<std::chrono::milliseconds>& roundTripTime() const PURE;
295

            
296
  /**
297
   * @return the filter chain info provider backing this socket.
298
   */
299
  virtual OptRef<const FilterChainInfo> filterChainInfo() const PURE;
300

            
301
  /**
302
   * @return the listener info backing this socket.
303
   */
304
  virtual OptRef<const ListenerInfo> listenerInfo() const PURE;
305
};
306

            
307
class ConnectionInfoSetter : public ConnectionInfoProvider {
308
public:
309
  /**
310
   * Set the local address of the socket. On accepted sockets the local address defaults to the
311
   * one at which the connection was received at, which is the same as the listener's address, if
312
   * the listener is bound to a specific address.
313
   *
314
   * @param local_address the new local address.
315
   */
316
  virtual void setLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE;
317

            
318
  /**
319
   * Restores the local address of the socket. On accepted sockets the local address defaults to the
320
   * one at which the connection was received at, which is the same as the listener's address, if
321
   * the listener is bound to a specific address. Call this to restore the address to a value
322
   * different from the one the socket was initially accepted at. This should only be called when
323
   * restoring the original destination address of a connection redirected by iptables REDIRECT. The
324
   * caller is responsible for making sure the new address is actually different.
325
   *
326
   * @param local_address the new local address.
327
   */
328
  virtual void restoreLocalAddress(const Address::InstanceConstSharedPtr& local_address) PURE;
329

            
330
  /**
331
   * Set the remote address of the socket.
332
   */
333
  virtual void setRemoteAddress(const Address::InstanceConstSharedPtr& remote_address) PURE;
334

            
335
  /**
336
   * @param SNI value requested.
337
   */
338
  virtual void setRequestedServerName(const absl::string_view requested_server_name) PURE;
339

            
340
  /**
341
   * @param protocols Application protocols requested.
342
   */
343
  virtual void
344
  setRequestedApplicationProtocols(const std::vector<absl::string_view>& protocols) PURE;
345

            
346
  /**
347
   * @param id Connection ID of the downstream connection.
348
   **/
349
  virtual void setConnectionID(uint64_t id) PURE;
350

            
351
  /**
352
   * @param enable whether to enable or disable setting interface name. While having an interface
353
   *               name might be helpful for debugging, it might come at a performance cost.
354
   */
355
  virtual void enableSettingInterfaceName(const bool enable) PURE;
356

            
357
  /**
358
   * @param interface_name the name of the network interface used by the local end of the
359
   *connection.
360
   **/
361
  virtual void maybeSetInterfaceName(IoHandle& io_handle) PURE;
362

            
363
  /**
364
   * @param connection_info sets the downstream ssl connection.
365
   */
366
  virtual void setSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) PURE;
367

            
368
  /**
369
   * @param JA3 fingerprint.
370
   */
371
  virtual void setJA3Hash(const absl::string_view ja3_hash) PURE;
372

            
373
  /**
374
   * @param JA4 fingerprint.
375
   */
376
  virtual void setJA4Hash(const absl::string_view ja4_hash) PURE;
377

            
378
  /**
379
   * @param  milliseconds of round trip time of previous connection
380
   */
381
  virtual void setRoundTripTime(std::chrono::milliseconds round_trip_time) PURE;
382

            
383
  /**
384
   * @param filter_chain_info the filter chain info provider backing this socket.
385
   */
386
  virtual void setFilterChainInfo(FilterChainInfoConstSharedPtr filter_chain_info) PURE;
387

            
388
  /**
389
   * @param listener_info the listener info provider backing this socket.
390
   */
391
  virtual void setListenerInfo(std::shared_ptr<const ListenerInfo> listener_info) PURE;
392
};
393

            
394
using ConnectionInfoSetterSharedPtr = std::shared_ptr<ConnectionInfoSetter>;
395
using ConnectionInfoProviderSharedPtr = std::shared_ptr<const ConnectionInfoProvider>;
396

            
397
/**
398
 * Base class for Sockets
399
 */
400
class Socket {
401
public:
402
203962
  virtual ~Socket() = default;
403

            
404
  /**
405
   * Type of sockets supported. See man 2 socket for more details
406
   */
407
  enum class Type { Stream, Datagram };
408

            
409
  /**
410
   * @return the connection info provider backing this socket.
411
   */
412
  virtual ConnectionInfoSetter& connectionInfoProvider() PURE;
413
  virtual const ConnectionInfoProvider& connectionInfoProvider() const PURE;
414
  virtual ConnectionInfoProviderSharedPtr connectionInfoProviderSharedPtr() const PURE;
415

            
416
  /**
417
   * @return IoHandle for the underlying connection
418
   */
419
  virtual IoHandle& ioHandle() PURE;
420

            
421
  /**
422
   * @return const IoHandle for the underlying connection
423
   */
424
  virtual const IoHandle& ioHandle() const PURE;
425

            
426
  /**
427
   * Used to duplicate the underlying file descriptor of the socket.
428
   * @return a pointer to the new Socket.
429
   */
430
  virtual std::unique_ptr<Socket> duplicate() PURE;
431

            
432
  /**
433
   * @return the type (stream or datagram) of the socket.
434
   */
435
  virtual Socket::Type socketType() const PURE;
436

            
437
  /**
438
   * @return the type (IP or pipe) of addresses used by the socket (subset of socket domain)
439
   */
440
  virtual Address::Type addressType() const PURE;
441

            
442
  /**
443
   * @return the IP version used by the socket if address type is IP, absl::nullopt otherwise
444
   */
445
  virtual absl::optional<Address::IpVersion> ipVersion() const PURE;
446

            
447
  /**
448
   * Close the underlying socket.
449
   */
450
  virtual void close() PURE;
451

            
452
  /**
453
   * Return true if close() hasn't been called.
454
   */
455
  virtual bool isOpen() const PURE;
456

            
457
  /**
458
   * Bind a socket to this address. The socket should have been created with a call to socket()
459
   * @param address address to bind the socket to.
460
   * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
461
   *   is successful, errno_ shouldn't be used.
462
   */
463
  virtual Api::SysCallIntResult bind(const Address::InstanceConstSharedPtr address) PURE;
464

            
465
  /**
466
   * Listen on bound socket.
467
   * @param backlog maximum number of pending connections for listener
468
   * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
469
   *   is successful, errno_ shouldn't be used.
470
   */
471
  virtual Api::SysCallIntResult listen(int backlog) PURE;
472

            
473
  /**
474
   * Connect a socket to this address. The socket should have been created with a call to socket()
475
   * on this object.
476
   * @param address remote address to connect to.
477
   * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
478
   *   is successful, errno_ shouldn't be used.
479
   */
480
  virtual Api::SysCallIntResult connect(const Address::InstanceConstSharedPtr address) PURE;
481

            
482
  /**
483
   * @see MSDN WSAIoctl. Controls the mode of a socket.
484
   */
485
  virtual Api::SysCallIntResult ioctl(unsigned long control_code, void* in_buffer,
486
                                      unsigned long in_buffer_len, void* out_buffer,
487
                                      unsigned long out_buffer_len,
488
                                      unsigned long* bytes_returned) PURE;
489

            
490
  /**
491
   * Propagates option to underlying socket (@see man 2 setsockopt)
492
   */
493
  virtual Api::SysCallIntResult setSocketOption(int level, int optname, const void* optval,
494
                                                socklen_t optlen) PURE;
495

            
496
  /**
497
   * Retrieves option from underlying socket (@see man 2 getsockopt)
498
   */
499
  virtual Api::SysCallIntResult getSocketOption(int level, int optname, void* optval,
500
                                                socklen_t* optlen) const PURE;
501

            
502
  /**
503
   * Toggle socket blocking state
504
   */
505
  virtual Api::SysCallIntResult setBlockingForTest(bool blocking) PURE;
506

            
507
  /**
508
   * Visitor class for setting socket options.
509
   */
510
  class Option {
511
  public:
512
61111
    virtual ~Option() = default;
513

            
514
    /**
515
     * @param socket the socket on which to apply options.
516
     * @param state the current state of the socket. Significant for options that can only be
517
     *        set for some particular state of the socket.
518
     * @return true if succeeded, false otherwise.
519
     */
520
    virtual bool setOption(Socket& socket,
521
                           envoy::config::core::v3::SocketOption::SocketState state) const PURE;
522

            
523
    /**
524
     * @param vector of bytes to which the option should append hash key data that will be used
525
     *        to separate connections based on the option. Any data already in the key vector must
526
     *        not be modified.
527
     */
528
    virtual void hashKey(std::vector<uint8_t>& key) const PURE;
529

            
530
    /**
531
     * Contains details about what this option applies to a socket.
532
     */
533
    struct Details {
534
      SocketOptionName name_;
535
      std::string value_; ///< Binary string representation of an option's value.
536

            
537
7
      bool operator==(const Details& other) const {
538
7
        return name_ == other.name_ && value_ == other.value_;
539
7
      }
540
    };
541

            
542
    /**
543
     * @param socket The socket for which we want to know the options that would be applied.
544
     * @param state The state at which we would apply the options.
545
     * @return What we would apply to the socket at the provided state. Empty if we'd apply nothing.
546
     */
547
    virtual absl::optional<Details>
548
    getOptionDetails(const Socket& socket,
549
                     envoy::config::core::v3::SocketOption::SocketState state) const PURE;
550

            
551
    /**
552
     * Whether the socket implementation is supported. Real implementations should typically return
553
     * true. Placeholder implementations may indicate such by returning false. Note this does NOT
554
     * inherently prevent an option from being applied if it's passed to socket/connection
555
     * interfaces.
556
     * @return Whether this is a supported socket option.
557
     */
558
    virtual bool isSupported() const PURE;
559
  };
560

            
561
  using OptionConstPtr = std::unique_ptr<const Option>;
562
  using OptionConstSharedPtr = std::shared_ptr<const Option>;
563
  using Options = std::vector<OptionConstSharedPtr>;
564
  using OptionsSharedPtr = std::shared_ptr<Options>;
565

            
566
201087
  static OptionsSharedPtr& appendOptions(OptionsSharedPtr& to, const OptionsSharedPtr& from) {
567
201087
    to->insert(to->end(), from->begin(), from->end());
568
201087
    return to;
569
201087
  }
570

            
571
  static bool applyOptions(const OptionsSharedPtr& options, Socket& socket,
572
127197
                           envoy::config::core::v3::SocketOption::SocketState state) {
573
127197
    if (options == nullptr) {
574
41581
      return true;
575
41581
    }
576
125809
    for (const auto& option : *options) {
577
92494
      if (!option->setOption(socket, state)) {
578
12
        return false;
579
12
      }
580
92494
    }
581
85604
    return true;
582
85616
  }
583

            
584
  /**
585
   * Add a socket option visitor for later retrieval with options().
586
   */
587
  virtual void addOption(const OptionConstSharedPtr&) PURE;
588

            
589
  /**
590
   * Add socket option visitors for later retrieval with options().
591
   */
592
  virtual void addOptions(const OptionsSharedPtr&) PURE;
593

            
594
  /**
595
   * @return the socket options stored earlier with addOption() and addOptions() calls, if any.
596
   */
597
  virtual const OptionsSharedPtr& options() const PURE;
598

            
599
  /**
600
   * @return a ParentDrainedCallbackRegistrar for UDP listen sockets during hot restart.
601
   */
602
4
  virtual OptRef<class ParentDrainedCallbackRegistrar> parentDrainedCallbackRegistrar() const {
603
4
    return absl::nullopt;
604
4
  }
605
};
606

            
607
using SocketPtr = std::unique_ptr<Socket>;
608
using SocketSharedPtr = std::shared_ptr<Socket>;
609
using SocketOptRef = absl::optional<std::reference_wrapper<Socket>>;
610

            
611
} // namespace Network
612
} // namespace Envoy