(Netplay) Add a private or CGNAT address warning to UPnP (#14461)

This commit is contained in:
Cthulhu-throwaway 2022-10-02 20:18:34 -03:00 committed by GitHub
parent 5627a09e0d
commit daf8cb9bc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 34 deletions

View File

@ -11659,6 +11659,10 @@ MSG_HASH(
MSG_PUBLIC_ADDRESS,
"Netplay Port Mapping Successful"
)
MSG_HASH(
MSG_PRIVATE_OR_SHARED_ADDRESS,
"External network has a private or shared address. Consider using a relay server."
)
MSG_HASH(
MSG_UPNP_FAILED,
"Netplay UPnP Port Mapping Failed"

View File

@ -395,6 +395,9 @@ int getnameinfo_retro(const struct sockaddr *addr, socklen_t addrlen,
bool addr_6to4(struct sockaddr_storage *addr);
bool ipv4_is_lan_address(struct sockaddr_in *addr);
bool ipv4_is_cgnat_address(struct sockaddr_in *addr);
/**
* network_init:
*

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include <compat/strl.h>
#include <retro_miscellaneous.h>
#include <retro_timers.h>
#include <net/net_compat.h>
@ -422,6 +423,35 @@ bool addr_6to4(struct sockaddr_storage *addr)
return true;
}
bool ipv4_is_lan_address(struct sockaddr_in *addr)
{
static const uint32_t subnets[] = {0x0A000000, 0xAC100000, 0xC0A80000};
static const uint32_t masks[] = {0xFF000000, 0xFFF00000, 0xFFFF0000};
size_t i;
uint32_t uaddr;
memcpy(&uaddr, &addr->sin_addr, sizeof(uaddr));
uaddr = ntohl(uaddr);
for (i = 0; i < ARRAY_SIZE(subnets); i++)
if ((uaddr & masks[i]) == subnets[i])
return true;
return false;
}
bool ipv4_is_cgnat_address(struct sockaddr_in *addr)
{
static const uint32_t subnet = 0x64400000;
static const uint32_t mask = 0xFFC00000;
uint32_t uaddr;
memcpy(&uaddr, &addr->sin_addr, sizeof(uaddr));
uaddr = ntohl(uaddr);
return (uaddr & mask) == subnet;
}
/**
* network_init:
*

View File

@ -277,6 +277,7 @@ enum msg_hash_enums
MSG_GOT_CONNECTION_FROM_NAME,
MSG_CONNECTION_SLOT,
MSG_PUBLIC_ADDRESS,
MSG_PRIVATE_OR_SHARED_ADDRESS,
MSG_UPNP_FAILED,
MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,
MSG_CANNOT_INFER_NEW_CONFIG_PATH,

View File

@ -285,7 +285,6 @@ net_driver_state_t *networking_state_get_ptr(void);
bool netplay_compatible_version(const char *version);
bool netplay_decode_hostname(const char *hostname,
char *address, unsigned *port, char *session, size_t len);
bool netplay_is_lan_address(struct sockaddr_in *addr);
int netplay_rooms_parse(const char *buf, size_t len);
int netplay_rooms_get_count(void);

View File

@ -331,7 +331,7 @@ static bool netplay_lan_ad_client_response(void)
if (!addr_6to4(&their_addr))
continue;
if (!netplay_is_lan_address((struct sockaddr_in*)&their_addr))
if (!ipv4_is_lan_address((struct sockaddr_in*)&their_addr))
continue;
if (getnameinfo_retro((struct sockaddr*)&their_addr, sizeof(their_addr),
@ -530,7 +530,7 @@ static bool netplay_lan_ad_server(netplay_t *netplay)
if (!addr_6to4(&their_addr))
return true;
if (!netplay_is_lan_address((struct sockaddr_in*)&their_addr))
if (!ipv4_is_lan_address((struct sockaddr_in*)&their_addr))
return true;
RARCH_LOG("[Discovery] Query received on LAN interface.\n");
@ -6420,24 +6420,35 @@ static void netplay_announce_nat_traversal(netplay_t *netplay,
if (net_st->nat_traversal_request.status == NAT_TRAVERSAL_STATUS_OPENED)
{
char msg[512];
char host[256], port[6];
struct sockaddr_in *addr = &net_st->nat_traversal_request.request.addr;
netplay->ext_tcp_port = ext_port;
if (!getnameinfo_retro(
(struct sockaddr*)&net_st->nat_traversal_request.request.addr,
sizeof(net_st->nat_traversal_request.request.addr),
host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV))
snprintf(msg, sizeof(msg), "%s: %s:%s",
msg_hash_to_str(MSG_PUBLIC_ADDRESS), host, port);
else
strlcpy(msg, msg_hash_to_str(MSG_PUBLIC_ADDRESS), sizeof(msg));
if (!ipv4_is_cgnat_address(addr) && !ipv4_is_lan_address(addr))
{
char msg[512];
char host[256], port[6];
RARCH_LOG("[Netplay] %s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
if (!getnameinfo_retro((struct sockaddr*)addr, sizeof(*addr),
host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV))
snprintf(msg, sizeof(msg), "%s: %s:%s",
msg_hash_to_str(MSG_PUBLIC_ADDRESS), host, port);
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
{
const char *msg = msg_hash_to_str(MSG_PRIVATE_OR_SHARED_ADDRESS);
RARCH_WARN("[Netplay] %s\n", msg);
runloop_msg_queue_push(msg, 1, 600, false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
}
}
else
{
@ -9124,23 +9135,6 @@ bool netplay_decode_hostname(const char *hostname,
return true;
}
bool netplay_is_lan_address(struct sockaddr_in *addr)
{
static const uint32_t subnets[] = {0x0A000000, 0xAC100000, 0xC0A80000};
static const uint32_t masks[] = {0xFF000000, 0xFFF00000, 0xFFFF0000};
size_t i;
uint32_t uaddr;
memcpy(&uaddr, &addr->sin_addr, sizeof(uaddr));
uaddr = ntohl(uaddr);
for (i = 0; i < ARRAY_SIZE(subnets); i++)
if ((uaddr & masks[i]) == subnets[i])
return true;
return false;
}
/* Netplay Widgets */
#ifdef HAVE_GFX_WIDGETS