summaryrefslogtreecommitdiff
path: root/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
diff options
context:
space:
mode:
Diffstat (limited to 'grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc')
-rw-r--r--grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc119
1 files changed, 59 insertions, 60 deletions
diff --git a/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 0060ad98..2911eae7 100644
--- a/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/grpc/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -80,10 +80,10 @@ class AresDnsResolver : public Resolver {
void MaybeStartResolvingLocked();
void StartResolvingLocked();
- static void OnNextResolution(void* arg, grpc_error* error);
- static void OnResolved(void* arg, grpc_error* error);
- void OnNextResolutionLocked(grpc_error* error);
- void OnResolvedLocked(grpc_error* error);
+ static void OnNextResolution(void* arg, grpc_error_handle error);
+ static void OnResolved(void* arg, grpc_error_handle error);
+ void OnNextResolutionLocked(grpc_error_handle error);
+ void OnResolvedLocked(grpc_error_handle error);
/// DNS server to use (if not system default)
std::string dns_server_;
@@ -91,10 +91,20 @@ class AresDnsResolver : public Resolver {
std::string name_to_resolve_;
/// channel args
grpc_channel_args* channel_args_;
- /// whether to request the service config
- bool request_service_config_;
+ std::shared_ptr<WorkSerializer> work_serializer_;
+ std::unique_ptr<ResultHandler> result_handler_;
/// pollset_set to drive the name resolution process
grpc_pollset_set* interested_parties_;
+
+ /// whether to request the service config
+ bool request_service_config_;
+ // whether or not to enable SRV DNS queries
+ bool enable_srv_queries_;
+ // timeout in milliseconds for active DNS queries
+ int query_timeout_ms_;
+ /// min interval between DNS requests
+ grpc_millis min_time_between_resolutions_;
+
/// closures used by the work_serializer
grpc_closure on_next_resolution_;
grpc_closure on_resolved_;
@@ -105,8 +115,6 @@ class AresDnsResolver : public Resolver {
/// 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
@@ -119,14 +127,25 @@ class AresDnsResolver : public Resolver {
char* service_config_json_ = nullptr;
// has shutdown been initiated
bool shutdown_initiated_ = false;
- // timeout in milliseconds for active DNS queries
- int query_timeout_ms_;
- // whether or not to enable SRV DNS queries
- bool enable_srv_queries_;
};
AresDnsResolver::AresDnsResolver(ResolverArgs args)
- : Resolver(std::move(args.work_serializer), std::move(args.result_handler)),
+ : dns_server_(args.uri.authority()),
+ name_to_resolve_(absl::StripPrefix(args.uri.path(), "/")),
+ channel_args_(grpc_channel_args_copy(args.args)),
+ work_serializer_(std::move(args.work_serializer)),
+ result_handler_(std::move(args.result_handler)),
+ interested_parties_(args.pollset_set),
+ request_service_config_(!grpc_channel_args_find_bool(
+ channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, true)),
+ enable_srv_queries_(grpc_channel_args_find_bool(
+ channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES, false)),
+ query_timeout_ms_(grpc_channel_args_find_integer(
+ channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS,
+ {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX})),
+ min_time_between_resolutions_(grpc_channel_args_find_integer(
+ channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS,
+ {1000 * 30, 0, INT_MAX})),
backoff_(
BackOff::Options()
.set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS *
@@ -134,42 +153,14 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args)
.set_multiplier(GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER)
.set_jitter(GRPC_DNS_RECONNECT_JITTER)
.set_max_backoff(GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) {
- // Closure Initialization
+ // Closure initialization.
GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&on_resolved_, OnResolved, this, grpc_schedule_on_exec_ctx);
- // Get name to resolve from URI path.
- name_to_resolve_ = std::string(absl::StripPrefix(args.uri.path(), "/"));
- // Get DNS server from URI authority.
- dns_server_ = args.uri.authority();
- channel_args_ = grpc_channel_args_copy(args.args);
- // Disable service config option
- const grpc_arg* arg = grpc_channel_args_find(
- channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION);
- request_service_config_ = !grpc_channel_arg_get_bool(arg, true);
- // Min time b/t resolutions option
- 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 * 30, 0, INT_MAX});
- // Enable SRV queries option
- arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES);
- enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false);
- interested_parties_ = grpc_pollset_set_create();
- if (args.pollset_set != nullptr) {
- grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set);
- }
-
- const grpc_arg* query_timeout_ms_arg =
- grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS);
- query_timeout_ms_ = grpc_channel_arg_get_integer(
- query_timeout_ms_arg,
- {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX});
}
AresDnsResolver::~AresDnsResolver() {
GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this);
- grpc_pollset_set_destroy(interested_parties_);
grpc_channel_args_destroy(channel_args_);
}
@@ -202,18 +193,18 @@ void AresDnsResolver::ShutdownLocked() {
}
}
-void AresDnsResolver::OnNextResolution(void* arg, grpc_error* error) {
+void AresDnsResolver::OnNextResolution(void* arg, grpc_error_handle error) {
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
GRPC_ERROR_REF(error); // ref owned by lambda
- r->work_serializer()->Run([r, error]() { r->OnNextResolutionLocked(error); },
- DEBUG_LOCATION);
+ r->work_serializer_->Run([r, error]() { r->OnNextResolutionLocked(error); },
+ DEBUG_LOCATION);
}
-void AresDnsResolver::OnNextResolutionLocked(grpc_error* error) {
+void AresDnsResolver::OnNextResolutionLocked(grpc_error_handle error) {
GRPC_CARES_TRACE_LOG(
"resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: "
"%d",
- this, grpc_error_string(error), shutdown_initiated_);
+ this, grpc_error_std_string(error).c_str(), shutdown_initiated_);
have_next_resolution_timer_ = false;
if (error == GRPC_ERROR_NONE && !shutdown_initiated_) {
if (!resolving_) {
@@ -236,7 +227,7 @@ bool ValueInJsonArray(const Json::Array& array, const char* value) {
}
std::string ChooseServiceConfig(char* service_config_choice_json,
- grpc_error** error) {
+ grpc_error_handle* error) {
Json json = Json::Parse(service_config_choice_json, error);
if (*error != GRPC_ERROR_NONE) return "";
if (json.type() != Json::Type::ARRAY) {
@@ -245,7 +236,7 @@ std::string ChooseServiceConfig(char* service_config_choice_json,
return "";
}
const Json* service_config = nullptr;
- absl::InlinedVector<grpc_error*, 4> error_list;
+ absl::InlinedVector<grpc_error_handle, 4> error_list;
for (const Json& choice : json.array_value()) {
if (choice.type() != Json::Type::OBJECT) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
@@ -314,14 +305,14 @@ std::string ChooseServiceConfig(char* service_config_choice_json,
return service_config->Dump();
}
-void AresDnsResolver::OnResolved(void* arg, grpc_error* error) {
+void AresDnsResolver::OnResolved(void* arg, grpc_error_handle error) {
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
GRPC_ERROR_REF(error); // ref owned by lambda
- r->work_serializer()->Run([r, error]() { r->OnResolvedLocked(error); },
- DEBUG_LOCATION);
+ r->work_serializer_->Run([r, error]() { r->OnResolvedLocked(error); },
+ DEBUG_LOCATION);
}
-void AresDnsResolver::OnResolvedLocked(grpc_error* error) {
+void AresDnsResolver::OnResolvedLocked(grpc_error_handle error) {
GPR_ASSERT(resolving_);
resolving_ = false;
gpr_free(pending_request_);
@@ -355,7 +346,7 @@ void AresDnsResolver::OnResolvedLocked(grpc_error* error) {
}
result.args = grpc_channel_args_copy_and_add(channel_args_, new_args.data(),
new_args.size());
- result_handler()->ReturnResult(std::move(result));
+ result_handler_->ReturnResult(std::move(result));
addresses_.reset();
balancer_addresses_.reset();
// Reset backoff state so that we start from the beginning when the
@@ -363,18 +354,22 @@ void AresDnsResolver::OnResolvedLocked(grpc_error* error) {
backoff_.Reset();
} else {
GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", this,
- grpc_error_string(error));
+ grpc_error_std_string(error).c_str());
std::string error_message =
absl::StrCat("DNS resolution failed for service: ", name_to_resolve_);
- result_handler()->ReturnError(grpc_error_set_int(
+ result_handler_->ReturnError(grpc_error_set_int(
GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(error_message.c_str(),
&error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
// Set retry timer.
+ // InvalidateNow to avoid getting stuck re-initializing this timer
+ // in a loop while draining the currently-held WorkSerializer.
+ // Also see https://github.com/grpc/grpc/issues/26079.
+ ExecCtx::Get()->InvalidateNow();
grpc_millis next_try = backoff_.NextAttemptTime();
grpc_millis timeout = next_try - ExecCtx::Get()->Now();
GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s",
- this, grpc_error_string(error));
+ this, grpc_error_std_string(error).c_str());
GPR_ASSERT(!have_next_resolution_timer_);
have_next_resolution_timer_ = true;
// TODO(roth): We currently deal with this ref manually. Once the
@@ -398,6 +393,10 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
// can start the next resolution.
if (have_next_resolution_timer_) return;
if (last_resolution_timestamp_ >= 0) {
+ // InvalidateNow to avoid getting stuck re-initializing this timer
+ // in a loop while draining the currently-held WorkSerializer.
+ // Also see https://github.com/grpc/grpc/issues/26079.
+ ExecCtx::Get()->InvalidateNow();
const grpc_millis earliest_next_resolution =
last_resolution_timestamp_ + min_time_between_resolutions_;
const grpc_millis ms_until_next_resolution =
@@ -436,7 +435,7 @@ void AresDnsResolver::StartResolvingLocked() {
interested_parties_, &on_resolved_, &addresses_,
enable_srv_queries_ ? &balancer_addresses_ : nullptr,
request_service_config_ ? &service_config_json_ : nullptr,
- query_timeout_ms_, work_serializer());
+ query_timeout_ms_, work_serializer_);
last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p",
this, pending_request_);
@@ -464,7 +463,7 @@ class AresDnsResolverFactory : public ResolverFactory {
extern grpc_address_resolver_vtable* grpc_resolve_address_impl;
static grpc_address_resolver_vtable* default_resolver;
-static grpc_error* blocking_resolve_address_ares(
+static grpc_error_handle blocking_resolve_address_ares(
const char* name, const char* default_port,
grpc_resolved_addresses** addresses) {
return default_resolver->blocking_resolve_address(name, default_port,
@@ -499,7 +498,7 @@ void grpc_resolver_dns_ares_init() {
g_use_ares_dns_resolver = true;
gpr_log(GPR_DEBUG, "Using ares dns resolver");
address_sorting_init();
- grpc_error* error = grpc_ares_init();
+ grpc_error_handle error = grpc_ares_init();
if (error != GRPC_ERROR_NONE) {
GRPC_LOG_IF_ERROR("grpc_ares_init() failed", error);
return;