diff options
author | Yuchen Zeng <zyc@google.com> | 2016-08-05 10:33:16 -0700 |
---|---|---|
committer | Yuchen Zeng <zyc@google.com> | 2016-08-05 10:33:16 -0700 |
commit | d4bbfc7dcf11a421d91918c8b32fc7ca959daff3 (patch) | |
tree | ad19e3b2c83081813727e5643e29859fa2368d1b /src | |
parent | 9b5aa6360dc07f054dda6f2e9983747e1798eb6c (diff) |
Implement c-ares based dns resolver
Diffstat (limited to 'src')
-rw-r--r-- | src/core/ext/client_config/client_channel.c | 46 | ||||
-rw-r--r-- | src/core/ext/client_config/resolver.c | 12 | ||||
-rw-r--r-- | src/core/ext/client_config/resolver.h | 12 | ||||
-rw-r--r-- | src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c | 390 | ||||
-rw-r--r-- | src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h | 52 | ||||
-rw-r--r-- | src/core/ext/resolver/sockaddr/sockaddr_resolver.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/error.c | 4 | ||||
-rw-r--r-- | src/core/lib/iomgr/ev_epoll_linux.c | 6 | ||||
-rw-r--r-- | src/core/lib/iomgr/resolve_address_cares.c | 201 | ||||
-rw-r--r-- | src/core/plugin_registry/grpc_plugin_registry.c | 8 | ||||
-rw-r--r-- | src/core/plugin_registry/grpc_unsecure_plugin_registry.c | 8 | ||||
-rw-r--r-- | src/python/grpcio/grpc_core_dependencies.py | 3 |
12 files changed, 518 insertions, 226 deletions
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index a096435c98..0c7aa86871 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -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); } diff --git a/src/core/ext/client_config/resolver.c b/src/core/ext/client_config/resolver.c index eb004455bd..ad9d30b302 100644 --- a/src/core/ext/client_config/resolver.c +++ b/src/core/ext/client_config/resolver.c @@ -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); } diff --git a/src/core/ext/client_config/resolver.h b/src/core/ext/client_config/resolver.h index 6ecb5d2774..fd907b2049 100644 --- a/src/core/ext/client_config/resolver.h +++ b/src/core/ext/client_config/resolver.h @@ -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); diff --git a/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c new file mode 100644 index 0000000000..7d0b573045 --- /dev/null +++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c @@ -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 diff --git a/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h new file mode 100644 index 0000000000..6d931c7e02 --- /dev/null +++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -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 */ diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c index 1f7cce2f43..792e2c3c02 100644 --- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c @@ -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; diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c index 149c55663c..a70280955c 100644 --- a/src/core/lib/iomgr/error.c +++ b/src/core/lib/iomgr/error.c @@ -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); diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 6a63c4d1d1..143facd260 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -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) { diff --git a/src/core/lib/iomgr/resolve_address_cares.c b/src/core/lib/iomgr/resolve_address_cares.c deleted file mode 100644 index 372a7cfcd9..0000000000 --- a/src/core/lib/iomgr/resolve_address_cares.c +++ /dev/null @@ -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 diff --git a/src/core/plugin_registry/grpc_plugin_registry.c b/src/core/plugin_registry/grpc_plugin_registry.c index 905cd59e23..cda0f9857f 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.c +++ b/src/core/plugin_registry/grpc_plugin_registry.c @@ -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, diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c index 7995078725..68c4afdae9 100644 --- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c +++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c @@ -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, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 59d01f7e17..5387d40a51 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -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', |