From e7f20a3673a1c04fec9934f56218845adede6f42 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Mon, 5 Dec 2016 00:45:40 -0500 Subject: [PATCH] Bugfixes Silence some Coverity warnings (including a real memory leak) and be more careful about checking IPv6 mode (for backwards compatibility with systems that don't support IPv6 but may run code compiled to expect IPv6) --- network/netplay/netplay.c | 22 ++++++++++++++++++++++ network/netplay/netplay_discovery.c | 28 +++++++++++++++++----------- tasks/task_netplay_lan_scan.c | 8 +------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index cb9c33f70f..114a9cce33 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -100,6 +100,15 @@ static int init_tcp_connection(const struct addrinfo *res, } else { +#if defined(AF_INET6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + /* Make sure we accept connections on both IPv6 and IPv4 */ + int on = 0; + if (res->ai_family == AF_INET6) + { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) + RARCH_WARN("Failed to listen on both IPv6 and IPv4\n"); + } +#endif if ( !socket_bind(fd, (void*)res) || listen(fd, spectate ? MAX_SPECTATORS : 1) < 0) { @@ -132,6 +141,7 @@ static bool init_tcp_socket(netplay_t *netplay, void *direct_host, if (!direct_host) { #ifdef AF_INET6 + /* Default to hosting on IPv6 and IPv4 */ if (!server) hints.ai_family = AF_INET6; #endif @@ -141,7 +151,19 @@ static bool init_tcp_socket(netplay_t *netplay, void *direct_host, snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port); if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0) + { +#ifdef AF_INET6 + if (!server) + { + /* Didn't work with IPv6, try wildcard */ + hints.ai_family = 0; + if (getaddrinfo_retro(server, port_buf, &hints, &res) < 0) + return false; + } + else +#endif return false; + } if (!res) return false; diff --git a/network/netplay/netplay_discovery.c b/network/netplay/netplay_discovery.c index 74bee51675..f35c7ce2ac 100644 --- a/network/netplay/netplay_discovery.c +++ b/network/netplay/netplay_discovery.c @@ -34,6 +34,7 @@ #include #include +#include #include #include "../../runloop.h" @@ -125,7 +126,8 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state, /* Make it broadcastable */ #if defined(SOL_SOCKET) && defined(SO_BROADCAST) - setsockopt(lan_ad_client_fd, SOL_SOCKET, SO_BROADCAST, (const char *) &canBroadcast, sizeof(canBroadcast)); + 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"); #endif /* Put together the request */ @@ -133,8 +135,12 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state, ad_packet_buffer.protocol_version = htonl(NETPLAY_PROTOCOL_VERSION); /* And send it off */ - sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer, - 2*sizeof(uint32_t), 0, addr->ai_addr, addr->ai_addrlen); + if (sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer, + 2*sizeof(uint32_t), 0, addr->ai_addr, addr->ai_addrlen) < + 2*sizeof(uint32_t)) + RARCH_WARN("Failed to send netplay discovery response.\n"); + + freeaddrinfo_retro(addr); break; } @@ -225,14 +231,14 @@ bool netplay_lan_ad_server(netplay_t *netplay) ad_packet_buffer.protocol_version = htonl(NETPLAY_PROTOCOL_VERSION); ad_packet_buffer.port = htonl(netplay->tcp_port); - strncpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION, + strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION, NETPLAY_HOST_STR_LEN); - strncpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN); + strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN); if (info) { - strncpy(ad_packet_buffer.core, info->info.library_name, + strlcpy(ad_packet_buffer.core, info->info.library_name, NETPLAY_HOST_STR_LEN); - strncpy(ad_packet_buffer.core_version, info->info.library_version, + strlcpy(ad_packet_buffer.core_version, info->info.library_version, NETPLAY_HOST_STR_LEN); } @@ -346,11 +352,11 @@ bool netplay_lan_ad_client(void) memset(host, 0, sizeof(struct netplay_host)); host->addr = their_addr; host->addrlen = addr_size; - strncpy(host->nick, ad_packet_buffer.nick, NETPLAY_HOST_STR_LEN); - strncpy(host->core, ad_packet_buffer.core, NETPLAY_HOST_STR_LEN); - strncpy(host->core_version, ad_packet_buffer.core_version, + strlcpy(host->nick, ad_packet_buffer.nick, NETPLAY_HOST_STR_LEN); + strlcpy(host->core, ad_packet_buffer.core, NETPLAY_HOST_STR_LEN); + strlcpy(host->core_version, ad_packet_buffer.core_version, NETPLAY_HOST_STR_LEN); - strncpy(host->content, ad_packet_buffer.content, + strlcpy(host->content, ad_packet_buffer.content, NETPLAY_HOST_STR_LEN); host->nick[NETPLAY_HOST_STR_LEN-1] = host->core[NETPLAY_HOST_STR_LEN-1] = diff --git a/tasks/task_netplay_lan_scan.c b/tasks/task_netplay_lan_scan.c index 51a925efac..15ce4ff513 100644 --- a/tasks/task_netplay_lan_scan.c +++ b/tasks/task_netplay_lan_scan.c @@ -84,7 +84,7 @@ bool task_push_netplay_lan_scan(void) retro_task_t *task = (retro_task_t*)calloc(1, sizeof(*task)); if (!task) - goto error; + return false; task->type = TASK_TYPE_BLOCKING; task->handler = task_netplay_lan_scan_handler; @@ -94,10 +94,4 @@ bool task_push_netplay_lan_scan(void) task_queue_ctl(TASK_QUEUE_CTL_PUSH, task); return true; - -error: - if (task) - free(task); - - return false; }