diff --git a/api/envoy/config/bootstrap/v3/bootstrap.proto b/api/envoy/config/bootstrap/v3/bootstrap.proto index b179d3f4f6645..431b45b661717 100644 --- a/api/envoy/config/bootstrap/v3/bootstrap.proto +++ b/api/envoy/config/bootstrap/v3/bootstrap.proto @@ -9,6 +9,7 @@ import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/config_source.proto"; import "envoy/config/core/v3/event_service_config.proto"; import "envoy/config/core/v3/extension.proto"; +import "envoy/config/core/v3/resolver.proto"; import "envoy/config/core/v3/socket_option.proto"; import "envoy/config/listener/v3/listener.proto"; import "envoy/config/metrics/v3/stats.proto"; @@ -39,7 +40,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 30] +// [#next-free-field: 31] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Bootstrap"; @@ -250,7 +251,16 @@ message Bootstrap { // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 20; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool use_tcp_for_dns_lookups = 20 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + // This may be overridden on a per-cluster basis in cds_config, when + // :ref:`dns_resolution_config ` + // is specified. + core.v3.DnsResolutionConfig dns_resolution_config = 30; // Specifies optional bootstrap extensions to be instantiated at startup time. // Each item contains extension specific configuration. diff --git a/api/envoy/config/bootstrap/v4alpha/bootstrap.proto b/api/envoy/config/bootstrap/v4alpha/bootstrap.proto index a6ec388d54c54..c8ac9b16d87d9 100644 --- a/api/envoy/config/bootstrap/v4alpha/bootstrap.proto +++ b/api/envoy/config/bootstrap/v4alpha/bootstrap.proto @@ -9,6 +9,7 @@ import "envoy/config/core/v4alpha/base.proto"; import "envoy/config/core/v4alpha/config_source.proto"; import "envoy/config/core/v4alpha/event_service_config.proto"; import "envoy/config/core/v4alpha/extension.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; import "envoy/config/core/v4alpha/socket_option.proto"; import "envoy/config/listener/v4alpha/listener.proto"; import "envoy/config/metrics/v4alpha/stats.proto"; @@ -36,7 +37,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 30] +// [#next-free-field: 31] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v3.Bootstrap"; @@ -96,9 +97,9 @@ message Bootstrap { core.v4alpha.ApiConfigSource ads_config = 3; } - reserved 10, 11, 8, 9; + reserved 10, 11, 8, 9, 20; - reserved "runtime", "watchdog", "tracing"; + reserved "runtime", "watchdog", "tracing", "use_tcp_for_dns_lookups"; // Node identity to present to the management server and for instance // identification purposes (e.g. in generated headers). @@ -222,15 +223,11 @@ message Bootstrap { // :ref:`stats sinks `. google.protobuf.UInt64Value stats_server_version_override = 19; - // Always use TCP queries instead of UDP queries for DNS lookups. - // This may be overridden on a per-cluster basis in cds_config, - // when :ref:`dns_resolvers ` and - // :ref:`use_tcp_for_dns_lookups ` are - // specified. - // Setting this value causes failure if the - // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during - // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 20; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + // This may be overridden on a per-cluster basis in cds_config, when + // :ref:`dns_resolution_config ` + // is specified. + core.v4alpha.DnsResolutionConfig dns_resolution_config = 30; // Specifies optional bootstrap extensions to be instantiated at startup time. // Each item contains extension specific configuration. diff --git a/api/envoy/config/cluster/v3/cluster.proto b/api/envoy/config/cluster/v3/cluster.proto index 957c2b3341e3a..5470b1807d435 100644 --- a/api/envoy/config/cluster/v3/cluster.proto +++ b/api/envoy/config/cluster/v3/cluster.proto @@ -11,6 +11,7 @@ import "envoy/config/core/v3/config_source.proto"; import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/health_check.proto"; import "envoy/config/core/v3/protocol.proto"; +import "envoy/config/core/v3/resolver.proto"; import "envoy/config/endpoint/v3/endpoint.proto"; import "envoy/type/v3/percent.proto"; @@ -42,7 +43,7 @@ message ClusterCollection { } // Configuration for a single upstream cluster. -// [#next-free-field: 53] +// [#next-free-field: 54] message Cluster { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Cluster"; @@ -858,14 +859,22 @@ message Cluster { // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. - repeated core.v3.Address dns_resolvers = 18; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + repeated core.v3.Address dns_resolvers = 18 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // [#next-major-version: Reconcile DNS options in a single message.] // Always use TCP queries instead of UDP queries for DNS lookups. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 45; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool use_tcp_for_dns_lookups = 45 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + core.v3.DnsResolutionConfig dns_resolution_config = 53; // If specified, outlier detection will be enabled for this upstream cluster. // Each of the configuration values can be overridden via diff --git a/api/envoy/config/cluster/v4alpha/cluster.proto b/api/envoy/config/cluster/v4alpha/cluster.proto index 8adf5ea460e4e..bfea44955bf58 100644 --- a/api/envoy/config/cluster/v4alpha/cluster.proto +++ b/api/envoy/config/cluster/v4alpha/cluster.proto @@ -10,6 +10,7 @@ import "envoy/config/core/v4alpha/base.proto"; import "envoy/config/core/v4alpha/config_source.proto"; import "envoy/config/core/v4alpha/extension.proto"; import "envoy/config/core/v4alpha/health_check.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; import "envoy/config/endpoint/v3/endpoint.proto"; import "envoy/type/v3/percent.proto"; @@ -42,7 +43,7 @@ message ClusterCollection { } // Configuration for a single upstream cluster. -// [#next-free-field: 53] +// [#next-free-field: 54] message Cluster { option (udpa.annotations.versioning).previous_message_type = "envoy.config.cluster.v3.Cluster"; @@ -630,11 +631,11 @@ message Cluster { [(validate.rules).double = {lte: 3.0 gte: 1.0}]; } - reserved 12, 15, 7, 11, 35, 46, 29, 13, 14, 26, 47; + reserved 12, 15, 7, 11, 35, 46, 29, 13, 14, 18, 45, 26, 47; reserved "hosts", "tls_context", "extension_protocol_options", "upstream_http_protocol_options", "common_http_protocol_options", "http_protocol_options", "http2_protocol_options", - "protocol_selection", "track_timeout_budgets"; + "dns_resolvers", "use_tcp_for_dns_lookups", "protocol_selection", "track_timeout_budgets"; // Configuration to use different transport sockets for different endpoints. // The entry of *envoy.transport_socket_match* in the @@ -798,27 +799,8 @@ message Cluster { // :ref:`AUTO`. DnsLookupFamily dns_lookup_family = 17 [(validate.rules).enum = {defined_only: true}]; - // If DNS resolvers are specified and the cluster type is either - // :ref:`STRICT_DNS`, - // or :ref:`LOGICAL_DNS`, - // this value is used to specify the cluster’s dns resolvers. - // If this setting is not specified, the value defaults to the default - // resolver, which uses /etc/resolv.conf for configuration. For cluster types - // other than - // :ref:`STRICT_DNS` - // and :ref:`LOGICAL_DNS` - // this setting is ignored. - // Setting this value causes failure if the - // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during - // server startup. Apple's API only allows overriding DNS resolvers via system settings. - repeated core.v4alpha.Address dns_resolvers = 18; - - // [#next-major-version: Reconcile DNS options in a single message.] - // Always use TCP queries instead of UDP queries for DNS lookups. - // Setting this value causes failure if the - // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during - // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 45; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + core.v4alpha.DnsResolutionConfig dns_resolution_config = 53; // If specified, outlier detection will be enabled for this upstream cluster. // Each of the configuration values can be overridden via diff --git a/api/envoy/config/core/v3/resolver.proto b/api/envoy/config/core/v3/resolver.proto index b5e31814f56aa..21d40425f7a6b 100644 --- a/api/envoy/config/core/v3/resolver.proto +++ b/api/envoy/config/core/v3/resolver.proto @@ -14,11 +14,28 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Resolver] -// DNS resolver configuration which includes the underlying dns resolver addresses and options. -message DnsResolver { - // A list of dns resolver addresses +// Configuration of DNS resolver option flags which control the behavior of the DNS resolver. +message DnsResolverOptions { + // Use TCP for all DNS queries instead of the default protocol UDP. + // Setting this value causes failure if the + // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + // server startup. Apple's API only uses UDP for DNS resolution. + bool use_tcp_for_dns_lookups = 1; + + // Do not use the default search domains; only query hostnames as-is or as aliases. + bool no_default_search_domain = 2; +} + +// DNS resolution configuration which includes the underlying dns resolver addresses and options. +message DnsResolutionConfig { + // A list of dns resolver addresses. If specified, the DNS client library will perform resolution + // via the underlying DNS resolvers. Otherwise, the default system resolvers + // (e.g., /etc/resolv.conf) will be used. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. repeated Address resolvers = 1 [(validate.rules).repeated = {min_items: 1}]; + + // Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + DnsResolverOptions dns_resolver_options = 2; } diff --git a/api/envoy/config/core/v4alpha/resolver.proto b/api/envoy/config/core/v4alpha/resolver.proto index ad597c85549de..4849a54161ced 100644 --- a/api/envoy/config/core/v4alpha/resolver.proto +++ b/api/envoy/config/core/v4alpha/resolver.proto @@ -15,13 +15,34 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // [#protodoc-title: Resolver] -// DNS resolver configuration which includes the underlying dns resolver addresses and options. -message DnsResolver { - option (udpa.annotations.versioning).previous_message_type = "envoy.config.core.v3.DnsResolver"; +// Configuration of DNS resolver option flags which control the behavior of the DNS resolver. +message DnsResolverOptions { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.core.v3.DnsResolverOptions"; - // A list of dns resolver addresses + // Use TCP for all DNS queries instead of the default protocol UDP. + // Setting this value causes failure if the + // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + // server startup. Apple's API only uses UDP for DNS resolution. + bool use_tcp_for_dns_lookups = 1; + + // Do not use the default search domains; only query hostnames as-is or as aliases. + bool no_default_search_domain = 2; +} + +// DNS resolution configuration which includes the underlying dns resolver addresses and options. +message DnsResolutionConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.core.v3.DnsResolutionConfig"; + + // A list of dns resolver addresses. If specified, the DNS client library will perform resolution + // via the underlying DNS resolvers. Otherwise, the default system resolvers + // (e.g., /etc/resolv.conf) will be used. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. repeated Address resolvers = 1 [(validate.rules).repeated = {min_items: 1}]; + + // Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + DnsResolverOptions dns_resolver_options = 2; } diff --git a/api/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/BUILD b/api/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..ca83092e39b11 --- /dev/null +++ b/api/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/clusters/dynamic_forward_proxy/v3:pkg", + "//envoy/extensions/common/dynamic_forward_proxy/v4alpha:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/cluster.proto b/api/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/cluster.proto new file mode 100644 index 0000000000000..1b989e0bb725e --- /dev/null +++ b/api/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/cluster.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package envoy.extensions.clusters.dynamic_forward_proxy.v4alpha; + +import "envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.clusters.dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "ClusterProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: Dynamic forward proxy cluster configuration] + +// Configuration for the dynamic forward proxy cluster. See the :ref:`architecture overview +// ` for more information. +// [#extension: envoy.clusters.dynamic_forward_proxy] +message ClusterConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig"; + + // The DNS cache configuration that the cluster will attach to. Note this configuration must + // match that of associated :ref:`dynamic forward proxy HTTP filter configuration + // `. + common.dynamic_forward_proxy.v4alpha.DnsCacheConfig dns_cache_config = 1 + [(validate.rules).message = {required: true}]; + + // If true allow the cluster configuration to disable the auto_sni and auto_san_validation options + // in the :ref:`cluster's upstream_http_protocol_options + // ` + bool allow_insecure_cluster_options = 2; +} diff --git a/api/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD b/api/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD index 6e74b985c580d..fb5436a6bf93a 100644 --- a/api/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD +++ b/api/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD @@ -6,6 +6,7 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ + "//envoy/annotations:pkg", "//envoy/config/cluster/v3:pkg", "//envoy/config/common/dynamic_forward_proxy/v2alpha:pkg", "//envoy/config/core/v3:pkg", diff --git a/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto b/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto index 1c14739b94c86..79d6752502094 100644 --- a/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto +++ b/api/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto @@ -8,6 +8,7 @@ import "envoy/config/core/v3/resolver.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; +import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -96,15 +97,15 @@ message DnsCacheConfig { // Envoy will use dns cache circuit breakers with default settings even if this value is not set. DnsCacheCircuitBreakers dns_cache_circuit_breaker = 7; - // [#next-major-version: Reconcile DNS options in a single message.] // Always use TCP queries instead of UDP queries for DNS lookups. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 8; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool use_tcp_for_dns_lookups = 8 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // DNS resolver configuration - // If specified, DNS cache will perform resolution via the underlying DNS resolvers. - // Otherwise, the default system resolvers (e.g., /etc/resolv.conf) will be used. - config.core.v3.DnsResolver dns_resolver = 9; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v3.DnsResolutionConfig dns_resolution_config = 9; } diff --git a/api/envoy/extensions/common/dynamic_forward_proxy/v4alpha/BUILD b/api/envoy/extensions/common/dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..a70cf4f2bbbd6 --- /dev/null +++ b/api/envoy/extensions/common/dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,14 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/config/cluster/v4alpha:pkg", + "//envoy/config/core/v4alpha:pkg", + "//envoy/extensions/common/dynamic_forward_proxy/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto b/api/envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto new file mode 100644 index 0000000000000..89b2fb12a0923 --- /dev/null +++ b/api/envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; + +package envoy.extensions.common.dynamic_forward_proxy.v4alpha; + +import "envoy/config/cluster/v4alpha/cluster.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.common.dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "DnsCacheProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: Dynamic forward proxy common configuration] + +// Configuration of circuit breakers for resolver. +message DnsCacheCircuitBreakers { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.common.dynamic_forward_proxy.v3.DnsCacheCircuitBreakers"; + + // The maximum number of pending requests that Envoy will allow to the + // resolver. If not specified, the default is 1024. + google.protobuf.UInt32Value max_pending_requests = 1; +} + +// Configuration for the dynamic forward proxy DNS cache. See the :ref:`architecture overview +// ` for more information. +// [#next-free-field: 10] +message DnsCacheConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.common.dynamic_forward_proxy.v3.DnsCacheConfig"; + + reserved 8; + + reserved "use_tcp_for_dns_lookups"; + + // The name of the cache. Multiple named caches allow independent dynamic forward proxy + // configurations to operate within a single Envoy process using different configurations. All + // configurations with the same name *must* otherwise have the same settings when referenced + // from different configuration components. Configuration will fail to load if this is not + // the case. + string name = 1 [(validate.rules).string = {min_len: 1}]; + + // The DNS lookup family to use during resolution. + // + // [#comment:TODO(mattklein123): Figure out how to support IPv4/IPv6 "happy eyeballs" mode. The + // way this might work is a new lookup family which returns both IPv4 and IPv6 addresses, and + // then configures a host to have a primary and fall back address. With this, we could very + // likely build a "happy eyeballs" connection pool which would race the primary / fall back + // address and return the one that wins. This same method could potentially also be used for + // QUIC to TCP fall back.] + config.cluster.v4alpha.Cluster.DnsLookupFamily dns_lookup_family = 2 + [(validate.rules).enum = {defined_only: true}]; + + // The DNS refresh rate for currently cached DNS hosts. If not specified defaults to 60s. + // + // .. note: + // + // The returned DNS TTL is not currently used to alter the refresh rate. This feature will be + // added in a future change. + // + // .. note: + // + // The refresh rate is rounded to the closest millisecond, and must be at least 1ms. + google.protobuf.Duration dns_refresh_rate = 3 + [(validate.rules).duration = {gte {nanos: 1000000}}]; + + // The TTL for hosts that are unused. Hosts that have not been used in the configured time + // interval will be purged. If not specified defaults to 5m. + // + // .. note: + // + // The TTL is only checked at the time of DNS refresh, as specified by *dns_refresh_rate*. This + // means that if the configured TTL is shorter than the refresh rate the host may not be removed + // immediately. + // + // .. note: + // + // The TTL has no relation to DNS TTL and is only used to control Envoy's resource usage. + google.protobuf.Duration host_ttl = 4 [(validate.rules).duration = {gt {}}]; + + // The maximum number of hosts that the cache will hold. If not specified defaults to 1024. + // + // .. note: + // + // The implementation is approximate and enforced independently on each worker thread, thus + // it is possible for the maximum hosts in the cache to go slightly above the configured + // value depending on timing. This is similar to how other circuit breakers work. + google.protobuf.UInt32Value max_hosts = 5 [(validate.rules).uint32 = {gt: 0}]; + + // If the DNS failure refresh rate is specified, + // this is used as the cache's DNS refresh rate when DNS requests are failing. If this setting is + // not specified, the failure refresh rate defaults to the dns_refresh_rate. + config.cluster.v4alpha.Cluster.RefreshRate dns_failure_refresh_rate = 6; + + // The config of circuit breakers for resolver. It provides a configurable threshold. + // Envoy will use dns cache circuit breakers with default settings even if this value is not set. + DnsCacheCircuitBreakers dns_cache_circuit_breaker = 7; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v4alpha.DnsResolutionConfig dns_resolution_config = 9; +} diff --git a/api/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/BUILD b/api/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..8486b45d71d91 --- /dev/null +++ b/api/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/common/dynamic_forward_proxy/v4alpha:pkg", + "//envoy/extensions/filters/http/dynamic_forward_proxy/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/dynamic_forward_proxy.proto b/api/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/dynamic_forward_proxy.proto new file mode 100644 index 0000000000000..0dba06106b074 --- /dev/null +++ b/api/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/dynamic_forward_proxy.proto @@ -0,0 +1,64 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.dynamic_forward_proxy.v4alpha; + +import "envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "DynamicForwardProxyProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: Dynamic forward proxy] + +// Configuration for the dynamic forward proxy HTTP filter. See the :ref:`architecture overview +// ` for more information. +// [#extension: envoy.filters.http.dynamic_forward_proxy] +message FilterConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig"; + + // The DNS cache configuration that the filter will attach to. Note this configuration must + // match that of associated :ref:`dynamic forward proxy cluster configuration + // `. + common.dynamic_forward_proxy.v4alpha.DnsCacheConfig dns_cache_config = 1 + [(validate.rules).message = {required: true}]; +} + +// Per route Configuration for the dynamic forward proxy HTTP filter. +message PerRouteConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.http.dynamic_forward_proxy.v3.PerRouteConfig"; + + oneof host_rewrite_specifier { + // Indicates that before DNS lookup, the host header will be swapped with + // this value. If not set or empty, the original host header value + // will be used and no rewrite will happen. + // + // Note: this rewrite affects both DNS lookup and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite ` given that the + // value set here would be used for DNS lookups whereas the value set in the HCM would be used + // for host header forwarding which is not the desired outcome. + string host_rewrite_literal = 1; + + // Indicates that before DNS lookup, the host header will be swapped with + // the value of this header. If not set or empty, the original host header + // value will be used and no rewrite will happen. + // + // Note: this rewrite affects both DNS lookup and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite header ` + // given that the value set here would be used for DNS lookups whereas the value set in the HCM + // would be used for host header forwarding which is not the desired outcome. + // + // .. note:: + // + // If the header appears multiple times only the first value is used. + string host_rewrite_header = 2; + } +} diff --git a/api/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/BUILD b/api/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..465ea4ff28449 --- /dev/null +++ b/api/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/common/dynamic_forward_proxy/v4alpha:pkg", + "//envoy/extensions/filters/network/sni_dynamic_forward_proxy/v3alpha:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/sni_dynamic_forward_proxy.proto b/api/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/sni_dynamic_forward_proxy.proto new file mode 100644 index 0000000000000..de2947fcba9ec --- /dev/null +++ b/api/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/sni_dynamic_forward_proxy.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package envoy.extensions.filters.network.sni_dynamic_forward_proxy.v4alpha; + +import "envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.network.sni_dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "SniDynamicForwardProxyProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).work_in_progress = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: SNI dynamic forward proxy] + +// Configuration for the SNI-based dynamic forward proxy filter. See the +// :ref:`architecture overview ` for +// more information. Note this filter must be configured along with +// :ref:`TLS inspector listener filter ` +// to work. +// [#extension: envoy.filters.network.sni_dynamic_forward_proxy] +message FilterConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.network.sni_dynamic_forward_proxy.v3alpha.FilterConfig"; + + // The DNS cache configuration that the filter will attach to. Note this + // configuration must match that of associated :ref:`dynamic forward proxy + // cluster configuration + // `. + common.dynamic_forward_proxy.v4alpha.DnsCacheConfig dns_cache_config = 1 + [(validate.rules).message = {required: true}]; + + oneof port_specifier { + // The port number to connect to the upstream. + uint32 port_value = 2 [(validate.rules).uint32 = {lte: 65535 gt: 0}]; + } +} diff --git a/api/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto b/api/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto index 32103540c1d2b..8221c11efbe78 100644 --- a/api/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto +++ b/api/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package envoy.extensions.filters.udp.dns_filter.v3alpha; -import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; +import "envoy/config/core/v3/resolver.proto"; import "envoy/data/dns/v3/dns_table.proto"; import "google/protobuf/duration.proto"; @@ -51,10 +51,8 @@ message DnsFilterConfig { // number of retries multiplied by the resolver_timeout. google.protobuf.Duration resolver_timeout = 1 [(validate.rules).duration = {gte {seconds: 1}}]; - // A list of DNS servers to which we can forward queries. If not - // specified, Envoy will use the ambient DNS resolvers in the - // system. - repeated config.core.v3.Address upstream_resolvers = 2; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v3.DnsResolutionConfig dns_resolution_config = 2; // Controls how many outstanding external lookup contexts the filter tracks. // The context structure allows the filter to respond to every query even if the external diff --git a/api/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto b/api/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto index 54615b8b93ed8..6957e58dbb068 100644 --- a/api/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto +++ b/api/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package envoy.extensions.filters.udp.dns_filter.v4alpha; -import "envoy/config/core/v4alpha/address.proto"; import "envoy/config/core/v4alpha/base.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; import "envoy/data/dns/v4alpha/dns_table.proto"; import "google/protobuf/duration.proto"; @@ -61,10 +61,8 @@ message DnsFilterConfig { // number of retries multiplied by the resolver_timeout. google.protobuf.Duration resolver_timeout = 1 [(validate.rules).duration = {gte {seconds: 1}}]; - // A list of DNS servers to which we can forward queries. If not - // specified, Envoy will use the ambient DNS resolvers in the - // system. - repeated config.core.v4alpha.Address upstream_resolvers = 2; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v4alpha.DnsResolutionConfig dns_resolution_config = 2; // Controls how many outstanding external lookup contexts the filter tracks. // The context structure allows the filter to respond to every query even if the external diff --git a/docs/root/configuration/http/http_filters/_include/dns-cache-circuit-breaker.yaml b/docs/root/configuration/http/http_filters/_include/dns-cache-circuit-breaker.yaml index 1efb16f48c768..c5cf2d2d2c582 100644 --- a/docs/root/configuration/http/http_filters/_include/dns-cache-circuit-breaker.yaml +++ b/docs/root/configuration/http/http_filters/_include/dns-cache-circuit-breaker.yaml @@ -43,6 +43,14 @@ static_resources: dns_cache_config: name: dynamic_forward_proxy_cache_config dns_lookup_family: V4_ONLY + dns_resolution_config: + resolvers: + - socket_address: + address: "8.8.8.8" + port_value: 53 + dns_resolver_options: + use_tcp_for_dns_lookups: true + no_default_search_domain: true - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -57,6 +65,14 @@ static_resources: dns_cache_config: name: dynamic_forward_proxy_cache_config dns_lookup_family: V4_ONLY + dns_resolution_config: + resolvers: + - socket_address: + address: "8.8.8.8" + port_value: 53 + dns_resolver_options: + use_tcp_for_dns_lookups: true + no_default_search_domain: true transport_socket: name: envoy.transport_sockets.tls typed_config: diff --git a/docs/root/configuration/listeners/udp_filters/dns_filter.rst b/docs/root/configuration/listeners/udp_filters/dns_filter.rst index d2243351f3403..7e3d74cf10f97 100644 --- a/docs/root/configuration/listeners/udp_filters/dns_filter.rst +++ b/docs/root/configuration/listeners/udp_filters/dns_filter.rst @@ -39,13 +39,17 @@ Example Configuration stat_prefix: "dns_filter_prefix" client_config: resolution_timeout: 5s - upstream_resolvers: - - socket_address: - address: "8.8.8.8" - port_value: 53 - - socket_address: - address: "8.8.4.4" - port_value: 53 + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: false + no_default_search_domain: false + resolvers: + - socket_address: + address: "8.8.8.8" + port_value: 53 + - socket_address: + address: "8.8.4.4" + port_value: 53 max_pending_lookups: 256 server_config: inline_dns_table: diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 2597bef503552..cfa3e576da865 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -66,8 +66,13 @@ New Features ------------ * bandwidth_limit: added new :ref:`HTTP bandwidth limit filter `. +* bootstrap: added :ref:`dns_resolution_config ` to aggregate all of the DNS resolver configuration in a single message. By setting one such configuration option *no_default_search_domain* as true the DNS resolver will not use the default search domains. And by setting the configuration *resolvers* we can specify the external DNS servers to be used for external DNS query. +* cluster: added :ref:`dns_resolution_config ` to aggregate all of the DNS resolver configuration in a single message. By setting one such configuration option *no_default_search_domain* as true the DNS resolver will not use the default search domains. * crash support: restore crash context when continuing to processing requests or responses as a result of an asynchronous callback that invokes a filter directly. This is unlike the call stacks that go through the various network layers, to eventually reach the filter. For a concrete example see: ``Envoy::Extensions::HttpFilters::Cache::CacheFilter::getHeaders`` which posts a callback on the dispatcher that will invoke the filter directly. -* dynamic_forward_proxy: added :ref:`dns_resolver` option to the DNS cache config in order use custom DNS resolvers instead of the system default resolvers. +* dns resolver: added *DnsResolverOptions* protobuf message to reconcile all of the DNS lookup option flags. By setting the configuration option :ref:`use_tcp_for_dns_lookups ` as true we can make the underlying dns resolver library to make only TCP queries to the DNS servers and by setting the configuration option :ref:`no_default_search_domain ` as true the DNS resolver library will not use the default search domains. +* dns resolver: added *DnsResolutionConfig* to combine :ref:`dns_resolver_options ` and :ref:`resolvers ` in a single protobuf message. The field *resolvers* can be specified with a list of DNS resolver addresses. If specified, DNS client library will perform resolution via the underlying DNS resolvers. Otherwise, the default system resolvers (e.g., /etc/resolv.conf) will be used. +* dns_filter: added :ref:`dns_resolution_config ` to aggregate all of the DNS resolver configuration in a single message. By setting the configuration option *use_tcp_for_dns_lookups* to true we can make dns filter's external resolvers to answer queries using TCP only, by setting the configuration option *no_default_search_domain* as true the DNS resolver will not use the default search domains. And by setting the configuration *resolvers* we can specify the external DNS servers to be used for external DNS query which replaces the pre-existing alpha api field *upstream_resolvers*. +* dynamic_forward_proxy: added :ref:`dns_resolution_config ` option to the DNS cache config in order to aggregate all of the DNS resolver configuration in a single message. By setting one such configuration option *no_default_search_domain* as true the DNS resolver will not use the default search domains. And by setting the configuration *resolvers* we can specify the external DNS servers to be used for external DNS query instead of the system default resolvers. * http: a new field `is_optional` is added to `extensions.filters.network.http_connection_manager.v3.HttpFilter`. When value is `true`, the unsupported http filter will be ignored by envoy. This is also same with unsupported http filter in the typed per filter config. For more information, please reference @@ -89,4 +94,7 @@ New Features Deprecated ---------- +* bootstrap: the field :ref:`use_tcp_for_dns_lookups ` is deprecated in favor of :ref:`dns_resolution_config ` which aggregates all of the DNS resolver configuration in a single message. +* cluster: the fields :ref:`use_tcp_for_dns_lookups ` and :ref:`dns_resolvers ` are deprecated in favor of :ref:`dns_resolution_config ` which aggregates all of the DNS resolver configuration in a single message. +* dynamic_forward_proxy: the field :ref:`use_tcp_for_dns_lookups ` is deprecated in favor of :ref:`dns_resolution_config ` which aggregates all of the DNS resolver configuration in a single message. * http: :ref:`xff_num_trusted_hops ` is deprecated in favor of :ref:`original IP detection extensions`. diff --git a/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto b/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto index 20470800201d3..32d865f1abf15 100644 --- a/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto +++ b/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto @@ -9,6 +9,7 @@ import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/config_source.proto"; import "envoy/config/core/v3/event_service_config.proto"; import "envoy/config/core/v3/extension.proto"; +import "envoy/config/core/v3/resolver.proto"; import "envoy/config/core/v3/socket_option.proto"; import "envoy/config/listener/v3/listener.proto"; import "envoy/config/metrics/v3/stats.proto"; @@ -39,7 +40,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 30] +// [#next-free-field: 31] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Bootstrap"; @@ -248,7 +249,16 @@ message Bootstrap { // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 20; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool use_tcp_for_dns_lookups = 20 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + // This may be overridden on a per-cluster basis in cds_config, when + // :ref:`dns_resolution_config ` + // is specified. + core.v3.DnsResolutionConfig dns_resolution_config = 30; // Specifies optional bootstrap extensions to be instantiated at startup time. // Each item contains extension specific configuration. diff --git a/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto b/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto index b572cd301959d..00f640675453d 100644 --- a/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto +++ b/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto @@ -9,6 +9,7 @@ import "envoy/config/core/v4alpha/base.proto"; import "envoy/config/core/v4alpha/config_source.proto"; import "envoy/config/core/v4alpha/event_service_config.proto"; import "envoy/config/core/v4alpha/extension.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; import "envoy/config/core/v4alpha/socket_option.proto"; import "envoy/config/listener/v4alpha/listener.proto"; import "envoy/config/metrics/v4alpha/stats.proto"; @@ -38,7 +39,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 30] +// [#next-free-field: 31] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v3.Bootstrap"; @@ -246,7 +247,16 @@ message Bootstrap { // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 20; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool hidden_envoy_deprecated_use_tcp_for_dns_lookups = 20 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + // This may be overridden on a per-cluster basis in cds_config, when + // :ref:`dns_resolution_config ` + // is specified. + core.v4alpha.DnsResolutionConfig dns_resolution_config = 30; // Specifies optional bootstrap extensions to be instantiated at startup time. // Each item contains extension specific configuration. diff --git a/generated_api_shadow/envoy/config/cluster/v3/cluster.proto b/generated_api_shadow/envoy/config/cluster/v3/cluster.proto index d9e64b44ce88a..7ba5e5c8fb436 100644 --- a/generated_api_shadow/envoy/config/cluster/v3/cluster.proto +++ b/generated_api_shadow/envoy/config/cluster/v3/cluster.proto @@ -11,6 +11,7 @@ import "envoy/config/core/v3/config_source.proto"; import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/health_check.proto"; import "envoy/config/core/v3/protocol.proto"; +import "envoy/config/core/v3/resolver.proto"; import "envoy/config/endpoint/v3/endpoint.proto"; import "envoy/extensions/transport_sockets/tls/v3/tls.proto"; import "envoy/type/v3/percent.proto"; @@ -43,7 +44,7 @@ message ClusterCollection { } // Configuration for a single upstream cluster. -// [#next-free-field: 53] +// [#next-free-field: 54] message Cluster { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Cluster"; @@ -859,14 +860,22 @@ message Cluster { // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. - repeated core.v3.Address dns_resolvers = 18; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + repeated core.v3.Address dns_resolvers = 18 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // [#next-major-version: Reconcile DNS options in a single message.] // Always use TCP queries instead of UDP queries for DNS lookups. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 45; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool use_tcp_for_dns_lookups = 45 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + core.v3.DnsResolutionConfig dns_resolution_config = 53; // If specified, outlier detection will be enabled for this upstream cluster. // Each of the configuration values can be overridden via diff --git a/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto b/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto index d637591a2251c..1ead224bc876f 100644 --- a/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto +++ b/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto @@ -11,6 +11,7 @@ import "envoy/config/core/v4alpha/config_source.proto"; import "envoy/config/core/v4alpha/extension.proto"; import "envoy/config/core/v4alpha/health_check.proto"; import "envoy/config/core/v4alpha/protocol.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; import "envoy/config/endpoint/v3/endpoint.proto"; import "envoy/type/v3/percent.proto"; @@ -44,7 +45,7 @@ message ClusterCollection { } // Configuration for a single upstream cluster. -// [#next-free-field: 53] +// [#next-free-field: 54] message Cluster { option (udpa.annotations.versioning).previous_message_type = "envoy.config.cluster.v3.Cluster"; @@ -867,14 +868,22 @@ message Cluster { // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. - repeated core.v4alpha.Address dns_resolvers = 18; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + repeated core.v4alpha.Address hidden_envoy_deprecated_dns_resolvers = 18 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // [#next-major-version: Reconcile DNS options in a single message.] // Always use TCP queries instead of UDP queries for DNS lookups. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 45; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool hidden_envoy_deprecated_use_tcp_for_dns_lookups = 45 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + core.v4alpha.DnsResolutionConfig dns_resolution_config = 53; // If specified, outlier detection will be enabled for this upstream cluster. // Each of the configuration values can be overridden via diff --git a/generated_api_shadow/envoy/config/core/v3/resolver.proto b/generated_api_shadow/envoy/config/core/v3/resolver.proto index b5e31814f56aa..21d40425f7a6b 100644 --- a/generated_api_shadow/envoy/config/core/v3/resolver.proto +++ b/generated_api_shadow/envoy/config/core/v3/resolver.proto @@ -14,11 +14,28 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Resolver] -// DNS resolver configuration which includes the underlying dns resolver addresses and options. -message DnsResolver { - // A list of dns resolver addresses +// Configuration of DNS resolver option flags which control the behavior of the DNS resolver. +message DnsResolverOptions { + // Use TCP for all DNS queries instead of the default protocol UDP. + // Setting this value causes failure if the + // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + // server startup. Apple's API only uses UDP for DNS resolution. + bool use_tcp_for_dns_lookups = 1; + + // Do not use the default search domains; only query hostnames as-is or as aliases. + bool no_default_search_domain = 2; +} + +// DNS resolution configuration which includes the underlying dns resolver addresses and options. +message DnsResolutionConfig { + // A list of dns resolver addresses. If specified, the DNS client library will perform resolution + // via the underlying DNS resolvers. Otherwise, the default system resolvers + // (e.g., /etc/resolv.conf) will be used. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. repeated Address resolvers = 1 [(validate.rules).repeated = {min_items: 1}]; + + // Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + DnsResolverOptions dns_resolver_options = 2; } diff --git a/generated_api_shadow/envoy/config/core/v4alpha/resolver.proto b/generated_api_shadow/envoy/config/core/v4alpha/resolver.proto index ad597c85549de..4849a54161ced 100644 --- a/generated_api_shadow/envoy/config/core/v4alpha/resolver.proto +++ b/generated_api_shadow/envoy/config/core/v4alpha/resolver.proto @@ -15,13 +15,34 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // [#protodoc-title: Resolver] -// DNS resolver configuration which includes the underlying dns resolver addresses and options. -message DnsResolver { - option (udpa.annotations.versioning).previous_message_type = "envoy.config.core.v3.DnsResolver"; +// Configuration of DNS resolver option flags which control the behavior of the DNS resolver. +message DnsResolverOptions { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.core.v3.DnsResolverOptions"; - // A list of dns resolver addresses + // Use TCP for all DNS queries instead of the default protocol UDP. + // Setting this value causes failure if the + // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + // server startup. Apple's API only uses UDP for DNS resolution. + bool use_tcp_for_dns_lookups = 1; + + // Do not use the default search domains; only query hostnames as-is or as aliases. + bool no_default_search_domain = 2; +} + +// DNS resolution configuration which includes the underlying dns resolver addresses and options. +message DnsResolutionConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.core.v3.DnsResolutionConfig"; + + // A list of dns resolver addresses. If specified, the DNS client library will perform resolution + // via the underlying DNS resolvers. Otherwise, the default system resolvers + // (e.g., /etc/resolv.conf) will be used. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple's API only allows overriding DNS resolvers via system settings. repeated Address resolvers = 1 [(validate.rules).repeated = {min_items: 1}]; + + // Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + DnsResolverOptions dns_resolver_options = 2; } diff --git a/generated_api_shadow/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/BUILD b/generated_api_shadow/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..ca83092e39b11 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/clusters/dynamic_forward_proxy/v3:pkg", + "//envoy/extensions/common/dynamic_forward_proxy/v4alpha:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/cluster.proto b/generated_api_shadow/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/cluster.proto new file mode 100644 index 0000000000000..1b989e0bb725e --- /dev/null +++ b/generated_api_shadow/envoy/extensions/clusters/dynamic_forward_proxy/v4alpha/cluster.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package envoy.extensions.clusters.dynamic_forward_proxy.v4alpha; + +import "envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.clusters.dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "ClusterProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: Dynamic forward proxy cluster configuration] + +// Configuration for the dynamic forward proxy cluster. See the :ref:`architecture overview +// ` for more information. +// [#extension: envoy.clusters.dynamic_forward_proxy] +message ClusterConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig"; + + // The DNS cache configuration that the cluster will attach to. Note this configuration must + // match that of associated :ref:`dynamic forward proxy HTTP filter configuration + // `. + common.dynamic_forward_proxy.v4alpha.DnsCacheConfig dns_cache_config = 1 + [(validate.rules).message = {required: true}]; + + // If true allow the cluster configuration to disable the auto_sni and auto_san_validation options + // in the :ref:`cluster's upstream_http_protocol_options + // ` + bool allow_insecure_cluster_options = 2; +} diff --git a/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD index 6e74b985c580d..fb5436a6bf93a 100644 --- a/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD +++ b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/BUILD @@ -6,6 +6,7 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ + "//envoy/annotations:pkg", "//envoy/config/cluster/v3:pkg", "//envoy/config/common/dynamic_forward_proxy/v2alpha:pkg", "//envoy/config/core/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto index 1c14739b94c86..79d6752502094 100644 --- a/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto +++ b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v3/dns_cache.proto @@ -8,6 +8,7 @@ import "envoy/config/core/v3/resolver.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; +import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -96,15 +97,15 @@ message DnsCacheConfig { // Envoy will use dns cache circuit breakers with default settings even if this value is not set. DnsCacheCircuitBreakers dns_cache_circuit_breaker = 7; - // [#next-major-version: Reconcile DNS options in a single message.] // Always use TCP queries instead of UDP queries for DNS lookups. // Setting this value causes failure if the // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during // server startup. Apple' API only uses UDP for DNS resolution. - bool use_tcp_for_dns_lookups = 8; + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool use_tcp_for_dns_lookups = 8 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // DNS resolver configuration - // If specified, DNS cache will perform resolution via the underlying DNS resolvers. - // Otherwise, the default system resolvers (e.g., /etc/resolv.conf) will be used. - config.core.v3.DnsResolver dns_resolver = 9; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v3.DnsResolutionConfig dns_resolution_config = 9; } diff --git a/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v4alpha/BUILD b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..20571020ac927 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,15 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/annotations:pkg", + "//envoy/config/cluster/v4alpha:pkg", + "//envoy/config/core/v4alpha:pkg", + "//envoy/extensions/common/dynamic_forward_proxy/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto new file mode 100644 index 0000000000000..a9040a90dfc20 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package envoy.extensions.common.dynamic_forward_proxy.v4alpha; + +import "envoy/config/cluster/v4alpha/cluster.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/wrappers.proto"; + +import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.common.dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "DnsCacheProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: Dynamic forward proxy common configuration] + +// Configuration of circuit breakers for resolver. +message DnsCacheCircuitBreakers { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.common.dynamic_forward_proxy.v3.DnsCacheCircuitBreakers"; + + // The maximum number of pending requests that Envoy will allow to the + // resolver. If not specified, the default is 1024. + google.protobuf.UInt32Value max_pending_requests = 1; +} + +// Configuration for the dynamic forward proxy DNS cache. See the :ref:`architecture overview +// ` for more information. +// [#next-free-field: 10] +message DnsCacheConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.common.dynamic_forward_proxy.v3.DnsCacheConfig"; + + // The name of the cache. Multiple named caches allow independent dynamic forward proxy + // configurations to operate within a single Envoy process using different configurations. All + // configurations with the same name *must* otherwise have the same settings when referenced + // from different configuration components. Configuration will fail to load if this is not + // the case. + string name = 1 [(validate.rules).string = {min_len: 1}]; + + // The DNS lookup family to use during resolution. + // + // [#comment:TODO(mattklein123): Figure out how to support IPv4/IPv6 "happy eyeballs" mode. The + // way this might work is a new lookup family which returns both IPv4 and IPv6 addresses, and + // then configures a host to have a primary and fall back address. With this, we could very + // likely build a "happy eyeballs" connection pool which would race the primary / fall back + // address and return the one that wins. This same method could potentially also be used for + // QUIC to TCP fall back.] + config.cluster.v4alpha.Cluster.DnsLookupFamily dns_lookup_family = 2 + [(validate.rules).enum = {defined_only: true}]; + + // The DNS refresh rate for currently cached DNS hosts. If not specified defaults to 60s. + // + // .. note: + // + // The returned DNS TTL is not currently used to alter the refresh rate. This feature will be + // added in a future change. + // + // .. note: + // + // The refresh rate is rounded to the closest millisecond, and must be at least 1ms. + google.protobuf.Duration dns_refresh_rate = 3 + [(validate.rules).duration = {gte {nanos: 1000000}}]; + + // The TTL for hosts that are unused. Hosts that have not been used in the configured time + // interval will be purged. If not specified defaults to 5m. + // + // .. note: + // + // The TTL is only checked at the time of DNS refresh, as specified by *dns_refresh_rate*. This + // means that if the configured TTL is shorter than the refresh rate the host may not be removed + // immediately. + // + // .. note: + // + // The TTL has no relation to DNS TTL and is only used to control Envoy's resource usage. + google.protobuf.Duration host_ttl = 4 [(validate.rules).duration = {gt {}}]; + + // The maximum number of hosts that the cache will hold. If not specified defaults to 1024. + // + // .. note: + // + // The implementation is approximate and enforced independently on each worker thread, thus + // it is possible for the maximum hosts in the cache to go slightly above the configured + // value depending on timing. This is similar to how other circuit breakers work. + google.protobuf.UInt32Value max_hosts = 5 [(validate.rules).uint32 = {gt: 0}]; + + // If the DNS failure refresh rate is specified, + // this is used as the cache's DNS refresh rate when DNS requests are failing. If this setting is + // not specified, the failure refresh rate defaults to the dns_refresh_rate. + config.cluster.v4alpha.Cluster.RefreshRate dns_failure_refresh_rate = 6; + + // The config of circuit breakers for resolver. It provides a configurable threshold. + // Envoy will use dns cache circuit breakers with default settings even if this value is not set. + DnsCacheCircuitBreakers dns_cache_circuit_breaker = 7; + + // Always use TCP queries instead of UDP queries for DNS lookups. + // Setting this value causes failure if the + // ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + // server startup. Apple' API only uses UDP for DNS resolution. + // This field is deprecated in favor of *dns_resolution_config* + // which aggregates all of the DNS resolver configuration in a single message. + bool hidden_envoy_deprecated_use_tcp_for_dns_lookups = 8 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v4alpha.DnsResolutionConfig dns_resolution_config = 9; +} diff --git a/generated_api_shadow/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/BUILD b/generated_api_shadow/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..8486b45d71d91 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/common/dynamic_forward_proxy/v4alpha:pkg", + "//envoy/extensions/filters/http/dynamic_forward_proxy/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/dynamic_forward_proxy.proto b/generated_api_shadow/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/dynamic_forward_proxy.proto new file mode 100644 index 0000000000000..0dba06106b074 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/filters/http/dynamic_forward_proxy/v4alpha/dynamic_forward_proxy.proto @@ -0,0 +1,64 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.dynamic_forward_proxy.v4alpha; + +import "envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "DynamicForwardProxyProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: Dynamic forward proxy] + +// Configuration for the dynamic forward proxy HTTP filter. See the :ref:`architecture overview +// ` for more information. +// [#extension: envoy.filters.http.dynamic_forward_proxy] +message FilterConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig"; + + // The DNS cache configuration that the filter will attach to. Note this configuration must + // match that of associated :ref:`dynamic forward proxy cluster configuration + // `. + common.dynamic_forward_proxy.v4alpha.DnsCacheConfig dns_cache_config = 1 + [(validate.rules).message = {required: true}]; +} + +// Per route Configuration for the dynamic forward proxy HTTP filter. +message PerRouteConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.http.dynamic_forward_proxy.v3.PerRouteConfig"; + + oneof host_rewrite_specifier { + // Indicates that before DNS lookup, the host header will be swapped with + // this value. If not set or empty, the original host header value + // will be used and no rewrite will happen. + // + // Note: this rewrite affects both DNS lookup and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite ` given that the + // value set here would be used for DNS lookups whereas the value set in the HCM would be used + // for host header forwarding which is not the desired outcome. + string host_rewrite_literal = 1; + + // Indicates that before DNS lookup, the host header will be swapped with + // the value of this header. If not set or empty, the original host header + // value will be used and no rewrite will happen. + // + // Note: this rewrite affects both DNS lookup and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite header ` + // given that the value set here would be used for DNS lookups whereas the value set in the HCM + // would be used for host header forwarding which is not the desired outcome. + // + // .. note:: + // + // If the header appears multiple times only the first value is used. + string host_rewrite_header = 2; + } +} diff --git a/generated_api_shadow/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/BUILD b/generated_api_shadow/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/BUILD new file mode 100644 index 0000000000000..465ea4ff28449 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/common/dynamic_forward_proxy/v4alpha:pkg", + "//envoy/extensions/filters/network/sni_dynamic_forward_proxy/v3alpha:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/sni_dynamic_forward_proxy.proto b/generated_api_shadow/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/sni_dynamic_forward_proxy.proto new file mode 100644 index 0000000000000..de2947fcba9ec --- /dev/null +++ b/generated_api_shadow/envoy/extensions/filters/network/sni_dynamic_forward_proxy/v4alpha/sni_dynamic_forward_proxy.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package envoy.extensions.filters.network.sni_dynamic_forward_proxy.v4alpha; + +import "envoy/extensions/common/dynamic_forward_proxy/v4alpha/dns_cache.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.network.sni_dynamic_forward_proxy.v4alpha"; +option java_outer_classname = "SniDynamicForwardProxyProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).work_in_progress = true; +option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; + +// [#protodoc-title: SNI dynamic forward proxy] + +// Configuration for the SNI-based dynamic forward proxy filter. See the +// :ref:`architecture overview ` for +// more information. Note this filter must be configured along with +// :ref:`TLS inspector listener filter ` +// to work. +// [#extension: envoy.filters.network.sni_dynamic_forward_proxy] +message FilterConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.network.sni_dynamic_forward_proxy.v3alpha.FilterConfig"; + + // The DNS cache configuration that the filter will attach to. Note this + // configuration must match that of associated :ref:`dynamic forward proxy + // cluster configuration + // `. + common.dynamic_forward_proxy.v4alpha.DnsCacheConfig dns_cache_config = 1 + [(validate.rules).message = {required: true}]; + + oneof port_specifier { + // The port number to connect to the upstream. + uint32 port_value = 2 [(validate.rules).uint32 = {lte: 65535 gt: 0}]; + } +} diff --git a/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto b/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto index 32103540c1d2b..8221c11efbe78 100644 --- a/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto +++ b/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v3alpha/dns_filter.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package envoy.extensions.filters.udp.dns_filter.v3alpha; -import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; +import "envoy/config/core/v3/resolver.proto"; import "envoy/data/dns/v3/dns_table.proto"; import "google/protobuf/duration.proto"; @@ -51,10 +51,8 @@ message DnsFilterConfig { // number of retries multiplied by the resolver_timeout. google.protobuf.Duration resolver_timeout = 1 [(validate.rules).duration = {gte {seconds: 1}}]; - // A list of DNS servers to which we can forward queries. If not - // specified, Envoy will use the ambient DNS resolvers in the - // system. - repeated config.core.v3.Address upstream_resolvers = 2; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v3.DnsResolutionConfig dns_resolution_config = 2; // Controls how many outstanding external lookup contexts the filter tracks. // The context structure allows the filter to respond to every query even if the external diff --git a/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto b/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto index 54615b8b93ed8..6957e58dbb068 100644 --- a/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto +++ b/generated_api_shadow/envoy/extensions/filters/udp/dns_filter/v4alpha/dns_filter.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package envoy.extensions.filters.udp.dns_filter.v4alpha; -import "envoy/config/core/v4alpha/address.proto"; import "envoy/config/core/v4alpha/base.proto"; +import "envoy/config/core/v4alpha/resolver.proto"; import "envoy/data/dns/v4alpha/dns_table.proto"; import "google/protobuf/duration.proto"; @@ -61,10 +61,8 @@ message DnsFilterConfig { // number of retries multiplied by the resolver_timeout. google.protobuf.Duration resolver_timeout = 1 [(validate.rules).duration = {gte {seconds: 1}}]; - // A list of DNS servers to which we can forward queries. If not - // specified, Envoy will use the ambient DNS resolvers in the - // system. - repeated config.core.v4alpha.Address upstream_resolvers = 2; + // DNS resolution configuration which includes the underlying dns resolver addresses and options. + config.core.v4alpha.DnsResolutionConfig dns_resolution_config = 2; // Controls how many outstanding external lookup contexts the filter tracks. // The context structure allows the filter to respond to every query even if the external diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 1618c9236d178..867fd651234a2 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -8,6 +8,7 @@ #include "envoy/common/scope_tracker.h" #include "envoy/common/time.h" +#include "envoy/config/core/v3/resolver.pb.h" #include "envoy/config/core/v3/udp_socket_config.pb.h" #include "envoy/event/dispatcher_thread_deletable.h" #include "envoy/event/file_event.h" @@ -208,13 +209,13 @@ class Dispatcher : public DispatcherBase { * dispatcher. * @param resolvers supplies the addresses of DNS resolvers that this resolver should use. If left * empty, it will not use any specific resolvers, but use defaults (/etc/resolv.conf) - * @param use_tcp_for_dns_lookups if set to true, tcp will be used to perform dns lookups. - * Otherwise, udp is used. + * @param dns_resolver_options supplies the aggregated area options flags needed for dns resolver + * init. * @return Network::DnsResolverSharedPtr that is owned by the caller. */ virtual Network::DnsResolverSharedPtr createDnsResolver(const std::vector& resolvers, - bool use_tcp_for_dns_lookups) PURE; + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) PURE; /** * @return Filesystem::WatcherPtr a filesystem watcher owned by the caller. diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index b3ff5128eb781..fa4f98e747ddc 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -157,7 +157,7 @@ DispatcherImpl::createClientConnection(Network::Address::InstanceConstSharedPtr Network::DnsResolverSharedPtr DispatcherImpl::createDnsResolver( const std::vector& resolvers, - const bool use_tcp_for_dns_lookups) { + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) { ASSERT(isThreadSafe()); #ifdef __APPLE__ static bool use_apple_api_for_dns_lookups = @@ -169,7 +169,7 @@ Network::DnsResolverSharedPtr DispatcherImpl::createDnsResolver( "Apple's API only allows overriding DNS resolvers via system settings. Delete resolvers " "config or disable the envoy.restart_features.use_apple_api_for_dns_lookups runtime " "feature."); - RELEASE_ASSERT(!use_tcp_for_dns_lookups, + RELEASE_ASSERT(!dns_resolver_options.use_tcp_for_dns_lookups(), "using TCP for DNS lookups is not possible when using Apple APIs for DNS " "resolution. Apple' API only uses UDP for DNS resolution. Use UDP or disable " "the envoy.restart_features.use_apple_api_for_dns_lookups runtime feature."); @@ -177,7 +177,7 @@ Network::DnsResolverSharedPtr DispatcherImpl::createDnsResolver( api_.rootScope()); } #endif - return std::make_shared(*this, resolvers, use_tcp_for_dns_lookups); + return std::make_shared(*this, resolvers, dns_resolver_options); } FileEventPtr DispatcherImpl::createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index fe16145e7cd2d..12df2c5030c14 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -66,9 +66,9 @@ class DispatcherImpl : Logger::Loggable, Network::Address::InstanceConstSharedPtr source_address, Network::TransportSocketPtr&& transport_socket, const Network::ConnectionSocket::OptionsSharedPtr& options) override; - Network::DnsResolverSharedPtr - createDnsResolver(const std::vector& resolvers, - const bool use_tcp_for_dns_lookups) override; + Network::DnsResolverSharedPtr createDnsResolver( + const std::vector& resolvers, + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) override; FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) override; Filesystem::WatcherPtr createFilesystemWatcher() override; diff --git a/source/common/network/dns_impl.cc b/source/common/network/dns_impl.cc index c2b0411a9696b..1adaa9656c0e6 100644 --- a/source/common/network/dns_impl.cc +++ b/source/common/network/dns_impl.cc @@ -23,10 +23,10 @@ namespace Network { DnsResolverImpl::DnsResolverImpl( Event::Dispatcher& dispatcher, const std::vector& resolvers, - const bool use_tcp_for_dns_lookups) + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) : dispatcher_(dispatcher), timer_(dispatcher.createTimer([this] { onEventCallback(ARES_SOCKET_BAD, 0); })), - use_tcp_for_dns_lookups_(use_tcp_for_dns_lookups), + dns_resolver_options_(dns_resolver_options), resolvers_csv_(maybeBuildResolversCsv(resolvers)) { AresOptions options = defaultAresOptions(); initializeChannel(&options.options_, options.optmask_); @@ -66,11 +66,16 @@ absl::optional DnsResolverImpl::maybeBuildResolversCsv( DnsResolverImpl::AresOptions DnsResolverImpl::defaultAresOptions() { AresOptions options{}; - if (use_tcp_for_dns_lookups_) { + if (dns_resolver_options_.use_tcp_for_dns_lookups()) { options.optmask_ |= ARES_OPT_FLAGS; options.options_.flags |= ARES_FLAG_USEVC; } + if (dns_resolver_options_.no_default_search_domain()) { + options.optmask_ |= ARES_OPT_FLAGS; + options.options_.flags |= ARES_FLAG_NOSEARCH; + } + return options; } diff --git a/source/common/network/dns_impl.h b/source/common/network/dns_impl.h index ace150273f31a..d03aacbb46d14 100644 --- a/source/common/network/dns_impl.h +++ b/source/common/network/dns_impl.h @@ -28,7 +28,7 @@ class DnsResolverImpl : public DnsResolver, protected Logger::Loggable& resolvers, - const bool use_tcp_for_dns_lookups); + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options); ~DnsResolverImpl() override; // Network::DnsResolver @@ -106,7 +106,8 @@ class DnsResolverImpl : public DnsResolver, protected Logger::Loggable events_; const absl::optional resolvers_csv_; }; diff --git a/source/common/upstream/cluster_factory_impl.cc b/source/common/upstream/cluster_factory_impl.cc index b9c21a75429ad..71d7fa9e9225b 100644 --- a/source/common/upstream/cluster_factory_impl.cc +++ b/source/common/upstream/cluster_factory_impl.cc @@ -89,15 +89,32 @@ ClusterFactoryImplBase::selectDnsResolver(const envoy::config::cluster::v3::Clus // where 'dns_resolvers' is specified, we have per-cluster DNS // resolvers that are created here but ownership resides with // StrictDnsClusterImpl/LogicalDnsCluster. - if (!cluster.dns_resolvers().empty()) { - const auto& resolver_addrs = cluster.dns_resolvers(); + if ((cluster.has_dns_resolution_config() && + !cluster.dns_resolution_config().resolvers().empty()) || + !cluster.dns_resolvers().empty()) { + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; std::vector resolvers; - resolvers.reserve(resolver_addrs.size()); - for (const auto& resolver_addr : resolver_addrs) { - resolvers.push_back(Network::Address::resolveProtoAddress(resolver_addr)); + Protobuf::RepeatedPtrField resolver_addrs; + if (cluster.has_dns_resolution_config()) { + dns_resolver_options.CopyFrom(cluster.dns_resolution_config().dns_resolver_options()); + resolver_addrs.CopyFrom(cluster.dns_resolution_config().resolvers()); + } else { + /* if `cluster.dns_resolution_config` is not set. */ + // Field bool `use_tcp_for_dns_lookups` will be deprecated in future. To be backward + // compatible utilize cluster.use_tcp_for_dns_lookups(). + dns_resolver_options.set_use_tcp_for_dns_lookups(cluster.use_tcp_for_dns_lookups()); + // Field repeated Address `dns_resolvers` will be deprecated in future. To be backward + // compatible utilize cluster.dns_resolvers(). + resolver_addrs.CopyFrom(cluster.dns_resolvers()); + } + + if (!resolver_addrs.empty()) { + resolvers.reserve(resolver_addrs.size()); + for (const auto& resolver_addr : resolver_addrs) { + resolvers.push_back(Network::Address::resolveProtoAddress(resolver_addr)); + } } - const bool use_tcp_for_dns_lookups = cluster.use_tcp_for_dns_lookups(); - return context.dispatcher().createDnsResolver(resolvers, use_tcp_for_dns_lookups); + return context.dispatcher().createDnsResolver(resolvers, dns_resolver_options); } return context.dnsResolver(); diff --git a/source/extensions/common/dynamic_forward_proxy/BUILD b/source/extensions/common/dynamic_forward_proxy/BUILD index 19d6138696182..618ec12bedea8 100644 --- a/source/extensions/common/dynamic_forward_proxy/BUILD +++ b/source/extensions/common/dynamic_forward_proxy/BUILD @@ -44,6 +44,7 @@ envoy_cc_library( "//include/envoy/thread_local:thread_local_interface", "//source/common/common:cleanup_lib", "//source/common/config:utility_lib", + "//source/common/network:resolver_lib", "//source/common/network:utility_lib", "//source/common/upstream:upstream_lib", "@envoy_api//envoy/extensions/common/dynamic_forward_proxy/v3:pkg_cc_proto", diff --git a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc index 2aa86bbb80ba4..585ef3f0793f3 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc @@ -50,17 +50,24 @@ DnsCacheImpl::~DnsCacheImpl() { Network::DnsResolverSharedPtr DnsCacheImpl::selectDnsResolver( const envoy::extensions::common::dynamic_forward_proxy::v3::DnsCacheConfig& config, Event::Dispatcher& main_thread_dispatcher) { - if (config.has_dns_resolver()) { - const auto& resolver_addrs = config.dns_resolver().resolvers(); - std::vector resolvers; - resolvers.reserve(resolver_addrs.size()); - for (const auto& resolver_addr : resolver_addrs) { - resolvers.push_back(Network::Address::resolveProtoAddress(resolver_addr)); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + std::vector resolvers; + if (config.has_dns_resolution_config()) { + dns_resolver_options.CopyFrom(config.dns_resolution_config().dns_resolver_options()); + if (!config.dns_resolution_config().resolvers().empty()) { + const auto& resolver_addrs = config.dns_resolution_config().resolvers(); + resolvers.reserve(resolver_addrs.size()); + for (const auto& resolver_addr : resolver_addrs) { + resolvers.push_back(Network::Address::resolveProtoAddress(resolver_addr)); + } } - return main_thread_dispatcher.createDnsResolver(resolvers, config.use_tcp_for_dns_lookups()); + } else { + // Field bool `use_tcp_for_dns_lookups` will be deprecated in future. To be backward + // compatible utilize config.use_tcp_for_dns_lookups() if `config.dns_resolution_config` + // is not set. + dns_resolver_options.set_use_tcp_for_dns_lookups(config.use_tcp_for_dns_lookups()); } - - return main_thread_dispatcher.createDnsResolver({}, config.use_tcp_for_dns_lookups()); + return main_thread_dispatcher.createDnsResolver(resolvers, dns_resolver_options); } DnsCacheStats DnsCacheImpl::generateDnsCacheStats(Stats::Scope& scope) { diff --git a/source/extensions/common/wasm/wasm.cc b/source/extensions/common/wasm/wasm.cc index c037c988c28ac..c1e7d91a11cda 100644 --- a/source/extensions/common/wasm/wasm.cc +++ b/source/extensions/common/wasm/wasm.cc @@ -187,7 +187,8 @@ Word resolve_dns(void* raw_context, Word dns_address_ptr, Word dns_address_size, root_context->onResolveDns(token, status, std::move(response)); }; if (!context->wasm()->dnsResolver()) { - context->wasm()->dnsResolver() = context->wasm()->dispatcher().createDnsResolver({}, false); + context->wasm()->dnsResolver() = context->wasm()->dispatcher().createDnsResolver( + {}, envoy::config::core::v3::DnsResolverOptions()); } context->wasm()->dnsResolver()->resolve(std::string(address.value()), Network::DnsLookupFamily::Auto, callback); diff --git a/source/extensions/filters/udp/dns_filter/dns_filter.cc b/source/extensions/filters/udp/dns_filter/dns_filter.cc index 206a264f28b46..331f280c2f99f 100644 --- a/source/extensions/filters/udp/dns_filter/dns_filter.cc +++ b/source/extensions/filters/udp/dns_filter/dns_filter.cc @@ -140,15 +140,18 @@ DnsFilterEnvoyConfig::DnsFilterEnvoyConfig( forward_queries_ = config.has_client_config(); if (forward_queries_) { const auto& client_config = config.client_config(); - const auto& upstream_resolvers = client_config.upstream_resolvers(); - resolvers_.reserve(upstream_resolvers.size()); - for (const auto& resolver : upstream_resolvers) { - auto ipaddr = Network::Utility::protobufAddressToAddress(resolver); - resolvers_.emplace_back(std::move(ipaddr)); + if (client_config.has_dns_resolution_config()) { + dns_resolver_options_.CopyFrom(client_config.dns_resolution_config().dns_resolver_options()); + if (!client_config.dns_resolution_config().resolvers().empty()) { + const auto& resolver_addrs = client_config.dns_resolution_config().resolvers(); + resolvers_.reserve(resolver_addrs.size()); + for (const auto& resolver_addr : resolver_addrs) { + resolvers_.push_back(Network::Utility::protobufAddressToAddress(resolver_addr)); + } + } } resolver_timeout_ = std::chrono::milliseconds(PROTOBUF_GET_MS_OR_DEFAULT( client_config, resolver_timeout, DEFAULT_RESOLVER_TIMEOUT.count())); - max_pending_lookups_ = client_config.max_pending_lookups(); } } @@ -220,9 +223,9 @@ DnsFilter::DnsFilter(Network::UdpReadFilterCallbacks& callbacks, sendDnsResponse(std::move(context)); }; - resolver_ = std::make_unique(resolver_callback_, config->resolvers(), - config->resolverTimeout(), listener_.dispatcher(), - config->maxPendingLookups()); + resolver_ = std::make_unique( + resolver_callback_, config->resolvers(), config->resolverTimeout(), listener_.dispatcher(), + config->maxPendingLookups(), config->dnsResolverOptions()); } void DnsFilter::onData(Network::UdpRecvData& client_request) { diff --git a/source/extensions/filters/udp/dns_filter/dns_filter.h b/source/extensions/filters/udp/dns_filter/dns_filter.h index 3a02f39db20aa..ea12d3b08fe68 100644 --- a/source/extensions/filters/udp/dns_filter/dns_filter.h +++ b/source/extensions/filters/udp/dns_filter/dns_filter.h @@ -93,6 +93,9 @@ class DnsFilterEnvoyConfig : public Logger::Loggable { uint64_t retryCount() const { return retry_count_; } Random::RandomGenerator& random() const { return random_; } uint64_t maxPendingLookups() const { return max_pending_lookups_; } + const envoy::config::core::v3::DnsResolverOptions& dnsResolverOptions() const { + return dns_resolver_options_; + } private: static DnsFilterStats generateStats(const std::string& stat_prefix, Stats::Scope& scope) { @@ -120,6 +123,7 @@ class DnsFilterEnvoyConfig : public Logger::Loggable { std::chrono::milliseconds resolver_timeout_; Random::RandomGenerator& random_; uint64_t max_pending_lookups_; + envoy::config::core::v3::DnsResolverOptions dns_resolver_options_; }; using DnsFilterEnvoyConfigSharedPtr = std::shared_ptr; diff --git a/source/extensions/filters/udp/dns_filter/dns_filter_resolver.h b/source/extensions/filters/udp/dns_filter/dns_filter_resolver.h index 23372871a618f..bed8585c86c3c 100644 --- a/source/extensions/filters/udp/dns_filter/dns_filter_resolver.h +++ b/source/extensions/filters/udp/dns_filter/dns_filter_resolver.h @@ -20,9 +20,10 @@ class DnsFilterResolver : Logger::Loggable { public: DnsFilterResolver(DnsFilterResolverCallback& callback, AddressConstPtrVec resolvers, std::chrono::milliseconds timeout, Event::Dispatcher& dispatcher, - uint64_t max_pending_lookups) + uint64_t max_pending_lookups, + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) : timeout_(timeout), dispatcher_(dispatcher), - resolver_(dispatcher.createDnsResolver(resolvers, false /* use_tcp_for_dns_lookups */)), + resolver_(dispatcher.createDnsResolver(resolvers, dns_resolver_options)), callback_(callback), max_pending_lookups_(max_pending_lookups) {} /** * @brief entry point to resolve the name in a DnsQueryRecord diff --git a/source/server/config_validation/dispatcher.cc b/source/server/config_validation/dispatcher.cc index 3316f58065c2b..6bbd96106ea38 100644 --- a/source/server/config_validation/dispatcher.cc +++ b/source/server/config_validation/dispatcher.cc @@ -17,7 +17,8 @@ Network::ClientConnectionPtr ValidationDispatcher::createClientConnection( } Network::DnsResolverSharedPtr ValidationDispatcher::createDnsResolver( - const std::vector&, const bool) { + const std::vector&, + const envoy::config::core::v3::DnsResolverOptions&) { return dns_resolver_; } diff --git a/source/server/config_validation/dispatcher.h b/source/server/config_validation/dispatcher.h index b5deea61f58db..960e29f1ad30b 100644 --- a/source/server/config_validation/dispatcher.h +++ b/source/server/config_validation/dispatcher.h @@ -23,9 +23,9 @@ class ValidationDispatcher : public DispatcherImpl { createClientConnection(Network::Address::InstanceConstSharedPtr, Network::Address::InstanceConstSharedPtr, Network::TransportSocketPtr&&, const Network::ConnectionSocket::OptionsSharedPtr& options) override; - Network::DnsResolverSharedPtr - createDnsResolver(const std::vector& resolvers, - const bool use_tcp_for_dns_lookups) override; + Network::DnsResolverSharedPtr createDnsResolver( + const std::vector& resolvers, + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) override; Network::ListenerPtr createListener(Network::SocketSharedPtr&&, Network::TcpListenerCallbacks&, bool bind_to_port, uint32_t backlog_size) override; diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index 1919a6643ad85..6d41f10d2799e 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -75,7 +75,7 @@ class ValidationInstance final : Logger::Loggable, Ssl::ContextManager& sslContextManager() override { return *ssl_context_manager_; } Event::Dispatcher& dispatcher() override { return *dispatcher_; } Network::DnsResolverSharedPtr dnsResolver() override { - return dispatcher().createDnsResolver({}, false); + return dispatcher().createDnsResolver({}, envoy::config::core::v3::DnsResolverOptions()); } void drainListeners() override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } DrainManager& drainManager() override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } diff --git a/source/server/server.cc b/source/server/server.cc index 920bd37f55e41..8661d3c570cf6 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -543,8 +543,23 @@ void InstanceImpl::initialize(const Options& options, // Once we have runtime we can initialize the SSL context manager. ssl_context_manager_ = createContextManager("ssl_context_manager", time_source_); - const bool use_tcp_for_dns_lookups = bootstrap_.use_tcp_for_dns_lookups(); - dns_resolver_ = dispatcher_->createDnsResolver({}, use_tcp_for_dns_lookups); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + std::vector resolvers; + if (bootstrap_.has_dns_resolution_config()) { + dns_resolver_options.CopyFrom(bootstrap_.dns_resolution_config().dns_resolver_options()); + if (!bootstrap_.dns_resolution_config().resolvers().empty()) { + const auto& resolver_addrs = bootstrap_.dns_resolution_config().resolvers(); + resolvers.reserve(resolver_addrs.size()); + for (const auto& resolver_addr : resolver_addrs) { + resolvers.push_back(Network::Address::resolveProtoAddress(resolver_addr)); + } + } + } else { + // Field bool `use_tcp_for_dns_lookups` will be deprecated in future. To be backward compatible + // utilize bootstrap_.use_tcp_for_dns_lookups() if `bootstrap_.dns_resolver_options` is not set. + dns_resolver_options.set_use_tcp_for_dns_lookups(bootstrap_.use_tcp_for_dns_lookups()); + } + dns_resolver_ = dispatcher_->createDnsResolver(resolvers, dns_resolver_options); cluster_manager_factory_ = std::make_unique( *admin_, Runtime::LoaderSingleton::get(), stats_store_, thread_local_, dns_resolver_, diff --git a/test/common/network/apple_dns_impl_test.cc b/test/common/network/apple_dns_impl_test.cc index 66cc2921300bb..75f666576da06 100644 --- a/test/common/network/apple_dns_impl_test.cc +++ b/test/common/network/apple_dns_impl_test.cc @@ -62,7 +62,9 @@ class AppleDnsImplTest : public testing::Test { AppleDnsImplTest() : api_(Api::createApiForTest()), dispatcher_(api_->allocateDispatcher("test_thread")) {} - void SetUp() override { resolver_ = dispatcher_->createDnsResolver({}, false); } + void SetUp() override { + resolver_ = dispatcher_->createDnsResolver({}, envoy::config::core::v3::DnsResolverOptions()); + } ActiveDnsQuery* resolveWithExpectations(const std::string& address, const DnsLookupFamily lookup_family, @@ -118,12 +120,14 @@ class AppleDnsImplTest : public testing::Test { }; TEST_F(AppleDnsImplTest, InvalidConfigOptions) { + auto dns_resolver_options = envoy::config::core::v3::DnsResolverOptions(); EXPECT_DEATH( - dispatcher_->createDnsResolver({}, true), - "using TCP for DNS lookups is not possible when using Apple APIs for DNS resolution"); - EXPECT_DEATH( - dispatcher_->createDnsResolver({nullptr}, false), + dispatcher_->createDnsResolver({nullptr}, dns_resolver_options), "defining custom resolvers is not possible when using Apple APIs for DNS resolution"); + dns_resolver_options.set_use_tcp_for_dns_lookups(true); + EXPECT_DEATH( + dispatcher_->createDnsResolver({}, dns_resolver_options), + "using TCP for DNS lookups is not possible when using Apple APIs for DNS resolution"); } // Validate that when AppleDnsResolverImpl is destructed with outstanding requests, diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 47476fa76a32f..8305acf032d81 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -348,6 +348,7 @@ class DnsImplConstructor : public testing::Test { Api::ApiPtr api_; Event::DispatcherPtr dispatcher_; + envoy::config::core::v3::DnsResolverOptions dns_resolver_options_; }; TEST_F(DnsImplConstructor, SupportsCustomResolvers) { @@ -357,7 +358,7 @@ TEST_F(DnsImplConstructor, SupportsCustomResolvers) { auto addr4 = Network::Utility::parseInternetAddressAndPort("127.0.0.1:54"); char addr6str[INET6_ADDRSTRLEN]; auto addr6 = Network::Utility::parseInternetAddressAndPort("[::1]:54"); - auto resolver = dispatcher_->createDnsResolver({addr4, addr6}, false); + auto resolver = dispatcher_->createDnsResolver({addr4, addr6}, dns_resolver_options_); auto peer = std::make_unique(dynamic_cast(resolver.get())); ares_addr_port_node* resolvers; int result = ares_get_servers_ports(peer->channel(), &resolvers); @@ -408,7 +409,7 @@ class CustomInstance : public Address::Instance { TEST_F(DnsImplConstructor, SupportCustomAddressInstances) { auto test_instance(std::make_shared("127.0.0.1", 45)); EXPECT_EQ(test_instance->asString(), "127.0.0.1:borked_port_45"); - auto resolver = dispatcher_->createDnsResolver({test_instance}, false); + auto resolver = dispatcher_->createDnsResolver({test_instance}, dns_resolver_options_); auto peer = std::make_unique(dynamic_cast(resolver.get())); ares_addr_port_node* resolvers; int result = ares_get_servers_ports(peer->channel(), &resolvers); @@ -424,8 +425,8 @@ TEST_F(DnsImplConstructor, BadCustomResolvers) { envoy::config::core::v3::Address pipe_address; pipe_address.mutable_pipe()->set_path("foo"); auto pipe_instance = Network::Utility::protobufAddressToAddress(pipe_address); - EXPECT_THROW_WITH_MESSAGE(dispatcher_->createDnsResolver({pipe_instance}, false), EnvoyException, - "DNS resolver 'foo' is not an IP address"); + EXPECT_THROW_WITH_MESSAGE(dispatcher_->createDnsResolver({pipe_instance}, dns_resolver_options_), + EnvoyException, "DNS resolver 'foo' is not an IP address"); } class DnsImplTest : public testing::TestWithParam { @@ -439,12 +440,12 @@ class DnsImplTest : public testing::TestWithParam { socket_ = std::make_shared( Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true); listener_ = dispatcher_->createListener(socket_, *server_, true, ENVOY_TCP_BACKLOG_SIZE); - + updateDnsResolverOptions(); if (setResolverInConstructor()) { resolver_ = dispatcher_->createDnsResolver({socket_->addressProvider().localAddress()}, - useTcpForDnsLookups()); + dns_resolver_options_); } else { - resolver_ = dispatcher_->createDnsResolver({}, useTcpForDnsLookups()); + resolver_ = dispatcher_->createDnsResolver({}, dns_resolver_options_); } // Point c-ares at the listener with no search domains and TCP-only. @@ -547,7 +548,7 @@ class DnsImplTest : public testing::TestWithParam { // Should the DnsResolverImpl use a zero timeout for c-ares queries? virtual bool zeroTimeout() const { return false; } virtual bool tcpOnly() const { return true; } - virtual bool useTcpForDnsLookups() const { return false; } + virtual void updateDnsResolverOptions(){}; virtual bool setResolverInConstructor() const { return false; } std::unique_ptr server_; std::unique_ptr peer_; @@ -556,6 +557,7 @@ class DnsImplTest : public testing::TestWithParam { Api::ApiPtr api_; Event::DispatcherPtr dispatcher_; DnsResolverSharedPtr resolver_; + envoy::config::core::v3::DnsResolverOptions dns_resolver_options_; }; // Parameterize the DNS test server socket address. @@ -876,7 +878,7 @@ TEST_P(DnsImplTest, PendingTimerEnable) { Event::MockDispatcher dispatcher; Event::MockTimer* timer = new NiceMock(); EXPECT_CALL(dispatcher, createTimer_(_)).WillOnce(Return(timer)); - resolver_ = std::make_shared(dispatcher, vec, false); + resolver_ = std::make_shared(dispatcher, vec, dns_resolver_options_); Event::FileEvent* file_event = new NiceMock(); EXPECT_CALL(dispatcher, createFileEvent_(_, _, _, _)).WillOnce(Return(file_event)); EXPECT_CALL(*timer, enableTimer(_, _)); @@ -907,7 +909,9 @@ TEST_P(DnsImplZeroTimeoutTest, Timeout) { class DnsImplAresFlagsForTcpTest : public DnsImplTest { protected: bool tcpOnly() const override { return false; } - bool useTcpForDnsLookups() const override { return true; } + void updateDnsResolverOptions() override { + dns_resolver_options_.set_use_tcp_for_dns_lookups(true); + } }; // Parameterize the DNS test server socket address. @@ -918,14 +922,41 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplAresFlagsForTcpTest, // Validate that c_ares flag `ARES_FLAG_USEVC` is set when boolean property // `use_tcp_for_dns_lookups` is enabled. TEST_P(DnsImplAresFlagsForTcpTest, TcpLookupsEnabled) { - server_->addCName("root.cnam.domain", "result.cname.domain"); + server_->addCName("root.cname.domain", "result.cname.domain"); server_->addHosts("result.cname.domain", {"201.134.56.7"}, RecordType::A); ares_options opts{}; int optmask = 0; EXPECT_EQ(ARES_SUCCESS, ares_save_options(peer_->channel(), &opts, &optmask)); EXPECT_TRUE((opts.flags & ARES_FLAG_USEVC) == ARES_FLAG_USEVC); EXPECT_NE(nullptr, - resolveWithUnreferencedParameters("root.cnam.domain", DnsLookupFamily::Auto, true)); + resolveWithUnreferencedParameters("root.cname.domain", DnsLookupFamily::Auto, true)); + ares_destroy_options(&opts); +} + +class DnsImplAresFlagsForNoDefaultSearchDomainTest : public DnsImplTest { +protected: + bool tcpOnly() const override { return false; } + void updateDnsResolverOptions() override { + dns_resolver_options_.set_no_default_search_domain(true); + } +}; + +// Parameterize the DNS test server socket address. +INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplAresFlagsForNoDefaultSearchDomainTest, + testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), + TestUtility::ipTestParamsToString); + +// Validate that c_ares flag `ARES_FLAG_NOSEARCH` is set when boolean property +// `no_default_search_domain` is enabled. +TEST_P(DnsImplAresFlagsForNoDefaultSearchDomainTest, NoDefaultSearchDomainSet) { + server_->addCName("root.cname.domain", "result.cname.domain"); + server_->addHosts("result.cname.domain", {"201.134.56.7"}, RecordType::A); + ares_options opts{}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(peer_->channel(), &opts, &optmask)); + EXPECT_TRUE((opts.flags & ARES_FLAG_NOSEARCH) == ARES_FLAG_NOSEARCH); + EXPECT_NE(nullptr, + resolveWithUnreferencedParameters("root.cname.domain", DnsLookupFamily::Auto, true)); ares_destroy_options(&opts); } @@ -942,20 +973,47 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplAresFlagsForUdpTest, // Validate that c_ares flag `ARES_FLAG_USEVC` is not set when boolean property // `use_tcp_for_dns_lookups` is disabled. TEST_P(DnsImplAresFlagsForUdpTest, UdpLookupsEnabled) { - server_->addCName("root.cnam.domain", "result.cname.domain"); + server_->addCName("root.cname.domain", "result.cname.domain"); server_->addHosts("result.cname.domain", {"201.134.56.7"}, RecordType::A); ares_options opts{}; int optmask = 0; EXPECT_EQ(ARES_SUCCESS, ares_save_options(peer_->channel(), &opts, &optmask)); EXPECT_FALSE((opts.flags & ARES_FLAG_USEVC) == ARES_FLAG_USEVC); EXPECT_NE(nullptr, - resolveWithUnreferencedParameters("root.cnam.domain", DnsLookupFamily::Auto, true)); + resolveWithUnreferencedParameters("root.cname.domain", DnsLookupFamily::Auto, true)); + ares_destroy_options(&opts); +} + +class DnsImplAresFlagsForDefaultSearchDomainTest : public DnsImplTest { +protected: + bool tcpOnly() const override { return false; } + void updateDnsResolverOptions() override {} +}; + +// Parameterize the DNS test server socket address. +INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplAresFlagsForDefaultSearchDomainTest, + testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), + TestUtility::ipTestParamsToString); + +// Validate that c_ares flag `ARES_FLAG_NOSEARCH` is not set when boolean property +// `no_default_search_domain` is disabled. +TEST_P(DnsImplAresFlagsForDefaultSearchDomainTest, NoDefaultSearchDomainNotSet) { + server_->addCName("root.cname.domain", "result.cname.domain"); + server_->addHosts("result.cname.domain", {"201.134.56.7"}, RecordType::A); + ares_options opts{}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(peer_->channel(), &opts, &optmask)); + EXPECT_FALSE((opts.flags & ARES_FLAG_NOSEARCH) == ARES_FLAG_NOSEARCH); + EXPECT_NE(nullptr, + resolveWithUnreferencedParameters("root.cname.domain", DnsLookupFamily::Auto, true)); ares_destroy_options(&opts); } class DnsImplCustomResolverTest : public DnsImplTest { bool tcpOnly() const override { return false; } - bool useTcpForDnsLookups() const override { return true; } + void updateDnsResolverOptions() override { + dns_resolver_options_.set_use_tcp_for_dns_lookups(true); + } bool setResolverInConstructor() const override { return true; } }; diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index d15250242ab6b..3c2b50ebdd399 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -5,6 +5,7 @@ #include "envoy/config/core/v3/base.pb.h" #include "common/network/raw_buffer_socket.h" +#include "common/network/resolver_impl.h" #include "common/router/context_impl.h" #include "extensions/transport_sockets/raw_buffer/config.h" @@ -155,6 +156,10 @@ class ClusterManagerImplTest : public testing::Test { Router::ContextImpl router_context_; }; +MATCHER_P(CustomDnsResolversSizeEquals, expectedResolvers, "") { + return expectedResolvers.size() == arg.size(); +} + envoy::config::bootstrap::v3::Bootstrap defaultConfig() { const std::string yaml = R"EOF( static_resources: @@ -1991,10 +1996,11 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemove) { connect_timeout: 0.250s type: STRICT_DNS lb_policy: ROUND_ROBIN - dns_resolvers: - - socket_address: - address: 1.2.3.4 - port_value: 80 + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 load_assignment: cluster_name: cluster_1 endpoints: @@ -2136,10 +2142,11 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { - name: cluster_1 connect_timeout: 0.250s type: STRICT_DNS - dns_resolvers: - - socket_address: - address: 1.2.3.4 - port_value: 80 + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 lb_policy: ROUND_ROBIN load_assignment: cluster_name: cluster_1 @@ -2374,10 +2381,14 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { } // Test that default DNS resolver with TCP lookups is used, when there are no DNS custom resolvers -// configured per cluster and `use_tcp_for_dns_lookups` is set in bootstrap config. +// configured per cluster and `dns_resolver_options.use_tcp_for_dns_lookups` is set in bootstrap +// config. TEST_F(ClusterManagerImplTest, UseTcpInDefaultDnsResolver) { const std::string yaml = R"EOF( - use_tcp_for_dns_lookups: true + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: true + no_default_search_domain: true static_resources: clusters: - name: cluster_1 @@ -2398,9 +2409,9 @@ TEST_F(ClusterManagerImplTest, UseTcpInDefaultDnsResolver) { factory_.tls_.shutdownThread(); } -// Test that custom DNS resolver with UDP lookups is used, when custom resolver is configured -// per cluster and `use_tcp_for_dns_lookups` is not specified. -TEST_F(ClusterManagerImplTest, UseUdpWithCustomDnsResolver) { +// Test that custom DNS resolver is used, when custom resolver is configured +// per cluster and deprecated field `dns_resolvers` is specified. +TEST_F(ClusterManagerImplTest, CustomDnsResolverSpecifiedViaDeprecatedField) { const std::string yaml = R"EOF( static_resources: clusters: @@ -2414,8 +2425,53 @@ TEST_F(ClusterManagerImplTest, UseUdpWithCustomDnsResolver) { )EOF"; std::shared_ptr dns_resolver(new Network::MockDnsResolver()); - // `false` here stands for using udp - EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, false)).WillOnce(Return(dns_resolver)); + auto resolvers = envoy::config::core::v3::Address(); + resolvers.mutable_socket_address()->set_address("1.2.3.4"); + resolvers.mutable_socket_address()->set_port_value(80); + std::vector expectedDnsResolvers; + expectedDnsResolvers.push_back(Network::Address::resolveProtoAddress(resolvers)); + + // As custom resolver is specified via deprecated field `dns_resolvers` in clusters + // config, the method `createDnsResolver` is called once. + EXPECT_CALL(factory_.dispatcher_, + createDnsResolver(CustomDnsResolversSizeEquals(expectedDnsResolvers), _)) + .WillOnce(Return(dns_resolver)); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver is used, when custom resolver is configured per cluster. +TEST_F(ClusterManagerImplTest, CustomDnsResolverSpecified) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + auto resolvers = envoy::config::core::v3::Address(); + resolvers.mutable_socket_address()->set_address("1.2.3.4"); + resolvers.mutable_socket_address()->set_port_value(80); + std::vector expectedDnsResolvers; + expectedDnsResolvers.push_back(Network::Address::resolveProtoAddress(resolvers)); + + // As custom resolver is specified via field `dns_resolution_config.resolvers` in clusters + // config, the method `createDnsResolver` is called once. + EXPECT_CALL(factory_.dispatcher_, + createDnsResolver(CustomDnsResolversSizeEquals(expectedDnsResolvers), _)) + .WillOnce(Return(dns_resolver)); Network::DnsResolver::ResolveCb dns_callback; Network::MockActiveDnsQuery active_dns_query; @@ -2425,9 +2481,40 @@ TEST_F(ClusterManagerImplTest, UseUdpWithCustomDnsResolver) { factory_.tls_.shutdownThread(); } +// Test that custom DNS resolver with UDP lookups is used, when custom resolver is configured +// per cluster and `use_tcp_for_dns_lookups` is not specified. +TEST_F(ClusterManagerImplTest, UseUdpWithCustomDnsResolver) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `false` here means use_tcp_for_dns_lookups is not being set via bootstrap config + EXPECT_EQ(false, dns_resolver_options.use_tcp_for_dns_lookups()); + factory_.tls_.shutdownThread(); +} + // Test that custom DNS resolver with TCP lookups is used, when custom resolver is configured -// per cluster and `use_tcp_for_dns_lookups` is enabled for that cluster. -TEST_F(ClusterManagerImplTest, UseTcpWithCustomDnsResolver) { +// per cluster and `use_tcp_for_dns_lookups` (deprecated field) is specified as true. +TEST_F(ClusterManagerImplTest, UseTcpWithCustomDnsResolverViaDeprecatedField) { const std::string yaml = R"EOF( static_resources: clusters: @@ -2442,14 +2529,218 @@ TEST_F(ClusterManagerImplTest, UseTcpWithCustomDnsResolver) { )EOF"; std::shared_ptr dns_resolver(new Network::MockDnsResolver()); - // `true` here stands for using tcp - EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, true)).WillOnce(Return(dns_resolver)); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `true` here means use_tcp_for_dns_lookups is set to true + EXPECT_EQ(true, dns_resolver_options.use_tcp_for_dns_lookups()); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver with UDP lookups is used, when custom resolver is configured +// per cluster and `use_tcp_for_dns_lookups` is specified as true but is overridden +// by dns_resolution_config.dns_resolver_options.use_tcp_for_dns_lookups which is set as false. +TEST_F(ClusterManagerImplTest, UseUdpWithCustomDnsResolverDeprecatedFieldOverridden) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + use_tcp_for_dns_lookups: true + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: false + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `false` here means dns_resolver_options.use_tcp_for_dns_lookups is set to false. + EXPECT_EQ(false, dns_resolver_options.use_tcp_for_dns_lookups()); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver with TCP lookups is used, when custom resolver is configured +// per cluster and `use_tcp_for_dns_lookups` is specified as false but is overridden +// by dns_resolution_config.dns_resolver_options.use_tcp_for_dns_lookups which is specified as true. +TEST_F(ClusterManagerImplTest, UseTcpWithCustomDnsResolverDeprecatedFieldOverridden) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + use_tcp_for_dns_lookups: false + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: true + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `true` here means dns_resolver_options.use_tcp_for_dns_lookups is set to true. + EXPECT_EQ(true, dns_resolver_options.use_tcp_for_dns_lookups()); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver with TCP lookups is used, when custom resolver is configured +// per cluster and `dns_resolution_config.dns_resolver_options.use_tcp_for_dns_lookups` is enabled +// for that cluster. +TEST_F(ClusterManagerImplTest, UseTcpWithCustomDnsResolver) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: true + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `true` here means dns_resolver_options.use_tcp_for_dns_lookups is set to true. + EXPECT_EQ(true, dns_resolver_options.use_tcp_for_dns_lookups()); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver with default search domain, when custom resolver is configured +// per cluster and `no_default_search_domain` is not specified. +TEST_F(ClusterManagerImplTest, DefaultSearchDomainWithCustomDnsResolver) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); Network::DnsResolver::ResolveCb dns_callback; Network::MockActiveDnsQuery active_dns_query; EXPECT_CALL(*dns_resolver, resolve(_, _, _)) .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); create(parseBootstrapFromV3Yaml(yaml)); + // `false` here means no_default_search_domain is not being set via bootstrap config + EXPECT_EQ(false, dns_resolver_options.no_default_search_domain()); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver with default search domain, when custom resolver is configured +// per cluster and `no_default_search_domain` is specified as false. +TEST_F(ClusterManagerImplTest, DefaultSearchDomainWithCustomDnsResolverWithConfig) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + dns_resolver_options: + no_default_search_domain: false + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `false` here means dns_resolver_options.no_default_search_domain is set to false. + EXPECT_EQ(false, dns_resolver_options.no_default_search_domain()); + factory_.tls_.shutdownThread(); +} + +// Test that custom DNS resolver with no default search domain, when custom resolver is +// configured per cluster and `no_default_search_domain` is specified as true. +TEST_F(ClusterManagerImplTest, NoDefaultSearchDomainWithCustomDnsResolver) { + const std::string yaml = R"EOF( + static_resources: + clusters: + - name: cluster_1 + connect_timeout: 0.250s + type: STRICT_DNS + dns_resolution_config: + dns_resolver_options: + no_default_search_domain: true + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 + )EOF"; + + std::shared_ptr dns_resolver(new Network::MockDnsResolver()); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(factory_.dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(dns_resolver))); + + Network::DnsResolver::ResolveCb dns_callback; + Network::MockActiveDnsQuery active_dns_query; + EXPECT_CALL(*dns_resolver, resolve(_, _, _)) + .WillRepeatedly(DoAll(SaveArg<2>(&dns_callback), Return(&active_dns_query))); + create(parseBootstrapFromV3Yaml(yaml)); + // `true` here means dns_resolver_options.no_default_search_domain is set to true. + EXPECT_EQ(true, dns_resolver_options.no_default_search_domain()); factory_.tls_.shutdownThread(); } @@ -2464,10 +2755,11 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveDefaultPriority) { - name: cluster_1 connect_timeout: 0.250s type: STRICT_DNS - dns_resolvers: - - socket_address: - address: 1.2.3.4 - port_value: 80 + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 lb_policy: ROUND_ROBIN load_assignment: cluster_name: cluster_1 @@ -2550,10 +2842,11 @@ TEST_F(ClusterManagerImplTest, ConnPoolDestroyWithDraining) { - name: cluster_1 connect_timeout: 0.250s type: STRICT_DNS - dns_resolvers: - - socket_address: - address: 1.2.3.4 - port_value: 80 + dns_resolution_config: + resolvers: + - socket_address: + address: 1.2.3.4 + port_value: 80 lb_policy: ROUND_ROBIN load_assignment: cluster_name: cluster_1 diff --git a/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc b/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc index ad5b0c5272146..4943270fac263 100644 --- a/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc +++ b/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc @@ -16,6 +16,7 @@ #include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" +using testing::DoAll; using testing::InSequence; using testing::Return; using testing::SaveArg; @@ -726,32 +727,61 @@ TEST_F(DnsCacheImplTest, DnsCacheCircuitBreakersOverflow) { EXPECT_EQ(1, TestUtility::findCounter(store_, "dns_cache.foo.dns_rq_pending_overflow")->value()); } -TEST(DnsCacheImplOptionsTest, UseTcpForDnsLookupsOptionSet) { - NiceMock dispatcher; - std::shared_ptr resolver{std::make_shared()}; - NiceMock tls; - NiceMock random; - NiceMock loader; - Stats::IsolatedStoreImpl store; +TEST_F(DnsCacheImplTest, UseTcpForDnsLookupsOptionSetDeprecatedField) { + initialize(); + config_.set_use_tcp_for_dns_lookups(true); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(resolver_))); + DnsCacheImpl dns_cache_(dispatcher_, tls_, random_, loader_, store_, config_); + // `true` here means dns_resolver_options.use_tcp_for_dns_lookups is set to true. + EXPECT_EQ(true, dns_resolver_options.use_tcp_for_dns_lookups()); +} - envoy::extensions::common::dynamic_forward_proxy::v3::DnsCacheConfig config; - config.set_use_tcp_for_dns_lookups(true); - EXPECT_CALL(dispatcher, createDnsResolver(_, true)).WillOnce(Return(resolver)); - DnsCacheImpl dns_cache_(dispatcher, tls, random, loader, store, config); +TEST_F(DnsCacheImplTest, UseTcpForDnsLookupsOptionSet) { + initialize(); + config_.mutable_dns_resolution_config() + ->mutable_dns_resolver_options() + ->set_use_tcp_for_dns_lookups(true); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(resolver_))); + DnsCacheImpl dns_cache_(dispatcher_, tls_, random_, loader_, store_, config_); + // `true` here means dns_resolver_options.use_tcp_for_dns_lookups is set to true. + EXPECT_EQ(true, dns_resolver_options.use_tcp_for_dns_lookups()); } -TEST(DnsCacheImplOptionsTest, UseTcpForDnsLookupsOptionUnSet) { - NiceMock dispatcher; - std::shared_ptr resolver{std::make_shared()}; - NiceMock tls; - NiceMock random; - NiceMock loader; - Stats::IsolatedStoreImpl store; +TEST_F(DnsCacheImplTest, NoDefaultSearchDomainOptionSet) { + initialize(); + config_.mutable_dns_resolution_config() + ->mutable_dns_resolver_options() + ->set_no_default_search_domain(true); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(resolver_))); + DnsCacheImpl dns_cache_(dispatcher_, tls_, random_, loader_, store_, config_); + // `true` here means dns_resolver_options.no_default_search_domain is set to true. + EXPECT_EQ(true, dns_resolver_options.no_default_search_domain()); +} - envoy::extensions::common::dynamic_forward_proxy::v3::DnsCacheConfig config; - config.set_use_tcp_for_dns_lookups(false); - EXPECT_CALL(dispatcher, createDnsResolver(_, false)).WillOnce(Return(resolver)); - DnsCacheImpl dns_cache_(dispatcher, tls, random, loader, store, config); +TEST_F(DnsCacheImplTest, UseTcpForDnsLookupsOptionUnSet) { + initialize(); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(resolver_))); + DnsCacheImpl dns_cache_(dispatcher_, tls_, random_, loader_, store_, config_); + // `false` here means dns_resolver_options.use_tcp_for_dns_lookups is set to false. + EXPECT_EQ(false, dns_resolver_options.use_tcp_for_dns_lookups()); +} + +TEST_F(DnsCacheImplTest, NoDefaultSearchDomainOptionUnSet) { + initialize(); + envoy::config::core::v3::DnsResolverOptions dns_resolver_options; + EXPECT_CALL(dispatcher_, createDnsResolver(_, _)) + .WillOnce(DoAll(SaveArg<1>(&dns_resolver_options), Return(resolver_))); + DnsCacheImpl dns_cache_(dispatcher_, tls_, random_, loader_, store_, config_); + // `false` here means dns_resolver_options.no_default_search_domain is set to false. + EXPECT_EQ(false, dns_resolver_options.no_default_search_domain()); } // DNS cache manager config tests. @@ -786,7 +816,7 @@ TEST(DnsCacheManagerImplTest, LoadViaConfig) { "config specified DNS cache 'foo' with different settings"); } -TEST(DnsCacheConfigOptionsTest, EmtpyDnsResolverConfig) { +TEST(DnsCacheConfigOptionsTest, EmtpyDnsResolutionConfig) { NiceMock dispatcher; std::shared_ptr resolver{std::make_shared()}; NiceMock tls; @@ -795,13 +825,13 @@ TEST(DnsCacheConfigOptionsTest, EmtpyDnsResolverConfig) { Stats::IsolatedStoreImpl store; envoy::extensions::common::dynamic_forward_proxy::v3::DnsCacheConfig config; - std::vector expectedEmptyDnsResolvers; - EXPECT_CALL(dispatcher, createDnsResolver(expectedEmptyDnsResolvers, _)) + std::vector expected_empty_dns_resolvers; + EXPECT_CALL(dispatcher, createDnsResolver(expected_empty_dns_resolvers, _)) .WillOnce(Return(resolver)); DnsCacheImpl dns_cache_(dispatcher, tls, random, loader, store, config); } -TEST(DnsCacheConfigOptionsTest, NonEmptyDnsResolverConfig) { +TEST(DnsCacheConfigOptionsTest, NonEmptyDnsResolutionConfig) { NiceMock dispatcher; std::shared_ptr resolver{std::make_shared()}; NiceMock tls; @@ -810,14 +840,15 @@ TEST(DnsCacheConfigOptionsTest, NonEmptyDnsResolverConfig) { Stats::IsolatedStoreImpl store; envoy::extensions::common::dynamic_forward_proxy::v3::DnsCacheConfig config; - envoy::config::core::v3::Address* dns_resolvers = config.mutable_dns_resolver()->add_resolvers(); + envoy::config::core::v3::Address* dns_resolvers = + config.mutable_dns_resolution_config()->add_resolvers(); dns_resolvers->mutable_socket_address()->set_address("1.2.3.4"); dns_resolvers->mutable_socket_address()->set_port_value(8080); - std::vector expected_dns_resolver_config; - expected_dns_resolver_config.push_back(Network::Address::resolveProtoAddress(*dns_resolvers)); + std::vector expected_dns_resolvers; + expected_dns_resolvers.push_back(Network::Address::resolveProtoAddress(*dns_resolvers)); EXPECT_CALL(dispatcher, - createDnsResolver(CustomDnsResolversSizeEquals(expected_dns_resolver_config), _)) + createDnsResolver(CustomDnsResolversSizeEquals(expected_dns_resolvers), _)) .WillOnce(Return(resolver)); DnsCacheImpl dns_cache_(dispatcher, tls, random, loader, store, config); } diff --git a/test/extensions/filters/udp/dns_filter/dns_filter_integration_test.cc b/test/extensions/filters/udp/dns_filter/dns_filter_integration_test.cc index ec160f1a584ab..9ddf0a3833d3b 100644 --- a/test/extensions/filters/udp/dns_filter/dns_filter_integration_test.cc +++ b/test/extensions/filters/udp/dns_filter/dns_filter_integration_test.cc @@ -88,10 +88,14 @@ reuse_port: true stat_prefix: "my_prefix" client_config: resolver_timeout: 1s - upstream_resolvers: - - socket_address: - address: {} - port_value: {} + dns_resolution_config: + resolvers: + - socket_address: + address: {} + port_value: {} + dns_resolver_options: + use_tcp_for_dns_lookups: false + no_default_search_domain: false max_pending_lookups: 256 server_config: inline_dns_table: diff --git a/test/extensions/filters/udp/dns_filter/dns_filter_test.cc b/test/extensions/filters/udp/dns_filter/dns_filter_test.cc index c4e0ca81177af..1ee2c6573ee36 100644 --- a/test/extensions/filters/udp/dns_filter/dns_filter_test.cc +++ b/test/extensions/filters/udp/dns_filter/dns_filter_test.cc @@ -18,6 +18,7 @@ using testing::AnyNumber; using testing::AtLeast; +using testing::DoAll; using testing::InSequence; using testing::Mock; using testing::Return; @@ -77,7 +78,8 @@ class DnsFilterTest : public testing::Test, public Event::TestUsingSimulatedTime ON_CALL(listener_factory_, random()).WillByDefault(ReturnRef(random_)); resolver_ = std::make_shared(); - ON_CALL(dispatcher_, createDnsResolver(_, _)).WillByDefault(Return(resolver_)); + ON_CALL(dispatcher_, createDnsResolver(_, _)) + .WillByDefault(DoAll(SaveArg<1>(&dns_resolver_options_), Return(resolver_))); config_ = std::make_shared(listener_factory_, config); filter_ = std::make_unique(callbacks_, config_); @@ -93,6 +95,7 @@ class DnsFilterTest : public testing::Test, public Event::TestUsingSimulatedTime } const Network::Address::InstanceConstSharedPtr listener_address_; + envoy::config::core::v3::DnsResolverOptions dns_resolver_options_; NiceMock random_; Api::ApiPtr api_; DnsFilterEnvoyConfigSharedPtr config_; @@ -180,16 +183,17 @@ stat_prefix: "my_prefix" stat_prefix: "my_prefix" client_config: resolver_timeout: 1s - upstream_resolvers: - - socket_address: - address: "1.1.1.1" - port_value: 53 - - socket_address: - address: "8.8.8.8" - port_value: 53 - - socket_address: - address: "8.8.4.4" - port_value: 53 + dns_resolution_config: + resolvers: + - socket_address: + address: "1.1.1.1" + port_value: 53 + - socket_address: + address: "8.8.8.8" + port_value: 53 + - socket_address: + address: "8.8.4.4" + port_value: 53 max_pending_lookups: 1 server_config: inline_dns_table: @@ -209,10 +213,62 @@ stat_prefix: "my_prefix" stat_prefix: "my_prefix" client_config: resolver_timeout: 1s - upstream_resolvers: - - socket_address: - address: "1.1.1.1" - port_value: 53 + dns_resolution_config: + resolvers: + - socket_address: + address: "1.1.1.1" + port_value: 53 + max_pending_lookups: 256 +server_config: + external_dns_table: + filename: {} +)EOF"; + + const std::string dns_resolver_options_config_not_set = R"EOF( +stat_prefix: "my_prefix" +client_config: + resolver_timeout: 1s + dns_resolution_config: + resolvers: + - socket_address: + address: "1.1.1.1" + port_value: 53 + max_pending_lookups: 256 +server_config: + external_dns_table: + filename: {} +)EOF"; + + const std::string dns_resolver_options_config_set_false = R"EOF( +stat_prefix: "my_prefix" +client_config: + resolver_timeout: 1s + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: false + no_default_search_domain: false + resolvers: + - socket_address: + address: "1.1.1.1" + port_value: 53 + max_pending_lookups: 256 +server_config: + external_dns_table: + filename: {} +)EOF"; + + const std::string dns_resolver_options_config_set_true = R"EOF( +stat_prefix: "my_prefix" +client_config: + resolver_timeout: 1s + dns_resolution_config: + dns_resolver_options: + use_tcp_for_dns_lookups: true + no_default_search_domain: true + resolvers: + - socket_address: + address: "1.1.1.1" + port_value: 53 max_pending_lookups: 256 server_config: external_dns_table: @@ -2034,6 +2090,47 @@ TEST_F(DnsFilterTest, SrvQueryMaxRecords) { EXPECT_LT(exact_matches, hosts.size()); } +TEST_F(DnsFilterTest, DnsResolverOptionsNotSet) { + InSequence s; + + std::string temp_path = + TestEnvironment::writeStringToFileForTest("dns_table.yaml", max_records_table_yaml); + std::string config_to_use = fmt::format(dns_resolver_options_config_not_set, temp_path); + setup(config_to_use); + // `false` here means use_tcp_for_dns_lookups is not set via dns filter config + EXPECT_EQ(false, dns_resolver_options_.use_tcp_for_dns_lookups()); + // `false` here means no_default_search_domain is not set via dns filter config + EXPECT_EQ(false, dns_resolver_options_.no_default_search_domain()); +} + +TEST_F(DnsFilterTest, DnsResolverOptionsSetTrue) { + InSequence s; + + std::string temp_path = + TestEnvironment::writeStringToFileForTest("dns_table.yaml", max_records_table_yaml); + std::string config_to_use = fmt::format(dns_resolver_options_config_set_true, temp_path); + setup(config_to_use); + + // `true` here means use_tcp_for_dns_lookups is set true + EXPECT_EQ(true, dns_resolver_options_.use_tcp_for_dns_lookups()); + // `true` here means no_default_search_domain is set true + EXPECT_EQ(true, dns_resolver_options_.no_default_search_domain()); +} + +TEST_F(DnsFilterTest, DnsResolverOptionsSetFalse) { + InSequence s; + + std::string temp_path = + TestEnvironment::writeStringToFileForTest("dns_table.yaml", max_records_table_yaml); + std::string config_to_use = fmt::format(dns_resolver_options_config_set_false, temp_path); + setup(config_to_use); + + // `false` here means use_tcp_for_dns_lookups is set true + EXPECT_EQ(false, dns_resolver_options_.use_tcp_for_dns_lookups()); + // `false` here means no_default_search_domain is set true + EXPECT_EQ(false, dns_resolver_options_.no_default_search_domain()); +} + } // namespace } // namespace DnsFilter } // namespace UdpFilters diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 36544bd2c1d2f..a1fd35a319341 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -132,7 +132,7 @@ class MockDispatcher : public Dispatcher { const Network::ConnectionSocket::OptionsSharedPtr& options)); MOCK_METHOD(Network::DnsResolverSharedPtr, createDnsResolver, (const std::vector& resolvers, - const bool use_tcp_for_dns_lookups)); + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options)); MOCK_METHOD(FileEvent*, createFileEvent_, (os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events)); MOCK_METHOD(Filesystem::Watcher*, createFilesystemWatcher_, ()); diff --git a/test/mocks/event/wrapped_dispatcher.h b/test/mocks/event/wrapped_dispatcher.h index 776f0a5035ec5..56f5270e05ab9 100644 --- a/test/mocks/event/wrapped_dispatcher.h +++ b/test/mocks/event/wrapped_dispatcher.h @@ -50,10 +50,10 @@ class WrappedDispatcher : public Dispatcher { std::move(transport_socket), options); } - Network::DnsResolverSharedPtr - createDnsResolver(const std::vector& resolvers, - const bool use_tcp_for_dns_lookups) override { - return impl_.createDnsResolver(resolvers, use_tcp_for_dns_lookups); + Network::DnsResolverSharedPtr createDnsResolver( + const std::vector& resolvers, + const envoy::config::core::v3::DnsResolverOptions& dns_resolver_options) override { + return impl_.createDnsResolver(resolvers, dns_resolver_options); } FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index b8a60c1da7a17..79abb1c0706e2 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -62,10 +62,13 @@ TEST_P(ConfigValidation, CreateScaledTimer) { // DNS resolver returns the same shared_ptr. TEST_F(ConfigValidation, SharedDnsResolver) { std::vector resolvers; + auto dns_resolver_options = envoy::config::core::v3::DnsResolverOptions(); - Network::DnsResolverSharedPtr dns1 = dispatcher_->createDnsResolver(resolvers, false); + Network::DnsResolverSharedPtr dns1 = + dispatcher_->createDnsResolver(resolvers, dns_resolver_options); long use_count = dns1.use_count(); - Network::DnsResolverSharedPtr dns2 = dispatcher_->createDnsResolver(resolvers, false); + Network::DnsResolverSharedPtr dns2 = + dispatcher_->createDnsResolver(resolvers, dns_resolver_options); EXPECT_EQ(dns1.get(), dns2.get()); // Both point to the same instance. EXPECT_EQ(use_count + 1, dns2.use_count()); // Each call causes ++ in use_count.