(Network) Refactor getaddrinfo_retro (#14258)

This commit is contained in:
Cthulhu-throwaway 2022-07-30 17:43:32 -03:00 committed by GitHub
parent f711940339
commit f96ef5407a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 95 deletions

View File

@ -58,14 +58,20 @@
#define socklen_t int #define socklen_t int
#ifndef h_addr
#define h_addr h_addr_list[0] /* for backward compatibility */
#endif
#ifndef SO_KEEPALIVE #ifndef SO_KEEPALIVE
#define SO_KEEPALIVE 0 /* verify if correct */ #define SO_KEEPALIVE 0 /* verify if correct */
#endif #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) #elif defined(GEKKO)
#include <network.h> #include <network.h>
@ -85,6 +91,7 @@
#define recv(a,b,c,d) net_recv(a,b,c,d) #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 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 select(a,b,c,d,e) net_select(a,b,c,d,e)
#define gethostbyname(a) net_gethostbyname(a)
#elif defined(VITA) #elif defined(VITA)
#include <psp2/net/net.h> #include <psp2/net/net.h>
@ -251,7 +258,7 @@ struct addrinfo
int ai_family; int ai_family;
int ai_socktype; int ai_socktype;
int ai_protocol; int ai_protocol;
size_t ai_addrlen; socklen_t ai_addrlen;
struct sockaddr *ai_addr; struct sockaddr *ai_addr;
char *ai_canonname; char *ai_canonname;
struct addrinfo *ai_next; struct addrinfo *ai_next;

View File

@ -33,52 +33,48 @@
#include <retro_timers.h> #include <retro_timers.h>
#include <compat/strl.h> #include <compat/strl.h>
#ifdef GEKKO #if defined(_XBOX)
#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 */
};
struct hostent *gethostbyname(const char *name) struct hostent *gethostbyname(const char *name)
{ {
WSAEVENT event;
static struct hostent he;
static struct in_addr addr; static struct in_addr addr;
static char *addr_ptr = NULL; static struct hostent he = {0};
WSAEVENT event;
XNDNS *dns = NULL; XNDNS *dns = NULL;
struct hostent *ret = NULL;
he.h_addr_list = &addr_ptr;
addr_ptr = (char*)&addr;
if (!name) if (!name)
return NULL; return NULL;
event = WSACreateEvent(); event = WSACreateEvent();
XNetDnsLookup(name, event, &dns); XNetDnsLookup(name, event, &dns);
if (!dns) if (!dns)
goto error; goto done;
WaitForSingleObject((HANDLE)event, INFINITE); WaitForSingleObject((HANDLE)event, INFINITE);
if (dns->iStatus) if (dns->iStatus)
goto error; goto done;
memcpy(&addr, dns->aina, sizeof(addr)); 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); WSACloseEvent(event);
if (dns)
XNetDnsRelease(dns); XNetDnsRelease(dns);
return &he; return ret;
error:
if (event)
WSACloseEvent(event);
return NULL;
} }
#elif defined(VITA) #elif defined(VITA)
#define COMPAT_NET_INIT_SIZE 512*1024 #define COMPAT_NET_INIT_SIZE 512*1024
#define MAX_NAME 512 #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, int getaddrinfo_retro(const char *node, const char *service,
struct addrinfo *hints, struct addrinfo **res) struct addrinfo *hints, struct addrinfo **res)
{ {
struct sockaddr_in *in_addr = NULL; #if defined(HAVE_SOCKET_LEGACY) || defined(WIIU)
struct addrinfo *info = NULL; struct addrinfo default_hints = {0};
(void)in_addr;
(void)info;
if (!hints)
hints = &default_hints;
if (!hints->ai_family) if (!hints->ai_family)
{
#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY) || defined(WIIU)
hints->ai_family = AF_INET; hints->ai_family = AF_INET;
#else
hints->ai_family = AF_UNSPEC;
#endif
}
#if defined(WIIU)
if (!node) if (!node)
{ node = (hints->ai_flags & AI_PASSIVE) ? "0.0.0.0" : "127.0.0.1";
/* 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";
}
#endif #endif
#ifdef HAVE_SOCKET_LEGACY #ifdef HAVE_SOCKET_LEGACY
info = (struct addrinfo*)calloc(1, sizeof(*info)); {
if (!info) struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info));
goto error; struct sockaddr_in *addr = (struct sockaddr_in*)malloc(sizeof(*addr));
struct hostent *host = gethostbyname(node);
if (!info || !addr || !host || !host->h_addr)
{
free(addr);
free(info);
return -1;
}
info->ai_family = AF_INET; info->ai_family = AF_INET;
info->ai_socktype = hints->ai_socktype; info->ai_socktype = hints->ai_socktype;
in_addr = (struct sockaddr_in*) info->ai_protocol = hints->ai_protocol;
calloc(1, sizeof(*in_addr)); info->ai_addrlen = sizeof(*addr);
info->ai_addr = (struct sockaddr*)addr;
if (!in_addr) addr->sin_family = AF_INET;
goto error; if (service)
addr->sin_port = inet_htons((uint16_t)strtoul(service, NULL, 10));
info->ai_addrlen = sizeof(*in_addr); #ifdef VITA
in_addr->sin_family = AF_INET; addr->sin_addr.s_addr = inet_addr(host->h_addr);
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);
if (!host || !host->h_addr_list[0])
goto error;
in_addr->sin_family = host->h_addrtype;
#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]);
#else #else
memcpy(&in_addr->sin_addr, host->h_addr, host->h_length); memcpy(&addr->sin_addr, host->h_addr, sizeof(addr->sin_addr));
#endif #endif
}
else
goto error;
info->ai_addr = (struct sockaddr*)in_addr;
*res = info; *res = info;
return 0; return 0;
}
error:
if (in_addr)
free(in_addr);
if (info)
free(info);
return -1;
#else #else
return getaddrinfo(node, service, hints, res); return getaddrinfo(node, service, hints, res);
#endif #endif