blob: a98d9a6217416cfd4b45b0ad98ba58d3e05c327e [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;
Masood Malekghassemib5b43722017-01-05 15:07:26 -080068 grpc_closure on_alarm;
ctiller58393c22015-01-07 14:03:30 -080069 int refs;
Craig Tiller33825112015-09-18 07:44:19 -070070 grpc_closure write_closure;
Craig Tillerb49736822015-06-30 08:15:08 -070071 grpc_pollset_set *interested_parties;
Craig Tiller1b22b9d2015-07-20 13:42:22 -070072 char *addr_str;
Craig Tillerd1bec032015-09-18 17:29:00 -070073 grpc_endpoint **ep;
74 grpc_closure *closure;
Craig Tiller86958762016-09-23 12:05:34 -070075 grpc_channel_args *channel_args;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080076} async_connect;
77
Yuchen Zeng64d518e2016-11-02 16:27:49 -070078static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd,
Yuchen Zeng929f4c62016-10-10 16:02:43 -070079 const grpc_channel_args *channel_args) {
Craig Tiller27f59af2016-04-28 14:19:48 -070080 grpc_error *err = GRPC_ERROR_NONE;
81
Craig Tiller80384bd2016-05-06 16:12:31 -070082 GPR_ASSERT(fd >= 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080083
Craig Tiller4f1d0f32016-05-06 17:12:37 -070084 err = grpc_set_socket_nonblocking(fd, 1);
85 if (err != GRPC_ERROR_NONE) goto error;
86 err = grpc_set_socket_cloexec(fd, 1);
87 if (err != GRPC_ERROR_NONE) goto error;
88 if (!grpc_is_unix_socket(addr)) {
89 err = grpc_set_socket_low_latency(fd, 1);
90 if (err != GRPC_ERROR_NONE) goto error;
Craig Tillera82950e2015-09-22 12:33:20 -070091 }
Craig Tiller4f1d0f32016-05-06 17:12:37 -070092 err = grpc_set_socket_no_sigpipe_if_possible(fd);
93 if (err != GRPC_ERROR_NONE) goto error;
Yuchen Zeng929f4c62016-10-10 16:02:43 -070094 if (channel_args) {
95 for (size_t i = 0; i < channel_args->num_args; i++) {
Yuchen Zenga4f708a2016-10-11 18:36:24 -070096 if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
97 GPR_ASSERT(channel_args->args[i].type == GRPC_ARG_POINTER);
98 grpc_socket_mutator *mutator = channel_args->args[i].value.pointer.p;
99 err = grpc_set_socket_with_mutator(fd, mutator);
Yuchen Zeng929f4c62016-10-10 16:02:43 -0700100 if (err != GRPC_ERROR_NONE) goto error;
Yuchen Zeng929f4c62016-10-10 16:02:43 -0700101 }
102 }
103 }
Craig Tiller27f59af2016-04-28 14:19:48 -0700104 goto done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800105
106error:
Craig Tillera82950e2015-09-22 12:33:20 -0700107 if (fd >= 0) {
108 close(fd);
109 }
Craig Tiller27f59af2016-04-28 14:19:48 -0700110done:
111 return err;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800112}
113
Craig Tillerc027e772016-05-03 16:27:00 -0700114static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
ctiller58393c22015-01-07 14:03:30 -0800115 int done;
116 async_connect *ac = acp;
Craig Tillera82950e2015-09-22 12:33:20 -0700117 if (grpc_tcp_trace) {
Craig Tillerc027e772016-05-03 16:27:00 -0700118 const char *str = grpc_error_string(error);
119 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
120 str);
Craig Tillera82950e2015-09-22 12:33:20 -0700121 }
122 gpr_mu_lock(&ac->mu);
123 if (ac->fd != NULL) {
Craig Tillercda759d2017-01-27 11:37:37 -0800124 grpc_fd_shutdown(exec_ctx, ac->fd,
125 GRPC_ERROR_CREATE("connect() timed out"));
Craig Tillera82950e2015-09-22 12:33:20 -0700126 }
ctiller58393c22015-01-07 14:03:30 -0800127 done = (--ac->refs == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700128 gpr_mu_unlock(&ac->mu);
129 if (done) {
130 gpr_mu_destroy(&ac->mu);
131 gpr_free(ac->addr_str);
Craig Tillera59c16c2016-10-31 07:25:01 -0700132 grpc_channel_args_destroy(exec_ctx, ac->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700133 gpr_free(ac);
134 }
ctiller58393c22015-01-07 14:03:30 -0800135}
136
Craig Tiller86958762016-09-23 12:05:34 -0700137grpc_endpoint *grpc_tcp_client_create_from_fd(
138 grpc_exec_ctx *exec_ctx, grpc_fd *fd, const grpc_channel_args *channel_args,
139 const char *addr_str) {
140 size_t tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
Craig Tiller20afa3d2016-10-17 14:52:14 -0700141 grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
Craig Tiller86958762016-09-23 12:05:34 -0700142 if (channel_args != NULL) {
143 for (size_t i = 0; i < channel_args->num_args; i++) {
144 if (0 ==
145 strcmp(channel_args->args[i].key, GRPC_ARG_TCP_READ_CHUNK_SIZE)) {
146 grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
147 8 * 1024 * 1024};
148 tcp_read_chunk_size = (size_t)grpc_channel_arg_get_integer(
149 &channel_args->args[i], options);
Craig Tiller153eaa72016-10-21 13:52:36 -0700150 } else if (0 ==
151 strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
Craig Tillera59c16c2016-10-31 07:25:01 -0700152 grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
153 resource_quota = grpc_resource_quota_ref_internal(
Craig Tiller86958762016-09-23 12:05:34 -0700154 channel_args->args[i].value.pointer.p);
155 }
156 }
157 }
158
159 grpc_endpoint *ep =
Craig Tiller20afa3d2016-10-17 14:52:14 -0700160 grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
Craig Tillera59c16c2016-10-31 07:25:01 -0700161 grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
Craig Tiller86958762016-09-23 12:05:34 -0700162 return ep;
163}
164
Craig Tillerc027e772016-05-03 16:27:00 -0700165static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800166 async_connect *ac = acp;
167 int so_error = 0;
168 socklen_t so_error_size;
169 int err;
ctiller58393c22015-01-07 14:03:30 -0800170 int done;
Craig Tillerd1bec032015-09-18 17:29:00 -0700171 grpc_endpoint **ep = ac->ep;
172 grpc_closure *closure = ac->closure;
Craig Tiller5553eb32015-07-21 12:28:56 -0700173 grpc_fd *fd;
174
Craig Tiller82c63eb2016-05-10 15:28:01 -0700175 GRPC_ERROR_REF(error);
176
Craig Tillera82950e2015-09-22 12:33:20 -0700177 if (grpc_tcp_trace) {
Craig Tillerc027e772016-05-03 16:27:00 -0700178 const char *str = grpc_error_string(error);
179 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s",
180 ac->addr_str, 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 =
ncteisenbbb38012017-03-10 14:58:43 -0800194 grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string("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;
ncteisenbbb38012017-03-10 14:58:43 -0800255 grpc_slice str;
256 bool ret = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str);
257 GPR_ASSERT(ret);
258 char* desc = grpc_slice_to_c_string(str);
259 gpr_asprintf(&error_descr, "Failed to connect to remote host: %s", desc);
260 error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION, grpc_slice_from_copied_string(error_descr));
David Garcia Quintas19badff2016-11-20 20:17:46 -0800261 gpr_free(error_descr);
ncteisenbbb38012017-03-10 14:58:43 -0800262 gpr_free(desc);
Craig Tiller27f59af2016-04-28 14:19:48 -0700263 error =
ncteisenbbb38012017-03-10 14:58:43 -0800264 grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(ac->addr_str));
Craig Tiller27f59af2016-04-28 14:19:48 -0700265 }
Craig Tillera82950e2015-09-22 12:33:20 -0700266 if (done) {
267 gpr_mu_destroy(&ac->mu);
268 gpr_free(ac->addr_str);
Craig Tillera59c16c2016-10-31 07:25:01 -0700269 grpc_channel_args_destroy(exec_ctx, ac->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700270 gpr_free(ac);
271 }
Craig Tiller91031da2016-12-28 15:44:25 -0800272 grpc_closure_sched(exec_ctx, closure, error);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800273}
274
Craig Tillere6282612016-04-13 14:14:34 -0700275static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
276 grpc_closure *closure, grpc_endpoint **ep,
277 grpc_pollset_set *interested_parties,
Craig Tiller86958762016-09-23 12:05:34 -0700278 const grpc_channel_args *channel_args,
murgatroid997871f732016-09-23 13:49:05 -0700279 const grpc_resolved_address *addr,
280 gpr_timespec deadline) {
nnoble0c475f02014-12-05 15:37:39 -0800281 int fd;
282 grpc_dualstack_mode dsmode;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800283 int err;
284 async_connect *ac;
murgatroid997871f732016-09-23 13:49:05 -0700285 grpc_resolved_address addr6_v4mapped;
286 grpc_resolved_address addr4_copy;
Craig Tiller9bcc7512015-05-11 14:59:48 -0700287 grpc_fd *fdobj;
Craig Tillerfa275a92015-06-01 13:55:54 -0700288 char *name;
289 char *addr_str;
Craig Tiller27f59af2016-04-28 14:19:48 -0700290 grpc_error *error;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800291
Craig Tillerd1bec032015-09-18 17:29:00 -0700292 *ep = NULL;
293
nnoble0c475f02014-12-05 15:37:39 -0800294 /* Use dualstack sockets where available. */
Craig Tillera82950e2015-09-22 12:33:20 -0700295 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
murgatroid997871f732016-09-23 13:49:05 -0700296 addr = &addr6_v4mapped;
Craig Tillera82950e2015-09-22 12:33:20 -0700297 }
nnoble0c475f02014-12-05 15:37:39 -0800298
Craig Tiller27f59af2016-04-28 14:19:48 -0700299 error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
300 if (error != GRPC_ERROR_NONE) {
Craig Tiller91031da2016-12-28 15:44:25 -0800301 grpc_closure_sched(exec_ctx, closure, error);
Craig Tiller27f59af2016-04-28 14:19:48 -0700302 return;
Craig Tillera82950e2015-09-22 12:33:20 -0700303 }
304 if (dsmode == GRPC_DSMODE_IPV4) {
305 /* If we got an AF_INET socket, map the address back to IPv4. */
306 GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy));
murgatroid997871f732016-09-23 13:49:05 -0700307 addr = &addr4_copy;
Craig Tillera82950e2015-09-22 12:33:20 -0700308 }
Yuchen Zeng67ffe3f2016-11-11 10:50:42 -0800309 if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
Craig Tiller91031da2016-12-28 15:44:25 -0800310 grpc_closure_sched(exec_ctx, closure, error);
Craig Tillera82950e2015-09-22 12:33:20 -0700311 return;
312 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800313
Craig Tillera82950e2015-09-22 12:33:20 -0700314 do {
murgatroid997871f732016-09-23 13:49:05 -0700315 GPR_ASSERT(addr->len < ~(socklen_t)0);
murgatroid99dedb9232016-09-26 13:54:04 -0700316 err =
317 connect(fd, (const struct sockaddr *)addr->addr, (socklen_t)addr->len);
Craig Tillera82950e2015-09-22 12:33:20 -0700318 } while (err < 0 && errno == EINTR);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800319
Craig Tillera82950e2015-09-22 12:33:20 -0700320 addr_str = grpc_sockaddr_to_uri(addr);
321 gpr_asprintf(&name, "tcp-client:%s", addr_str);
Craig Tillerfa275a92015-06-01 13:55:54 -0700322
Craig Tillera82950e2015-09-22 12:33:20 -0700323 fdobj = grpc_fd_create(fd, name);
Craig Tiller9bcc7512015-05-11 14:59:48 -0700324
Craig Tillera82950e2015-09-22 12:33:20 -0700325 if (err >= 0) {
Craig Tiller86958762016-09-23 12:05:34 -0700326 *ep =
327 grpc_tcp_client_create_from_fd(exec_ctx, fdobj, channel_args, addr_str);
Craig Tiller91031da2016-12-28 15:44:25 -0800328 grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
Craig Tillera82950e2015-09-22 12:33:20 -0700329 goto done;
330 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800331
Craig Tillera82950e2015-09-22 12:33:20 -0700332 if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
yang-g5d850372015-12-01 10:32:28 -0800333 grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error");
Craig Tiller91031da2016-12-28 15:44:25 -0800334 grpc_closure_sched(exec_ctx, closure, GRPC_OS_ERROR(errno, "connect"));
Craig Tillera82950e2015-09-22 12:33:20 -0700335 goto done;
336 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800337
Craig Tillera82950e2015-09-22 12:33:20 -0700338 grpc_pollset_set_add_fd(exec_ctx, interested_parties, fdobj);
Craig Tiller4b678bd2015-06-02 16:12:24 -0700339
Craig Tillera82950e2015-09-22 12:33:20 -0700340 ac = gpr_malloc(sizeof(async_connect));
Craig Tillerd1bec032015-09-18 17:29:00 -0700341 ac->closure = closure;
342 ac->ep = ep;
Craig Tiller9bcc7512015-05-11 14:59:48 -0700343 ac->fd = fdobj;
Craig Tillerb49736822015-06-30 08:15:08 -0700344 ac->interested_parties = interested_parties;
Craig Tiller1b22b9d2015-07-20 13:42:22 -0700345 ac->addr_str = addr_str;
346 addr_str = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700347 gpr_mu_init(&ac->mu);
ctiller58393c22015-01-07 14:03:30 -0800348 ac->refs = 2;
Craig Tillerd6887e02016-12-29 10:11:40 -0800349 grpc_closure_init(&ac->write_closure, on_writable, ac,
350 grpc_schedule_on_exec_ctx);
Craig Tiller86958762016-09-23 12:05:34 -0700351 ac->channel_args = grpc_channel_args_copy(channel_args);
ctiller58393c22015-01-07 14:03:30 -0800352
Craig Tillera82950e2015-09-22 12:33:20 -0700353 if (grpc_tcp_trace) {
354 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting",
355 ac->addr_str);
356 }
Craig Tiller5e53ddb2015-09-16 10:53:15 -0700357
Craig Tillera82950e2015-09-22 12:33:20 -0700358 gpr_mu_lock(&ac->mu);
Masood Malekghassemib5b43722017-01-05 15:07:26 -0800359 grpc_closure_init(&ac->on_alarm, tc_on_alarm, ac, grpc_schedule_on_exec_ctx);
David Garcia Quintasf747bbc2015-10-04 23:09:47 -0700360 grpc_timer_init(exec_ctx, &ac->alarm,
Craig Tillera82950e2015-09-22 12:33:20 -0700361 gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
Masood Malekghassemib5b43722017-01-05 15:07:26 -0800362 &ac->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
Craig Tillera82950e2015-09-22 12:33:20 -0700363 grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure);
364 gpr_mu_unlock(&ac->mu);
Craig Tillerfa275a92015-06-01 13:55:54 -0700365
366done:
Craig Tillera82950e2015-09-22 12:33:20 -0700367 gpr_free(name);
368 gpr_free(addr_str);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800369}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800370
Craig Tillere6282612016-04-13 14:14:34 -0700371// overridden by api_fuzzer.c
372void (*grpc_tcp_client_connect_impl)(
373 grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_endpoint **ep,
Craig Tiller86958762016-09-23 12:05:34 -0700374 grpc_pollset_set *interested_parties, const grpc_channel_args *channel_args,
Craig Tiller3d357d92016-10-26 20:52:03 -0700375 const grpc_resolved_address *addr,
Craig Tillere34c2852016-09-23 09:43:32 -0700376 gpr_timespec deadline) = tcp_client_connect_impl;
Craig Tillere6282612016-04-13 14:14:34 -0700377
378void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
379 grpc_endpoint **ep,
380 grpc_pollset_set *interested_parties,
Craig Tiller86958762016-09-23 12:05:34 -0700381 const grpc_channel_args *channel_args,
murgatroid997871f732016-09-23 13:49:05 -0700382 const grpc_resolved_address *addr,
Craig Tillere6282612016-04-13 14:14:34 -0700383 gpr_timespec deadline) {
Craig Tillere34c2852016-09-23 09:43:32 -0700384 grpc_tcp_client_connect_impl(exec_ctx, closure, ep, interested_parties,
Craig Tiller3d357d92016-10-26 20:52:03 -0700385 channel_args, addr, deadline);
Craig Tillere6282612016-04-13 14:14:34 -0700386}
387
Craig Tiller190d3602015-02-18 09:23:38 -0800388#endif