Ver código fonte

added windows support for ipv6, cleaned up unix code

Ariel Manzur 9 anos atrás
pai
commit
672225b710

+ 13 - 2
core/io/ip.cpp

@@ -117,7 +117,9 @@ IP_Address IP::resolve_hostname(const String& p_hostname, IP_Address::AddrType p
 	GLOBAL_LOCK_FUNCTION;
 
 	if (resolver->cache.has(p_hostname))
-		return resolver->cache[p_hostname];
+		if (resolver->cache[p_hostname].type & p_type != 0)
+			return resolver->cache[p_hostname];
+		// requested type is different from type in cache. continue resolution, if successful it'll overwrite cache
 
 	IP_Address res = _resolve_hostname(p_hostname, p_type);
 	resolver->cache[p_hostname]=res;
@@ -137,7 +139,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP_Addr
 
 	resolver->queue[id].hostname=p_hostname;
 	resolver->queue[id].type = p_type;
-	if (resolver->cache.has(p_hostname)) {
+	if (resolver->cache.has(p_hostname) && (resolver->cache[p_hostname].type & p_type) != 0) {
 		resolver->queue[id].response=resolver->cache[p_hostname];
 		resolver->queue[id].status=IP::RESOLVER_STATUS_DONE;
 	} else {
@@ -187,6 +189,14 @@ void IP::erase_resolve_item(ResolverID p_id) {
 
 }
 
+void IP::clear_cache(const String &p_hostname) {
+
+	if (p_hostname.empty()) {
+		resolver->cache.clear();
+	} else {
+		resolver->cache.erase(p_hostname);
+	}
+};
 
 Array IP::_get_local_addresses() const {
 
@@ -208,6 +218,7 @@ void IP::_bind_methods() {
 	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);
 	ObjectTypeDB::bind_method(_MD("get_local_addresses"),&IP::_get_local_addresses);
+	ObjectTypeDB::bind_method(_MD("clear_cache"),&IP::clear_cache, DEFVAL(""));
 
 	BIND_CONSTANT( RESOLVER_STATUS_NONE );
 	BIND_CONSTANT( RESOLVER_STATUS_WAITING );

+ 2 - 0
core/io/ip.h

@@ -89,6 +89,8 @@ public:
 	virtual void get_local_addresses(List<IP_Address> *r_addresses) const=0;
 	void erase_resolve_item(ResolverID p_id);
 
+	void clear_cache(const String& p_hostname = "");
+
 	static IP* get_singleton();
 
 	static IP* create();

+ 4 - 25
drivers/unix/packet_peer_udp_posix.cpp

@@ -54,6 +54,7 @@
 #include <arpa/inet.h>
 #endif
 
+#include "drivers/unix/socket_helpers.h"
 
 int PacketPeerUDPPosix::get_available_packet_count() const {
 
@@ -98,17 +99,7 @@ Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer,int p_buffer_size){
 	int sock = _get_socket(peer_addr.type);
 	ERR_FAIL_COND_V( sock == -1, FAILED );
 	struct sockaddr_storage addr;
-	if (peer_addr.type == IP_Address::TYPE_IPV4) {
-		struct sockaddr_in* addr_in = (struct sockaddr_in*)&addr;
-		addr_in->sin_family = AF_INET;
-		addr_in->sin_port = htons(peer_port);
-		addr_in->sin_addr = *((struct in_addr*)&peer_addr.field32[0]);
-	} else {
-		struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)&addr;
-		addr_in6->sin6_family = AF_INET;
-		addr_in6->sin6_port = htons(peer_port);
-		copymem(&addr_in6->sin6_addr.s6_addr, peer_addr.field8, 16);
-	};
+	_set_sockaddr(&addr, peer_addr, peer_port);
 
 	errno = 0;
 	int err;
@@ -138,20 +129,7 @@ Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type
 		return ERR_CANT_CREATE;
 
 	sockaddr_storage addr = {0};
-
-	if (p_address_type == IP_Address::TYPE_IPV4) {
-		struct sockaddr_in* addr4 = (struct sockaddr_in*)&addr;
-		addr4->sin_family = AF_INET;
-		addr4->sin_port = htons(p_port);
-		addr4->sin_addr.s_addr = INADDR_ANY;
-	} else {
-
-		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&addr;
-
-		addr6->sin6_family = AF_INET6;
-		addr6->sin6_port = htons(p_port);
-		addr6->sin6_addr = in6addr_any;
-	};
+	_set_listen_sockaddr(&addr, p_port, p_address_type, NULL);
 
 	if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_storage)) == -1 ) {
 		close();
@@ -212,6 +190,7 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) {
 		rb.write((uint8_t*)&ret, 4);
 		rb.write(recv_buffer, ret);
 
+		len = sizeof(struct sockaddr_storage);
 		++queue_count;
 	};
 

+ 66 - 0
drivers/unix/socket_helpers.h

@@ -0,0 +1,66 @@
+#ifndef SOCKET_HELPERS_H
+#define SOCKET_HELPERS_H
+
+#include <string.h>
+
+// helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this
+
+static void _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) {
+
+	memset(p_addr, 0, sizeof(struct sockaddr_storage));
+	if (p_ip.type == IP_Address::TYPE_IPV6) {
+
+		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);
+
+	} else {
+
+		struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr;
+		addr4->sin_family = AF_INET;    // host byte order
+		addr4->sin_port = htons(p_port);  // short, network byte order
+		addr4->sin_addr = *((struct in_addr*)&p_ip.field32[0]);
+	};
+};
+
+static void _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP_Address::AddrType p_address_type, const List<String> *p_accepted_hosts) {
+
+	memset(p_addr, 0, sizeof(struct sockaddr_storage));
+	if (p_address_type == IP_Address::TYPE_IPV4) {
+		struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr;
+		addr4->sin_family = AF_INET;
+		addr4->sin_port = htons(p_port);
+		addr4->sin_addr.s_addr = INADDR_ANY; // TODO: use accepted hosts list
+	} else {
+		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr;
+
+		addr6->sin6_family = AF_INET6;
+		addr6->sin6_port = htons(p_port);
+		addr6->sin6_addr = in6addr_any; // TODO: use accepted hosts list
+	};
+};
+
+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_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(&addr6->sin6_addr.s6_addr, r_ip.field8, 16);
+
+		r_port = ntohs(addr6->sin6_port);
+	};
+};
+
+
+#endif

+ 4 - 20
drivers/unix/stream_peer_tcp_posix.cpp

@@ -61,24 +61,7 @@
 	#define MSG_NOSIGNAL    SO_NOSIGPIPE
 #endif
 
-static void set_addr_in(struct sockaddr_storage& their_addr, const IP_Address& p_host, uint16_t p_port) {
-
-	memset(&their_addr, 0, sizeof(struct sockaddr_storage));
-	if (p_host.type == IP_Address::TYPE_IPV6) {
-
-		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&their_addr;
-		addr6->sin6_family = AF_INET6;
-		addr6->sin6_port = htons(p_port);
-		copymem(&addr6->sin6_addr.s6_addr, p_host.field8, 16);
-
-	} else {
-
-		struct sockaddr_in* addr4 = (struct sockaddr_in*)&their_addr;
-		addr4->sin_family = AF_INET;    // host byte order
-		addr4->sin_port = htons(p_port);  // short, network byte order
-		addr4->sin_addr = *((struct in_addr*)&p_host.field32[0]);
-	};
-};
+#include "drivers/unix/socket_helpers.h"
 
 StreamPeerTCP* StreamPeerTCPPosix::_create() {
 
@@ -115,7 +98,8 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const {
 	};
 
 	struct sockaddr_storage their_addr;
-	set_addr_in(their_addr, peer_host, peer_port);
+	_set_sockaddr(&their_addr, peer_host, peer_port);
+
 	if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(their_addr)) == -1) {
 
 		if (errno == EISCONN) {
@@ -169,7 +153,7 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) {
 #endif
 
 	struct sockaddr_storage their_addr;
-	set_addr_in(their_addr, p_host, p_port);
+	_set_sockaddr(&their_addr, p_host, p_port);
 
 	errno = 0;
 	if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(their_addr)) == -1 && errno != EINPROGRESS) {

+ 8 - 28
drivers/unix/tcp_server_posix.cpp

@@ -56,6 +56,8 @@
 #include <sys/socket.h>
 #include <assert.h>
 
+#include "drivers/unix/socket_helpers.h"
+
 TCP_Server* TCPServerPosix::_create() {
 
 	return memnew(TCPServerPosix);
@@ -84,19 +86,9 @@ Error TCPServerPosix::listen(uint16_t p_port, IP_Address::AddrType p_type, const
 		WARN_PRINT("REUSEADDR failed!")
 	}
 
-	sockaddr_storage addr = {0};
-	if (p_type == IP_Address::TYPE_IPV4) {
-		struct sockaddr_in* addr4 = (struct sockaddr_in*)&addr;
-		addr4->sin_family = AF_INET;
-		addr4->sin_port = htons(p_port);
-		addr4->sin_addr.s_addr = INADDR_ANY;
-	} else {
-
-		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&addr;
-		addr6->sin6_family = AF_INET6;
-		addr6->sin6_port = htons(p_port);
-		addr6->sin6_addr = in6addr_any;
-	};
+	struct sockaddr_storage addr;
+	_set_listen_sockaddr(&addr, p_port, p_type, p_accepted_hosts);
+
 	// automatically fill with my IP TODO: use p_accepted_hosts
 
 	if (bind(sockfd, (struct sockaddr *)&addr, sizeof addr) != -1) {
@@ -161,22 +153,10 @@ Ref<StreamPeerTCP> TCPServerPosix::take_connection() {
 	Ref<StreamPeerTCPPosix> conn = memnew(StreamPeerTCPPosix);
 	IP_Address ip;
 
-	if (their_addr.ss_family == AF_INET) {
-		ip.type = IP_Address::TYPE_IPV4;
-
-		struct sockaddr_in* addr4 = (struct sockaddr_in*)&their_addr;
-		ip.field32[0] = (uint32_t)addr4->sin_addr.s_addr;
-		conn->set_socket(fd, ip, ntohs(addr4->sin_port));
+	int port;
+	_set_ip_addr_port(ip, port, &their_addr);
 
-	} else if (their_addr.ss_family == AF_INET6) {
-
-		ip.type = IP_Address::TYPE_IPV6;
-
-		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&their_addr;
-		copymem(&addr6->sin6_addr.s6_addr, ip.field8, 16);
-
-		conn->set_socket(fd, ip, ntohs(addr6->sin6_port));
-	};
+	conn->set_socket(fd, ip, port);
 
 	return conn;
 };

+ 54 - 20
platform/windows/packet_peer_udp_winsock.cpp

@@ -29,6 +29,9 @@
 #include "packet_peer_udp_winsock.h"
 
 #include <winsock2.h>
+#include <ws2tcpip.h>
+
+#include "drivers/unix/socket_helpers.h"
 
 int PacketPeerUDPWinsock::get_available_packet_count() const {
 
@@ -48,7 +51,15 @@ Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer,int &r_buffer_si
 		return ERR_UNAVAILABLE;
 
 	uint32_t size;
-	rb.read((uint8_t*)&packet_ip.host,4,true);
+	uint8_t type;
+	rb.read(&type, 1, true);
+	if (type == IP_Address::TYPE_IPV4) {
+		rb.read((uint8_t*)&packet_ip.field8,4,true);
+		packet_ip.type = IP_Address::TYPE_IPV4;
+	} else {
+		rb.read((uint8_t*)&packet_ip.field8,16,true);
+		packet_ip.type = IP_Address::TYPE_IPV6;
+	};
 	rb.read((uint8_t*)&packet_port,4,true);
 	rb.read((uint8_t*)&size,4,true);
 	rb.read(packet_buffer,size,true);
@@ -60,13 +71,10 @@ Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer,int &r_buffer_si
 }
 Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer,int p_buffer_size){
 
-	int sock = _get_socket();
+	int sock = _get_socket(peer_addr.type);
 	ERR_FAIL_COND_V( sock == -1, FAILED );
-	struct sockaddr_in addr;
-	addr.sin_family = AF_INET;
-	addr.sin_port = htons(peer_port);
-	addr.sin_addr = *((struct in_addr*)&peer_addr.host);
-
+	struct sockaddr_storage addr;
+	_set_sockaddr(&addr, peer_addr, peer_port);
 
 	_set_blocking(true);
 
@@ -104,16 +112,16 @@ void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) {
 	};
 }
 
-Error PacketPeerUDPWinsock::listen(int p_port, int p_recv_buffer_size){
+Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) {
 
 	close();
-	int sock = _get_socket();
+	int sock = _get_socket(p_address_type);
 	if (sock == -1 )
 		return ERR_CANT_CREATE;
-	sockaddr_in addr = {0};
-	addr.sin_family = AF_INET;
-	addr.sin_port = htons(p_port);
-	addr.sin_addr.s_addr = INADDR_ANY;
+
+	struct sockaddr_storage addr = {0};
+	_set_listen_sockaddr(&addr, p_port, p_address_type, NULL);
+
 	if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == -1 ) {
 		close();
 		return ERR_UNAVAILABLE;
@@ -146,17 +154,41 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) {
 	_set_blocking(p_wait);
 
 
-	struct sockaddr_in from = {0};
-	int len = sizeof(struct sockaddr_in);
+	struct sockaddr_storage from = {0};
+	int len = sizeof(struct sockaddr_storage);
 	int ret;
 	while ( (ret = recvfrom(sockfd, (char*)recv_buffer, MIN((int)sizeof(recv_buffer),MAX(rb.space_left()-12, 0)), 0, (struct sockaddr*)&from, &len)) > 0) {
-		rb.write((uint8_t*)&from.sin_addr, 4);
-		uint32_t port = ntohs(from.sin_port);
+
+		uint32_t port = 0;
+
+		if (from.ss_family == AF_INET) {
+			uint8_t type = (uint8_t)IP_Address::TYPE_IPV4;
+			rb.write(&type, 1);
+			struct sockaddr_in* sin_from = (struct sockaddr_in*)&from;
+			rb.write((uint8_t*)&sin_from->sin_addr, 4);
+			port = sin_from->sin_port;
+
+		} else if (from.ss_family == AF_INET6) {
+
+			uint8_t type = (uint8_t)IP_Address::TYPE_IPV6;
+			rb.write(&type, 1);
+
+			struct sockaddr_in6* s6_from = (struct sockaddr_in6*)&from;
+			rb.write((uint8_t*)&s6_from->sin6_addr, 16);
+
+			port = s6_from->sin6_port;
+
+		} else {
+			// WARN_PRINT("Ignoring packet with unknown address family");
+			uint8_t type = (uint8_t)IP_Address::TYPE_NONE;
+			rb.write(&type, 1);
+		};
+
 		rb.write((uint8_t*)&port, 4);
 		rb.write((uint8_t*)&ret, 4);
 		rb.write(recv_buffer, ret);
 
-		len = sizeof(struct sockaddr_in);
+		len = sizeof(struct sockaddr_storage);
 		++queue_count;
 	};
 
@@ -202,12 +234,14 @@ int PacketPeerUDPWinsock::get_packet_port() const{
 	return packet_port;
 }
 
-int PacketPeerUDPWinsock::_get_socket() {
+int PacketPeerUDPWinsock::_get_socket(IP_Address::AddrType p_type) {
 
 	if (sockfd != -1)
 		return sockfd;
 
-	sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	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);
 

+ 4 - 4
platform/windows/packet_peer_udp_winsock.h

@@ -42,15 +42,15 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
 	mutable RingBuffer<uint8_t> rb;
 	uint8_t recv_buffer[PACKET_BUFFER_SIZE];
 	mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE];
-	IP_Address packet_ip;
-	int packet_port;
+	mutable IP_Address packet_ip;
+	mutable int packet_port;
 	mutable int queue_count;
 	int sockfd;
 
 	IP_Address peer_addr;
 	int peer_port;
 
-	_FORCE_INLINE_ int _get_socket();
+	_FORCE_INLINE_ int _get_socket(IP_Address::AddrType p_type);
 
 	static PacketPeerUDP* _create();
 
@@ -67,7 +67,7 @@ public:
 
 	virtual int get_max_packet_size() const;
 
-	virtual Error listen(int p_port,int p_recv_buffer_size=65536);
+	virtual Error listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size=65536);
 	virtual void close();
 	virtual Error wait();
 	virtual bool is_listening() const;

+ 10 - 14
platform/windows/stream_peer_winsock.cpp

@@ -31,16 +31,11 @@
 #include "stream_peer_winsock.h"
 
 #include <winsock2.h>
+#include <ws2tcpip.h>
 
-int winsock_refcount = 0;
-
-static void set_addr_in(struct sockaddr_in& their_addr, const IP_Address& p_host, uint16_t p_port) {
+#include "drivers/unix/socket_helpers.h"
 
-	their_addr.sin_family = AF_INET;    // host byte order
-	their_addr.sin_port = htons(p_port);  // short, network byte order
-	their_addr.sin_addr = *((struct in_addr*)&p_host.host);
-	memset(&(their_addr.sin_zero), '\0', 8);
-};
+int winsock_refcount = 0;
 
 StreamPeerTCP* StreamPeerWinsock::_create() {
 
@@ -92,8 +87,8 @@ Error StreamPeerWinsock::_poll_connection(bool p_block) const {
 		_block(sockfd, false, true);
 	};
 
-	struct sockaddr_in their_addr;
-	set_addr_in(their_addr, peer_host, peer_port);
+	struct sockaddr_storage their_addr;
+	_set_sockaddr(&their_addr, peer_host, peer_port);
 
 	if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) {
 
@@ -299,9 +294,10 @@ void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port)
 
 Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) {
 
-	ERR_FAIL_COND_V( p_host.host == 0, ERR_INVALID_PARAMETER);
+	ERR_FAIL_COND_V( p_host.type == IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER);
 
-	if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+	int family = p_host.type == IP_Address::TYPE_IPV6 ? AF_INET6 : AF_INET;
+	if ((sockfd = socket(family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
 		ERR_PRINT("Socket creation failed!");
 		disconnect();
 		//perror("socket");
@@ -315,8 +311,8 @@ Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) {
 		return FAILED;
 	};
 
-	struct sockaddr_in their_addr;
-	set_addr_in(their_addr, p_host, p_port);
+	struct sockaddr_storage their_addr;
+	_set_sockaddr(&their_addr, p_host, p_port);
 
 	if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) {
 

+ 10 - 9
platform/windows/tcp_server_winsock.cpp

@@ -31,6 +31,9 @@
 #include "stream_peer_winsock.h"
 
 #include <winsock2.h>
+#include <ws2tcpip.h>
+
+#include "drivers/unix/socket_helpers.h"
 
 extern int winsock_refcount;
 
@@ -60,7 +63,7 @@ void TCPServerWinsock::cleanup() {
 };
 
 
-Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_hosts) {
+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);
@@ -73,11 +76,8 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_ho
 		return FAILED;
 	};
 
-	struct sockaddr_in my_addr;
-	my_addr.sin_family = AF_INET;         // host byte order
-	my_addr.sin_port = htons(p_port);     // short, network byte order
-	my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP TODO: use p_accepted_hosts
-	memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
+	struct sockaddr_storage my_addr;
+	_set_listen_sockaddr(&my_addr, p_port, p_type, p_accepted_hosts);
 
 	int reuse=1;
 	if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
@@ -140,16 +140,17 @@ Ref<StreamPeerTCP> TCPServerWinsock::take_connection() {
 		return NULL;
 	};
 
-	struct sockaddr_in their_addr;
+	struct sockaddr_storage their_addr;
 	int sin_size = sizeof(their_addr);
 	int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &sin_size);
 	ERR_FAIL_COND_V(fd == INVALID_SOCKET, NULL);
 
 	Ref<StreamPeerWinsock> conn = memnew(StreamPeerWinsock);
 	IP_Address ip;
-	ip.host = (uint32_t)their_addr.sin_addr.s_addr;
+	int port;
+	_set_ip_addr_port(ip, port, &their_addr);
 
-	conn->set_socket(fd, ip, ntohs(their_addr.sin_port));
+	conn->set_socket(fd, ip, port);
 
 	return conn;
 };

+ 1 - 1
platform/windows/tcp_server_winsock.h

@@ -39,7 +39,7 @@ class TCPServerWinsock : public TCP_Server {
 
 public:
 
-	virtual Error listen(uint16_t p_port,const List<String> *p_accepted_hosts=NULL);
+	virtual Error listen(uint16_t p_port, IP_Address::AddrType p_type = IP_Address::TYPE_IPV4,const List<String> *p_accepted_hosts=NULL);
 	virtual bool is_connection_available() const;
 	virtual Ref<StreamPeerTCP> take_connection();