From f96ef5407ac186751c12b0296558a3b4789149c3 Mon Sep 17 00:00:00 2001 From: Cthulhu-throwaway <96153783+Cthulhu-throwaway@users.noreply.github.com> Date: Sat, 30 Jul 2022 17:43:32 -0300 Subject: [PATCH] (Network) Refactor getaddrinfo_retro (#14258) --- libretro-common/include/net/net_compat.h | 17 ++- libretro-common/net/net_compat.c | 144 +++++++++-------------- 2 files changed, 66 insertions(+), 95 deletions(-) diff --git a/libretro-common/include/net/net_compat.h b/libretro-common/include/net/net_compat.h index 591f4cedbd..737f71191c 100644 --- a/libretro-common/include/net/net_compat.h +++ b/libretro-common/include/net/net_compat.h @@ -58,14 +58,20 @@ #define socklen_t int -#ifndef h_addr -#define h_addr h_addr_list[0] /* for backward compatibility */ -#endif - #ifndef SO_KEEPALIVE #define SO_KEEPALIVE 0 /* verify if correct */ #endif +struct hostent +{ + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; + char *h_addr; +}; + #elif defined(GEKKO) #include <network.h> @@ -85,6 +91,7 @@ #define recv(a,b,c,d) net_recv(a,b,c,d) #define recvfrom(a,b,c,d,e,f) net_recvfrom(a,b,c,d,e,f) #define select(a,b,c,d,e) net_select(a,b,c,d,e) +#define gethostbyname(a) net_gethostbyname(a) #elif defined(VITA) #include <psp2/net/net.h> @@ -251,7 +258,7 @@ struct addrinfo int ai_family; int ai_socktype; int ai_protocol; - size_t ai_addrlen; + socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index 3833862ed5..146f4c630b 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -33,52 +33,48 @@ #include <retro_timers.h> #include <compat/strl.h> -#ifdef GEKKO -#define gethostbyname net_gethostbyname -#elif defined(_XBOX) -/* TODO - implement h_length and h_addrtype */ -struct hostent -{ - int h_addrtype; /* host address type */ - int h_length; /* length of addresses */ - char **h_addr_list; /* list of addresses */ -}; - +#if defined(_XBOX) struct hostent *gethostbyname(const char *name) { - WSAEVENT event; - static struct hostent he; static struct in_addr addr; - static char *addr_ptr = NULL; - XNDNS *dns = NULL; - - he.h_addr_list = &addr_ptr; - addr_ptr = (char*)&addr; + static struct hostent he = {0}; + WSAEVENT event; + XNDNS *dns = NULL; + struct hostent *ret = NULL; if (!name) return NULL; event = WSACreateEvent(); + XNetDnsLookup(name, event, &dns); if (!dns) - goto error; + goto done; WaitForSingleObject((HANDLE)event, INFINITE); + if (dns->iStatus) - goto error; + goto done; memcpy(&addr, dns->aina, sizeof(addr)); + he.h_name = NULL; + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = sizeof(addr); + he.h_addr_list = &he.h_addr; + he.h_addr = (char*)&addr; + + ret = &he; + +done: WSACloseEvent(event); - XNetDnsRelease(dns); + if (dns) + XNetDnsRelease(dns); - return &he; - -error: - if (event) - WSACloseEvent(event); - return NULL; + return ret; } + #elif defined(VITA) #define COMPAT_NET_INIT_SIZE 512*1024 #define MAX_NAME 512 @@ -176,83 +172,51 @@ int inet_aton(const char *cp, struct in_addr *inp) int getaddrinfo_retro(const char *node, const char *service, struct addrinfo *hints, struct addrinfo **res) { - struct sockaddr_in *in_addr = NULL; - struct addrinfo *info = NULL; - - (void)in_addr; - (void)info; +#if defined(HAVE_SOCKET_LEGACY) || defined(WIIU) + struct addrinfo default_hints = {0}; + if (!hints) + hints = &default_hints; if (!hints->ai_family) - { -#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) || defined(WIIU) - hints->ai_family = AF_INET; -#else - hints->ai_family = AF_UNSPEC; -#endif - } + hints->ai_family = AF_INET; -#if defined(WIIU) if (!node) - { - /* Wii U's socket library chokes on NULL node */ - if (hints->ai_flags & AI_PASSIVE) - node = "0.0.0.0"; - else - node = "127.0.0.1"; - } + node = (hints->ai_flags & AI_PASSIVE) ? "0.0.0.0" : "127.0.0.1"; #endif #ifdef HAVE_SOCKET_LEGACY - info = (struct addrinfo*)calloc(1, sizeof(*info)); - if (!info) - goto error; - - info->ai_family = AF_INET; - info->ai_socktype = hints->ai_socktype; - in_addr = (struct sockaddr_in*) - calloc(1, sizeof(*in_addr)); - - if (!in_addr) - goto error; - - info->ai_addrlen = sizeof(*in_addr); - in_addr->sin_family = AF_INET; - in_addr->sin_port = inet_htons(strtoul(service, NULL, 0)); - - if (!node && (hints->ai_flags & AI_PASSIVE)) - in_addr->sin_addr.s_addr = INADDR_ANY; - else if (node && isdigit((unsigned char)*node)) - in_addr->sin_addr.s_addr = inet_addr(node); - else if (node && !isdigit((unsigned char)*node)) { - struct hostent *host = (struct hostent*)gethostbyname(node); + struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info)); + struct sockaddr_in *addr = (struct sockaddr_in*)malloc(sizeof(*addr)); + struct hostent *host = gethostbyname(node); - if (!host || !host->h_addr_list[0]) - goto error; + if (!info || !addr || !host || !host->h_addr) + { + free(addr); + free(info); - in_addr->sin_family = host->h_addrtype; + return -1; + } -#if defined(AF_INET6) && !defined(__PS3__) || defined(VITA) - /* TODO/FIXME - In case we ever want to support IPv6 */ - in_addr->sin_addr.s_addr = inet_addr(host->h_addr_list[0]); + info->ai_family = AF_INET; + info->ai_socktype = hints->ai_socktype; + info->ai_protocol = hints->ai_protocol; + info->ai_addrlen = sizeof(*addr); + info->ai_addr = (struct sockaddr*)addr; + + addr->sin_family = AF_INET; + if (service) + addr->sin_port = inet_htons((uint16_t)strtoul(service, NULL, 10)); +#ifdef VITA + addr->sin_addr.s_addr = inet_addr(host->h_addr); #else - memcpy(&in_addr->sin_addr, host->h_addr, host->h_length); + memcpy(&addr->sin_addr, host->h_addr, sizeof(addr->sin_addr)); #endif + + *res = info; + + return 0; } - else - goto error; - - info->ai_addr = (struct sockaddr*)in_addr; - *res = info; - - return 0; - -error: - if (in_addr) - free(in_addr); - if (info) - free(info); - return -1; #else return getaddrinfo(node, service, hints, res); #endif