syntax = "proto3";

package envoy.extensions.filters.udp.dns_filter.v3;

import "envoy/config/accesslog/v3/accesslog.proto";
import "envoy/config/core/v3/address.proto";
import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/extension.proto";
import "envoy/config/core/v3/resolver.proto";
import "envoy/data/dns/v3/dns_table.proto";

import "google/protobuf/duration.proto";

import "envoy/annotations/deprecation.proto";
import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.udp.dns_filter.v3";
option java_outer_classname = "DnsFilterProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/dns_filter/v3;dns_filterv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: DNS Filter]
// DNS Filter :ref:`configuration overview <config_udp_listener_filters_dns_filter>`.
// [#extension: envoy.filters.udp.dns_filter]

// Configuration for the DNS filter.
message DnsFilterConfig {
  // This message contains the configuration for the DNS Filter operating
  // in a server context. This message will contain the virtual hosts and
  // associated addresses with which Envoy will respond to queries
  message ServerContextConfig {
    oneof config_source {
      option (validate.required) = true;

      // Load the configuration specified from the control plane
      data.dns.v3.DnsTable inline_dns_table = 1;

      // Seed the filter configuration from an external path. This source
      // is a yaml formatted file that contains the DnsTable driving Envoy's
      // responses to DNS queries
      config.core.v3.DataSource external_dns_table = 2;
    }
  }

  // This message contains the configuration for the DNS Filter operating
  // in a client context. This message will contain the timeouts, retry,
  // and forwarding configuration for Envoy to make DNS requests to other
  // resolvers
  //
  // [#next-free-field: 6]
  message ClientContextConfig {
    // Sets the maximum time we will wait for the upstream query to complete
    // We allow 5s for the upstream resolution to complete, so the minimum
    // value here is 1. Note that the total latency for a failed query is the
    // number of retries multiplied by the resolver_timeout.
    google.protobuf.Duration resolver_timeout = 1 [(validate.rules).duration = {gte {seconds: 1}}];

    // This field was used for `dns_resolution_config` in Envoy 1.19.0 and
    // 1.19.1.
    // Control planes that need to set this field for Envoy 1.19.0 and
    // 1.19.1 clients should fork the protobufs and change the field type
    // to `DnsResolutionConfig`.
    // Control planes that need to simultaneously support Envoy 1.18.x and
    // Envoy 1.19.x should avoid Envoy 1.19.0 and 1.19.1.
    //
    // [#not-implemented-hide:]
    repeated config.core.v3.Address upstream_resolvers = 2
        [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

    // DNS resolution configuration which includes the underlying dns resolver addresses and options.
    // This field is deprecated in favor of
    // :ref:`typed_dns_resolver_config <envoy_v3_api_field_extensions.filters.udp.dns_filter.v3.DnsFilterConfig.ClientContextConfig.typed_dns_resolver_config>`.
    config.core.v3.DnsResolutionConfig dns_resolution_config = 5
        [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

    // DNS resolver type configuration extension. This extension can be used to configure c-ares, apple,
    // or any other DNS resolver types and the related parameters.
    // For example, an object of
    // :ref:`CaresDnsResolverConfig <envoy_v3_api_msg_extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig>`
    // can be packed into this ``typed_dns_resolver_config``. This configuration replaces the
    // :ref:`dns_resolution_config <envoy_v3_api_field_extensions.filters.udp.dns_filter.v3.DnsFilterConfig.ClientContextConfig.dns_resolution_config>`
    // configuration.
    // During the transition period when both ``dns_resolution_config`` and ``typed_dns_resolver_config`` exists,
    // when ``typed_dns_resolver_config`` is in place, Envoy will use it and ignore ``dns_resolution_config``.
    // When ``typed_dns_resolver_config`` is missing, the default behavior is in place.
    // [#extension-category: envoy.network.dns_resolver]
    config.core.v3.TypedExtensionConfig typed_dns_resolver_config = 4;

    // 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
    // resolution times out or is otherwise unsuccessful
    uint64 max_pending_lookups = 3 [(validate.rules).uint64 = {gte: 1}];
  }

  // The stat prefix used when emitting DNS filter statistics
  string stat_prefix = 1 [(validate.rules).string = {min_len: 1}];

  // Server context configuration contains the data that the filter uses to respond
  // to DNS requests.
  ServerContextConfig server_config = 2;

  // Client context configuration controls Envoy's behavior when it must use external
  // resolvers to answer a query. This object is optional and if omitted instructs
  // the filter to resolve queries from the data in the server_config.
  // Also, if ``client_config`` is omitted, here is the Envoy's behavior to create DNS resolver:
  //
  // 1. If :ref:`typed_dns_resolver_config <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.typed_dns_resolver_config>`
  // is not empty, uses it.
  //
  // 2. Otherwise, uses the default c-ares DNS resolver.
  //
  ClientContextConfig client_config = 3;

  // Configuration for :ref:`access logs <arch_overview_access_logs>`
  // emitted by the DNS filter for each DNS query received.
  // Supports custom format commands for DNS-specific attributes:
  // - ``QUERY_NAME``: The DNS query name being resolved
  // - ``QUERY_TYPE``: The DNS query type (A, AAAA, SRV, etc.)
  // - ``QUERY_CLASS``: The DNS query class
  // - ``ANSWER_COUNT``: Number of answers in the response
  // - ``RESPONSE_CODE``: DNS response code
  // - ``PARSE_STATUS``: Whether the query was successfully parsed
  repeated config.accesslog.v3.AccessLog access_log = 4;
}
