blob: 4a6570015f2a103daa4b5bb982ae6ac0c7e8bd59 [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
murgatroid99c36f6ea2016-10-03 09:24:09 -070034#include "src/core/lib/iomgr/port.h"
35
36// This test won't work except with posix sockets enabled
37#ifdef GRPC_POSIX_SOCKET
38
Craig Tiller9533d042016-03-25 17:11:06 -070039#include "src/core/lib/iomgr/tcp_server.h"
Craig Tiller69b093b2016-02-25 19:04:07 -080040
41#include <errno.h>
Dan Born8886a812016-07-08 16:06:07 -070042#include <ifaddrs.h>
Craig Tiller69b093b2016-02-25 19:04:07 -080043#include <netinet/in.h>
Dan Born8886a812016-07-08 16:06:07 -070044#include <stdio.h>
Craig Tiller69b093b2016-02-25 19:04:07 -080045#include <string.h>
46#include <sys/socket.h>
Dan Born8886a812016-07-08 16:06:07 -070047#include <sys/types.h>
Craig Tiller69b093b2016-02-25 19:04:07 -080048#include <unistd.h>
49
Dan Bornb13a69d2016-01-14 16:53:18 -080050#include <grpc/grpc.h>
Craig Tiller69b093b2016-02-25 19:04:07 -080051#include <grpc/support/alloc.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080052#include <grpc/support/log.h>
53#include <grpc/support/sync.h>
54#include <grpc/support/time.h>
Craig Tiller69b093b2016-02-25 19:04:07 -080055
Dan Born8886a812016-07-08 16:06:07 -070056#include "src/core/lib/iomgr/error.h"
Craig Tiller9533d042016-03-25 17:11:06 -070057#include "src/core/lib/iomgr/iomgr.h"
murgatroid997871f732016-09-23 13:49:05 -070058#include "src/core/lib/iomgr/resolve_address.h"
Craig Tiller9533d042016-03-25 17:11:06 -070059#include "src/core/lib/iomgr/sockaddr_utils.h"
Dan Bornd890a212016-01-14 15:00:21 -080060#include "test/core/util/port.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061#include "test/core/util/test_config.h"
62
Craig Tiller35696192015-05-24 15:00:37 -070063#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080064
Craig Tiller69b093b2016-02-25 19:04:07 -080065static gpr_mu *g_mu;
66static grpc_pollset *g_pollset;
Craig Tiller451b4df2015-05-12 16:47:46 -070067static int g_nconnects = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080068
Dan Born8886a812016-07-08 16:06:07 -070069typedef struct {
Dan Bornb13a69d2016-01-14 16:53:18 -080070 /* Owns a ref to server. */
71 grpc_tcp_server *server;
Dan Born601acad2016-01-13 19:52:58 -080072 unsigned port_index;
73 unsigned fd_index;
Dan Bornfa6b6062016-01-08 21:01:59 -080074 int server_fd;
Dan Born601acad2016-01-13 19:52:58 -080075} on_connect_result;
76
Dan Born8886a812016-07-08 16:06:07 -070077typedef struct {
Dan Born9c12bc22016-01-13 16:52:20 -080078 grpc_tcp_server *server;
79
80 /* arg is this server_weak_ref. */
81 grpc_closure server_shutdown;
82} server_weak_ref;
83
Dan Born8886a812016-07-08 16:06:07 -070084#define MAX_URI 1024
85typedef struct {
86 grpc_resolved_address addr;
87 char str[MAX_URI];
88} test_addr;
89
90#define MAX_ADDRS 100
91typedef struct {
92 size_t naddrs;
93 test_addr addrs[MAX_ADDRS];
94} test_addrs;
95
Dan Born9c12bc22016-01-13 16:52:20 -080096static on_connect_result g_result = {NULL, 0, 0, -1};
97
Dan Born8886a812016-07-08 16:06:07 -070098static char family_name_buf[1024];
99static const char *sock_family_name(int family) {
100 if (family == AF_INET) {
101 return "AF_INET";
102 } else if (family == AF_INET6) {
103 return "AF_INET6";
104 } else if (family == AF_UNSPEC) {
105 return "AF_UNSPEC";
106 } else {
107 sprintf(family_name_buf, "%d", family);
108 return family_name_buf;
109 }
110}
111
Dan Born9c12bc22016-01-13 16:52:20 -0800112static void on_connect_result_init(on_connect_result *result) {
Dan Bornb13a69d2016-01-14 16:53:18 -0800113 result->server = NULL;
114 result->port_index = 0;
115 result->fd_index = 0;
116 result->server_fd = -1;
117}
118
Dan Born9c12bc22016-01-13 16:52:20 -0800119static void on_connect_result_set(on_connect_result *result,
120 const grpc_tcp_server_acceptor *acceptor) {
Dan Bornb13a69d2016-01-14 16:53:18 -0800121 result->server = grpc_tcp_server_ref(acceptor->from_server);
122 result->port_index = acceptor->port_index;
123 result->fd_index = acceptor->fd_index;
124 result->server_fd = grpc_tcp_server_port_fd(
125 result->server, acceptor->port_index, acceptor->fd_index);
126}
127
Dan Born9c12bc22016-01-13 16:52:20 -0800128static void server_weak_ref_shutdown(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tillerf707d622016-05-06 14:26:12 -0700129 grpc_error *error) {
Dan Born9c12bc22016-01-13 16:52:20 -0800130 server_weak_ref *weak_ref = arg;
131 weak_ref->server = NULL;
132}
133
134static void server_weak_ref_init(server_weak_ref *weak_ref) {
135 weak_ref->server = NULL;
136 grpc_closure_init(&weak_ref->server_shutdown, server_weak_ref_shutdown,
Craig Tiller91031da2016-12-28 15:44:25 -0800137 weak_ref, grpc_schedule_on_exec_ctx);
Dan Born9c12bc22016-01-13 16:52:20 -0800138}
139
140/* Make weak_ref->server_shutdown a shutdown_starting cb on server.
141 grpc_tcp_server promises that the server object will live until
142 weak_ref->server_shutdown has returned. A strong ref on grpc_tcp_server
143 should be held until server_weak_ref_set() returns to avoid a race where the
144 server is deleted before the shutdown_starting cb is added. */
145static void server_weak_ref_set(server_weak_ref *weak_ref,
146 grpc_tcp_server *server) {
147 grpc_tcp_server_shutdown_starting_add(server, &weak_ref->server_shutdown);
148 weak_ref->server = server;
149}
Dan Bornfa6b6062016-01-08 21:01:59 -0800150
Dan Born8886a812016-07-08 16:06:07 -0700151static void test_addr_init_str(test_addr *addr) {
152 char *str = NULL;
153 if (grpc_sockaddr_to_string(&str, &addr->addr, 0) != -1) {
154 size_t str_len;
155 memcpy(addr->str, str, (str_len = strnlen(str, sizeof(addr->str) - 1)));
156 addr->str[str_len] = '\0';
157 gpr_free(str);
158 } else {
159 addr->str[0] = '\0';
160 }
161}
162
Dan Bornfa6b6062016-01-08 21:01:59 -0800163static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
Craig Tiller29dc4902016-05-20 08:43:48 -0700164 grpc_pollset *pollset,
Dan Born5d81d152016-01-12 20:29:29 -0800165 grpc_tcp_server_acceptor *acceptor) {
Craig Tillercda759d2017-01-27 11:37:37 -0800166 grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
Craig Tillera82950e2015-09-22 12:33:20 -0700167 grpc_endpoint_destroy(exec_ctx, tcp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800168
Craig Tiller2406e312016-10-19 13:26:48 -0700169 on_connect_result temp_result;
170 on_connect_result_set(&temp_result, acceptor);
Mark D. Roth96ba68d2016-12-09 17:21:26 +0000171 gpr_free(acceptor);
Craig Tiller2406e312016-10-19 13:26:48 -0700172
Craig Tiller69b093b2016-02-25 19:04:07 -0800173 gpr_mu_lock(g_mu);
Craig Tiller2406e312016-10-19 13:26:48 -0700174 g_result = temp_result;
Craig Tiller451b4df2015-05-12 16:47:46 -0700175 g_nconnects++;
Craig Tiller1aee5362016-05-07 11:26:50 -0700176 GPR_ASSERT(
177 GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, NULL)));
Craig Tiller69b093b2016-02-25 19:04:07 -0800178 gpr_mu_unlock(g_mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800179}
180
Craig Tillera82950e2015-09-22 12:33:20 -0700181static void test_no_op(void) {
Craig Tillerb8b1a462015-09-22 12:50:03 -0700182 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerf707d622016-05-06 14:26:12 -0700183 grpc_tcp_server *s;
Craig Tiller30ff60e2016-09-23 14:54:27 -0700184 GPR_ASSERT(GRPC_ERROR_NONE ==
185 grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
Dan Bornfa6b6062016-01-08 21:01:59 -0800186 grpc_tcp_server_unref(&exec_ctx, s);
Craig Tillerb8b1a462015-09-22 12:50:03 -0700187 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800188}
189
Craig Tillera82950e2015-09-22 12:33:20 -0700190static void test_no_op_with_start(void) {
Craig Tillerf5768a62015-09-22 10:54:34 -0700191 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerf707d622016-05-06 14:26:12 -0700192 grpc_tcp_server *s;
Craig Tiller30ff60e2016-09-23 14:54:27 -0700193 GPR_ASSERT(GRPC_ERROR_NONE ==
194 grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
Craig Tillera82950e2015-09-22 12:33:20 -0700195 LOG_TEST("test_no_op_with_start");
196 grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
Dan Bornfa6b6062016-01-08 21:01:59 -0800197 grpc_tcp_server_unref(&exec_ctx, s);
Craig Tillera82950e2015-09-22 12:33:20 -0700198 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800199}
200
Craig Tillera82950e2015-09-22 12:33:20 -0700201static void test_no_op_with_port(void) {
Craig Tillerf5768a62015-09-22 10:54:34 -0700202 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
murgatroid997871f732016-09-23 13:49:05 -0700203 grpc_resolved_address resolved_addr;
204 struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
Craig Tillerf707d622016-05-06 14:26:12 -0700205 grpc_tcp_server *s;
Craig Tiller30ff60e2016-09-23 14:54:27 -0700206 GPR_ASSERT(GRPC_ERROR_NONE ==
207 grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
Craig Tillera82950e2015-09-22 12:33:20 -0700208 LOG_TEST("test_no_op_with_port");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800209
murgatroid997871f732016-09-23 13:49:05 -0700210 memset(&resolved_addr, 0, sizeof(resolved_addr));
211 resolved_addr.len = sizeof(struct sockaddr_in);
212 addr->sin_family = AF_INET;
Dan Born8886a812016-07-08 16:06:07 -0700213 int port = -1;
murgatroid99dedb9232016-09-26 13:54:04 -0700214 GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
215 GRPC_ERROR_NONE &&
Craig Tillerf707d622016-05-06 14:26:12 -0700216 port > 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800217
Dan Bornfa6b6062016-01-08 21:01:59 -0800218 grpc_tcp_server_unref(&exec_ctx, s);
Craig Tillera82950e2015-09-22 12:33:20 -0700219 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800220}
221
Craig Tillera82950e2015-09-22 12:33:20 -0700222static void test_no_op_with_port_and_start(void) {
Craig Tillerf5768a62015-09-22 10:54:34 -0700223 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
murgatroid997871f732016-09-23 13:49:05 -0700224 grpc_resolved_address resolved_addr;
225 struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
Craig Tillerf707d622016-05-06 14:26:12 -0700226 grpc_tcp_server *s;
Craig Tiller30ff60e2016-09-23 14:54:27 -0700227 GPR_ASSERT(GRPC_ERROR_NONE ==
228 grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
Craig Tillera82950e2015-09-22 12:33:20 -0700229 LOG_TEST("test_no_op_with_port_and_start");
Dan Born8886a812016-07-08 16:06:07 -0700230 int port = -1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800231
murgatroid997871f732016-09-23 13:49:05 -0700232 memset(&resolved_addr, 0, sizeof(resolved_addr));
233 resolved_addr.len = sizeof(struct sockaddr_in);
234 addr->sin_family = AF_INET;
murgatroid99dedb9232016-09-26 13:54:04 -0700235 GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
236 GRPC_ERROR_NONE &&
Craig Tillerf707d622016-05-06 14:26:12 -0700237 port > 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800238
Craig Tillera82950e2015-09-22 12:33:20 -0700239 grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800240
Dan Bornfa6b6062016-01-08 21:01:59 -0800241 grpc_tcp_server_unref(&exec_ctx, s);
Craig Tillera82950e2015-09-22 12:33:20 -0700242 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800243}
244
Dan Born8886a812016-07-08 16:06:07 -0700245static grpc_error *tcp_connect(grpc_exec_ctx *exec_ctx, const test_addr *remote,
246 on_connect_result *result) {
Robbie Shadeca7effc2017-01-17 09:14:29 -0500247 gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
Dan Born8886a812016-07-08 16:06:07 -0700248 int clifd;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800249 int nconnects_before;
Dan Born8886a812016-07-08 16:06:07 -0700250 const struct sockaddr *remote_addr =
251 (const struct sockaddr *)remote->addr.addr;
Craig Tiller451b4df2015-05-12 16:47:46 -0700252
Dan Born8886a812016-07-08 16:06:07 -0700253 gpr_log(GPR_INFO, "Connecting to %s", remote->str);
Craig Tiller69b093b2016-02-25 19:04:07 -0800254 gpr_mu_lock(g_mu);
Dan Born601acad2016-01-13 19:52:58 -0800255 nconnects_before = g_nconnects;
Dan Bornb13a69d2016-01-14 16:53:18 -0800256 on_connect_result_init(&g_result);
Dan Born8886a812016-07-08 16:06:07 -0700257 clifd = socket(remote_addr->sa_family, SOCK_STREAM, 0);
258 if (clifd < 0) {
259 gpr_mu_unlock(g_mu);
260 return GRPC_OS_ERROR(errno, "Failed to create socket");
261 }
262 gpr_log(GPR_DEBUG, "start connect to %s", remote->str);
263 if (connect(clifd, remote_addr, (socklen_t)remote->addr.len) != 0) {
264 gpr_mu_unlock(g_mu);
265 close(clifd);
266 return GRPC_OS_ERROR(errno, "connect");
267 }
Dan Born601acad2016-01-13 19:52:58 -0800268 gpr_log(GPR_DEBUG, "wait");
269 while (g_nconnects == nconnects_before &&
270 gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
Craig Tillerf290e302016-02-18 08:04:36 -0800271 grpc_pollset_worker *worker = NULL;
Dan Born8886a812016-07-08 16:06:07 -0700272 grpc_error *err;
273 if ((err = grpc_pollset_work(exec_ctx, g_pollset, &worker,
274 gpr_now(GPR_CLOCK_MONOTONIC), deadline)) !=
275 GRPC_ERROR_NONE) {
276 gpr_mu_unlock(g_mu);
277 close(clifd);
278 return err;
279 }
Craig Tiller69b093b2016-02-25 19:04:07 -0800280 gpr_mu_unlock(g_mu);
Dan Born601acad2016-01-13 19:52:58 -0800281 grpc_exec_ctx_finish(exec_ctx);
Craig Tiller69b093b2016-02-25 19:04:07 -0800282 gpr_mu_lock(g_mu);
Craig Tillera82950e2015-09-22 12:33:20 -0700283 }
Dan Born601acad2016-01-13 19:52:58 -0800284 gpr_log(GPR_DEBUG, "wait done");
Dan Born8886a812016-07-08 16:06:07 -0700285 if (g_nconnects != nconnects_before + 1) {
286 gpr_mu_unlock(g_mu);
287 close(clifd);
288 return GRPC_ERROR_CREATE("Didn't connect");
289 }
Dan Born601acad2016-01-13 19:52:58 -0800290 close(clifd);
291 *result = g_result;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800292
Craig Tiller69b093b2016-02-25 19:04:07 -0800293 gpr_mu_unlock(g_mu);
Dan Born8886a812016-07-08 16:06:07 -0700294 gpr_log(GPR_INFO, "Result (%d, %d) fd %d", result->port_index,
295 result->fd_index, result->server_fd);
296 grpc_tcp_server_unref(exec_ctx, result->server);
297 return GRPC_ERROR_NONE;
Dan Born601acad2016-01-13 19:52:58 -0800298}
299
Dan Born8886a812016-07-08 16:06:07 -0700300/* Tests a tcp server on "::" listeners with multiple ports. If channel_args is
301 non-NULL, pass them to the server. If dst_addrs is non-NULL, use valid addrs
302 as destination addrs (port is not set). If dst_addrs is NULL, use listener
303 addrs as destination addrs. If test_dst_addrs is true, test connectivity with
304 each destination address, set grpc_resolved_address::len=0 for failures, but
305 don't fail the overall unitest. */
306static void test_connect(size_t num_connects,
307 const grpc_channel_args *channel_args,
308 test_addrs *dst_addrs, bool test_dst_addrs) {
Dan Born601acad2016-01-13 19:52:58 -0800309 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
murgatroid997871f732016-09-23 13:49:05 -0700310 grpc_resolved_address resolved_addr;
311 grpc_resolved_address resolved_addr1;
Dan Born8886a812016-07-08 16:06:07 -0700312 struct sockaddr_storage *const addr =
313 (struct sockaddr_storage *)resolved_addr.addr;
314 struct sockaddr_storage *const addr1 =
murgatroid99dedb9232016-09-26 13:54:04 -0700315 (struct sockaddr_storage *)resolved_addr1.addr;
Dan Born601acad2016-01-13 19:52:58 -0800316 unsigned svr_fd_count;
Dan Born8886a812016-07-08 16:06:07 -0700317 int port;
Dan Born601acad2016-01-13 19:52:58 -0800318 int svr_port;
319 unsigned svr1_fd_count;
Dan Bornb13a69d2016-01-14 16:53:18 -0800320 int svr1_port;
Craig Tillerf707d622016-05-06 14:26:12 -0700321 grpc_tcp_server *s;
Dan Born8886a812016-07-08 16:06:07 -0700322 const unsigned num_ports = 2;
Craig Tiller30ff60e2016-09-23 14:54:27 -0700323 GPR_ASSERT(GRPC_ERROR_NONE ==
Dan Born8886a812016-07-08 16:06:07 -0700324 grpc_tcp_server_create(&exec_ctx, NULL, channel_args, &s));
325 unsigned port_num;
Dan Born9c12bc22016-01-13 16:52:20 -0800326 server_weak_ref weak_ref;
327 server_weak_ref_init(&weak_ref);
Dan Born8886a812016-07-08 16:06:07 -0700328 server_weak_ref_set(&weak_ref, s);
Dan Born601acad2016-01-13 19:52:58 -0800329 LOG_TEST("test_connect");
Dan Born8886a812016-07-08 16:06:07 -0700330 gpr_log(GPR_INFO,
331 "clients=%lu, num chan args=%lu, remote IP=%s, test_dst_addrs=%d",
332 (unsigned long)num_connects,
333 (unsigned long)(channel_args != NULL ? channel_args->num_args : 0),
334 dst_addrs != NULL ? "<specific>" : "::", test_dst_addrs);
murgatroid997871f732016-09-23 13:49:05 -0700335 memset(&resolved_addr, 0, sizeof(resolved_addr));
336 memset(&resolved_addr1, 0, sizeof(resolved_addr1));
337 resolved_addr.len = sizeof(struct sockaddr_storage);
338 resolved_addr1.len = sizeof(struct sockaddr_storage);
339 addr->ss_family = addr1->ss_family = AF_INET;
Dan Born8886a812016-07-08 16:06:07 -0700340 GPR_ASSERT(GRPC_LOG_IF_ERROR(
341 "grpc_tcp_server_add_port",
342 grpc_tcp_server_add_port(s, &resolved_addr, &svr_port)));
343 gpr_log(GPR_INFO, "Allocated port %d", svr_port);
Dan Born601acad2016-01-13 19:52:58 -0800344 GPR_ASSERT(svr_port > 0);
Dan Bornb13a69d2016-01-14 16:53:18 -0800345 /* Cannot use wildcard (port==0), because add_port() will try to reuse the
346 same port as a previous add_port(). */
347 svr1_port = grpc_pick_unused_port_or_die();
Dan Born8886a812016-07-08 16:06:07 -0700348 GPR_ASSERT(svr1_port > 0);
349 gpr_log(GPR_INFO, "Picked unused port %d", svr1_port);
murgatroid997871f732016-09-23 13:49:05 -0700350 grpc_sockaddr_set_port(&resolved_addr1, svr1_port);
Dan Born8886a812016-07-08 16:06:07 -0700351 GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr1, &port) ==
murgatroid99dedb9232016-09-26 13:54:04 -0700352 GRPC_ERROR_NONE &&
Dan Born8886a812016-07-08 16:06:07 -0700353 port == svr1_port);
Dan Born601acad2016-01-13 19:52:58 -0800354
355 /* Bad port_index. */
356 GPR_ASSERT(grpc_tcp_server_port_fd_count(s, 2) == 0);
357 GPR_ASSERT(grpc_tcp_server_port_fd(s, 2, 0) < 0);
358
359 /* Bad fd_index. */
360 GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 100) < 0);
361 GPR_ASSERT(grpc_tcp_server_port_fd(s, 1, 100) < 0);
362
363 /* Got at least one fd per port. */
364 svr_fd_count = grpc_tcp_server_port_fd_count(s, 0);
365 GPR_ASSERT(svr_fd_count >= 1);
366 svr1_fd_count = grpc_tcp_server_port_fd_count(s, 1);
367 GPR_ASSERT(svr1_fd_count >= 1);
368
Craig Tiller69b093b2016-02-25 19:04:07 -0800369 grpc_tcp_server_start(&exec_ctx, s, &g_pollset, 1, on_connect, NULL);
Dan Born601acad2016-01-13 19:52:58 -0800370
Dan Born8886a812016-07-08 16:06:07 -0700371 if (dst_addrs != NULL) {
372 int ports[] = {svr_port, svr1_port};
373 for (port_num = 0; port_num < num_ports; ++port_num) {
374 size_t dst_idx;
375 size_t num_tested = 0;
376 for (dst_idx = 0; dst_idx < dst_addrs->naddrs; ++dst_idx) {
377 test_addr dst = dst_addrs->addrs[dst_idx];
378 on_connect_result result;
379 grpc_error *err;
380 if (dst.addr.len == 0) {
381 gpr_log(GPR_DEBUG, "Skipping test of non-functional local IP %s",
382 dst.str);
383 continue;
384 }
385 GPR_ASSERT(grpc_sockaddr_set_port(&dst.addr, ports[port_num]));
386 test_addr_init_str(&dst);
387 ++num_tested;
388 on_connect_result_init(&result);
389 if ((err = tcp_connect(&exec_ctx, &dst, &result)) == GRPC_ERROR_NONE &&
390 result.server_fd >= 0 && result.server == s) {
391 continue;
392 }
Dan Born3158f7b2017-02-09 20:32:02 -0800393 gpr_log(GPR_ERROR, "Failed to connect to %s: %s", dst.str,
394 grpc_error_string(err));
Dan Born8886a812016-07-08 16:06:07 -0700395 GPR_ASSERT(test_dst_addrs);
396 dst_addrs->addrs[dst_idx].addr.len = 0;
397 GRPC_ERROR_UNREF(err);
398 }
399 GPR_ASSERT(num_tested > 0);
Dan Born9c12bc22016-01-13 16:52:20 -0800400 }
Dan Born8886a812016-07-08 16:06:07 -0700401 } else {
402 for (port_num = 0; port_num < num_ports; ++port_num) {
403 const unsigned num_fds = grpc_tcp_server_port_fd_count(s, port_num);
404 unsigned fd_num;
405 for (fd_num = 0; fd_num < num_fds; ++fd_num) {
406 int fd = grpc_tcp_server_port_fd(s, port_num, fd_num);
407 size_t connect_num;
408 test_addr dst;
409 GPR_ASSERT(fd >= 0);
410 dst.addr.len = sizeof(dst.addr.addr);
411 GPR_ASSERT(getsockname(fd, (struct sockaddr *)dst.addr.addr,
412 (socklen_t *)&dst.addr.len) == 0);
413 GPR_ASSERT(dst.addr.len <= sizeof(dst.addr.addr));
414 test_addr_init_str(&dst);
415 gpr_log(GPR_INFO, "(%d, %d) fd %d family %s listening on %s", port_num,
416 fd_num, fd, sock_family_name(addr->ss_family), dst.str);
417 for (connect_num = 0; connect_num < num_connects; ++connect_num) {
418 on_connect_result result;
419 on_connect_result_init(&result);
420 GPR_ASSERT(GRPC_LOG_IF_ERROR("tcp_connect",
421 tcp_connect(&exec_ctx, &dst, &result)));
422 GPR_ASSERT(result.server_fd == fd);
423 GPR_ASSERT(result.port_index == port_num);
424 GPR_ASSERT(result.fd_index == fd_num);
425 GPR_ASSERT(result.server == s);
426 GPR_ASSERT(
427 grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
428 result.server_fd);
429 }
430 }
431 }
Dan Born601acad2016-01-13 19:52:58 -0800432 }
Dan Born9c12bc22016-01-13 16:52:20 -0800433 /* Weak ref to server valid until final unref. */
434 GPR_ASSERT(weak_ref.server != NULL);
435 GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0);
436
Dan Bornfa6b6062016-01-08 21:01:59 -0800437 grpc_tcp_server_unref(&exec_ctx, s);
Dan Born930c2982016-09-08 19:12:18 -0700438 grpc_exec_ctx_finish(&exec_ctx);
Dan Born9c12bc22016-01-13 16:52:20 -0800439
440 /* Weak ref lost. */
441 GPR_ASSERT(weak_ref.server == NULL);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800442}
443
Craig Tillerf707d622016-05-06 14:26:12 -0700444static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
445 grpc_error *error) {
Craig Tillera82950e2015-09-22 12:33:20 -0700446 grpc_pollset_destroy(p);
Craig Tiller294d0ec2015-09-21 14:59:45 -0700447}
Craig Tiller451b4df2015-05-12 16:47:46 -0700448
Craig Tillera82950e2015-09-22 12:33:20 -0700449int main(int argc, char **argv) {
Craig Tiller294d0ec2015-09-21 14:59:45 -0700450 grpc_closure destroyed;
Craig Tillerf5768a62015-09-22 10:54:34 -0700451 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Dan Born8886a812016-07-08 16:06:07 -0700452 grpc_arg chan_args[] = {
453 {GRPC_ARG_INTEGER, GRPC_ARG_EXPAND_WILDCARD_ADDRS, {.integer = 1}}};
454 const grpc_channel_args channel_args = {1, chan_args};
455 struct ifaddrs *ifa = NULL;
456 struct ifaddrs *ifa_it;
457 test_addrs dst_addrs;
Craig Tillera82950e2015-09-22 12:33:20 -0700458 grpc_test_init(argc, argv);
Dan Bornb13a69d2016-01-14 16:53:18 -0800459 grpc_init();
Craig Tiller69b093b2016-02-25 19:04:07 -0800460 g_pollset = gpr_malloc(grpc_pollset_size());
461 grpc_pollset_init(g_pollset, &g_mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800462
Craig Tillera82950e2015-09-22 12:33:20 -0700463 test_no_op();
464 test_no_op_with_start();
465 test_no_op_with_port();
466 test_no_op_with_port_and_start();
Dan Born8886a812016-07-08 16:06:07 -0700467
468 if (getifaddrs(&ifa) != 0 || ifa == NULL) {
469 gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno));
470 return EXIT_FAILURE;
471 }
472 dst_addrs.naddrs = 0;
473 for (ifa_it = ifa; ifa_it != NULL && dst_addrs.naddrs < MAX_ADDRS;
474 ifa_it = ifa_it->ifa_next) {
475 if (ifa_it->ifa_addr == NULL) {
476 continue;
477 } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
478 dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in);
479 } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
480 dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in6);
481 } else {
482 continue;
483 }
484 memcpy(dst_addrs.addrs[dst_addrs.naddrs].addr.addr, ifa_it->ifa_addr,
485 dst_addrs.addrs[dst_addrs.naddrs].addr.len);
486 GPR_ASSERT(
487 grpc_sockaddr_set_port(&dst_addrs.addrs[dst_addrs.naddrs].addr, 0));
488 test_addr_init_str(&dst_addrs.addrs[dst_addrs.naddrs]);
489 ++dst_addrs.naddrs;
490 }
491 freeifaddrs(ifa);
492 ifa = NULL;
493
494 /* Connect to same addresses as listeners. */
495 test_connect(1, NULL, NULL, false);
496 test_connect(10, NULL, NULL, false);
497
498 /* Set dst_addrs.addrs[i].len=0 for dst_addrs that are unreachable with a "::"
499 listener. */
500 test_connect(1, NULL, &dst_addrs, true);
501
502 /* Test connect(2) with dst_addrs. */
503 test_connect(1, &channel_args, &dst_addrs, false);
504 /* Test connect(2) with dst_addrs. */
505 test_connect(10, &channel_args, &dst_addrs, false);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800506
Craig Tiller91031da2016-12-28 15:44:25 -0800507 grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
508 grpc_schedule_on_exec_ctx);
Craig Tiller69b093b2016-02-25 19:04:07 -0800509 grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
Craig Tillera82950e2015-09-22 12:33:20 -0700510 grpc_exec_ctx_finish(&exec_ctx);
Dan Bornb13a69d2016-01-14 16:53:18 -0800511 grpc_shutdown();
Craig Tiller69b093b2016-02-25 19:04:07 -0800512 gpr_free(g_pollset);
Dan Born8886a812016-07-08 16:06:07 -0700513 return EXIT_SUCCESS;
Craig Tiller190d3602015-02-18 09:23:38 -0800514}
murgatroid99c36f6ea2016-10-03 09:24:09 -0700515
516#else /* GRPC_POSIX_SOCKET */
517
murgatroid99aa9c5782016-10-10 12:16:13 -0700518int main(int argc, char **argv) { return 1; }
murgatroid99c36f6ea2016-10-03 09:24:09 -0700519
520#endif /* GRPC_POSIX_SOCKET */