From 24e3bc5510bfee61d9f62feac95fbe32b1267b85 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Tue, 30 May 2017 18:26:17 -0700 Subject: Fix api_fuzzer, dns_resolver_connectivity_test --- test/core/end2end/fuzzers/api_fuzzer.c | 38 +++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'test/core/end2end') diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c index b33b43dac5..32f75f6b7d 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.c +++ b/test/core/end2end/fuzzers/api_fuzzer.c @@ -39,6 +39,8 @@ #include #include +#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" @@ -377,6 +379,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, @@ -384,11 +387,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, @@ -409,6 +418,24 @@ 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)); +} + +void 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)), @@ -725,6 +752,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); -- cgit v1.2.3 From 3b4bed273cd38964d097cb110f894c9963137af2 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Sun, 4 Jun 2017 01:41:15 -0700 Subject: Cancel the dns lookup in dns_ares_shutdown --- .../resolver/dns/c_ares/dns_resolver_ares.c | 14 +++++--- .../resolver/dns/c_ares/grpc_ares_ev_driver.h | 4 +++ .../dns/c_ares/grpc_ares_ev_driver_posix.c | 14 ++++++++ .../resolver/dns/c_ares/grpc_ares_wrapper.c | 37 ++++++++++++---------- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 8 ++++- .../resolvers/dns_resolver_connectivity_test.c | 11 +++---- test/core/end2end/fuzzers/api_fuzzer.c | 10 +++--- 7 files changed, 66 insertions(+), 32 deletions(-) (limited to 'test/core/end2end') diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c index dcd16a3f1c..4080fb1770 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c @@ -80,6 +80,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? */ @@ -124,6 +126,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( @@ -160,6 +165,7 @@ 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; + 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); @@ -216,10 +222,10 @@ static void dns_ares_start_resolving_locked(grpc_exec_ctx *exec_ctx, GPR_ASSERT(!r->resolving); r->resolving = true; r->lb_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->lb_addresses, - true /* check_grpclb */); + 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, diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h index aa88940021..b45d7299e2 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h @@ -62,5 +62,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 \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c index 1e4f3eb5ab..91183e30af 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c @@ -155,6 +155,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) { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c index 8f856885ec..afbccfd840 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c @@ -61,7 +61,7 @@ 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 */ @@ -80,7 +80,7 @@ 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 */ @@ -121,12 +121,10 @@ static void grpc_ares_request_unref(grpc_exec_ctx *exec_ctx, the newly created exec_ctx, since the caller has been warned not to acquire locks in on_done. ares_dns_resolver is using combiner to protect resources needed by on_done. */ - gpr_log(GPR_DEBUG, "grpc_ares_request_unref NULl"); grpc_exec_ctx new_exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure_sched(&new_exec_ctx, r->on_done, r->error); grpc_exec_ctx_finish(&new_exec_ctx); } else { - gpr_log(GPR_DEBUG, "grpc_ares_request_unref exec_ctx"); grpc_closure_sched(exec_ctx, r->on_done, r->error); } gpr_mu_destroy(&r->mu); @@ -177,11 +175,11 @@ static void on_hostbyname_done_cb(void *arg, int status, int timeouts, gpr_realloc((*lb_addresses)->addresses, sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses); for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) { - memset(&(*lb_addresses)->addresses[i], 0, sizeof(grpc_lb_address)); 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; @@ -202,6 +200,7 @@ static void on_hostbyname_done_cb(void *arg, int status, int timeouts, 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; @@ -282,11 +281,10 @@ static void on_srv_query_done_cb(void *arg, int status, int timeouts, grpc_exec_ctx_finish(&exec_ctx); } -void 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_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) { @@ -384,19 +382,26 @@ void grpc_dns_lookup_ares_impl(grpc_exec_ctx *exec_ctx, const char *dns_server, grpc_ares_request_unref(exec_ctx, r); gpr_free(host); gpr_free(port); - return; + return r; error_cleanup: grpc_closure_sched(exec_ctx, on_done, error); gpr_free(host); gpr_free(port); + return NULL; } -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_lb_addresses **addrs, - bool check_grpclb) = grpc_dns_lookup_ares_impl; +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) { + 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); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 9bcc115beb..4a8374a192 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -40,6 +40,8 @@ #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 @@ -59,11 +61,15 @@ extern void (*grpc_resolve_address_ares)(grpc_exec_ctx *exec_ctx, 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 void (*grpc_dns_lookup_ares)( +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(). */ grpc_error *grpc_ares_init(void); diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c index 35b73a355c..df7a693287 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -72,12 +72,10 @@ static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr, grpc_closure_sched(exec_ctx, on_done, error); } -static void 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) { +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; @@ -91,6 +89,7 @@ static void my_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server, grpc_lb_addresses_set_address(*lb_addrs, 0, NULL, 0, NULL, NULL, NULL); } grpc_closure_sched(exec_ctx, on_done, error); + return NULL; } static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx, diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c index 32f75f6b7d..c81ff19d76 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.c +++ b/test/core/end2end/fuzzers/api_fuzzer.c @@ -426,11 +426,10 @@ void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr, gpr_now(GPR_CLOCK_MONOTONIC)); } -void 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) { +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; @@ -441,6 +440,7 @@ void my_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server, 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; } //////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 1f4b2a8e33e045464793665be887b54ec37b7a9d Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 5 Jun 2017 15:24:31 -0700 Subject: Fix the fd clean up process --- .../dns/c_ares/grpc_ares_ev_driver_posix.c | 9 +++-- .../resolvers/dns_resolver_connectivity_test.c | 2 +- test/core/end2end/goaway_server_test.c | 39 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) (limited to 'test/core/end2end') diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c index 91183e30af..f036630f02 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c @@ -114,9 +114,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); } diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c index df7a693287..f4ea5aa0c8 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -86,7 +86,7 @@ static grpc_ares_request *my_dns_lookup_ares( } else { gpr_mu_unlock(&g_mu); *lb_addrs = grpc_lb_addresses_create(1, NULL); - grpc_lb_addresses_set_address(*lb_addrs, 0, NULL, 0, NULL, NULL, NULL); + grpc_lb_addresses_set_address(*lb_addrs, 0, NULL, 0, false, NULL, NULL); } grpc_closure_sched(exec_ctx, on_done, error); return NULL; diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c index ababdb70a8..8ea78542b4 100644 --- a/test/core/end2end/goaway_server_test.c +++ b/test/core/end2end/goaway_server_test.c @@ -42,6 +42,8 @@ #include #include #include +#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" @@ -58,6 +60,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; @@ -95,6 +102,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; @@ -106,7 +143,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; -- cgit v1.2.3