Implement c-ares based dns resolver

pull/7704/head
Yuchen Zeng 8 years ago
parent 9b5aa6360d
commit d4bbfc7dcf
  1. 12
      BUILD
  2. 6
      CMakeLists.txt
  3. 1038
      Makefile
  4. 3
      binding.gyp
  5. 14
      build.yaml
  6. 5
      config.m4
  7. 2
      examples/cpp/helloworld/Makefile
  8. 8
      examples/cpp/helloworld/greeter_async_client.cc
  9. 2
      examples/cpp/helloworld/greeter_client.cc
  10. 5
      gRPC-Core.podspec
  11. 4
      grpc.gemspec
  12. 4
      package.xml
  13. 46
      src/core/ext/client_config/client_channel.c
  14. 12
      src/core/ext/client_config/resolver.c
  15. 12
      src/core/ext/client_config/resolver.h
  16. 390
      src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
  17. 52
      src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h
  18. 2
      src/core/ext/resolver/sockaddr/sockaddr_resolver.c
  19. 4
      src/core/lib/iomgr/error.c
  20. 6
      src/core/lib/iomgr/ev_epoll_linux.c
  21. 201
      src/core/lib/iomgr/resolve_address_cares.c
  22. 8
      src/core/plugin_registry/grpc_plugin_registry.c
  23. 8
      src/core/plugin_registry/grpc_unsecure_plugin_registry.c
  24. 3
      src/python/grpcio/grpc_core_dependencies.py
  25. 2
      templates/Makefile.template
  26. 4
      test/core/client_config/resolvers/dns_resolver_connectivity_test.c
  27. 4
      tools/doxygen/Doxyfile.core.internal
  28. 23
      tools/run_tests/sources_and_headers.json
  29. 5
      vsprojects/vcxproj/grpc/grpc.vcxproj
  30. 14
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  31. 5
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  32. 14
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

12
BUILD

@ -302,6 +302,7 @@ cc_library(
"src/core/ext/client_config/uri_parser.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h",
"src/core/ext/load_reporting/load_reporting.h",
"src/core/ext/load_reporting/load_reporting_filter.h",
"src/core/ext/census/aggregation.h",
@ -480,7 +481,8 @@ cc_library(
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
"src/core/ext/lb_policy/pick_first/pick_first.c",
"src/core/ext/lb_policy/round_robin/round_robin.c",
"src/core/ext/resolver/dns/native/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
"src/core/ext/load_reporting/load_reporting.c",
"src/core/ext/load_reporting/load_reporting_filter.c",
@ -1020,6 +1022,7 @@ cc_library(
"src/core/ext/client_config/subchannel_call_holder.h",
"src/core/ext/client_config/subchannel_index.h",
"src/core/ext/client_config/uri_parser.h",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h",
"src/core/ext/load_reporting/load_reporting.h",
"src/core/ext/load_reporting/load_reporting_filter.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
@ -1167,7 +1170,8 @@ cc_library(
"src/core/ext/client_config/subchannel_call_holder.c",
"src/core/ext/client_config/subchannel_index.c",
"src/core/ext/client_config/uri_parser.c",
"src/core/ext/resolver/dns/native/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
"src/core/ext/load_reporting/load_reporting.c",
"src/core/ext/load_reporting/load_reporting_filter.c",
@ -1961,7 +1965,8 @@ objc_library(
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
"src/core/ext/lb_policy/pick_first/pick_first.c",
"src/core/ext/lb_policy/round_robin/round_robin.c",
"src/core/ext/resolver/dns/native/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
"src/core/ext/load_reporting/load_reporting.c",
"src/core/ext/load_reporting/load_reporting_filter.c",
@ -2152,6 +2157,7 @@ objc_library(
"src/core/ext/client_config/uri_parser.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h",
"src/core/ext/load_reporting/load_reporting.h",
"src/core/ext/load_reporting/load_reporting_filter.h",
"src/core/ext/census/aggregation.h",

@ -312,7 +312,8 @@ add_library(grpc
third_party/nanopb/pb_encode.c
src/core/ext/lb_policy/pick_first/pick_first.c
src/core/ext/lb_policy/round_robin/round_robin.c
src/core/ext/resolver/dns/native/dns_resolver.c
src/core/ext/resolver/dns/c_ares/dns_resolver.c
src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
src/core/ext/resolver/sockaddr/sockaddr_resolver.c
src/core/ext/load_reporting/load_reporting.c
src/core/ext/load_reporting/load_reporting_filter.c
@ -665,7 +666,8 @@ add_library(grpc_unsecure
src/core/ext/client_config/subchannel_call_holder.c
src/core/ext/client_config/subchannel_index.c
src/core/ext/client_config/uri_parser.c
src/core/ext/resolver/dns/native/dns_resolver.c
src/core/ext/resolver/dns/c_ares/dns_resolver.c
src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
src/core/ext/resolver/sockaddr/sockaddr_resolver.c
src/core/ext/load_reporting/load_reporting.c
src/core/ext/load_reporting/load_reporting_filter.c

1038
Makefile

File diff suppressed because it is too large Load Diff

@ -734,7 +734,8 @@
'third_party/nanopb/pb_encode.c',
'src/core/ext/lb_policy/pick_first/pick_first.c',
'src/core/ext/lb_policy/round_robin/round_robin.c',
'src/core/ext/resolver/dns/native/dns_resolver.c',
'src/core/ext/resolver/dns/c_ares/dns_resolver.c',
'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/load_reporting/load_reporting.c',
'src/core/ext/load_reporting/load_reporting_filter.c',

@ -412,6 +412,16 @@ filegroups:
plugin: grpc_load_reporting_plugin
uses:
- grpc_base
- name: grpc_resolver_dns_ares
headers:
- src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h
src:
- src/core/ext/resolver/dns/c_ares/dns_resolver.c
- src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
plugin: grpc_resolver_dns_ares
uses:
- grpc_base
- grpc_client_config
- name: grpc_resolver_dns_native
src:
- src/core/ext/resolver/dns/native/dns_resolver.c
@ -819,7 +829,7 @@ libs:
- grpc_lb_policy_grpclb
- grpc_lb_policy_pick_first
- grpc_lb_policy_round_robin
- grpc_resolver_dns_native
- grpc_resolver_dns_ares
- grpc_resolver_sockaddr
- grpc_load_reporting
- cares_wrapper
@ -911,7 +921,7 @@ libs:
- grpc_base
- grpc_transport_chttp2_server_insecure
- grpc_transport_chttp2_client_insecure
- grpc_resolver_dns_native
- grpc_resolver_dns_ares
- grpc_resolver_sockaddr
- grpc_load_reporting
- grpc_lb_policy_grpclb

@ -253,7 +253,8 @@ if test "$PHP_GRPC" != "no"; then
third_party/nanopb/pb_encode.c \
src/core/ext/lb_policy/pick_first/pick_first.c \
src/core/ext/lb_policy/round_robin/round_robin.c \
src/core/ext/resolver/dns/native/dns_resolver.c \
src/core/ext/resolver/dns/c_ares/dns_resolver.c \
src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/load_reporting/load_reporting.c \
src/core/ext/load_reporting/load_reporting_filter.c \
@ -583,7 +584,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/pick_first)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/round_robin)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/load_reporting)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/dns/native)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/dns/c_ares)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/sockaddr)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/alpn)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client/insecure)

@ -39,7 +39,7 @@ LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \
-lgrpc++_reflection \
-lprotobuf -lpthread -ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \
LDFLAGS += -L/usr/local/lib -lgrpc++ -lgrpc \
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \
-lprotobuf -lpthread -ldl
endif

@ -79,17 +79,19 @@ class GreeterClient {
// hold on to the "rpc" instance in order to get updates on the ongoing RPC.
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
stub_->AsyncSayHello(&context, request, &cq));
std::cout << "after AsyncSayHello\n";
// Request that, upon completion of the RPC, "reply" be updated with the
// server's response; "status" with the indication of whether the operation
// was successful. Tag the request with the integer 1.
rpc->Finish(&reply, &status, (void*)1);
std::cout << "after Finish\n";
void* got_tag;
bool ok = false;
// Block until the next result is available in the completion queue "cq".
// The return value of Next should always be checked. This return value
// tells us whether there is any kind of event or the cq_ is shutting down.
GPR_ASSERT(cq.Next(&got_tag, &ok));
std::cout << "after Next\n";
// Verify that the result from "cq" corresponds, by its tag, our previous
// request.
@ -117,8 +119,8 @@ int main(int argc, char** argv) {
// are created. This channel models a connection to an endpoint (in this case,
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureChannelCredentials()).
GreeterClient greeter(grpc::CreateChannel(
"localhost:50051", grpc::InsecureChannelCredentials()));
GreeterClient greeter(
grpc::CreateChannel("[::1]:50051", grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user); // The actual RPC call!
std::cout << "Greeter received: " << reply << std::endl;

@ -88,7 +88,7 @@ int main(int argc, char** argv) {
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureChannelCredentials()).
GreeterClient greeter(grpc::CreateChannel(
"localhost:50051", grpc::InsecureChannelCredentials()));
"ip6-localhost:50051", grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;

@ -399,6 +399,7 @@ Pod::Spec.new do |s|
'third_party/nanopb/pb_common.h',
'third_party/nanopb/pb_decode.h',
'third_party/nanopb/pb_encode.h',
'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/load_reporting/load_reporting.h',
'src/core/ext/load_reporting/load_reporting_filter.h',
'src/core/ext/census/aggregation.h',
@ -580,7 +581,8 @@ Pod::Spec.new do |s|
'third_party/nanopb/pb_encode.c',
'src/core/ext/lb_policy/pick_first/pick_first.c',
'src/core/ext/lb_policy/round_robin/round_robin.c',
'src/core/ext/resolver/dns/native/dns_resolver.c',
'src/core/ext/resolver/dns/c_ares/dns_resolver.c',
'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/load_reporting/load_reporting.c',
'src/core/ext/load_reporting/load_reporting_filter.c',
@ -755,6 +757,7 @@ Pod::Spec.new do |s|
'third_party/nanopb/pb_common.h',
'third_party/nanopb/pb_decode.h',
'third_party/nanopb/pb_encode.h',
'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/load_reporting/load_reporting.h',
'src/core/ext/load_reporting/load_reporting_filter.h',
'src/core/ext/census/aggregation.h',

@ -318,6 +318,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/nanopb/pb_common.h )
s.files += %w( third_party/nanopb/pb_decode.h )
s.files += %w( third_party/nanopb/pb_encode.h )
s.files += %w( src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h )
s.files += %w( src/core/ext/load_reporting/load_reporting.h )
s.files += %w( src/core/ext/load_reporting/load_reporting_filter.h )
s.files += %w( src/core/ext/census/aggregation.h )
@ -499,7 +500,8 @@ Gem::Specification.new do |s|
s.files += %w( third_party/nanopb/pb_encode.c )
s.files += %w( src/core/ext/lb_policy/pick_first/pick_first.c )
s.files += %w( src/core/ext/lb_policy/round_robin/round_robin.c )
s.files += %w( src/core/ext/resolver/dns/native/dns_resolver.c )
s.files += %w( src/core/ext/resolver/dns/c_ares/dns_resolver.c )
s.files += %w( src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c )
s.files += %w( src/core/ext/resolver/sockaddr/sockaddr_resolver.c )
s.files += %w( src/core/ext/load_reporting/load_reporting.c )
s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c )

@ -326,6 +326,7 @@
<file baseinstalldir="/" name="third_party/nanopb/pb_common.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/aggregation.h" role="src" />
@ -507,7 +508,8 @@
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/pick_first/pick_first.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/round_robin/round_robin.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/resolver/dns/native/dns_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/dns_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/resolver/sockaddr/sockaddr_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.c" role="src" />

@ -36,6 +36,9 @@
#include <stdio.h>
#include <string.h>
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
@ -82,6 +85,22 @@ typedef struct client_channel_channel_data {
grpc_pollset_set *interested_parties;
} channel_data;
struct grpc_pollset_set {
gpr_mu mu;
size_t pollset_count;
size_t pollset_capacity;
grpc_pollset **pollsets;
size_t pollset_set_count;
size_t pollset_set_capacity;
struct grpc_pollset_set **pollset_sets;
size_t fd_count;
size_t fd_capacity;
grpc_fd **fds;
};
/** We create one watcher for each new lb_policy that is returned from a
resolver,
to watch for state changes from the lb_policy. When a state change is seen,
@ -233,7 +252,7 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
watch_lb_policy(exec_ctx, chand, lb_policy, state);
}
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
grpc_resolver_next(exec_ctx, chand->resolver,
grpc_resolver_next(exec_ctx, chand->resolver, NULL,
&chand->incoming_configuration,
&chand->on_config_changed);
gpr_mu_unlock(&chand->mu_config);
@ -411,7 +430,9 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
if (chand->resolver != NULL && !chand->started_resolving) {
chand->started_resolving = 1;
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
grpc_resolver_next(exec_ctx, chand->resolver,
// grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent,
// chand->interested_parties);
grpc_resolver_next(exec_ctx, chand->resolver, calld->pollent,
&chand->incoming_configuration,
&chand->on_config_changed);
}
@ -521,13 +542,18 @@ void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(!chand->resolver);
chand->resolver = resolver;
GRPC_RESOLVER_REF(resolver, "channel");
if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
chand->exit_idle_when_lb_policy_arrives) {
chand->started_resolving = 1;
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
grpc_resolver_next(exec_ctx, resolver, &chand->incoming_configuration,
&chand->on_config_changed);
}
// TODO(zyc): check if the following part is needed
// if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
// chand->exit_idle_when_lb_policy_arrives) {
// chand->started_resolving = 1;
// GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
// grpc_resolver_next(exec_ctx, resolver, &chand->incoming_configuration,
// &chand->on_config_changed);
// gpr_log(GPR_ERROR, "%" PRIuPTR "%" PRIuPTR "%"
// PRIuPTR, chand->interested_parties->pollset_count,
// chand->interested_parties->pollset_set_count,
// chand->interested_parties->fd_count);
// }
gpr_mu_unlock(&chand->mu_config);
}
@ -545,7 +571,7 @@ grpc_connectivity_state grpc_client_channel_check_connectivity_state(
if (!chand->started_resolving && chand->resolver != NULL) {
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
chand->started_resolving = 1;
grpc_resolver_next(exec_ctx, chand->resolver,
grpc_resolver_next(exec_ctx, chand->resolver, NULL,
&chand->incoming_configuration,
&chand->on_config_changed);
}

@ -36,6 +36,7 @@
void grpc_resolver_init(grpc_resolver *resolver,
const grpc_resolver_vtable *vtable) {
resolver->vtable = vtable;
resolver->pollset_set = grpc_pollset_set_create();
gpr_ref_init(&resolver->refs, 1);
}
@ -62,6 +63,7 @@ void grpc_resolver_unref(grpc_resolver *resolver,
void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
#endif
if (gpr_unref(&resolver->refs)) {
grpc_pollset_set_destroy(resolver->pollset_set);
resolver->vtable->destroy(exec_ctx, resolver);
}
}
@ -75,8 +77,16 @@ void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx,
resolver->vtable->channel_saw_error(exec_ctx, resolver);
}
// void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
// grpc_client_config **target_config,
// grpc_closure *on_complete) {
// resolver->vtable->next(exec_ctx, resolver, target_config, on_complete);
// }
void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
grpc_polling_entity *pollent,
grpc_client_config **target_config,
grpc_closure *on_complete) {
resolver->vtable->next(exec_ctx, resolver, target_config, on_complete);
resolver->vtable->next(exec_ctx, resolver, pollent, target_config,
on_complete);
}

@ -45,6 +45,7 @@ typedef struct grpc_resolver_vtable grpc_resolver_vtable;
objects */
struct grpc_resolver {
const grpc_resolver_vtable *vtable;
grpc_pollset_set *pollset_set;
gpr_refcount refs;
};
@ -52,8 +53,12 @@ struct grpc_resolver_vtable {
void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
void (*channel_saw_error)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
// void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
// grpc_client_config **target_config, grpc_closure
// *on_complete);
void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
grpc_client_config **target_config, grpc_closure *on_complete);
grpc_polling_entity *pollent, grpc_client_config **target_config,
grpc_closure *on_complete);
};
#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG
@ -87,7 +92,12 @@ void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx,
If resolution is fatally broken, set *target_config to NULL and
schedule on_complete. */
// void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
// grpc_client_config **target_config,
// grpc_closure *on_complete);
void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
grpc_polling_entity *pollent,
grpc_client_config **target_config,
grpc_closure *on_complete);

@ -0,0 +1,390 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/port_platform.h>
#ifdef GPR_POSIX_SOCKET
#include "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include <string.h>
#include <sys/types.h>
#include <ares.h>
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/support/block_annotate.h"
#include "src/core/lib/support/string.h"
#include <arpa/inet.h>
typedef struct fd_pair {
grpc_fd *grpc_fd;
int fd;
struct fd_pair *next;
} fd_pair;
typedef struct {
int id;
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
int bitmask;
grpc_closure driver_closure;
grpc_pollset_set *pollset_set;
ares_channel *channel;
fd_pair *fds;
} driver;
struct grpc_ares_request {
char *name;
char *host;
char *port;
char *default_port;
grpc_polling_entity *pollent;
grpc_closure *on_done;
grpc_resolved_addresses **addrs_out;
grpc_closure request_closure;
void *arg;
ares_channel channel;
driver ev_driver;
};
struct grpc_pollset_set {
gpr_mu mu;
size_t pollset_count;
size_t pollset_capacity;
grpc_pollset **pollsets;
size_t pollset_set_count;
size_t pollset_set_capacity;
struct grpc_pollset_set **pollset_sets;
size_t fd_count;
size_t fd_capacity;
grpc_fd **fds;
};
static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
static fd_pair *get_fd(fd_pair **head, int fd) {
fd_pair dummy_head;
fd_pair *node;
fd_pair *ret;
dummy_head.next = *head;
node = &dummy_head;
while (node->next != NULL) {
if (node->next->fd == fd) {
ret = node->next;
node->next = node->next->next;
*head = dummy_head.next;
return ret;
}
}
return NULL;
}
static void notify_on_event(grpc_exec_ctx *exec_ctx, driver *ev_driver) {
size_t i;
fd_pair *new_list = NULL;
ev_driver->bitmask =
ares_getsock(*ev_driver->channel, ev_driver->socks, ARES_GETSOCK_MAXNUM);
grpc_closure_init(&ev_driver->driver_closure, driver_cb, ev_driver);
for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
char *final_name;
gpr_asprintf(&final_name, "host1%" PRIuPTR, i);
if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i) ||
ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
gpr_log(GPR_ERROR, "%d", ev_driver->socks[i]);
fd_pair *fdp = get_fd(&ev_driver->fds, ev_driver->socks[i]);
if (!fdp) {
gpr_log(GPR_ERROR, "new fd");
fdp = gpr_malloc(sizeof(fd_pair));
fdp->grpc_fd = grpc_fd_create(ev_driver->socks[i], final_name);
fdp->fd = ev_driver->socks[i];
grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set, fdp->grpc_fd);
// new_fd_pair->grpc_fd = fd;
// new_fd_pair->next = ev_driver->fds;
}
fdp->next = new_list;
new_list = fdp;
if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i)) {
gpr_log(GPR_ERROR, "READABLE");
grpc_fd_notify_on_read(exec_ctx, fdp->grpc_fd,
&ev_driver->driver_closure);
}
if (ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
gpr_log(GPR_ERROR, "writable");
grpc_fd_notify_on_write(exec_ctx, fdp->grpc_fd,
&ev_driver->driver_closure);
}
}
gpr_free(final_name);
}
while (ev_driver->fds != NULL) {
fd_pair *cur;
// int fd;s
cur = ev_driver->fds;
ev_driver->fds = ev_driver->fds->next;
gpr_log(GPR_ERROR, "fd in ev_driver: %d\n", cur->fd);
grpc_pollset_set_del_fd(exec_ctx, ev_driver->pollset_set, cur->grpc_fd);
gpr_log(GPR_ERROR, "grpc_pollset_set_del_fd");
grpc_fd_shutdown(exec_ctx, cur->grpc_fd);
gpr_log(GPR_ERROR, "grpc_fd_shutdown");
grpc_fd_orphan(exec_ctx, cur->grpc_fd, NULL, NULL, "come on..");
gpr_log(GPR_ERROR, "grpc_fd_orphan");
gpr_free(cur);
}
ev_driver->fds = new_list;
gpr_log(GPR_ERROR, "eof notify_on_event");
}
static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
driver *d = arg;
size_t i;
gpr_log(GPR_ERROR, "driver_cb");
if (error == GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "GRPC_ERROR_NONE");
for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
ares_process_fd(
*d->channel,
ARES_GETSOCK_READABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD,
ARES_GETSOCK_WRITABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD);
}
}
notify_on_event(exec_ctx, d);
grpc_exec_ctx_flush(exec_ctx);
}
static void on_done_cb(void *arg, int status, int timeouts,
struct hostent *hostent) {
gpr_log(GPR_ERROR, "status: %d", status);
grpc_ares_request *r = (grpc_ares_request *)arg;
grpc_error *err;
gpr_log(GPR_ERROR, "status: %s", r->name);
grpc_resolved_addresses **addresses = r->addrs_out;
size_t i;
if (status == ARES_SUCCESS) {
gpr_log(GPR_ERROR, "status ARES_SUCCESS");
err = GRPC_ERROR_NONE;
*addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
for ((*addresses)->naddrs = 0;
hostent->h_addr_list[(*addresses)->naddrs] != NULL;
(*addresses)->naddrs++) {
}
gpr_log(GPR_ERROR, "naddr: %" PRIuPTR, (*addresses)->naddrs);
(*addresses)->addrs =
gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs);
for (i = 0; i < (*addresses)->naddrs; i++) {
if (hostent->h_addrtype == AF_INET6) {
char output[INET6_ADDRSTRLEN];
gpr_log(GPR_ERROR, "AF_INET6");
struct sockaddr_in6 *addr;
(*addresses)->addrs[i].len = sizeof(struct sockaddr_in6);
// &(*addresses)->addrs[i].addr =
// gpr_malloc((*addresses)->addrs[i].len);
addr = (struct sockaddr_in6 *)&(*addresses)->addrs[i].addr;
memcpy(&addr->sin6_addr, hostent->h_addr_list[i],
sizeof(struct in6_addr));
ares_inet_ntop(AF_INET6, &addr->sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_ERROR, "addr: %s", output);
gpr_log(GPR_ERROR, "port: %s", r->port);
addr->sin6_family = (sa_family_t)hostent->h_addrtype;
addr->sin6_port = htons(atoi(r->port)); // TODO: port
} else {
gpr_log(GPR_ERROR, "AF_INET");
struct sockaddr_in *addr;
(*addresses)->addrs[i].len = sizeof(struct sockaddr_in);
// &(*addresses)->addrs[i].addr =
// gpr_malloc((*addresses)->addrs[i].len);
addr = (struct sockaddr_in *)&(*addresses)->addrs[i].addr;
memcpy(&addr->sin_addr, hostent->h_addr_list[i],
sizeof(struct in_addr));
addr->sin_family = (sa_family_t)hostent->h_addrtype;
addr->sin_port = htons(atoi(r->port)); // TODO: port
}
}
// ares_destroy(r->channel);
} else {
gpr_log(GPR_ERROR, "status not ARES_SUCCESS");
err = grpc_error_set_str(
grpc_error_set_str(
grpc_error_set_str(grpc_error_set_int(GRPC_ERROR_CREATE("OS Error"),
GRPC_ERROR_INT_ERRNO, status),
GRPC_ERROR_STR_OS_ERROR, gai_strerror(status)),
GRPC_ERROR_STR_SYSCALL, "getaddrinfo"),
GRPC_ERROR_STR_TARGET_ADDRESS, r->name);
}
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_exec_ctx_sched(&exec_ctx, r->on_done, err, NULL);
grpc_exec_ctx_flush(&exec_ctx);
grpc_exec_ctx_finish(&exec_ctx);
}
static void resolve_address_impl(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
int status;
grpc_ares_request *r = (grpc_ares_request *)arg;
gpr_log(GPR_ERROR, "Really?");
status = ares_init(&r->channel);
if (status != ARES_SUCCESS) {
gpr_log(GPR_ERROR, "ares_init failed");
}
driver *ev_driver = &r->ev_driver;
ev_driver->channel = &r->channel;
gpr_log(GPR_ERROR, "before ares_gethostbyname %s", r->host);
ares_gethostbyname(r->channel, r->host, AF_UNSPEC, on_done_cb, r);
gpr_log(GPR_ERROR, "before ares_getsock");
notify_on_event(exec_ctx, &r->ev_driver);
gpr_log(GPR_ERROR, "before poll");
gpr_log(GPR_ERROR, "eof resolve_address_impl");
}
static int try_fake_resolve(const char *name, const char *port,
grpc_resolved_addresses **addresses) {
struct sockaddr_in sa;
struct sockaddr_in6 sa6;
if (0 != ares_inet_pton(AF_INET, name, &(sa.sin_addr))) {
gpr_log(GPR_ERROR, "AF_INET");
*addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
(*addresses)->naddrs = 1;
(*addresses)->addrs =
gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs);
(*addresses)->addrs[0].len = sizeof(struct sockaddr_in);
sa.sin_family = AF_INET;
sa.sin_port = htons(atoi(port)); // TODO: port
memcpy(&(*addresses)->addrs[0].addr, &sa, sizeof(struct sockaddr_in));
return 1;
}
if (0 != ares_inet_pton(AF_INET6, name, &(sa6.sin6_addr))) {
char output[INET6_ADDRSTRLEN];
gpr_log(GPR_ERROR, "AF_INET6");
*addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
(*addresses)->naddrs = 1;
(*addresses)->addrs =
gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs);
(*addresses)->addrs[0].len = sizeof(struct sockaddr_in6);
sa6.sin6_family = AF_INET6;
sa6.sin6_port = htons(atoi(port)); // TODO: port
memcpy(&(*addresses)->addrs[0].addr, &sa6, sizeof(struct sockaddr_in6));
ares_inet_ntop(AF_INET6, &sa6.sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_ERROR, "addr: %s", output);
gpr_log(GPR_ERROR, "port: %s", port);
return 1;
}
return 0;
}
grpc_ares_request *grpc_resolve_address_ares(grpc_exec_ctx *exec_ctx,
const char *name,
const char *default_port,
grpc_pollset_set *pollset_set,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
char *host;
char *port;
grpc_error *err;
grpc_ares_request *r = gpr_malloc(sizeof(grpc_ares_request));
r->name = gpr_strdup(name);
r->default_port = gpr_strdup(default_port);
r->on_done = on_done;
r->addrs_out = addrs;
r->ev_driver.pollset_set = pollset_set;
r->ev_driver.fds = NULL;
if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
name[4] == ':' && name[5] != 0) {
grpc_resolve_unix_domain_address(name + 5, addrs);
}
/* parse name, splitting it into host and port parts */
gpr_split_host_port(name, &host, &port);
if (host == NULL) {
err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
GRPC_ERROR_STR_TARGET_ADDRESS, name);
grpc_exec_ctx_sched(exec_ctx, on_done, err, NULL);
} else if (port == NULL) {
if (default_port == NULL) {
err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
GRPC_ERROR_STR_TARGET_ADDRESS, name);
grpc_exec_ctx_sched(exec_ctx, on_done, err, NULL);
}
port = gpr_strdup(default_port);
} else if (try_fake_resolve(host, port, addrs)) {
grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
} else {
r->port = gpr_strdup(port);
r->host = gpr_strdup(host);
grpc_closure_init(&r->request_closure, resolve_address_impl, r);
grpc_exec_ctx_sched(exec_ctx, &r->request_closure, GRPC_ERROR_NONE, NULL);
}
gpr_free(host);
gpr_free(port);
return r;
}
void grpc_ares_init(void) {
int status = ares_library_init(ARES_LIB_INIT_ALL);
if (status != ARES_SUCCESS) {
gpr_log(GPR_ERROR, "ares_library_init failed");
}
}
#endif

@ -0,0 +1,52 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_RESOLVER_DNS_CARES_RESOLVE_ADDRESS_CARES_H
#define GRPC_CORE_EXT_RESOLVER_DNS_CARES_RESOLVE_ADDRESS_CARES_H
#include <stddef.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/resolve_address.h"
typedef struct grpc_ares_request grpc_ares_request;
grpc_ares_request *grpc_resolve_address_ares(
grpc_exec_ctx *exec_ctx, const char *addr, const char *default_port,
grpc_pollset_set *pollset_set, grpc_closure *on_done,
grpc_resolved_addresses **addresses);
void grpc_ares_init(void);
#endif /* GRPC_CORE_EXT_RESOLVER_DNS_CARES_RESOLVE_ADDRESS_CARES_H */

@ -79,6 +79,7 @@ static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
grpc_resolver *r);
static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
grpc_polling_entity *pollent,
grpc_client_config **target_config,
grpc_closure *on_complete);
@ -108,6 +109,7 @@ static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
}
static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
grpc_polling_entity *pollent,
grpc_client_config **target_config,
grpc_closure *on_complete) {
sockaddr_resolver *r = (sockaddr_resolver *)resolver;

@ -174,7 +174,7 @@ static bool is_special(grpc_error *err) {
grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
const char *func) {
if (is_special(err)) return err;
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
gpr_log(GPR_ERROR, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
err->refs.count, err->refs.count + 1, file, line, func);
gpr_ref(&err->refs);
return err;
@ -200,7 +200,7 @@ static void error_destroy(grpc_error *err) {
void grpc_error_unref(grpc_error *err, const char *file, int line,
const char *func) {
if (is_special(err)) return;
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
gpr_log(GPR_ERROR, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
err->refs.count, err->refs.count - 1, file, line, func);
if (gpr_unref(&err->refs)) {
error_destroy(err);

@ -911,8 +911,8 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
REF_BY(fd, 1, reason);
/* Remove the fd from the polling island:
- Get a lock on the latest polling island (i.e the last island in the
linked list pointed by fd->polling_island). This is the island that
- Get a lock on the latest polling island (i.e the last island in the
would actually contain the fd
- Remove the fd from the latest polling island
- Unlock the latest polling island
@ -927,7 +927,8 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
fd->polling_island = NULL;
}
grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, error, NULL);
grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error),
NULL);
gpr_mu_unlock(&fd->mu);
UNREF_BY(fd, 2, reason); /* Drop the reference */
@ -939,6 +940,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
PI_UNREF(exec_ctx, unref_pi, "fd_orphan");
}
GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error));
GRPC_ERROR_UNREF(error);
}
static grpc_error *fd_shutdown_error(bool shutdown) {

@ -1,201 +0,0 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/port_platform.h>
#ifdef GPR_POSIX_SOCKET
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include <string.h>
#include <sys/types.h>
#include <ares.h>
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/support/block_annotate.h"
#include "src/core/lib/support/string.h"
static grpc_error *blocking_resolve_address_impl(
const char *name, const char *default_port,
grpc_resolved_addresses **addresses) {
struct addrinfo hints;
struct addrinfo *result = NULL, *resp;
char *host;
char *port;
int s;
size_t i;
grpc_error *err;
if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
name[4] == ':' && name[5] != 0) {
return grpc_resolve_unix_domain_address(name + 5, addresses);
}
/* parse name, splitting it into host and port parts */
gpr_split_host_port(name, &host, &port);
if (host == NULL) {
err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
GRPC_ERROR_STR_TARGET_ADDRESS, name);
goto done;
}
if (port == NULL) {
if (default_port == NULL) {
err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
GRPC_ERROR_STR_TARGET_ADDRESS, name);
goto done;
}
port = gpr_strdup(default_port);
}
/* Call getaddrinfo */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */
hints.ai_socktype = SOCK_STREAM; /* stream socket */
hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
GRPC_SCHEDULING_START_BLOCKING_REGION;
s = getaddrinfo(host, port, &hints, &result);
GRPC_SCHEDULING_END_BLOCKING_REGION;
if (s != 0) {
/* Retry if well-known service name is recognized */
char *svc[][2] = {{"http", "80"}, {"https", "443"}};
for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
if (strcmp(port, svc[i][0]) == 0) {
GRPC_SCHEDULING_START_BLOCKING_REGION;
s = getaddrinfo(host, svc[i][1], &hints, &result);
GRPC_SCHEDULING_END_BLOCKING_REGION;
break;
}
}
}
if (s != 0) {
err = grpc_error_set_str(
grpc_error_set_str(
grpc_error_set_str(grpc_error_set_int(GRPC_ERROR_CREATE("OS Error"),
GRPC_ERROR_INT_ERRNO, s),
GRPC_ERROR_STR_OS_ERROR, gai_strerror(s)),
GRPC_ERROR_STR_SYSCALL, "getaddrinfo"),
GRPC_ERROR_STR_TARGET_ADDRESS, name);
goto done;
}
/* Success path: set addrs non-NULL, fill it in */
*addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
(*addresses)->naddrs = 0;
for (resp = result; resp != NULL; resp = resp->ai_next) {
(*addresses)->naddrs++;
}
(*addresses)->addrs =
gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs);
i = 0;
for (resp = result; resp != NULL; resp = resp->ai_next) {
memcpy(&(*addresses)->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
(*addresses)->addrs[i].len = resp->ai_addrlen;
i++;
}
err = GRPC_ERROR_NONE;
done:
gpr_free(host);
gpr_free(port);
if (result) {
freeaddrinfo(result);
}
return err;
}
grpc_error *(*grpc_blocking_resolve_address)(
const char *name, const char *default_port,
grpc_resolved_addresses **addresses) = blocking_resolve_address_impl;
typedef struct {
char *name;
char *default_port;
grpc_closure *on_done;
grpc_resolved_addresses **addrs_out;
grpc_closure request_closure;
void *arg;
} request;
/* Callback to be passed to grpc_executor to asynch-ify
* grpc_blocking_resolve_address */
static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp,
grpc_error *error) {
request *r = rp;
grpc_exec_ctx_sched(
exec_ctx, r->on_done,
grpc_blocking_resolve_address(r->name, r->default_port, r->addrs_out),
NULL);
gpr_free(r->name);
gpr_free(r->default_port);
gpr_free(r);
}
void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
if (addrs != NULL) {
gpr_free(addrs->addrs);
}
gpr_free(addrs);
}
static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
const char *default_port,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
request *r = gpr_malloc(sizeof(request));
grpc_closure_init(&r->request_closure, do_request_thread, r);
r->name = gpr_strdup(name);
r->default_port = gpr_strdup(default_port);
r->on_done = on_done;
r->addrs_out = addrs;
grpc_executor_push(&r->request_closure, GRPC_ERROR_NONE);
}
void (*grpc_resolve_address)(grpc_exec_ctx *exec_ctx, const char *name,
const char *default_port, grpc_closure *on_done,
grpc_resolved_addresses **addrs) =
resolve_address_impl;
#endif

@ -41,8 +41,8 @@ extern void grpc_lb_policy_pick_first_init(void);
extern void grpc_lb_policy_pick_first_shutdown(void);
extern void grpc_lb_policy_round_robin_init(void);
extern void grpc_lb_policy_round_robin_shutdown(void);
extern void grpc_resolver_dns_native_init(void);
extern void grpc_resolver_dns_native_shutdown(void);
extern void grpc_resolver_dns_ares_init(void);
extern void grpc_resolver_dns_ares_shutdown(void);
extern void grpc_resolver_sockaddr_init(void);
extern void grpc_resolver_sockaddr_shutdown(void);
extern void grpc_load_reporting_plugin_init(void);
@ -59,8 +59,8 @@ void grpc_register_built_in_plugins(void) {
grpc_lb_policy_pick_first_shutdown);
grpc_register_plugin(grpc_lb_policy_round_robin_init,
grpc_lb_policy_round_robin_shutdown);
grpc_register_plugin(grpc_resolver_dns_native_init,
grpc_resolver_dns_native_shutdown);
grpc_register_plugin(grpc_resolver_dns_ares_init,
grpc_resolver_dns_ares_shutdown);
grpc_register_plugin(grpc_resolver_sockaddr_init,
grpc_resolver_sockaddr_shutdown);
grpc_register_plugin(grpc_load_reporting_plugin_init,

@ -37,8 +37,8 @@ extern void grpc_chttp2_plugin_init(void);
extern void grpc_chttp2_plugin_shutdown(void);
extern void grpc_client_config_init(void);
extern void grpc_client_config_shutdown(void);
extern void grpc_resolver_dns_native_init(void);
extern void grpc_resolver_dns_native_shutdown(void);
extern void grpc_resolver_dns_ares_init(void);
extern void grpc_resolver_dns_ares_shutdown(void);
extern void grpc_resolver_sockaddr_init(void);
extern void grpc_resolver_sockaddr_shutdown(void);
extern void grpc_load_reporting_plugin_init(void);
@ -55,8 +55,8 @@ void grpc_register_built_in_plugins(void) {
grpc_chttp2_plugin_shutdown);
grpc_register_plugin(grpc_client_config_init,
grpc_client_config_shutdown);
grpc_register_plugin(grpc_resolver_dns_native_init,
grpc_resolver_dns_native_shutdown);
grpc_register_plugin(grpc_resolver_dns_ares_init,
grpc_resolver_dns_ares_shutdown);
grpc_register_plugin(grpc_resolver_sockaddr_init,
grpc_resolver_sockaddr_shutdown);
grpc_register_plugin(grpc_load_reporting_plugin_init,

@ -247,7 +247,8 @@ CORE_SOURCE_FILES = [
'third_party/nanopb/pb_encode.c',
'src/core/ext/lb_policy/pick_first/pick_first.c',
'src/core/ext/lb_policy/round_robin/round_robin.c',
'src/core/ext/resolver/dns/native/dns_resolver.c',
'src/core/ext/resolver/dns/c_ares/dns_resolver.c',
'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/load_reporting/load_reporting.c',
'src/core/ext/load_reporting/load_reporting_filter.c',

@ -1691,6 +1691,7 @@
% for dep in tgt.deps:
$(LIBDIR)/$(CONFIG)/lib${dep}.a\
% endfor
$(CARES_DEP)\
% if tgt.language == "c++" or tgt.boringssl or tgt.build == 'fuzzer':
## C++ targets specificies.
@ -1721,6 +1722,7 @@
% for dep in tgt.deps:
$(LIBDIR)/$(CONFIG)/lib${dep}.a\
% endfor
$(LDLIBS_CARES)\
% if tgt.language == "c++":
% if tgt.build == 'protoc':
$(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC)\

@ -132,7 +132,7 @@ int main(int argc, char **argv) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_event ev1;
gpr_event_init(&ev1);
grpc_resolver_next(&exec_ctx, resolver, &config,
grpc_resolver_next(&exec_ctx, resolver, NULL, &config,
grpc_closure_create(on_done, &ev1));
grpc_exec_ctx_flush(&exec_ctx);
GPR_ASSERT(wait_loop(5, &ev1));
@ -140,7 +140,7 @@ int main(int argc, char **argv) {
gpr_event ev2;
gpr_event_init(&ev2);
grpc_resolver_next(&exec_ctx, resolver, &config,
grpc_resolver_next(&exec_ctx, resolver, NULL, &config,
grpc_closure_create(on_done, &ev2));
grpc_exec_ctx_flush(&exec_ctx);
GPR_ASSERT(wait_loop(30, &ev2));

@ -937,6 +937,7 @@ third_party/nanopb/pb.h \
third_party/nanopb/pb_common.h \
third_party/nanopb/pb_decode.h \
third_party/nanopb/pb_encode.h \
src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h \
src/core/ext/load_reporting/load_reporting.h \
src/core/ext/load_reporting/load_reporting_filter.h \
src/core/ext/census/aggregation.h \
@ -1118,7 +1119,8 @@ third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/lb_policy/pick_first/pick_first.c \
src/core/ext/lb_policy/round_robin/round_robin.c \
src/core/ext/resolver/dns/native/dns_resolver.c \
src/core/ext/resolver/dns/c_ares/dns_resolver.c \
src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/load_reporting/load_reporting.c \
src/core/ext/load_reporting/load_reporting_filter.c \

@ -4181,7 +4181,7 @@
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
"grpc_resolver_dns_native",
"grpc_resolver_dns_ares",
"grpc_resolver_sockaddr",
"grpc_secure",
"grpc_transport_chttp2_client_insecure",
@ -4275,7 +4275,7 @@
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
"grpc_resolver_dns_native",
"grpc_resolver_dns_ares",
"grpc_resolver_sockaddr",
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_server_insecure"
@ -6137,6 +6137,25 @@
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"gpr",
"grpc_base",
"grpc_client_config"
],
"headers": [
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
],
"language": "c",
"name": "grpc_resolver_dns_ares",
"src": [
"src/core/ext/resolver/dns/c_ares/dns_resolver.c",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
],
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"gpr",

@ -446,6 +446,7 @@
<ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
<ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
<ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\census\aggregation.h" />
@ -801,7 +802,9 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\round_robin\round_robin.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
</ClCompile>

@ -517,8 +517,11 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\round_robin\round_robin.c">
<Filter>src\core\ext\lb_policy\round_robin</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
<Filter>src\core\ext\resolver\dns\native</Filter>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
<Filter>src\core\ext\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
<Filter>src\core\ext\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
<Filter>src\core\ext\resolver\sockaddr</Filter>
@ -1100,6 +1103,9 @@
<ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
<Filter>third_party\nanopb</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h">
<Filter>src\core\ext\resolver\dns\c_ares</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h">
<Filter>src\core\ext\load_reporting</Filter>
</ClInclude>
@ -1196,8 +1202,8 @@
<Filter Include="src\core\ext\resolver\dns">
<UniqueIdentifier>{e8fe6413-ab8c-48d5-2c7b-aa79e3db4ab2}</UniqueIdentifier>
</Filter>
<Filter Include="src\core\ext\resolver\dns\native">
<UniqueIdentifier>{94e34be0-29d2-1731-3c1e-617ec4986acb}</UniqueIdentifier>
<Filter Include="src\core\ext\resolver\dns\c_ares">
<UniqueIdentifier>{2b72688f-79b8-05dd-2896-c7d5dec07dd6}</UniqueIdentifier>
</Filter>
<Filter Include="src\core\ext\resolver\sockaddr">
<UniqueIdentifier>{98c1ccc2-2c91-a3d2-6040-a2e15993d51a}</UniqueIdentifier>

@ -405,6 +405,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_call_holder.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
@ -694,7 +695,9 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
</ClCompile>

@ -409,8 +409,11 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.c">
<Filter>src\core\ext\client_config</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\native\dns_resolver.c">
<Filter>src\core\ext\resolver\dns\native</Filter>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
<Filter>src\core\ext\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
<Filter>src\core\ext\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
<Filter>src\core\ext\resolver\sockaddr</Filter>
@ -914,6 +917,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h">
<Filter>src\core\ext\client_config</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h">
<Filter>src\core\ext\resolver\dns\c_ares</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h">
<Filter>src\core\ext\load_reporting</Filter>
</ClInclude>
@ -1025,8 +1031,8 @@
<Filter Include="src\core\ext\resolver\dns">
<UniqueIdentifier>{2e0a9b4f-6394-7c0e-6e5a-0f8b3ee29b41}</UniqueIdentifier>
</Filter>
<Filter Include="src\core\ext\resolver\dns\native">
<UniqueIdentifier>{3d5398c8-928b-9096-8eb7-f8c40ee68c4d}</UniqueIdentifier>
<Filter Include="src\core\ext\resolver\dns\c_ares">
<UniqueIdentifier>{932d8afd-e042-46d0-30c5-1c45386165d9}</UniqueIdentifier>
</Filter>
<Filter Include="src\core\ext\resolver\sockaddr">
<UniqueIdentifier>{71686ed0-fbf9-02a4-d65a-a73f7dc4e2be}</UniqueIdentifier>

Loading…
Cancel
Save