diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index a7bf1e7508..fa022808d2 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -35,6 +35,10 @@ #include +#if !defined(HAVE_SOCKET_LEGACY) && defined(_WIN32) && defined(IP_MULTICAST_IF) +#include +#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 diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 25fe571067..c91b03438f 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -41,6 +41,10 @@ #include #include +#if defined(_WIN32) && defined(IP_MULTICAST_IF) +#include +#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&"