NAT and netplay Fixes (#13400)

* NAT and netplay Fixes

Fix a crash when announcing your room to the internet without being in a tunnel.

Fix improper interface for UPnP for some Windows devices.

* Final edits
This commit is contained in:
Cthulhu-throwaway 2021-12-23 17:28:30 -03:00 committed by GitHub
parent e0ad9f7e26
commit c4049b9597
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 5 deletions

View File

@ -35,6 +35,10 @@
#include <net/net_natt.h>
#if !defined(HAVE_SOCKET_LEGACY) && defined(_WIN32) && defined(IP_MULTICAST_IF)
#include <iphlpapi.h>
#endif
static natt_state_t natt_st = {{0}, {{0}}, 0, -1};
natt_state_t *natt_state_get_ptr(void)
@ -52,6 +56,9 @@ bool natt_init(void)
"MX: 2\r\n"
"ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n";
static struct sockaddr_in msearch_addr = {0};
#if defined(_WIN32) && defined(IP_MULTICAST_IF)
MIB_IPFORWARDROW ip_forward;
#endif
natt_state_t *st = &natt_st;
struct addrinfo *bind_addr = NULL;
@ -81,6 +88,52 @@ bool natt_init(void)
if (!bind_addr)
goto failure;
#if defined(_WIN32) && defined(IP_MULTICAST_IF)
if (GetBestRoute(0xDFFFFFFF, 0, &ip_forward) == NO_ERROR)
{
IF_INDEX index = ip_forward.dwForwardIfIndex;
PMIB_IPADDRTABLE table = malloc(sizeof(MIB_IPADDRTABLE));
if (table)
{
DWORD len = sizeof(*table);
DWORD result = GetIpAddrTable(table, &len, FALSE);
if (result == ERROR_INSUFFICIENT_BUFFER)
{
PMIB_IPADDRTABLE new_table = realloc(table, len);
if (new_table)
{
table = new_table;
result = GetIpAddrTable(table, &len, FALSE);
}
}
if (result == NO_ERROR)
{
DWORD i;
for (i = 0; i < table->dwNumEntries; i++)
{
PMIB_IPADDRROW ip_addr = &table->table[i];
if (ip_addr->dwIndex == index)
{
setsockopt(st->fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char *) &ip_addr->dwAddr, sizeof(ip_addr->dwAddr));
((struct sockaddr_in *) bind_addr->ai_addr)->sin_addr.s_addr =
ip_addr->dwAddr;
break;
}
}
}
free(table);
}
}
#endif
#ifdef IP_MULTICAST_TTL
{
#ifdef _WIN32

View File

@ -41,6 +41,10 @@
#include <string/stdstring.h>
#include <file/file_path.h>
#if defined(_WIN32) && defined(IP_MULTICAST_IF)
#include <iphlpapi.h>
#endif
#ifdef HAVE_DISCORD
#include "../discord.h"
#endif
@ -240,14 +244,71 @@ bool init_netplay_discovery(void)
if (ret)
{
#if defined(_WIN32) && defined(IP_MULTICAST_IF)
MIB_IPFORWARDROW ip_forward;
if (GetBestRoute(0xDFFFFFFF, 0, &ip_forward) == NO_ERROR)
{
IF_INDEX index = ip_forward.dwForwardIfIndex;
PMIB_IPADDRTABLE table = malloc(sizeof(MIB_IPADDRTABLE));
if (table)
{
DWORD len = sizeof(*table);
DWORD result = GetIpAddrTable(table, &len, FALSE);
if (result == ERROR_INSUFFICIENT_BUFFER)
{
PMIB_IPADDRTABLE new_table = realloc(table, len);
if (new_table)
{
table = new_table;
result = GetIpAddrTable(table, &len, FALSE);
}
}
if (result == NO_ERROR)
{
DWORD i;
for (i = 0; i < table->dwNumEntries; i++)
{
PMIB_IPADDRROW ip_addr = &table->table[i];
if (ip_addr->dwIndex == index)
{
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char *) &ip_addr->dwAddr, sizeof(ip_addr->dwAddr));
((struct sockaddr_in *) addr->ai_addr)->sin_addr.s_addr =
ip_addr->dwAddr;
break;
}
}
}
free(table);
}
}
#endif
#if defined(SOL_SOCKET) && defined(SO_BROADCAST)
/* Make it broadcastable */
int broadcast = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
(const char *) &broadcast, sizeof(broadcast)) < 0)
RARCH_WARN("[Discovery] Failed to set netplay discovery port to broadcast.\n");
{
int broadcast = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
(const char *) &broadcast, sizeof(broadcast)) < 0)
RARCH_WARN("[Discovery] Failed to set netplay discovery port to broadcast.\n");
}
#endif
if (!socket_bind(fd, addr))
{
socket_close(fd);
net_st->lan_ad_client_fd = -1;
return false;
}
net_st->lan_ad_client_fd = fd;
}
else
@ -7854,7 +7915,7 @@ static void netplay_announce(netplay_t *netplay)
char *gamename = NULL;
char *subsystemname = NULL;
char *frontend_ident = NULL;
char *mitm_session = "";
char *mitm_session = NULL;
const char *mitm_custom_addr = "";
int mitm_custom_port = 0;
int is_mitm = 0;
@ -7929,6 +7990,10 @@ static void netplay_announce(netplay_t *netplay)
mitm_custom_port = host_room->mitm_port;
}
}
else
{
net_http_urlencode(&mitm_session, "");
}
snprintf(buf, sizeof(buf),
"username=%s&"