blob: d089d2bc3b7406e53acbb460ea3a489a0459f01c [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * 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
murgatroid9954070892016-08-08 17:01:18 -070034#include "src/core/lib/iomgr/port.h"
Craig Tiller0c0b60c2015-01-21 15:49:28 -080035
murgatroid99623dd4f2016-08-08 17:31:27 -070036#ifdef GRPC_POSIX_SOCKET
Craig Tiller0c0b60c2015-01-21 15:49:28 -080037
Craig Tiller86958762016-09-23 12:05:34 -070038#include "src/core/lib/iomgr/tcp_client_posix.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039
40#include <errno.h>
nnoble0c475f02014-12-05 15:37:39 -080041#include <netinet/in.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080042#include <string.h>
43#include <unistd.h>
44
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045#include <grpc/support/alloc.h>
46#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070047#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080048#include <grpc/support/time.h>
49
Craig Tiller86958762016-09-23 12:05:34 -070050#include "src/core/lib/channel/channel_args.h"
Craig Tiller8a034482016-03-28 16:09:04 -070051#include "src/core/lib/iomgr/ev_posix.h"
Craig Tiller9533d042016-03-25 17:11:06 -070052#include "src/core/lib/iomgr/iomgr_posix.h"
Craig Tiller9533d042016-03-25 17:11:06 -070053#include "src/core/lib/iomgr/sockaddr_utils.h"
Yuchen Zengde3daf52016-10-13 17:26:26 -070054#include "src/core/lib/iomgr/socket_mutator.h"
Craig Tiller9533d042016-03-25 17:11:06 -070055#include "src/core/lib/iomgr/socket_utils_posix.h"
56#include "src/core/lib/iomgr/tcp_posix.h"
57#include "src/core/lib/iomgr/timer.h"
58#include "src/core/lib/iomgr/unix_sockets_posix.h"
59#include "src/core/lib/support/string.h"
Craig Tillerc46beaa2016-02-24 09:17:19 -080060
Craig Tiller5e53ddb2015-09-16 10:53:15 -070061extern int grpc_tcp_trace;
62
Craig Tillera82950e2015-09-22 12:33:20 -070063typedef struct {
ctiller58393c22015-01-07 14:03:30 -080064 gpr_mu mu;
ctiller18b49ab2014-12-09 14:39:16 -080065 grpc_fd *fd;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066 gpr_timespec deadline;
David Garcia Quintasf747bbc2015-10-04 23:09:47 -070067 grpc_timer alarm;
ctiller58393c22015-01-07 14:03:30 -080068 int refs;
Craig Tiller33825112015-09-18 07:44:19 -070069 grpc_closure write_closure;
Craig Tillerb49736822015-06-30 08:15:08 -070070 grpc_pollset_set *interested_parties;
Craig Tiller1b22b9d2015-07-20 13:42:22 -070071 char *addr_str;
Craig Tillerd1bec032015-09-18 17:29:00 -070072 grpc_endpoint **ep;
73 grpc_closure *closure;
Craig Tiller86958762016-09-23 12:05:34 -070074 grpc_channel_args *channel_args;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080075} async_connect;
76
Yuchen Zeng64d518e2016-11-02 16:27:49 -070077static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd,
Yuchen Zeng929f4c62016-10-10 16:02:43 -070078 const grpc_channel_args *channel_args) {
Craig Tiller27f59af2016-04-28 14:19:48 -070079 grpc_error *err = GRPC_ERROR_NONE;
80
Craig Tiller80384bd2016-05-06 16:12:31 -070081 GPR_ASSERT(fd >= 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080082
Craig Tiller4f1d0f32016-05-06 17:12:37 -070083 err = grpc_set_socket_nonblocking(fd, 1);
84 if (err != GRPC_ERROR_NONE) goto error;
85 err = grpc_set_socket_cloexec(fd, 1);
86 if (err != GRPC_ERROR_NONE) goto error;
87 if (!grpc_is_unix_socket(addr)) {
88 err = grpc_set_socket_low_latency(fd, 1);
89 if (err != GRPC_ERROR_NONE) goto error;
Craig Tillera82950e2015-09-22 12:33:20 -070090 }
Craig Tiller4f1d0f32016-05-06 17:12:37 -070091 err = grpc_set_socket_no_sigpipe_if_possible(fd);
92 if (err != GRPC_ERROR_NONE) goto error;
Yuchen Zeng929f4c62016-10-10 16:02:43 -070093 if (channel_args) {
94 for (size_t i = 0; i < channel_args->num_args; i++) {
Yuchen Zenga4f708a2016-10-11 18:36:24 -070095 if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
96 GPR_ASSERT(channel_args->args[i].type == GRPC_ARG_POINTER);
97 grpc_socket_mutator *mutator = channel_args->args[i].value.pointer.p;
98 err = grpc_set_socket_with_mutator(fd, mutator);
Yuchen Zeng929f4c62016-10-10 16:02:43 -070099 if (err != GRPC_ERROR_NONE) goto error;
Yuchen Zeng929f4c62016-10-10 16:02:43 -0700100 }
101 }
102 }
Craig Tiller27f59af2016-04-28 14:19:48 -0700103 goto done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800104
105error:
Craig Tillera82950e2015-09-22 12:33:20 -0700106 if (fd >= 0) {
107 close(fd);
108 }
Craig Tiller27f59af2016-04-28 14:19:48 -0700109done:
110 return err;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800111}
112
Craig Tillerc027e772016-05-03 16:27:00 -0700113static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
ctiller58393c22015-01-07 14:03:30 -0800114 int done;
115 async_connect *ac = acp;
Craig Tillera82950e2015-09-22 12:33:20 -0700116 if (grpc_tcp_trace) {
Craig Tillerc027e772016-05-03 16:27:00 -0700117 const char *str = grpc_error_string(error);
118 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
119 str);
120 grpc_error_free_string(str);
Craig Tillera82950e2015-09-22 12:33:20 -0700121 }
122 gpr_mu_lock(&ac->mu);
123 if (ac->fd != NULL) {
124 grpc_fd_shutdown(exec_ctx, ac->fd);
125 }
ctiller58393c22015-01-07 14:03:30 -0800126 done = (--ac->refs == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700127 gpr_mu_unlock(&ac->mu);
128 if (done) {
129 gpr_mu_destroy(&ac->mu);
130 gpr_free(ac->addr_str);
Craig Tiller86958762016-09-23 12:05:34 -0700131 grpc_channel_args_destroy(ac->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700132 gpr_free(ac);
133 }
ctiller58393c22015-01-07 14:03:30 -0800134}
135
Craig Tiller86958762016-09-23 12:05:34 -0700136grpc_endpoint *grpc_tcp_client_create_from_fd(
137 grpc_exec_ctx *exec_ctx, grpc_fd *fd, const grpc_channel_args *channel_args,
138 const char *addr_str) {
139 size_t tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
Craig Tiller20afa3d2016-10-17 14:52:14 -0700140 grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
Craig Tiller86958762016-09-23 12:05:34 -0700141 if (channel_args != NULL) {
142 for (size_t i = 0; i < channel_args->num_args; i++) {
143 if (0 ==
144 strcmp(channel_args->args[i].key, GRPC_ARG_TCP_READ_CHUNK_SIZE)) {
145 grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
146 8 * 1024 * 1024};
147 tcp_read_chunk_size = (size_t)grpc_channel_arg_get_integer(
148 &channel_args->args[i], options);
Craig Tiller153eaa72016-10-21 13:52:36 -0700149 } else if (0 ==
150 strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
Craig Tiller20afa3d2016-10-17 14:52:14 -0700151 grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
152 resource_quota = grpc_resource_quota_internal_ref(
Craig Tiller86958762016-09-23 12:05:34 -0700153 channel_args->args[i].value.pointer.p);
154 }
155 }
156 }
157
158 grpc_endpoint *ep =
Craig Tiller20afa3d2016-10-17 14:52:14 -0700159 grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
160 grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
Craig Tiller86958762016-09-23 12:05:34 -0700161 return ep;
162}
163
Craig Tillerc027e772016-05-03 16:27:00 -0700164static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800165 async_connect *ac = acp;
166 int so_error = 0;
167 socklen_t so_error_size;
168 int err;
ctiller58393c22015-01-07 14:03:30 -0800169 int done;
Craig Tillerd1bec032015-09-18 17:29:00 -0700170 grpc_endpoint **ep = ac->ep;
171 grpc_closure *closure = ac->closure;
Craig Tiller5553eb32015-07-21 12:28:56 -0700172 grpc_fd *fd;
173
Craig Tiller82c63eb2016-05-10 15:28:01 -0700174 GRPC_ERROR_REF(error);
175
Craig Tillera82950e2015-09-22 12:33:20 -0700176 if (grpc_tcp_trace) {
Craig Tillerc027e772016-05-03 16:27:00 -0700177 const char *str = grpc_error_string(error);
178 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s",
179 ac->addr_str, str);
180 grpc_error_free_string(str);
Craig Tillera82950e2015-09-22 12:33:20 -0700181 }
Craig Tiller5e53ddb2015-09-16 10:53:15 -0700182
Craig Tillera82950e2015-09-22 12:33:20 -0700183 gpr_mu_lock(&ac->mu);
184 GPR_ASSERT(ac->fd);
Craig Tiller5553eb32015-07-21 12:28:56 -0700185 fd = ac->fd;
186 ac->fd = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700187 gpr_mu_unlock(&ac->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800188
David Garcia Quintasf747bbc2015-10-04 23:09:47 -0700189 grpc_timer_cancel(exec_ctx, &ac->alarm);
Craig Tiller26205362015-07-21 08:21:57 -0700190
Craig Tillera82950e2015-09-22 12:33:20 -0700191 gpr_mu_lock(&ac->mu);
Mark D. Rothe65ff112016-09-09 13:48:38 -0700192 if (error != GRPC_ERROR_NONE) {
Craig Tiller27f59af2016-04-28 14:19:48 -0700193 error =
194 grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, "Timeout occurred");
Craig Tillera82950e2015-09-22 12:33:20 -0700195 goto finish;
196 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800197
Mark D. Rothe65ff112016-09-09 13:48:38 -0700198 do {
199 so_error_size = sizeof(so_error);
200 err = getsockopt(grpc_fd_wrapped_fd(fd), SOL_SOCKET, SO_ERROR, &so_error,
201 &so_error_size);
202 } while (err < 0 && errno == EINTR);
203 if (err < 0) {
204 error = GRPC_OS_ERROR(errno, "getsockopt");
205 goto finish;
206 }
207
208 switch (so_error) {
209 case 0:
210 grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd);
Craig Tillerd88c4612016-09-29 10:35:38 -0700211 *ep = grpc_tcp_client_create_from_fd(exec_ctx, fd, ac->channel_args,
Craig Tiller9c7f4f72016-09-29 10:36:20 -0700212 ac->addr_str);
Mark D. Rothe65ff112016-09-09 13:48:38 -0700213 fd = NULL;
214 break;
215 case ENOBUFS:
216 /* We will get one of these errors if we have run out of
217 memory in the kernel for the data structures allocated
218 when you connect a socket. If this happens it is very
219 likely that if we wait a little bit then try again the
220 connection will work (since other programs or this
221 program will close their network connections and free up
222 memory). This does _not_ indicate that there is anything
223 wrong with the server we are connecting to, this is a
224 local problem.
225
226 If you are looking at this code, then chances are that
227 your program or another program on the same computer
228 opened too many network connections. The "easy" fix:
229 don't do that! */
230 gpr_log(GPR_ERROR, "kernel out of buffers");
231 gpr_mu_unlock(&ac->mu);
232 grpc_fd_notify_on_write(exec_ctx, fd, &ac->write_closure);
233 return;
234 case ECONNREFUSED:
235 /* This error shouldn't happen for anything other than connect(). */
236 error = GRPC_OS_ERROR(so_error, "connect");
237 break;
238 default:
239 /* We don't really know which syscall triggered the problem here,
240 so punt by reporting getsockopt(). */
241 error = GRPC_OS_ERROR(so_error, "getsockopt(SO_ERROR)");
242 break;
243 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800244
ctiller58393c22015-01-07 14:03:30 -0800245finish:
Craig Tillera82950e2015-09-22 12:33:20 -0700246 if (fd != NULL) {
247 grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd);
yang-g5d850372015-12-01 10:32:28 -0800248 grpc_fd_orphan(exec_ctx, fd, NULL, NULL, "tcp_client_orphan");
Craig Tillera82950e2015-09-22 12:33:20 -0700249 fd = NULL;
250 }
ctiller58393c22015-01-07 14:03:30 -0800251 done = (--ac->refs == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700252 gpr_mu_unlock(&ac->mu);
Craig Tiller27f59af2016-04-28 14:19:48 -0700253 if (error != GRPC_ERROR_NONE) {
David Garcia Quintas19badff2016-11-20 20:17:46 -0800254 char *error_descr;
255 gpr_asprintf(&error_descr, "Failed to connect to remote host: %s",
256 grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION));
257 error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION, error_descr);
258 gpr_free(error_descr);
Craig Tiller27f59af2016-04-28 14:19:48 -0700259 error =
260 grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, ac->addr_str);
261 }
Craig Tillera82950e2015-09-22 12:33:20 -0700262 if (done) {
263 gpr_mu_destroy(&ac->mu);
264 gpr_free(ac->addr_str);
Craig Tiller287928c2016-09-23 16:04:30 -0700265 grpc_channel_args_destroy(ac->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700266 gpr_free(ac);
267 }
Craig Tiller91031da2016-12-28 15:44:25 -0800268 grpc_closure_sched(exec_ctx, closure, error);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800269}
270
Craig Tillere6282612016-04-13 14:14:34 -0700271static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
272 grpc_closure *closure, grpc_endpoint **ep,
273 grpc_pollset_set *interested_parties,
Craig Tiller86958762016-09-23 12:05:34 -0700274 const grpc_channel_args *channel_args,
murgatroid997871f732016-09-23 13:49:05 -0700275 const grpc_resolved_address *addr,
276 gpr_timespec deadline) {
nnoble0c475f02014-12-05 15:37:39 -0800277 int fd;
278 grpc_dualstack_mode dsmode;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800279 int err;
280 async_connect *ac;
murgatroid997871f732016-09-23 13:49:05 -0700281 grpc_resolved_address addr6_v4mapped;
282 grpc_resolved_address addr4_copy;
Craig Tiller9bcc7512015-05-11 14:59:48 -0700283 grpc_fd *fdobj;
Craig Tillerfa275a92015-06-01 13:55:54 -0700284 char *name;
285 char *addr_str;
Craig Tiller27f59af2016-04-28 14:19:48 -0700286 grpc_error *error;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800287
Craig Tillerd1bec032015-09-18 17:29:00 -0700288 *ep = NULL;
289
nnoble0c475f02014-12-05 15:37:39 -0800290 /* Use dualstack sockets where available. */
Craig Tillera82950e2015-09-22 12:33:20 -0700291 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
murgatroid997871f732016-09-23 13:49:05 -0700292 addr = &addr6_v4mapped;
Craig Tillera82950e2015-09-22 12:33:20 -0700293 }
nnoble0c475f02014-12-05 15:37:39 -0800294
Craig Tiller27f59af2016-04-28 14:19:48 -0700295 error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
296 if (error != GRPC_ERROR_NONE) {
Craig Tiller91031da2016-12-28 15:44:25 -0800297 grpc_closure_sched(exec_ctx, closure, error);
Craig Tiller27f59af2016-04-28 14:19:48 -0700298 return;
Craig Tillera82950e2015-09-22 12:33:20 -0700299 }
300 if (dsmode == GRPC_DSMODE_IPV4) {
301 /* If we got an AF_INET socket, map the address back to IPv4. */
302 GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy));
murgatroid997871f732016-09-23 13:49:05 -0700303 addr = &addr4_copy;
Craig Tillera82950e2015-09-22 12:33:20 -0700304 }
Yuchen Zeng67ffe3f2016-11-11 10:50:42 -0800305 if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
Craig Tiller91031da2016-12-28 15:44:25 -0800306 grpc_closure_sched(exec_ctx, closure, error);
Craig Tillera82950e2015-09-22 12:33:20 -0700307 return;
308 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800309
Craig Tillera82950e2015-09-22 12:33:20 -0700310 do {
murgatroid997871f732016-09-23 13:49:05 -0700311 GPR_ASSERT(addr->len < ~(socklen_t)0);
murgatroid99dedb9232016-09-26 13:54:04 -0700312 err =
313 connect(fd, (const struct sockaddr *)addr->addr, (socklen_t)addr->len);
Craig Tillera82950e2015-09-22 12:33:20 -0700314 } while (err < 0 && errno == EINTR);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800315
Craig Tillera82950e2015-09-22 12:33:20 -0700316 addr_str = grpc_sockaddr_to_uri(addr);
317 gpr_asprintf(&name, "tcp-client:%s", addr_str);
Craig Tillerfa275a92015-06-01 13:55:54 -0700318
Craig Tillera82950e2015-09-22 12:33:20 -0700319 fdobj = grpc_fd_create(fd, name);
Craig Tiller9bcc7512015-05-11 14:59:48 -0700320
Craig Tillera82950e2015-09-22 12:33:20 -0700321 if (err >= 0) {
Craig Tiller86958762016-09-23 12:05:34 -0700322 *ep =
323 grpc_tcp_client_create_from_fd(exec_ctx, fdobj, channel_args, addr_str);
Craig Tiller91031da2016-12-28 15:44:25 -0800324 grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
Craig Tillera82950e2015-09-22 12:33:20 -0700325 goto done;
326 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800327
Craig Tillera82950e2015-09-22 12:33:20 -0700328 if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
yang-g5d850372015-12-01 10:32:28 -0800329 grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error");
Craig Tiller91031da2016-12-28 15:44:25 -0800330 grpc_closure_sched(exec_ctx, closure, GRPC_OS_ERROR(errno, "connect"));
Craig Tillera82950e2015-09-22 12:33:20 -0700331 goto done;
332 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800333
Craig Tillera82950e2015-09-22 12:33:20 -0700334 grpc_pollset_set_add_fd(exec_ctx, interested_parties, fdobj);
Craig Tiller4b678bd2015-06-02 16:12:24 -0700335
Craig Tillera82950e2015-09-22 12:33:20 -0700336 ac = gpr_malloc(sizeof(async_connect));
Craig Tillerd1bec032015-09-18 17:29:00 -0700337 ac->closure = closure;
338 ac->ep = ep;
Craig Tiller9bcc7512015-05-11 14:59:48 -0700339 ac->fd = fdobj;
Craig Tillerb49736822015-06-30 08:15:08 -0700340 ac->interested_parties = interested_parties;
Craig Tiller1b22b9d2015-07-20 13:42:22 -0700341 ac->addr_str = addr_str;
342 addr_str = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700343 gpr_mu_init(&ac->mu);
ctiller58393c22015-01-07 14:03:30 -0800344 ac->refs = 2;
Craig Tillerd6887e02016-12-29 10:11:40 -0800345 grpc_closure_init(&ac->write_closure, on_writable, ac,
346 grpc_schedule_on_exec_ctx);
Craig Tiller86958762016-09-23 12:05:34 -0700347 ac->channel_args = grpc_channel_args_copy(channel_args);
ctiller58393c22015-01-07 14:03:30 -0800348
Craig Tillera82950e2015-09-22 12:33:20 -0700349 if (grpc_tcp_trace) {
350 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting",
351 ac->addr_str);
352 }
Craig Tiller5e53ddb2015-09-16 10:53:15 -0700353
Craig Tillera82950e2015-09-22 12:33:20 -0700354 gpr_mu_lock(&ac->mu);
David Garcia Quintasf747bbc2015-10-04 23:09:47 -0700355 grpc_timer_init(exec_ctx, &ac->alarm,
Craig Tillera82950e2015-09-22 12:33:20 -0700356 gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
357 tc_on_alarm, ac, gpr_now(GPR_CLOCK_MONOTONIC));
358 grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure);
359 gpr_mu_unlock(&ac->mu);
Craig Tillerfa275a92015-06-01 13:55:54 -0700360
361done:
Craig Tillera82950e2015-09-22 12:33:20 -0700362 gpr_free(name);
363 gpr_free(addr_str);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800364}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800365
Craig Tillere6282612016-04-13 14:14:34 -0700366// overridden by api_fuzzer.c
367void (*grpc_tcp_client_connect_impl)(
368 grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_endpoint **ep,
Craig Tiller86958762016-09-23 12:05:34 -0700369 grpc_pollset_set *interested_parties, const grpc_channel_args *channel_args,
Craig Tiller3d357d92016-10-26 20:52:03 -0700370 const grpc_resolved_address *addr,
Craig Tillere34c2852016-09-23 09:43:32 -0700371 gpr_timespec deadline) = tcp_client_connect_impl;
Craig Tillere6282612016-04-13 14:14:34 -0700372
373void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
374 grpc_endpoint **ep,
375 grpc_pollset_set *interested_parties,
Craig Tiller86958762016-09-23 12:05:34 -0700376 const grpc_channel_args *channel_args,
murgatroid997871f732016-09-23 13:49:05 -0700377 const grpc_resolved_address *addr,
Craig Tillere6282612016-04-13 14:14:34 -0700378 gpr_timespec deadline) {
Craig Tillere34c2852016-09-23 09:43:32 -0700379 grpc_tcp_client_connect_impl(exec_ctx, closure, ep, interested_parties,
Craig Tiller3d357d92016-10-26 20:52:03 -0700380 channel_args, addr, deadline);
Craig Tillere6282612016-04-13 14:14:34 -0700381}
382
Craig Tiller190d3602015-02-18 09:23:38 -0800383#endif