[Networking] GetBestRoute refactor (#13553)

Refactor to support UWP.
This commit is contained in:
Cthulhu-throwaway 2022-01-27 07:38:31 -03:00 committed by GitHub
parent d9a4dc52c0
commit cd74221d33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 111 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010-2020 The RetroArch team
/* Copyright (C) 2010-2022 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (net_ifinfo.h).
@ -50,6 +50,8 @@ void net_ifinfo_free(net_ifinfo_t *list);
bool net_ifinfo_new(net_ifinfo_t *list);
bool net_ifinfo_best(const char *dst, void *src, bool ipv6);
RETRO_END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010-2020 The RetroArch team
/* Copyright (C) 2010-2022 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (net_ifinfo.c).
@ -27,6 +27,10 @@
#include <retro_miscellaneous.h>
#if defined(_WIN32) && !defined(_XBOX)
#ifdef _MSC_VER
#pragma comment(lib, "Iphlpapi")
#endif
#include <winsock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
@ -256,3 +260,94 @@ error:
return false;
}
bool net_ifinfo_best(const char *dst, void *src, bool ipv6)
{
bool ret = false;
/* TODO/FIXME: Implement for other platforms, if necessary. */
#if defined(_WIN32) && !defined(_XBOX)
if (!ipv6)
{
/* Courtesy of MiniUPnP: https://github.com/miniupnp/miniupnp */
DWORD index;
unsigned long udst = inet_addr(dst);
#ifdef __WINRT__
struct sockaddr_in addr_dst = {0};
#endif
if (udst == INADDR_NONE || udst == INADDR_ANY)
return ret;
if (!src)
return ret;
#ifdef __WINRT__
addr_dst.sin_family = AF_INET;
addr_dst.sin_addr.s_addr = udst;
if (GetBestInterfaceEx((struct sockaddr *) &addr_dst, &index)
== NO_ERROR)
#else
if (GetBestInterface(udst, &index) == NO_ERROR)
#endif
{
/* Microsoft docs recommend doing it this way. */
ULONG len = 15 * 1024;
PIP_ADAPTER_ADDRESSES addresses = calloc(1, len);
if (addresses)
{
ULONG flags = GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER |
GAA_FLAG_SKIP_FRIENDLY_NAME;
ULONG result = GetAdaptersAddresses(AF_INET, flags, NULL,
addresses, &len);
if (result == ERROR_BUFFER_OVERFLOW)
{
PIP_ADAPTER_ADDRESSES new_addresses = realloc(addresses, len);
if (new_addresses)
{
memset(new_addresses, 0, len);
addresses = new_addresses;
result = GetAdaptersAddresses(AF_INET, flags, NULL,
addresses, &len);
}
}
if (result == NO_ERROR)
{
PIP_ADAPTER_ADDRESSES addr = addresses;
do
{
if (addr->IfIndex == index)
{
if (addr->FirstUnicastAddress)
{
struct sockaddr_in *addr_unicast =
(struct sockaddr_in *)
addr->FirstUnicastAddress->Address.lpSockaddr;
memcpy(src, &addr_unicast->sin_addr,
sizeof(addr_unicast->sin_addr));
ret = true;
}
break;
}
} while ((addr = addr->Next));
}
free(addresses);
}
}
}
#endif
return ret;
}

View File

@ -20,10 +20,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if defined(_WIN32) && !defined(__WINRT__) && defined(_MSC_VER)
#pragma comment(lib, "Iphlpapi")
#endif
#include <stdlib.h>
#include <stdio.h>
@ -33,14 +29,14 @@
#include <string/stdstring.h>
#ifndef HAVE_SOCKET_LEGACY
#include <net/net_ifinfo.h>
#endif
#include "../../tasks/tasks_internal.h"
#include <net/net_natt.h>
#if defined(_WIN32) && !defined(__WINRT__)
#include <iphlpapi.h>
#endif
static bool translate_addr(struct sockaddr_in *addr,
char *host, size_t hostlen, char *port, size_t portlen)
{
@ -85,9 +81,6 @@ bool natt_init(struct natt_discovery *discovery)
"ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
"MX: 5\r\n"
"\r\n";
#if defined(_WIN32) && !defined(__WINRT__)
MIB_IPFORWARDROW ip_forward;
#endif
bool ret;
int fd = -1;
struct addrinfo *msearch_addr = NULL;
@ -110,51 +103,16 @@ bool natt_init(struct natt_discovery *discovery)
if (!bind_addr)
goto failure;
#if defined(_WIN32) && !defined(__WINRT__)
if (GetBestRoute(inet_addr("223.255.255.255"),
0, &ip_forward) == NO_ERROR)
#ifndef HAVE_SOCKET_LEGACY
{
DWORD index = ip_forward.dwForwardIfIndex;
PMIB_IPADDRTABLE table = malloc(sizeof(*table));
struct sockaddr_in *addr = (struct sockaddr_in *) bind_addr->ai_addr;
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)
if (net_ifinfo_best("223.255.255.255", &addr->sin_addr, false))
{
#ifdef IP_MULTICAST_IF
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char *) &ip_addr->dwAddr, sizeof(ip_addr->dwAddr));
(const char *) &addr->sin_addr, sizeof(addr->sin_addr));
#endif
((struct sockaddr_in *) bind_addr->ai_addr)->sin_addr.s_addr =
ip_addr->dwAddr;
break;
}
}
}
free(table);
}
}
#endif

View File

@ -2,7 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2021 - Daniel De Matteis
* Copyright (C) 2016-2017 - Gregor Richards
* Copyright (C) 2021-2021 - Roberto V. Rampim
* Copyright (C) 2021-2022 - Roberto V. Rampim
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -20,10 +20,6 @@
#pragma comment(lib, "ws2_32")
#endif
#if defined(_WIN32) && !defined(__WINRT__) && defined(_MSC_VER)
#pragma comment(lib, "Iphlpapi")
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@ -41,14 +37,14 @@
#include <lrc_hash.h>
#include <retro_timers.h>
#ifndef HAVE_SOCKET_LEGACY
#include <net/net_ifinfo.h>
#endif
#include <math/float_minmax.h>
#include <string/stdstring.h>
#include <file/file_path.h>
#if defined(_WIN32) && !defined(__WINRT__)
#include <iphlpapi.h>
#endif
#ifdef HAVE_DISCORD
#include "../discord.h"
#endif
@ -247,55 +243,9 @@ bool init_netplay_discovery(void)
if (ret)
{
#if defined(_WIN32) && !defined(__WINRT__)
MIB_IPFORWARDROW ip_forward;
if (GetBestRoute(inet_addr("223.255.255.255"),
0, &ip_forward) == NO_ERROR)
{
DWORD index = ip_forward.dwForwardIfIndex;
PMIB_IPADDRTABLE table = malloc(sizeof(*table));
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)
{
#ifdef IP_MULTICAST_IF
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char *) &ip_addr->dwAddr, sizeof(ip_addr->dwAddr));
#endif
((struct sockaddr_in *) addr->ai_addr)->sin_addr.s_addr =
ip_addr->dwAddr;
break;
}
}
}
free(table);
}
}
#ifndef HAVE_SOCKET_LEGACY
net_ifinfo_best("223.255.255.255",
&((struct sockaddr_in *) addr->ai_addr)->sin_addr, false);
#endif
#ifdef SO_BROADCAST