1
#include "source/extensions/clusters/common/logical_host.h"
2

            
3
namespace Envoy {
4
namespace Upstream {
5

            
6
absl::StatusOr<std::unique_ptr<LogicalHost>> LogicalHost::create(
7
    const ClusterInfoConstSharedPtr& cluster, const std::string& hostname,
8
    const Network::Address::InstanceConstSharedPtr& address, const AddressVector& address_list,
9
    const envoy::config::endpoint::v3::LocalityLbEndpoints& locality_lb_endpoint,
10
    const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint,
11
179
    const Network::TransportSocketOptionsConstSharedPtr& override_transport_socket_options) {
12
179
  absl::Status creation_status = absl::OkStatus();
13
179
  auto ret = std::unique_ptr<LogicalHost>(
14
179
      new LogicalHost(cluster, hostname, address, address_list, locality_lb_endpoint, lb_endpoint,
15
179
                      override_transport_socket_options, creation_status));
16
179
  RETURN_IF_NOT_OK(creation_status);
17
179
  return ret;
18
179
}
19

            
20
LogicalHost::LogicalHost(
21
    const ClusterInfoConstSharedPtr& cluster, const std::string& hostname,
22
    const Network::Address::InstanceConstSharedPtr& address, const AddressVector& address_list,
23
    const envoy::config::endpoint::v3::LocalityLbEndpoints& locality_lb_endpoint,
24
    const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint,
25
    const Network::TransportSocketOptionsConstSharedPtr& override_transport_socket_options,
26
    absl::Status& creation_status)
27
179
    : HostImplBase(lb_endpoint.load_balancing_weight().value(),
28
179
                   lb_endpoint.endpoint().health_check_config(), lb_endpoint.health_status()),
29
179
      HostDescriptionImplBase(
30
179
          cluster, hostname, address,
31
          // TODO(zyfjeff): Created through metadata shared pool
32
179
          std::make_shared<const envoy::config::core::v3::Metadata>(lb_endpoint.metadata()),
33
179
          std::make_shared<const envoy::config::core::v3::Metadata>(
34
179
              locality_lb_endpoint.metadata()),
35
          // TODO(adisuissa): Create through localities shared pool.
36
179
          std::make_shared<const envoy::config::core::v3::Locality>(
37
179
              locality_lb_endpoint.locality()),
38
179
          lb_endpoint.endpoint().health_check_config(), locality_lb_endpoint.priority(),
39
179
          creation_status),
40
179
      override_transport_socket_options_(override_transport_socket_options), address_(address),
41
179
      address_list_or_null_(makeAddressListOrNull(address, address_list)) {
42
179
  health_check_address_ =
43
179
      resolveHealthCheckAddress(lb_endpoint.endpoint().health_check_config(), address);
44
179
}
45

            
46
12
Network::Address::InstanceConstSharedPtr LogicalHost::healthCheckAddress() const {
47
12
  absl::MutexLock lock(address_lock_);
48
12
  return health_check_address_;
49
12
}
50

            
51
void LogicalHost::setNewAddresses(const Network::Address::InstanceConstSharedPtr& address,
52
                                  const AddressVector& address_list,
53
118
                                  const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint) {
54
118
  const auto& health_check_config = lb_endpoint.endpoint().health_check_config();
55
  // TODO(jmarantz): change setNewAddresses interface to specify the address_list as a shared_ptr.
56
118
  auto health_check_address = resolveHealthCheckAddress(health_check_config, address);
57
118
  SharedConstAddressVector shared_address_list;
58
118
  if (!address_list.empty()) {
59
117
    shared_address_list = std::make_shared<AddressVector>(address_list);
60
117
    ASSERT(*address_list.front() == *address);
61
117
  }
62
118
  {
63
118
    absl::MutexLock lock(address_lock_);
64
118
    address_ = address;
65
118
    address_list_or_null_ = std::move(shared_address_list);
66
118
    health_check_address_ = std::move(health_check_address);
67
118
  }
68
118
}
69

            
70
12
HostDescription::SharedConstAddressVector LogicalHost::addressListOrNull() const {
71
12
  absl::MutexLock lock(address_lock_);
72
12
  return address_list_or_null_;
73
12
}
74

            
75
442
Network::Address::InstanceConstSharedPtr LogicalHost::address() const {
76
442
  absl::MutexLock lock(address_lock_);
77
442
  return address_;
78
442
}
79

            
80
Upstream::Host::CreateConnectionData LogicalHost::createConnection(
81
    Event::Dispatcher& dispatcher, const Network::ConnectionSocket::OptionsSharedPtr& options,
82
108
    Network::TransportSocketOptionsConstSharedPtr transport_socket_options) const {
83
108
  Network::Address::InstanceConstSharedPtr address;
84
108
  SharedConstAddressVector address_list_or_null;
85
108
  {
86
108
    absl::MutexLock lock(address_lock_);
87
108
    address = address_;
88
108
    address_list_or_null = address_list_or_null_;
89
108
  }
90

            
91
  // Use override_transport_socket_options if set, otherwise use the passed options.
92
108
  const auto& effective_options = override_transport_socket_options_ != nullptr
93
108
                                      ? override_transport_socket_options_
94
108
                                      : transport_socket_options;
95

            
96
  // Per-connection resolution for filter state-based transport socket matching.
97
108
  const bool needs_per_connection_resolution =
98
108
      cluster().transportSocketMatcher().usesFilterState() && effective_options &&
99
108
      !effective_options->downstreamSharedFilterStateObjects().empty();
100

            
101
108
  Network::UpstreamTransportSocketFactory& factory =
102
108
      needs_per_connection_resolution
103
108
          ? resolveTransportSocketFactory(address, metadata().get(), effective_options)
104
108
          : transportSocketFactory();
105

            
106
108
  return HostImplBase::createConnection(
107
108
      dispatcher, cluster(), address, address_list_or_null, factory, options, effective_options,
108
108
      std::make_shared<RealHostDescription>(address, shared_from_this()));
109
108
}
110

            
111
} // namespace Upstream
112
} // namespace Envoy