|  | @@ -49,109 +49,168 @@
 | 
	
		
			
				|  |  |  #define GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS 120
 | 
	
		
			
				|  |  |  #define GRPC_DNS_RECONNECT_JITTER 0.2
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -typedef struct {
 | 
	
		
			
				|  |  | -  /** base class: must be first */
 | 
	
		
			
				|  |  | -  grpc_resolver base;
 | 
	
		
			
				|  |  | -  /** DNS server to use (if not system default) */
 | 
	
		
			
				|  |  | -  char* dns_server;
 | 
	
		
			
				|  |  | -  /** name to resolve (usually the same as target_name) */
 | 
	
		
			
				|  |  | -  char* name_to_resolve;
 | 
	
		
			
				|  |  | -  /** default port to use */
 | 
	
		
			
				|  |  | -  char* default_port;
 | 
	
		
			
				|  |  | -  /** channel args. */
 | 
	
		
			
				|  |  | -  grpc_channel_args* channel_args;
 | 
	
		
			
				|  |  | -  /** whether to request the service config */
 | 
	
		
			
				|  |  | -  bool request_service_config;
 | 
	
		
			
				|  |  | -  /** pollset_set to drive the name resolution process */
 | 
	
		
			
				|  |  | -  grpc_pollset_set* interested_parties;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  /** Closures used by the combiner */
 | 
	
		
			
				|  |  | -  grpc_closure dns_ares_on_next_resolution_timer_closure;
 | 
	
		
			
				|  |  | -  grpc_closure dns_ares_on_resolved_closure;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  /** Combiner guarding the rest of the state */
 | 
	
		
			
				|  |  | -  grpc_combiner* combiner;
 | 
	
		
			
				|  |  | -  /** are we currently resolving? */
 | 
	
		
			
				|  |  | -  bool resolving;
 | 
	
		
			
				|  |  | -  /** the pending resolving request */
 | 
	
		
			
				|  |  | -  grpc_ares_request* pending_request;
 | 
	
		
			
				|  |  | -  /** which version of the result have we published? */
 | 
	
		
			
				|  |  | -  int published_version;
 | 
	
		
			
				|  |  | -  /** which version of the result is current? */
 | 
	
		
			
				|  |  | -  int resolved_version;
 | 
	
		
			
				|  |  | -  /** pending next completion, or NULL */
 | 
	
		
			
				|  |  | -  grpc_closure* next_completion;
 | 
	
		
			
				|  |  | -  /** target result address for next completion */
 | 
	
		
			
				|  |  | -  grpc_channel_args** target_result;
 | 
	
		
			
				|  |  | -  /** current (fully resolved) result */
 | 
	
		
			
				|  |  | -  grpc_channel_args* resolved_result;
 | 
	
		
			
				|  |  | -  /** next resolution timer */
 | 
	
		
			
				|  |  | -  bool have_next_resolution_timer;
 | 
	
		
			
				|  |  | -  grpc_timer next_resolution_timer;
 | 
	
		
			
				|  |  | -  /** retry backoff state */
 | 
	
		
			
				|  |  | -  grpc_core::ManualConstructor<grpc_core::BackOff> backoff;
 | 
	
		
			
				|  |  | -  /** min resolution period. Max one resolution will happen per period */
 | 
	
		
			
				|  |  | -  grpc_millis min_time_between_resolutions;
 | 
	
		
			
				|  |  | -  /** when was the last resolution? -1 if no resolution has happened yet */
 | 
	
		
			
				|  |  | -  grpc_millis last_resolution_timestamp;
 | 
	
		
			
				|  |  | -  /** currently resolving addresses */
 | 
	
		
			
				|  |  | -  grpc_lb_addresses* lb_addresses;
 | 
	
		
			
				|  |  | -  /** currently resolving service config */
 | 
	
		
			
				|  |  | -  char* service_config_json;
 | 
	
		
			
				|  |  | -} ares_dns_resolver;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_destroy(grpc_resolver* r);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_start_resolving_locked(ares_dns_resolver* r);
 | 
	
		
			
				|  |  | -static void dns_ares_maybe_start_resolving_locked(ares_dns_resolver* r);
 | 
	
		
			
				|  |  | -static void dns_ares_maybe_finish_next_locked(ares_dns_resolver* r);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_shutdown_locked(grpc_resolver* r);
 | 
	
		
			
				|  |  | -static void dns_ares_channel_saw_error_locked(grpc_resolver* r);
 | 
	
		
			
				|  |  | -static void dns_ares_next_locked(grpc_resolver* r,
 | 
	
		
			
				|  |  | -                                 grpc_channel_args** target_result,
 | 
	
		
			
				|  |  | -                                 grpc_closure* on_complete);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static const grpc_resolver_vtable dns_ares_resolver_vtable = {
 | 
	
		
			
				|  |  | -    dns_ares_destroy, dns_ares_shutdown_locked,
 | 
	
		
			
				|  |  | -    dns_ares_channel_saw_error_locked, dns_ares_next_locked};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_shutdown_locked(grpc_resolver* resolver) {
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r = (ares_dns_resolver*)resolver;
 | 
	
		
			
				|  |  | -  if (r->have_next_resolution_timer) {
 | 
	
		
			
				|  |  | -    grpc_timer_cancel(&r->next_resolution_timer);
 | 
	
		
			
				|  |  | +namespace grpc_core {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +namespace {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kDefaultPort[] = "https";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class AresDnsResolver : public Resolver {
 | 
	
		
			
				|  |  | + public:
 | 
	
		
			
				|  |  | +  explicit AresDnsResolver(const ResolverArgs& args);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  void NextLocked(grpc_channel_args** result,
 | 
	
		
			
				|  |  | +                  grpc_closure* on_complete) override;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  void RequestReresolutionLocked() override;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  void ShutdownLocked() override;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + private:
 | 
	
		
			
				|  |  | +  virtual ~AresDnsResolver();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  void MaybeStartResolvingLocked();
 | 
	
		
			
				|  |  | +  void StartResolvingLocked();
 | 
	
		
			
				|  |  | +  void MaybeFinishNextLocked();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  static void OnNextResolutionLocked(void* arg, grpc_error* error);
 | 
	
		
			
				|  |  | +  static void OnResolvedLocked(void* arg, grpc_error* error);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// DNS server to use (if not system default)
 | 
	
		
			
				|  |  | +  char* dns_server_;
 | 
	
		
			
				|  |  | +  /// name to resolve (usually the same as target_name)
 | 
	
		
			
				|  |  | +  char* name_to_resolve_;
 | 
	
		
			
				|  |  | +  /// channel args
 | 
	
		
			
				|  |  | +  grpc_channel_args* channel_args_;
 | 
	
		
			
				|  |  | +  /// whether to request the service config
 | 
	
		
			
				|  |  | +  bool request_service_config_;
 | 
	
		
			
				|  |  | +  /// pollset_set to drive the name resolution process
 | 
	
		
			
				|  |  | +  grpc_pollset_set* interested_parties_;
 | 
	
		
			
				|  |  | +  /// closures used by the combiner
 | 
	
		
			
				|  |  | +  grpc_closure on_next_resolution_;
 | 
	
		
			
				|  |  | +  grpc_closure on_resolved_;
 | 
	
		
			
				|  |  | +  /// are we currently resolving?
 | 
	
		
			
				|  |  | +  bool resolving_ = false;
 | 
	
		
			
				|  |  | +  /// the pending resolving request
 | 
	
		
			
				|  |  | +  grpc_ares_request* pending_request_ = nullptr;
 | 
	
		
			
				|  |  | +  /// which version of the result have we published?
 | 
	
		
			
				|  |  | +  int published_version_ = 0;
 | 
	
		
			
				|  |  | +  /// which version of the result is current?
 | 
	
		
			
				|  |  | +  int resolved_version_ = 0;
 | 
	
		
			
				|  |  | +  /// pending next completion, or NULL
 | 
	
		
			
				|  |  | +  grpc_closure* next_completion_ = nullptr;
 | 
	
		
			
				|  |  | +  /// target result address for next completion
 | 
	
		
			
				|  |  | +  grpc_channel_args** target_result_ = nullptr;
 | 
	
		
			
				|  |  | +  /// current (fully resolved) result
 | 
	
		
			
				|  |  | +  grpc_channel_args* resolved_result_ = nullptr;
 | 
	
		
			
				|  |  | +  /// next resolution timer
 | 
	
		
			
				|  |  | +  bool have_next_resolution_timer_ = false;
 | 
	
		
			
				|  |  | +  grpc_timer next_resolution_timer_;
 | 
	
		
			
				|  |  | +  /// min interval between DNS requests
 | 
	
		
			
				|  |  | +  grpc_millis min_time_between_resolutions_;
 | 
	
		
			
				|  |  | +  /// timestamp of last DNS request
 | 
	
		
			
				|  |  | +  grpc_millis last_resolution_timestamp_ = -1;
 | 
	
		
			
				|  |  | +  /// retry backoff state
 | 
	
		
			
				|  |  | +  BackOff backoff_;
 | 
	
		
			
				|  |  | +  /// currently resolving addresses
 | 
	
		
			
				|  |  | +  grpc_lb_addresses* lb_addresses_ = nullptr;
 | 
	
		
			
				|  |  | +  /// currently resolving service config
 | 
	
		
			
				|  |  | +  char* service_config_json_ = nullptr;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
 | 
	
		
			
				|  |  | +    : Resolver(args.combiner),
 | 
	
		
			
				|  |  | +      backoff_(
 | 
	
		
			
				|  |  | +          BackOff::Options()
 | 
	
		
			
				|  |  | +              .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS *
 | 
	
		
			
				|  |  | +                                   1000)
 | 
	
		
			
				|  |  | +              .set_multiplier(GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER)
 | 
	
		
			
				|  |  | +              .set_jitter(GRPC_DNS_RECONNECT_JITTER)
 | 
	
		
			
				|  |  | +              .set_max_backoff(GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) {
 | 
	
		
			
				|  |  | +  // Get name to resolve from URI path.
 | 
	
		
			
				|  |  | +  const char* path = args.uri->path;
 | 
	
		
			
				|  |  | +  if (path[0] == '/') ++path;
 | 
	
		
			
				|  |  | +  name_to_resolve_ = gpr_strdup(path);
 | 
	
		
			
				|  |  | +  // Get DNS server from URI authority.
 | 
	
		
			
				|  |  | +  if (0 != strcmp(args.uri->authority, "")) {
 | 
	
		
			
				|  |  | +    dns_server_ = gpr_strdup(args.uri->authority);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  channel_args_ = grpc_channel_args_copy(args.args);
 | 
	
		
			
				|  |  | +  const grpc_arg* arg = grpc_channel_args_find(
 | 
	
		
			
				|  |  | +      channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION);
 | 
	
		
			
				|  |  | +  request_service_config_ = !grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  | +      arg, (grpc_integer_options){false, false, true});
 | 
	
		
			
				|  |  | +  arg = grpc_channel_args_find(channel_args_,
 | 
	
		
			
				|  |  | +                               GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
 | 
	
		
			
				|  |  | +  min_time_between_resolutions_ =
 | 
	
		
			
				|  |  | +      grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX});
 | 
	
		
			
				|  |  | +  interested_parties_ = grpc_pollset_set_create();
 | 
	
		
			
				|  |  | +  if (args.pollset_set != nullptr) {
 | 
	
		
			
				|  |  | +    grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolutionLocked, this,
 | 
	
		
			
				|  |  | +                    grpc_combiner_scheduler(combiner()));
 | 
	
		
			
				|  |  | +  GRPC_CLOSURE_INIT(&on_resolved_, OnResolvedLocked, this,
 | 
	
		
			
				|  |  | +                    grpc_combiner_scheduler(combiner()));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +AresDnsResolver::~AresDnsResolver() {
 | 
	
		
			
				|  |  | +  gpr_log(GPR_DEBUG, "destroying AresDnsResolver");
 | 
	
		
			
				|  |  | +  if (resolved_result_ != nullptr) {
 | 
	
		
			
				|  |  | +    grpc_channel_args_destroy(resolved_result_);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  if (r->pending_request != nullptr) {
 | 
	
		
			
				|  |  | -    grpc_cancel_ares_request(r->pending_request);
 | 
	
		
			
				|  |  | +  grpc_pollset_set_destroy(interested_parties_);
 | 
	
		
			
				|  |  | +  gpr_free(dns_server_);
 | 
	
		
			
				|  |  | +  gpr_free(name_to_resolve_);
 | 
	
		
			
				|  |  | +  grpc_channel_args_destroy(channel_args_);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void AresDnsResolver::NextLocked(grpc_channel_args** target_result,
 | 
	
		
			
				|  |  | +                                 grpc_closure* on_complete) {
 | 
	
		
			
				|  |  | +  gpr_log(GPR_DEBUG, "AresDnsResolver::NextLocked() is called.");
 | 
	
		
			
				|  |  | +  GPR_ASSERT(next_completion_ == nullptr);
 | 
	
		
			
				|  |  | +  next_completion_ = on_complete;
 | 
	
		
			
				|  |  | +  target_result_ = target_result;
 | 
	
		
			
				|  |  | +  if (resolved_version_ == 0 && !resolving_) {
 | 
	
		
			
				|  |  | +    MaybeStartResolvingLocked();
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    MaybeFinishNextLocked();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  if (r->next_completion != nullptr) {
 | 
	
		
			
				|  |  | -    *r->target_result = nullptr;
 | 
	
		
			
				|  |  | -    GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
 | 
	
		
			
				|  |  | -                                               "Resolver Shutdown"));
 | 
	
		
			
				|  |  | -    r->next_completion = nullptr;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void AresDnsResolver::RequestReresolutionLocked() {
 | 
	
		
			
				|  |  | +  if (!resolving_) {
 | 
	
		
			
				|  |  | +    MaybeStartResolvingLocked();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void dns_ares_channel_saw_error_locked(grpc_resolver* resolver) {
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r = (ares_dns_resolver*)resolver;
 | 
	
		
			
				|  |  | -  if (!r->resolving) {
 | 
	
		
			
				|  |  | -    dns_ares_maybe_start_resolving_locked(r);
 | 
	
		
			
				|  |  | +void AresDnsResolver::ShutdownLocked() {
 | 
	
		
			
				|  |  | +  if (have_next_resolution_timer_) {
 | 
	
		
			
				|  |  | +    grpc_timer_cancel(&next_resolution_timer_);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (pending_request_ != nullptr) {
 | 
	
		
			
				|  |  | +    grpc_cancel_ares_request(pending_request_);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (next_completion_ != nullptr) {
 | 
	
		
			
				|  |  | +    *target_result_ = nullptr;
 | 
	
		
			
				|  |  | +    GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
 | 
	
		
			
				|  |  | +                                             "Resolver Shutdown"));
 | 
	
		
			
				|  |  | +    next_completion_ = nullptr;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void dns_ares_on_next_resolution_timer_locked(void* arg,
 | 
	
		
			
				|  |  | -                                                     grpc_error* error) {
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r = (ares_dns_resolver*)arg;
 | 
	
		
			
				|  |  | -  r->have_next_resolution_timer = false;
 | 
	
		
			
				|  |  | +void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) {
 | 
	
		
			
				|  |  | +  AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
 | 
	
		
			
				|  |  | +  r->have_next_resolution_timer_ = false;
 | 
	
		
			
				|  |  |    if (error == GRPC_ERROR_NONE) {
 | 
	
		
			
				|  |  | -    if (!r->resolving) {
 | 
	
		
			
				|  |  | -      dns_ares_start_resolving_locked(r);
 | 
	
		
			
				|  |  | +    if (!r->resolving_) {
 | 
	
		
			
				|  |  | +      r->StartResolvingLocked();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  GRPC_RESOLVER_UNREF(&r->base, "next_resolution_timer");
 | 
	
		
			
				|  |  | +  r->Unref(DEBUG_LOCATION, "next_resolution_timer");
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static bool value_in_json_array(grpc_json* array, const char* value) {
 | 
	
		
			
				|  |  | +bool ValueInJsonArray(grpc_json* array, const char* value) {
 | 
	
		
			
				|  |  |    for (grpc_json* entry = array->child; entry != nullptr; entry = entry->next) {
 | 
	
		
			
				|  |  |      if (entry->type == GRPC_JSON_STRING && strcmp(entry->value, value) == 0) {
 | 
	
		
			
				|  |  |        return true;
 | 
	
	
		
			
				|  | @@ -160,7 +219,7 @@ static bool value_in_json_array(grpc_json* array, const char* value) {
 | 
	
		
			
				|  |  |    return false;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static char* choose_service_config(char* service_config_choice_json) {
 | 
	
		
			
				|  |  | +char* ChooseServiceConfig(char* service_config_choice_json) {
 | 
	
		
			
				|  |  |    grpc_json* choices_json = grpc_json_parse_string(service_config_choice_json);
 | 
	
		
			
				|  |  |    if (choices_json == nullptr || choices_json->type != GRPC_JSON_ARRAY) {
 | 
	
		
			
				|  |  |      gpr_log(GPR_ERROR, "cannot parse service config JSON string");
 | 
	
	
		
			
				|  | @@ -178,8 +237,7 @@ static char* choose_service_config(char* service_config_choice_json) {
 | 
	
		
			
				|  |  |           field = field->next) {
 | 
	
		
			
				|  |  |        // Check client language, if specified.
 | 
	
		
			
				|  |  |        if (strcmp(field->key, "clientLanguage") == 0) {
 | 
	
		
			
				|  |  | -        if (field->type != GRPC_JSON_ARRAY ||
 | 
	
		
			
				|  |  | -            !value_in_json_array(field, "c++")) {
 | 
	
		
			
				|  |  | +        if (field->type != GRPC_JSON_ARRAY || !ValueInJsonArray(field, "c++")) {
 | 
	
		
			
				|  |  |            service_config_json = nullptr;
 | 
	
		
			
				|  |  |            break;
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -188,7 +246,7 @@ static char* choose_service_config(char* service_config_choice_json) {
 | 
	
		
			
				|  |  |        if (strcmp(field->key, "clientHostname") == 0) {
 | 
	
		
			
				|  |  |          char* hostname = grpc_gethostname();
 | 
	
		
			
				|  |  |          if (hostname == nullptr || field->type != GRPC_JSON_ARRAY ||
 | 
	
		
			
				|  |  | -            !value_in_json_array(field, hostname)) {
 | 
	
		
			
				|  |  | +            !ValueInJsonArray(field, hostname)) {
 | 
	
		
			
				|  |  |            service_config_json = nullptr;
 | 
	
		
			
				|  |  |            break;
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -223,24 +281,24 @@ static char* choose_service_config(char* service_config_choice_json) {
 | 
	
		
			
				|  |  |    return service_config;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void dns_ares_on_resolved_locked(void* arg, grpc_error* error) {
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r = (ares_dns_resolver*)arg;
 | 
	
		
			
				|  |  | +void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
 | 
	
		
			
				|  |  | +  AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
 | 
	
		
			
				|  |  |    grpc_channel_args* result = nullptr;
 | 
	
		
			
				|  |  | -  GPR_ASSERT(r->resolving);
 | 
	
		
			
				|  |  | -  r->resolving = false;
 | 
	
		
			
				|  |  | -  r->pending_request = nullptr;
 | 
	
		
			
				|  |  | -  if (r->lb_addresses != nullptr) {
 | 
	
		
			
				|  |  | +  GPR_ASSERT(r->resolving_);
 | 
	
		
			
				|  |  | +  r->resolving_ = false;
 | 
	
		
			
				|  |  | +  r->pending_request_ = nullptr;
 | 
	
		
			
				|  |  | +  if (r->lb_addresses_ != nullptr) {
 | 
	
		
			
				|  |  |      static const char* args_to_remove[2];
 | 
	
		
			
				|  |  |      size_t num_args_to_remove = 0;
 | 
	
		
			
				|  |  |      grpc_arg new_args[3];
 | 
	
		
			
				|  |  |      size_t num_args_to_add = 0;
 | 
	
		
			
				|  |  |      new_args[num_args_to_add++] =
 | 
	
		
			
				|  |  | -        grpc_lb_addresses_create_channel_arg(r->lb_addresses);
 | 
	
		
			
				|  |  | +        grpc_lb_addresses_create_channel_arg(r->lb_addresses_);
 | 
	
		
			
				|  |  |      grpc_service_config* service_config = nullptr;
 | 
	
		
			
				|  |  |      char* service_config_string = nullptr;
 | 
	
		
			
				|  |  | -    if (r->service_config_json != nullptr) {
 | 
	
		
			
				|  |  | -      service_config_string = choose_service_config(r->service_config_json);
 | 
	
		
			
				|  |  | -      gpr_free(r->service_config_json);
 | 
	
		
			
				|  |  | +    if (r->service_config_json_ != nullptr) {
 | 
	
		
			
				|  |  | +      service_config_string = ChooseServiceConfig(r->service_config_json_);
 | 
	
		
			
				|  |  | +      gpr_free(r->service_config_json_);
 | 
	
		
			
				|  |  |        if (service_config_string != nullptr) {
 | 
	
		
			
				|  |  |          gpr_log(GPR_INFO, "selected service config choice: %s",
 | 
	
		
			
				|  |  |                  service_config_string);
 | 
	
	
		
			
				|  | @@ -260,221 +318,150 @@ static void dns_ares_on_resolved_locked(void* arg, grpc_error* error) {
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      result = grpc_channel_args_copy_and_add_and_remove(
 | 
	
		
			
				|  |  | -        r->channel_args, args_to_remove, num_args_to_remove, new_args,
 | 
	
		
			
				|  |  | +        r->channel_args_, args_to_remove, num_args_to_remove, new_args,
 | 
	
		
			
				|  |  |          num_args_to_add);
 | 
	
		
			
				|  |  |      if (service_config != nullptr) grpc_service_config_destroy(service_config);
 | 
	
		
			
				|  |  |      gpr_free(service_config_string);
 | 
	
		
			
				|  |  | -    grpc_lb_addresses_destroy(r->lb_addresses);
 | 
	
		
			
				|  |  | +    grpc_lb_addresses_destroy(r->lb_addresses_);
 | 
	
		
			
				|  |  |      // Reset backoff state so that we start from the beginning when the
 | 
	
		
			
				|  |  |      // next request gets triggered.
 | 
	
		
			
				|  |  | -    r->backoff->Reset();
 | 
	
		
			
				|  |  | +    r->backoff_.Reset();
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  |      const char* msg = grpc_error_string(error);
 | 
	
		
			
				|  |  |      gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
 | 
	
		
			
				|  |  | -    grpc_millis next_try = r->backoff->NextAttemptTime();
 | 
	
		
			
				|  |  | -    grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
 | 
	
		
			
				|  |  | +    grpc_millis next_try = r->backoff_.NextAttemptTime();
 | 
	
		
			
				|  |  | +    grpc_millis timeout = next_try - ExecCtx::Get()->Now();
 | 
	
		
			
				|  |  |      gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
 | 
	
		
			
				|  |  |              grpc_error_string(error));
 | 
	
		
			
				|  |  | -    GPR_ASSERT(!r->have_next_resolution_timer);
 | 
	
		
			
				|  |  | -    r->have_next_resolution_timer = true;
 | 
	
		
			
				|  |  | -    GRPC_RESOLVER_REF(&r->base, "next_resolution_timer");
 | 
	
		
			
				|  |  | +    GPR_ASSERT(!r->have_next_resolution_timer_);
 | 
	
		
			
				|  |  | +    r->have_next_resolution_timer_ = true;
 | 
	
		
			
				|  |  | +    // TODO(roth): We currently deal with this ref manually.  Once the
 | 
	
		
			
				|  |  | +    // new closure API is done, find a way to track this ref with the timer
 | 
	
		
			
				|  |  | +    // callback as part of the type system.
 | 
	
		
			
				|  |  | +    RefCountedPtr<Resolver> self = r->Ref(DEBUG_LOCATION, "retry-timer");
 | 
	
		
			
				|  |  | +    self.release();
 | 
	
		
			
				|  |  |      if (timeout > 0) {
 | 
	
		
			
				|  |  |        gpr_log(GPR_DEBUG, "retrying in %" PRIdPTR " milliseconds", timeout);
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |        gpr_log(GPR_DEBUG, "retrying immediately");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    grpc_timer_init(&r->next_resolution_timer, next_try,
 | 
	
		
			
				|  |  | -                    &r->dns_ares_on_next_resolution_timer_closure);
 | 
	
		
			
				|  |  | +    grpc_timer_init(&r->next_resolution_timer_, next_try,
 | 
	
		
			
				|  |  | +                    &r->on_next_resolution_);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  if (r->resolved_result != nullptr) {
 | 
	
		
			
				|  |  | -    grpc_channel_args_destroy(r->resolved_result);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  r->resolved_result = result;
 | 
	
		
			
				|  |  | -  r->last_resolution_timestamp = grpc_core::ExecCtx::Get()->Now();
 | 
	
		
			
				|  |  | -  r->resolved_version++;
 | 
	
		
			
				|  |  | -  dns_ares_maybe_finish_next_locked(r);
 | 
	
		
			
				|  |  | -  GRPC_RESOLVER_UNREF(&r->base, "dns-resolving");
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_next_locked(grpc_resolver* resolver,
 | 
	
		
			
				|  |  | -                                 grpc_channel_args** target_result,
 | 
	
		
			
				|  |  | -                                 grpc_closure* on_complete) {
 | 
	
		
			
				|  |  | -  gpr_log(GPR_DEBUG, "dns_ares_next is called.");
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r = (ares_dns_resolver*)resolver;
 | 
	
		
			
				|  |  | -  GPR_ASSERT(!r->next_completion);
 | 
	
		
			
				|  |  | -  r->next_completion = on_complete;
 | 
	
		
			
				|  |  | -  r->target_result = target_result;
 | 
	
		
			
				|  |  | -  if (r->resolved_version == 0 && !r->resolving) {
 | 
	
		
			
				|  |  | -    dns_ares_maybe_start_resolving_locked(r);
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    dns_ares_maybe_finish_next_locked(r);
 | 
	
		
			
				|  |  | +  if (r->resolved_result_ != nullptr) {
 | 
	
		
			
				|  |  | +    grpc_channel_args_destroy(r->resolved_result_);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  r->resolved_result_ = result;
 | 
	
		
			
				|  |  | +  ++r->resolved_version_;
 | 
	
		
			
				|  |  | +  r->MaybeFinishNextLocked();
 | 
	
		
			
				|  |  | +  r->Unref(DEBUG_LOCATION, "dns-resolving");
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void dns_ares_start_resolving_locked(ares_dns_resolver* r) {
 | 
	
		
			
				|  |  | -  GRPC_RESOLVER_REF(&r->base, "dns-resolving");
 | 
	
		
			
				|  |  | -  GPR_ASSERT(!r->resolving);
 | 
	
		
			
				|  |  | -  r->resolving = true;
 | 
	
		
			
				|  |  | -  r->lb_addresses = nullptr;
 | 
	
		
			
				|  |  | -  r->service_config_json = nullptr;
 | 
	
		
			
				|  |  | -  r->pending_request = grpc_dns_lookup_ares(
 | 
	
		
			
				|  |  | -      r->dns_server, r->name_to_resolve, r->default_port, r->interested_parties,
 | 
	
		
			
				|  |  | -      &r->dns_ares_on_resolved_closure, &r->lb_addresses,
 | 
	
		
			
				|  |  | -      true /* check_grpclb */,
 | 
	
		
			
				|  |  | -      r->request_service_config ? &r->service_config_json : nullptr);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_maybe_finish_next_locked(ares_dns_resolver* r) {
 | 
	
		
			
				|  |  | -  if (r->next_completion != nullptr &&
 | 
	
		
			
				|  |  | -      r->resolved_version != r->published_version) {
 | 
	
		
			
				|  |  | -    *r->target_result = r->resolved_result == nullptr
 | 
	
		
			
				|  |  | -                            ? nullptr
 | 
	
		
			
				|  |  | -                            : grpc_channel_args_copy(r->resolved_result);
 | 
	
		
			
				|  |  | -    gpr_log(GPR_DEBUG, "dns_ares_maybe_finish_next_locked");
 | 
	
		
			
				|  |  | -    GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_NONE);
 | 
	
		
			
				|  |  | -    r->next_completion = nullptr;
 | 
	
		
			
				|  |  | -    r->published_version = r->resolved_version;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_maybe_start_resolving_locked(ares_dns_resolver* r) {
 | 
	
		
			
				|  |  | -  if (r->last_resolution_timestamp >= 0) {
 | 
	
		
			
				|  |  | +void AresDnsResolver::MaybeStartResolvingLocked() {
 | 
	
		
			
				|  |  | +  if (last_resolution_timestamp_ >= 0) {
 | 
	
		
			
				|  |  |      const grpc_millis earliest_next_resolution =
 | 
	
		
			
				|  |  | -        r->last_resolution_timestamp + r->min_time_between_resolutions;
 | 
	
		
			
				|  |  | +        last_resolution_timestamp_ + min_time_between_resolutions_;
 | 
	
		
			
				|  |  |      const grpc_millis ms_until_next_resolution =
 | 
	
		
			
				|  |  |          earliest_next_resolution - grpc_core::ExecCtx::Get()->Now();
 | 
	
		
			
				|  |  |      if (ms_until_next_resolution > 0) {
 | 
	
		
			
				|  |  |        const grpc_millis last_resolution_ago =
 | 
	
		
			
				|  |  | -          grpc_core::ExecCtx::Get()->Now() - r->last_resolution_timestamp;
 | 
	
		
			
				|  |  | +          grpc_core::ExecCtx::Get()->Now() - last_resolution_timestamp_;
 | 
	
		
			
				|  |  |        gpr_log(GPR_DEBUG,
 | 
	
		
			
				|  |  |                "In cooldown from last resolution (from %" PRIdPTR
 | 
	
		
			
				|  |  |                " ms ago). Will resolve again in %" PRIdPTR " ms",
 | 
	
		
			
				|  |  |                last_resolution_ago, ms_until_next_resolution);
 | 
	
		
			
				|  |  | -      if (!r->have_next_resolution_timer) {
 | 
	
		
			
				|  |  | -        r->have_next_resolution_timer = true;
 | 
	
		
			
				|  |  | -        GRPC_RESOLVER_REF(&r->base, "next_resolution_timer_cooldown");
 | 
	
		
			
				|  |  | -        grpc_timer_init(&r->next_resolution_timer, ms_until_next_resolution,
 | 
	
		
			
				|  |  | -                        &r->dns_ares_on_next_resolution_timer_closure);
 | 
	
		
			
				|  |  | +      if (!have_next_resolution_timer_) {
 | 
	
		
			
				|  |  | +        have_next_resolution_timer_ = true;
 | 
	
		
			
				|  |  | +        // TODO(roth): We currently deal with this ref manually.  Once the
 | 
	
		
			
				|  |  | +        // new closure API is done, find a way to track this ref with the timer
 | 
	
		
			
				|  |  | +        // callback as part of the type system.
 | 
	
		
			
				|  |  | +        RefCountedPtr<Resolver> self =
 | 
	
		
			
				|  |  | +            Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown");
 | 
	
		
			
				|  |  | +        self.release();
 | 
	
		
			
				|  |  | +        grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
 | 
	
		
			
				|  |  | +                        &on_next_resolution_);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        // TODO(dgq): remove the following two lines once Pick First stops
 | 
	
		
			
				|  |  |        // discarding subchannels after selecting.
 | 
	
		
			
				|  |  | -      ++r->resolved_version;
 | 
	
		
			
				|  |  | -      dns_ares_maybe_finish_next_locked(r);
 | 
	
		
			
				|  |  | +      ++resolved_version_;
 | 
	
		
			
				|  |  | +      MaybeFinishNextLocked();
 | 
	
		
			
				|  |  |        return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  dns_ares_start_resolving_locked(r);
 | 
	
		
			
				|  |  | +  StartResolvingLocked();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void dns_ares_destroy(grpc_resolver* gr) {
 | 
	
		
			
				|  |  | -  gpr_log(GPR_DEBUG, "dns_ares_destroy");
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r = (ares_dns_resolver*)gr;
 | 
	
		
			
				|  |  | -  if (r->resolved_result != nullptr) {
 | 
	
		
			
				|  |  | -    grpc_channel_args_destroy(r->resolved_result);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  grpc_pollset_set_destroy(r->interested_parties);
 | 
	
		
			
				|  |  | -  gpr_free(r->dns_server);
 | 
	
		
			
				|  |  | -  gpr_free(r->name_to_resolve);
 | 
	
		
			
				|  |  | -  gpr_free(r->default_port);
 | 
	
		
			
				|  |  | -  grpc_channel_args_destroy(r->channel_args);
 | 
	
		
			
				|  |  | -  gpr_free(r);
 | 
	
		
			
				|  |  | +void AresDnsResolver::StartResolvingLocked() {
 | 
	
		
			
				|  |  | +  // TODO(roth): We currently deal with this ref manually.  Once the
 | 
	
		
			
				|  |  | +  // new closure API is done, find a way to track this ref with the timer
 | 
	
		
			
				|  |  | +  // callback as part of the type system.
 | 
	
		
			
				|  |  | +  RefCountedPtr<Resolver> self = Ref(DEBUG_LOCATION, "dns-resolving");
 | 
	
		
			
				|  |  | +  self.release();
 | 
	
		
			
				|  |  | +  GPR_ASSERT(!resolving_);
 | 
	
		
			
				|  |  | +  resolving_ = true;
 | 
	
		
			
				|  |  | +  lb_addresses_ = nullptr;
 | 
	
		
			
				|  |  | +  service_config_json_ = nullptr;
 | 
	
		
			
				|  |  | +  pending_request_ = grpc_dns_lookup_ares(
 | 
	
		
			
				|  |  | +      dns_server_, name_to_resolve_, kDefaultPort, interested_parties_,
 | 
	
		
			
				|  |  | +      &on_resolved_, &lb_addresses_, true /* check_grpclb */,
 | 
	
		
			
				|  |  | +      request_service_config_ ? &service_config_json_ : nullptr);
 | 
	
		
			
				|  |  | +  last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static grpc_resolver* dns_ares_create(grpc_resolver_args* args,
 | 
	
		
			
				|  |  | -                                      const char* default_port) {
 | 
	
		
			
				|  |  | -  /* Get name from args. */
 | 
	
		
			
				|  |  | -  const char* path = args->uri->path;
 | 
	
		
			
				|  |  | -  if (path[0] == '/') ++path;
 | 
	
		
			
				|  |  | -  /* Create resolver. */
 | 
	
		
			
				|  |  | -  ares_dns_resolver* r =
 | 
	
		
			
				|  |  | -      (ares_dns_resolver*)gpr_zalloc(sizeof(ares_dns_resolver));
 | 
	
		
			
				|  |  | -  grpc_resolver_init(&r->base, &dns_ares_resolver_vtable, args->combiner);
 | 
	
		
			
				|  |  | -  if (0 != strcmp(args->uri->authority, "")) {
 | 
	
		
			
				|  |  | -    r->dns_server = gpr_strdup(args->uri->authority);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  r->name_to_resolve = gpr_strdup(path);
 | 
	
		
			
				|  |  | -  r->default_port = gpr_strdup(default_port);
 | 
	
		
			
				|  |  | -  r->channel_args = grpc_channel_args_copy(args->args);
 | 
	
		
			
				|  |  | -  const grpc_arg* arg = grpc_channel_args_find(
 | 
	
		
			
				|  |  | -      r->channel_args, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION);
 | 
	
		
			
				|  |  | -  r->request_service_config = !grpc_channel_arg_get_integer(
 | 
	
		
			
				|  |  | -      arg, (grpc_integer_options){false, false, true});
 | 
	
		
			
				|  |  | -  r->interested_parties = grpc_pollset_set_create();
 | 
	
		
			
				|  |  | -  if (args->pollset_set != nullptr) {
 | 
	
		
			
				|  |  | -    grpc_pollset_set_add_pollset_set(r->interested_parties, args->pollset_set);
 | 
	
		
			
				|  |  | +void AresDnsResolver::MaybeFinishNextLocked() {
 | 
	
		
			
				|  |  | +  if (next_completion_ != nullptr && resolved_version_ != published_version_) {
 | 
	
		
			
				|  |  | +    *target_result_ = resolved_result_ == nullptr
 | 
	
		
			
				|  |  | +                          ? nullptr
 | 
	
		
			
				|  |  | +                          : grpc_channel_args_copy(resolved_result_);
 | 
	
		
			
				|  |  | +    gpr_log(GPR_DEBUG, "AresDnsResolver::MaybeFinishNextLocked()");
 | 
	
		
			
				|  |  | +    GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE);
 | 
	
		
			
				|  |  | +    next_completion_ = nullptr;
 | 
	
		
			
				|  |  | +    published_version_ = resolved_version_;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  grpc_core::BackOff::Options backoff_options;
 | 
	
		
			
				|  |  | -  backoff_options
 | 
	
		
			
				|  |  | -      .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * 1000)
 | 
	
		
			
				|  |  | -      .set_multiplier(GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER)
 | 
	
		
			
				|  |  | -      .set_jitter(GRPC_DNS_RECONNECT_JITTER)
 | 
	
		
			
				|  |  | -      .set_max_backoff(GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
 | 
	
		
			
				|  |  | -  r->backoff.Init(grpc_core::BackOff(backoff_options));
 | 
	
		
			
				|  |  | -  GRPC_CLOSURE_INIT(&r->dns_ares_on_next_resolution_timer_closure,
 | 
	
		
			
				|  |  | -                    dns_ares_on_next_resolution_timer_locked, r,
 | 
	
		
			
				|  |  | -                    grpc_combiner_scheduler(r->base.combiner));
 | 
	
		
			
				|  |  | -  GRPC_CLOSURE_INIT(&r->dns_ares_on_resolved_closure,
 | 
	
		
			
				|  |  | -                    dns_ares_on_resolved_locked, r,
 | 
	
		
			
				|  |  | -                    grpc_combiner_scheduler(r->base.combiner));
 | 
	
		
			
				|  |  | -  const grpc_arg* period_arg = grpc_channel_args_find(
 | 
	
		
			
				|  |  | -      args->args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
 | 
	
		
			
				|  |  | -  r->min_time_between_resolutions =
 | 
	
		
			
				|  |  | -      grpc_channel_arg_get_integer(period_arg, {1000, 0, INT_MAX});
 | 
	
		
			
				|  |  | -  r->last_resolution_timestamp = -1;
 | 
	
		
			
				|  |  | -  return &r->base;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/*
 | 
	
		
			
				|  |  | - * FACTORY
 | 
	
		
			
				|  |  | - */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static void dns_ares_factory_ref(grpc_resolver_factory* factory) {}
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +// Factory
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void dns_ares_factory_unref(grpc_resolver_factory* factory) {}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static grpc_resolver* dns_factory_create_resolver(
 | 
	
		
			
				|  |  | -    grpc_resolver_factory* factory, grpc_resolver_args* args) {
 | 
	
		
			
				|  |  | -  return dns_ares_create(args, "https");
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +class AresDnsResolverFactory : public ResolverFactory {
 | 
	
		
			
				|  |  | + public:
 | 
	
		
			
				|  |  | +  OrphanablePtr<Resolver> CreateResolver(
 | 
	
		
			
				|  |  | +      const ResolverArgs& args) const override {
 | 
	
		
			
				|  |  | +    return OrphanablePtr<Resolver>(New<AresDnsResolver>(args));
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static char* dns_ares_factory_get_default_host_name(
 | 
	
		
			
				|  |  | -    grpc_resolver_factory* factory, grpc_uri* uri) {
 | 
	
		
			
				|  |  | -  const char* path = uri->path;
 | 
	
		
			
				|  |  | -  if (path[0] == '/') ++path;
 | 
	
		
			
				|  |  | -  return gpr_strdup(path);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +  const char* scheme() const override { return "dns"; }
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static const grpc_resolver_factory_vtable dns_ares_factory_vtable = {
 | 
	
		
			
				|  |  | -    dns_ares_factory_ref, dns_ares_factory_unref, dns_factory_create_resolver,
 | 
	
		
			
				|  |  | -    dns_ares_factory_get_default_host_name, "dns"};
 | 
	
		
			
				|  |  | -static grpc_resolver_factory dns_resolver_factory = {&dns_ares_factory_vtable};
 | 
	
		
			
				|  |  | +}  // namespace
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static grpc_resolver_factory* dns_ares_resolver_factory_create() {
 | 
	
		
			
				|  |  | -  return &dns_resolver_factory;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +}  // namespace grpc_core
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void grpc_resolver_dns_ares_init(void) {
 | 
	
		
			
				|  |  | -  char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
 | 
	
		
			
				|  |  | +void grpc_resolver_dns_ares_init() {
 | 
	
		
			
				|  |  | +  char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
 | 
	
		
			
				|  |  |    /* TODO(zyc): Turn on c-ares based resolver by default after the address
 | 
	
		
			
				|  |  |       sorter and the CNAME support are added. */
 | 
	
		
			
				|  |  | -  if (resolver != nullptr && gpr_stricmp(resolver, "ares") == 0) {
 | 
	
		
			
				|  |  | +  if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) {
 | 
	
		
			
				|  |  |      grpc_error* error = grpc_ares_init();
 | 
	
		
			
				|  |  |      if (error != GRPC_ERROR_NONE) {
 | 
	
		
			
				|  |  |        GRPC_LOG_IF_ERROR("ares_library_init() failed", error);
 | 
	
		
			
				|  |  |        return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      grpc_resolve_address = grpc_resolve_address_ares;
 | 
	
		
			
				|  |  | -    grpc_register_resolver_type(dns_ares_resolver_factory_create());
 | 
	
		
			
				|  |  | +    grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
 | 
	
		
			
				|  |  | +        grpc_core::UniquePtr<grpc_core::ResolverFactory>(
 | 
	
		
			
				|  |  | +            grpc_core::New<grpc_core::AresDnsResolverFactory>()));
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  gpr_free(resolver);
 | 
	
		
			
				|  |  | +  gpr_free(resolver_env);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void grpc_resolver_dns_ares_shutdown(void) {
 | 
	
		
			
				|  |  | -  char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
 | 
	
		
			
				|  |  | -  if (resolver != nullptr && gpr_stricmp(resolver, "ares") == 0) {
 | 
	
		
			
				|  |  | +void grpc_resolver_dns_ares_shutdown() {
 | 
	
		
			
				|  |  | +  char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
 | 
	
		
			
				|  |  | +  if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) {
 | 
	
		
			
				|  |  |      grpc_ares_cleanup();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  gpr_free(resolver);
 | 
	
		
			
				|  |  | +  gpr_free(resolver_env);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #else /* GRPC_ARES == 1 && !defined(GRPC_UV) */
 |