summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/ip.cpp15
-rw-r--r--core/io/ip.h2
-rw-r--r--drivers/unix/packet_peer_udp_posix.cpp29
-rw-r--r--drivers/unix/socket_helpers.h66
-rw-r--r--drivers/unix/stream_peer_tcp_posix.cpp24
-rw-r--r--drivers/unix/tcp_server_posix.cpp36
-rw-r--r--platform/windows/packet_peer_udp_winsock.cpp74
-rw-r--r--platform/windows/packet_peer_udp_winsock.h8
-rw-r--r--platform/windows/stream_peer_winsock.cpp24
-rw-r--r--platform/windows/tcp_server_winsock.cpp19
-rw-r--r--platform/windows/tcp_server_winsock.h2
11 files changed, 176 insertions, 123 deletions
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index aba55687a5..4ee1b281c4 100644
--- a/core/io/ip.cpp
+++ b/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 );
diff --git a/core/io/ip.h b/core/io/ip.h
index 9ffe01b1af..742dd0e740 100644
--- a/core/io/ip.h
+++ b/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();
diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp
index cab2b2bbb9..cdc3bfce28 100644
--- a/drivers/unix/packet_peer_udp_posix.cpp
+++ b/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;
};
diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h
new file mode 100644
index 0000000000..622b45c500
--- /dev/null
+++ b/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
diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp
index bb672cef31..5a63a512e4 100644
--- a/drivers/unix/stream_peer_tcp_posix.cpp
+++ b/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) {
diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp
index 03312a7538..27c5618479 100644
--- a/drivers/unix/tcp_server_posix.cpp
+++ b/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;
};
diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp
index 2c79365c08..cd4e85fd87 100644
--- a/platform/windows/packet_peer_udp_winsock.cpp
+++ b/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);
diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/windows/packet_peer_udp_winsock.h
index b24dbac592..9837ef6621 100644
--- a/platform/windows/packet_peer_udp_winsock.h
+++ b/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;
diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp
index fcf0cb1640..cd9cc99024 100644
--- a/platform/windows/stream_peer_winsock.cpp
+++ b/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) {
diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp
index dd1cf43f3b..049e609d60 100644
--- a/platform/windows/tcp_server_winsock.cpp
+++ b/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;
};
diff --git a/platform/windows/tcp_server_winsock.h b/platform/windows/tcp_server_winsock.h
index bd6a05c74d..94601a2e12 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,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();