From 812908e236e83db368dfef49b8badb9a6182e1de Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 28 Oct 2016 04:18:17 +0200 Subject: Fix windows debugger connection problems. Unify network socket creation between platform. Ensure IPV6_V6ONLY flag is not set on sockets (allow IPv4 connection in IPv6 socket, dual-stack). --- drivers/unix/socket_helpers.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 4ee40e3d3d..b432a028b3 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -45,6 +45,27 @@ static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, }; }; +static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { + + ERR_FAIL_COND_V(p_type > IP_Address::TYPE_ANY || p_type < IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); + + int family = p_type == IP_Address::TYPE_IPV4 ? AF_INET : AF_INET6; + int sockfd = socket(family, type, protocol); + + ERR_FAIL_COND_V( sockfd == -1, -1 ); + + if(family == AF_INET6) { + // Ensure IPv4 over IPv6 is enabled + int v6_only = 0; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&v6_only, sizeof(v6_only)) != 0) { + WARN_PRINT("Unable to set IPv4 address mapping over IPv6"); + } + } + + return sockfd; +} + + static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_storage* p_addr) { if (p_addr->ss_family == AF_INET) { -- cgit v1.2.3 From eb27e993f0f2fb3de48b7b8aa01c74cc1635a178 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 28 Oct 2016 23:11:53 +0200 Subject: TCP/UDP Listen sockets can now be set to IPv6 only --- drivers/unix/socket_helpers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index b432a028b3..80e013ad68 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -56,8 +56,8 @@ static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { if(family == AF_INET6) { // Ensure IPv4 over IPv6 is enabled - int v6_only = 0; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&v6_only, sizeof(v6_only)) != 0) { + int no = 0; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&no, sizeof(no)) != 0) { WARN_PRINT("Unable to set IPv4 address mapping over IPv6"); } } -- cgit v1.2.3 From bdc7ca84cac727f3f94663f23e1229450230bd2e Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sun, 30 Oct 2016 22:58:15 +0100 Subject: Define IPV6_V6ONLY flag if not defined on windows (old mingw versions) --- drivers/unix/socket_helpers.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 80e013ad68..9693911acd 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -3,6 +3,13 @@ #include +#ifdef WINDOWS_ENABLED + // Workaround mingw missing flags! + #ifndef IPV6_V6ONLY + #define IPV6_V6ONLY 27 + #endif +#endif + // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { -- cgit v1.2.3 From 4160b3c9feb32e7762ea121bb44b30ba65676760 Mon Sep 17 00:00:00 2001 From: George Marques Date: Mon, 31 Oct 2016 21:39:45 -0200 Subject: Fix IPv6 linking for UWP --- drivers/unix/socket_helpers.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 9693911acd..3aaae82da2 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -10,6 +10,10 @@ #endif #endif +#ifdef WINRT_ENABLED +#define in6addr_any IN6ADDR_ANY_INIT +#endif + // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { -- cgit v1.2.3 From b113c7b7a3e63581ae268b0ae7f827d55e381b82 Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 2 Nov 2016 18:57:35 -0200 Subject: Rename WINRT_ENABLED to UWP_ENABLED --- drivers/unix/socket_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 3aaae82da2..5e8e8dfd7a 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -10,7 +10,7 @@ #endif #endif -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED #define in6addr_any IN6ADDR_ANY_INIT #endif -- cgit v1.2.3 From cdc1ca0f1301bb907121292db83f98706722ff1e Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 2 Dec 2016 04:10:55 +0100 Subject: Fix _set_ip_addr_port not setting the address. --- drivers/unix/socket_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 5e8e8dfd7a..84b1ca5740 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -92,7 +92,7 @@ static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_sto r_ip.type = IP_Address::TYPE_IPV6; struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; - copymem(&addr6->sin6_addr.s6_addr, r_ip.field8, 16); + copymem(&r_ip.field8, addr6->sin6_addr.s6_addr, 16); r_port = ntohs(addr6->sin6_port); }; -- cgit v1.2.3 From 9200da58e4c2498c833d9f2505600c7049e80940 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 1 Dec 2016 04:23:57 +0100 Subject: Automatically map IPv4 address to IPv6 when needed --- drivers/unix/socket_helpers.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 84b1ca5740..a860c2f80e 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -16,18 +16,30 @@ // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this -static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { +static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP_Address::AddrType p_sock_type = IP_Address::TYPE_ANY) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); - if (p_ip.type == IP_Address::TYPE_IPV6) { + + // Dual stack (ANY) or matching ip type is required + ERR_FAIL_COND_V(p_sock_type != IP_Address::TYPE_ANY && p_sock_type != p_ip.type,0); + + // IPv6 socket + if (p_sock_type == IP_Address::TYPE_IPV6 || p_sock_type == IP_Address::TYPE_ANY) { struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); - copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); + if(p_ip.type == IP_Address::TYPE_IPV4) { + // Remapping needed + uint16_t base[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, p_ip.field16[0], p_ip.field16[1]}; + copymem(&addr6->sin6_addr.s6_addr, base, 16); + + } else { + copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); + } return sizeof(sockaddr_in6); - } else { + } else { // IPv4 socket struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; addr4->sin_family = AF_INET; // host byte order -- cgit v1.2.3 From 4d90a4fcd5fcdca42df47062f94a1fa4e5635a94 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 1 Dec 2016 05:05:44 +0100 Subject: Move V6ONLY flag selection inside helpers --- drivers/unix/socket_helpers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index a860c2f80e..aec4ec8843 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -78,10 +78,10 @@ static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { ERR_FAIL_COND_V( sockfd == -1, -1 ); if(family == AF_INET6) { - // Ensure IPv4 over IPv6 is enabled - int no = 0; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&no, sizeof(no)) != 0) { - WARN_PRINT("Unable to set IPv4 address mapping over IPv6"); + // Select IPv4 over IPv6 mapping + int opt = p_type != IP_Address::TYPE_ANY; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&opt, sizeof(opt)) != 0) { + WARN_PRINT("Unable to set/unset IPv4 address mapping over IPv6"); } } -- cgit v1.2.3 From c18c5013f837ea7d4de2f022d36f84e0abce6439 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 1 Dec 2016 06:34:05 +0100 Subject: Migrate int.IP_TYPE_ constants to IP.TYPE_ --- drivers/unix/socket_helpers.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index aec4ec8843..ffe2015947 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -16,15 +16,15 @@ // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this -static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP_Address::AddrType p_sock_type = IP_Address::TYPE_ANY) { +static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP::Type p_sock_type = IP::TYPE_ANY) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); // Dual stack (ANY) or matching ip type is required - ERR_FAIL_COND_V(p_sock_type != IP_Address::TYPE_ANY && p_sock_type != p_ip.type,0); + ERR_FAIL_COND_V(p_sock_type != IP::TYPE_ANY && p_sock_type != p_ip.type,0); // IPv6 socket - if (p_sock_type == IP_Address::TYPE_IPV6 || p_sock_type == IP_Address::TYPE_ANY) { + if (p_sock_type == IP::TYPE_IPV6 || p_sock_type == IP::TYPE_ANY) { struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; @@ -49,10 +49,10 @@ static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p }; }; -static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP_Address::AddrType p_address_type, const List *p_accepted_hosts) { +static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP::Type p_sock_type, const List *p_accepted_hosts) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); - if (p_address_type == IP_Address::TYPE_IPV4) { + if (p_sock_type == IP::TYPE_IPV4) { struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; addr4->sin_family = AF_INET; addr4->sin_port = htons(p_port); @@ -68,18 +68,18 @@ static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, }; }; -static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { +static int _socket_create(IP::Type p_type, int type, int protocol) { - ERR_FAIL_COND_V(p_type > IP_Address::TYPE_ANY || p_type < IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_type > IP::TYPE_ANY || p_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); - int family = p_type == IP_Address::TYPE_IPV4 ? AF_INET : AF_INET6; + int family = p_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; int sockfd = socket(family, type, protocol); ERR_FAIL_COND_V( sockfd == -1, -1 ); if(family == AF_INET6) { // Select IPv4 over IPv6 mapping - int opt = p_type != IP_Address::TYPE_ANY; + int opt = p_type != IP::TYPE_ANY; if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&opt, sizeof(opt)) != 0) { WARN_PRINT("Unable to set/unset IPv4 address mapping over IPv6"); } -- cgit v1.2.3 From 1aff508dd9713abf0db0d0436fa7f7c4788c5a4a Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 5 Dec 2016 16:32:38 +0100 Subject: IP_Address now handle IPv4 and IPv6 transparently IP_Address changes: - Converts to and from String transparently while handling IPv4 as IPv6 mapped (::ffff:[IP]) address internally. - Completely remove AddrType enum. - Setting/Getting of ip array is now only possible through dedicated functions (ie. set_ipv4, get_ipv4, set_ipv6, get_ipv6) - Add function to know if the address is a valid IPv4 (for IP implementation and enet) --- drivers/unix/socket_helpers.h | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index ffe2015947..962f228c3c 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -20,31 +20,30 @@ static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p memset(p_addr, 0, sizeof(struct sockaddr_storage)); - // Dual stack (ANY) or matching ip type is required - ERR_FAIL_COND_V(p_sock_type != IP::TYPE_ANY && p_sock_type != p_ip.type,0); + ERR_FAIL_COND_V(p_ip==IP_Address(),0); // IPv6 socket if (p_sock_type == IP::TYPE_IPV6 || p_sock_type == IP::TYPE_ANY) { + // IPv6 only socket with IPv4 address + ERR_FAIL_COND_V(p_sock_type == IP::TYPE_IPV6 && p_ip.is_ipv4(),0); + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); - if(p_ip.type == IP_Address::TYPE_IPV4) { - // Remapping needed - uint16_t base[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, p_ip.field16[0], p_ip.field16[1]}; - copymem(&addr6->sin6_addr.s6_addr, base, 16); - - } else { - copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); - } + copymem(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16); return sizeof(sockaddr_in6); } else { // IPv4 socket + // IPv4 socket with IPv6 address + ERR_FAIL_COND_V(!p_ip.is_ipv4(),0); + + uint32_t ipv4 = *((uint32_t *)p_ip.get_ipv4()); struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; - addr4->sin_family = AF_INET; // host byte order + addr4->sin_family = AF_INET; addr4->sin_port = htons(p_port); // short, network byte order - addr4->sin_addr = *((struct in_addr*)&p_ip.field32[0]); + copymem(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 16); return sizeof(sockaddr_in); }; }; @@ -92,19 +91,16 @@ static int _socket_create(IP::Type p_type, int type, int protocol) { static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_storage* p_addr) { if (p_addr->ss_family == AF_INET) { - r_ip.type = IP_Address::TYPE_IPV4; struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; - r_ip.field32[0] = (uint32_t)addr4->sin_addr.s_addr; + r_ip.set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr)); r_port = ntohs(addr4->sin_port); } else if (p_addr->ss_family == AF_INET6) { - r_ip.type = IP_Address::TYPE_IPV6; - struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; - copymem(&r_ip.field8, addr6->sin6_addr.s6_addr, 16); + r_ip.set_ipv6(addr6->sin6_addr.s6_addr); r_port = ntohs(addr6->sin6_port); }; -- cgit v1.2.3