grpc_error *grpc_create_dualstack_socket_using_factory( grpc_socket_factory *factory, const grpc_resolved_address *resolved_addr, int type, int protocol, grpc_dualstack_mode *dsmode, int *newfd) { const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr; int family = addr->sa_family; if (family == AF_INET6) { if (grpc_ipv6_loopback_available()) { *newfd = create_socket(factory, family, type, protocol); } else { *newfd = -1; errno = EAFNOSUPPORT; } /* Check if we've got a valid dualstack socket. */ if (*newfd >= 0 && set_socket_dualstack(*newfd)) { *dsmode = GRPC_DSMODE_DUALSTACK; return GRPC_ERROR_NONE; } /* If this isn't an IPv4 address, then return whatever we've got. */ if (!grpc_sockaddr_is_v4mapped(resolved_addr, NULL)) { *dsmode = GRPC_DSMODE_IPV6; return error_for_fd(*newfd, resolved_addr); } /* Fall back to AF_INET. */ if (*newfd >= 0) { close(*newfd); } family = AF_INET; } *dsmode = family == AF_INET ? GRPC_DSMODE_IPV4 : GRPC_DSMODE_NONE; *newfd = create_socket(factory, family, type, protocol); return error_for_fd(*newfd, resolved_addr); }
int main(int argc, char **argv) { int do_ipv6 = 1; grpc_test_init(argc, argv); grpc_init(); if (!grpc_ipv6_loopback_available()) { gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests."); do_ipv6 = 0; } /* For coverage, test with and without dualstack sockets. */ for (grpc_forbid_dualstack_sockets_for_testing = 0; grpc_forbid_dualstack_sockets_for_testing <= 1; grpc_forbid_dualstack_sockets_for_testing++) { /* :: and 0.0.0.0 are handled identically. */ test_connect("::", "127.0.0.1", 0, 1); test_connect("::", "::ffff:127.0.0.1", 0, 1); test_connect("::", "localhost", 0, 1); test_connect("0.0.0.0", "127.0.0.1", 0, 1); test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1); test_connect("0.0.0.0", "localhost", 0, 1); if (do_ipv6) { test_connect("::", "::1", 0, 1); test_connect("0.0.0.0", "::1", 0, 1); } /* These only work when the families agree. */ test_connect("127.0.0.1", "127.0.0.1", 0, 1); if (do_ipv6) { test_connect("::1", "::1", 0, 1); test_connect("::1", "127.0.0.1", 0, 0); test_connect("127.0.0.1", "::1", 0, 0); } } grpc_shutdown(); return 0; }
int main(int argc, char **argv) { int do_ipv6 = 1; grpc_test_init(argc, argv); grpc_init(); if (!grpc_ipv6_loopback_available()) { gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests."); do_ipv6 = 0; } /* For coverage, test with and without dualstack sockets. */ for (grpc_forbid_dualstack_sockets_for_testing = 0; grpc_forbid_dualstack_sockets_for_testing <= 1; grpc_forbid_dualstack_sockets_for_testing++) { /* :: and 0.0.0.0 are handled identically. */ test_connect("::", "127.0.0.1", 0, 1); test_connect("::", "::ffff:127.0.0.1", 0, 1); test_connect("::", "ipv4:127.0.0.1", 0, 1); test_connect("::", "ipv6:[::ffff:127.0.0.1]", 0, 1); test_connect("::", "localhost", 0, 1); test_connect("0.0.0.0", "127.0.0.1", 0, 1); test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1); test_connect("0.0.0.0", "ipv4:127.0.0.1", 0, 1); test_connect("0.0.0.0", "ipv4:127.0.0.1,127.0.0.2,127.0.0.3", 0, 1); test_connect("0.0.0.0", "ipv6:[::ffff:127.0.0.1],[::ffff:127.0.0.2]", 0, 1); test_connect("0.0.0.0", "localhost", 0, 1); if (do_ipv6) { test_connect("::", "::1", 0, 1); test_connect("0.0.0.0", "::1", 0, 1); test_connect("::", "ipv6:[::1]", 0, 1); test_connect("0.0.0.0", "ipv6:[::1]", 0, 1); } /* These only work when the families agree. */ test_connect("127.0.0.1", "127.0.0.1", 0, 1); test_connect("127.0.0.1", "ipv4:127.0.0.1", 0, 1); if (do_ipv6) { test_connect("::1", "::1", 0, 1); test_connect("::1", "127.0.0.1", 0, 0); test_connect("127.0.0.1", "::1", 0, 0); test_connect("::1", "ipv6:[::1]", 0, 1); test_connect("::1", "ipv4:127.0.0.1", 0, 0); test_connect("127.0.0.1", "ipv6:[::1]", 0, 0); } if (!external_dns_works("loopback46.unittest.grpc.io")) { gpr_log(GPR_INFO, "Skipping tests that depend on *.unittest.grpc.io."); } else { test_connect("loopback46.unittest.grpc.io", "loopback4.unittest.grpc.io", 0, 1); test_connect("loopback4.unittest.grpc.io", "loopback46.unittest.grpc.io", 0, 1); if (do_ipv6) { test_connect("loopback46.unittest.grpc.io", "loopback6.unittest.grpc.io", 0, 1); test_connect("loopback6.unittest.grpc.io", "loopback46.unittest.grpc.io", 0, 1); test_connect("loopback4.unittest.grpc.io", "loopback6.unittest.grpc.io", 0, 0); test_connect("loopback6.unittest.grpc.io", "loopback4.unittest.grpc.io", 0, 0); } } } grpc_shutdown(); return 0; }