static void test_connect(int n) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); int svrfd, clifd; grpc_tcp_server *s = grpc_tcp_server_create(); int nconnects_before; gpr_timespec deadline; grpc_pollset *pollsets[1]; int i; LOG_TEST("test_connect"); gpr_log(GPR_INFO, "clients=%d", n); memset(&addr, 0, sizeof(addr)); addr.ss_family = AF_INET; GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len)); svrfd = grpc_tcp_server_get_fd(s, 0); GPR_ASSERT(svrfd >= 0); GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0); GPR_ASSERT(addr_len <= sizeof(addr)); pollsets[0] = &g_pollset; grpc_tcp_server_start(s, pollsets, 1, on_connect, NULL); gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset)); for (i = 0; i < n; i++) { deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); nconnects_before = g_nconnects; clifd = socket(addr.ss_family, SOCK_STREAM, 0); GPR_ASSERT(clifd >= 0); gpr_log(GPR_DEBUG, "start connect"); GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0); gpr_log(GPR_DEBUG, "wait"); while (g_nconnects == nconnects_before && gpr_time_cmp(deadline, gpr_now(GPR_CLOCK_REALTIME)) > 0) { grpc_pollset_work(&g_pollset, deadline); } gpr_log(GPR_DEBUG, "wait done"); GPR_ASSERT(g_nconnects == nconnects_before + 1); close(clifd); } gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset)); grpc_tcp_server_destroy(s, NULL, NULL); }
static void test_no_op_with_port_and_start(void) { struct sockaddr_in addr; grpc_tcp_server *s = grpc_tcp_server_create(); LOG_TEST("test_no_op_with_port_and_start"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; GPR_ASSERT( grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr))); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_destroy(s, NULL, NULL); }
static void test_connect(int n) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); int svrfd, clifd; grpc_tcp_server *s = grpc_tcp_server_create(); int nconnects_before; gpr_timespec deadline; int i; LOG_TEST(); gpr_log(GPR_INFO, "clients=%d", n); gpr_mu_lock(&mu); memset(&addr, 0, sizeof(addr)); addr.ss_family = AF_INET; GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len)); svrfd = grpc_tcp_server_get_fd(s, 0); GPR_ASSERT(svrfd >= 0); GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0); GPR_ASSERT(addr_len <= sizeof(addr)); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); for (i = 0; i < n; i++) { deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); nconnects_before = nconnects; clifd = socket(addr.ss_family, SOCK_STREAM, 0); GPR_ASSERT(clifd >= 0); GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0); while (nconnects == nconnects_before) { GPR_ASSERT(gpr_cv_wait(&cv, &mu, deadline) == 0); } GPR_ASSERT(nconnects == nconnects_before + 1); close(clifd); if (i != n - 1) { sleep(1); } } gpr_mu_unlock(&mu); grpc_tcp_server_destroy(s); }
static void test_no_op_with_port_and_start(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; struct sockaddr_in addr; grpc_tcp_server *s = grpc_tcp_server_create(NULL); LOG_TEST("test_no_op_with_port_and_start"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; GPR_ASSERT( grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)) > 0); grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL); grpc_tcp_server_unref(&exec_ctx, s); grpc_exec_ctx_finish(&exec_ctx); }
void bad_server_thread(void *vargs) { struct server_thread_args *args = (struct server_thread_args *)vargs; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_resolved_address resolved_addr; struct sockaddr_storage *addr = (struct sockaddr_storage *)resolved_addr.addr; int port; grpc_tcp_server *s; grpc_error *error = grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s); GPR_ASSERT(error == GRPC_ERROR_NONE); memset(&resolved_addr, 0, sizeof(resolved_addr)); addr->ss_family = AF_INET; error = grpc_tcp_server_add_port(s, &resolved_addr, &port); GPR_ASSERT(GRPC_LOG_IF_ERROR("grpc_tcp_server_add_port", error)); GPR_ASSERT(port > 0); gpr_asprintf(&args->addr, "localhost:%d", port); grpc_tcp_server_start(&exec_ctx, s, &args->pollset, 1, on_connect, args); gpr_event_set(&args->ready, (void *)1); gpr_mu_lock(args->mu); while (gpr_atm_acq_load(&args->stop) == 0) { gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec deadline = gpr_time_add(now, gpr_time_from_millis(100, GPR_TIMESPAN)); grpc_pollset_worker *worker = NULL; if (!GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(&exec_ctx, args->pollset, &worker, now, deadline))) { gpr_atm_rel_store(&args->stop, 1); } gpr_mu_unlock(args->mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(args->mu); } gpr_mu_unlock(args->mu); grpc_tcp_server_unref(&exec_ctx, s); grpc_exec_ctx_finish(&exec_ctx); gpr_free(args->addr); }
void test_tcp_server_start(test_tcp_server *server, int port) { struct sockaddr_in addr; int port_added; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; addr.sin_family = AF_INET; addr.sin_port = htons((uint16_t)port); memset(&addr.sin_addr, 0, sizeof(addr.sin_addr)); server->tcp_server = grpc_tcp_server_create(&server->shutdown_complete); port_added = grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr)); GPR_ASSERT(port_added == port); grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1, server->on_connect, server->cb_data); gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port); grpc_exec_ctx_finish(&exec_ctx); }
static void test_no_op_with_port_and_start(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_resolved_address resolved_addr; struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr; grpc_tcp_server *s; GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s)); LOG_TEST("test_no_op_with_port_and_start"); int port; memset(&resolved_addr, 0, sizeof(resolved_addr)); resolved_addr.len = sizeof(struct sockaddr_in); addr->sin_family = AF_INET; GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) == GRPC_ERROR_NONE && port > 0); grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL); grpc_tcp_server_unref(&exec_ctx, s); grpc_exec_ctx_finish(&exec_ctx); }
void bad_server_thread(void *vargs) { struct server_thread_args *args = (struct server_thread_args *)vargs; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); int port; grpc_tcp_server *s = grpc_tcp_server_create(NULL); memset(&addr, 0, sizeof(addr)); addr.ss_family = AF_INET; port = grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len); GPR_ASSERT(port > 0); gpr_asprintf(&args->addr, "localhost:%d", port); grpc_tcp_server_start(&exec_ctx, s, &args->pollset, 1, on_connect, args); gpr_event_set(&args->ready, (void *)1); gpr_mu_lock(args->mu); while (gpr_atm_acq_load(&args->stop) == 0) { gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec deadline = gpr_time_add(now, gpr_time_from_millis(100, GPR_TIMESPAN)); grpc_pollset_worker *worker = NULL; grpc_pollset_work(&exec_ctx, args->pollset, &worker, now, deadline); gpr_mu_unlock(args->mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(args->mu); } gpr_mu_unlock(args->mu); grpc_tcp_server_unref(&exec_ctx, s); grpc_exec_ctx_finish(&exec_ctx); gpr_free(args->addr); }
static void test_no_op_with_start(void) { grpc_tcp_server *s = grpc_tcp_server_create(); LOG_TEST(); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_destroy(s); }
/* Server callback: start listening on our ports */ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) { grpc_tcp_server *tcp = tcpp; grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, server); }
/* Tests a tcp server with multiple ports. TODO(daniel-j-born): Multiple fds for the same port should be tested. */ static void test_connect(unsigned n) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; struct sockaddr_storage addr; struct sockaddr_storage addr1; socklen_t addr_len = sizeof(addr); unsigned svr_fd_count; int svr_port; unsigned svr1_fd_count; int svr1_port; grpc_tcp_server *s = grpc_tcp_server_create(NULL); unsigned i; server_weak_ref weak_ref; server_weak_ref_init(&weak_ref); LOG_TEST("test_connect"); gpr_log(GPR_INFO, "clients=%d", n); memset(&addr, 0, sizeof(addr)); memset(&addr1, 0, sizeof(addr1)); addr.ss_family = addr1.ss_family = AF_INET; svr_port = grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len); GPR_ASSERT(svr_port > 0); /* Cannot use wildcard (port==0), because add_port() will try to reuse the same port as a previous add_port(). */ svr1_port = grpc_pick_unused_port_or_die(); grpc_sockaddr_set_port((struct sockaddr *)&addr1, svr1_port); GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr1, addr_len) == svr1_port); /* Bad port_index. */ GPR_ASSERT(grpc_tcp_server_port_fd_count(s, 2) == 0); GPR_ASSERT(grpc_tcp_server_port_fd(s, 2, 0) < 0); /* Bad fd_index. */ GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 100) < 0); GPR_ASSERT(grpc_tcp_server_port_fd(s, 1, 100) < 0); /* Got at least one fd per port. */ svr_fd_count = grpc_tcp_server_port_fd_count(s, 0); GPR_ASSERT(svr_fd_count >= 1); svr1_fd_count = grpc_tcp_server_port_fd_count(s, 1); GPR_ASSERT(svr1_fd_count >= 1); for (i = 0; i < svr_fd_count; ++i) { int fd = grpc_tcp_server_port_fd(s, 0, i); GPR_ASSERT(fd >= 0); if (i == 0) { GPR_ASSERT(getsockname(fd, (struct sockaddr *)&addr, &addr_len) == 0); GPR_ASSERT(addr_len <= sizeof(addr)); } } for (i = 0; i < svr1_fd_count; ++i) { int fd = grpc_tcp_server_port_fd(s, 1, i); GPR_ASSERT(fd >= 0); if (i == 0) { GPR_ASSERT(getsockname(fd, (struct sockaddr *)&addr1, &addr_len) == 0); GPR_ASSERT(addr_len <= sizeof(addr1)); } } grpc_tcp_server_start(&exec_ctx, s, &g_pollset, 1, on_connect, NULL); for (i = 0; i < n; i++) { on_connect_result result; int svr_fd; on_connect_result_init(&result); tcp_connect(&exec_ctx, (struct sockaddr *)&addr, addr_len, &result); GPR_ASSERT(result.server_fd >= 0); svr_fd = result.server_fd; GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) == result.server_fd); GPR_ASSERT(result.port_index == 0); GPR_ASSERT(result.fd_index < svr_fd_count); GPR_ASSERT(result.server == s); if (weak_ref.server == NULL) { server_weak_ref_set(&weak_ref, result.server); } grpc_tcp_server_unref(&exec_ctx, result.server); on_connect_result_init(&result); tcp_connect(&exec_ctx, (struct sockaddr *)&addr1, addr_len, &result); GPR_ASSERT(result.server_fd >= 0); GPR_ASSERT(result.server_fd != svr_fd); GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) == result.server_fd); GPR_ASSERT(result.port_index == 1); GPR_ASSERT(result.fd_index < svr_fd_count); GPR_ASSERT(result.server == s); grpc_tcp_server_unref(&exec_ctx, result.server); } /* Weak ref to server valid until final unref. */ GPR_ASSERT(weak_ref.server != NULL); GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0); grpc_tcp_server_unref(&exec_ctx, s); /* Weak ref lost. */ GPR_ASSERT(weak_ref.server == NULL); grpc_exec_ctx_finish(&exec_ctx); }
/* Server callback: start listening on our ports */ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, grpc_pollset **pollsets, size_t pollset_count) { server_secure_state *state = statep; grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count, on_accept, state); }
/* Server callback: start listening on our ports */ static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) { grpc_tcp_server *tcp = tcpp; grpc_tcp_server_start(tcp, pollsets, pollset_count, on_accept, server); }
/* Tests a tcp server on "::" listeners with multiple ports. If channel_args is non-NULL, pass them to the server. If dst_addrs is non-NULL, use valid addrs as destination addrs (port is not set). If dst_addrs is NULL, use listener addrs as destination addrs. If test_dst_addrs is true, test connectivity with each destination address, set grpc_resolved_address::len=0 for failures, but don't fail the overall unitest. */ static void test_connect(size_t num_connects, const grpc_channel_args *channel_args, test_addrs *dst_addrs, bool test_dst_addrs) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_resolved_address resolved_addr; grpc_resolved_address resolved_addr1; struct sockaddr_storage *const addr = (struct sockaddr_storage *)resolved_addr.addr; struct sockaddr_storage *const addr1 = (struct sockaddr_storage *)resolved_addr1.addr; unsigned svr_fd_count; int port; int svr_port; unsigned svr1_fd_count; int svr1_port; grpc_tcp_server *s; const unsigned num_ports = 2; GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(&exec_ctx, NULL, channel_args, &s)); unsigned port_num; server_weak_ref weak_ref; server_weak_ref_init(&weak_ref); server_weak_ref_set(&weak_ref, s); LOG_TEST("test_connect"); gpr_log(GPR_INFO, "clients=%lu, num chan args=%lu, remote IP=%s, test_dst_addrs=%d", (unsigned long)num_connects, (unsigned long)(channel_args != NULL ? channel_args->num_args : 0), dst_addrs != NULL ? "<specific>" : "::", test_dst_addrs); memset(&resolved_addr, 0, sizeof(resolved_addr)); memset(&resolved_addr1, 0, sizeof(resolved_addr1)); resolved_addr.len = sizeof(struct sockaddr_storage); resolved_addr1.len = sizeof(struct sockaddr_storage); addr->ss_family = addr1->ss_family = AF_INET; GPR_ASSERT(GRPC_LOG_IF_ERROR( "grpc_tcp_server_add_port", grpc_tcp_server_add_port(s, &resolved_addr, &svr_port))); gpr_log(GPR_INFO, "Allocated port %d", svr_port); GPR_ASSERT(svr_port > 0); /* Cannot use wildcard (port==0), because add_port() will try to reuse the same port as a previous add_port(). */ svr1_port = grpc_pick_unused_port_or_die(); GPR_ASSERT(svr1_port > 0); gpr_log(GPR_INFO, "Picked unused port %d", svr1_port); grpc_sockaddr_set_port(&resolved_addr1, svr1_port); GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr1, &port) == GRPC_ERROR_NONE && port == svr1_port); /* Bad port_index. */ GPR_ASSERT(grpc_tcp_server_port_fd_count(s, 2) == 0); GPR_ASSERT(grpc_tcp_server_port_fd(s, 2, 0) < 0); /* Bad fd_index. */ GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 100) < 0); GPR_ASSERT(grpc_tcp_server_port_fd(s, 1, 100) < 0); /* Got at least one fd per port. */ svr_fd_count = grpc_tcp_server_port_fd_count(s, 0); GPR_ASSERT(svr_fd_count >= 1); svr1_fd_count = grpc_tcp_server_port_fd_count(s, 1); GPR_ASSERT(svr1_fd_count >= 1); grpc_tcp_server_start(&exec_ctx, s, &g_pollset, 1, on_connect, NULL); if (dst_addrs != NULL) { int ports[] = {svr_port, svr1_port}; for (port_num = 0; port_num < num_ports; ++port_num) { size_t dst_idx; size_t num_tested = 0; for (dst_idx = 0; dst_idx < dst_addrs->naddrs; ++dst_idx) { test_addr dst = dst_addrs->addrs[dst_idx]; on_connect_result result; grpc_error *err; if (dst.addr.len == 0) { gpr_log(GPR_DEBUG, "Skipping test of non-functional local IP %s", dst.str); continue; } GPR_ASSERT(grpc_sockaddr_set_port(&dst.addr, ports[port_num])); test_addr_init_str(&dst); ++num_tested; on_connect_result_init(&result); if ((err = tcp_connect(&exec_ctx, &dst, &result)) == GRPC_ERROR_NONE && result.server_fd >= 0 && result.server == s) { continue; } gpr_log(GPR_ERROR, "Failed to connect to %s: %s", dst.str, grpc_error_string(err)); GPR_ASSERT(test_dst_addrs); dst_addrs->addrs[dst_idx].addr.len = 0; GRPC_ERROR_UNREF(err); } GPR_ASSERT(num_tested > 0); } } else { for (port_num = 0; port_num < num_ports; ++port_num) { const unsigned num_fds = grpc_tcp_server_port_fd_count(s, port_num); unsigned fd_num; for (fd_num = 0; fd_num < num_fds; ++fd_num) { int fd = grpc_tcp_server_port_fd(s, port_num, fd_num); size_t connect_num; test_addr dst; GPR_ASSERT(fd >= 0); dst.addr.len = sizeof(dst.addr.addr); GPR_ASSERT(getsockname(fd, (struct sockaddr *)dst.addr.addr, (socklen_t *)&dst.addr.len) == 0); GPR_ASSERT(dst.addr.len <= sizeof(dst.addr.addr)); test_addr_init_str(&dst); gpr_log(GPR_INFO, "(%d, %d) fd %d family %s listening on %s", port_num, fd_num, fd, sock_family_name(addr->ss_family), dst.str); for (connect_num = 0; connect_num < num_connects; ++connect_num) { on_connect_result result; on_connect_result_init(&result); GPR_ASSERT(GRPC_LOG_IF_ERROR("tcp_connect", tcp_connect(&exec_ctx, &dst, &result))); GPR_ASSERT(result.server_fd == fd); GPR_ASSERT(result.port_index == port_num); GPR_ASSERT(result.fd_index == fd_num); GPR_ASSERT(result.server == s); GPR_ASSERT( grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) == result.server_fd); } } } } /* Weak ref to server valid until final unref. */ GPR_ASSERT(weak_ref.server != NULL); GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0); grpc_tcp_server_unref(&exec_ctx, s); grpc_exec_ctx_finish(&exec_ctx); /* Weak ref lost. */ GPR_ASSERT(weak_ref.server == NULL); }