aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c')
-rw-r--r--src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
new file mode 100644
index 0000000000..b65974e1bb
--- /dev/null
+++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
@@ -0,0 +1,205 @@
+/*
+ *
+ * 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>
+#ifndef GRPC_NATIVE_ADDRESS_RESOLVE
+#ifdef GPR_POSIX_SOCKET
+
+#include "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h"
+
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+
+#include <ares.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.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"
+
+typedef struct fd_pair {
+ grpc_fd *grpc_fd;
+ int fd;
+ struct fd_pair *next;
+} fd_pair;
+
+struct grpc_ares_ev_driver {
+ bool closing;
+ ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+ int bitmask;
+ grpc_closure driver_closure;
+ grpc_pollset_set *pollset_set;
+ ares_channel channel;
+ fd_pair *fds;
+};
+
+grpc_error *grpc_ares_ev_driver_create(grpc_ares_ev_driver **ev_driver,
+ grpc_pollset_set *pollset_set) {
+ int status;
+ *ev_driver = gpr_malloc(sizeof(grpc_ares_ev_driver));
+ status = ares_init(&(*ev_driver)->channel);
+ if (status != ARES_SUCCESS) {
+ gpr_free(*ev_driver);
+ return GRPC_ERROR_CREATE("Failed to init ares channel");
+ }
+ (*ev_driver)->pollset_set = pollset_set;
+ (*ev_driver)->fds = NULL;
+ (*ev_driver)->closing = false;
+ return GRPC_ERROR_NONE;
+}
+
+void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver) {
+ // ev_driver->pollset_set = NULL;
+ ev_driver->closing = true;
+}
+
+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 driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ grpc_ares_ev_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);
+ }
+ }
+ grpc_ares_notify_on_event(exec_ctx, d);
+ grpc_exec_ctx_flush(exec_ctx);
+}
+
+void grpc_ares_gethostbyname(grpc_ares_ev_driver *ev_driver, const char *host,
+ ares_host_callback on_done_cb, void *arg) {
+ ares_gethostbyname(ev_driver->channel, host, AF_UNSPEC, on_done_cb, arg);
+}
+
+ares_channel *grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver *ev_driver) {
+ return &ev_driver->channel;
+}
+
+void grpc_ares_notify_on_event(grpc_exec_ctx *exec_ctx,
+ grpc_ares_ev_driver *ev_driver) {
+ size_t i;
+ fd_pair *new_list = NULL;
+ gpr_log(GPR_ERROR, "\n\n notify_on_event");
+ if (!ev_driver->closing) {
+ 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, "ares_ev_driver-%" 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;
+ if (ev_driver->closing) {
+ ares_destroy(ev_driver->channel);
+ gpr_free(ev_driver);
+ }
+
+ gpr_log(GPR_ERROR, "eof notify_on_event");
+}
+
+#endif /* GPR_POSIX_SOCKET */
+#endif /* GRPC_NATIVE_ADDRESS_RESOLVE */