Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/config/bootstrap/v3/bootstrap.pb.h" 4 : #include "envoy/config/cluster/v3/cluster.pb.h" 5 : #include "envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.pb.h" 6 : #include "envoy/extensions/filters/udp/dns_filter/v3/dns_filter.pb.h" 7 : #include "envoy/extensions/network/dns_resolver/apple/v3/apple_dns_resolver.pb.h" 8 : #include "envoy/extensions/network/dns_resolver/cares/v3/cares_dns_resolver.pb.h" 9 : #include "envoy/network/dns_resolver.h" 10 : 11 : #include "source/common/runtime/runtime_features.h" 12 : 13 : namespace Envoy { 14 : namespace Network { 15 : 16 : // Create a default c-ares DNS resolver typed config. 17 : void makeDefaultCaresDnsResolverConfig( 18 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 19 : 20 : // Create a default apple DNS resolver typed config. 21 : void makeDefaultAppleDnsResolverConfig( 22 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 23 : 24 : // Create a default DNS resolver typed config based on build system and configuration. 25 : void makeDefaultDnsResolverConfig( 26 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 27 : 28 : // If it is MacOS and it's compiled it, create an AppleDnsResolverConfig typed config. 29 : bool tryUseAppleApiForDnsLookups( 30 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 31 : 32 : // If the config has typed_dns_resolver_config, copy it over. 33 : template <class ConfigType> 34 : bool checkTypedDnsResolverConfigExist( 35 : const ConfigType& config, 36 5 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) { 37 5 : if (config.has_typed_dns_resolver_config()) { 38 0 : typed_dns_resolver_config.MergeFrom(config.typed_dns_resolver_config()); 39 0 : return true; 40 0 : } 41 5 : return false; 42 5 : } 43 : 44 : // If the config has dns_resolution_config, create a CaresDnsResolverConfig typed config based on 45 : // it. 46 : template <class ConfigType> 47 : bool checkDnsResolutionConfigExist( 48 : const ConfigType& config, 49 5 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) { 50 5 : if (config.has_dns_resolution_config()) { 51 0 : envoy::extensions::network::dns_resolver::cares::v3::CaresDnsResolverConfig cares; 52 0 : if (!config.dns_resolution_config().resolvers().empty()) { 53 0 : cares.mutable_resolvers()->MergeFrom(config.dns_resolution_config().resolvers()); 54 0 : } 55 0 : cares.mutable_dns_resolver_options()->MergeFrom( 56 0 : config.dns_resolution_config().dns_resolver_options()); 57 0 : typed_dns_resolver_config.mutable_typed_config()->PackFrom(cares); 58 0 : typed_dns_resolver_config.set_name(std::string(CaresDnsResolver)); 59 0 : return true; 60 0 : } 61 5 : return false; 62 5 : } 63 : 64 : // For backward compatibility, copy over use_tcp_for_dns_lookups from config, and create 65 : // a CaresDnsResolverConfig typed config. This logic fit for bootstrap, and dns_cache config types. 66 : template <class ConfigType> 67 : void handleLegacyDnsResolverData( 68 : const ConfigType& config, 69 5 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) { 70 5 : envoy::extensions::network::dns_resolver::cares::v3::CaresDnsResolverConfig cares; 71 5 : cares.mutable_dns_resolver_options()->set_use_tcp_for_dns_lookups( 72 5 : config.use_tcp_for_dns_lookups()); 73 5 : typed_dns_resolver_config.mutable_typed_config()->PackFrom(cares); 74 5 : typed_dns_resolver_config.set_name(std::string(CaresDnsResolver)); 75 5 : } 76 : 77 : // Overloading the template function for DnsFilterConfig type, which doesn't need to copy anything. 78 : void handleLegacyDnsResolverData( 79 : const envoy::extensions::filters::udp::dns_filter::v3::DnsFilterConfig::ClientContextConfig&, 80 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 81 : 82 : // Overloading the template function for Cluster config type, which need to copy 83 : // both use_tcp_for_dns_lookups and dns_resolvers. 84 : void handleLegacyDnsResolverData( 85 : const envoy::config::cluster::v3::Cluster& config, 86 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 87 : 88 : // Make typed_dns_resolver_config from the passed @param config. 89 : template <class ConfigType> 90 5 : envoy::config::core::v3::TypedExtensionConfig makeDnsResolverConfig(const ConfigType& config) { 91 5 : envoy::config::core::v3::TypedExtensionConfig typed_dns_resolver_config; 92 : 93 : // typed_dns_resolver_config takes precedence 94 5 : if (checkTypedDnsResolverConfigExist(config, typed_dns_resolver_config)) { 95 0 : return typed_dns_resolver_config; 96 0 : } 97 : 98 : // If use apple API for DNS lookups, create an AppleDnsResolverConfig typed config. 99 5 : if (tryUseAppleApiForDnsLookups(typed_dns_resolver_config)) { 100 0 : return typed_dns_resolver_config; 101 0 : } 102 : 103 : // If dns_resolution_config exits, create a CaresDnsResolverConfig typed config based on it. 104 5 : if (checkDnsResolutionConfigExist(config, typed_dns_resolver_config)) { 105 0 : return typed_dns_resolver_config; 106 0 : } 107 : 108 : // Handle legacy DNS resolver fields for backward compatibility. 109 : // Different config type has different fields to copy. 110 5 : handleLegacyDnsResolverData(config, typed_dns_resolver_config); 111 5 : return typed_dns_resolver_config; 112 5 : } 113 : 114 : // Create the DNS resolver factory from the typed config. This is the underline 115 : // function which performs the registry lookup based on typed config. 116 : Network::DnsResolverFactory& createDnsResolverFactoryFromTypedConfig( 117 : const envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 118 : 119 : // Create the default DNS resolver factory. apple for MacOS or c-ares for all others. 120 : // The default registry lookup will always succeed, thus no exception throwing. 121 : // This function can be called in main or worker threads. 122 : Network::DnsResolverFactory& createDefaultDnsResolverFactory( 123 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config); 124 : 125 : // Create the DNS resolver factory from the proto config. 126 : // The passed in config parameter may contain invalid typed_dns_resolver_config. 127 : // In that case, the underline registry lookup will throw an exception. 128 : // This function has to be called in main thread. 129 : template <class ConfigType> 130 : Network::DnsResolverFactory& createDnsResolverFactoryFromProto( 131 : const ConfigType& config, 132 5 : envoy::config::core::v3::TypedExtensionConfig& typed_dns_resolver_config) { 133 5 : ASSERT_IS_MAIN_OR_TEST_THREAD(); 134 5 : typed_dns_resolver_config = makeDnsResolverConfig(config); 135 5 : return createDnsResolverFactoryFromTypedConfig(typed_dns_resolver_config); 136 5 : } 137 : 138 : } // namespace Network 139 : } // namespace Envoy