aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuchen Zeng <zyc@google.com>2016-08-05 10:33:16 -0700
committerGravatar Yuchen Zeng <zyc@google.com>2016-08-05 10:33:16 -0700
commitd4bbfc7dcf11a421d91918c8b32fc7ca959daff3 (patch)
treead19e3b2c83081813727e5643e29859fa2368d1b /src
parent9b5aa6360dc07f054dda6f2e9983747e1798eb6c (diff)
Implement c-ares based dns resolver
Diffstat (limited to 'src')
-rw-r--r--src/core/ext/client_config/client_channel.c46
-rw-r--r--src/core/ext/client_config/resolver.c12
-rw-r--r--src/core/ext/client_config/resolver.h12
-rw-r--r--src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c390
-rw-r--r--src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h52
-rw-r--r--src/core/ext/resolver/sockaddr/sockaddr_resolver.c2
-rw-r--r--src/core/lib/iomgr/error.c4
-rw-r--r--src/core/lib/iomgr/ev_epoll_linux.c6
-rw-r--r--src/core/lib/iomgr/resolve_address_cares.c201
-rw-r--r--src/core/plugin_registry/grpc_plugin_registry.c8
-rw-r--r--src/core/plugin_registry/grpc_unsecure_plugin_registry.c8
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py3
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',