1
#pragma once
2

            
3
#include <chrono>
4
#include <cstdint>
5
#include <functional>
6
#include <list>
7
#include <memory>
8
#include <string>
9
#include <vector>
10

            
11
#include "envoy/common/callback.h"
12
#include "envoy/common/optref.h"
13
#include "envoy/config/cluster/v3/cluster.pb.h"
14
#include "envoy/config/core/v3/base.pb.h"
15
#include "envoy/config/core/v3/protocol.pb.h"
16
#include "envoy/config/typed_metadata.h"
17
#include "envoy/http/codec.h"
18
#include "envoy/http/filter_factory.h"
19
#include "envoy/http/header_validator.h"
20
#include "envoy/network/connection.h"
21
#include "envoy/network/transport_socket.h"
22
#include "envoy/ssl/context.h"
23
#include "envoy/stats/scope.h"
24
#include "envoy/stats/stats.h"
25
#include "envoy/upstream/health_check_host_monitor.h"
26
#include "envoy/upstream/locality.h"
27
#include "envoy/upstream/outlier_detection.h"
28
#include "envoy/upstream/resource_manager.h"
29
#include "envoy/upstream/types.h"
30

            
31
#include "absl/strings/string_view.h"
32
#include "absl/types/optional.h"
33
#include "fmt/format.h"
34

            
35
namespace Envoy {
36
namespace Http {
37
class FilterChainManager;
38
class HashPolicy;
39
} // namespace Http
40

            
41
namespace Router {
42
class ShadowPolicy;
43
using ShadowPolicyPtr = std::shared_ptr<ShadowPolicy>;
44
class RetryPolicy;
45
} // namespace Router
46

            
47
namespace Upstream {
48

            
49
/**
50
 * A bundle struct for address and socket options.
51
 */
52
struct UpstreamLocalAddress {
53
public:
54
  Network::Address::InstanceConstSharedPtr address_;
55
  Network::ConnectionSocket::OptionsSharedPtr socket_options_;
56
};
57

            
58
/**
59
 * Interface to select upstream local address based on the endpoint address.
60
 */
61
class UpstreamLocalAddressSelector {
62
public:
63
246455
  virtual ~UpstreamLocalAddressSelector() = default;
64

            
65
  /**
66
   * Return UpstreamLocalAddress based on the endpoint address.
67
   * @param endpoint_address is the address used to select upstream local address.
68
   * @param socket_options applied to the selected address.
69
   * @param transport_socket_options transport-level options applied to the connection.
70
   * @return UpstreamLocalAddress which includes the selected upstream local address and socket
71
   * options.
72
   */
73
  virtual UpstreamLocalAddress getUpstreamLocalAddress(
74
      const Network::Address::InstanceConstSharedPtr& endpoint_address,
75
      const Network::ConnectionSocket::OptionsSharedPtr& socket_options,
76
      OptRef<const Network::TransportSocketOptions> transport_socket_options) const PURE;
77
};
78

            
79
class UpstreamLocalAddressSelectorBase : public UpstreamLocalAddressSelector {
80
public:
81
246443
  ~UpstreamLocalAddressSelectorBase() override = default;
82

            
83
  UpstreamLocalAddress getUpstreamLocalAddress(
84
      const Network::Address::InstanceConstSharedPtr& endpoint_address,
85
      const Network::ConnectionSocket::OptionsSharedPtr& socket_options,
86
31629
      OptRef<const Network::TransportSocketOptions> transport_socket_options) const override {
87
31629
    UpstreamLocalAddress local_address =
88
31629
        getUpstreamLocalAddressImpl(endpoint_address, transport_socket_options);
89
31629
    Network::ConnectionSocket::OptionsSharedPtr connection_options =
90
31629
        std::make_shared<Network::ConnectionSocket::Options>(
91
31629
            socket_options ? *socket_options
92
31629
                           : std::vector<Network::ConnectionSocket::OptionConstSharedPtr>{});
93
31629
    return {local_address.address_,
94
31629
            local_address.socket_options_ != nullptr
95
31629
                ? Network::Socket::appendOptions(connection_options, local_address.socket_options_)
96
31629
                : connection_options};
97
31629
  }
98

            
99
private:
100
  /*
101
   * The implementation is responsible for picking the ``UpstreamLocalAddress``
102
   * based on the ``endpoint_address``. However adding the connection socket
103
   * options is the responsibility of the base class.
104
   */
105
  virtual UpstreamLocalAddress getUpstreamLocalAddressImpl(
106
      const Network::Address::InstanceConstSharedPtr& endpoint_address,
107
      OptRef<const Network::TransportSocketOptions> transport_socket_options) const PURE;
108
};
109

            
110
using UpstreamLocalAddressSelectorConstSharedPtr =
111
    std::shared_ptr<const UpstreamLocalAddressSelector>;
112

            
113
class UpstreamLocalAddressSelectorFactory : public Config::TypedFactory {
114
public:
115
3
  ~UpstreamLocalAddressSelectorFactory() override = default;
116

            
117
  /**
118
   * @param cluster_name is set to the name of the cluster if ``bind_config`` is
119
   *   from cluster config. If the bind config from the cluster manager, the param
120
   *   is empty.
121
   */
122
  virtual absl::StatusOr<UpstreamLocalAddressSelectorConstSharedPtr>
123
  createLocalAddressSelector(std::vector<UpstreamLocalAddress> upstream_local_addresses,
124
                             absl::optional<std::string> cluster_name) const PURE;
125

            
126
2625
  std::string category() const override { return "envoy.upstream.local_address_selector"; }
127
};
128

            
129
/**
130
 * RAII handle for tracking the host usage by the connection pools.
131
 **/
132
class HostHandle {
133
public:
134
12553
  virtual ~HostHandle() = default;
135
};
136

            
137
using HostHandlePtr = std::unique_ptr<HostHandle>;
138

            
139
/**
140
 * An upstream host.
141
 */
142
class Host : virtual public HostDescription {
143
public:
144
  struct CreateConnectionData {
145
    Network::ClientConnectionPtr connection_;
146
    HostDescriptionConstSharedPtr host_description_;
147
  };
148

            
149
  // We use an X-macro here to make it easier to verify that all the enum values are accounted for.
150
  // clang-format off
151
#define HEALTH_FLAG_ENUM_VALUES(m)                                               \
152
  /* The host is currently failing active health checks. */                      \
153
17
  m(FAILED_ACTIVE_HC, 0x1)                                                       \
154
10
  /* The host is currently considered an outlier and has been ejected. */        \
155
17
  m(FAILED_OUTLIER_CHECK, 0x02)                                                  \
156
10
  /* The host is currently marked as unhealthy by EDS. */                        \
157
17
  m(FAILED_EDS_HEALTH, 0x04)                                                     \
158
10
  /* The host is currently marked as degraded through active health checking. */ \
159
17
  m(DEGRADED_ACTIVE_HC, 0x08)                                                    \
160
10
  /* The host is currently marked as degraded by EDS. */                         \
161
17
  m(DEGRADED_EDS_HEALTH, 0x10)                                                   \
162
10
  /* The host is pending removal from discovery but is stabilized due to */      \
163
10
  /* active HC. */                                                               \
164
17
  m(PENDING_DYNAMIC_REMOVAL, 0x20)                                               \
165
10
  /* The host is pending its initial active health check. */                     \
166
17
  m(PENDING_ACTIVE_HC, 0x40)                                                     \
167
10
  /* The host should be excluded from panic, spillover, etc. calculations */     \
168
10
  /* because it was explicitly taken out of rotation via protocol signal and */  \
169
10
  /* is not meant to be routed to. */                                            \
170
17
  m(EXCLUDED_VIA_IMMEDIATE_HC_FAIL, 0x80)                                        \
171
10
  /* The host failed active HC due to timeout. */                                \
172
17
  m(ACTIVE_HC_TIMEOUT, 0x100)                                                    \
173
10
  /* The host is currently marked as draining by EDS */                          \
174
17
  m(EDS_STATUS_DRAINING, 0x200)                                                  \
175
10
  /* The host is currently marked as degraded by outlier detection */            \
176
17
  m(DEGRADED_OUTLIER_DETECTION, 0x400)
177
  // clang-format on
178

            
179
#define DECLARE_ENUM(name, value) name = value,
180

            
181
  enum class HealthFlag { HEALTH_FLAG_ENUM_VALUES(DECLARE_ENUM) };
182

            
183
#undef DECLARE_ENUM
184

            
185
  /**
186
   * @return host specific counters.
187
   */
188
  virtual std::vector<std::pair<absl::string_view, Stats::PrimitiveCounterReference>>
189
  counters() const PURE;
190

            
191
  /**
192
   * Create a connection for this host.
193
   * @param dispatcher supplies the owning dispatcher.
194
   * @param options supplies the socket options that will be set on the new connection.
195
   * @param transport_socket_options supplies the transport options that will be set on the new
196
   * connection.
197
   * @return the connection data which includes the raw network connection as well as the *real*
198
   *         host that backs it. The reason why a 2nd host is returned is that some hosts are
199
   *         logical and wrap multiple real network destinations. In this case, a different host
200
   *         will be returned along with the connection vs. the host the method was called on.
201
   *         If it matters, callers should not assume that the returned host will be the same.
202
   */
203
  virtual CreateConnectionData createConnection(
204
      Event::Dispatcher& dispatcher, const Network::ConnectionSocket::OptionsSharedPtr& options,
205
      Network::TransportSocketOptionsConstSharedPtr transport_socket_options) const PURE;
206

            
207
  /**
208
   * Create a health check connection for this host.
209
   * @param dispatcher supplies the owning dispatcher.
210
   * @param transport_socket_options supplies the transport options that will be set on the new
211
   * connection.
212
   * @return the connection data.
213
   */
214
  virtual CreateConnectionData createHealthCheckConnection(
215
      Event::Dispatcher& dispatcher,
216
      Network::TransportSocketOptionsConstSharedPtr transport_socket_options,
217
      const envoy::config::core::v3::Metadata* metadata) const PURE;
218

            
219
  /**
220
   * @return host specific gauges.
221
   */
222
  virtual std::vector<std::pair<absl::string_view, Stats::PrimitiveGaugeReference>>
223
  gauges() const PURE;
224

            
225
  /**
226
   * Atomically clear a health flag for a host. Flags are specified in HealthFlags.
227
   */
228
  virtual void healthFlagClear(HealthFlag flag) PURE;
229

            
230
  /**
231
   * Atomically get whether a health flag is set for a host. Flags are specified in HealthFlags.
232
   */
233
  virtual bool healthFlagGet(HealthFlag flag) const PURE;
234

            
235
  /**
236
   * Atomically set a health flag for a host. Flags are specified in HealthFlags.
237
   */
238
  virtual void healthFlagSet(HealthFlag flag) PURE;
239

            
240
  /**
241
   * Atomically get multiple health flags that are set for a host. Flags are specified
242
   * as a bitset of HealthFlags.
243
   */
244
  virtual uint32_t healthFlagsGetAll() const PURE;
245

            
246
  /**
247
   * Atomically set the health flag for a host. Flags are specified as a bitset
248
   * of HealthFlags.
249
   */
250
  virtual void healthFlagsSetAll(uint32_t bits) PURE;
251

            
252
  enum class Health {
253
    /**
254
     * Host is unhealthy and is not able to serve traffic. A host may be marked as unhealthy either
255
     * through EDS or through active health checking.
256
     */
257
    Unhealthy,
258
    /**
259
     * Host is healthy, but degraded. It is able to serve traffic, but hosts that aren't degraded
260
     * should be preferred. A host may be marked as degraded either through EDS or through active
261
     * health checking.
262
     */
263
    Degraded,
264
    /**
265
     * Host is healthy and is able to serve traffic.
266
     */
267
    Healthy,
268
  };
269

            
270
  /**
271
   * @return the coarse health status of the host.
272
   */
273
  virtual Health coarseHealth() const PURE;
274

            
275
  using HealthStatus = envoy::config::core::v3::HealthStatus;
276

            
277
  /**
278
   * @return more specific health status of host. This status is hybrid of EDS status and runtime
279
   * active status (from active health checker or outlier detection). Active status will be taken as
280
   * a priority.
281
   */
282
  virtual HealthStatus healthStatus() const PURE;
283

            
284
  /**
285
   * Set the EDS health status of the host. This is used when the host status is updated via EDS.
286
   */
287
  virtual void setEdsHealthStatus(HealthStatus health_status) PURE;
288

            
289
  /**
290
   * @return the EDS health status of the host.
291
   */
292
  virtual HealthStatus edsHealthStatus() const PURE;
293

            
294
  /**
295
   * @return the current load balancing weight of the host, in the range 1-128 (see
296
   * envoy.api.v2.endpoint.Endpoint.load_balancing_weight).
297
   */
298
  virtual uint32_t weight() const PURE;
299

            
300
  /**
301
   * Set the current load balancing weight of the host, in the range 1-128 (see
302
   * envoy.api.v2.endpoint.Endpoint.load_balancing_weight).
303
   */
304
  virtual void weight(uint32_t new_weight) PURE;
305

            
306
  /**
307
   * @return the current boolean value of host being in use by any connection pool.
308
   */
309
  virtual bool used() const PURE;
310

            
311
  /**
312
   * Creates a handle for a host. Deletion of the handle signals that the
313
   * connection pools no longer need this host.
314
   */
315
  virtual HostHandlePtr acquireHandle() const PURE;
316

            
317
  /**
318
   * @return true if active health check is disabled.
319
   */
320
  virtual bool disableActiveHealthCheck() const PURE;
321

            
322
  /**
323
   * Set true to disable active health check for the host.
324
   */
325
  virtual void setDisableActiveHealthCheck(bool disable_active_health_check) PURE;
326
};
327

            
328
using HostConstSharedPtr = std::shared_ptr<const Host>;
329

            
330
using HostVector = std::vector<HostSharedPtr>;
331
using HealthyHostVector = Phantom<HostVector, Healthy>;
332
using DegradedHostVector = Phantom<HostVector, Degraded>;
333
using ExcludedHostVector = Phantom<HostVector, Excluded>;
334
using HostMap = absl::flat_hash_map<std::string, Upstream::HostSharedPtr>;
335
using HostMapSharedPtr = std::shared_ptr<HostMap>;
336
using HostMapConstSharedPtr = std::shared_ptr<const HostMap>;
337
using HostVectorSharedPtr = std::shared_ptr<HostVector>;
338
using HostVectorConstSharedPtr = std::shared_ptr<const HostVector>;
339

            
340
using HealthyHostVectorConstSharedPtr = std::shared_ptr<const HealthyHostVector>;
341
using DegradedHostVectorConstSharedPtr = std::shared_ptr<const DegradedHostVector>;
342
using ExcludedHostVectorConstSharedPtr = std::shared_ptr<const ExcludedHostVector>;
343

            
344
using HostListPtr = std::unique_ptr<HostVector>;
345
using LocalityWeightsMap =
346
    absl::node_hash_map<envoy::config::core::v3::Locality, uint32_t, LocalityHash, LocalityEqualTo>;
347
using PriorityState = std::vector<std::pair<HostListPtr, LocalityWeightsMap>>;
348

            
349
/**
350
 * Bucket hosts by locality.
351
 */
352
class HostsPerLocality {
353
public:
354
254532
  virtual ~HostsPerLocality() = default;
355

            
356
  /**
357
   * @return bool is local locality one of the locality buckets? If so, the
358
   *         local locality will be the first in the get() vector.
359
   */
360
  virtual bool hasLocalLocality() const PURE;
361

            
362
  /**
363
   * @return const std::vector<HostVector>& list of hosts organized per
364
   *         locality. The local locality is the first entry if
365
   *         hasLocalLocality() is true. All hosts within the same entry have the same locality
366
   *         and all hosts with a given locality are in the same entry. With the exception of
367
   *         the local locality entry (if present), all entries are sorted by locality with
368
   *         those considered less by the LocalityLess comparator ordered earlier in the list.
369
   */
370
  virtual const std::vector<HostVector>& get() const PURE;
371

            
372
  /**
373
   * Clone object with multiple filter predicates. Returns a vector of clones, each with host that
374
   * match the provided predicates.
375
   * @param predicates vector of predicates on Host entries.
376
   * @return vector of HostsPerLocalityConstSharedPtr clones of the HostsPerLocality that match
377
   *         hosts according to predicates.
378
   */
379
  virtual std::vector<std::shared_ptr<const HostsPerLocality>>
380
  filter(const std::vector<std::function<bool(const Host&)>>& predicates) const PURE;
381

            
382
  /**
383
   * Clone object.
384
   * @return HostsPerLocalityConstSharedPtr clone of the HostsPerLocality.
385
   */
386
101
  std::shared_ptr<const HostsPerLocality> clone() const {
387
125
    return filter({[](const Host&) { return true; }})[0];
388
101
  }
389
};
390

            
391
using HostsPerLocalitySharedPtr = std::shared_ptr<HostsPerLocality>;
392
using HostsPerLocalityConstSharedPtr = std::shared_ptr<const HostsPerLocality>;
393

            
394
// Weight for each locality index in HostsPerLocality.
395
using LocalityWeights = std::vector<uint32_t>;
396
using LocalityWeightsSharedPtr = std::shared_ptr<LocalityWeights>;
397
using LocalityWeightsConstSharedPtr = std::shared_ptr<const LocalityWeights>;
398

            
399
/**
400
 * Base host set interface. This contains all of the endpoints for a given LocalityLbEndpoints
401
 * priority level.
402
 */
403
// TODO(snowp): Remove the const ref accessors in favor of the shared_ptr ones.
404
class HostSet {
405
public:
406
97932
  virtual ~HostSet() = default;
407

            
408
  /**
409
   * @return all hosts that make up the set at the current time.
410
   */
411
  virtual const HostVector& hosts() const PURE;
412

            
413
  /**
414
   * @return a shared ptr to the vector returned by hosts().
415
   */
416
  virtual HostVectorConstSharedPtr hostsPtr() const PURE;
417

            
418
  /**
419
   * @return all healthy hosts contained in the set at the current time. NOTE: This set is
420
   *         eventually consistent. There is a time window where a host in this set may become
421
   *         unhealthy and calling healthy() on it will return false. Code should be written to
422
   *         deal with this case if it matters.
423
   */
424
  virtual const HostVector& healthyHosts() const PURE;
425

            
426
  /**
427
   * @return a shared ptr to the vector returned by healthyHosts().
428
   */
429
  virtual HealthyHostVectorConstSharedPtr healthyHostsPtr() const PURE;
430

            
431
  /**
432
   * @return all degraded hosts contained in the set at the current time. NOTE: This set is
433
   *         eventually consistent. There is a time window where a host in this set may become
434
   *         undegraded and calling degraded() on it will return false. Code should be written to
435
   *         deal with this case if it matters.
436
   */
437
  virtual const HostVector& degradedHosts() const PURE;
438

            
439
  /**
440
   * @return a shared ptr to the vector returned by degradedHosts().
441
   */
442
  virtual DegradedHostVectorConstSharedPtr degradedHostsPtr() const PURE;
443

            
444
  /*
445
   * @return all excluded hosts contained in the set at the current time. Excluded hosts should be
446
   * ignored when computing load balancing weights, but may overlap with hosts in hosts().
447
   */
448
  virtual const HostVector& excludedHosts() const PURE;
449

            
450
  /**
451
   * @return a shared ptr to the vector returned by excludedHosts().
452
   */
453
  virtual ExcludedHostVectorConstSharedPtr excludedHostsPtr() const PURE;
454

            
455
  /**
456
   * @return hosts per locality.
457
   */
458
  virtual const HostsPerLocality& hostsPerLocality() const PURE;
459

            
460
  /**
461
   * @return a shared ptr to the HostsPerLocality returned by hostsPerLocality().
462
   */
463
  virtual HostsPerLocalityConstSharedPtr hostsPerLocalityPtr() const PURE;
464

            
465
  /**
466
   * @return same as hostsPerLocality but only contains healthy hosts.
467
   */
468
  virtual const HostsPerLocality& healthyHostsPerLocality() const PURE;
469

            
470
  /**
471
   * @return a shared ptr to the HostsPerLocality returned by healthyHostsPerLocality().
472
   */
473
  virtual HostsPerLocalityConstSharedPtr healthyHostsPerLocalityPtr() const PURE;
474

            
475
  /**
476
   * @return same as hostsPerLocality but only contains degraded hosts.
477
   */
478
  virtual const HostsPerLocality& degradedHostsPerLocality() const PURE;
479

            
480
  /**
481
   * @return a shared ptr to the HostsPerLocality returned by degradedHostsPerLocality().
482
   */
483
  virtual HostsPerLocalityConstSharedPtr degradedHostsPerLocalityPtr() const PURE;
484

            
485
  /**
486
   * @return same as hostsPerLocality but only contains excluded hosts.
487
   */
488
  virtual const HostsPerLocality& excludedHostsPerLocality() const PURE;
489

            
490
  /**
491
   * @return a shared ptr to the HostsPerLocality returned by excludedHostsPerLocality().
492
   */
493
  virtual HostsPerLocalityConstSharedPtr excludedHostsPerLocalityPtr() const PURE;
494

            
495
  /**
496
   * @return weights for each locality in the host set.
497
   */
498
  virtual LocalityWeightsConstSharedPtr localityWeights() const PURE;
499

            
500
  /**
501
   * @return uint32_t the priority of this host set.
502
   */
503
  virtual uint32_t priority() const PURE;
504

            
505
  /**
506
   * @return uint32_t the overprovisioning factor of this host set.
507
   */
508
  virtual uint32_t overprovisioningFactor() const PURE;
509

            
510
  /**
511
   * @return true to use host weights to calculate the health of a priority.
512
   */
513
  virtual bool weightedPriorityHealth() const PURE;
514
};
515

            
516
using HostSetPtr = std::unique_ptr<HostSet>;
517

            
518
/**
519
 * This class contains all of the HostSets for a given cluster grouped by priority, for
520
 * ease of load balancing.
521
 */
522
class PrioritySet {
523
public:
524
  using MemberUpdateCb =
525
      std::function<void(const HostVector& hosts_added, const HostVector& hosts_removed)>;
526

            
527
  using PriorityUpdateCb = std::function<void(uint32_t priority, const HostVector& hosts_added,
528
                                              const HostVector& hosts_removed)>;
529

            
530
97223
  virtual ~PrioritySet() = default;
531

            
532
  /**
533
   * Install a callback that will be invoked when anything on any host in the PrioritySet is
534
   * changed.
535
   *
536
   * hosts_added and hosts_removed will only be populated when a host is added or
537
   * completely removed from the PrioritySet. This includes when a new HostSet is created.
538
   *
539
   * @param callback supplies the callback to invoke.
540
   * @return Common::CallbackHandlePtr a handle which unregisters the callback upon its destruction.
541
   */
542
  ABSL_MUST_USE_RESULT virtual Common::CallbackHandlePtr
543
  addMemberUpdateCb(MemberUpdateCb callback) const PURE;
544

            
545
  /**
546
   * Install a callback that will be invoked when a host changes. Triggers when any change
547
   * happens to the hosts within that priority, and is invoked once for each priority that has a
548
   * change.
549
   *
550
   * If hosts are added/removed from the host set, the added/removed hosts will be passed to
551
   * the callback.
552
   *
553
   * @param callback supplies the callback to invoke.
554
   * @return Common::CallbackHandlePtr a handle which unregisters the callback upon its destruction.
555
   */
556
  ABSL_MUST_USE_RESULT virtual Common::CallbackHandlePtr
557
  addPriorityUpdateCb(PriorityUpdateCb callback) const PURE;
558

            
559
  /**
560
   * @return const std::vector<HostSetPtr>& the host sets, ordered by priority.
561
   */
562
  virtual const std::vector<HostSetPtr>& hostSetsPerPriority() const PURE;
563

            
564
  /**
565
   * @return HostMapConstSharedPtr read only cross priority host map that indexed by host address
566
   * string.
567
   */
568
  virtual HostMapConstSharedPtr crossPriorityHostMap() const PURE;
569

            
570
  /**
571
   * Parameter class for updateHosts.
572
   */
573
  struct UpdateHostsParams {
574
    HostVectorConstSharedPtr hosts;
575
    HealthyHostVectorConstSharedPtr healthy_hosts;
576
    DegradedHostVectorConstSharedPtr degraded_hosts;
577
    ExcludedHostVectorConstSharedPtr excluded_hosts;
578
    HostsPerLocalityConstSharedPtr hosts_per_locality;
579
    HostsPerLocalityConstSharedPtr healthy_hosts_per_locality;
580
    HostsPerLocalityConstSharedPtr degraded_hosts_per_locality;
581
    HostsPerLocalityConstSharedPtr excluded_hosts_per_locality;
582
  };
583

            
584
  /**
585
   * Updates the hosts in a given host set.
586
   *
587
   * @param priority the priority of the host set to update.
588
   * @param update_hosts_param supplies the list of hosts and hosts per locality.
589
   * @param locality_weights supplies a map from locality to associated weight.
590
   * @param hosts_added supplies the hosts added since the last update.
591
   * @param hosts_removed supplies the hosts removed since the last update.
592
   * @param weighted_priority_health if present, overwrites the current weighted_priority_health.
593
   * @param overprovisioning_factor if present, overwrites the current overprovisioning_factor.
594
   * @param cross_priority_host_map read only cross-priority host map which is created in the main
595
   * thread and shared by all the worker threads.
596
   */
597
  virtual void updateHosts(uint32_t priority, UpdateHostsParams&& update_hosts_params,
598
                           LocalityWeightsConstSharedPtr locality_weights,
599
                           const HostVector& hosts_added, const HostVector& hosts_removed,
600
                           absl::optional<bool> weighted_priority_health,
601
                           absl::optional<uint32_t> overprovisioning_factor,
602
                           HostMapConstSharedPtr cross_priority_host_map = nullptr) PURE;
603

            
604
  /**
605
   * Callback provided during batch updates that can be used to update hosts.
606
   */
607
  class HostUpdateCb {
608
  public:
609
803
    virtual ~HostUpdateCb() = default;
610
    /**
611
     * Updates the hosts in a given host set.
612
     *
613
     * @param priority the priority of the host set to update.
614
     * @param update_hosts_param supplies the list of hosts and hosts per locality.
615
     * @param locality_weights supplies a map from locality to associated weight.
616
     * @param hosts_added supplies the hosts added since the last update.
617
     * @param hosts_removed supplies the hosts removed since the last update.
618
     * @param weighted_priority_health if present, overwrites the current weighted_priority_health.
619
     * @param overprovisioning_factor if present, overwrites the current overprovisioning_factor.
620
     */
621
    virtual void updateHosts(uint32_t priority, UpdateHostsParams&& update_hosts_params,
622
                             LocalityWeightsConstSharedPtr locality_weights,
623
                             const HostVector& hosts_added, const HostVector& hosts_removed,
624
                             absl::optional<bool> weighted_priority_health,
625
                             absl::optional<uint32_t> overprovisioning_factor) PURE;
626
  };
627

            
628
  /**
629
   * Callback that provides the mechanism for performing batch host updates for a PrioritySet.
630
   */
631
  class BatchUpdateCb {
632
  public:
633
3
    virtual ~BatchUpdateCb() = default;
634

            
635
    /**
636
     * Performs a batch host update. Implementors should use the provided callback to update hosts
637
     * in the PrioritySet.
638
     */
639
    virtual void batchUpdate(HostUpdateCb& host_update_cb) PURE;
640
  };
641

            
642
  /**
643
   * Allows updating hosts for multiple priorities at once, deferring the MemberUpdateCb from
644
   * triggering until all priorities have been updated. The resulting callback will take into
645
   * account hosts moved from one priority to another.
646
   *
647
   * @param callback callback to use to add hosts.
648
   */
649
  virtual void batchHostUpdate(BatchUpdateCb& callback) PURE;
650
};
651

            
652
/**
653
 * All cluster config update related stats.
654
 * See https://github.com/envoyproxy/envoy/issues/23575 for details. Stats from ClusterInfo::stats()
655
 * will be split into subgroups "config-update", "lb", "endpoint" and "the rest"(which are mainly
656
 * upstream related), roughly based on their semantics.
657
 */
658
#define ALL_CLUSTER_CONFIG_UPDATE_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)         \
659
  COUNTER(assignment_stale)                                                                        \
660
  COUNTER(assignment_timeout_received)                                                             \
661
  COUNTER(assignment_use_cached)                                                                   \
662
  COUNTER(update_attempt)                                                                          \
663
  COUNTER(update_empty)                                                                            \
664
  COUNTER(update_failure)                                                                          \
665
  COUNTER(update_no_rebuild)                                                                       \
666
  COUNTER(update_success)                                                                          \
667
  GAUGE(version, NeverImport)                                                                      \
668
  GAUGE(warming_state, NeverImport)
669

            
670
/**
671
 * All cluster endpoints related stats.
672
 */
673
#define ALL_CLUSTER_ENDPOINT_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)              \
674
  GAUGE(max_host_weight, NeverImport)                                                              \
675
  COUNTER(membership_change)                                                                       \
676
  GAUGE(membership_degraded, NeverImport)                                                          \
677
  GAUGE(membership_excluded, NeverImport)                                                          \
678
  GAUGE(membership_healthy, NeverImport)                                                           \
679
  GAUGE(membership_total, NeverImport)
680

            
681
/**
682
 * All cluster load balancing related stats.
683
 */
684
#define ALL_CLUSTER_LB_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)                    \
685
  COUNTER(lb_healthy_panic)                                                                        \
686
  COUNTER(lb_local_cluster_not_ok)                                                                 \
687
  COUNTER(lb_recalculate_zone_structures)                                                          \
688
  COUNTER(lb_subsets_created)                                                                      \
689
  COUNTER(lb_subsets_fallback)                                                                     \
690
  COUNTER(lb_subsets_fallback_panic)                                                               \
691
  COUNTER(lb_subsets_removed)                                                                      \
692
  COUNTER(lb_subsets_selected)                                                                     \
693
  COUNTER(lb_zone_cluster_too_small)                                                               \
694
  COUNTER(lb_zone_no_capacity_left)                                                                \
695
  COUNTER(lb_zone_routing_all_directly)                                                            \
696
  COUNTER(lb_zone_routing_cross_zone)                                                              \
697
  COUNTER(lb_zone_routing_sampled)                                                                 \
698
  GAUGE(lb_subsets_active, Accumulate)
699

            
700
/**
701
 * All cluster stats. @see stats_macros.h
702
 */
703
#define ALL_CLUSTER_TRAFFIC_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)               \
704
  COUNTER(bind_errors)                                                                             \
705
  COUNTER(original_dst_host_invalid)                                                               \
706
  COUNTER(retry_or_shadow_abandoned)                                                               \
707
  COUNTER(upstream_cx_close_notify)                                                                \
708
  COUNTER(upstream_cx_connect_attempts_exceeded)                                                   \
709
  COUNTER(upstream_cx_connect_fail)                                                                \
710
  COUNTER(upstream_cx_connect_timeout)                                                             \
711
  COUNTER(upstream_cx_connect_with_0_rtt)                                                          \
712
  COUNTER(upstream_cx_destroy)                                                                     \
713
  COUNTER(upstream_cx_destroy_local)                                                               \
714
  COUNTER(upstream_cx_destroy_local_with_active_rq)                                                \
715
  COUNTER(upstream_cx_destroy_remote)                                                              \
716
  COUNTER(upstream_cx_destroy_remote_with_active_rq)                                               \
717
  COUNTER(upstream_cx_destroy_with_active_rq)                                                      \
718
  COUNTER(upstream_cx_http1_total)                                                                 \
719
  COUNTER(upstream_cx_http2_total)                                                                 \
720
  COUNTER(upstream_cx_http3_total)                                                                 \
721
  COUNTER(upstream_cx_idle_timeout)                                                                \
722
  COUNTER(upstream_cx_max_duration_reached)                                                        \
723
  COUNTER(upstream_cx_max_requests)                                                                \
724
  COUNTER(upstream_cx_none_healthy)                                                                \
725
  COUNTER(upstream_cx_overflow)                                                                    \
726
  COUNTER(upstream_cx_pool_overflow)                                                               \
727
  COUNTER(upstream_cx_protocol_error)                                                              \
728
  COUNTER(upstream_cx_rx_bytes_total)                                                              \
729
  COUNTER(upstream_cx_total)                                                                       \
730
  COUNTER(upstream_cx_tx_bytes_total)                                                              \
731
  COUNTER(upstream_flow_control_backed_up_total)                                                   \
732
  COUNTER(upstream_flow_control_drained_total)                                                     \
733
  COUNTER(upstream_flow_control_paused_reading_total)                                              \
734
  COUNTER(upstream_flow_control_resumed_reading_total)                                             \
735
  COUNTER(upstream_internal_redirect_failed_total)                                                 \
736
  COUNTER(upstream_internal_redirect_succeeded_total)                                              \
737
  COUNTER(upstream_rq_cancelled)                                                                   \
738
  COUNTER(upstream_rq_completed)                                                                   \
739
  COUNTER(upstream_rq_maintenance_mode)                                                            \
740
  COUNTER(upstream_rq_max_duration_reached)                                                        \
741
  COUNTER(upstream_rq_pending_failure_eject)                                                       \
742
  COUNTER(upstream_rq_pending_overflow)                                                            \
743
  COUNTER(upstream_rq_pending_total)                                                               \
744
  COUNTER(upstream_rq_0rtt)                                                                        \
745
  COUNTER(upstream_rq_per_try_timeout)                                                             \
746
  COUNTER(upstream_rq_per_try_idle_timeout)                                                        \
747
  COUNTER(upstream_rq_retry)                                                                       \
748
  COUNTER(upstream_rq_retry_backoff_exponential)                                                   \
749
  COUNTER(upstream_rq_retry_backoff_ratelimited)                                                   \
750
  COUNTER(upstream_rq_retry_limit_exceeded)                                                        \
751
  COUNTER(upstream_rq_retry_overflow)                                                              \
752
  COUNTER(upstream_rq_retry_success)                                                               \
753
  COUNTER(upstream_rq_rx_reset)                                                                    \
754
  COUNTER(upstream_rq_timeout)                                                                     \
755
  COUNTER(upstream_rq_total)                                                                       \
756
  COUNTER(upstream_rq_tx_reset)                                                                    \
757
  COUNTER(upstream_http3_broken)                                                                   \
758
  GAUGE(upstream_cx_active, Accumulate)                                                            \
759
  GAUGE(upstream_cx_rx_bytes_buffered, Accumulate)                                                 \
760
  GAUGE(upstream_cx_tx_bytes_buffered, Accumulate)                                                 \
761
  GAUGE(upstream_rq_active, Accumulate)                                                            \
762
  GAUGE(upstream_rq_pending_active, Accumulate)                                                    \
763
  HISTOGRAM(upstream_cx_connect_ms, Milliseconds)                                                  \
764
  HISTOGRAM(upstream_cx_length_ms, Milliseconds)                                                   \
765
  HISTOGRAM(upstream_rq_per_cx, Unspecified)
766

            
767
/**
768
 * All cluster load report stats. These are only use for EDS load reporting and not sent to the
769
 * stats sink. See envoy.config.endpoint.v3.ClusterStats for the definition of
770
 * total_dropped_requests and dropped_requests, which correspond to the upstream_rq_dropped and
771
 * upstream_rq_drop_overload counter here. These are latched by LoadStatsReporter interface
772
 * implementations, independent of the normal stats sink flushing.
773

            
774
 */
775
#define ALL_CLUSTER_LOAD_REPORT_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)           \
776
  COUNTER(upstream_rq_dropped)                                                                     \
777
  COUNTER(upstream_rq_drop_overload)
778

            
779
/**
780
 * Cluster circuit breakers gauges. Note that we do not generate a stats
781
 * structure from this macro. This is because depending on flags, we want to use
782
 * null gauges for all the "remaining" ones. This is hard to automate with the
783
 * 2-phase macros, so ClusterInfoImpl::generateCircuitBreakersStats is
784
 * hand-coded and must be changed if we alter the set of gauges in this macro.
785
 * We also include stat-names in this structure that are used when composing
786
 * the circuit breaker names, depending on priority settings.
787
 */
788
#define ALL_CLUSTER_CIRCUIT_BREAKERS_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)      \
789
3
  GAUGE(cx_open, Accumulate)                                                                       \
790
3
  GAUGE(cx_pool_open, Accumulate)                                                                  \
791
3
  GAUGE(rq_open, Accumulate)                                                                       \
792
3
  GAUGE(rq_pending_open, Accumulate)                                                               \
793
3
  GAUGE(rq_retry_open, Accumulate)                                                                 \
794
3
  GAUGE(remaining_cx, Accumulate)                                                                  \
795
3
  GAUGE(remaining_cx_pools, Accumulate)                                                            \
796
3
  GAUGE(remaining_pending, Accumulate)                                                             \
797
3
  GAUGE(remaining_retries, Accumulate)                                                             \
798
3
  GAUGE(remaining_rq, Accumulate)                                                                  \
799
3
  STATNAME(circuit_breakers)                                                                       \
800
3
  STATNAME(default)                                                                                \
801
3
  STATNAME(high)
802

            
803
/**
804
 * All stats tracking request/response headers and body sizes. Not used by default.
805
 */
806
#define ALL_CLUSTER_REQUEST_RESPONSE_SIZE_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME) \
807
  HISTOGRAM(upstream_rq_headers_size, Bytes)                                                       \
808
  HISTOGRAM(upstream_rq_headers_count, Unspecified)                                                \
809
  HISTOGRAM(upstream_rq_body_size, Bytes)                                                          \
810
  HISTOGRAM(upstream_rs_headers_size, Bytes)                                                       \
811
  HISTOGRAM(upstream_rs_headers_count, Unspecified)                                                \
812
  HISTOGRAM(upstream_rs_body_size, Bytes)
813

            
814
/**
815
 * All stats around timeout budgets. Not used by default.
816
 */
817
#define ALL_CLUSTER_TIMEOUT_BUDGET_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)        \
818
  HISTOGRAM(upstream_rq_timeout_budget_percent_used, Unspecified)                                  \
819
  HISTOGRAM(upstream_rq_timeout_budget_per_try_percent_used, Unspecified)
820

            
821
/**
822
 * Struct definition for cluster config update stats. @see stats_macros.h
823
 */
824
MAKE_STAT_NAMES_STRUCT(ClusterConfigUpdateStatNames, ALL_CLUSTER_CONFIG_UPDATE_STATS);
825
MAKE_STATS_STRUCT(ClusterConfigUpdateStats, ClusterConfigUpdateStatNames,
826
                  ALL_CLUSTER_CONFIG_UPDATE_STATS);
827

            
828
/**
829
 * Struct definition for cluster endpoint related stats. @see stats_macros.h
830
 */
831
MAKE_STAT_NAMES_STRUCT(ClusterEndpointStatNames, ALL_CLUSTER_ENDPOINT_STATS);
832
MAKE_STATS_STRUCT(ClusterEndpointStats, ClusterEndpointStatNames, ALL_CLUSTER_ENDPOINT_STATS);
833

            
834
/**
835
 * Struct definition for cluster load balancing stats. @see stats_macros.h
836
 */
837
MAKE_STAT_NAMES_STRUCT(ClusterLbStatNames, ALL_CLUSTER_LB_STATS);
838
MAKE_STATS_STRUCT(ClusterLbStats, ClusterLbStatNames, ALL_CLUSTER_LB_STATS);
839

            
840
/**
841
 * Struct definition for all cluster traffic stats. @see stats_macros.h
842
 */
843
MAKE_STAT_NAMES_STRUCT(ClusterTrafficStatNames, ALL_CLUSTER_TRAFFIC_STATS);
844
MAKE_STATS_STRUCT(ClusterTrafficStats, ClusterTrafficStatNames, ALL_CLUSTER_TRAFFIC_STATS);
845
using DeferredCreationCompatibleClusterTrafficStats =
846
    Stats::DeferredCreationCompatibleStats<ClusterTrafficStats>;
847

            
848
MAKE_STAT_NAMES_STRUCT(ClusterLoadReportStatNames, ALL_CLUSTER_LOAD_REPORT_STATS);
849
MAKE_STATS_STRUCT(ClusterLoadReportStats, ClusterLoadReportStatNames,
850
                  ALL_CLUSTER_LOAD_REPORT_STATS);
851

            
852
// We can't use macros to make the Stats class for circuit breakers due to
853
// the conditional inclusion of 'remaining' gauges. But we do auto-generate
854
// the StatNames struct.
855
MAKE_STAT_NAMES_STRUCT(ClusterCircuitBreakersStatNames, ALL_CLUSTER_CIRCUIT_BREAKERS_STATS);
856

            
857
MAKE_STAT_NAMES_STRUCT(ClusterRequestResponseSizeStatNames,
858
                       ALL_CLUSTER_REQUEST_RESPONSE_SIZE_STATS);
859
MAKE_STATS_STRUCT(ClusterRequestResponseSizeStats, ClusterRequestResponseSizeStatNames,
860
                  ALL_CLUSTER_REQUEST_RESPONSE_SIZE_STATS);
861

            
862
MAKE_STAT_NAMES_STRUCT(ClusterTimeoutBudgetStatNames, ALL_CLUSTER_TIMEOUT_BUDGET_STATS);
863
MAKE_STATS_STRUCT(ClusterTimeoutBudgetStats, ClusterTimeoutBudgetStatNames,
864
                  ALL_CLUSTER_TIMEOUT_BUDGET_STATS);
865

            
866
/**
867
 * Struct definition for cluster circuit breakers stats. @see stats_macros.h
868
 */
869
struct ClusterCircuitBreakersStats {
870
  ALL_CLUSTER_CIRCUIT_BREAKERS_STATS(c, GENERATE_GAUGE_STRUCT, h, tr, GENERATE_STATNAME_STRUCT)
871
};
872

            
873
using ClusterRequestResponseSizeStatsPtr = std::unique_ptr<ClusterRequestResponseSizeStats>;
874
using ClusterRequestResponseSizeStatsOptRef =
875
    absl::optional<std::reference_wrapper<ClusterRequestResponseSizeStats>>;
876

            
877
using ClusterTimeoutBudgetStatsPtr = std::unique_ptr<ClusterTimeoutBudgetStats>;
878
using ClusterTimeoutBudgetStatsOptRef =
879
    absl::optional<std::reference_wrapper<ClusterTimeoutBudgetStats>>;
880

            
881
/**
882
 * All extension protocol specific options returned by the method at
883
 *   NamedNetworkFilterConfigFactory::createProtocolOptions
884
 * must be derived from this class.
885
 */
886
class ProtocolOptionsConfig {
887
public:
888
246557
  virtual ~ProtocolOptionsConfig() = default;
889
};
890
using ProtocolOptionsConfigConstSharedPtr = std::shared_ptr<const ProtocolOptionsConfig>;
891

            
892
/**
893
 * Interface describing HTTP protocol options exposed by a cluster.
894
 */
895
class HttpProtocolOptionsConfig : public ProtocolOptionsConfig {
896
public:
897
246446
  ~HttpProtocolOptionsConfig() override = default;
898

            
899
  /**
900
   * @return const Http::Http1Settings& the HTTP/1.1 settings for upstream connections.
901
   */
902
  virtual const Http::Http1Settings& http1Settings() const PURE;
903

            
904
  /**
905
   * @return const envoy::config::core::v3::Http2ProtocolOptions& the HTTP/2 protocol options for
906
   *         upstream connections.
907
   */
908
  virtual const envoy::config::core::v3::Http2ProtocolOptions& http2Options() const PURE;
909

            
910
  /**
911
   * @return const envoy::config::core::v3::Http3ProtocolOptions& the HTTP/3 protocol options for
912
   *         upstream connections.
913
   */
914
  virtual const envoy::config::core::v3::Http3ProtocolOptions& http3Options() const PURE;
915

            
916
  /**
917
   * @return const envoy::config::core::v3::HttpProtocolOptions& the common HTTP protocol options
918
   *         that apply to all HTTP versions for upstream connections.
919
   */
920
  virtual const envoy::config::core::v3::HttpProtocolOptions&
921
  commonHttpProtocolOptions() const PURE;
922

            
923
  /**
924
   * @return const absl::optional<envoy::config::core::v3::UpstreamHttpProtocolOptions>& the
925
   *         optional upstream-specific HTTP protocol options. Returns absl::nullopt if not
926
   *         configured.
927
   */
928
  virtual const absl::optional<envoy::config::core::v3::UpstreamHttpProtocolOptions>&
929
  upstreamHttpProtocolOptions() const PURE;
930

            
931
  /**
932
   * @return const absl::optional<const envoy::config::core::v3::AlternateProtocolsCacheOptions>&
933
   *         the optional alternate protocols cache options for upstream connections. Returns
934
   *         absl::nullopt if not configured.
935
   */
936
  virtual const absl::optional<const envoy::config::core::v3::AlternateProtocolsCacheOptions>&
937
  alternateProtocolsCacheOptions() const PURE;
938

            
939
  /**
940
   * @return const std::vector<Router::ShadowPolicyPtr>& the shadow policies configured for this
941
   *         cluster. The vector is empty if no shadowing takes place.
942
   */
943
  virtual const std::vector<Router::ShadowPolicyPtr>& shadowPolicies() const PURE;
944

            
945
  /**
946
   * @return const Router::RetryPolicy* the retry policy configured for this cluster. Returns
947
   *         nullptr if no cluster-level retry policy is configured.
948
   */
949
  virtual const Router::RetryPolicy* retryPolicy() const PURE;
950

            
951
  /**
952
   * @return const Http::HashPolicy* the optional hash policy for load balancing. Returns nullptr
953
   *         if no hash policy is configured.
954
   */
955
  virtual const Http::HashPolicy* hashPolicy() const PURE;
956
};
957

            
958
using HttpProtocolOptionsConfigConstSharedPtr = std::shared_ptr<const HttpProtocolOptionsConfig>;
959

            
960
/**
961
 *  Base class for all cluster typed metadata factory.
962
 */
963
class ClusterTypedMetadataFactory : public Envoy::Config::TypedMetadataFactory {};
964

            
965
class LoadBalancerConfig;
966
class TypedLoadBalancerFactory;
967

            
968
/**
969
 * This is a function used by upstream binding config to select the source address based on the
970
 * target address. Given the target address through the parameter expect the source address
971
 * returned.
972
 */
973
using AddressSelectFn = std::function<const Network::Address::InstanceConstSharedPtr(
974
    const Network::Address::InstanceConstSharedPtr&)>;
975

            
976
/**
977
 * Information about a given upstream cluster.
978
 * This includes the information and interfaces for building an upstream filter chain.
979
 */
980
class ClusterInfo : public Http::FilterChainFactory {
981
public:
982
  struct Features {
983
    // Whether the upstream supports HTTP2. This is used when creating connection pools.
984
    static constexpr uint64_t HTTP2 = 0x1;
985
    // Use the downstream protocol (HTTP1.1, HTTP2) for upstream connections as well, if available.
986
    // This is used when creating connection pools.
987
    static constexpr uint64_t USE_DOWNSTREAM_PROTOCOL = 0x2;
988
    // Whether connections should be immediately closed upon health failure.
989
    static constexpr uint64_t CLOSE_CONNECTIONS_ON_HOST_HEALTH_FAILURE = 0x4;
990
    // If USE_ALPN and HTTP2 are true, the upstream protocol will be negotiated using ALPN.
991
    // If ALPN is attempted but not supported by the upstream HTTP/1.1 is used.
992
    static constexpr uint64_t USE_ALPN = 0x8;
993
    // Whether the upstream supports HTTP3. This is used when creating connection pools.
994
    static constexpr uint64_t HTTP3 = 0x10;
995
  };
996

            
997
246454
  ~ClusterInfo() override = default;
998

            
999
  /**
   * @return bool whether the cluster was added via API (if false the cluster was present in the
   *         initial configuration and cannot be removed or updated).
   */
  virtual bool addedViaApi() const PURE;
  /**
   * @return the connect timeout for upstream hosts that belong to this cluster.
   */
  virtual std::chrono::milliseconds connectTimeout() const PURE;
  /**
   * @return the idle timeout for upstream HTTP connection pool connections.
   */
  virtual const absl::optional<std::chrono::milliseconds> idleTimeout() const PURE;
  /**
   * @return the idle timeout for each connection in TCP connection pool.
   */
  virtual const absl::optional<std::chrono::milliseconds> tcpPoolIdleTimeout() const PURE;
  /**
   * @return optional maximum connection duration timeout for manager connections.
   */
  virtual const absl::optional<std::chrono::milliseconds> maxConnectionDuration() const PURE;
  /**
   * @return how many streams should be anticipated per each current stream.
   */
  virtual float perUpstreamPreconnectRatio() const PURE;
  /**
   * @return how many streams should be anticipated per each current stream.
   */
  virtual float peekaheadRatio() const PURE;
  /**
   * @return soft limit on size of the cluster's connections read and write buffers.
   */
  virtual uint32_t perConnectionBufferLimitBytes() const PURE;
  /**
   * @return how long an upstream connection is allowed to remain above the buffer high watermark
   * before being closed. A zero duration disables the timeout.
   */
  virtual std::chrono::milliseconds perConnectionBufferHighWatermarkTimeout() const PURE;
  /**
   * @return uint64_t features supported by the cluster. @see Features.
   */
  virtual uint64_t features() const PURE;
  /**
   * @return const HttpProtocolOptionsConfig& HTTP protocol options for this cluster.
   */
  virtual const HttpProtocolOptionsConfig& httpProtocolOptions() const PURE;
  /**
   * @param name std::string containing the well-known name of the extension for which protocol
   *        options are desired
   * @return std::shared_ptr<const Derived> where Derived is a subclass of ProtocolOptionsConfig
   *         and contains extension-specific protocol options for upstream connections.
   */
  template <class Derived>
37470
  std::shared_ptr<const Derived> extensionProtocolOptionsTyped(const std::string& name) const {
37470
    return std::dynamic_pointer_cast<const Derived>(extensionProtocolOptions(name));
37470
  }
  /**
   * @return OptRef<const LoadBalancerConfig> the validated load balancing policy configuration to
   * use for this cluster.
   */
  virtual OptRef<const LoadBalancerConfig> loadBalancerConfig() const PURE;
  /**
   * @return the load balancer factory for this cluster. Cluster will always has a valid load
   * balancer factory if it is created successfully.
   */
  virtual TypedLoadBalancerFactory& loadBalancerFactory() const PURE;
  /**
   * @return const envoy::config::cluster::v3::Cluster::CommonLbConfig& the common configuration for
   * all load balancers for this cluster.
   */
  virtual const envoy::config::cluster::v3::Cluster::CommonLbConfig& lbConfig() const PURE;
  /**
   * @param response Http::ResponseHeaderMap response headers received from upstream
   * @return absl::optional<bool> absl::nullopt is returned when matching did not took place.
   *         Otherwise, the boolean value indicates the matching result. True indicates that
   *         response should be treated as error, False as success.
   */
  virtual absl::optional<bool>
  processHttpForOutlierDetection(Http::ResponseHeaderMap& response) const PURE;
  /**
   * @return the service discovery type to use for resolving the cluster.
   */
  virtual envoy::config::cluster::v3::Cluster::DiscoveryType type() const PURE;
  /**
   * @return the type of cluster, only used for custom discovery types.
   */
  virtual OptRef<const envoy::config::cluster::v3::Cluster::CustomClusterType>
  clusterType() const PURE;
  /**
   * @return const absl::optional<envoy::config::core::v3::TypedExtensionConfig>& the configuration
   *         for the upstream, if a custom upstream is configured.
   */
  virtual OptRef<const envoy::config::core::v3::TypedExtensionConfig> upstreamConfig() const PURE;
  /**
   * @return Whether the cluster is currently in maintenance mode and should not be routed to.
   *         Different filters may handle this situation in different ways. The implementation
   *         of this routine is typically based on randomness and may not return the same answer
   *         on each call.
   */
  virtual bool maintenanceMode() const PURE;
  /**
   * @return uint32_t the maximum number of outbound requests that a connection pool will make on
   *         each upstream connection. This can be used to increase spread if the backends cannot
   *         tolerate imbalance. 0 indicates no maximum.
   */
  virtual uint32_t maxRequestsPerConnection() const PURE;
  /**
   * @return uint32_t the maximum number of response headers. The default value is 100. Results in a
   * reset if the number of headers exceeds this value.
   */
  virtual uint32_t maxResponseHeadersCount() const PURE;
  /**
   * @return uint32_t the maximum total size of response headers in KB.
   */
  virtual absl::optional<uint16_t> maxResponseHeadersKb() const PURE;
  /**
   * @return the human readable name of the cluster.
   */
  virtual const std::string& name() const PURE;
  /**
   * @return the observability name associated to the cluster. Used in stats, tracing, logging, and
   * config dumps. The observability name is configured with :ref:`alt_stat_name
   * <envoy_api_field_config.cluster.v3.Cluster.alt_stat_name>`. If unprovided, the default value is
   * the cluster name.
   */
  virtual const std::string& observabilityName() const PURE;
  /**
   * @return ResourceManager& the resource manager to use by proxy agents for this cluster (at
   *         a particular priority).
   */
  virtual ResourceManager& resourceManager(ResourcePriority priority) const PURE;
  /**
   * @return TransportSocketMatcher& the transport socket matcher associated
   * factory.
   */
  virtual TransportSocketMatcher& transportSocketMatcher() const PURE;
  /**
   * @return ClusterConfigUpdateStats& config update stats for this cluster.
   */
  virtual ClusterConfigUpdateStats& configUpdateStats() const PURE;
  /**
   * @return ClusterLbStats& load-balancer-related stats for this cluster.
   */
  virtual ClusterLbStats& lbStats() const PURE;
  /**
   * @return ClusterEndpointStats& endpoint related stats for this cluster.
   */
  virtual ClusterEndpointStats& endpointStats() const PURE;
  /**
   * @return  all traffic related stats for this cluster.
   */
  virtual DeferredCreationCompatibleClusterTrafficStats& trafficStats() const PURE;
  /**
   * @return the stats scope that contains all cluster stats. This can be used to produce dynamic
   *         stats that will be freed when the cluster is removed.
   */
  virtual Stats::Scope& statsScope() const PURE;
  /**
   * @return ClusterLoadReportStats& load report stats for this cluster.
   */
  virtual ClusterLoadReportStats& loadReportStats() const PURE;
  /**
   * @return absl::optional<std::reference_wrapper<ClusterRequestResponseSizeStats>> stats to track
   * headers/body sizes of request/response for this cluster.
   */
  virtual ClusterRequestResponseSizeStatsOptRef requestResponseSizeStats() const PURE;
  /**
   * @return absl::optional<std::reference_wrapper<ClusterTimeoutBudgetStats>> stats on timeout
   * budgets for this cluster.
   */
  virtual ClusterTimeoutBudgetStatsOptRef timeoutBudgetStats() const PURE;
  /**
   * @return true if this cluster should produce per-endpoint stats.
   */
  virtual bool perEndpointStatsEnabled() const PURE;
  /**
   * @return std::shared_ptr<const UpstreamLocalAddressSelector> as upstream local address selector.
   */
  virtual UpstreamLocalAddressSelectorConstSharedPtr getUpstreamLocalAddressSelector() const PURE;
  /**
   * @return const envoy::config::core::v3::Metadata& the configuration metadata for this cluster.
   */
  virtual const envoy::config::core::v3::Metadata& metadata() const PURE;
  /**
   * @return const Envoy::Config::TypedMetadata&& the typed metadata for this cluster.
   */
  virtual const Envoy::Config::TypedMetadata& typedMetadata() const PURE;
  /**
   * @return whether to skip waiting for health checking before draining connections
   *         after a host is removed from service discovery.
   */
  virtual bool drainConnectionsOnHostRemoval() const PURE;
  /**
   *  @return whether to create a new connection pool for each downstream connection routed to
   *          the cluster
   */
  virtual bool connectionPoolPerDownstreamConnection() const PURE;
  /**
   * @return true if this cluster is configured to ignore hosts for the purpose of load balancing
   * computations until they have been health checked for the first time.
   */
  virtual bool warmHosts() const PURE;
  /**
   * @return true if this cluster is configured to set local interface name on upstream connections.
   */
  virtual bool setLocalInterfaceNameOnUpstreamConnections() const PURE;
  /**
   * @return const std::string& eds cluster service_name of the cluster. Empty if not an EDS
   * cluster or eds cluster service_name is not set.
   */
  virtual const std::string& edsServiceName() const PURE;
  /**
   * Create network filters on a new upstream connection.
   */
  virtual void createNetworkFilterChain(Network::Connection& connection) const PURE;
  /**
   * Calculate upstream protocol(s) based on features.
   */
  virtual std::vector<Http::Protocol>
  upstreamHttpProtocol(absl::optional<Http::Protocol> downstream_protocol) const PURE;
  /**
   * @return the Http1 Codec Stats.
   */
  virtual Http::Http1::CodecStats& http1CodecStats() const PURE;
  /**
   * @return the Http2 Codec Stats.
   */
  virtual Http::Http2::CodecStats& http2CodecStats() const PURE;
  /**
   * @return the Http3 Codec Stats.
   */
  virtual Http::Http3::CodecStats& http3CodecStats() const PURE;
  /**
   * @return create header validator based on cluster configuration. Returns nullptr if
   * ENVOY_ENABLE_UHV is undefined.
   */
  virtual Http::ClientHeaderValidatorPtr makeHeaderValidator(Http::Protocol protocol) const PURE;
  /**
   * @return OptRef<const envoy::config::cluster::v3::Cluster::HappyEyeballsConfig>
   * an optional value of the configuration for happy eyeballs for this cluster.
   */
  virtual OptRef<const envoy::config::cluster::v3::UpstreamConnectionOptions::HappyEyeballsConfig>
  happyEyeballsConfig() const PURE;
  /**
   * @return Reference to the optional config for LRS endpoint metric reporting.
   */
  virtual OptRef<const std::vector<std::string>> lrsReportMetricNames() const PURE;
protected:
  /**
   * Invoked by extensionProtocolOptionsTyped.
   * @param name std::string containing the well-known name of the extension for which protocol
   *        options are desired
   * @return ProtocolOptionsConfigConstSharedPtr with extension-specific protocol options for
   *         upstream connections.
   */
  virtual ProtocolOptionsConfigConstSharedPtr
  extensionProtocolOptions(const std::string& name) const PURE;
};
using ClusterInfoConstSharedPtr = std::shared_ptr<const ClusterInfo>;
class HealthChecker;
/**
 * An upstream cluster (group of hosts). This class is the "primary" singleton cluster used amongst
 * all forwarding threads/workers. Individual HostSets are used on the workers themselves.
 */
class Cluster {
public:
62481
  virtual ~Cluster() = default;
  enum class InitializePhase { Primary, Secondary };
  /**
   * @return a pointer to the cluster's health checker. If a health checker has not been installed,
   *         returns nullptr.
   */
  virtual HealthChecker* healthChecker() PURE;
  /**
   * @return the information about this upstream cluster.
   */
  virtual ClusterInfoConstSharedPtr info() const PURE;
  /**
   * @return a pointer to the cluster's outlier detector. If an outlier detector has not been
   *         installed, returns nullptr.
   */
  virtual Outlier::Detector* outlierDetector() PURE;
  virtual const Outlier::Detector* outlierDetector() const PURE;
  /**
   * Initialize the cluster. This will be called either immediately at creation or after all primary
   * clusters have been initialized (determined via initializePhase()).
   * @param callback supplies a callback that will be invoked after the cluster has undergone first
   *        time initialization. E.g., for a dynamic DNS cluster the initialize callback will be
   *        called when initial DNS resolution is complete.
   */
  virtual void initialize(std::function<absl::Status()> callback) PURE;
  /**
   * @return the phase in which the cluster is initialized at boot. This mechanism is used such that
   *         clusters that depend on other clusters can correctly initialize. (E.g., an EDS cluster
   *         that depends on resolution of the EDS server itself).
   */
  virtual InitializePhase initializePhase() const PURE;
  /**
   * @return the PrioritySet for the cluster.
   */
  virtual PrioritySet& prioritySet() PURE;
  /**
   * @return the const PrioritySet for the cluster.
   */
  virtual const PrioritySet& prioritySet() const PURE;
  /**
   * @return the cluster drop_overload configuration.
   */
  virtual UnitFloat dropOverload() const PURE;
  /**
   * @return the cluster drop_category_ configuration.
   */
  virtual const std::string& dropCategory() const PURE;
  /**
   * Set up the drop_overload value for the cluster.
   */
  virtual void setDropOverload(UnitFloat drop_overload) PURE;
  /**
   * Set up the drop_category value for the thread local cluster.
   */
  virtual void setDropCategory(absl::string_view drop_category) PURE;
};
using ClusterSharedPtr = std::shared_ptr<Cluster>;
using ClusterConstOptRef = absl::optional<std::reference_wrapper<const Cluster>>;
} // namespace Upstream
} // namespace Envoy
// NOLINT(namespace-envoy)
namespace fmt {
// fmt formatter class for Host
template <> struct formatter<Envoy::Upstream::Host> : formatter<absl::string_view> {
  template <typename FormatContext>
48
  auto format(const Envoy::Upstream::Host& host, FormatContext& ctx) const -> decltype(ctx.out()) {
48
    absl::string_view out = !host.hostname().empty() ? host.hostname()
48
                            : host.address()         ? host.address()->asStringView()
44
                                                     : "<empty>";
48
    return formatter<absl::string_view>().format(out, ctx);
48
  }
};
} // namespace fmt