diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 0b172b6a51a..01c26420a84 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -121,8 +121,6 @@ int PacketPeerUDPPosix::get_max_packet_size() const{ Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) { - ERR_FAIL_COND_V(p_address_type != IP_Address::TYPE_IPV4 && p_address_type != IP_Address::TYPE_IPV6, ERR_INVALID_PARAMETER); - close(); int sock = _get_socket(p_address_type); if (sock == -1 ) @@ -223,11 +221,7 @@ int PacketPeerUDPPosix::_get_socket(IP_Address::AddrType p_type) { if (sockfd != -1) return sockfd; - int family = p_type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET; - - sockfd = socket(family, SOCK_DGRAM, IPPROTO_UDP); - ERR_FAIL_COND_V( sockfd == -1, -1 ); - //fcntl(sockfd, F_SETFL, O_NONBLOCK); + sockfd = _socket_create(p_type, SOCK_DGRAM, IPPROTO_UDP); return sockfd; } diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 4ee40e3d3d1..b432a028b3b 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) { diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index f2915b0a163..b1636abd692 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -137,8 +137,8 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) { ERR_FAIL_COND_V( p_host.type == IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); - int family = p_host.type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET; - if ((sockfd = socket(family, SOCK_STREAM, 0)) == -1) { + sockfd = _socket_create(p_host.type, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { ERR_PRINT("Socket creation failed!"); disconnect(); //perror("socket"); diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 05b739804c0..32fda618b24 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -71,8 +71,8 @@ void TCPServerPosix::make_default() { Error TCPServerPosix::listen(uint16_t p_port, IP_Address::AddrType p_type, const List *p_accepted_hosts) { int sockfd; - int family = p_type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET; - sockfd = socket(family, SOCK_STREAM, 0); + sockfd = _socket_create(p_type, SOCK_STREAM, IPPROTO_TCP); + ERR_FAIL_COND_V(sockfd == -1, FAILED); #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index b4cd60979c7..6c661db0c74 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -239,11 +239,7 @@ int PacketPeerUDPWinsock::_get_socket(IP_Address::AddrType p_type) { if (sockfd != -1) return sockfd; - int family = p_type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET; - - sockfd = socket(family, SOCK_DGRAM, IPPROTO_UDP); - ERR_FAIL_COND_V( sockfd == -1, -1 ); - //fcntl(sockfd, F_SETFL, O_NONBLOCK); + sockfd = _socket_create(p_type, SOCK_DGRAM, IPPROTO_UDP); return sockfd; } diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index b511e38ecbf..44c17c73e5e 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -296,8 +296,8 @@ Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) { ERR_FAIL_COND_V( p_host.type == IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); - int family = p_host.type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET; - if ((sockfd = socket(family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { + sockfd = _socket_create(p_host.type, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == INVALID_SOCKET) { ERR_PRINT("Socket creation failed!"); disconnect(); //perror("socket"); diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index 1aedc52bb92..a4eb3a769ce 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -66,7 +66,7 @@ void TCPServerWinsock::cleanup() { Error TCPServerWinsock::listen(uint16_t p_port, IP_Address::AddrType p_type,const List *p_accepted_hosts) { int sockfd; - sockfd = socket(AF_INET, SOCK_STREAM, 0); + sockfd = _socket_create(p_type, SOCK_STREAM, IPPROTO_TCP); ERR_FAIL_COND_V(sockfd == INVALID_SOCKET, FAILED); unsigned long par = 1;