blob: 302a10370355e6e986357a0bb7e4c8329eb5cea0 [file] [log] [blame]
Yuchen Zeng85750b02016-08-08 14:16:34 -07001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33#include <grpc/support/port_platform.h>
Yuchen Zeng299dd8d2016-08-16 21:40:13 -070034#ifndef GRPC_NATIVE_ADDRESS_RESOLVE
Yuchen Zeng85750b02016-08-08 14:16:34 -070035#ifdef GPR_POSIX_SOCKET
36
37#include "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h"
38
Yuchen Zeng85750b02016-08-08 14:16:34 -070039#include "src/core/lib/iomgr/ev_posix.h"
40#include "src/core/lib/iomgr/sockaddr.h"
41
42#include <ares.h>
43#include <grpc/support/alloc.h>
44#include <grpc/support/log.h>
45#include <grpc/support/string_util.h>
46#include <grpc/support/time.h>
47#include <grpc/support/useful.h>
48#include "src/core/lib/iomgr/iomgr_internal.h"
49#include "src/core/lib/iomgr/sockaddr_utils.h"
50#include "src/core/lib/iomgr/unix_sockets_posix.h"
51#include "src/core/lib/support/block_annotate.h"
52#include "src/core/lib/support/string.h"
53
Yuchen Zengc1893dc2016-09-30 18:49:41 -070054typedef struct fd_node {
Yuchen Zenga418ed22016-08-08 17:24:33 -070055 grpc_fd *grpc_fd;
Yuchen Zengc1893dc2016-09-30 18:49:41 -070056 struct fd_node *next;
57} fd_node;
Yuchen Zeng85750b02016-08-08 14:16:34 -070058
59struct grpc_ares_ev_driver {
Yuchen Zengc1893dc2016-09-30 18:49:41 -070060 /** the ares_channel owned by this event driver */
Yuchen Zeng8917aec2016-08-09 18:41:31 -070061 ares_channel channel;
Yuchen Zengc1893dc2016-09-30 18:49:41 -070062 /** a closure wrapping the driver_cb, which should be invoked each time the ev
63 driver gets notified by fds. */
64 grpc_closure driver_closure;
65 /** pollset set for driving the IO events of the channel */
66 grpc_pollset_set *pollset_set;
Yuchen Zengc1893dc2016-09-30 18:49:41 -070067 /** has grpc_ares_ev_driver_destroy been called on this event driver? */
68 bool closing;
Yuchen Zengc1893dc2016-09-30 18:49:41 -070069 /** an array of ares sockets that the ares channel owned by this event driver
70 is currently using */
71 ares_socket_t socks[ARES_GETSOCK_MAXNUM];
72 /** a bitmask that can tell if an ares socket in the socks array is readable
73 or/and writable */
74 int socks_bitmask;
75 /** a list of grpc_fd that this event driver is currently using. */
76 fd_node *fds;
Yuchen Zengc87b77f2016-10-03 11:36:36 -070077
Yuchen Zeng43aa9a12016-10-25 10:44:39 -070078 /** mutex guarding the rest of the state */
Yuchen Zengc87b77f2016-10-03 11:36:36 -070079 gpr_mu mu;
80 /** is this event driver currently working? */
81 bool working;
Yuchen Zeng85750b02016-08-08 14:16:34 -070082};
83
Yuchen Zengc1893dc2016-09-30 18:49:41 -070084static void grpc_ares_notify_on_event(grpc_exec_ctx *exec_ctx,
85 grpc_ares_ev_driver *ev_driver);
Yuchen Zeng213d7842016-08-26 19:28:16 -070086
Yuchen Zeng8917aec2016-08-09 18:41:31 -070087grpc_error *grpc_ares_ev_driver_create(grpc_ares_ev_driver **ev_driver,
88 grpc_pollset_set *pollset_set) {
89 int status;
90 *ev_driver = gpr_malloc(sizeof(grpc_ares_ev_driver));
91 status = ares_init(&(*ev_driver)->channel);
92 if (status != ARES_SUCCESS) {
Yuchen Zeng43aa9a12016-10-25 10:44:39 -070093 char *err_msg;
94 gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s",
95 ares_strerror(status));
96 grpc_error *err = GRPC_ERROR_CREATE(err_msg);
97 gpr_free(err_msg);
Yuchen Zeng8917aec2016-08-09 18:41:31 -070098 gpr_free(*ev_driver);
Yuchen Zeng43aa9a12016-10-25 10:44:39 -070099 return err;
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700100 }
Yuchen Zeng213d7842016-08-26 19:28:16 -0700101 gpr_mu_init(&(*ev_driver)->mu);
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700102 (*ev_driver)->pollset_set = pollset_set;
103 (*ev_driver)->fds = NULL;
104 (*ev_driver)->closing = false;
Yuchen Zengffbc1672016-10-03 11:29:22 -0700105 (*ev_driver)->working = false;
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700106 return GRPC_ERROR_NONE;
107}
108
109void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver) {
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700110 ev_driver->closing = true;
111}
112
Yuchen Zeng3026b6c2016-10-03 16:03:29 -0700113// Search fd in the fd_node list head. This is an O(n) search, the max possible
Yuchen Zeng4eedcde2016-10-11 11:23:37 -0700114// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 3 in our tests.
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700115static fd_node *get_fd(fd_node **head, int fd) {
116 fd_node dummy_head;
117 fd_node *node;
118 fd_node *ret;
Yuchen Zeng925b6882016-08-24 18:42:25 -0700119
Yuchen Zeng85750b02016-08-08 14:16:34 -0700120 dummy_head.next = *head;
121 node = &dummy_head;
122 while (node->next != NULL) {
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700123 if (grpc_fd_wrapped_fd(node->next->grpc_fd) == fd) {
Yuchen Zeng85750b02016-08-08 14:16:34 -0700124 ret = node->next;
125 node->next = node->next->next;
126 *head = dummy_head.next;
127 return ret;
128 }
Yuchen Zengc87b77f2016-10-03 11:36:36 -0700129 node = node->next;
Yuchen Zeng85750b02016-08-08 14:16:34 -0700130 }
131 return NULL;
132}
133
Yuchen Zeng3026b6c2016-10-03 16:03:29 -0700134// Process each file descriptor that may wake this callback up.
Yuchen Zeng85750b02016-08-08 14:16:34 -0700135static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
136 grpc_ares_ev_driver *d = arg;
137 size_t i;
Yuchen Zeng925b6882016-08-24 18:42:25 -0700138
Yuchen Zeng85750b02016-08-08 14:16:34 -0700139 if (error == GRPC_ERROR_NONE) {
Yuchen Zeng85750b02016-08-08 14:16:34 -0700140 for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
Yuchen Zeng43aa9a12016-10-25 10:44:39 -0700141 ares_socket_t read_fd = ARES_GETSOCK_READABLE(d->socks_bitmask, i)
142 ? d->socks[i]
143 : ARES_SOCKET_BAD;
144 ares_socket_t write_fd = ARES_GETSOCK_WRITABLE(d->socks_bitmask, i)
145 ? d->socks[i]
146 : ARES_SOCKET_BAD;
147 ares_process_fd(d->channel, read_fd, write_fd);
Yuchen Zeng85750b02016-08-08 14:16:34 -0700148 }
Yuchen Zeng4dd18912016-08-24 17:17:17 -0700149 } else {
Yuchen Zeng912327e2016-10-25 18:27:17 -0700150 // error != GRPC_ERROR_NONE means the waiting timed out or the fd has been
151 // shutdown. In this case, the event driver cancels all the ongoing requests
152 // that are using its channel. The fds get cleaned up in the next
153 // grpc_ares_notify_on_event.
Yuchen Zeng4dd18912016-08-24 17:17:17 -0700154 ares_cancel(d->channel);
Yuchen Zeng85750b02016-08-08 14:16:34 -0700155 }
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700156 grpc_ares_notify_on_event(exec_ctx, d);
Yuchen Zeng85750b02016-08-08 14:16:34 -0700157}
158
Yuchen Zeng9248d352016-08-16 16:33:10 -0700159ares_channel *grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver *ev_driver) {
160 return &ev_driver->channel;
161}
162
Yuchen Zeng3026b6c2016-10-03 16:03:29 -0700163// Get the file descriptors used by the ev_driver's ares channel, register
164// driver_closure with these filedescriptors.
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700165static void grpc_ares_notify_on_event(grpc_exec_ctx *exec_ctx,
166 grpc_ares_ev_driver *ev_driver) {
Yuchen Zeng85750b02016-08-08 14:16:34 -0700167 size_t i;
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700168 fd_node *new_list = NULL;
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700169 if (!ev_driver->closing) {
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700170 ev_driver->socks_bitmask =
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700171 ares_getsock(ev_driver->channel, ev_driver->socks, ARES_GETSOCK_MAXNUM);
172 grpc_closure_init(&ev_driver->driver_closure, driver_cb, ev_driver);
173 for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700174 if (ARES_GETSOCK_READABLE(ev_driver->socks_bitmask, i) ||
175 ARES_GETSOCK_WRITABLE(ev_driver->socks_bitmask, i)) {
176 fd_node *fdn = get_fd(&ev_driver->fds, ev_driver->socks[i]);
Yuchen Zeng912327e2016-10-25 18:27:17 -0700177 if (fdn == NULL) {
Yuchen Zengd0725d72016-08-26 17:27:32 -0700178 char *fd_name;
179 gpr_asprintf(&fd_name, "ares_ev_driver-%" PRIuPTR, i);
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700180 fdn = gpr_malloc(sizeof(fd_node));
181 fdn->grpc_fd = grpc_fd_create(ev_driver->socks[i], fd_name);
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700182 grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set,
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700183 fdn->grpc_fd);
Yuchen Zengd0725d72016-08-26 17:27:32 -0700184 gpr_free(fd_name);
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700185 }
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700186 fdn->next = new_list;
187 new_list = fdn;
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700188
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700189 if (ARES_GETSOCK_READABLE(ev_driver->socks_bitmask, i)) {
190 grpc_fd_notify_on_read(exec_ctx, fdn->grpc_fd,
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700191 &ev_driver->driver_closure);
192 }
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700193 if (ARES_GETSOCK_WRITABLE(ev_driver->socks_bitmask, i)) {
194 grpc_fd_notify_on_write(exec_ctx, fdn->grpc_fd,
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700195 &ev_driver->driver_closure);
196 }
Yuchen Zeng85750b02016-08-08 14:16:34 -0700197 }
Yuchen Zeng85750b02016-08-08 14:16:34 -0700198 }
Yuchen Zeng85750b02016-08-08 14:16:34 -0700199 }
200
201 while (ev_driver->fds != NULL) {
Yuchen Zeng912327e2016-10-25 18:27:17 -0700202 fd_node *cur = ev_driver->fds;
Yuchen Zeng85750b02016-08-08 14:16:34 -0700203 ev_driver->fds = ev_driver->fds->next;
Yuchen Zeng85750b02016-08-08 14:16:34 -0700204 grpc_pollset_set_del_fd(exec_ctx, ev_driver->pollset_set, cur->grpc_fd);
Yuchen Zeng85750b02016-08-08 14:16:34 -0700205 grpc_fd_shutdown(exec_ctx, cur->grpc_fd);
Yuchen Zeng00565312016-08-24 16:41:12 -0700206 grpc_fd_orphan(exec_ctx, cur->grpc_fd, NULL, NULL, "c-ares query finished");
Yuchen Zeng85750b02016-08-08 14:16:34 -0700207 gpr_free(cur);
208 }
209
210 ev_driver->fds = new_list;
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700211 // If the ev driver has no working fd, all the tasks are done.
212 if (!new_list) {
213 gpr_mu_lock(&ev_driver->mu);
214 ev_driver->working = false;
215 gpr_mu_unlock(&ev_driver->mu);
216 }
Yuchen Zeng213d7842016-08-26 19:28:16 -0700217
Yuchen Zeng8917aec2016-08-09 18:41:31 -0700218 if (ev_driver->closing) {
219 ares_destroy(ev_driver->channel);
220 gpr_free(ev_driver);
221 }
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700222}
223
224void grpc_ares_ev_driver_start(grpc_exec_ctx *exec_ctx,
225 grpc_ares_ev_driver *ev_driver) {
226 gpr_mu_lock(&ev_driver->mu);
227 if (ev_driver->working) {
228 gpr_mu_unlock(&ev_driver->mu);
229 return;
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700230 }
Yuchen Zeng912327e2016-10-25 18:27:17 -0700231 ev_driver->working = true;
Yuchen Zeng213d7842016-08-26 19:28:16 -0700232 gpr_mu_unlock(&ev_driver->mu);
Yuchen Zengc1893dc2016-09-30 18:49:41 -0700233 grpc_ares_notify_on_event(exec_ctx, ev_driver);
Yuchen Zeng85750b02016-08-08 14:16:34 -0700234}
235
Yuchen Zeng299dd8d2016-08-16 21:40:13 -0700236#endif /* GPR_POSIX_SOCKET */
237#endif /* GRPC_NATIVE_ADDRESS_RESOLVE */