tcp_server_posix_test.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * 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
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * 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.
  16. *
  17. */
  18. #include "src/core/lib/gprpp/time.h"
  19. #include "src/core/lib/iomgr/port.h"
  20. // This test won't work except with posix sockets enabled
  21. #ifdef GRPC_POSIX_SOCKET_TCP_SERVER
  22. #include <errno.h>
  23. #include <ifaddrs.h>
  24. #include <netinet/in.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <sys/socket.h>
  28. #include <sys/types.h>
  29. #include <unistd.h>
  30. #include <string>
  31. #include <grpc/grpc.h>
  32. #include <grpc/support/alloc.h>
  33. #include <grpc/support/log.h>
  34. #include <grpc/support/sync.h>
  35. #include <grpc/support/time.h>
  36. #include "src/core/lib/address_utils/sockaddr_utils.h"
  37. #include "src/core/lib/gprpp/memory.h"
  38. #include "src/core/lib/iomgr/error.h"
  39. #include "src/core/lib/iomgr/iomgr.h"
  40. #include "src/core/lib/iomgr/resolve_address.h"
  41. #include "src/core/lib/iomgr/tcp_server.h"
  42. #include "src/core/lib/resource_quota/api.h"
  43. #include "test/core/util/port.h"
  44. #include "test/core/util/test_config.h"
  45. #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
  46. static gpr_mu* g_mu;
  47. static grpc_pollset* g_pollset;
  48. static int g_nconnects = 0;
  49. typedef struct {
  50. /* Owns a ref to server. */
  51. grpc_tcp_server* server;
  52. unsigned port_index;
  53. unsigned fd_index;
  54. int server_fd;
  55. } on_connect_result;
  56. typedef struct {
  57. grpc_tcp_server* server;
  58. /* arg is this server_weak_ref. */
  59. grpc_closure server_shutdown;
  60. } server_weak_ref;
  61. #define MAX_URI 1024
  62. typedef struct {
  63. grpc_resolved_address addr;
  64. char str[MAX_URI];
  65. } test_addr;
  66. #define MAX_ADDRS 100
  67. typedef struct {
  68. size_t naddrs;
  69. test_addr addrs[MAX_ADDRS];
  70. } test_addrs;
  71. static on_connect_result g_result = {nullptr, 0, 0, -1};
  72. static char family_name_buf[1024];
  73. static const char* sock_family_name(int family) {
  74. if (family == AF_INET) {
  75. return "AF_INET";
  76. } else if (family == AF_INET6) {
  77. return "AF_INET6";
  78. } else if (family == AF_UNSPEC) {
  79. return "AF_UNSPEC";
  80. } else {
  81. sprintf(family_name_buf, "%d", family);
  82. return family_name_buf;
  83. }
  84. }
  85. static void on_connect_result_init(on_connect_result* result) {
  86. result->server = nullptr;
  87. result->port_index = 0;
  88. result->fd_index = 0;
  89. result->server_fd = -1;
  90. }
  91. static void on_connect_result_set(on_connect_result* result,
  92. const grpc_tcp_server_acceptor* acceptor) {
  93. result->server = grpc_tcp_server_ref(acceptor->from_server);
  94. result->port_index = acceptor->port_index;
  95. result->fd_index = acceptor->fd_index;
  96. result->server_fd = grpc_tcp_server_port_fd(
  97. result->server, acceptor->port_index, acceptor->fd_index);
  98. }
  99. static void server_weak_ref_shutdown(void* arg, grpc_error_handle /*error*/) {
  100. server_weak_ref* weak_ref = static_cast<server_weak_ref*>(arg);
  101. weak_ref->server = nullptr;
  102. }
  103. static void server_weak_ref_init(server_weak_ref* weak_ref) {
  104. weak_ref->server = nullptr;
  105. GRPC_CLOSURE_INIT(&weak_ref->server_shutdown, server_weak_ref_shutdown,
  106. weak_ref, grpc_schedule_on_exec_ctx);
  107. }
  108. /* Make weak_ref->server_shutdown a shutdown_starting cb on server.
  109. grpc_tcp_server promises that the server object will live until
  110. weak_ref->server_shutdown has returned. A strong ref on grpc_tcp_server
  111. should be held until server_weak_ref_set() returns to avoid a race where the
  112. server is deleted before the shutdown_starting cb is added. */
  113. static void server_weak_ref_set(server_weak_ref* weak_ref,
  114. grpc_tcp_server* server) {
  115. grpc_tcp_server_shutdown_starting_add(server, &weak_ref->server_shutdown);
  116. weak_ref->server = server;
  117. }
  118. static void test_addr_init_str(test_addr* addr) {
  119. std::string str = grpc_sockaddr_to_string(&addr->addr, false);
  120. size_t str_len = std::min(str.size(), sizeof(addr->str) - 1);
  121. memcpy(addr->str, str.c_str(), str_len);
  122. addr->str[str_len] = '\0';
  123. }
  124. static void on_connect(void* /*arg*/, grpc_endpoint* tcp,
  125. grpc_pollset* /*pollset*/,
  126. grpc_tcp_server_acceptor* acceptor) {
  127. grpc_endpoint_shutdown(tcp,
  128. GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected"));
  129. grpc_endpoint_destroy(tcp);
  130. on_connect_result temp_result;
  131. on_connect_result_set(&temp_result, acceptor);
  132. gpr_free(acceptor);
  133. gpr_mu_lock(g_mu);
  134. g_result = temp_result;
  135. g_nconnects++;
  136. GPR_ASSERT(
  137. GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)));
  138. gpr_mu_unlock(g_mu);
  139. }
  140. static void test_no_op(void) {
  141. grpc_core::ExecCtx exec_ctx;
  142. grpc_tcp_server* s;
  143. const grpc_channel_args* args = grpc_core::CoreConfiguration::Get()
  144. .channel_args_preconditioning()
  145. .PreconditionChannelArgs(nullptr);
  146. GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s));
  147. grpc_channel_args_destroy(args);
  148. grpc_tcp_server_unref(s);
  149. }
  150. static void test_no_op_with_start(void) {
  151. grpc_core::ExecCtx exec_ctx;
  152. grpc_tcp_server* s;
  153. const grpc_channel_args* args = grpc_core::CoreConfiguration::Get()
  154. .channel_args_preconditioning()
  155. .PreconditionChannelArgs(nullptr);
  156. GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s));
  157. grpc_channel_args_destroy(args);
  158. LOG_TEST("test_no_op_with_start");
  159. std::vector<grpc_pollset*> empty_pollset;
  160. grpc_tcp_server_start(s, &empty_pollset, on_connect, nullptr);
  161. grpc_tcp_server_unref(s);
  162. }
  163. static void test_no_op_with_port(void) {
  164. grpc_core::ExecCtx exec_ctx;
  165. grpc_resolved_address resolved_addr;
  166. struct sockaddr_in* addr =
  167. reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr);
  168. grpc_tcp_server* s;
  169. const grpc_channel_args* args = grpc_core::CoreConfiguration::Get()
  170. .channel_args_preconditioning()
  171. .PreconditionChannelArgs(nullptr);
  172. GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s));
  173. grpc_channel_args_destroy(args);
  174. LOG_TEST("test_no_op_with_port");
  175. memset(&resolved_addr, 0, sizeof(resolved_addr));
  176. resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
  177. addr->sin_family = AF_INET;
  178. int port = -1;
  179. GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
  180. GRPC_ERROR_NONE &&
  181. port > 0);
  182. grpc_tcp_server_unref(s);
  183. }
  184. static void test_no_op_with_port_and_start(void) {
  185. grpc_core::ExecCtx exec_ctx;
  186. grpc_resolved_address resolved_addr;
  187. struct sockaddr_in* addr =
  188. reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr);
  189. grpc_tcp_server* s;
  190. const grpc_channel_args* args = grpc_core::CoreConfiguration::Get()
  191. .channel_args_preconditioning()
  192. .PreconditionChannelArgs(nullptr);
  193. GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s));
  194. grpc_channel_args_destroy(args);
  195. LOG_TEST("test_no_op_with_port_and_start");
  196. int port = -1;
  197. memset(&resolved_addr, 0, sizeof(resolved_addr));
  198. resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
  199. addr->sin_family = AF_INET;
  200. GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
  201. GRPC_ERROR_NONE &&
  202. port > 0);
  203. std::vector<grpc_pollset*> empty_pollset;
  204. grpc_tcp_server_start(s, &empty_pollset, on_connect, nullptr);
  205. grpc_tcp_server_unref(s);
  206. }
  207. static grpc_error_handle tcp_connect(const test_addr* remote,
  208. on_connect_result* result) {
  209. grpc_core::Timestamp deadline = grpc_core::Timestamp::FromTimespecRoundUp(
  210. grpc_timeout_seconds_to_deadline(10));
  211. int clifd;
  212. int nconnects_before;
  213. const struct sockaddr* remote_addr =
  214. reinterpret_cast<const struct sockaddr*>(remote->addr.addr);
  215. gpr_log(GPR_INFO, "Connecting to %s", remote->str);
  216. gpr_mu_lock(g_mu);
  217. nconnects_before = g_nconnects;
  218. on_connect_result_init(&g_result);
  219. clifd = socket(remote_addr->sa_family, SOCK_STREAM, 0);
  220. if (clifd < 0) {
  221. gpr_mu_unlock(g_mu);
  222. return GRPC_OS_ERROR(errno, "Failed to create socket");
  223. }
  224. gpr_log(GPR_DEBUG, "start connect to %s", remote->str);
  225. if (connect(clifd, remote_addr, static_cast<socklen_t>(remote->addr.len)) !=
  226. 0) {
  227. gpr_mu_unlock(g_mu);
  228. close(clifd);
  229. return GRPC_OS_ERROR(errno, "connect");
  230. }
  231. gpr_log(GPR_DEBUG, "wait");
  232. while (g_nconnects == nconnects_before &&
  233. deadline > grpc_core::ExecCtx::Get()->Now()) {
  234. grpc_pollset_worker* worker = nullptr;
  235. grpc_error_handle err;
  236. if ((err = grpc_pollset_work(g_pollset, &worker, deadline)) !=
  237. GRPC_ERROR_NONE) {
  238. gpr_mu_unlock(g_mu);
  239. close(clifd);
  240. return err;
  241. }
  242. gpr_mu_unlock(g_mu);
  243. gpr_mu_lock(g_mu);
  244. }
  245. gpr_log(GPR_DEBUG, "wait done");
  246. if (g_nconnects != nconnects_before + 1) {
  247. gpr_mu_unlock(g_mu);
  248. close(clifd);
  249. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Didn't connect");
  250. }
  251. close(clifd);
  252. *result = g_result;
  253. gpr_mu_unlock(g_mu);
  254. gpr_log(GPR_INFO, "Result (%d, %d) fd %d", result->port_index,
  255. result->fd_index, result->server_fd);
  256. grpc_tcp_server_unref(result->server);
  257. return GRPC_ERROR_NONE;
  258. }
  259. /* Tests a tcp server on "::" listeners with multiple ports. If channel_args is
  260. non-NULL, pass them to the server. If dst_addrs is non-NULL, use valid addrs
  261. as destination addrs (port is not set). If dst_addrs is NULL, use listener
  262. addrs as destination addrs. If test_dst_addrs is true, test connectivity with
  263. each destination address, set grpc_resolved_address::len=0 for failures, but
  264. don't fail the overall unitest. */
  265. static void test_connect(size_t num_connects,
  266. const grpc_channel_args* channel_args,
  267. test_addrs* dst_addrs, bool test_dst_addrs) {
  268. grpc_core::ExecCtx exec_ctx;
  269. grpc_resolved_address resolved_addr;
  270. grpc_resolved_address resolved_addr1;
  271. struct sockaddr_storage* const addr =
  272. reinterpret_cast<struct sockaddr_storage*>(resolved_addr.addr);
  273. struct sockaddr_storage* const addr1 =
  274. reinterpret_cast<struct sockaddr_storage*>(resolved_addr1.addr);
  275. unsigned svr_fd_count;
  276. int port;
  277. int svr_port;
  278. unsigned svr1_fd_count;
  279. int svr1_port;
  280. grpc_tcp_server* s;
  281. const unsigned num_ports = 2;
  282. const grpc_channel_args* new_channel_args =
  283. grpc_core::CoreConfiguration::Get()
  284. .channel_args_preconditioning()
  285. .PreconditionChannelArgs(channel_args);
  286. GPR_ASSERT(GRPC_ERROR_NONE ==
  287. grpc_tcp_server_create(nullptr, new_channel_args, &s));
  288. grpc_channel_args_destroy(new_channel_args);
  289. unsigned port_num;
  290. server_weak_ref weak_ref;
  291. server_weak_ref_init(&weak_ref);
  292. server_weak_ref_set(&weak_ref, s);
  293. LOG_TEST("test_connect");
  294. gpr_log(GPR_INFO,
  295. "clients=%lu, num chan args=%lu, remote IP=%s, test_dst_addrs=%d",
  296. static_cast<unsigned long>(num_connects),
  297. static_cast<unsigned long>(
  298. channel_args != nullptr ? channel_args->num_args : 0),
  299. dst_addrs != nullptr ? "<specific>" : "::", test_dst_addrs);
  300. memset(&resolved_addr, 0, sizeof(resolved_addr));
  301. memset(&resolved_addr1, 0, sizeof(resolved_addr1));
  302. resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
  303. resolved_addr1.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
  304. addr->ss_family = addr1->ss_family = AF_INET;
  305. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  306. "grpc_tcp_server_add_port",
  307. grpc_tcp_server_add_port(s, &resolved_addr, &svr_port)));
  308. gpr_log(GPR_INFO, "Allocated port %d", svr_port);
  309. GPR_ASSERT(svr_port > 0);
  310. /* Cannot use wildcard (port==0), because add_port() will try to reuse the
  311. same port as a previous add_port(). */
  312. svr1_port = grpc_pick_unused_port_or_die();
  313. GPR_ASSERT(svr1_port > 0);
  314. gpr_log(GPR_INFO, "Picked unused port %d", svr1_port);
  315. grpc_sockaddr_set_port(&resolved_addr1, svr1_port);
  316. GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr1, &port) ==
  317. GRPC_ERROR_NONE &&
  318. port == svr1_port);
  319. /* Bad port_index. */
  320. GPR_ASSERT(grpc_tcp_server_port_fd_count(s, 2) == 0);
  321. GPR_ASSERT(grpc_tcp_server_port_fd(s, 2, 0) < 0);
  322. /* Bad fd_index. */
  323. GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 100) < 0);
  324. GPR_ASSERT(grpc_tcp_server_port_fd(s, 1, 100) < 0);
  325. /* Got at least one fd per port. */
  326. svr_fd_count = grpc_tcp_server_port_fd_count(s, 0);
  327. GPR_ASSERT(svr_fd_count >= 1);
  328. svr1_fd_count = grpc_tcp_server_port_fd_count(s, 1);
  329. GPR_ASSERT(svr1_fd_count >= 1);
  330. std::vector<grpc_pollset*> test_pollset;
  331. test_pollset.push_back(g_pollset);
  332. grpc_tcp_server_start(s, &test_pollset, on_connect, nullptr);
  333. if (dst_addrs != nullptr) {
  334. int ports[] = {svr_port, svr1_port};
  335. for (port_num = 0; port_num < num_ports; ++port_num) {
  336. size_t dst_idx;
  337. size_t num_tested = 0;
  338. for (dst_idx = 0; dst_idx < dst_addrs->naddrs; ++dst_idx) {
  339. test_addr dst = dst_addrs->addrs[dst_idx];
  340. on_connect_result result;
  341. grpc_error_handle err;
  342. if (dst.addr.len == 0) {
  343. gpr_log(GPR_DEBUG, "Skipping test of non-functional local IP %s",
  344. dst.str);
  345. continue;
  346. }
  347. GPR_ASSERT(grpc_sockaddr_set_port(&dst.addr, ports[port_num]));
  348. test_addr_init_str(&dst);
  349. ++num_tested;
  350. on_connect_result_init(&result);
  351. if ((err = tcp_connect(&dst, &result)) == GRPC_ERROR_NONE &&
  352. result.server_fd >= 0 && result.server == s) {
  353. continue;
  354. }
  355. gpr_log(GPR_ERROR, "Failed to connect to %s: %s", dst.str,
  356. grpc_error_std_string(err).c_str());
  357. GPR_ASSERT(test_dst_addrs);
  358. dst_addrs->addrs[dst_idx].addr.len = 0;
  359. GRPC_ERROR_UNREF(err);
  360. }
  361. GPR_ASSERT(num_tested > 0);
  362. }
  363. } else {
  364. for (port_num = 0; port_num < num_ports; ++port_num) {
  365. const unsigned num_fds = grpc_tcp_server_port_fd_count(s, port_num);
  366. unsigned fd_num;
  367. for (fd_num = 0; fd_num < num_fds; ++fd_num) {
  368. int fd = grpc_tcp_server_port_fd(s, port_num, fd_num);
  369. size_t connect_num;
  370. test_addr dst;
  371. GPR_ASSERT(fd >= 0);
  372. dst.addr.len = static_cast<socklen_t>(sizeof(dst.addr.addr));
  373. GPR_ASSERT(getsockname(fd, (struct sockaddr*)dst.addr.addr,
  374. (socklen_t*)&dst.addr.len) == 0);
  375. GPR_ASSERT(dst.addr.len <= sizeof(dst.addr.addr));
  376. test_addr_init_str(&dst);
  377. gpr_log(GPR_INFO, "(%d, %d) fd %d family %s listening on %s", port_num,
  378. fd_num, fd, sock_family_name(addr->ss_family), dst.str);
  379. for (connect_num = 0; connect_num < num_connects; ++connect_num) {
  380. on_connect_result result;
  381. on_connect_result_init(&result);
  382. GPR_ASSERT(
  383. GRPC_LOG_IF_ERROR("tcp_connect", tcp_connect(&dst, &result)));
  384. GPR_ASSERT(result.server_fd == fd);
  385. GPR_ASSERT(result.port_index == port_num);
  386. GPR_ASSERT(result.fd_index == fd_num);
  387. GPR_ASSERT(result.server == s);
  388. GPR_ASSERT(
  389. grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
  390. result.server_fd);
  391. }
  392. }
  393. }
  394. }
  395. /* Weak ref to server valid until final unref. */
  396. GPR_ASSERT(weak_ref.server != nullptr);
  397. GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0);
  398. grpc_tcp_server_unref(s);
  399. grpc_core::ExecCtx::Get()->Flush();
  400. /* Weak ref lost. */
  401. GPR_ASSERT(weak_ref.server == nullptr);
  402. }
  403. static void destroy_pollset(void* p, grpc_error_handle /*error*/) {
  404. grpc_pollset_destroy(static_cast<grpc_pollset*>(p));
  405. }
  406. int main(int argc, char** argv) {
  407. grpc_closure destroyed;
  408. grpc_arg chan_args[1];
  409. chan_args[0].type = GRPC_ARG_INTEGER;
  410. chan_args[0].key = const_cast<char*>(GRPC_ARG_EXPAND_WILDCARD_ADDRS);
  411. chan_args[0].value.integer = 1;
  412. const grpc_channel_args channel_args = {1, chan_args};
  413. struct ifaddrs* ifa = nullptr;
  414. struct ifaddrs* ifa_it;
  415. // Zalloc dst_addrs to avoid oversized frames.
  416. test_addrs* dst_addrs = grpc_core::Zalloc<test_addrs>();
  417. grpc::testing::TestEnvironment env(argc, argv);
  418. grpc_init();
  419. // wait a few seconds to make sure IPv6 link-local addresses can be bound
  420. // if we are running under docker container that has just started.
  421. // See https://github.com/moby/moby/issues/38491
  422. // See https://github.com/grpc/grpc/issues/15610
  423. gpr_sleep_until(grpc_timeout_seconds_to_deadline(4));
  424. {
  425. grpc_core::ExecCtx exec_ctx;
  426. g_pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
  427. grpc_pollset_init(g_pollset, &g_mu);
  428. test_no_op();
  429. test_no_op_with_start();
  430. test_no_op_with_port();
  431. test_no_op_with_port_and_start();
  432. if (getifaddrs(&ifa) != 0 || ifa == nullptr) {
  433. gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno));
  434. return EXIT_FAILURE;
  435. }
  436. dst_addrs->naddrs = 0;
  437. for (ifa_it = ifa; ifa_it != nullptr && dst_addrs->naddrs < MAX_ADDRS;
  438. ifa_it = ifa_it->ifa_next) {
  439. if (ifa_it->ifa_addr == nullptr) {
  440. continue;
  441. } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
  442. dst_addrs->addrs[dst_addrs->naddrs].addr.len =
  443. static_cast<socklen_t>(sizeof(struct sockaddr_in));
  444. } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
  445. dst_addrs->addrs[dst_addrs->naddrs].addr.len =
  446. static_cast<socklen_t>(sizeof(struct sockaddr_in6));
  447. } else {
  448. continue;
  449. }
  450. memcpy(dst_addrs->addrs[dst_addrs->naddrs].addr.addr, ifa_it->ifa_addr,
  451. dst_addrs->addrs[dst_addrs->naddrs].addr.len);
  452. GPR_ASSERT(
  453. grpc_sockaddr_set_port(&dst_addrs->addrs[dst_addrs->naddrs].addr, 0));
  454. test_addr_init_str(&dst_addrs->addrs[dst_addrs->naddrs]);
  455. ++dst_addrs->naddrs;
  456. }
  457. freeifaddrs(ifa);
  458. ifa = nullptr;
  459. /* Connect to same addresses as listeners. */
  460. test_connect(1, nullptr, nullptr, false);
  461. test_connect(10, nullptr, nullptr, false);
  462. /* Set dst_addrs->addrs[i].len=0 for dst_addrs that are unreachable with a
  463. "::" listener. */
  464. test_connect(1, nullptr, dst_addrs, true);
  465. /* Test connect(2) with dst_addrs. */
  466. test_connect(1, &channel_args, dst_addrs, false);
  467. /* Test connect(2) with dst_addrs. */
  468. test_connect(10, &channel_args, dst_addrs, false);
  469. GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset,
  470. grpc_schedule_on_exec_ctx);
  471. grpc_pollset_shutdown(g_pollset, &destroyed);
  472. }
  473. grpc_shutdown();
  474. gpr_free(dst_addrs);
  475. gpr_free(g_pollset);
  476. return EXIT_SUCCESS;
  477. }
  478. #else /* GRPC_POSIX_SOCKET_SERVER */
  479. int main(int argc, char** argv) { return 1; }
  480. #endif /* GRPC_POSIX_SOCKET_SERVER */