(Network) Add getnameinfo_retro (#14278)

This commit is contained in:
Cthulhu-throwaway 2022-08-04 08:22:49 -03:00 committed by GitHub
parent 88bc26da4e
commit 3aa1811ca9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 529 additions and 689 deletions

View File

@ -540,6 +540,48 @@ static bool command_verify(const char *cmd)
return false; return false;
} }
static bool udp_send_packet(const char *host, uint16_t port, const char *msg)
{
char port_buf[6];
const struct addrinfo *tmp_info;
struct addrinfo *addr = NULL;
struct addrinfo hints = {0};
size_t len = strlen(msg);
bool ret = false;
snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICSERV;
if (getaddrinfo_retro(host, port_buf, &hints, &addr))
return false;
if (!addr)
return false;
/* Send to all possible targets. */
tmp_info = addr;
do
{
int fd = socket(tmp_info->ai_family,
tmp_info->ai_socktype, tmp_info->ai_protocol);
if (fd < 0)
continue;
if (sendto(fd, msg, len, 0, tmp_info->ai_addr, tmp_info->ai_addrlen) ==
(ssize_t)len)
ret = true;
socket_close(fd);
} while ((tmp_info = tmp_info->ai_next));
freeaddrinfo_retro(addr);
return ret;
}
bool command_network_send(const char *cmd_) bool command_network_send(const char *cmd_)
{ {
char *command = NULL; char *command = NULL;

View File

@ -20,33 +20,32 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LIBRETRO_SDK_NET_COMPAT_H__ #ifndef _LIBRETRO_SDK_NET_COMPAT_H
#define LIBRETRO_SDK_NET_COMPAT_H__ #define _LIBRETRO_SDK_NET_COMPAT_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#include <boolean.h> #include <boolean.h>
#include <retro_inline.h> #include <retro_inline.h>
#include <stdint.h>
#if defined(_WIN32) && !defined(_XBOX) #include <errno.h>
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 #ifndef _WIN32
#include <sys/time.h>
#include <unistd.h>
#endif #endif
#include <retro_common_api.h>
RETRO_BEGIN_DECLS
#if defined(_WIN32) && !defined(_XBOX)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <winsock2.h> #include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#ifndef MSG_NOSIGNAL #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
#define MSG_NOSIGNAL 0
#endif
#if _WIN32_WINNT >= 0x0600
#define NETWORK_HAVE_POLL 1 #define NETWORK_HAVE_POLL 1
#endif #endif
@ -56,12 +55,12 @@
#include <xtl.h> #include <xtl.h>
#include <io.h> #include <io.h>
#define socklen_t int
#ifndef SO_KEEPALIVE #ifndef SO_KEEPALIVE
#define SO_KEEPALIVE 0 /* verify if correct */ #define SO_KEEPALIVE 0 /* verify if correct */
#endif #endif
#define socklen_t unsigned int
struct hostent struct hostent
{ {
char *h_name; char *h_name;
@ -73,26 +72,7 @@ struct hostent
char *h_end; char *h_end;
}; };
#elif defined(GEKKO) struct hostent *gethostbyname(const char *name);
#include <network.h>
#define NETWORK_HAVE_POLL 1
#define pollfd pollsd
#define socket(a,b,c) net_socket(a,b,c)
#define getsockopt(a,b,c,d,e) net_getsockopt(a,b,c,d,e)
#define setsockopt(a,b,c,d,e) net_setsockopt(a,b,c,d,e)
#define bind(a,b,c) net_bind(a,b,c)
#define listen(a,b) net_listen(a,b)
#define accept(a,b,c) net_accept(a,b,c)
#define connect(a,b,c) net_connect(a,b,c)
#define send(a,b,c,d) net_send(a,b,c,d)
#define sendto(a,b,c,d,e,f) net_sendto(a,b,c,d,e,f)
#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) #elif defined(VITA)
#include <psp2/net/net.h> #include <psp2/net/net.h>
@ -136,8 +116,9 @@ struct hostent
#define POLLHUP SCE_NET_EPOLLHUP #define POLLHUP SCE_NET_EPOLLHUP
#define POLLNVAL 0 #define POLLNVAL 0
#define sockaddr_in SceNetSockaddrIn
#define sockaddr SceNetSockaddr #define sockaddr SceNetSockaddr
#define sockaddr_in SceNetSockaddrIn
#define in_addr SceNetInAddr
#define socklen_t unsigned int #define socklen_t unsigned int
#define socket(a,b,c) sceNetSocket("unknown",a,b,c) #define socket(a,b,c) sceNetSocket("unknown",a,b,c)
@ -156,6 +137,8 @@ struct hostent
#define ntohl sceNetNtohl #define ntohl sceNetNtohl
#define htons sceNetHtons #define htons sceNetHtons
#define ntohs sceNetNtohs #define ntohs sceNetNtohs
#define inet_ntop sceNetInetNtop
#define inet_pton sceNetInetPton
struct pollfd struct pollfd
{ {
@ -176,14 +159,42 @@ struct hostent
char *h_end; char *h_end;
}; };
struct SceNetInAddr inet_aton(const char *ip_addr); char *inet_ntoa(struct in_addr in);
int inet_aton(const char *cp, struct in_addr *inp);
uint32_t inet_addr(const char *cp);
struct hostent *gethostbyname(const char *name);
#elif defined(GEKKO)
#include <network.h>
#define NETWORK_HAVE_POLL 1
#define pollfd pollsd
#define socket(a,b,c) net_socket(a,b,c)
#define getsockopt(a,b,c,d,e) net_getsockopt(a,b,c,d,e)
#define setsockopt(a,b,c,d,e) net_setsockopt(a,b,c,d,e)
#define bind(a,b,c) net_bind(a,b,c)
#define listen(a,b) net_listen(a,b)
#define accept(a,b,c) net_accept(a,b,c)
#define connect(a,b,c) net_connect(a,b,c)
#define send(a,b,c,d) net_send(a,b,c,d)
#define sendto(a,b,c,d,e,f) net_sendto(a,b,c,d,e,f)
#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)
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
int inet_pton(int af, const char *src, void *dst);
#else #else
#include <sys/select.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <sys/select.h>
#include <netinet/in.h>
#ifndef __PSL1GHT__ #ifndef __PSL1GHT__
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif #endif
@ -199,17 +210,16 @@ struct SceNetInAddr inet_aton(const char *ip_addr);
#include <signal.h> #include <signal.h>
#endif #endif
#ifdef WIIU
#define WIIU_RCVBUF (128 * 2 * 1024)
#define WIIU_SNDBUF (128 * 2 * 1024)
#endif
#if defined(__PSL1GHT__) #if defined(__PSL1GHT__)
#include <net/poll.h> #include <net/poll.h>
#define NETWORK_HAVE_POLL 1 #define NETWORK_HAVE_POLL 1
#elif !defined(WIIU) && !defined(__PS3__) #elif defined(WIIU)
#define WIIU_RCVBUF 0x40000
#define WIIU_SNDBUF 0x40000
#elif !defined(__PS3__)
#include <poll.h> #include <poll.h>
#define NETWORK_HAVE_POLL 1 #define NETWORK_HAVE_POLL 1
@ -217,13 +227,6 @@ struct SceNetInAddr inet_aton(const char *ip_addr);
#endif #endif
#endif #endif
#ifndef _WIN32
#include <sys/time.h>
#include <unistd.h>
#endif
#include <errno.h>
#ifndef MSG_NOSIGNAL #ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0 #define MSG_NOSIGNAL 0
#endif #endif
@ -246,13 +249,18 @@ struct SceNetInAddr inet_aton(const char *ip_addr);
* Only for IPv4. Mostly useful for the consoles which do not support * Only for IPv4. Mostly useful for the consoles which do not support
* anything reasonably modern on the socket API side of things. */ * anything reasonably modern on the socket API side of things. */
#ifdef HAVE_SOCKET_LEGACY #ifdef HAVE_SOCKET_LEGACY
#define sockaddr_storage sockaddr_in #define sockaddr_storage sockaddr_in
#define addrinfo addrinfo_retro__
#ifndef AI_PASSIVE #define AI_PASSIVE 1
#define AI_PASSIVE 1 #define AI_CANONNAME 2
#endif #define AI_NUMERICHOST 4
#define AI_NUMERICSERV 8
#define NI_NUMERICHOST 1
#define NI_NUMERICSERV 2
#define NI_NOFQDN 4
#define NI_NAMEREQD 8
#define NI_DGRAM 16
struct addrinfo struct addrinfo
{ {
@ -267,48 +275,46 @@ struct addrinfo
}; };
/* gai_strerror() not used, so we skip that. */ /* gai_strerror() not used, so we skip that. */
#endif #endif
static INLINE bool isagain(int bytes) static INLINE bool isagain(int val)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return (bytes == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK); return (val == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK);
#elif !defined(__PSL1GHT__) && defined(__PS3__) #elif !defined(__PSL1GHT__) && defined(__PS3__)
return (sys_net_errno == SYS_NET_EAGAIN) || (sys_net_errno == SYS_NET_EWOULDBLOCK); return (sys_net_errno == SYS_NET_EAGAIN) || (sys_net_errno == SYS_NET_EWOULDBLOCK);
#elif defined(VITA) #elif defined(VITA)
return (bytes == SCE_NET_ERROR_EAGAIN) || (bytes == SCE_NET_ERROR_EWOULDBLOCK); return (val == SCE_NET_ERROR_EAGAIN) || (val == SCE_NET_ERROR_EWOULDBLOCK);
#elif defined(WIIU) #elif defined(WIIU)
return (bytes == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK); return (val == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK);
#else #else
return (bytes < 0) && (errno == EAGAIN || errno == EWOULDBLOCK); return (val < 0) && (errno == EAGAIN || errno == EWOULDBLOCK);
#endif #endif
} }
static INLINE bool isinprogress(int bytes) static INLINE bool isinprogress(int val)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return (bytes == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK); return (val == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK);
#elif !defined(__PSL1GHT__) && defined(__PS3__) #elif !defined(__PSL1GHT__) && defined(__PS3__)
return (sys_net_errno == SYS_NET_EINPROGRESS); return (sys_net_errno == SYS_NET_EINPROGRESS);
#elif defined(VITA) #elif defined(VITA)
return (bytes == SCE_NET_ERROR_EINPROGRESS); return (val == SCE_NET_ERROR_EINPROGRESS);
#elif defined(WIIU) #elif defined(WIIU)
return (bytes == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK); return (val == -1) && (socketlasterr() == SO_EINPROGRESS);
#else #else
return (bytes < 0) && (errno == EINPROGRESS); return (val < 0) && (errno == EINPROGRESS);
#endif #endif
} }
uint16_t inet_htons(uint16_t hostshort);
int inet_ptrton(int af, const char *src, void *dst);
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);
void freeaddrinfo_retro(struct addrinfo *res); void freeaddrinfo_retro(struct addrinfo *res);
int getnameinfo_retro(const struct sockaddr *addr, socklen_t addrlen,
char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags);
bool addr_6to4(struct sockaddr_storage *addr); bool addr_6to4(struct sockaddr_storage *addr);
/** /**
@ -320,15 +326,6 @@ bool addr_6to4(struct sockaddr_storage *addr);
**/ **/
bool network_init(void); bool network_init(void);
/** RETRO_END_DECLS
* network_deinit:
*
* Deinitialize platform specific socket libraries.
**/
void network_deinit(void);
const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt);
bool udp_send_packet(const char *host, uint16_t port, const char *msg);
#endif #endif

View File

@ -20,18 +20,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <stdlib.h> #include <compat/strl.h>
#include <sys/types.h> #include <retro_timers.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <net/net_compat.h> #include <net/net_compat.h>
#include <net/net_socket.h>
#include <retro_timers.h>
#include <compat/strl.h>
#if defined(_XBOX) #if defined(_XBOX)
struct hostent *gethostbyname(const char *name) struct hostent *gethostbyname(const char *name)
@ -76,40 +71,27 @@ done:
} }
#elif defined(VITA) #elif defined(VITA)
#define COMPAT_NET_INIT_SIZE 512*1024 #define COMPAT_NET_INIT_SIZE 0x80000
#define MAX_NAME 512
typedef uint32_t in_addr_t; char *inet_ntoa(struct in_addr in)
struct in_addr
{
in_addr_t s_addr;
};
static void *_net_compat_net_memory = NULL;
char *inet_ntoa(struct SceNetInAddr in)
{ {
static char ip_addr[16]; static char ip_addr[16];
if (!inet_ntop_compat(AF_INET, &in, ip_addr, sizeof(ip_addr))) sceNetInetNtop(AF_INET, &in, ip_addr, sizeof(ip_addr));
strlcpy(ip_addr, "Invalid", sizeof(ip_addr));
return ip_addr; return ip_addr;
} }
struct SceNetInAddr inet_aton(const char *ip_addr) int inet_aton(const char *cp, struct in_addr *inp)
{ {
SceNetInAddr inaddr; return sceNetInetPton(AF_INET, cp, inp);
inet_ptrton(AF_INET, ip_addr, &inaddr);
return inaddr;
} }
unsigned int inet_addr(const char *cp) uint32_t inet_addr(const char *cp)
{ {
return inet_aton(cp).s_addr; struct in_addr in;
return (sceNetInetPton(AF_INET, cp, &in) == 1) ? in.s_addr : INADDR_NONE;
} }
struct hostent *gethostbyname(const char *name) struct hostent *gethostbyname(const char *name)
@ -144,33 +126,58 @@ done:
return ret; return ret;
} }
#elif defined(GEKKO)
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
const char *addr_str = inet_ntoa(*(struct in_addr*)src);
if (addr_str)
{
strlcpy(dst, addr_str, size);
return dst;
}
return NULL;
}
int inet_pton(int af, const char *src, void *dst)
{
if (inet_aton(src, (struct in_addr*)dst))
return 1;
return 0;
}
#elif defined(WIIU)
#include <malloc.h>
static int _net_compat_thread_entry(int argc, const char **argv)
{
void *buf = memalign(128, WIIU_RCVBUF + WIIU_SNDBUF);
if (!buf)
return -1;
somemopt(1, buf, WIIU_RCVBUF + WIIU_SNDBUF, 0);
free(buf);
return 0;
}
static void _net_compat_thread_cleanup(OSThread *thread, void *stack)
{
free(stack);
}
#elif defined(_3DS) #elif defined(_3DS)
#include <malloc.h> #include <malloc.h>
#include <3ds/types.h> #include <3ds/types.h>
#include <3ds/services/soc.h> #include <3ds/services/soc.h>
#define SOC_ALIGN 0x1000 #define SOC_ALIGN 0x1000
#define SOC_BUFFERSIZE 0x100000 #define SOC_BUFFERSIZE 0x100000
static u32* _net_compat_net_memory = NULL;
#endif
#if defined(_WIN32)
int inet_aton(const char *cp, struct in_addr *inp)
{
uint32_t addr = 0;
#ifndef _XBOX
if (cp == 0 || inp == 0)
return -1;
#endif
addr = inet_addr(cp);
if (addr == INADDR_NONE || addr == INADDR_ANY)
return -1;
inp->s_addr = addr;
return 1;
}
#endif #endif
int getaddrinfo_retro(const char *node, const char *service, int getaddrinfo_retro(const char *node, const char *service,
@ -192,30 +199,55 @@ int getaddrinfo_retro(const char *node, const char *service,
{ {
struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info)); struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info));
struct sockaddr_in *addr = (struct sockaddr_in*)malloc(sizeof(*addr)); struct sockaddr_in *addr = (struct sockaddr_in*)malloc(sizeof(*addr));
struct hostent *host = gethostbyname(node);
if (!info || !addr || !host || !host->h_addr) if (!info || !addr)
{ goto failure;
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;
info->ai_protocol = hints->ai_protocol; info->ai_protocol = hints->ai_protocol;
info->ai_addrlen = sizeof(*addr); info->ai_addrlen = sizeof(*addr);
info->ai_addr = (struct sockaddr*)addr; info->ai_addr = (struct sockaddr*)addr;
/* We ignore AI_CANONNAME; ai_canonname is always NULL. */
addr->sin_family = AF_INET;
addr->sin_family = AF_INET;
if (service) if (service)
addr->sin_port = inet_htons((uint16_t)strtoul(service, NULL, 10)); {
memcpy(&addr->sin_addr, host->h_addr, sizeof(addr->sin_addr)); /* We can only handle numeric ports; ignore AI_NUMERICSERV. */
char *service_end = NULL;
uint16_t port = (uint16_t)strtoul(service, &service_end, 10);
if (service_end == service || *service_end)
goto failure;
addr->sin_port = htons(port);
}
if (hints->ai_flags & AI_NUMERICHOST)
{
if (!inet_aton(node, &addr->sin_addr))
goto failure;
}
else
{
struct hostent *host = gethostbyname(node);
if (!host || !host->h_addr)
goto failure;
memcpy(&addr->sin_addr, host->h_addr, sizeof(addr->sin_addr));
}
*res = info; *res = info;
return 0; return 0;
failure:
free(addr);
free(info);
return -1;
} }
#else #else
return getaddrinfo(node, service, hints, res); return getaddrinfo(node, service, hints, res);
@ -235,193 +267,37 @@ void freeaddrinfo_retro(struct addrinfo *res)
#endif #endif
} }
#if defined(WIIU) int getnameinfo_retro(const struct sockaddr *addr, socklen_t addrlen,
#include <malloc.h> char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
static OSThread wiiu_net_cmpt_thread;
static void wiiu_net_cmpt_thread_cleanup(OSThread *thread, void *stack)
{ {
free(stack); #ifdef HAVE_SOCKET_LEGACY
} const struct sockaddr_in *addr4 = (const struct sockaddr_in*)addr;
static int wiiu_net_cmpt_thread_entry(int argc, const char** argv) /* We cannot perform reverse DNS lookups here; ignore the following flags:
{ NI_NAMEREQD
const int buf_size = WIIU_RCVBUF + WIIU_SNDBUF; NI_NOFQDN
void* buf = memalign(128, buf_size); NI_NUMERICHOST (always enforced)
if (!buf) return -1; */
if (host && hostlen)
{
const char *_host = inet_ntoa(addr4->sin_addr);
somemopt(1, buf, buf_size, 0); if (!_host)
return -1;
strlcpy(host, _host, hostlen);
}
/* We cannot get service names here; ignore the following flags:
NI_DGRAM
NI_NUMERICSERV (always enforced)
*/
if (serv && servlen)
snprintf(serv, servlen, "%hu", (unsigned short)addr4->sin_port);
free(buf);
return 0; return 0;
}
#endif
#if defined(GEKKO)
static char localip[16] = {0};
static char gateway[16] = {0};
static char netmask[16] = {0};
#endif
/**
* network_init:
*
* Platform specific socket library initialization.
*
* @return true if successful, otherwise false.
**/
bool network_init(void)
{
static bool inited = false;
#if defined(_WIN32)
WSADATA wsaData;
#elif defined(__PSL1GHT__) || defined(__PS3__)
int timeout_count = 10;
#elif defined(WIIU)
void* stack;
#endif
if (inited)
return true;
#if defined(_WIN32)
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
goto failure;
#elif defined(__PSL1GHT__) || defined(__PS3__)
sysModuleLoad(SYSMODULE_NET);
netInitialize();
if (netCtlInit() < 0)
goto failure;
for (;;)
{
int state;
if (netCtlGetState(&state) < 0)
goto failure;
if (state == NET_CTL_STATE_IPObtained)
break;
if (!(timeout_count--))
goto failure;
retro_sleep(500);
}
#elif defined(VITA)
if (sceNetShowNetstat() == SCE_NET_ERROR_ENOTINIT)
{
SceNetInitParam param;
_net_compat_net_memory = malloc(COMPAT_NET_INIT_SIZE);
if (!_net_compat_net_memory)
goto failure;
param.memory = _net_compat_net_memory;
param.size = COMPAT_NET_INIT_SIZE;
param.flags = 0;
if (sceNetInit(&param) < 0)
goto failure;
if (sceNetCtlInit() < 0)
goto failure;
}
#elif defined(GEKKO)
if (if_config(localip, netmask, gateway, true, 10) < 0)
goto failure;
#elif defined(WIIU)
stack = malloc(4096);
if (!stack)
goto failure;
socket_lib_init();
if (OSCreateThread(&wiiu_net_cmpt_thread, wiiu_net_cmpt_thread_entry,
0, NULL, stack+4096, 4096, 3,
OS_THREAD_ATTRIB_AFFINITY_ANY))
{
OSSetThreadName(&wiiu_net_cmpt_thread, "Network compat thread");
OSSetThreadDeallocator(&wiiu_net_cmpt_thread,
wiiu_net_cmpt_thread_cleanup);
OSResumeThread(&wiiu_net_cmpt_thread);
}
else
{
free(stack);
goto failure;
}
#elif defined(_3DS)
_net_compat_net_memory = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
if (!_net_compat_net_memory)
goto failure;
/* WIFI init */
if (socInit(_net_compat_net_memory, SOC_BUFFERSIZE))
goto failure;
#else #else
signal(SIGPIPE, SIG_IGN); /* Do not like SIGPIPE killing our app. */ return getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
#endif
inited = true;
return true;
#if defined(_WIN32) || defined(__PSL1GHT__) || defined(__PS3__) || defined(VITA) || defined(GEKKO) || defined(WIIU) || defined(_3DS)
failure:
network_deinit();
return false;
#endif
}
/**
* network_deinit:
*
* Deinitialize platform specific socket libraries.
**/
void network_deinit(void)
{
#if defined(_WIN32)
WSACleanup();
#elif defined(__PSL1GHT__) || defined(__PS3__)
netCtlTerm();
netFinalizeNetwork();
sysModuleUnload(SYSMODULE_NET);
#elif defined(VITA)
sceNetCtlTerm();
sceNetTerm();
free(_net_compat_net_memory);
_net_compat_net_memory = NULL;
#elif defined(GEKKO) && !defined(HW_DOL)
net_deinit();
#elif defined(_3DS)
socExit();
free(_net_compat_net_memory);
_net_compat_net_memory = NULL;
#endif
}
uint16_t inet_htons(uint16_t hostshort)
{
#if defined(VITA)
return sceNetHtons(hostshort);
#else
return htons(hostshort);
#endif
}
int inet_ptrton(int af, const char *src, void *dst)
{
#if defined(VITA)
return sceNetInetPton(af, src, dst);
#elif defined(GEKKO) || defined(_WIN32)
/* TODO/FIXME - should use InetPton on Vista and later */
return inet_aton(src, (struct in_addr*)dst);
#else
return inet_pton(af, src, dst);
#endif #endif
} }
@ -454,6 +330,7 @@ bool addr_6to4(struct sockaddr_storage *addr)
port = addr6->sin6_port; port = addr6->sin6_port;
memset(addr, 0, sizeof(*addr)); memset(addr, 0, sizeof(*addr));
addr4->sin_family = AF_INET; addr4->sin_family = AF_INET;
addr4->sin_port = port; addr4->sin_port = port;
memcpy(&addr4->sin_addr, &address, sizeof(addr4->sin_addr)); memcpy(&addr4->sin_addr, &address, sizeof(addr4->sin_addr));
@ -462,271 +339,188 @@ bool addr_6to4(struct sockaddr_storage *addr)
return true; return true;
} }
struct in_addr6_compat
{
unsigned char ip_addr[16];
};
#ifdef _XBOX
#ifndef IM_IN6ADDRSZ
#define IM_IN6ADDRSZ 16
#endif
#ifndef IM_INT16SZ
#define IM_INT16SZ 2
#endif
#ifndef IM_INADDRSZ
#define IM_INADDRSZ 4
#endif
/* Taken from https://github.com/skywind3000/easenet/blob/master/inetbase.c
*/
/** /**
* inet_ntop4x: * network_init:
* *
* Convert presentation format to network format. * Platform specific socket library initialization.
**/
static const char *
inet_ntop4x(const unsigned char *src, char *dst, size_t size)
{
char tmp[64];
size_t len = snprintf(tmp,
sizeof(tmp),
"%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
if (len >= size)
goto error;
memcpy(dst, tmp, len + 1);
return dst;
error:
errno = ENOSPC;
return NULL;
}
/**
* inet_ntop6x:
* *
* Convert presentation format to network format. * @return true if successful, otherwise false.
**/ **/
static const char * bool network_init(void)
inet_ntop6x(const unsigned char *src, char *dst, size_t size)
{ {
char tmp[64], *tp; #if defined(_WIN32)
int i, inc; static bool initialized = false;
struct { int base, len; } best, cur;
unsigned int words[IM_IN6ADDRSZ / IM_INT16SZ];
memset(words, '\0', sizeof(words)); if (!initialized)
best.base = best.len = 0;
cur.base = cur.len = 0;
for (i = 0; i < IM_IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for (i = 0; i < (IM_IN6ADDRSZ / IM_INT16SZ); i++)
{ {
if (words[i] == 0) WSADATA wsaData;
{
if (cur.base == -1)
{
cur.base = i;
cur.len = 1;
}
else cur.len++;
}
else
{
if (cur.base != -1)
{
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1)
{
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
tp = tmp; if (WSAStartup(MAKEWORD(2, 2), &wsaData))
for (i = 0; i < (IM_IN6ADDRSZ / IM_INT16SZ); i++)
{
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len))
{ {
if (i == best.base) WSACleanup();
*tp++ = ':';
continue; return false;
} }
if (i != 0) initialized = true;
*tp++ = ':'; }
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) return true;
#elif defined(__PSL1GHT__) || defined(__PS3__)
static bool initialized = false;
if (!initialized)
{
int tries;
sysModuleLoad(SYSMODULE_NET);
netInitialize();
if (netCtlInit() < 0)
goto failure;
for (tries = 10;;)
{ {
if (!inet_ntop4x(src+12, tp, sizeof(tmp) - (tp - tmp))) int state;
return NULL;
tp += strlen(tp); if (netCtlGetState(&state) < 0)
break; goto failure;
if (state == NET_CTL_STATE_IPObtained)
break;
if (!(--tries))
goto failure;
retro_sleep(500);
} }
inc = sprintf(tp, "%x", words[i]);
tp += inc; initialized = true;
} }
if (best.base != -1 && (best.base + best.len) == return true;
(IM_IN6ADDRSZ / IM_INT16SZ))
*tp++ = ':';
*tp++ = '\0'; failure:
netCtlTerm();
netFinalizeNetwork();
if ((size_t)(tp - tmp) > size) sysModuleUnload(SYSMODULE_NET);
goto error;
memcpy(dst, tmp, tp - tmp); return false;
return dst; #elif defined(VITA)
if (sceNetShowNetstat() == SCE_NET_ERROR_ENOTINIT)
error:
errno = ENOSPC;
return NULL;
}
/*
* isockaddr_ntop:
*
* Convert network format to presentation format.
* Another inet_ntop, supports AF_INET/AF_INET6
**/
static const char *isockaddr_ntop(int af,
const void *src, char *dst, size_t size)
{
switch (af)
{ {
case AF_INET: SceNetInitParam param;
return inet_ntop4x((const unsigned char*)src, dst, size); void *net_compat_memory = malloc(COMPAT_NET_INIT_SIZE);
#ifdef AF_INET6
case AF_INET6:
return inet_ntop6x((const unsigned char*)src, dst, size);
#endif
default:
if (af == -6)
return inet_ntop6x((const unsigned char*)src, dst, size);
errno = EAFNOSUPPORT;
return NULL;
}
}
#endif
const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt) if (!net_compat_memory)
{ return false;
#if defined(VITA)
return sceNetInetNtop(af,src,dst,cnt);
#elif defined(WIIU)
return inet_ntop(af, src, dst, cnt);
#elif defined(GEKKO)
if (af == AF_INET)
{
const char *addr_str = inet_ntoa(*(struct in_addr*)src);
if (addr_str) param.memory = net_compat_memory;
{ param.size = COMPAT_NET_INIT_SIZE;
strlcpy(dst, addr_str, cnt); param.flags = 0;
return dst; if (sceNetInit(&param) < 0)
} goto failure;
} if (sceNetCtlInit() < 0)
goto failure;
return NULL; return true;
#elif defined(_XBOX)
return isockaddr_ntop(af, src, dst, cnt);
#elif defined(_WIN32)
if (af == AF_INET)
{
struct sockaddr_in in;
memset(&in, 0, sizeof(in));
in.sin_family = AF_INET;
memcpy(&in.sin_addr, src, sizeof(struct in_addr));
getnameinfo((struct sockaddr *)&in, sizeof(struct
sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
return dst;
}
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
else if (af == AF_INET6)
{
struct sockaddr_in6 in;
memset(&in, 0, sizeof(in));
in.sin6_family = AF_INET6;
memcpy(&in.sin6_addr, src, sizeof(struct in_addr6_compat));
getnameinfo((struct sockaddr *)&in, sizeof(struct
sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
return dst;
}
#endif
else
return NULL;
#else
return inet_ntop(af, src, dst, cnt);
#endif
}
bool udp_send_packet(const char *host, failure:
uint16_t port, const char *msg) sceNetCtlTerm();
{ sceNetTerm();
char port_buf[16] = {0};
struct addrinfo hints = {0};
struct addrinfo *res = NULL;
const struct addrinfo *tmp = NULL;
int fd = -1;
bool ret = true;
hints.ai_socktype = SOCK_DGRAM; free(net_compat_memory);
snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
if (getaddrinfo_retro(host, port_buf, &hints, &res) != 0)
return false; return false;
/* Send to all possible targets.
* "localhost" might resolve to several different IPs. */
tmp = (const struct addrinfo*)res;
while (tmp)
{
ssize_t len, ret_len;
fd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
if (fd < 0)
{
ret = false;
goto end;
}
len = strlen(msg);
ret_len = sendto(fd, msg, len, 0, tmp->ai_addr, tmp->ai_addrlen);
if (ret_len < len)
{
ret = false;
goto end;
}
socket_close(fd);
fd = -1;
tmp = tmp->ai_next;
} }
end: return true;
freeaddrinfo_retro(res); #elif defined(GEKKO)
if (fd >= 0) static bool initialized = false;
socket_close(fd);
return ret; if (!initialized)
{
char localip[16] = {0};
char netmask[16] = {0};
char gateway[16] = {0};
if (if_config(localip, netmask, gateway, true, 10) < 0)
{
net_deinit();
return false;
}
initialized = true;
}
return true;
#elif defined(WIIU)
static bool initialized = false;
if (!initialized)
{
OSThread net_compat_thread;
void *stack = malloc(0x1000);
if (!stack)
return false;
socket_lib_init();
if (!OSCreateThread(&net_compat_thread, _net_compat_thread_entry,
0, NULL, (void*)((size_t)stack + 0x1000), 0x1000, 3,
OS_THREAD_ATTRIB_AFFINITY_ANY))
{
free(stack);
return false;
}
OSSetThreadName(&net_compat_thread, "Network compat thread");
OSSetThreadDeallocator(&net_compat_thread, _net_compat_thread_cleanup);
OSResumeThread(&net_compat_thread);
initialized = true;
}
return true;
#elif defined(_3DS)
static bool initialized = false;
if (!initialized)
{
u32 *net_compat_memory = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
if (!net_compat_memory)
return false;
/* WIFI init */
if (socInit(net_compat_memory, SOC_BUFFERSIZE))
{
socExit();
free(net_compat_memory);
return false;
}
initialized = true;
}
return true;
#else
static bool initialized = false;
if (!initialized)
{
/* Do not like SIGPIPE killing our app. */
signal(SIGPIPE, SIG_IGN);
initialized = true;
}
return true;
#endif
} }

View File

@ -133,7 +133,7 @@ bool net_ifinfo_new(net_ifinfo_t *list)
do do
{ {
if (getnameinfo(unicast_addr->Address.lpSockaddr, if (getnameinfo_retro(unicast_addr->Address.lpSockaddr,
unicast_addr->Address.iSockaddrLength, unicast_addr->Address.iSockaddrLength,
entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST)) entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST))
continue; continue;
@ -304,7 +304,7 @@ failure:
continue; continue;
} }
if (getnameinfo(addr->ifa_addr, addrlen, if (getnameinfo_retro(addr->ifa_addr, addrlen,
entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST)) entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST))
continue; continue;

View File

@ -68,6 +68,7 @@ int socket_init(void **address, uint16_t port, const char *server,
return -1; return -1;
snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
hints.ai_flags |= AI_NUMERICSERV;
if (getaddrinfo_retro(server, port_buf, &hints, addrinfo)) if (getaddrinfo_retro(server, port_buf, &hints, addrinfo))
return -1; return -1;
@ -686,7 +687,7 @@ int socket_connect(int fd, void *data, bool timeout_enable)
int sendsz = WIIU_SNDBUF; int sendsz = WIIU_SNDBUF;
setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op)); setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op));
setsockopt(fd, SOL_SOCKET, 0x10000, &op, sizeof(op)); setsockopt(fd, SOL_SOCKET, SO_RUSRBUF, &op, sizeof(op));
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz)); setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz));
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz)); setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz));
} }
@ -716,7 +717,7 @@ bool socket_connect_with_timeout(int fd, void *data, int timeout)
int sendsz = WIIU_SNDBUF; int sendsz = WIIU_SNDBUF;
setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op)); setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op));
setsockopt(fd, SOL_SOCKET, 0x10000, &op, sizeof(op)); setsockopt(fd, SOL_SOCKET, SO_RUSRBUF, &op, sizeof(op));
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz)); setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz));
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz)); setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz));
} }
@ -809,6 +810,9 @@ void socket_set_target(void *data, socket_target_t *in_addr)
{ {
struct sockaddr_in *out_target = (struct sockaddr_in*)data; struct sockaddr_in *out_target = (struct sockaddr_in*)data;
#ifdef GEKKO
out_target->sin_len = 8;
#endif
switch (in_addr->domain) switch (in_addr->domain)
{ {
case SOCKET_DOMAIN_INET: case SOCKET_DOMAIN_INET:
@ -818,13 +822,6 @@ void socket_set_target(void *data, socket_target_t *in_addr)
out_target->sin_family = 0; out_target->sin_family = 0;
break; break;
} }
#ifndef VITA out_target->sin_port = htons(in_addr->port);
#ifdef GEKKO inet_pton(AF_INET, in_addr->server, &out_target->sin_addr);
out_target->sin_len = 8;
#endif
inet_ptrton(AF_INET, in_addr->server, &out_target->sin_addr);
#else
out_target->sin_addr = inet_aton(in_addr->server);
#endif
out_target->sin_port = inet_htons(in_addr->port);
} }

View File

@ -52,7 +52,5 @@ int main(void)
net_http_delete(http1); net_http_delete(http1);
net_http_delete(http3); net_http_delete(http3);
network_deinit();
return 0; return 0;
} }

View File

@ -30,41 +30,6 @@
#include "natt.h" #include "natt.h"
static bool translate_addr(struct sockaddr_in *addr,
char *host, size_t hostlen, char *port, size_t portlen)
{
#ifndef HAVE_SOCKET_LEGACY
if (getnameinfo((struct sockaddr *) addr, sizeof(*addr),
host, hostlen, port, portlen,
NI_NUMERICHOST | NI_NUMERICSERV))
return false;
#else
/* We need to do the conversion/translation manually. */
{
int res;
uint8_t *addr8 = (uint8_t *) &addr->sin_addr;
uint16_t port16 = ntohs(addr->sin_port);
if (host)
{
res = snprintf(host, hostlen, "%d.%d.%d.%d",
(int) addr8[0], (int) addr8[1],
(int) addr8[2], (int) addr8[3]);
if (res < 0 || res >= hostlen)
return false;
}
if (port)
{
res = snprintf(port, portlen, "%hu", port16);
if (res < 0 || res >= portlen)
return false;
}
}
#endif
return true;
}
bool natt_init(struct natt_discovery *discovery) bool natt_init(struct natt_discovery *discovery)
{ {
static const char msearch[] = static const char msearch[] =
@ -85,6 +50,7 @@ bool natt_init(struct natt_discovery *discovery)
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM; hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
if (getaddrinfo_retro("239.255.255.250", "1900", &hints, &msearch_addr)) if (getaddrinfo_retro("239.255.255.250", "1900", &hints, &msearch_addr))
goto failure; goto failure;
if (!msearch_addr) if (!msearch_addr)
@ -429,6 +395,7 @@ static bool parse_external_address_node(rxml_node_t *node,
return false; return false;
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
if (getaddrinfo_retro(node->data, "0", &hints, &addr)) if (getaddrinfo_retro(node->data, "0", &hints, &addr))
return false; return false;
if (!addr) if (!addr)
@ -702,8 +669,9 @@ bool natt_open_port(struct natt_device *device,
if (!request->addr.sin_port) if (!request->addr.sin_port)
return false; return false;
if (!translate_addr(&request->addr, if (getnameinfo_retro((struct sockaddr*)&request->addr,
host, sizeof(host), port, sizeof(port))) sizeof(request->addr), host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV))
return false; return false;
action = (forward_type == NATT_FORWARD_TYPE_ANY) ? action = (forward_type == NATT_FORWARD_TYPE_ANY) ?
@ -759,8 +727,8 @@ bool natt_close_port(struct natt_device *device,
if (!request->addr.sin_port) if (!request->addr.sin_port)
return false; return false;
if (!translate_addr(&request->addr, if (getnameinfo_retro((struct sockaddr*)&request->addr,
NULL, 0, port, sizeof(port))) sizeof(request->addr), NULL, 0, port, sizeof(port), NI_NUMERICSERV))
return false; return false;
protocol = (request->proto == SOCKET_PROTOCOL_UDP) ? protocol = (request->proto == SOCKET_PROTOCOL_UDP) ?

View File

@ -76,9 +76,7 @@ void logger_init(void)
void logger_shutdown(void) void logger_shutdown(void)
{ {
if (socket_close(g_sid) < 0) { } socket_close(g_sid);
network_deinit();
} }
void logger_send(const char *__format,...) void logger_send(const char *__format,...)

View File

@ -280,6 +280,7 @@ static bool netplay_lan_ad_client_query(void)
snprintf(port, sizeof(port), "%hu", (unsigned short)RARCH_DISCOVERY_PORT); snprintf(port, sizeof(port), "%hu", (unsigned short)RARCH_DISCOVERY_PORT);
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM; hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
if (getaddrinfo_retro("255.255.255.255", port, &hints, &addr)) if (getaddrinfo_retro("255.255.255.255", port, &hints, &addr))
return ret; return ret;
if (!addr) if (!addr)
@ -337,20 +338,9 @@ static bool netplay_lan_ad_client_response(void)
if (!netplay_is_lan_address((struct sockaddr_in*)&their_addr)) if (!netplay_is_lan_address((struct sockaddr_in*)&their_addr))
continue; continue;
#ifndef HAVE_SOCKET_LEGACY if (getnameinfo_retro((struct sockaddr*)&their_addr, sizeof(their_addr),
if (getnameinfo((struct sockaddr*)&their_addr, sizeof(their_addr),
address, sizeof(address), NULL, 0, NI_NUMERICHOST)) address, sizeof(address), NULL, 0, NI_NUMERICHOST))
continue; continue;
#else
/* We need to convert the address manually */
{
uint8_t *addr8 =
(uint8_t*)&((struct sockaddr_in*)&their_addr)->sin_addr;
snprintf(address, sizeof(address), "%d.%d.%d.%d",
(int)addr8[0], (int)addr8[1], (int)addr8[2], (int)addr8[3]);
}
#endif
/* Allocate space for it */ /* Allocate space for it */
if (net_st->discovered_hosts.size >= net_st->discovered_hosts.allocated) if (net_st->discovered_hosts.size >= net_st->discovered_hosts.allocated)
@ -6552,47 +6542,35 @@ static void netplay_handle_slaves(netplay_t *netplay)
static void netplay_announce_nat_traversal(netplay_t *netplay, static void netplay_announce_nat_traversal(netplay_t *netplay,
uint16_t ext_port) uint16_t ext_port)
{ {
char msg[512];
const char *dmsg = NULL;
net_driver_state_t *net_st = &networking_driver_st; net_driver_state_t *net_st = &networking_driver_st;
if (net_st->nat_traversal_request.status == NAT_TRAVERSAL_STATUS_OPENED) if (net_st->nat_traversal_request.status == NAT_TRAVERSAL_STATUS_OPENED)
{ {
char msg[512];
char host[256], port[6]; char host[256], port[6];
netplay->ext_tcp_port = ext_port; netplay->ext_tcp_port = ext_port;
#ifndef HAVE_SOCKET_LEGACY if (!getnameinfo_retro(
if (!getnameinfo(
(struct sockaddr*)&net_st->nat_traversal_request.request.addr, (struct sockaddr*)&net_st->nat_traversal_request.request.addr,
sizeof(net_st->nat_traversal_request.request.addr), sizeof(net_st->nat_traversal_request.request.addr),
host, sizeof(host), port, sizeof(port), host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV)) NI_NUMERICHOST | NI_NUMERICSERV))
#else
{
uint8_t *addr8 =
(uint8_t*)&net_st->nat_traversal_request.request.addr.sin_addr;
uint16_t port16 =
ntohs(net_st->nat_traversal_request.request.addr.sin_port);
snprintf(host, sizeof(host), "%d.%d.%d.%d",
(int)addr8[0], (int)addr8[1], (int)addr8[2], (int)addr8[3]);
snprintf(port, sizeof(port), "%hu", (unsigned short)port16);
}
#endif
{
snprintf(msg, sizeof(msg), "%s: %s:%s", snprintf(msg, sizeof(msg), "%s: %s:%s",
msg_hash_to_str(MSG_PUBLIC_ADDRESS), host, port); msg_hash_to_str(MSG_PUBLIC_ADDRESS), host, port);
dmsg = msg; else
} strlcpy(msg, msg_hash_to_str(MSG_PUBLIC_ADDRESS), sizeof(msg));
RARCH_LOG("[Netplay] %s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
} }
else else
dmsg = msg_hash_to_str(MSG_UPNP_FAILED);
if (dmsg)
{ {
RARCH_LOG("[Netplay] %s\n", dmsg); const char *msg = msg_hash_to_str(MSG_UPNP_FAILED);
runloop_msg_queue_push(dmsg, 1, 180, false, NULL,
RARCH_ERR("[Netplay] %s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
} }
} }
@ -6620,10 +6598,8 @@ static void netplay_deinit_nat_traversal(void)
static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr, static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
bool is_server, bool is_mitm) bool is_server, bool is_mitm)
{ {
#ifndef HAVE_SOCKET_LEGACY
char msg[512]; char msg[512];
char host[256], port[6]; char host[256], port[6];
#endif
const char *dmsg = NULL; const char *dmsg = NULL;
int fd = socket(addr->ai_family, addr->ai_socktype, int fd = socket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol); addr->ai_protocol);
@ -6647,8 +6623,7 @@ static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
return fd; return fd;
} }
#ifndef HAVE_SOCKET_LEGACY if (!getnameinfo_retro(addr->ai_addr, addr->ai_addrlen,
if (!getnameinfo(addr->ai_addr, addr->ai_addrlen,
host, sizeof(host), port, sizeof(port), host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV)) NI_NUMERICHOST | NI_NUMERICSERV))
{ {
@ -6658,7 +6633,6 @@ static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
dmsg = msg; dmsg = msg;
} }
else else
#endif
dmsg = "Failed to connect to host."; dmsg = "Failed to connect to host.";
} }
else if (is_mitm) else if (is_mitm)
@ -6703,8 +6677,7 @@ static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
} }
else else
{ {
#ifndef HAVE_SOCKET_LEGACY if (!getnameinfo_retro(addr->ai_addr, addr->ai_addrlen,
if (!getnameinfo(addr->ai_addr, addr->ai_addrlen,
host, sizeof(host), port, sizeof(port), host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV)) NI_NUMERICHOST | NI_NUMERICSERV))
{ {
@ -6714,19 +6687,19 @@ static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
dmsg = msg; dmsg = msg;
} }
else else
#endif
dmsg = "Failed to connect to relay server."; dmsg = "Failed to connect to relay server.";
} }
} }
else else
{ {
#if defined(HAVE_INET6) && defined(IPV6_V6ONLY) #if defined(HAVE_INET6) && defined(IPV6_V6ONLY)
/* Make sure we accept connections on both IPv6 and IPv4 */ /* Make sure we accept connections on both IPv6 and IPv4. */
if (addr->ai_family == AF_INET6) if (addr->ai_family == AF_INET6)
{ {
int on = 0; int on = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
(const char*) &on, sizeof(on)) < 0) (const char*)&on, sizeof(on)) < 0)
RARCH_WARN("[Netplay] Failed to listen on both IPv6 and IPv4.\n"); RARCH_WARN("[Netplay] Failed to listen on both IPv6 and IPv4.\n");
} }
#endif #endif
@ -6738,8 +6711,7 @@ static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
} }
else else
{ {
#ifndef HAVE_SOCKET_LEGACY if (!getnameinfo_retro(addr->ai_addr, addr->ai_addrlen,
if (!getnameinfo(addr->ai_addr, addr->ai_addrlen,
NULL, 0, port, sizeof(port), NI_NUMERICSERV)) NULL, 0, port, sizeof(port), NI_NUMERICSERV))
{ {
snprintf(msg, sizeof(msg), snprintf(msg, sizeof(msg),
@ -6748,7 +6720,6 @@ static int init_tcp_connection(netplay_t *netplay, const struct addrinfo *addr,
dmsg = msg; dmsg = msg;
} }
else else
#endif
dmsg = "Failed to bind port."; dmsg = "Failed to bind port.";
} }
} }
@ -6794,7 +6765,8 @@ static bool init_tcp_socket(netplay_t *netplay,
} }
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
snprintf(port_buf, sizeof(port_buf), "%hu", port); snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
hints.ai_flags |= AI_NUMERICSERV;
if (getaddrinfo_retro(is_mitm ? mitm : server, port_buf, if (getaddrinfo_retro(is_mitm ? mitm : server, port_buf,
&hints, &addr)) &hints, &addr))

View File

@ -59,6 +59,7 @@ static bool find_local_address(struct natt_device *device,
goto done; goto done;
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_flags = AI_NUMERICHOST;
/* Score interfaces based on how "close" their address /* Score interfaces based on how "close" their address
is from the device's address. */ is from the device's address. */

View File

@ -9,13 +9,36 @@ extern "C" {
typedef uint32_t socklen_t; typedef uint32_t socklen_t;
#define NI_NUMERICHOST 2 #define AI_PASSIVE 1
#define NI_NUMERICSERV 8 #define AI_CANONNAME 2
#define AI_NUMERICHOST 4
#define AI_NUMERICSERV 8
#define AI_PASSIVE 1 #define NI_MAXHOST 1025
#define NI_MAXSERV 32
#define NI_MAXHOST 1025 #define NI_NOFQDN 1
#define NI_MAXSERV 32 #define NI_NUMERICHOST 2
#define NI_NAMEREQD 4
#define NI_NUMERICSERV 8
#define NI_DGRAM 16
#define EAI_ADDRFAMILY 1
#define EAI_AGAIN 2
#define EAI_BADFLAGS 3
#define EAI_FAIL 4
#define EAI_FAMILY 5
#define EAI_MEMORY 6
#define EAI_NODATA 7
#define EAI_NONAME 8
#define EAI_SERVICE 9
#define EAI_SOCKTYPE 10
#define EAI_SYSTEM 11
#define EAI_BADHINTS 12
#define EAI_PROTOCOL 13
#define EAI_OVERFLOW 14
#define EAI_INPROGRESS 15
#define EAI_MAX 16
struct addrinfo { struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, int ai_flags; /* AI_PASSIVE, AI_CANONNAME,

View File

@ -11,6 +11,8 @@ extern "C" {
#define INADDR_ANY 0 #define INADDR_ANY 0
#define PF_UNSPEC 0
#define PF_INET 2
#define AF_UNSPEC 0 #define AF_UNSPEC 0
#define AF_INET 2 #define AF_INET 2
@ -20,20 +22,64 @@ extern "C" {
#define MSG_DONTWAIT 0x0020 #define MSG_DONTWAIT 0x0020
/* #define MSG_DONTWAIT 0x0004 */ /* #define MSG_DONTWAIT 0x0004 */
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#define SO_REUSEADDR 0x0004 #define SO_REUSEADDR 0x0004
#define SO_WINSCALE 0x0400 #define SO_KEEPALIVE 0x0008
#define SO_BROADCAST 0x0020
#define SO_TCPSACK 0x0200 #define SO_TCPSACK 0x0200
#define SO_WINSCALE 0x0400
#define SO_SNDBUF 0x1001 #define SO_SNDBUF 0x1001
#define SO_RCVBUF 0x1002 #define SO_RCVBUF 0x1002
#define SO_NBIO 0x1014 #define SO_NBIO 0x1014
#define SO_BIO 0x1015
#define SO_NONBLOCK 0x1016 #define SO_NONBLOCK 0x1016
#define SO_RUSRBUF 0x10000
/* return codes */ #define SO_SUCCESS 0
#define SO_SUCCESS 0 #define SO_ENOBUFS 1
#define SO_ETIMEDOUT 2
#define SO_EISCONN 3
#define SO_EWOULDBLOCK 6 #define SO_EOPNOTSUPP 4
#define SO_EINVAL 11 #define SO_ECONNABORTED 5
#define SO_EWOULDBLOCK 6
#define SO_ECONNREFUSED 7
#define SO_ECONNRESET 8
#define SO_ENOTCONN 9
#define SO_EALREADY 10
#define SO_EINVAL 11
#define SO_EMSGSIZE 12
#define SO_EPIPE 13
#define SO_EDESTADDRREQ 14
#define SO_ESHUTDOWN 15
#define SO_ENOPROTOOPT 16
#define SO_EHAVEOOB 17
#define SO_ENOMEM 18
#define SO_EADDRNOTAVAIL 19
#define SO_EADDRINUSE 20
#define SO_EAFNOSUPPORT 21
#define SO_EINPROGRESS 22
#define SO_ELOWER 23
#define SO_ENOTSOCK 24
#define SO_EIEIO 27
#define SO_ETOOMANYREFS 28
#define SO_EFAULT 29
#define SO_ENETUNREACH 30
#define SO_EPROTONOSUPPORT 31
#define SO_EPROTOTYPE 32
#define SO_ERROR 41
#define SO_ENOLIBRM 42
#define SO_ELIBNOTREADY 43
#define SO_EBUSY 44
#define SO_EUNKNOWN 45
#define SO_EAPIERROR 46
#define SO_ERANGEINVALID 47
#define SO_ENORESOURCES 48
#define SO_EBADFD 49
#define SO_EABORTED 50
#define SO_EMFILE 51
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
#undef EWOULDBLOCK #undef EWOULDBLOCK
@ -43,9 +89,13 @@ extern "C" {
#undef EAGAIN #undef EAGAIN
#endif #endif
#ifdef EINPROGRESS
#undef EINPROGRESS
#endif
#define EWOULDBLOCK SO_EWOULDBLOCK #define EWOULDBLOCK SO_EWOULDBLOCK
#define EAGAIN SO_EWOULDBLOCK #define EAGAIN SO_EWOULDBLOCK
#define ENOBUFS 105 /* No buffer space available */ #define EINPROGRESS SO_EINPROGRESS
typedef uint32_t socklen_t; typedef uint32_t socklen_t;
typedef uint16_t sa_family_t; typedef uint16_t sa_family_t;