1
#include "source/common/network/dns_resolver/dns_factory_util.h"
2

            
3
namespace Envoy {
4
namespace Network {
5

            
6
// Create a default c-ares DNS resolver typed config.
7
void makeDefaultCaresDnsResolverConfig(
8
93
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
9
93
  envoy::extensions::network::dns_resolver::cares::v3::CaresDnsResolverConfig cares;
10
93
  typed_dns_resolver_config.mutable_typed_config()->PackFrom(cares);
11
93
  typed_dns_resolver_config.set_name(std::string(CaresDnsResolver));
12
93
}
13

            
14
// Create a default apple DNS resolver typed config.
15
void makeDefaultAppleDnsResolverConfig(
16
1
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
17
1
  envoy::extensions::network::dns_resolver::apple::v3::AppleDnsResolverConfig apple;
18
1
  typed_dns_resolver_config.mutable_typed_config()->PackFrom(apple);
19
1
  typed_dns_resolver_config.set_name(std::string(AppleDnsResolver));
20
1
}
21

            
22
// Create a default DNS resolver typed config based on build system and configuration.
23
void makeDefaultDnsResolverConfig(
24
90
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
25
  // If use apple API for DNS lookups, create an AppleDnsResolverConfig typed config.
26
90
  if (tryUseAppleApiForDnsLookups(typed_dns_resolver_config)) {
27
    return;
28
  }
29
  // Otherwise, create a CaresDnsResolverConfig typed config.
30
90
  makeDefaultCaresDnsResolverConfig(typed_dns_resolver_config);
31
90
}
32

            
33
bool tryUseAppleApiForDnsLookups(
34
240
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
35
240
  if (Config::Utility::getAndCheckFactoryByName<Network::DnsResolverFactory>(
36
240
          std::string(AppleDnsResolver), true) != nullptr) {
37
    makeDefaultAppleDnsResolverConfig(typed_dns_resolver_config);
38
    ENVOY_LOG_MISC(debug, "create Apple DNS resolver type: {} in MacOS.",
39
                   typed_dns_resolver_config.name());
40
    return true;
41
  }
42
#ifdef __APPLE__
43
  ENVOY_LOG_MISC(warn, "Unable to create Apple DNS resolver type: {} in MacOS.",
44
                 typed_dns_resolver_config.name());
45
#endif
46
240
  return false;
47
240
}
48

            
49
// Overloading the template function for DnsFilterConfig type, which doesn't need to copy anything.
50
void handleLegacyDnsResolverData(
51
    const envoy::extensions::filters::udp::dns_filter::v3::DnsFilterConfig::ClientContextConfig&,
52
2
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
53
2
  makeDefaultCaresDnsResolverConfig(typed_dns_resolver_config);
54
2
}
55

            
56
// Overloading the template function for Cluster config type, which need to copy
57
// both use_tcp_for_dns_lookups and dns_resolvers.
58
void handleLegacyDnsResolverData(
59
    const envoy::config::cluster::v3::Cluster& config,
60
7
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
61
7
  envoy::extensions::network::dns_resolver::cares::v3::CaresDnsResolverConfig cares;
62
7
  cares.mutable_dns_resolver_options()->set_use_tcp_for_dns_lookups(
63
7
      config.use_tcp_for_dns_lookups());
64
7
  if (!config.dns_resolvers().empty()) {
65
6
    cares.mutable_resolvers()->MergeFrom(config.dns_resolvers());
66
6
  }
67
7
  typed_dns_resolver_config.mutable_typed_config()->PackFrom(cares);
68
7
  typed_dns_resolver_config.set_name(std::string(CaresDnsResolver));
69
7
}
70

            
71
// Create the DNS resolver factory from the typed config. This is the underline
72
// function which performs the registry lookup based on typed config.
73
Network::DnsResolverFactory& createDnsResolverFactoryFromTypedConfig(
74
543
    const envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
75
543
  ENVOY_LOG_MISC(debug, "create DNS resolver type: {}", typed_dns_resolver_config.name());
76
543
  return DnsResolverFactory::createFactory(typed_dns_resolver_config);
77
543
}
78

            
79
// Create the default DNS resolver factory. apple for MacOS or c-ares for all others.
80
// The default registry lookup will always succeed, thus no exception throwing.
81
// This function can be called in main or worker threads.
82
Network::DnsResolverFactory& createDefaultDnsResolverFactory(
83
89
    envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
84
89
  Network::makeDefaultDnsResolverConfig(typed_dns_resolver_config);
85
89
  return createDnsResolverFactoryFromTypedConfig(typed_dns_resolver_config);
86
89
}
87

            
88
Network::DnsResolverFactory& DnsResolverFactory::createFactory(
89
543
    const envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) {
90
543
  auto& factory =
91
543
      Config::Utility::getAndCheckFactory<Network::DnsResolverFactory>(typed_dns_resolver_config);
92
543
  factory.initialize();
93
543
  return factory;
94
543
}
95

            
96
1665
void DnsResolverFactory::terminateFactories() {
97
1665
  auto& factories = Registry::FactoryRegistry<Network::DnsResolverFactory>::factories();
98
1665
  std::for_each(factories.begin(), factories.end(),
99
1671
                [](auto& factory_it) { factory_it.second->terminate(); });
100
1665
}
101

            
102
} // namespace Network
103
} // namespace Envoy