blob: 85a4c2949721d642458cd958f0e94cc28881701a [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080016 *
17 */
18
murgatroid9954070892016-08-08 17:01:18 -070019#include "src/core/lib/iomgr/port.h"
Craig Tiller0c0b60c2015-01-21 15:49:28 -080020
murgatroid99623dd4f2016-08-08 17:31:27 -070021#ifdef GRPC_POSIX_SOCKET
Craig Tiller0c0b60c2015-01-21 15:49:28 -080022
Craig Tiller86958762016-09-23 12:05:34 -070023#include "src/core/lib/iomgr/tcp_client_posix.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080024
25#include <errno.h>
nnoble0c475f02014-12-05 15:37:39 -080026#include <netinet/in.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080027#include <string.h>
28#include <unistd.h>
29
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080030#include <grpc/support/alloc.h>
31#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070032#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080033#include <grpc/support/time.h>
34
Craig Tiller86958762016-09-23 12:05:34 -070035#include "src/core/lib/channel/channel_args.h"
Craig Tiller8a034482016-03-28 16:09:04 -070036#include "src/core/lib/iomgr/ev_posix.h"
Craig Tiller9533d042016-03-25 17:11:06 -070037#include "src/core/lib/iomgr/iomgr_posix.h"
Craig Tiller9533d042016-03-25 17:11:06 -070038#include "src/core/lib/iomgr/sockaddr_utils.h"
Yuchen Zengde3daf52016-10-13 17:26:26 -070039#include "src/core/lib/iomgr/socket_mutator.h"
Craig Tiller9533d042016-03-25 17:11:06 -070040#include "src/core/lib/iomgr/socket_utils_posix.h"
41#include "src/core/lib/iomgr/tcp_posix.h"
42#include "src/core/lib/iomgr/timer.h"
43#include "src/core/lib/iomgr/unix_sockets_posix.h"
44#include "src/core/lib/support/string.h"
Craig Tillerc46beaa2016-02-24 09:17:19 -080045
Craig Tiller84f75d42017-05-03 13:06:35 -070046extern grpc_tracer_flag grpc_tcp_trace;
Craig Tiller5e53ddb2015-09-16 10:53:15 -070047
Craig Tillera82950e2015-09-22 12:33:20 -070048typedef struct {
ctiller58393c22015-01-07 14:03:30 -080049 gpr_mu mu;
Craig Tillerbaa14a92017-11-03 09:09:36 -070050 grpc_fd* fd;
David Garcia Quintasf747bbc2015-10-04 23:09:47 -070051 grpc_timer alarm;
Masood Malekghassemib5b43722017-01-05 15:07:26 -080052 grpc_closure on_alarm;
ctiller58393c22015-01-07 14:03:30 -080053 int refs;
Craig Tiller33825112015-09-18 07:44:19 -070054 grpc_closure write_closure;
Craig Tillerbaa14a92017-11-03 09:09:36 -070055 grpc_pollset_set* interested_parties;
56 char* addr_str;
57 grpc_endpoint** ep;
58 grpc_closure* closure;
59 grpc_channel_args* channel_args;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080060} async_connect;
61
Craig Tillerbaa14a92017-11-03 09:09:36 -070062static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd,
63 const grpc_channel_args* channel_args) {
64 grpc_error* err = GRPC_ERROR_NONE;
Craig Tiller27f59af2016-04-28 14:19:48 -070065
Craig Tiller80384bd2016-05-06 16:12:31 -070066 GPR_ASSERT(fd >= 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080067
Craig Tiller4f1d0f32016-05-06 17:12:37 -070068 err = grpc_set_socket_nonblocking(fd, 1);
69 if (err != GRPC_ERROR_NONE) goto error;
70 err = grpc_set_socket_cloexec(fd, 1);
71 if (err != GRPC_ERROR_NONE) goto error;
72 if (!grpc_is_unix_socket(addr)) {
73 err = grpc_set_socket_low_latency(fd, 1);
74 if (err != GRPC_ERROR_NONE) goto error;
Craig Tillera82950e2015-09-22 12:33:20 -070075 }
Craig Tiller4f1d0f32016-05-06 17:12:37 -070076 err = grpc_set_socket_no_sigpipe_if_possible(fd);
77 if (err != GRPC_ERROR_NONE) goto error;
Yuchen Zeng929f4c62016-10-10 16:02:43 -070078 if (channel_args) {
79 for (size_t i = 0; i < channel_args->num_args; i++) {
Yuchen Zenga4f708a2016-10-11 18:36:24 -070080 if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
81 GPR_ASSERT(channel_args->args[i].type == GRPC_ARG_POINTER);
Craig Tillerbaa14a92017-11-03 09:09:36 -070082 grpc_socket_mutator* mutator =
83 (grpc_socket_mutator*)channel_args->args[i].value.pointer.p;
Yuchen Zenga4f708a2016-10-11 18:36:24 -070084 err = grpc_set_socket_with_mutator(fd, mutator);
Yuchen Zeng929f4c62016-10-10 16:02:43 -070085 if (err != GRPC_ERROR_NONE) goto error;
Yuchen Zeng929f4c62016-10-10 16:02:43 -070086 }
87 }
88 }
Craig Tiller27f59af2016-04-28 14:19:48 -070089 goto done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080090
91error:
Craig Tillera82950e2015-09-22 12:33:20 -070092 if (fd >= 0) {
93 close(fd);
94 }
Craig Tiller27f59af2016-04-28 14:19:48 -070095done:
96 return err;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080097}
98
Craig Tillerbaa14a92017-11-03 09:09:36 -070099static void tc_on_alarm(grpc_exec_ctx* exec_ctx, void* acp, grpc_error* error) {
ctiller58393c22015-01-07 14:03:30 -0800100 int done;
Craig Tillerbaa14a92017-11-03 09:09:36 -0700101 async_connect* ac = (async_connect*)acp;
Craig Tiller84f75d42017-05-03 13:06:35 -0700102 if (GRPC_TRACER_ON(grpc_tcp_trace)) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700103 const char* str = grpc_error_string(error);
Craig Tillerc027e772016-05-03 16:27:00 -0700104 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
105 str);
Craig Tillera82950e2015-09-22 12:33:20 -0700106 }
107 gpr_mu_lock(&ac->mu);
Craig Tiller4782d922017-11-10 09:53:21 -0800108 if (ac->fd != nullptr) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700109 grpc_fd_shutdown(
110 exec_ctx, ac->fd,
111 GRPC_ERROR_CREATE_FROM_STATIC_STRING("connect() timed out"));
Craig Tillera82950e2015-09-22 12:33:20 -0700112 }
ctiller58393c22015-01-07 14:03:30 -0800113 done = (--ac->refs == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700114 gpr_mu_unlock(&ac->mu);
115 if (done) {
116 gpr_mu_destroy(&ac->mu);
117 gpr_free(ac->addr_str);
Craig Tillera59c16c2016-10-31 07:25:01 -0700118 grpc_channel_args_destroy(exec_ctx, ac->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700119 gpr_free(ac);
120 }
ctiller58393c22015-01-07 14:03:30 -0800121}
122
Craig Tillerbaa14a92017-11-03 09:09:36 -0700123grpc_endpoint* grpc_tcp_client_create_from_fd(
124 grpc_exec_ctx* exec_ctx, grpc_fd* fd, const grpc_channel_args* channel_args,
125 const char* addr_str) {
Craig Tiller547cb4b2017-03-28 09:50:33 -0700126 return grpc_tcp_create(exec_ctx, fd, channel_args, addr_str);
Craig Tiller86958762016-09-23 12:05:34 -0700127}
128
Craig Tillerbaa14a92017-11-03 09:09:36 -0700129static void on_writable(grpc_exec_ctx* exec_ctx, void* acp, grpc_error* error) {
130 async_connect* ac = (async_connect*)acp;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800131 int so_error = 0;
132 socklen_t so_error_size;
133 int err;
ctiller58393c22015-01-07 14:03:30 -0800134 int done;
Craig Tillerbaa14a92017-11-03 09:09:36 -0700135 grpc_endpoint** ep = ac->ep;
136 grpc_closure* closure = ac->closure;
137 grpc_fd* fd;
Craig Tiller5553eb32015-07-21 12:28:56 -0700138
Craig Tiller82c63eb2016-05-10 15:28:01 -0700139 GRPC_ERROR_REF(error);
140
Craig Tiller84f75d42017-05-03 13:06:35 -0700141 if (GRPC_TRACER_ON(grpc_tcp_trace)) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700142 const char* str = grpc_error_string(error);
Craig Tillerc027e772016-05-03 16:27:00 -0700143 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s",
144 ac->addr_str, str);
Craig Tillera82950e2015-09-22 12:33:20 -0700145 }
Craig Tiller5e53ddb2015-09-16 10:53:15 -0700146
Craig Tillera82950e2015-09-22 12:33:20 -0700147 gpr_mu_lock(&ac->mu);
148 GPR_ASSERT(ac->fd);
Craig Tiller5553eb32015-07-21 12:28:56 -0700149 fd = ac->fd;
Craig Tiller4782d922017-11-10 09:53:21 -0800150 ac->fd = nullptr;
Craig Tillera82950e2015-09-22 12:33:20 -0700151 gpr_mu_unlock(&ac->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800152
David Garcia Quintasf747bbc2015-10-04 23:09:47 -0700153 grpc_timer_cancel(exec_ctx, &ac->alarm);
Craig Tiller26205362015-07-21 08:21:57 -0700154
Craig Tillera82950e2015-09-22 12:33:20 -0700155 gpr_mu_lock(&ac->mu);
Mark D. Rothe65ff112016-09-09 13:48:38 -0700156 if (error != GRPC_ERROR_NONE) {
Craig Tiller27f59af2016-04-28 14:19:48 -0700157 error =
ncteisen4b36a3d2017-03-13 19:08:06 -0700158 grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
159 grpc_slice_from_static_string("Timeout occurred"));
Craig Tillera82950e2015-09-22 12:33:20 -0700160 goto finish;
161 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800162
Mark D. Rothe65ff112016-09-09 13:48:38 -0700163 do {
164 so_error_size = sizeof(so_error);
165 err = getsockopt(grpc_fd_wrapped_fd(fd), SOL_SOCKET, SO_ERROR, &so_error,
166 &so_error_size);
167 } while (err < 0 && errno == EINTR);
168 if (err < 0) {
169 error = GRPC_OS_ERROR(errno, "getsockopt");
170 goto finish;
171 }
172
173 switch (so_error) {
174 case 0:
175 grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd);
Craig Tillerd88c4612016-09-29 10:35:38 -0700176 *ep = grpc_tcp_client_create_from_fd(exec_ctx, fd, ac->channel_args,
Craig Tiller9c7f4f72016-09-29 10:36:20 -0700177 ac->addr_str);
Craig Tiller4782d922017-11-10 09:53:21 -0800178 fd = nullptr;
Mark D. Rothe65ff112016-09-09 13:48:38 -0700179 break;
180 case ENOBUFS:
181 /* We will get one of these errors if we have run out of
182 memory in the kernel for the data structures allocated
183 when you connect a socket. If this happens it is very
184 likely that if we wait a little bit then try again the
185 connection will work (since other programs or this
186 program will close their network connections and free up
187 memory). This does _not_ indicate that there is anything
188 wrong with the server we are connecting to, this is a
189 local problem.
190
191 If you are looking at this code, then chances are that
192 your program or another program on the same computer
193 opened too many network connections. The "easy" fix:
194 don't do that! */
195 gpr_log(GPR_ERROR, "kernel out of buffers");
196 gpr_mu_unlock(&ac->mu);
197 grpc_fd_notify_on_write(exec_ctx, fd, &ac->write_closure);
198 return;
199 case ECONNREFUSED:
200 /* This error shouldn't happen for anything other than connect(). */
201 error = GRPC_OS_ERROR(so_error, "connect");
202 break;
203 default:
204 /* We don't really know which syscall triggered the problem here,
205 so punt by reporting getsockopt(). */
206 error = GRPC_OS_ERROR(so_error, "getsockopt(SO_ERROR)");
207 break;
208 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800209
ctiller58393c22015-01-07 14:03:30 -0800210finish:
Craig Tiller4782d922017-11-10 09:53:21 -0800211 if (fd != nullptr) {
Craig Tillera82950e2015-09-22 12:33:20 -0700212 grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd);
Craig Tiller4782d922017-11-10 09:53:21 -0800213 grpc_fd_orphan(exec_ctx, fd, nullptr, nullptr, false /* already_closed */,
Yuchen Zengd40a7ae2017-07-12 15:59:56 -0700214 "tcp_client_orphan");
Craig Tiller4782d922017-11-10 09:53:21 -0800215 fd = nullptr;
Craig Tillera82950e2015-09-22 12:33:20 -0700216 }
ctiller58393c22015-01-07 14:03:30 -0800217 done = (--ac->refs == 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700218 gpr_mu_unlock(&ac->mu);
Craig Tiller27f59af2016-04-28 14:19:48 -0700219 if (error != GRPC_ERROR_NONE) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700220 char* error_descr;
ncteisenbbb38012017-03-10 14:58:43 -0800221 grpc_slice str;
222 bool ret = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &str);
223 GPR_ASSERT(ret);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700224 char* desc = grpc_slice_to_c_string(str);
ncteisenbbb38012017-03-10 14:58:43 -0800225 gpr_asprintf(&error_descr, "Failed to connect to remote host: %s", desc);
ncteisen4b36a3d2017-03-13 19:08:06 -0700226 error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION,
227 grpc_slice_from_copied_string(error_descr));
David Garcia Quintas19badff2016-11-20 20:17:46 -0800228 gpr_free(error_descr);
ncteisenbbb38012017-03-10 14:58:43 -0800229 gpr_free(desc);
ncteisen4b36a3d2017-03-13 19:08:06 -0700230 error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
231 grpc_slice_from_copied_string(ac->addr_str));
Craig Tiller27f59af2016-04-28 14:19:48 -0700232 }
Craig Tillera82950e2015-09-22 12:33:20 -0700233 if (done) {
234 gpr_mu_destroy(&ac->mu);
235 gpr_free(ac->addr_str);
Craig Tillera59c16c2016-10-31 07:25:01 -0700236 grpc_channel_args_destroy(exec_ctx, ac->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700237 gpr_free(ac);
238 }
ncteisen274bbbe2017-06-08 14:57:11 -0700239 GRPC_CLOSURE_SCHED(exec_ctx, closure, error);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800240}
241
Craig Tillerbaa14a92017-11-03 09:09:36 -0700242static void tcp_client_connect_impl(grpc_exec_ctx* exec_ctx,
243 grpc_closure* closure, grpc_endpoint** ep,
244 grpc_pollset_set* interested_parties,
245 const grpc_channel_args* channel_args,
246 const grpc_resolved_address* addr,
Craig Tillerdc3998e2017-05-12 09:55:30 -0700247 grpc_millis deadline) {
nnoble0c475f02014-12-05 15:37:39 -0800248 int fd;
249 grpc_dualstack_mode dsmode;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800250 int err;
Craig Tillerbaa14a92017-11-03 09:09:36 -0700251 async_connect* ac;
murgatroid997871f732016-09-23 13:49:05 -0700252 grpc_resolved_address addr6_v4mapped;
253 grpc_resolved_address addr4_copy;
Craig Tillerbaa14a92017-11-03 09:09:36 -0700254 grpc_fd* fdobj;
255 char* name;
256 char* addr_str;
257 grpc_error* error;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800258
Craig Tiller4782d922017-11-10 09:53:21 -0800259 *ep = nullptr;
Craig Tillerd1bec032015-09-18 17:29:00 -0700260
nnoble0c475f02014-12-05 15:37:39 -0800261 /* Use dualstack sockets where available. */
Craig Tillera82950e2015-09-22 12:33:20 -0700262 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
murgatroid997871f732016-09-23 13:49:05 -0700263 addr = &addr6_v4mapped;
Craig Tillera82950e2015-09-22 12:33:20 -0700264 }
nnoble0c475f02014-12-05 15:37:39 -0800265
Craig Tiller27f59af2016-04-28 14:19:48 -0700266 error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
267 if (error != GRPC_ERROR_NONE) {
ncteisen274bbbe2017-06-08 14:57:11 -0700268 GRPC_CLOSURE_SCHED(exec_ctx, closure, error);
Craig Tiller27f59af2016-04-28 14:19:48 -0700269 return;
Craig Tillera82950e2015-09-22 12:33:20 -0700270 }
271 if (dsmode == GRPC_DSMODE_IPV4) {
272 /* If we got an AF_INET socket, map the address back to IPv4. */
273 GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy));
murgatroid997871f732016-09-23 13:49:05 -0700274 addr = &addr4_copy;
Craig Tillera82950e2015-09-22 12:33:20 -0700275 }
Yuchen Zeng67ffe3f2016-11-11 10:50:42 -0800276 if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
ncteisen274bbbe2017-06-08 14:57:11 -0700277 GRPC_CLOSURE_SCHED(exec_ctx, closure, error);
Craig Tillera82950e2015-09-22 12:33:20 -0700278 return;
279 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800280
Craig Tillera82950e2015-09-22 12:33:20 -0700281 do {
murgatroid997871f732016-09-23 13:49:05 -0700282 GPR_ASSERT(addr->len < ~(socklen_t)0);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700283 err = connect(fd, (const struct sockaddr*)addr->addr, (socklen_t)addr->len);
Craig Tillera82950e2015-09-22 12:33:20 -0700284 } while (err < 0 && errno == EINTR);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800285
Craig Tillera82950e2015-09-22 12:33:20 -0700286 addr_str = grpc_sockaddr_to_uri(addr);
287 gpr_asprintf(&name, "tcp-client:%s", addr_str);
Craig Tillerfa275a92015-06-01 13:55:54 -0700288
Craig Tillera82950e2015-09-22 12:33:20 -0700289 fdobj = grpc_fd_create(fd, name);
Craig Tiller9bcc7512015-05-11 14:59:48 -0700290
Craig Tillera82950e2015-09-22 12:33:20 -0700291 if (err >= 0) {
Craig Tiller86958762016-09-23 12:05:34 -0700292 *ep =
293 grpc_tcp_client_create_from_fd(exec_ctx, fdobj, channel_args, addr_str);
ncteisen274bbbe2017-06-08 14:57:11 -0700294 GRPC_CLOSURE_SCHED(exec_ctx, closure, GRPC_ERROR_NONE);
Craig Tillera82950e2015-09-22 12:33:20 -0700295 goto done;
296 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800297
Craig Tillera82950e2015-09-22 12:33:20 -0700298 if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
Craig Tiller4782d922017-11-10 09:53:21 -0800299 grpc_fd_orphan(exec_ctx, fdobj, nullptr, nullptr, false /* already_closed */,
Yuchen Zengd40a7ae2017-07-12 15:59:56 -0700300 "tcp_client_connect_error");
ncteisen274bbbe2017-06-08 14:57:11 -0700301 GRPC_CLOSURE_SCHED(exec_ctx, closure, GRPC_OS_ERROR(errno, "connect"));
Craig Tillera82950e2015-09-22 12:33:20 -0700302 goto done;
303 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800304
Craig Tillera82950e2015-09-22 12:33:20 -0700305 grpc_pollset_set_add_fd(exec_ctx, interested_parties, fdobj);
Craig Tiller4b678bd2015-06-02 16:12:24 -0700306
Craig Tillerbaa14a92017-11-03 09:09:36 -0700307 ac = (async_connect*)gpr_malloc(sizeof(async_connect));
Craig Tillerd1bec032015-09-18 17:29:00 -0700308 ac->closure = closure;
309 ac->ep = ep;
Craig Tiller9bcc7512015-05-11 14:59:48 -0700310 ac->fd = fdobj;
Craig Tillerb49736822015-06-30 08:15:08 -0700311 ac->interested_parties = interested_parties;
Craig Tiller1b22b9d2015-07-20 13:42:22 -0700312 ac->addr_str = addr_str;
Craig Tiller4782d922017-11-10 09:53:21 -0800313 addr_str = nullptr;
Craig Tillera82950e2015-09-22 12:33:20 -0700314 gpr_mu_init(&ac->mu);
ctiller58393c22015-01-07 14:03:30 -0800315 ac->refs = 2;
ncteisen274bbbe2017-06-08 14:57:11 -0700316 GRPC_CLOSURE_INIT(&ac->write_closure, on_writable, ac,
Craig Tillerd6887e02016-12-29 10:11:40 -0800317 grpc_schedule_on_exec_ctx);
Craig Tiller86958762016-09-23 12:05:34 -0700318 ac->channel_args = grpc_channel_args_copy(channel_args);
ctiller58393c22015-01-07 14:03:30 -0800319
Craig Tiller84f75d42017-05-03 13:06:35 -0700320 if (GRPC_TRACER_ON(grpc_tcp_trace)) {
Craig Tiller6c8383a2017-05-05 16:54:42 +0000321 gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting fd %p",
322 ac->addr_str, fdobj);
Craig Tillera82950e2015-09-22 12:33:20 -0700323 }
Craig Tiller5e53ddb2015-09-16 10:53:15 -0700324
Craig Tillera82950e2015-09-22 12:33:20 -0700325 gpr_mu_lock(&ac->mu);
ncteisen274bbbe2017-06-08 14:57:11 -0700326 GRPC_CLOSURE_INIT(&ac->on_alarm, tc_on_alarm, ac, grpc_schedule_on_exec_ctx);
Craig Tillerdc3998e2017-05-12 09:55:30 -0700327 grpc_timer_init(exec_ctx, &ac->alarm, deadline, &ac->on_alarm);
Craig Tillera82950e2015-09-22 12:33:20 -0700328 grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure);
329 gpr_mu_unlock(&ac->mu);
Craig Tillerfa275a92015-06-01 13:55:54 -0700330
331done:
Craig Tillera82950e2015-09-22 12:33:20 -0700332 gpr_free(name);
333 gpr_free(addr_str);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800334}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800335
Craig Tillere6282612016-04-13 14:14:34 -0700336// overridden by api_fuzzer.c
Yash Tibrewalf5b4f802017-09-26 00:07:41 -0700337extern "C" {
Craig Tillere6282612016-04-13 14:14:34 -0700338void (*grpc_tcp_client_connect_impl)(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700339 grpc_exec_ctx* exec_ctx, grpc_closure* closure, grpc_endpoint** ep,
340 grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args,
341 const grpc_resolved_address* addr,
Craig Tillerdc3998e2017-05-12 09:55:30 -0700342 grpc_millis deadline) = tcp_client_connect_impl;
Yash Tibrewalf5b4f802017-09-26 00:07:41 -0700343}
Craig Tillere6282612016-04-13 14:14:34 -0700344
Craig Tillerbaa14a92017-11-03 09:09:36 -0700345void grpc_tcp_client_connect(grpc_exec_ctx* exec_ctx, grpc_closure* closure,
346 grpc_endpoint** ep,
347 grpc_pollset_set* interested_parties,
348 const grpc_channel_args* channel_args,
349 const grpc_resolved_address* addr,
Craig Tillerdc3998e2017-05-12 09:55:30 -0700350 grpc_millis deadline) {
Craig Tillere34c2852016-09-23 09:43:32 -0700351 grpc_tcp_client_connect_impl(exec_ctx, closure, ep, interested_parties,
Craig Tiller3d357d92016-10-26 20:52:03 -0700352 channel_args, addr, deadline);
Craig Tillere6282612016-04-13 14:14:34 -0700353}
354
Craig Tiller190d3602015-02-18 09:23:38 -0800355#endif