Merge pull request #11237 from y-zeng/srv_record

Support grpclb address in the c-ares resolver
pull/11419/merge
Yuchen Zeng 8 years ago committed by GitHub
commit 8f3d02106b
  1. 1
      BUILD
  2. 2
      CMakeLists.txt
  3. 2
      Makefile
  4. 1
      binding.gyp
  5. 1
      build.yaml
  6. 1
      config.m4
  7. 1
      config.w32
  8. 1
      gRPC-Core.podspec
  9. 1
      grpc.gemspec
  10. 1
      package.xml
  11. 37
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
  12. 4
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  13. 23
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
  14. 325
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
  15. 23
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  16. 74
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
  17. 5
      src/core/lib/iomgr/ev_epollsig_linux.c
  18. 1
      src/python/grpcio/grpc_core_dependencies.py
  19. 23
      test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
  20. 7
      test/core/client_channel/resolvers/dns_resolver_test.c
  21. 38
      test/core/end2end/fuzzers/api_fuzzer.c
  22. 39
      test/core/end2end/goaway_server_test.c
  23. 2
      test/core/util/port_server_client.c
  24. 1
      tools/doxygen/Doxyfile.core.internal
  25. 3
      tools/run_tests/generated/sources_and_headers.json
  26. 2
      vsprojects/vcxproj/grpc/grpc.vcxproj
  27. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  28. 2
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  29. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -998,6 +998,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c",
],
hdrs = [
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",

@ -1133,6 +1133,7 @@ add_library(grpc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
src/core/ext/filters/load_reporting/load_reporting.c
@ -2014,6 +2015,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c

@ -3116,6 +3116,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/filters/load_reporting/load_reporting.c \
@ -3966,6 +3967,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c \

@ -864,6 +864,7 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/filters/load_reporting/load_reporting.c',

@ -594,6 +594,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
plugin: grpc_resolver_dns_ares
uses:
- grpc_base

@ -311,6 +311,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/filters/load_reporting/load_reporting.c \

@ -288,6 +288,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.c " +
"src\\core\\ext\\filters\\load_reporting\\load_reporting.c " +

@ -690,6 +690,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/filters/load_reporting/load_reporting.c',

@ -621,6 +621,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c )
s.files += %w( src/core/ext/filters/load_reporting/load_reporting.c )

@ -635,6 +635,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/load_reporting.c" role="src" />

@ -65,6 +65,8 @@ typedef struct {
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? */
@ -82,7 +84,7 @@ typedef struct {
gpr_backoff backoff_state;
/** currently resolving addresses */
grpc_resolved_addresses *addresses;
grpc_lb_addresses *lb_addresses;
} ares_dns_resolver;
static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
@ -109,6 +111,9 @@ static void dns_ares_shutdown_locked(grpc_exec_ctx *exec_ctx,
if (r->have_retry_timer) {
grpc_timer_cancel(exec_ctx, &r->retry_timer);
}
if (r->pending_request != NULL) {
grpc_cancel_ares_request(exec_ctx, r->pending_request);
}
if (r->next_completion != NULL) {
*r->target_result = NULL;
grpc_closure_sched(
@ -145,19 +150,11 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_channel_args *result = NULL;
GPR_ASSERT(r->resolving);
r->resolving = false;
if (r->addresses != NULL) {
grpc_lb_addresses *addresses = grpc_lb_addresses_create(
r->addresses->naddrs, NULL /* user_data_vtable */);
for (size_t i = 0; i < r->addresses->naddrs; ++i) {
grpc_lb_addresses_set_address(
addresses, i, &r->addresses->addrs[i].addr,
r->addresses->addrs[i].len, false /* is_balancer */,
NULL /* balancer_name */, NULL /* user_data */);
}
grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
r->pending_request = NULL;
if (r->lb_addresses != NULL) {
grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(r->lb_addresses);
result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
grpc_resolved_addresses_destroy(r->addresses);
grpc_lb_addresses_destroy(exec_ctx, addresses);
grpc_lb_addresses_destroy(exec_ctx, r->lb_addresses);
} else {
const char *msg = grpc_error_string(error);
gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
@ -209,10 +206,11 @@ static void dns_ares_start_resolving_locked(grpc_exec_ctx *exec_ctx,
GRPC_RESOLVER_REF(&r->base, "dns-resolving");
GPR_ASSERT(!r->resolving);
r->resolving = true;
r->addresses = NULL;
grpc_dns_lookup_ares(exec_ctx, r->dns_server, r->name_to_resolve,
r->default_port, r->interested_parties,
&r->dns_ares_on_resolved_locked, &r->addresses);
r->lb_addresses = NULL;
r->pending_request = grpc_dns_lookup_ares(
exec_ctx, r->dns_server, r->name_to_resolve, r->default_port,
r->interested_parties, &r->dns_ares_on_resolved_locked, &r->lb_addresses,
true /* check_grpclb */);
}
static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
@ -222,6 +220,7 @@ static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
*r->target_result = r->resolved_result == NULL
? NULL
: grpc_channel_args_copy(r->resolved_result);
gpr_log(GPR_DEBUG, "dns_ares_maybe_finish_next_locked");
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
r->published_version = r->resolved_version;
@ -245,10 +244,10 @@ static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
static grpc_resolver *dns_ares_create(grpc_exec_ctx *exec_ctx,
grpc_resolver_args *args,
const char *default_port) {
// Get name from args.
/* Get name from args. */
const char *path = args->uri->path;
if (path[0] == '/') ++path;
// Create resolver.
/* Create resolver. */
ares_dns_resolver *r = gpr_zalloc(sizeof(ares_dns_resolver));
grpc_resolver_init(&r->base, &dns_ares_resolver_vtable, args->combiner);
if (0 != strcmp(args->uri->authority, "")) {

@ -47,5 +47,9 @@ grpc_error *grpc_ares_ev_driver_create(grpc_ares_ev_driver **ev_driver,
of ARES_ECANCELLED. */
void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver);
/* Shutdown all the grpc_fds used by \a ev_driver */
void grpc_ares_ev_driver_shutdown(grpc_exec_ctx *exec_ctx,
grpc_ares_ev_driver *ev_driver);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H \
*/

@ -99,9 +99,12 @@ static void fd_node_destroy(grpc_exec_ctx *exec_ctx, fd_node *fdn) {
GPR_ASSERT(!fdn->writable_registered);
gpr_mu_destroy(&fdn->mu);
grpc_pollset_set_del_fd(exec_ctx, fdn->ev_driver->pollset_set, fdn->grpc_fd);
grpc_fd_shutdown(exec_ctx, fdn->grpc_fd,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd node destroyed"));
grpc_fd_orphan(exec_ctx, fdn->grpc_fd, NULL, NULL, "c-ares query finished");
/* c-ares library has closed the fd inside grpc_fd. This fd may be picked up
immediately by another thread, and should not be closed by the following
grpc_fd_orphan. To prevent this fd from being closed by grpc_fd_orphan,
a fd pointer is provided. */
int fd;
grpc_fd_orphan(exec_ctx, fdn->grpc_fd, NULL, &fd, "c-ares query finished");
gpr_free(fdn);
}
@ -140,6 +143,20 @@ void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver) {
grpc_ares_ev_driver_unref(ev_driver);
}
void grpc_ares_ev_driver_shutdown(grpc_exec_ctx *exec_ctx,
grpc_ares_ev_driver *ev_driver) {
gpr_mu_lock(&ev_driver->mu);
ev_driver->shutting_down = true;
fd_node *fn = ev_driver->fds;
while (fn != NULL) {
grpc_fd_shutdown(
exec_ctx, fn->grpc_fd,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_ares_ev_driver_shutdown"));
fn = fn->next;
}
gpr_mu_unlock(&ev_driver->mu);
}
// Search fd in the fd_node list head. This is an O(n) search, the max possible
// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
static fd_node *pop_fd_node(fd_node **head, int fd) {

@ -33,6 +33,7 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include <nameser.h>
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
@ -45,20 +46,14 @@
static gpr_once g_basic_init = GPR_ONCE_INIT;
static gpr_mu g_init_mu;
typedef struct grpc_ares_request {
struct grpc_ares_request {
/** indicates the DNS server to use, if specified */
struct ares_addr_port_node dns_server_addr;
/** following members are set in grpc_resolve_address_ares_impl */
/** host to resolve, parsed from the name to resolve */
char *host;
/** port to fill in sockaddr_in, parsed from the name to resolve */
char *port;
/** default port to use */
char *default_port;
/** closure to call when the request completes */
grpc_closure *on_done;
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses **addrs_out;
grpc_lb_addresses **lb_addrs_out;
/** the evernt driver used by this request */
grpc_ares_ev_driver *ev_driver;
/** number of ongoing queries */
@ -70,7 +65,19 @@ typedef struct grpc_ares_request {
bool success;
/** the errors explaining the request failure, set in on_done_cb */
grpc_error *error;
} grpc_ares_request;
};
typedef struct grpc_ares_hostbyname_request {
/** following members are set in create_hostbyname_request */
/** the top-level request instance */
grpc_ares_request *parent_request;
/** host to resolve, parsed from the name to resolve */
char *host;
/** port to fill in sockaddr_in, parsed from the name to resolve */
uint16_t port;
/** is it a grpclb address */
bool is_balancer;
} grpc_ares_hostbyname_request;
static void do_basic_init(void) { gpr_mu_init(&g_init_mu); }
@ -83,6 +90,10 @@ static uint16_t strhtons(const char *port) {
return htons((unsigned short)atoi(port));
}
static void grpc_ares_request_ref(grpc_ares_request *r) {
gpr_ref(&r->pending_queries);
}
static void grpc_ares_request_unref(grpc_exec_ctx *exec_ctx,
grpc_ares_request *r) {
/* If there are no pending queries, invoke on_done callback and destroy the
@ -103,67 +114,95 @@ static void grpc_ares_request_unref(grpc_exec_ctx *exec_ctx,
}
gpr_mu_destroy(&r->mu);
grpc_ares_ev_driver_destroy(r->ev_driver);
gpr_free(r->host);
gpr_free(r->port);
gpr_free(r->default_port);
gpr_free(r);
}
}
static void on_done_cb(void *arg, int status, int timeouts,
struct hostent *hostent) {
grpc_ares_request *r = (grpc_ares_request *)arg;
static grpc_ares_hostbyname_request *create_hostbyname_request(
grpc_ares_request *parent_request, char *host, uint16_t port,
bool is_balancer) {
grpc_ares_hostbyname_request *hr =
gpr_zalloc(sizeof(grpc_ares_hostbyname_request));
hr->parent_request = parent_request;
hr->host = gpr_strdup(host);
hr->port = port;
hr->is_balancer = is_balancer;
grpc_ares_request_ref(parent_request);
return hr;
}
static void destroy_hostbyname_request(grpc_exec_ctx *exec_ctx,
grpc_ares_hostbyname_request *hr) {
grpc_ares_request_unref(exec_ctx, hr->parent_request);
gpr_free(hr->host);
gpr_free(hr);
}
static void on_hostbyname_done_cb(void *arg, int status, int timeouts,
struct hostent *hostent) {
grpc_ares_hostbyname_request *hr = (grpc_ares_hostbyname_request *)arg;
grpc_ares_request *r = hr->parent_request;
gpr_mu_lock(&r->mu);
if (status == ARES_SUCCESS) {
GRPC_ERROR_UNREF(r->error);
r->error = GRPC_ERROR_NONE;
r->success = true;
grpc_resolved_addresses **addresses = r->addrs_out;
if (*addresses == NULL) {
*addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
(*addresses)->naddrs = 0;
(*addresses)->addrs = NULL;
grpc_lb_addresses **lb_addresses = r->lb_addrs_out;
if (*lb_addresses == NULL) {
*lb_addresses = grpc_lb_addresses_create(0, NULL);
}
size_t prev_naddr = (*addresses)->naddrs;
size_t prev_naddr = (*lb_addresses)->num_addresses;
size_t i;
for (i = 0; hostent->h_addr_list[i] != NULL; i++) {
}
(*addresses)->naddrs += i;
(*addresses)->addrs =
gpr_realloc((*addresses)->addrs,
sizeof(grpc_resolved_address) * (*addresses)->naddrs);
for (i = prev_naddr; i < (*addresses)->naddrs; i++) {
memset(&(*addresses)->addrs[i], 0, sizeof(grpc_resolved_address));
if (hostent->h_addrtype == AF_INET6) {
(*addresses)->addrs[i].len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 *addr =
(struct sockaddr_in6 *)&(*addresses)->addrs[i].addr;
addr->sin6_family = (sa_family_t)hostent->h_addrtype;
addr->sin6_port = strhtons(r->port);
char output[INET6_ADDRSTRLEN];
memcpy(&addr->sin6_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in6_addr));
ares_inet_ntop(AF_INET6, &addr->sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET6 result: \n"
" addr: %s\n port: %s\n sin6_scope_id: %d\n",
output, r->port, addr->sin6_scope_id);
} else {
(*addresses)->addrs[i].len = sizeof(struct sockaddr_in);
struct sockaddr_in *addr =
(struct sockaddr_in *)&(*addresses)->addrs[i].addr;
memcpy(&addr->sin_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in_addr));
addr->sin_family = (sa_family_t)hostent->h_addrtype;
addr->sin_port = strhtons(r->port);
char output[INET_ADDRSTRLEN];
ares_inet_ntop(AF_INET, &addr->sin_addr, output, INET_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET result: \n"
" addr: %s\n port: %s\n",
output, r->port);
(*lb_addresses)->num_addresses += i;
(*lb_addresses)->addresses =
gpr_realloc((*lb_addresses)->addresses,
sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses);
for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) {
switch (hostent->h_addrtype) {
case AF_INET6: {
size_t addr_len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 addr;
memset(&addr, 0, addr_len);
memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in6_addr));
addr.sin6_family = (sa_family_t)hostent->h_addrtype;
addr.sin6_port = hr->port;
grpc_lb_addresses_set_address(
*lb_addresses, i, &addr, addr_len,
hr->is_balancer /* is_balancer */,
hr->is_balancer ? strdup(hr->host) : NULL /* balancer_name */,
NULL /* user_data */);
char output[INET6_ADDRSTRLEN];
ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET6 result: \n"
" addr: %s\n port: %d\n sin6_scope_id: %d\n",
output, ntohs(hr->port), addr.sin6_scope_id);
break;
}
case AF_INET: {
size_t addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in addr;
memset(&addr, 0, addr_len);
memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in_addr));
addr.sin_family = (sa_family_t)hostent->h_addrtype;
addr.sin_port = hr->port;
grpc_lb_addresses_set_address(
*lb_addresses, i, &addr, addr_len,
hr->is_balancer /* is_balancer */,
hr->is_balancer ? strdup(hr->host) : NULL /* balancer_name */,
NULL /* user_data */);
char output[INET_ADDRSTRLEN];
ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET result: \n"
" addr: %s\n port: %d\n",
output, ntohs(hr->port));
break;
}
}
}
} else if (!r->success) {
@ -179,14 +218,58 @@ static void on_done_cb(void *arg, int status, int timeouts,
}
}
gpr_mu_unlock(&r->mu);
grpc_ares_request_unref(NULL, r);
destroy_hostbyname_request(NULL, hr);
}
static void on_srv_query_done_cb(void *arg, int status, int timeouts,
unsigned char *abuf, int alen) {
grpc_ares_request *r = (grpc_ares_request *)arg;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_log(GPR_DEBUG, "on_query_srv_done_cb");
if (status == ARES_SUCCESS) {
gpr_log(GPR_DEBUG, "on_query_srv_done_cb ARES_SUCCESS");
struct ares_srv_reply *reply;
const int parse_status = ares_parse_srv_reply(abuf, alen, &reply);
if (parse_status == ARES_SUCCESS) {
ares_channel *channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
for (struct ares_srv_reply *srv_it = reply; srv_it != NULL;
srv_it = srv_it->next) {
if (grpc_ipv6_loopback_available()) {
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, srv_it->host, srv_it->port, true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6,
on_hostbyname_done_cb, hr);
}
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, srv_it->host, srv_it->port, true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb,
hr);
grpc_ares_ev_driver_start(&exec_ctx, r->ev_driver);
}
}
if (reply != NULL) {
ares_free_data(reply);
}
} else if (!r->success) {
char *error_msg;
gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s",
ares_strerror(status));
grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
if (r->error == GRPC_ERROR_NONE) {
r->error = error;
} else {
r->error = grpc_error_add_child(error, r->error);
}
}
grpc_ares_request_unref(&exec_ctx, r);
grpc_exec_ctx_finish(&exec_ctx);
}
void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
const char *name, const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
static grpc_ares_request *grpc_dns_lookup_ares_impl(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb) {
grpc_error *error = GRPC_ERROR_NONE;
/* TODO(zyc): Enable tracing after #9603 is checked in */
/* if (grpc_dns_trace) {
@ -221,10 +304,7 @@ void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
gpr_mu_init(&r->mu);
r->ev_driver = ev_driver;
r->on_done = on_done;
r->addrs_out = addrs;
r->default_port = gpr_strdup(default_port);
r->port = port;
r->host = host;
r->lb_addrs_out = addrs;
r->success = false;
r->error = GRPC_ERROR_NONE;
ares_channel *channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
@ -248,6 +328,7 @@ void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
error = grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("cannot parse authority"),
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
gpr_free(r);
goto error_cleanup;
}
int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
@ -257,41 +338,55 @@ void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
ares_strerror(status));
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
gpr_free(r);
goto error_cleanup;
}
}
// An extra reference is put here to avoid destroying the request in
// on_done_cb before calling grpc_ares_ev_driver_start.
gpr_ref_init(&r->pending_queries, 2);
gpr_ref_init(&r->pending_queries, 1);
if (grpc_ipv6_loopback_available()) {
gpr_ref(&r->pending_queries);
ares_gethostbyname(*channel, r->host, AF_INET6, on_done_cb, r);
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, host, strhtons(port), false /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_cb, hr);
}
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, host, strhtons(port), false /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb, hr);
if (check_grpclb) {
/* Query the SRV record */
grpc_ares_request_ref(r);
char *service_name;
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host);
ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_cb,
r);
gpr_free(service_name);
}
ares_gethostbyname(*channel, r->host, AF_INET, on_done_cb, r);
/* TODO(zyc): Handle CNAME records here. */
grpc_ares_ev_driver_start(exec_ctx, r->ev_driver);
grpc_ares_request_unref(exec_ctx, r);
return;
gpr_free(host);
gpr_free(port);
return r;
error_cleanup:
grpc_closure_sched(exec_ctx, on_done, error);
gpr_free(host);
gpr_free(port);
return NULL;
}
void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx, const char *name,
const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
grpc_dns_lookup_ares(exec_ctx, NULL /* dns_server */, name, default_port,
interested_parties, on_done, addrs);
}
grpc_ares_request *(*grpc_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs,
bool check_grpclb) = grpc_dns_lookup_ares_impl;
void (*grpc_resolve_address_ares)(
grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
grpc_pollset_set *interested_parties, grpc_closure *on_done,
grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx, grpc_ares_request *r) {
if (grpc_dns_lookup_ares == grpc_dns_lookup_ares_impl) {
grpc_ares_ev_driver_shutdown(exec_ctx, r->ev_driver);
}
}
grpc_error *grpc_ares_init(void) {
gpr_once_init(&g_basic_init, do_basic_init);
@ -316,4 +411,66 @@ void grpc_ares_cleanup(void) {
gpr_mu_unlock(&g_init_mu);
}
/*
* grpc_resolve_address_ares related structs and functions
*/
typedef struct grpc_resolve_address_ares_request {
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses **addrs_out;
/** currently resolving lb addresses */
grpc_lb_addresses *lb_addrs;
/** closure to call when the resolve_address_ares request completes */
grpc_closure *on_resolve_address_done;
/** a closure wrapping on_dns_lookup_done_cb, which should be invoked when the
grpc_dns_lookup_ares operation is done. */
grpc_closure on_dns_lookup_done;
} grpc_resolve_address_ares_request;
static void on_dns_lookup_done_cb(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_resolve_address_ares_request *r =
(grpc_resolve_address_ares_request *)arg;
grpc_resolved_addresses **resolved_addresses = r->addrs_out;
if (r->lb_addrs == NULL || r->lb_addrs->num_addresses == 0) {
*resolved_addresses = NULL;
} else {
*resolved_addresses = gpr_zalloc(sizeof(grpc_resolved_addresses));
(*resolved_addresses)->naddrs = r->lb_addrs->num_addresses;
(*resolved_addresses)->addrs = gpr_zalloc(sizeof(grpc_resolved_address) *
(*resolved_addresses)->naddrs);
for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) {
GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer);
memcpy(&(*resolved_addresses)->addrs[i],
&r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address));
}
}
grpc_closure_sched(exec_ctx, r->on_resolve_address_done,
GRPC_ERROR_REF(error));
grpc_lb_addresses_destroy(exec_ctx, r->lb_addrs);
gpr_free(r);
}
static void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx,
const char *name,
const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
grpc_resolve_address_ares_request *r =
gpr_zalloc(sizeof(grpc_resolve_address_ares_request));
r->addrs_out = addrs;
r->on_resolve_address_done = on_done;
grpc_closure_init(&r->on_dns_lookup_done, on_dns_lookup_done_cb, r,
grpc_schedule_on_exec_ctx);
grpc_dns_lookup_ares(exec_ctx, NULL /* dns_server */, name, default_port,
interested_parties, &r->on_dns_lookup_done, &r->lb_addrs,
false /* check_grpclb */);
}
void (*grpc_resolve_address_ares)(
grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
grpc_pollset_set *interested_parties, grpc_closure *on_done,
grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */

@ -19,11 +19,14 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
#include "src/core/ext/filters/client_channel/lb_policy_factory.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;
/* Asynchronously resolve addr. Use \a default_port if a port isn't designated
in addr, otherwise use the port in addr. grpc_ares_init() must be called at
least once before this function. \a on_done may be called directly in this
@ -36,11 +39,21 @@ extern void (*grpc_resolve_address_ares)(grpc_exec_ctx *exec_ctx,
grpc_closure *on_done,
grpc_resolved_addresses **addresses);
void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
const char *addr, const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addresses);
/* Asynchronously resolve addr. It will try to resolve grpclb SRV records in
addition to the normal address records. For normal address records, it uses
\a default_port if a port isn't designated in \a addr, otherwise it uses the
port in \a addr. grpc_ares_init() must be called at least once before this
function. \a on_done may be called directly in this function without being
scheduled with \a exec_ctx, it must not try to acquire locks that are being
held by the caller. */
extern grpc_ares_request *(*grpc_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb);
/* Cancel the pending grpc_ares_request \a request */
void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx,
grpc_ares_request *request);
/* Initialize gRPC ares wrapper. Must be called at least once before
grpc_resolve_address_ares(). */

@ -0,0 +1,74 @@
/*
*
* Copyright 2017, 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>
#if GRPC_ARES != 1 || defined(GRPC_UV)
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
struct grpc_ares_request {
char val;
};
static grpc_ares_request *grpc_dns_lookup_ares_impl(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb) {
return NULL;
}
grpc_ares_request *(*grpc_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs,
bool check_grpclb) = grpc_dns_lookup_ares_impl;
void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx, grpc_ares_request *r) {}
grpc_error *grpc_ares_init(void) { return GRPC_ERROR_NONE; }
void grpc_ares_cleanup(void) {}
static void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx,
const char *name,
const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {}
void (*grpc_resolve_address_ares)(
grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
grpc_pollset_set *interested_parties, grpc_closure *on_done,
grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
#endif /* GRPC_ARES != 1 || defined(GRPC_UV) */

@ -1032,7 +1032,10 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
unhappy. */
PI_UNREF(exec_ctx, unref_pi, "fd_orphan");
}
GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error));
if (error != GRPC_ERROR_NONE) {
const char *msg = grpc_error_string(error);
gpr_log(GPR_DEBUG, "fd_orphan: %s", msg);
}
GRPC_ERROR_UNREF(error);
}

@ -287,6 +287,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/filters/load_reporting/load_reporting.c',

@ -21,7 +21,9 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/combiner.h"
@ -55,6 +57,26 @@ static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
grpc_closure_sched(exec_ctx, on_done, error);
}
static grpc_ares_request *my_dns_lookup_ares(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb) {
gpr_mu_lock(&g_mu);
GPR_ASSERT(0 == strcmp("test", addr));
grpc_error *error = GRPC_ERROR_NONE;
if (g_fail_resolution) {
g_fail_resolution = false;
gpr_mu_unlock(&g_mu);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
gpr_mu_unlock(&g_mu);
*lb_addrs = grpc_lb_addresses_create(1, NULL);
grpc_lb_addresses_set_address(*lb_addrs, 0, NULL, 0, false, NULL, NULL);
}
grpc_closure_sched(exec_ctx, on_done, error);
return NULL;
}
static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx,
const char *name) {
grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
@ -125,6 +147,7 @@ int main(int argc, char **argv) {
gpr_mu_init(&g_mu);
g_combiner = grpc_combiner_create(NULL);
grpc_resolve_address = my_resolve_address;
grpc_dns_lookup_ares = my_dns_lookup_ares;
grpc_channel_args *result = (grpc_channel_args *)1;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

@ -20,6 +20,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/iomgr/combiner.h"
#include "test/core/util/test_config.h"
@ -73,7 +74,11 @@ int main(int argc, char **argv) {
test_succeeds(dns, "dns:10.2.1.1");
test_succeeds(dns, "dns:10.2.1.1:1234");
test_succeeds(dns, "ipv4:www.google.com");
test_fails(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
if (grpc_resolve_address == grpc_resolve_address_ares) {
test_succeeds(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
} else {
test_fails(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
}
grpc_resolver_factory_unref(dns);
{

@ -24,6 +24,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/resolve_address.h"
@ -362,6 +364,7 @@ typedef struct addr_req {
char *addr;
grpc_closure *on_done;
grpc_resolved_addresses **addrs;
grpc_lb_addresses **lb_addrs;
} addr_req;
static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg,
@ -369,11 +372,17 @@ static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg,
addr_req *r = arg;
if (error == GRPC_ERROR_NONE && 0 == strcmp(r->addr, "server")) {
grpc_resolved_addresses *addrs = gpr_malloc(sizeof(*addrs));
addrs->naddrs = 1;
addrs->addrs = gpr_malloc(sizeof(*addrs->addrs));
addrs->addrs[0].len = 0;
*r->addrs = addrs;
if (r->addrs != NULL) {
grpc_resolved_addresses *addrs = gpr_malloc(sizeof(*addrs));
addrs->naddrs = 1;
addrs->addrs = gpr_malloc(sizeof(*addrs->addrs));
addrs->addrs[0].len = 0;
*r->addrs = addrs;
} else if (r->lb_addrs != NULL) {
grpc_lb_addresses *lb_addrs = grpc_lb_addresses_create(1, NULL);
grpc_lb_addresses_set_address(lb_addrs, 0, NULL, 0, NULL, NULL, NULL);
*r->lb_addrs = lb_addrs;
}
grpc_closure_sched(exec_ctx, r->on_done, GRPC_ERROR_NONE);
} else {
grpc_closure_sched(exec_ctx, r->on_done,
@ -394,11 +403,29 @@ void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
r->addr = gpr_strdup(addr);
r->on_done = on_done;
r->addrs = addresses;
r->lb_addrs = NULL;
grpc_timer_init(
exec_ctx, &r->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(1, GPR_TIMESPAN)),
grpc_closure_create(finish_resolve, r, grpc_schedule_on_exec_ctx),
gpr_now(GPR_CLOCK_MONOTONIC));
}
grpc_ares_request *my_dns_lookup_ares(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb) {
addr_req *r = gpr_malloc(sizeof(*r));
r->addr = gpr_strdup(addr);
r->on_done = on_done;
r->addrs = NULL;
r->lb_addrs = lb_addrs;
grpc_timer_init(
exec_ctx, &r->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(1, GPR_TIMESPAN)),
grpc_closure_create(finish_resolve, r, grpc_schedule_on_exec_ctx),
gpr_now(GPR_CLOCK_MONOTONIC));
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
@ -710,6 +737,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_init();
grpc_timer_manager_set_threading(false);
grpc_resolve_address = my_resolve_address;
grpc_dns_lookup_ares = my_dns_lookup_ares;
GPR_ASSERT(g_channel == NULL);
GPR_ASSERT(g_server == NULL);

@ -27,6 +27,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <string.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/end2end/cq_verifier.h"
@ -43,6 +45,11 @@ static void (*iomgr_resolve_address)(grpc_exec_ctx *exec_ctx, const char *addr,
grpc_closure *on_done,
grpc_resolved_addresses **addresses);
static grpc_ares_request *(*iomgr_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb);
static void set_resolve_port(int port) {
gpr_mu_lock(&g_mu);
g_resolve_port = port;
@ -80,6 +87,36 @@ static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
grpc_closure_sched(exec_ctx, on_done, error);
}
static grpc_ares_request *my_dns_lookup_ares(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb) {
if (0 != strcmp(addr, "test")) {
return iomgr_dns_lookup_ares(exec_ctx, dns_server, addr, default_port,
interested_parties, on_done, lb_addrs,
check_grpclb);
}
grpc_error *error = GRPC_ERROR_NONE;
gpr_mu_lock(&g_mu);
if (g_resolve_port < 0) {
gpr_mu_unlock(&g_mu);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
*lb_addrs = grpc_lb_addresses_create(1, NULL);
struct sockaddr_in *sa = gpr_zalloc(sizeof(struct sockaddr_in));
sa->sin_family = AF_INET;
sa->sin_addr.s_addr = htonl(0x7f000001);
sa->sin_port = htons((uint16_t)g_resolve_port);
grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, NULL,
NULL);
gpr_free(sa);
gpr_mu_unlock(&g_mu);
}
grpc_closure_sched(exec_ctx, on_done, error);
return NULL;
}
int main(int argc, char **argv) {
grpc_completion_queue *cq;
cq_verifier *cqv;
@ -91,7 +128,9 @@ int main(int argc, char **argv) {
gpr_mu_init(&g_mu);
grpc_init();
iomgr_resolve_address = grpc_resolve_address;
iomgr_dns_lookup_ares = grpc_dns_lookup_ares;
grpc_resolve_address = my_resolve_address;
grpc_dns_lookup_ares = my_dns_lookup_ares;
int was_cancelled1;
int was_cancelled2;

@ -92,6 +92,7 @@ void grpc_free_port_using_server(int port) {
grpc_schedule_on_exec_ctx),
&rsp);
grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(pr.mu);
while (!pr.done) {
grpc_pollset_worker *worker = NULL;
@ -224,6 +225,7 @@ int grpc_pick_port_using_server(void) {
grpc_closure_create(got_port_from_server, &pr, grpc_schedule_on_exec_ctx),
&pr.response);
grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(pr.mu);
while (pr.port == -1) {
grpc_pollset_worker *worker = NULL;

@ -948,6 +948,7 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c \
src/core/ext/filters/client_channel/resolver/dns/native/README.md \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c \

@ -8526,7 +8526,8 @@
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c"
],
"third_party": false,
"type": "filegroup"

@ -974,6 +974,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper_fallback.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\sockaddr\sockaddr_resolver.c">

@ -679,6 +679,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
<Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper_fallback.c">
<Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
<Filter>src\core\ext\filters\client_channel\resolver\dns\native</Filter>
</ClCompile>

@ -857,6 +857,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper_fallback.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\sockaddr\sockaddr_resolver.c">

@ -556,6 +556,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.c">
<Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper_fallback.c">
<Filter>src\core\ext\filters\client_channel\resolver\dns\c_ares</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\client_channel\resolver\dns\native\dns_resolver.c">
<Filter>src\core\ext\filters\client_channel\resolver\dns\native</Filter>
</ClCompile>

Loading…
Cancel
Save