aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorRémi Verschelde2017-03-23 08:29:08 +0100
committerGitHub2017-03-23 08:29:08 +0100
commitaaf4e3ab9f8ffca22b34b63aaaf8cc87ead22e48 (patch)
treeed6abd04f1d1ef9bf3bfb92761ed8a58b137a476 /platform
parenta14ad02d155da315b247c03337d98e151b504c61 (diff)
parent15ecdb5f00da2f19974d70ddd8f2658d9f2f4903 (diff)
downloadgodot-aaf4e3ab9f8ffca22b34b63aaaf8cc87ead22e48.tar.gz
godot-aaf4e3ab9f8ffca22b34b63aaaf8cc87ead22e48.tar.zst
godot-aaf4e3ab9f8ffca22b34b63aaaf8cc87ead22e48.zip
Merge pull request #8108 from Faless/2.1-v6fix-cherry
Cherry pick #7510 and #7581 to 2.1
Diffstat (limited to 'platform')
-rw-r--r--platform/windows/packet_peer_udp_winsock.cpp36
-rw-r--r--platform/windows/packet_peer_udp_winsock.h3
-rw-r--r--platform/windows/stream_peer_winsock.cpp29
-rw-r--r--platform/windows/stream_peer_winsock.h5
-rw-r--r--platform/windows/tcp_server_winsock.cpp20
-rw-r--r--platform/windows/tcp_server_winsock.h3
6 files changed, 63 insertions, 33 deletions
diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp
index d8707709f..38c9d322e 100644
--- a/platform/windows/packet_peer_udp_winsock.cpp
+++ b/platform/windows/packet_peer_udp_winsock.cpp
@@ -72,10 +72,15 @@ Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer, int &r_buffer_s
}
Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
+ ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED);
+
+ if (sock_type == IP::TYPE_NONE)
+ sock_type = peer_addr.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+
int sock = _get_socket();
ERR_FAIL_COND_V(sock == -1, FAILED);
struct sockaddr_storage addr;
- size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, ip_type);
+ size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type);
_set_blocking(true);
@@ -112,15 +117,22 @@ 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 p_bind_address, int p_recv_buffer_size) {
+
+ ERR_FAIL_COND_V(sockfd != -1, ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
+
+ sock_type = IP::TYPE_ANY;
+
+ if (p_bind_address.is_valid())
+ sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
- close();
int sock = _get_socket();
if (sock == -1)
return ERR_CANT_CREATE;
struct sockaddr_storage addr = { 0 };
- size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, NULL);
+ size_t addr_size = _set_listen_sockaddr(&addr, p_port, sock_type, IP_Address());
if (bind(sock, (struct sockaddr *)&addr, addr_size) == -1) {
close();
@@ -139,7 +151,8 @@ void PacketPeerUDPWinsock::close() {
if (sockfd != -1)
::closesocket(sockfd);
sockfd = -1;
- rb.resize(8);
+ sock_type = IP::TYPE_NONE;
+ rb.resize(16);
queue_count = 0;
}
@@ -149,12 +162,16 @@ Error PacketPeerUDPWinsock::wait() {
}
Error PacketPeerUDPWinsock::_poll(bool p_wait) {
+ if (sockfd == -1) {
+ return FAILED;
+ }
+
_set_blocking(p_wait);
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) {
+ while ((ret = recvfrom(sockfd, (char *)recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), 0, (struct sockaddr *)&from, &len)) > 0) {
uint32_t port = 0;
@@ -228,10 +245,12 @@ int PacketPeerUDPWinsock::get_packet_port() const {
int PacketPeerUDPWinsock::_get_socket() {
+ ERR_FAIL_COND_V(sock_type == IP::TYPE_NONE, -1);
+
if (sockfd != -1)
return sockfd;
- sockfd = _socket_create(ip_type, SOCK_DGRAM, IPPROTO_UDP);
+ sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP);
return sockfd;
}
@@ -258,7 +277,8 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() {
packet_port = 0;
queue_count = 0;
peer_port = 0;
- ip_type = IP::TYPE_ANY;
+ sock_type = IP::TYPE_NONE;
+ rb.resize(16);
}
PacketPeerUDPWinsock::~PacketPeerUDPWinsock() {
diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/windows/packet_peer_udp_winsock.h
index d24bb8397..47e926600 100644
--- a/platform/windows/packet_peer_udp_winsock.h
+++ b/platform/windows/packet_peer_udp_winsock.h
@@ -45,6 +45,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
mutable int packet_port;
mutable int queue_count;
int sockfd;
+ IP::Type sock_type;
IP_Address peer_addr;
int peer_port;
@@ -65,7 +66,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 p_bind_address = IP_Address("*"), 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 c16fa73bd..7bf43e52f 100644
--- a/platform/windows/stream_peer_winsock.cpp
+++ b/platform/windows/stream_peer_winsock.cpp
@@ -77,17 +77,12 @@ Error StreamPeerWinsock::_block(int p_sockfd, bool p_read, bool p_write) const {
return ret < 0 ? FAILED : OK;
};
-Error StreamPeerWinsock::_poll_connection(bool p_block) const {
+Error StreamPeerWinsock::_poll_connection() const {
ERR_FAIL_COND_V(status != STATUS_CONNECTING || sockfd == INVALID_SOCKET, FAILED);
- if (p_block) {
-
- _block(sockfd, false, true);
- };
-
struct sockaddr_storage their_addr;
- size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port, ip_type);
+ size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port, sock_type);
if (::connect(sockfd, (struct sockaddr *)&their_addr, addr_size) == SOCKET_ERROR) {
@@ -121,7 +116,7 @@ Error StreamPeerWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent,
if (status != STATUS_CONNECTED) {
- if (_poll_connection(p_block) != OK) {
+ if (_poll_connection() != OK) {
return FAILED;
};
@@ -179,7 +174,7 @@ Error StreamPeerWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, b
if (status != STATUS_CONNECTED) {
- if (_poll_connection(p_block) != OK) {
+ if (_poll_connection() != OK) {
return FAILED;
};
@@ -253,7 +248,7 @@ Error StreamPeerWinsock::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r
StreamPeerTCP::Status StreamPeerWinsock::get_status() const {
if (status == STATUS_CONNECTING) {
- _poll_connection(false);
+ _poll_connection();
};
return status;
@@ -277,6 +272,7 @@ void StreamPeerWinsock::disconnect() {
if (sockfd != INVALID_SOCKET)
closesocket(sockfd);
sockfd = INVALID_SOCKET;
+ sock_type = IP::TYPE_NONE;
status = STATUS_NONE;
@@ -284,10 +280,10 @@ void StreamPeerWinsock::disconnect() {
peer_port = 0;
};
-void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type) {
+void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type) {
- ip_type = p_ip_type;
sockfd = p_sockfd;
+ sock_type = p_sock_type;
status = STATUS_CONNECTING;
peer_host = p_host;
peer_port = p_port;
@@ -295,9 +291,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 == IP_Address(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
- sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP);
+ sock_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+ sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP);
if (sockfd == INVALID_SOCKET) {
ERR_PRINT("Socket creation failed!");
disconnect();
@@ -313,7 +310,7 @@ Error StreamPeerWinsock::connect(const IP_Address &p_host, uint16_t p_port) {
};
struct sockaddr_storage their_addr;
- size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, ip_type);
+ size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, sock_type);
if (::connect(sockfd, (struct sockaddr *)&their_addr, addr_size) == SOCKET_ERROR) {
@@ -359,10 +356,10 @@ uint16_t StreamPeerWinsock::get_connected_port() const {
StreamPeerWinsock::StreamPeerWinsock() {
+ sock_type = IP::TYPE_NONE;
sockfd = INVALID_SOCKET;
status = STATUS_NONE;
peer_port = 0;
- ip_type = IP::TYPE_ANY;
};
StreamPeerWinsock::~StreamPeerWinsock() {
diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h
index de5faf981..04a820e7f 100644
--- a/platform/windows/stream_peer_winsock.h
+++ b/platform/windows/stream_peer_winsock.h
@@ -40,12 +40,13 @@ class StreamPeerWinsock : public StreamPeerTCP {
protected:
mutable Status status;
+ IP::Type sock_type;
int sockfd;
Error _block(int p_sockfd, bool p_read, bool p_write) const;
- Error _poll_connection(bool p_block) const;
+ Error _poll_connection() const;
IP_Address peer_host;
int peer_port;
@@ -66,7 +67,7 @@ public:
virtual int get_available_bytes() const;
- void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type);
+ void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type);
virtual IP_Address get_connected_host() const;
virtual uint16_t get_connected_port() const;
diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp
index b65eee30a..67713f5d1 100644
--- a/platform/windows/tcp_server_winsock.cpp
+++ b/platform/windows/tcp_server_winsock.cpp
@@ -62,10 +62,19 @@ void TCPServerWinsock::cleanup() {
};
};
-Error TCPServerWinsock::listen(uint16_t p_port, const List<String> *p_accepted_hosts) {
+Error TCPServerWinsock::listen(uint16_t p_port, const IP_Address p_bind_address) {
+
+ ERR_FAIL_COND_V(listen_sockfd != -1, ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
int sockfd;
- sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP);
+ sock_type = IP::TYPE_ANY;
+
+ // If the bind address is valid use its type as the socket type
+ if (p_bind_address.is_valid())
+ sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+
+ sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP);
ERR_FAIL_COND_V(sockfd == INVALID_SOCKET, FAILED);
unsigned long par = 1;
@@ -76,7 +85,7 @@ Error TCPServerWinsock::listen(uint16_t p_port, const List<String> *p_accepted_h
};
struct sockaddr_storage my_addr;
- size_t addr_size = _set_listen_sockaddr(&my_addr, p_port, ip_type, p_accepted_hosts);
+ size_t addr_size = _set_listen_sockaddr(&my_addr, p_port, sock_type, p_bind_address);
int reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
@@ -146,7 +155,7 @@ Ref<StreamPeerTCP> TCPServerWinsock::take_connection() {
int port;
_set_ip_addr_port(ip, port, &their_addr);
- conn->set_socket(fd, ip, port, ip_type);
+ conn->set_socket(fd, ip, port, sock_type);
return conn;
};
@@ -158,12 +167,13 @@ void TCPServerWinsock::stop() {
};
listen_sockfd = -1;
+ sock_type = IP::TYPE_NONE;
};
TCPServerWinsock::TCPServerWinsock() {
listen_sockfd = INVALID_SOCKET;
- ip_type = IP::TYPE_ANY;
+ sock_type = IP::TYPE_NONE;
};
TCPServerWinsock::~TCPServerWinsock() {
diff --git a/platform/windows/tcp_server_winsock.h b/platform/windows/tcp_server_winsock.h
index 22a504a41..d7b1aee05 100644
--- a/platform/windows/tcp_server_winsock.h
+++ b/platform/windows/tcp_server_winsock.h
@@ -34,11 +34,12 @@
class TCPServerWinsock : public TCP_Server {
int listen_sockfd;
+ IP::Type sock_type;
static TCP_Server *_create();
public:
- virtual Error listen(uint16_t p_port, const List<String> *p_accepted_hosts = NULL);
+ virtual Error listen(uint16_t p_port, const IP_Address p_bind_address = IP_Address("*"));
virtual bool is_connection_available() const;
virtual Ref<StreamPeerTCP> take_connection();