aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/tcp_client_posix.cc
diff options
context:
space:
mode:
authorGravatar Dan Born <dborn@google.com>2017-11-17 14:31:00 -0800
committerGravatar Dan Born <dborn@google.com>2017-12-12 11:09:15 -0800
commitbdf63919b8e7e5fde7ce63b9bf2acbd85cc712e2 (patch)
tree83f4e24f54b957135174ec8286529f1533ae95d0 /src/core/lib/iomgr/tcp_client_posix.cc
parent94e676e10f8c739289924b8458a246699e3623ce (diff)
Refactor POSIX TCP client connect.
Diffstat (limited to 'src/core/lib/iomgr/tcp_client_posix.cc')
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc101
1 files changed, 59 insertions, 42 deletions
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 15062a52cd..24ccab14b2 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -236,65 +236,68 @@ finish:
GRPC_CLOSURE_SCHED(closure, error);
}
-static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep,
- grpc_pollset_set* interested_parties,
- const grpc_channel_args* channel_args,
- const grpc_resolved_address* addr,
- grpc_millis deadline) {
- int fd;
+grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args,
+ const grpc_resolved_address* addr,
+ grpc_resolved_address* mapped_addr,
+ grpc_fd** fdobj) {
grpc_dualstack_mode dsmode;
- int err;
- async_connect* ac;
- grpc_resolved_address addr6_v4mapped;
- grpc_resolved_address addr4_copy;
- grpc_fd* fdobj;
+ int fd;
+ grpc_error* error;
char* name;
char* addr_str;
- grpc_error* error;
-
- *ep = nullptr;
-
- /* Use dualstack sockets where available. */
- if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
- addr = &addr6_v4mapped;
+ *fdobj = nullptr;
+ /* Use dualstack sockets where available. Set mapped to v6 or v4 mapped to
+ v6. */
+ if (!grpc_sockaddr_to_v4mapped(addr, mapped_addr)) {
+ /* addr is v4 mapped to v6 or v6. */
+ memcpy(mapped_addr, addr, sizeof(*mapped_addr));
}
-
- error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
+ error =
+ grpc_create_dualstack_socket(mapped_addr, SOCK_STREAM, 0, &dsmode, &fd);
if (error != GRPC_ERROR_NONE) {
- GRPC_CLOSURE_SCHED(closure, error);
- return;
+ return error;
}
if (dsmode == GRPC_DSMODE_IPV4) {
- /* If we got an AF_INET socket, map the address back to IPv4. */
- GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy));
- addr = &addr4_copy;
+ /* Original addr is either v4 or v4 mapped to v6. Set mapped_addr to v4. */
+ if (!grpc_sockaddr_is_v4mapped(addr, mapped_addr)) {
+ memcpy(mapped_addr, addr, sizeof(*mapped_addr));
+ }
}
- if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
- GRPC_CLOSURE_SCHED(closure, error);
- return;
+ if ((error = prepare_socket(mapped_addr, fd, channel_args)) !=
+ GRPC_ERROR_NONE) {
+ return error;
}
+ addr_str = grpc_sockaddr_to_uri(mapped_addr);
+ gpr_asprintf(&name, "tcp-client:%s", addr_str);
+ *fdobj = grpc_fd_create(fd, name);
+ gpr_free(name);
+ gpr_free(addr_str);
+ return GRPC_ERROR_NONE;
+}
+void grpc_tcp_client_create_from_prepared_fd(
+ grpc_pollset_set* interested_parties, grpc_closure* closure, grpc_fd* fdobj,
+ const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
+ grpc_millis deadline, grpc_endpoint** ep) {
+ const int fd = grpc_fd_wrapped_fd(fdobj);
+ int err;
+ async_connect* ac;
do {
GPR_ASSERT(addr->len < ~(socklen_t)0);
err = connect(fd, (const struct sockaddr*)addr->addr, (socklen_t)addr->len);
} while (err < 0 && errno == EINTR);
-
- addr_str = grpc_sockaddr_to_uri(addr);
- gpr_asprintf(&name, "tcp-client:%s", addr_str);
-
- fdobj = grpc_fd_create(fd, name);
-
if (err >= 0) {
+ char* addr_str = grpc_sockaddr_to_uri(addr);
*ep = grpc_tcp_client_create_from_fd(fdobj, channel_args, addr_str);
+ gpr_free(addr_str);
GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_NONE);
- goto done;
+ return;
}
-
if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
grpc_fd_orphan(fdobj, nullptr, nullptr, false /* already_closed */,
"tcp_client_connect_error");
GRPC_CLOSURE_SCHED(closure, GRPC_OS_ERROR(errno, "connect"));
- goto done;
+ return;
}
grpc_pollset_set_add_fd(interested_parties, fdobj);
@@ -304,8 +307,7 @@ static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep,
ac->ep = ep;
ac->fd = fdobj;
ac->interested_parties = interested_parties;
- ac->addr_str = addr_str;
- addr_str = nullptr;
+ ac->addr_str = grpc_sockaddr_to_uri(addr);
gpr_mu_init(&ac->mu);
ac->refs = 2;
GRPC_CLOSURE_INIT(&ac->write_closure, on_writable, ac,
@@ -322,10 +324,25 @@ static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep,
grpc_timer_init(&ac->alarm, deadline, &ac->on_alarm);
grpc_fd_notify_on_write(ac->fd, &ac->write_closure);
gpr_mu_unlock(&ac->mu);
+}
-done:
- gpr_free(name);
- gpr_free(addr_str);
+static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep,
+ grpc_pollset_set* interested_parties,
+ const grpc_channel_args* channel_args,
+ const grpc_resolved_address* addr,
+ grpc_millis deadline) {
+ grpc_resolved_address mapped_addr;
+ grpc_fd* fdobj = nullptr;
+ grpc_error* error;
+ *ep = nullptr;
+ if ((error = grpc_tcp_client_prepare_fd(channel_args, addr, &mapped_addr,
+ &fdobj)) != GRPC_ERROR_NONE) {
+ GRPC_CLOSURE_SCHED(closure, error);
+ return;
+ }
+ grpc_tcp_client_create_from_prepared_fd(interested_parties, closure, fdobj,
+ channel_args, &mapped_addr, deadline,
+ ep);
}
// overridden by api_fuzzer.c