27 #include <type_traits>
31 #include "absl/base/thread_annotations.h"
32 #include "absl/memory/memory.h"
33 #include "absl/status/status.h"
34 #include "absl/status/statusor.h"
35 #include "absl/strings/string_view.h"
36 #include "absl/strings/strip.h"
70 #include "absl/container/flat_hash_set.h"
71 #include "absl/container/inlined_vector.h"
72 #include "absl/strings/str_cat.h"
90 #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
91 #define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6
92 #define GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS 120
93 #define GRPC_DNS_RECONNECT_JITTER 0.2
99 class AresClientChannelDNSResolver :
public PollingResolver {
101 AresClientChannelDNSResolver(ResolverArgs
args,
104 OrphanablePtr<Orphanable> StartRequest()
override;
107 class AresRequestWrapper :
public InternallyRefCounted<AresRequestWrapper> {
109 explicit AresRequestWrapper(
110 RefCountedPtr<AresClientChannelDNSResolver> resolver)
118 resolver_->enable_srv_queries_ ? &balancer_addresses_ :
nullptr,
119 resolver_->request_service_config_ ? &service_config_json_ :
nullptr,
125 ~AresRequestWrapper()
override {
130 void Orphan()
override {
139 RefCountedPtr<AresClientChannelDNSResolver>
resolver_;
140 std::unique_ptr<grpc_ares_request>
request_;
143 std::unique_ptr<ServerAddressList>
addresses_;
144 std::unique_ptr<ServerAddressList> balancer_addresses_;
145 char* service_config_json_ =
nullptr;
148 ~AresClientChannelDNSResolver()
override;
151 const bool request_service_config_;
153 const bool enable_srv_queries_;
155 const int query_timeout_ms_;
158 AresClientChannelDNSResolver::AresClientChannelDNSResolver(
164 {1000 * 30, 0, INT_MAX})),
181 AresClientChannelDNSResolver::~AresClientChannelDNSResolver() {
186 OrphanablePtr<Orphanable> AresClientChannelDNSResolver::StartRequest() {
187 return MakeOrphanable<AresRequestWrapper>(
191 bool ValueInJsonArray(
const Json::Array&
array,
const char*
value) {
193 if (entry.type() == Json::Type::STRING && entry.string_value() ==
value) {
200 std::string ChooseServiceConfig(
char* service_config_choice_json,
204 if (json.type() != Json::Type::ARRAY) {
206 "Service Config Choices, error: should be of type array");
209 const Json* service_config =
nullptr;
210 std::vector<grpc_error_handle> error_list;
211 for (
const Json& choice : json.array_value()) {
212 if (choice.type() != Json::Type::OBJECT) {
214 "Service Config Choice, error: should be of type object"));
218 auto it = choice.object_value().find(
"clientLanguage");
219 if (
it != choice.object_value().end()) {
220 if (
it->second.type() != Json::Type::ARRAY) {
222 "field:clientLanguage error:should be of type array"));
223 }
else if (!ValueInJsonArray(
it->second.array_value(),
"c++")) {
228 it = choice.object_value().find(
"clientHostname");
229 if (
it != choice.object_value().end()) {
230 if (
it->second.type() != Json::Type::ARRAY) {
232 "field:clientHostname error:should be of type array"));
235 if (hostname ==
nullptr ||
236 !ValueInJsonArray(
it->second.array_value(), hostname)) {
242 it = choice.object_value().find(
"percentage");
243 if (
it != choice.object_value().end()) {
244 if (
it->second.type() != Json::Type::NUMBER) {
246 "field:percentage error:should be of type number"));
248 int random_pct = rand() % 100;
250 if (sscanf(
it->second.string_value().c_str(),
"%d", &
percentage) != 1) {
252 "field:percentage error:should be of type integer"));
259 it = choice.object_value().find(
"serviceConfig");
260 if (
it == choice.object_value().end()) {
262 "field:serviceConfig error:required field missing"));
263 }
else if (
it->second.type() != Json::Type::OBJECT) {
265 "field:serviceConfig error:should be of type object"));
266 }
else if (service_config ==
nullptr) {
267 service_config = &
it->second;
270 if (!error_list.empty()) {
271 service_config =
nullptr;
275 if (service_config ==
nullptr)
return "";
276 return service_config->Dump();
279 void AresClientChannelDNSResolver::AresRequestWrapper::OnResolved(
281 auto*
self =
static_cast<AresRequestWrapper*
>(
arg);
282 self->OnResolved(
error);
285 void AresClientChannelDNSResolver::AresRequestWrapper::OnResolved(
292 if (
addresses_ !=
nullptr || balancer_addresses_ !=
nullptr) {
298 if (service_config_json_ !=
nullptr) {
301 ChooseServiceConfig(service_config_json_, &service_config_error);
302 RefCountedPtr<ServiceConfig> service_config;
304 !service_config_string.empty()) {
306 this, service_config_string.c_str());
307 service_config = ServiceConfigImpl::Create(
resolver_->channel_args(),
308 service_config_string,
309 &service_config_error);
320 if (balancer_addresses_ !=
nullptr) {
331 ": ", error_message));
345 class AresClientChannelDNSResolverFactory :
public ResolverFactory {
349 bool IsValidUri(
const URI& uri)
const override {
357 OrphanablePtr<Resolver> CreateResolver(ResolverArgs
args)
const override {
359 return MakeOrphanable<AresClientChannelDNSResolver>(
std::move(
args),
364 class AresDNSResolver :
public DNSResolver {
372 on_resolve_address_done,
373 AresDNSResolver* resolver,
intptr_t aba_token)
375 default_port_(
std::
string(default_port)),
378 on_resolve_address_done_(
std::
move(on_resolve_address_done)),
381 aba_token_(aba_token) {
384 grpc_schedule_on_exec_ctx);
388 "",
name_.c_str(), default_port_.c_str(), pollset_set_,
393 ares_request_.get());
398 ares_request_.get());
399 resolver_->UnregisterRequest(task_handle());
406 ares_request_.get());
407 if (completed_)
return false;
415 TaskHandle task_handle() {
416 return {
reinterpret_cast<intptr_t>(
this), aba_token_};
423 AresRequest*
request =
static_cast<AresRequest*
>(
arg);
426 std::unique_ptr<AresRequest> deleter(
request);
427 std::vector<grpc_resolved_address> resolved_addresses;
430 if (
request->completed_)
return;
432 if (
request->addresses_ !=
nullptr) {
433 resolved_addresses.reserve(
request->addresses_->size());
463 on_resolve_address_done_;
481 static AresDNSResolver* GetOrCreate() {
482 static AresDNSResolver*
instance =
new AresDNSResolver();
486 TaskHandle ResolveName(
492 auto*
request =
new AresRequest(
name, default_port, interested_parties,
495 open_requests_.insert(
handle);
503 return default_resolver_->ResolveNameBlocking(
name, default_port);
506 bool Cancel(TaskHandle
handle)
override {
508 if (!open_requests_.contains(
handle)) {
511 "AresDNSResolver:%p attempt to cancel unknown TaskHandle:%s",
this,
515 auto*
request =
reinterpret_cast<AresRequest*
>(
handle.keys[0]);
523 void UnregisterRequest(TaskHandle
handle) {
525 open_requests_.erase(
handle);
536 bool ShouldUseAres(
const char* resolver_env) {
537 return resolver_env ==
nullptr || strlen(resolver_env) == 0 ||
541 bool UseAresDnsResolver() {
542 static const bool result = []() {
544 bool result = ShouldUseAres(resolver.get());
554 if (UseAresDnsResolver()) {
555 builder->resolver_registry()->RegisterResolverFactory(
556 absl::make_unique<AresClientChannelDNSResolverFactory>());
563 if (grpc_core::UseAresDnsResolver()) {
575 if (grpc_core::UseAresDnsResolver()) {