mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 19:20:35 +00:00
Fix lan rooms
Squashed commit of the following: commit 6e1fea3b16bb330ed2862eb00d2e911221c48a34 Author: radius <andres.430@gmail.com> Date: Sat Nov 18 22:16:02 2017 -0500 use the baked in address instead of sockaddr commit 84f2d389fd6352b3037f48c18d133d2f1063d461 Author: radius <andres.430@gmail.com> Date: Sat Nov 18 22:05:57 2017 -0500 send replies commit c6733009cc5a25e58391c5fc693b277ea27404b3 Author: radius <andres.430@gmail.com> Date: Sat Nov 18 21:53:12 2017 -0500 send replies commit a6816c9481f7ea89a3c97597233e54c6354716e7 Author: radius <andres.430@gmail.com> Date: Sat Nov 18 21:46:55 2017 -0500 send replies commit c2453b73ccafbd53192507affbc11d5f279c2e7c Author: radius <andres.430@gmail.com> Date: Sat Nov 18 21:26:34 2017 -0500 look for common interfaces commit fb42e6470242689f5e6160149ef91f0f0abf068d Author: radius <andres.430@gmail.com> Date: Sat Nov 18 20:06:50 2017 -0500 send broadcasts in all interfaces commit b7730596df9775fb815007689e9c7cc06b317b03 Author: radius <andres.430@gmail.com> Date: Sat Nov 18 20:00:17 2017 -0500 send broadcasts in all interfaces commit b620a78052d1b95e81d346f3e5efb233e0547793 Author: radius <andres.430@gmail.com> Date: Sat Nov 18 14:30:31 2017 -0500 add more logging commit c016c7d559cd631172a58f99cd3e1a1365965b8e Author: radius <andres.430@gmail.com> Date: Sat Nov 18 14:12:03 2017 -0500 update log messages commit 0a49ba61f56f2ca483fa76c7a04f0709c68b95ad Author: radius <andres.430@gmail.com> Date: Sat Nov 18 13:50:47 2017 -0500 fix lan room listing for rooms > 1, allow connecting in arbitrary ports
This commit is contained in:
parent
c89ed117b6
commit
149469515f
@ -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);
|
||||
@ -3760,34 +3760,23 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
|
||||
for (i = 0; i < netplay_room_count; i++)
|
||||
memcpy(&netplay_room_list[i], netplay_room_get(i), sizeof(netplay_room_list[i]));
|
||||
|
||||
|
||||
|
||||
if (lan_room_count != 0)
|
||||
{
|
||||
struct netplay_host *host = NULL;
|
||||
|
||||
for (host = &lan_hosts->hosts[k]; i < netplay_room_count + lan_room_count; i++)
|
||||
for (j = 0; 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 +3791,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;
|
||||
@ -3810,8 +3799,10 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
|
||||
snprintf(s, sizeof(s),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME),
|
||||
netplay_room_list[i].nickname);
|
||||
j++;
|
||||
}
|
||||
netplay_room_count += lan_room_count;
|
||||
|
||||
}
|
||||
netplay_refresh_rooms_menu(file_list);
|
||||
}
|
||||
|
@ -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];
|
||||
@ -90,6 +91,7 @@ bool init_netplay_discovery(void)
|
||||
{
|
||||
struct addrinfo *addr = NULL;
|
||||
int fd = socket_init((void **) &addr, 0, NULL, SOCKET_TYPE_DATAGRAM);
|
||||
char s[NETPLAY_HOST_STR_LEN];
|
||||
|
||||
if (fd < 0)
|
||||
goto error;
|
||||
@ -100,6 +102,9 @@ bool init_netplay_discovery(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
inet_ntop_compat(AF_INET, &((struct sockaddr_in *)addr->ai_addr)->sin_addr,
|
||||
s, INET6_ADDRSTRLEN);
|
||||
RARCH_WARN("[discovery] Initialized discovery on %s\n", s);
|
||||
lan_ad_client_fd = fd;
|
||||
freeaddrinfo_retro(addr);
|
||||
return true;
|
||||
@ -107,7 +112,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;
|
||||
}
|
||||
|
||||
@ -136,6 +141,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 +155,27 @@ 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 (int k = 0; k < interfaces.size; k++)
|
||||
{
|
||||
strlcpy(ad_packet_buffer.address, interfaces.entries[k].host,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
/* And send it off */
|
||||
if (sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer,
|
||||
2*sizeof(uint32_t) + NETPLAY_HOST_STR_LEN, 0, addr->ai_addr, addr->ai_addrlen) <
|
||||
(ssize_t) (2*sizeof(uint32_t)))
|
||||
RARCH_WARN("[discovery] Failed to send netplay discovery response.\n");
|
||||
}
|
||||
|
||||
freeaddrinfo_retro(addr);
|
||||
net_ifinfo_free(&interfaces);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -201,7 +218,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,9 +234,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;
|
||||
char reply_addr[NETPLAY_HOST_STR_LEN];
|
||||
char our_addr[NETPLAY_HOST_STR_LEN];
|
||||
|
||||
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 +255,102 @@ 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 (int 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*/
|
||||
struct addrinfo hints = {0}, *addr;
|
||||
char port_str[6];
|
||||
|
||||
snprintf(port_str, 6, "%hu", ntohs(((struct sockaddr_in*)(&their_addr))->sin_port));
|
||||
if (getaddrinfo_retro(reply_addr, port_str, &hints, &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, addr->ai_addr, addr_size);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -350,7 +416,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 +425,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 +468,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,
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user