1
#pragma once
2

            
3
#include "envoy/config/cluster/v3/cluster.pb.h"
4
#include "envoy/config/endpoint/v3/endpoint_components.pb.h"
5
#include "envoy/extensions/clusters/dns/v3/dns_cluster.pb.h"
6
#include "envoy/extensions/clusters/dns/v3/dns_cluster.pb.validate.h"
7

            
8
#include "source/common/upstream/cluster_factory_impl.h"
9
#include "source/common/upstream/upstream_impl.h"
10

            
11
namespace Envoy {
12
namespace Upstream {
13

            
14
/**
15
 * Implementation of Upstream::Cluster that does periodic DNS resolution and updates the host
16
 * member set if the DNS members change.
17
 */
18
class StrictDnsClusterImpl : public BaseDynamicClusterImpl {
19
public:
20
  // Upstream::Cluster
21
149
  InitializePhase initializePhase() const override { return InitializePhase::Primary; }
22
  static absl::StatusOr<std::unique_ptr<StrictDnsClusterImpl>>
23
  create(const envoy::config::cluster::v3::Cluster& cluster,
24
         const envoy::extensions::clusters::dns::v3::DnsCluster& dns_cluster,
25
         ClusterFactoryContext& context, Network::DnsResolverSharedPtr dns_resolver);
26

            
27
protected:
28
  StrictDnsClusterImpl(const envoy::config::cluster::v3::Cluster& cluster,
29
                       const envoy::extensions::clusters::dns::v3::DnsCluster& dns_cluster,
30
                       ClusterFactoryContext& context, Network::DnsResolverSharedPtr dns_resolver,
31
                       absl::Status& creation_status);
32

            
33
private:
34
  struct ResolveTarget {
35
    ResolveTarget(StrictDnsClusterImpl& parent, Event::Dispatcher& dispatcher,
36
                  const std::string& dns_address, const uint32_t dns_port,
37
                  const envoy::config::endpoint::v3::LocalityLbEndpoints& locality_lb_endpoint,
38
                  const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint);
39
    ~ResolveTarget();
40
    void startResolve();
41

            
42
    StrictDnsClusterImpl& parent_;
43
    Network::ActiveDnsQuery* active_query_{};
44
    const envoy::config::endpoint::v3::LocalityLbEndpoints& locality_lb_endpoints_;
45
    const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint_;
46
    const std::string dns_address_;
47
    const std::string hostname_;
48
    const uint32_t port_;
49
    const Event::TimerPtr resolve_timer_;
50
    HostVector hosts_;
51

            
52
    // Host map for current resolve target. When we have multiple resolve targets, multiple targets
53
    // may contain two different hosts with the same address. This has two effects:
54
    // 1) This host map cannot be replaced by the cross-priority global host map in the priority
55
    // set.
56
    // 2) Cross-priority global host map may not be able to search for the expected host based on
57
    // the address.
58
    HostMap all_hosts_;
59
  };
60

            
61
  using ResolveTargetPtr = std::unique_ptr<ResolveTarget>;
62

            
63
  void updateAllHosts(const HostVector& hosts_added, const HostVector& hosts_removed,
64
                      uint32_t priority);
65

            
66
  // ClusterImplBase
67
  void startPreInit() override;
68

            
69
  // Keep load assignment as a member to make sure its data referenced in
70
  // resolve_targets_ outlives them.
71
  const envoy::config::endpoint::v3::ClusterLoadAssignment load_assignment_;
72
  const LocalInfo::LocalInfo& local_info_;
73
  Network::DnsResolverSharedPtr dns_resolver_;
74
  std::list<ResolveTargetPtr> resolve_targets_;
75
  const std::chrono::milliseconds dns_refresh_rate_ms_;
76
  const std::chrono::milliseconds dns_jitter_ms_;
77
  BackOffStrategyPtr failure_backoff_strategy_;
78
  const bool respect_dns_ttl_;
79
  Network::DnsLookupFamily dns_lookup_family_;
80
  uint32_t overprovisioning_factor_;
81
  bool weighted_priority_health_;
82
};
83

            
84
} // namespace Upstream
85
} // namespace Envoy