/* Prepare a recently-created socket for listening. */ static int prepare_socket(int fd, const struct sockaddr *addr, size_t addr_len) { struct sockaddr_storage sockname_temp; socklen_t sockname_len; if (fd < 0) { goto error; } if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) || !grpc_set_socket_reuse_addr(fd, 1))) || !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); goto error; } GPR_ASSERT(addr_len < ~(socklen_t)0); if (bind(fd, addr, (socklen_t)addr_len) < 0) { char *addr_str; grpc_sockaddr_to_string(&addr_str, addr, 0); gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno)); gpr_free(addr_str); goto error; } if (listen(fd, get_max_accept_queue_size()) < 0) { gpr_log(GPR_ERROR, "listen: %s", strerror(errno)); goto error; } sockname_len = sizeof(sockname_temp); if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) { goto error; } return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); error: if (fd >= 0) { close(fd); } return -1; }
static int prepare_socket(const struct sockaddr *addr, int fd) { if (fd < 0) { goto error; } if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1))) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); goto error; } return 1; error: if (fd >= 0) { close(fd); } return 0; }
/* Prepare a recently-created socket for listening. */ static int prepare_socket(grpc_socket_factory *socket_factory, int fd, const grpc_resolved_address *addr) { grpc_resolved_address sockname_temp; struct sockaddr *addr_ptr = (struct sockaddr *)addr->addr; /* Set send/receive socket buffers to 1 MB */ int buffer_size_bytes = 1024 * 1024; if (fd < 0) { goto error; } if (grpc_set_socket_nonblocking(fd, 1) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Unable to set nonblocking %d: %s", fd, strerror(errno)); goto error; } if (grpc_set_socket_cloexec(fd, 1) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Unable to set cloexec %d: %s", fd, strerror(errno)); goto error; } if (grpc_set_socket_ip_pktinfo_if_possible(fd) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Unable to set ip_pktinfo."); goto error; } else if (addr_ptr->sa_family == AF_INET6) { if (grpc_set_socket_ipv6_recvpktinfo_if_possible(fd) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Unable to set ipv6_recvpktinfo."); goto error; } } GPR_ASSERT(addr->len < ~(socklen_t)0); if (bind_socket(socket_factory, fd, addr) < 0) { char *addr_str; grpc_sockaddr_to_string(&addr_str, addr, 0); gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno)); gpr_free(addr_str); goto error; } sockname_temp.len = sizeof(struct sockaddr_storage); if (getsockname(fd, (struct sockaddr *)sockname_temp.addr, (socklen_t *)&sockname_temp.len) < 0) { goto error; } if (grpc_set_socket_sndbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes", buffer_size_bytes); goto error; } if (grpc_set_socket_rcvbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes", buffer_size_bytes); goto error; } return grpc_sockaddr_get_port(&sockname_temp); error: if (fd >= 0) { close(fd); } return -1; }
void test_times_out(void) { struct sockaddr_in addr; socklen_t addr_len = sizeof(addr); int svr_fd; #define NUM_CLIENT_CONNECTS 100 int client_fd[NUM_CLIENT_CONNECTS]; int i; int r; int connections_complete_before; gpr_timespec connect_deadline; grpc_closure done; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_log(GPR_DEBUG, "test_times_out"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; /* create a dummy server */ svr_fd = socket(AF_INET, SOCK_STREAM, 0); GPR_ASSERT(svr_fd >= 0); GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len)); GPR_ASSERT(0 == listen(svr_fd, 1)); /* Get its address */ GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0); /* tie up the listen buffer, which is somewhat arbitrarily sized. */ for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) { client_fd[i] = socket(AF_INET, SOCK_STREAM, 0); grpc_set_socket_nonblocking(client_fd[i], 1); do { r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len); } while (r == -1 && errno == EINTR); GPR_ASSERT(r < 0); GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS); } /* connect to dummy server address */ connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset)); connections_complete_before = g_connections_complete; gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset)); grpc_closure_init(&done, must_fail, NULL); grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set, (struct sockaddr *)&addr, addr_len, connect_deadline); /* Make sure the event doesn't trigger early */ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset)); for (;;) { grpc_pollset_worker worker; gpr_timespec now = gpr_now(connect_deadline.clock_type); gpr_timespec continue_verifying_time = gpr_time_from_seconds(5, GPR_TIMESPAN); gpr_timespec grace_time = gpr_time_from_seconds(3, GPR_TIMESPAN); gpr_timespec finish_time = gpr_time_add(connect_deadline, continue_verifying_time); gpr_timespec restart_verifying_time = gpr_time_add(connect_deadline, grace_time); int is_after_deadline = gpr_time_cmp(now, connect_deadline) > 0; if (gpr_time_cmp(now, finish_time) > 0) { break; } gpr_log(GPR_DEBUG, "now=%lld.%09d connect_deadline=%lld.%09d", (long long)now.tv_sec, (int)now.tv_nsec, (long long)connect_deadline.tv_sec, (int)connect_deadline.tv_nsec); if (is_after_deadline && gpr_time_cmp(now, restart_verifying_time) <= 0) { /* allow some slack before insisting that things be done */ } else { GPR_ASSERT(g_connections_complete == connections_complete_before + is_after_deadline); } grpc_pollset_work(&exec_ctx, &g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC), GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10)); gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset)); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset)); } gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset)); close(svr_fd); for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) { close(client_fd[i]); } }