Merge pull request #5715 from fr500/master

Fix lan rooms
This commit is contained in:
Twinaphex 2017-11-19 17:01:20 +01:00 committed by GitHub
commit 846181951b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 67 deletions

View File

@ -33,6 +33,8 @@
- LINUX/PI: Broadcom VC4: Add Videocore config option
- LINUX/UDEV: Fix - RetroArch reads keyboard input when not focused with the udev input driver.
- NETPLAY: Fix disconnection not fully deinitializing Netplay.
- NETPLAY: Fix lan rooms when there is more than one room
- NETPLAY: Fix lan rooms on systems where all addresses are treated as IPv6
- COMMON: Fix clear/free loop conditionals in playlists.
- WINDOWS/GDI: Fix flickering of text.
- WINDOWS/GDI: Fix graphics corruption on Windows 98

View File

@ -3735,8 +3735,8 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
else
{
char s[PATH_MAX_LENGTH];
int i = 0;
int k = 0;
unsigned i = 0;
unsigned j = 0;
file_list_t *file_list = menu_entries_get_selection_buf_ptr(0);
netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &lan_hosts);
@ -3764,30 +3764,17 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
{
struct netplay_host *host = NULL;
for (host = &lan_hosts->hosts[k]; i < netplay_room_count + lan_room_count; i++)
for (i = netplay_room_count; i < netplay_room_count + lan_room_count; i++)
{
struct sockaddr *address = NULL;
struct netplay_host *host = NULL;
host = &lan_hosts->hosts[j++];
strlcpy(netplay_room_list[i].nickname,
host->nick,
sizeof(netplay_room_list[i].nickname));
address = &host->addr;
if (address->sa_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) address;
inet_ntop_compat(AF_INET, &sin->sin_addr,
netplay_room_list[i].address, INET6_ADDRSTRLEN);
}
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
else if (address->sa_family == AF_INET6)
{
struct sockaddr_in6 *sin = (struct sockaddr_in6 *) address;
inet_ntop_compat(AF_INET6, &sin->sin6_addr,
netplay_room_list[i].address, INET6_ADDRSTRLEN);
}
#endif
strlcpy(netplay_room_list[i].address, host->address, INET6_ADDRSTRLEN);
strlcpy(netplay_room_list[i].corename,
host->core,
@ -3802,7 +3789,7 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
host->content,
sizeof(netplay_room_list[i].gamename));
netplay_room_list[i].port = 55435;
netplay_room_list[i].port = host->port;
netplay_room_list[i].gamecrc = host->content_crc;
netplay_room_list[i].timestamp = 0;
netplay_room_list[i].lan = true;

View File

@ -60,6 +60,7 @@ struct ad_packet
uint32_t header;
uint32_t protocol_version;
uint32_t port;
char address[NETPLAY_HOST_STR_LEN];
char retroarch_version[NETPLAY_HOST_STR_LEN];
char nick[NETPLAY_HOST_STR_LEN];
char core[NETPLAY_HOST_STR_LEN];
@ -107,7 +108,7 @@ bool init_netplay_discovery(void)
error:
if (addr)
freeaddrinfo_retro(addr);
RARCH_ERR("Failed to initialize netplay advertisement client socket.\n");
RARCH_ERR("[discovery] Failed to initialize netplay advertisement client socket.\n");
return false;
}
@ -125,6 +126,8 @@ void deinit_netplay_discovery(void)
bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state, void *data)
{
char port_str[6];
int k = 0;
int ret;
if (lan_ad_client_fd < 0)
return false;
@ -136,6 +139,11 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state,
struct addrinfo hints = {0}, *addr;
int canBroadcast = 1;
net_ifinfo_t interfaces;
if (!net_ifinfo_new(&interfaces))
return false;
/* Get the broadcast address (IPv4 only for now) */
snprintf(port_str, 6, "%hu", (unsigned short) RARCH_DEFAULT_PORT);
if (getaddrinfo_retro("255.255.255.255", port_str, &hints, &addr) < 0)
@ -145,20 +153,28 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state,
#if defined(SOL_SOCKET) && defined(SO_BROADCAST)
if (setsockopt(lan_ad_client_fd, SOL_SOCKET, SO_BROADCAST,
(const char *)&canBroadcast, sizeof(canBroadcast)) < 0)
RARCH_WARN("Failed to set netplay discovery port to broadcast.\n");
RARCH_WARN("[discovery] Failed to set netplay discovery port to broadcast\n");
#endif
/* Put together the request */
memcpy((void *) &ad_packet_buffer, "RANQ", 4);
ad_packet_buffer.protocol_version = htonl(NETPLAY_PROTOCOL_VERSION);
/* And send it off */
if (sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer,
2*sizeof(uint32_t), 0, addr->ai_addr, addr->ai_addrlen) <
(ssize_t) (2*sizeof(uint32_t)))
RARCH_WARN("Failed to send netplay discovery response.\n");
for (k=0; k < interfaces.size; k++)
{
strlcpy(ad_packet_buffer.address, interfaces.entries[k].host,
NETPLAY_HOST_STR_LEN);
/* And send it off */
ret = sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer,
sizeof(struct ad_packet), 0, addr->ai_addr, addr->ai_addrlen);
if (ret < (ssize_t) (2*sizeof(uint32_t)))
RARCH_WARN("[discovery] Failed to send netplay discovery query (error: %d)\n", ret);
}
freeaddrinfo_retro(addr);
net_ifinfo_free(&interfaces);
break;
}
@ -201,7 +217,7 @@ static bool init_lan_ad_server_socket(netplay_t *netplay, uint16_t port)
error:
if (addr)
freeaddrinfo_retro(addr);
RARCH_ERR("Failed to initialize netplay advertisement socket.\n");
RARCH_ERR("[discovery] Failed to initialize netplay advertisement socket\n");
return false;
}
@ -217,10 +233,13 @@ bool netplay_lan_ad_server(netplay_t *netplay)
struct sockaddr their_addr;
socklen_t addr_size;
rarch_system_info_t *info = NULL;
int ret, k = 0;
char reply_addr[NETPLAY_HOST_STR_LEN], port_str[6];
struct addrinfo *our_addr, hints = {0};
if (lan_ad_server_fd < 0 && !init_lan_ad_server_socket(netplay, RARCH_DEFAULT_PORT))
return false;
/* Check for any ad queries */
while (1)
{
@ -234,57 +253,101 @@ bool netplay_lan_ad_server(netplay_t *netplay)
/* Somebody queried, so check that it's valid */
addr_size = sizeof(their_addr);
if (recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer,
sizeof(struct ad_packet), 0, &their_addr, &addr_size) >=
(ssize_t) (2*sizeof(uint32_t)))
ret = recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer,
sizeof(struct ad_packet), 0, &their_addr, &addr_size);
if (ret >= (ssize_t) (2 * sizeof(uint32_t)))
{
char s[NETPLAY_HOST_STR_LEN];
uint32_t content_crc = 0;
/* Make sure it's a valid query */
if (memcmp((void *) &ad_packet_buffer, "RANQ", 4))
{
RARCH_LOG("[discovery] invalid query\n");
continue;
}
/* For this version */
if (ntohl(ad_packet_buffer.protocol_version) !=
NETPLAY_PROTOCOL_VERSION)
continue;
info = runloop_get_system_info();
/* Now build our response */
content_crc = content_get_crc();
memset(&ad_packet_buffer, 0, sizeof(struct ad_packet));
memcpy(&ad_packet_buffer, "RANS", 4);
ad_packet_buffer.protocol_version =
htonl(NETPLAY_PROTOCOL_VERSION);
ad_packet_buffer.port = htonl(netplay->tcp_port);
strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION,
NETPLAY_HOST_STR_LEN);
strlcpy(ad_packet_buffer.content, !string_is_empty(
path_basename(path_get(RARCH_PATH_BASENAME)))
? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A",
NETPLAY_HOST_LONGSTR_LEN);
strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN);
if (info)
{
strlcpy(ad_packet_buffer.core, info->info.library_name,
NETPLAY_HOST_STR_LEN);
strlcpy(ad_packet_buffer.core_version, info->info.library_version,
NETPLAY_HOST_STR_LEN);
RARCH_LOG("[discovery] invalid protocol version\n");
continue;
}
snprintf(s, sizeof(s), "%d", content_crc);
strlcpy(ad_packet_buffer.content_crc, s,
NETPLAY_HOST_STR_LEN);
strlcpy(reply_addr, ad_packet_buffer.address, NETPLAY_HOST_STR_LEN);
/* And send it */
sendto(lan_ad_server_fd, (const char*)&ad_packet_buffer,
sizeof(struct ad_packet), 0, &their_addr, addr_size);
net_ifinfo_t interfaces;
if (!net_ifinfo_new(&interfaces))
return false;
for (k = 0; k < interfaces.size; k++)
{
char *p;
char sub[NETPLAY_HOST_STR_LEN];
p=strrchr(reply_addr,'.');
if (p)
{
strlcpy(sub, reply_addr, p - reply_addr + 1);
if (strstr(interfaces.entries[k].host, sub) &&
!strstr(interfaces.entries[k].host, "127.0.0.1"))
{
RARCH_LOG ("[discovery] query received on common interface: %s/%s (theirs / ours) \n",
reply_addr, interfaces.entries[k].host);
info = runloop_get_system_info();
/* Now build our response */
content_crc = content_get_crc();
memset(&ad_packet_buffer, 0, sizeof(struct ad_packet));
memcpy(&ad_packet_buffer, "RANS", 4);
strlcpy(ad_packet_buffer.address, interfaces.entries[k].host,
NETPLAY_HOST_STR_LEN);
ad_packet_buffer.protocol_version =
htonl(NETPLAY_PROTOCOL_VERSION);
ad_packet_buffer.port = htonl(netplay->tcp_port);
strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION,
NETPLAY_HOST_STR_LEN);
strlcpy(ad_packet_buffer.content, !string_is_empty(
path_basename(path_get(RARCH_PATH_BASENAME)))
? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A",
NETPLAY_HOST_LONGSTR_LEN);
strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN);
if (info)
{
strlcpy(ad_packet_buffer.core, info->info.library_name,
NETPLAY_HOST_STR_LEN);
strlcpy(ad_packet_buffer.core_version, info->info.library_version,
NETPLAY_HOST_STR_LEN);
}
snprintf(s, sizeof(s), "%d", content_crc);
strlcpy(ad_packet_buffer.content_crc, s,
NETPLAY_HOST_STR_LEN);
/* Build up the destination address*/
snprintf(port_str, 6, "%hu", ntohs(((struct sockaddr_in*)(&their_addr))->sin_port));
if (getaddrinfo_retro(reply_addr, port_str, &hints, &our_addr) < 0)
continue;
RARCH_LOG ("[discovery] sending reply to %s \n", reply_addr);
/* And send it */
sendto(lan_ad_server_fd, (const char*)&ad_packet_buffer,
sizeof(struct ad_packet), 0, our_addr->ai_addr, our_addr->ai_addrlen);
}
else
continue;
}
else
continue;
}
}
}
return true;
@ -350,7 +413,7 @@ static bool netplay_lan_ad_client(void)
{
struct sockaddr_in *sin = NULL;
RARCH_WARN ("[lobby] using IPv4 for discovery\n");
RARCH_WARN ("[discovery] using IPv4 for discovery\n");
sin = (struct sockaddr_in *) &their_addr;
sin->sin_port = htons(ntohl(ad_packet_buffer.port));
@ -359,7 +422,7 @@ static bool netplay_lan_ad_client(void)
else if (their_addr.sa_family == AF_INET6)
{
struct sockaddr_in6 *sin6 = NULL;
RARCH_WARN ("[lobby] using IPv6 for discovery\n");
RARCH_WARN ("[discovery] using IPv6 for discovery\n");
sin6 = (struct sockaddr_in6 *) &their_addr;
sin6->sin6_port = htons(ad_packet_buffer.port);
@ -402,6 +465,9 @@ static bool netplay_lan_ad_client(void)
host->addr = their_addr;
host->addrlen = addr_size;
host->port = ntohl(ad_packet_buffer.port);
strlcpy(host->address, ad_packet_buffer.address, NETPLAY_HOST_STR_LEN);
strlcpy(host->nick, ad_packet_buffer.nick, NETPLAY_HOST_STR_LEN);
strlcpy(host->core, ad_packet_buffer.core, NETPLAY_HOST_STR_LEN);
strlcpy(host->retroarch_version, ad_packet_buffer.retroarch_version,

View File

@ -18,6 +18,7 @@
#define __RARCH_NETPLAY_DISCOVERY_H
#include <net/net_compat.h>
#include <net/net_ifinfo.h>
#include <retro_miscellaneous.h>
#define NETPLAY_HOST_STR_LEN 32
@ -36,12 +37,14 @@ struct netplay_host
struct sockaddr addr;
socklen_t addrlen;
char address[NETPLAY_HOST_STR_LEN];
char nick[NETPLAY_HOST_STR_LEN];
char core[NETPLAY_HOST_STR_LEN];
char core_version[NETPLAY_HOST_STR_LEN];
char retroarch_version[NETPLAY_HOST_STR_LEN];
char content[NETPLAY_HOST_LONGSTR_LEN];
int content_crc;
int port;
};
struct netplay_host_list