static bool init_tcp_socket(netplay_t *netplay, const char *server, uint16_t port, bool spectate) { char port_buf[16] = {0}; bool ret = false; const struct addrinfo *tmp_info = NULL; struct addrinfo hints, *res = NULL; memset(&hints, 0, sizeof(hints)); #if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) hints.ai_family = AF_INET; #else hints.ai_family = AF_UNSPEC; #endif hints.ai_socktype = SOCK_STREAM; if (!server) hints.ai_flags = AI_PASSIVE; snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0) return false; if (!res) return false; /* If "localhost" is used, it is important to check every possible * address for IPv4/IPv6. */ tmp_info = res; while (tmp_info) { int fd; if ((fd = init_tcp_connection(tmp_info, server, netplay->spectate.enabled, (struct sockaddr*)&netplay->other_addr, sizeof(netplay->other_addr))) >= 0) { ret = true; netplay->fd = fd; break; } tmp_info = tmp_info->ai_next; } if (res) freeaddrinfo_retro(res); if (!ret) RARCH_ERR("Failed to set up netplay sockets.\n"); return ret; }
static bool init_tcp_socket(netplay_t *netplay, void *direct_host, const char *server, uint16_t port) { char port_buf[16]; bool ret = false; const struct addrinfo *tmp_info = NULL; struct addrinfo *res = NULL; struct addrinfo hints = {0}; port_buf[0] = '\0'; if (!direct_host) { #ifdef HAVE_INET6 /* Default to hosting on IPv6 and IPv4 */ if (!server) hints.ai_family = AF_INET6; #endif hints.ai_socktype = SOCK_STREAM; if (!server) hints.ai_flags = AI_PASSIVE; snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0) { #ifdef HAVE_INET6 if (!server) { /* Didn't work with IPv6, try wildcard */ hints.ai_family = 0; if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0) return false; } else #endif return false; } if (!res) return false; } else { /* I'll build my own addrinfo! With blackjack and hookers! */ struct netplay_host *host = (struct netplay_host *) direct_host; hints.ai_family = host->addr.sa_family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; hints.ai_addrlen = host->addrlen; hints.ai_addr = &host->addr; res = &hints; } /* If we're serving on IPv6, make sure we accept all connections, including * IPv4 */ #ifdef HAVE_INET6 if (!direct_host && !server && res->ai_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) res->ai_addr; sin6->sin6_addr = in6addr_any; } #endif /* If "localhost" is used, it is important to check every possible * address for IPv4/IPv6. */ tmp_info = res; while (tmp_info) { struct sockaddr_storage sad; int fd = init_tcp_connection( tmp_info, direct_host || server, (struct sockaddr*)&sad, sizeof(sad)); if (fd >= 0) { ret = true; if (direct_host || server) { netplay->connections[0].active = true; netplay->connections[0].fd = fd; netplay->connections[0].addr = sad; } else { netplay->listen_fd = fd; } break; } tmp_info = tmp_info->ai_next; } if (res && !direct_host) freeaddrinfo_retro(res); if (!ret) RARCH_ERR("Failed to set up netplay sockets.\n"); return ret; }