summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2016-10-31 08:00:54 +0100
committerGitHub <noreply@github.com>2016-10-31 08:00:54 +0100
commit434d120226c31fea9c1ff905c37486d6ed58633a (patch)
treef3d69229c6c14f8b5e84337b3ac8ad0f470e5548
parentde454318e72f5de13c5a1efff5811d41e360a8a2 (diff)
parentbdc7ca84cac727f3f94663f23e1229450230bd2e (diff)
downloadredot-engine-434d120226c31fea9c1ff905c37486d6ed58633a.tar.gz
Merge pull request #6981 from Faless/ipv6_fix
Use IPv6 dual stack socket by default. Allow restricting IP version for TCP/UDP.
-rw-r--r--core/io/ip.cpp4
-rw-r--r--core/io/packet_peer_udp.cpp8
-rw-r--r--core/io/packet_peer_udp.h4
-rw-r--r--core/io/stream_peer_tcp.cpp19
-rw-r--r--core/io/stream_peer_tcp.h2
-rw-r--r--core/io/tcp_server.cpp2
-rw-r--r--core/io/tcp_server.h4
-rw-r--r--doc/base/classes.xml34
-rw-r--r--drivers/unix/ip_unix.cpp9
-rw-r--r--drivers/unix/packet_peer_udp_posix.cpp23
-rw-r--r--drivers/unix/socket_helpers.h28
-rw-r--r--drivers/unix/stream_peer_tcp_posix.cpp4
-rw-r--r--drivers/unix/tcp_server_posix.cpp12
-rw-r--r--drivers/unix/tcp_server_posix.h2
-rw-r--r--platform/windows/packet_peer_udp_winsock.cpp20
-rw-r--r--platform/windows/stream_peer_winsock.cpp4
-rw-r--r--platform/windows/tcp_server_winsock.cpp10
-rw-r--r--platform/windows/tcp_server_winsock.h2
18 files changed, 144 insertions, 47 deletions
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 4ee1b281c4..f0f273af1a 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -212,8 +212,8 @@ Array IP::_get_local_addresses() const {
void IP::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("resolve_hostname","host"),&IP::resolve_hostname);
- ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host"),&IP::resolve_hostname_queue_item);
+ ObjectTypeDB::bind_method(_MD("resolve_hostname","host","ip_type"),&IP::resolve_hostname,DEFVAL(IP_Address::TYPE_ANY));
+ ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host","ip_type"),&IP::resolve_hostname_queue_item,DEFVAL(IP_Address::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("get_resolve_item_status","id"),&IP::get_resolve_item_status);
ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address);
ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item);
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index 018dc77d91..925d00a84a 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -38,13 +38,13 @@ String PacketPeerUDP::_get_packet_ip() const {
return get_packet_address();
}
-Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port) {
+Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port,IP_Address::AddrType p_type) {
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip=p_address;
} else {
- ip=IP::get_singleton()->resolve_hostname(p_address);
+ ip=IP::get_singleton()->resolve_hostname(p_address, p_type);
if (ip==IP_Address())
return ERR_CANT_RESOLVE;
}
@@ -55,14 +55,14 @@ Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port) {
void PacketPeerUDP::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("listen:Error","port","recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(65536));
+ ObjectTypeDB::bind_method(_MD("listen:Error","port","ip_type", "recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(IP_Address::TYPE_ANY),DEFVAL(65536));
ObjectTypeDB::bind_method(_MD("close"),&PacketPeerUDP::close);
ObjectTypeDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait);
ObjectTypeDB::bind_method(_MD("is_listening"),&PacketPeerUDP::is_listening);
ObjectTypeDB::bind_method(_MD("get_packet_ip"),&PacketPeerUDP::_get_packet_ip);
//ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address);
ObjectTypeDB::bind_method(_MD("get_packet_port"),&PacketPeerUDP::get_packet_port);
- ObjectTypeDB::bind_method(_MD("set_send_address","host","port"),&PacketPeerUDP::_set_send_address);
+ ObjectTypeDB::bind_method(_MD("set_send_address","host","port","ip_type"),&PacketPeerUDP::_set_send_address,DEFVAL(IP_Address::TYPE_ANY));
}
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index c0806a9e6a..37e700cebd 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -42,11 +42,11 @@ protected:
String _get_packet_ip() const;
- virtual Error _set_send_address(const String& p_address,int p_port);
+ virtual Error _set_send_address(const String& p_address,int p_port, IP_Address::AddrType p_address_type = IP_Address::TYPE_ANY);
public:
- virtual Error listen(int p_port, IP_Address::AddrType p_address_type = IP_Address::TYPE_IPV4, int p_recv_buffer_size=65536)=0;
+ virtual Error listen(int p_port, IP_Address::AddrType p_address_type = IP_Address::TYPE_ANY, int p_recv_buffer_size=65536)=0;
virtual void close()=0;
virtual Error wait()=0;
virtual bool is_listening() const=0;
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index fbb0c69cb7..528f2e8cab 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -30,9 +30,26 @@
StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL;
+VARIANT_ENUM_CAST(IP_Address::AddrType);
+
+Error StreamPeerTCP::_connect(const String& p_address,int p_port,IP_Address::AddrType p_type) {
+
+ IP_Address ip;
+ if (p_address.is_valid_ip_address()) {
+ ip=p_address;
+ } else {
+ ip=IP::get_singleton()->resolve_hostname(p_address, p_type);
+ if (ip==IP_Address())
+ return ERR_CANT_RESOLVE;
+ }
+
+ connect(ip,p_port);
+ return OK;
+}
+
void StreamPeerTCP::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("connect","host","port"),&StreamPeerTCP::connect);
+ ObjectTypeDB::bind_method(_MD("connect","host","port","ip_type"),&StreamPeerTCP::_connect,DEFVAL(IP_Address::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected);
ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerTCP::get_status);
ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host);
diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h
index 4c58e7e149..a151fffad8 100644
--- a/core/io/stream_peer_tcp.h
+++ b/core/io/stream_peer_tcp.h
@@ -32,6 +32,7 @@
#include "stream_peer.h"
#include "ip_address.h"
+#include "io/ip.h"
class StreamPeerTCP : public StreamPeer {
@@ -50,6 +51,7 @@ public:
protected:
+ virtual Error _connect(const String& p_address, int p_port, IP_Address::AddrType p_type = IP_Address::TYPE_ANY);
static StreamPeerTCP* (*_create)();
static void _bind_methods();
diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp
index 53d6e900f3..894cccf691 100644
--- a/core/io/tcp_server.cpp
+++ b/core/io/tcp_server.cpp
@@ -58,7 +58,7 @@ Error TCP_Server::_listen(uint16_t p_port, IP_Address::AddrType p_type, DVector<
void TCP_Server::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("listen","port","accepted_hosts"),&TCP_Server::_listen,DEFVAL(IP_Address::TYPE_IPV4), DEFVAL(DVector<String>()));
+ ObjectTypeDB::bind_method(_MD("listen","port","ip_type", "accepted_hosts"),&TCP_Server::_listen,DEFVAL(IP_Address::TYPE_ANY),DEFVAL(DVector<String>()));
ObjectTypeDB::bind_method(_MD("is_connection_available"),&TCP_Server::is_connection_available);
ObjectTypeDB::bind_method(_MD("take_connection"),&TCP_Server::take_connection);
ObjectTypeDB::bind_method(_MD("stop"),&TCP_Server::stop);
diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h
index 883a3ef2f6..0267895008 100644
--- a/core/io/tcp_server.h
+++ b/core/io/tcp_server.h
@@ -41,11 +41,11 @@ protected:
static TCP_Server* (*_create)();
//bind helper
- Error _listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_IPV4 ,DVector<String> p_accepted_hosts=DVector<String>());
+ Error _listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_ANY ,DVector<String> p_accepted_hosts=DVector<String>());
static void _bind_methods();
public:
- virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_IPV4, const List<String> *p_accepted_hosts=NULL)=0;
+ virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_ANY, const List<String> *p_accepted_hosts=NULL)=0;
virtual bool is_connection_available() const=0;
virtual Ref<StreamPeerTCP> take_connection()=0;
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 977b44763e..92b208ff50 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -16068,8 +16068,10 @@
</return>
<argument index="0" name="host" type="String">
</argument>
+ <argument index="1" name="ip_type" type="int" default="int.IP_TYPE_ANY">
+ </argument>
<description>
- Resolve a given hostname, blocking. Resolved hostname is returned as an IP.
+ Resolve a given hostname, blocking. Resolved hostname is returned as an IPv4 or IPv6 depending on "ip_type".
</description>
</method>
<method name="resolve_hostname_queue_item">
@@ -16077,8 +16079,10 @@
</return>
<argument index="0" name="host" type="String">
</argument>
+ <argument index="1" name="ip_type" type="int" default="int.IP_TYPE_ANY">
+ </argument>
<description>
- Create a queue item for resolving a given hostname. The queue ID is returned, or RESOLVER_INVALID_ID on error.
+ Create a queue item for resolving a given hostname to an IPv4 or IPv6 depending on "ip_type". The queue ID is returned, or RESOLVER_INVALID_ID on error.
</description>
</method>
</methods>
@@ -25357,10 +25361,15 @@
</return>
<argument index="0" name="port" type="int">
</argument>
- <argument index="1" name="recv_buf_size" type="int" default="65536">
+ <argument index="1" name="ip_type" type="int" default="int.IP_TYPE_ANY">
+ </argument>
+ <argument index="2" name="recv_buf_size" type="int" default="65536">
</argument>
<description>
- Make this [PacketPeerUDP] listen on the "port" using a buffer size "recv_buf_size". Listens on all available adresses.
+ Make this [PacketPeerUDP] listen on the "port" using protocol "ip_type" and a buffer size "recv_buf_size". Listens on all available adresses.
+ IP_TYPE_IPV4 = IPv4 only
+ IP_TYPE_IPV6 = IPv6 only
+ IP_TYPE_ANY = Dual stack (supports both IPv6 and IPv4 connections).
</description>
</method>
<method name="set_send_address">
@@ -25370,8 +25379,10 @@
</argument>
<argument index="1" name="port" type="int">
</argument>
+ <argument index="2" name="ip_type" type="int" default="int.IP_TYPE_ANY">
+ </argument>
<description>
- Set the destination address and port for sending packets and variables, a hostname will be resolved if valid.
+ Set the destination address and port for sending packets and variables, a hostname will be resolved using "ip_type" (v4/v6/any) if valid.
</description>
</method>
<method name="wait">
@@ -39181,8 +39192,10 @@
</argument>
<argument index="1" name="port" type="int">
</argument>
+ <argument index="2" name="ip_type" type="int" default="int.IP_TYPE_ANY">
+ </argument>
<description>
- Connect to the specified IP:port pair. Returns [OK] on success or [FAILED] on failure.
+ Connect to the specified host:port pair. A hostname will be resolved using "ip_type" (v4/v6/any) if valid. Returns [OK] on success or [FAILED] on failure.
</description>
</method>
<method name="disconnect">
@@ -40505,10 +40518,15 @@
</return>
<argument index="0" name="port" type="int">
</argument>
- <argument index="1" name="accepted_hosts" type="StringArray" default="StringArray([])">
+ <argument index="1" name="ip_type" type="int" default="int.IP_TYPE_ANY">
+ </argument>
+ <argument index="2" name="accepted_hosts" type="StringArray" default="StringArray([])">
</argument>
<description>
- Listen on a port, alternatively give a white-list of accepted hosts.
+ Listen on a port using protocol "ip_type", alternatively give a white-list of accepted hosts.
+ IP_TYPE_IPV4 = IPv4 only
+ IP_TYPE_IPV6 = IPv6 only
+ IP_TYPE_ANY = Dual stack (supports both IPv6 and IPv4 connections).
</description>
</method>
<method name="stop">
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index d6d1be3395..e3d32618ee 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -33,6 +33,13 @@
#include <string.h>
#ifdef WINDOWS_ENABLED
+ // Workaround mingw missing flags!
+ #ifndef AI_ADDRCONFIG
+ #define AI_ADDRCONFIG 0x00000400
+ #endif
+ #ifndef AI_V4MAPPED
+ #define AI_V4MAPPED 0x00000800
+ #endif
#ifdef WINRT_ENABLED
#include <ws2tcpip.h>
#include <winsock2.h>
@@ -90,8 +97,10 @@ IP_Address IP_Unix::_resolve_hostname(const String& p_hostname, IP_Address::Addr
hints.ai_family = AF_INET;
} else if (p_type == IP_Address::TYPE_IPV6) {
hints.ai_family = AF_INET6;
+ hints.ai_flags = 0;
} else {
hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
};
int s = getaddrinfo(p_hostname.utf8().get_data(), NULL, &hints, &result);
diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp
index 0b172b6a51..ed295f0459 100644
--- a/drivers/unix/packet_peer_udp_posix.cpp
+++ b/drivers/unix/packet_peer_udp_posix.cpp
@@ -119,17 +119,24 @@ int PacketPeerUDPPosix::get_max_packet_size() const{
return 512; // uhm maybe not
}
-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);
+Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_type, int p_recv_buffer_size) {
close();
- int sock = _get_socket(p_address_type);
+ int sock = _get_socket(p_type);
+
if (sock == -1 )
return ERR_CANT_CREATE;
+ if(p_type == IP_Address::TYPE_IPV6) {
+ // Use IPv6 only socket
+ int yes = 1;
+ if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) {
+ WARN_PRINT("Unable to unset IPv4 address mapping over IPv6");
+ }
+ }
+
sockaddr_storage addr = {0};
- size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL);
+ size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_type, NULL);
if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) {
close();
@@ -223,11 +230,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 4ee40e3d3d..9693911acd 100644
--- a/drivers/unix/socket_helpers.h
+++ b/drivers/unix/socket_helpers.h
@@ -3,6 +3,13 @@
#include <string.h>
+#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) {
@@ -45,6 +52,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 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");
+ }
+ }
+
+ 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 f2915b0a16..b1636abd69 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 05b739804c..7028c1a107 100644
--- a/drivers/unix/tcp_server_posix.cpp
+++ b/drivers/unix/tcp_server_posix.cpp
@@ -71,9 +71,17 @@ void TCPServerPosix::make_default() {
Error TCPServerPosix::listen(uint16_t p_port, IP_Address::AddrType p_type, const List<String> *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);
+
+ if(p_type == IP_Address::TYPE_IPV6) {
+ // Use IPv6 only socket
+ int yes = 1;
+ if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) {
+ WARN_PRINT("Unable to unset IPv4 address mapping over IPv6");
+ }
+ }
#ifndef NO_FCNTL
fcntl(sockfd, F_SETFL, O_NONBLOCK);
#else
diff --git a/drivers/unix/tcp_server_posix.h b/drivers/unix/tcp_server_posix.h
index 134ec494cb..a700b6ae0e 100644
--- a/drivers/unix/tcp_server_posix.h
+++ b/drivers/unix/tcp_server_posix.h
@@ -40,7 +40,7 @@ class TCPServerPosix : public TCP_Server {
public:
- virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_IPV4, const List<String> *p_accepted_hosts=NULL);
+ virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type, const List<String> *p_accepted_hosts=NULL);
virtual bool is_connection_available() const;
virtual Ref<StreamPeerTCP> take_connection();
diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp
index b4cd60979c..73c6116aa3 100644
--- a/platform/windows/packet_peer_udp_winsock.cpp
+++ b/platform/windows/packet_peer_udp_winsock.cpp
@@ -112,15 +112,23 @@ void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) {
};
}
-Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) {
+Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_type, int p_recv_buffer_size) {
close();
- int sock = _get_socket(p_address_type);
+ int sock = _get_socket(p_type);
if (sock == -1 )
return ERR_CANT_CREATE;
+ if(p_type == IP_Address::TYPE_IPV6) {
+ // Use IPv6 only socket
+ int yes = 1;
+ if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) {
+ WARN_PRINT("Unable to unset IPv4 address mapping over IPv6");
+ }
+ }
+
struct sockaddr_storage addr = {0};
- size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL);
+ size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_type, NULL);
if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) {
close();
@@ -239,11 +247,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 b511e38ecb..44c17c73e5 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 1aedc52bb9..38a6b04100 100644
--- a/platform/windows/tcp_server_winsock.cpp
+++ b/platform/windows/tcp_server_winsock.cpp
@@ -66,9 +66,17 @@ void TCPServerWinsock::cleanup() {
Error TCPServerWinsock::listen(uint16_t p_port, IP_Address::AddrType p_type,const List<String> *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);
+ if(p_type == IP_Address::TYPE_IPV6) {
+ // Use IPv6 only socket
+ int yes = 1;
+ if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) {
+ WARN_PRINT("Unable to unset IPv4 address mapping over IPv6");
+ }
+ }
+
unsigned long par = 1;
if (ioctlsocket(sockfd, FIONBIO, &par)) {
perror("setting non-block mode");
diff --git a/platform/windows/tcp_server_winsock.h b/platform/windows/tcp_server_winsock.h
index 94601a2e12..115fdb4234 100644
--- a/platform/windows/tcp_server_winsock.h
+++ b/platform/windows/tcp_server_winsock.h
@@ -39,7 +39,7 @@ class TCPServerWinsock : public TCP_Server {
public:
- virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_IPV4,const List<String> *p_accepted_hosts=NULL);
+ virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type,const List<String> *p_accepted_hosts=NULL);
virtual bool is_connection_available() const;
virtual Ref<StreamPeerTCP> take_connection();