From ccf37c4ca2aabb212ef82bee7162401280f59e4d Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 20 Dec 2016 15:13:16 +0100 Subject: TCP connect always opens correct socket type TCP client connections does not need to rely on ipv6 dual stack sockets (cherry picked from commit 55b4f3686d8f51958132a1a1745cc4e128fd118d) --- drivers/unix/stream_peer_tcp_posix.cpp | 11 ++++++++--- drivers/unix/stream_peer_tcp_posix.h | 3 +-- platform/windows/stream_peer_winsock.cpp | 10 +++++++--- platform/windows/stream_peer_winsock.h | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 58c78b638..7ebcc34c0 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -98,7 +98,7 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { }; 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) == -1) { @@ -125,6 +125,7 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type) { ip_type = p_ip_type; + sock_type = p_ip_type; sockfd = p_sockfd; #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); @@ -143,7 +144,8 @@ Error StreamPeerTCPPosix::connect(const IP_Address &p_host, uint16_t p_port) { ERR_FAIL_COND_V(p_host == IP_Address(), 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 == -1) { ERR_PRINT("Socket creation failed!"); disconnect(); @@ -159,7 +161,7 @@ Error StreamPeerTCPPosix::connect(const IP_Address &p_host, uint16_t p_port) { #endif 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); errno = 0; if (::connect(sockfd, (struct sockaddr *)&their_addr, addr_size) == -1 && errno != EINPROGRESS) { @@ -339,6 +341,8 @@ void StreamPeerTCPPosix::disconnect() { if (sockfd != -1) close(sockfd); + + sock_type = IP::TYPE_NONE; sockfd = -1; status = STATUS_NONE; @@ -387,6 +391,7 @@ uint16_t StreamPeerTCPPosix::get_connected_port() const { StreamPeerTCPPosix::StreamPeerTCPPosix() { + sock_type = IP::TYPE_NONE; sockfd = -1; status = STATUS_NONE; peer_port = 0; diff --git a/drivers/unix/stream_peer_tcp_posix.h b/drivers/unix/stream_peer_tcp_posix.h index f071d3919..c0ce62a7d 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.h @@ -35,13 +35,12 @@ #include "core/io/stream_peer_tcp.h" #include "error_list.h" -#include "core/io/ip_address.h" - class StreamPeerTCPPosix : public StreamPeerTCP { protected: mutable Status status; + IP::Type sock_type; int sockfd; Error _block(int p_sockfd, bool p_read, bool p_write) const; diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index c16fa73bd..99ee5ef47 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -87,7 +87,7 @@ Error StreamPeerWinsock::_poll_connection(bool p_block) const { }; 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) { @@ -277,6 +277,7 @@ void StreamPeerWinsock::disconnect() { if (sockfd != INVALID_SOCKET) closesocket(sockfd); sockfd = INVALID_SOCKET; + sock_type = IP::TYPE_NONE; status = STATUS_NONE; @@ -288,6 +289,7 @@ void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, ip_type = p_ip_type; sockfd = p_sockfd; + sock_type = p_ip_type; status = STATUS_CONNECTING; peer_host = p_host; peer_port = p_port; @@ -297,7 +299,8 @@ Error StreamPeerWinsock::connect(const IP_Address &p_host, uint16_t p_port) { ERR_FAIL_COND_V(p_host == IP_Address(), 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 +316,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,6 +362,7 @@ uint16_t StreamPeerWinsock::get_connected_port() const { StreamPeerWinsock::StreamPeerWinsock() { + sock_type = IP::TYPE_NONE; sockfd = INVALID_SOCKET; status = STATUS_NONE; peer_port = 0; diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h index de5faf981..7bea3c564 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -40,6 +40,7 @@ class StreamPeerWinsock : public StreamPeerTCP { protected: mutable Status status; + IP::Type sock_type; int sockfd; -- cgit v1.2.3-70-g09d2 From aeffe74a27fbe83f9f3da2672e2b62efe1255bf0 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 10:48:50 +0100 Subject: Avoid calling close when polling a UDP peer without socket (cherry picked from commit e4b9b37ccf8495be674bc15cf0bf9d76fe94e6be) --- drivers/unix/packet_peer_udp_posix.cpp | 4 ++++ platform/windows/packet_peer_udp_winsock.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 04be55d6c..faabe902f 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -154,6 +154,10 @@ Error PacketPeerUDPPosix::wait() { Error PacketPeerUDPPosix::_poll(bool p_wait) { + if (sockfd == -1) { + return FAILED; + } + struct sockaddr_storage from = { 0 }; socklen_t len = sizeof(struct sockaddr_storage); int ret; diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index d8707709f..1dc23fcab 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -149,6 +149,10 @@ Error PacketPeerUDPWinsock::wait() { } Error PacketPeerUDPWinsock::_poll(bool p_wait) { + if (sockfd == -1) { + return FAILED; + } + _set_blocking(p_wait); struct sockaddr_storage from = { 0 }; -- cgit v1.2.3-70-g09d2 From 603105df189699c62b9462839302dae7d9a090de Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 17 Jan 2017 09:22:56 +0100 Subject: Convert validity checks of IP_Address to is_valid method. (cherry picked from commit 98a7e2b4e09791705cd9dfd4d13611bc02fe47d4) --- core/io/ip.cpp | 2 +- core/io/ip_address.cpp | 20 ++++++++++++++++---- core/io/ip_address.h | 7 +++++++ core/io/packet_peer_udp.cpp | 2 +- core/io/stream_peer_tcp.cpp | 2 +- drivers/unix/packet_peer_udp_posix.cpp | 2 +- drivers/unix/socket_helpers.h | 2 +- drivers/unix/stream_peer_tcp_posix.cpp | 2 +- platform/windows/stream_peer_winsock.cpp | 2 +- 9 files changed, 30 insertions(+), 11 deletions(-) diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 963e8a612..0d9296159 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -81,7 +81,7 @@ struct _IP_ResolverPrivate { continue; queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type); - if (queue[i].response == IP_Address()) + if (!queue[i].response.is_valid()) queue[i].status = IP::RESOLVER_STATUS_ERROR; else queue[i].status = IP::RESOLVER_STATUS_DONE; diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index e03dac8d3..594edbf8e 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -38,6 +38,9 @@ IP_Address::operator Variant() const { IP_Address::operator String() const { + if (!valid) + return ""; + if (is_ipv4()) // IPv4 address mapped to IPv6 return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]); @@ -170,6 +173,7 @@ void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret void IP_Address::clear() { memset(&field8[0], 0, sizeof(field8)); + valid = false; }; bool IP_Address::is_ipv4() const { @@ -183,6 +187,7 @@ const uint8_t *IP_Address::get_ipv4() const { void IP_Address::set_ipv4(const uint8_t *p_ip) { clear(); + valid = true; field16[5] = 0xffff; field32[3] = *((const uint32_t *)p_ip); } @@ -193,6 +198,7 @@ const uint8_t *IP_Address::get_ipv6() const { void IP_Address::set_ipv6(const uint8_t *p_buf) { clear(); + valid = true; for (int i = 0; i < 16; i++) field8[i] = p_buf[i]; } @@ -201,13 +207,18 @@ IP_Address::IP_Address(const String &p_string) { clear(); if (p_string.find(":") >= 0) { - + // IPv6 _parse_ipv6(p_string); - } else { - // Mapped to IPv6 + valid = true; + } else if (p_string.get_slice_count(".") == 4) { + // IPv4 (mapped to IPv6 internally) field16[5] = 0xffff; _parse_ipv4(p_string, 0, &field8[12]); - }; + valid = true; + + } else { + ERR_PRINT("Invalid IP address"); + } } _FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) { @@ -221,6 +232,7 @@ _FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) { IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) { clear(); + valid = true; if (!is_v6) { // Mapped to IPv6 field16[5] = 0xffff; diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 200df57aa..2ed77cc3b 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -40,6 +40,8 @@ private: uint32_t field32[4]; }; + bool valid; + protected: void _parse_ipv6(const String &p_string); void _parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret); @@ -47,12 +49,16 @@ protected: public: //operator Variant() const; bool operator==(const IP_Address &p_ip) const { + if (p_ip.valid != valid) return false; + if (!valid) return false; for (int i = 0; i < 4; i++) if (field32[i] != p_ip.field32[i]) return false; return true; } bool operator!=(const IP_Address &p_ip) const { + if (p_ip.valid != valid) return true; + if (!valid) return true; for (int i = 0; i < 4; i++) if (field32[i] != p_ip.field32[i]) return true; @@ -60,6 +66,7 @@ public: } void clear(); + bool is_valid() const { return valid; } bool is_ipv4() const; const uint8_t *get_ipv4() const; void set_ipv4(const uint8_t *p_ip); diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index eb51a4207..8e5e46fd9 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -43,7 +43,7 @@ Error PacketPeerUDP::_set_send_address(const String &p_address, int p_port) { ip = p_address; } else { ip = IP::get_singleton()->resolve_hostname(p_address, ip_type); - if (ip == IP_Address()) + if (!ip.is_valid()) return ERR_CANT_RESOLVE; } diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index 753d66734..f303d8fd1 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -37,7 +37,7 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) { ip = p_address; } else { ip = IP::get_singleton()->resolve_hostname(p_address, ip_type); - if (ip == IP_Address()) + if (!ip.is_valid()) return ERR_CANT_RESOLVE; } diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index faabe902f..13fef5921 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -94,7 +94,7 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer, int &r_buffer_siz } Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer, int p_buffer_size) { - ERR_FAIL_COND_V(peer_addr == IP_Address(), ERR_UNCONFIGURED); + ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED); int sock = _get_socket(); ERR_FAIL_COND_V(sock == -1, FAILED); diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index c7828ae94..80f02f623 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -16,7 +16,7 @@ static size_t _set_sockaddr(struct sockaddr_storage *p_addr, const IP_Address &p memset(p_addr, 0, sizeof(struct sockaddr_storage)); - ERR_FAIL_COND_V(p_ip == IP_Address(), 0); + ERR_FAIL_COND_V(!p_ip.is_valid(), 0); // IPv6 socket if (p_sock_type == IP::TYPE_IPV6 || p_sock_type == IP::TYPE_ANY) { diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 7ebcc34c0..779d9e427 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -142,7 +142,7 @@ void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, Error StreamPeerTCPPosix::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); sock_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP); diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index 99ee5ef47..6723a6d0f 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -297,7 +297,7 @@ 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); sock_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP); -- cgit v1.2.3-70-g09d2 From 90a747a52dac1214a1ff1c6b7c65228bf41a6e1f Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 04:03:51 +0100 Subject: IP_Address can now be a wildcard (not a valid IP, used for binding) (cherry picked from commit 4198291cd45da7fce278d21cd5ef4a506086d5f8) --- core/io/ip_address.cpp | 9 ++++++++- core/io/ip_address.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 594edbf8e..fa0eab4f0 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -174,6 +174,7 @@ void IP_Address::clear() { memset(&field8[0], 0, sizeof(field8)); valid = false; + wildcard = false; }; bool IP_Address::is_ipv4() const { @@ -206,10 +207,16 @@ void IP_Address::set_ipv6(const uint8_t *p_buf) { IP_Address::IP_Address(const String &p_string) { clear(); - if (p_string.find(":") >= 0) { + + if (p_string == "*") { + // Wildcard (not a vaild IP) + wildcard = true; + + } else if (p_string.find(":") >= 0) { // IPv6 _parse_ipv6(p_string); valid = true; + } else if (p_string.get_slice_count(".") == 4) { // IPv4 (mapped to IPv6 internally) field16[5] = 0xffff; diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 2ed77cc3b..52d6974d5 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -41,6 +41,7 @@ private: }; bool valid; + bool wildcard; protected: void _parse_ipv6(const String &p_string); @@ -66,6 +67,7 @@ public: } void clear(); + bool is_wildcard() const { return wildcard; } bool is_valid() const { return valid; } bool is_ipv4() const; const uint8_t *get_ipv4() const; -- cgit v1.2.3-70-g09d2 From 43d992fc3413af7a0fea54eeded8609e4ebd0f16 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 08:37:24 +0100 Subject: Implement TCP Server bind address (cherry picked from commit b2839343cab66880f647c77da7b2e1826761776a) --- core/io/tcp_server.cpp | 11 +---------- core/io/tcp_server.h | 3 +-- drivers/unix/packet_peer_udp_posix.cpp | 2 +- drivers/unix/socket_helpers.h | 14 +++++++++++--- drivers/unix/tcp_server_posix.cpp | 21 +++++++++++++++------ drivers/unix/tcp_server_posix.h | 3 ++- platform/windows/packet_peer_udp_winsock.cpp | 2 +- platform/windows/tcp_server_winsock.cpp | 19 +++++++++++++++---- platform/windows/tcp_server_winsock.h | 3 ++- 9 files changed, 49 insertions(+), 29 deletions(-) diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index 2b4206ba3..393dd363a 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -44,15 +44,6 @@ TCP_Server *TCP_Server::create() { return _create(); } -Error TCP_Server::_listen(uint16_t p_port, DVector p_accepted_hosts) { - - List hosts; - for (int i = 0; i < p_accepted_hosts.size(); i++) - hosts.push_back(p_accepted_hosts.get(i)); - - return listen(p_port, hosts.size() ? &hosts : NULL); -} - void TCP_Server::set_ip_type(IP::Type p_type) { stop(); ip_type = p_type; @@ -61,7 +52,7 @@ void TCP_Server::set_ip_type(IP::Type p_type) { void TCP_Server::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &TCP_Server::set_ip_type); - ObjectTypeDB::bind_method(_MD("listen", "port", "accepted_hosts"), &TCP_Server::_listen, DEFVAL(DVector())); + ObjectTypeDB::bind_method(_MD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*")); 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 481945b6d..671b03308 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -43,12 +43,11 @@ protected: static TCP_Server *(*_create)(); //bind helper - Error _listen(uint16_t p_port, DVector p_accepted_hosts = DVector()); static void _bind_methods(); public: virtual void set_ip_type(IP::Type p_type); - virtual Error listen(uint16_t p_port, const List *p_accepted_hosts = NULL) = 0; + virtual Error listen(uint16_t p_port, const IP_Address p_bind_address = IP_Address("*")) = 0; virtual bool is_connection_available() const = 0; virtual Ref take_connection() = 0; diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 13fef5921..c5daba4d2 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -128,7 +128,7 @@ Error PacketPeerUDPPosix::listen(int p_port, int p_recv_buffer_size) { return ERR_CANT_CREATE; 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, ip_type, IP_Address()); if (bind(sock, (struct sockaddr *)&addr, addr_size) == -1) { close(); diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 80f02f623..b3b0d4e53 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -44,21 +44,29 @@ static size_t _set_sockaddr(struct sockaddr_storage *p_addr, const IP_Address &p }; }; -static size_t _set_listen_sockaddr(struct sockaddr_storage *p_addr, int p_port, IP::Type p_sock_type, const List *p_accepted_hosts) { +static size_t _set_listen_sockaddr(struct sockaddr_storage *p_addr, int p_port, IP::Type p_sock_type, const IP_Address p_bind_address) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); if (p_sock_type == IP::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 + if (p_bind_address.is_valid()) { + copymem(&addr4->sin_addr.s_addr, p_bind_address.get_ipv4(), 4); + } else { + addr4->sin_addr.s_addr = INADDR_ANY; + } return sizeof(sockaddr_in); } 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 + if (p_bind_address.is_valid()) { + copymem(&addr6->sin6_addr.s6_addr, p_bind_address.get_ipv6(), 16); + } else { + addr6->sin6_addr = in6addr_any; + } return sizeof(sockaddr_in6); }; }; diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index cdd451062..79ebf1873 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -68,10 +68,19 @@ void TCPServerPosix::make_default() { TCP_Server::_create = TCPServerPosix::_create; }; -Error TCPServerPosix::listen(uint16_t p_port, const List *p_accepted_hosts) { +Error TCPServerPosix::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; + + // 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 == -1, FAILED); @@ -88,9 +97,7 @@ Error TCPServerPosix::listen(uint16_t p_port, const List *p_accepted_hos } struct sockaddr_storage addr; - size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, p_accepted_hosts); - - // automatically fill with my IP TODO: use p_accepted_hosts + size_t addr_size = _set_listen_sockaddr(&addr, p_port, sock_type, p_bind_address); if (bind(sockfd, (struct sockaddr *)&addr, addr_size) != -1) { @@ -156,7 +163,7 @@ Ref TCPServerPosix::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; }; @@ -169,12 +176,14 @@ void TCPServerPosix::stop() { }; listen_sockfd = -1; + sock_type = IP::TYPE_NONE; }; TCPServerPosix::TCPServerPosix() { listen_sockfd = -1; ip_type = IP::TYPE_ANY; + sock_type = IP::TYPE_NONE; }; TCPServerPosix::~TCPServerPosix() { diff --git a/drivers/unix/tcp_server_posix.h b/drivers/unix/tcp_server_posix.h index aa02b4c46..408179c19 100644 --- a/drivers/unix/tcp_server_posix.h +++ b/drivers/unix/tcp_server_posix.h @@ -35,11 +35,12 @@ class TCPServerPosix : public TCP_Server { int listen_sockfd; + IP::Type sock_type; static TCP_Server *_create(); public: - virtual Error listen(uint16_t p_port, const List *p_accepted_hosts = NULL); + virtual Error listen(uint16_t p_port, IP_Address p_bind_address = IP_Address("*")); virtual bool is_connection_available() const; virtual Ref take_connection(); diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 1dc23fcab..92cc720f4 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -120,7 +120,7 @@ Error PacketPeerUDPWinsock::listen(int p_port, int p_recv_buffer_size) { 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, ip_type, IP_Address()); if (bind(sock, (struct sockaddr *)&addr, addr_size) == -1) { close(); diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index b65eee30a..0f117bc6b 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 *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; + + // 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 *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 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,14 @@ 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 *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 take_connection(); -- cgit v1.2.3-70-g09d2 From 0b9684a085f244210f166070a9589bdd70876196 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 10:24:26 +0100 Subject: Implement UDP listen bind address (cherry picked from commit 2fe4ef66991b483640f59873c22b3af671626ccc) --- core/io/packet_peer_udp.cpp | 2 +- core/io/packet_peer_udp.h | 4 ++-- drivers/unix/packet_peer_udp_posix.cpp | 24 +++++++++++++++++++----- drivers/unix/packet_peer_udp_posix.h | 3 ++- platform/windows/packet_peer_udp_winsock.cpp | 26 +++++++++++++++++++++----- platform/windows/packet_peer_udp_winsock.h | 3 ++- 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 8e5e46fd9..0c008b6dc 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -59,7 +59,7 @@ void PacketPeerUDP::set_ip_type(IP::Type p_type) { void PacketPeerUDP::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &PacketPeerUDP::set_ip_type); - ObjectTypeDB::bind_method(_MD("listen:Error", "port", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL(65536)); + ObjectTypeDB::bind_method(_MD("listen:Error", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), 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); diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index e17f9b505..e20863045 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -43,11 +43,11 @@ protected: String _get_packet_ip() const; - virtual Error _set_send_address(const String &p_address, int p_port); + Error _set_send_address(const String &p_address, int p_port); public: virtual void set_ip_type(IP::Type p_type); - virtual Error listen(int p_port, int p_recv_buffer_size = 65536) = 0; + virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0; virtual void close() = 0; virtual Error wait() = 0; virtual bool is_listening() const = 0; diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index c5daba4d2..ea900062f 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -96,10 +96,13 @@ Error PacketPeerUDPPosix::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); errno = 0; int err; @@ -119,16 +122,23 @@ int PacketPeerUDPPosix::get_max_packet_size() const { return 512; // uhm maybe not } -Error PacketPeerUDPPosix::listen(int p_port, int p_recv_buffer_size) { +Error PacketPeerUDPPosix::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; + + 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; sockaddr_storage addr = { 0 }; - size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, IP_Address()); + size_t addr_size = _set_listen_sockaddr(&addr, p_port, sock_type, IP_Address()); if (bind(sock, (struct sockaddr *)&addr, addr_size) == -1) { close(); @@ -143,6 +153,7 @@ void PacketPeerUDPPosix::close() { if (sockfd != -1) ::close(sockfd); sockfd = -1; + sock_type = IP::TYPE_NONE; rb.resize(8); queue_count = 0; } @@ -221,10 +232,12 @@ int PacketPeerUDPPosix::get_packet_port() const { int PacketPeerUDPPosix::_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; } @@ -251,6 +264,7 @@ PacketPeerUDPPosix::PacketPeerUDPPosix() { packet_port = 0; queue_count = 0; peer_port = 0; + sock_type = IP::TYPE_NONE; ip_type = IP::TYPE_ANY; } diff --git a/drivers/unix/packet_peer_udp_posix.h b/drivers/unix/packet_peer_udp_posix.h index ee0cd2dbd..027ec3be7 100644 --- a/drivers/unix/packet_peer_udp_posix.h +++ b/drivers/unix/packet_peer_udp_posix.h @@ -47,6 +47,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP { mutable int packet_port; mutable int queue_count; int sockfd; + IP::Type sock_type; IP_Address peer_addr; int peer_port; @@ -63,7 +64,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/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 92cc720f4..4ee94c264 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; + + 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, IP_Address()); + 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,6 +151,7 @@ void PacketPeerUDPWinsock::close() { if (sockfd != -1) ::closesocket(sockfd); sockfd = -1; + sock_type = IP::TYPE_NONE; rb.resize(8); queue_count = 0; } @@ -232,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; } @@ -263,6 +278,7 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() { queue_count = 0; peer_port = 0; ip_type = IP::TYPE_ANY; + sock_type = IP::TYPE_NONE; } 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; -- cgit v1.2.3-70-g09d2 From d9525082feb6165944082fb80ae7785b23a2250c Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 12:47:12 +0100 Subject: Remove set_ip_type from network classes (no longer needed) - TCP: - `listen` bind to wildcard "*" -> dual stack socket - `listen` bind to address -> socket from address type - `connect` -> resolve using best protocol (UNSPEC), socket from address type - UDP: - `listen` bind to wildcard "*" -> dual stack socket - `listen` bind to address -> socket from address type - `put_packet`/`put_var` -> resolve using TYPE_ANY (UNSPEC), socket from address type (to change socket type you must first call `close` it) (cherry picked from commit 88a56ba783d36d52a1023759e69f026b1ae255b4) --- core/io/http_client.cpp | 9 +-------- core/io/http_client.h | 2 -- core/io/packet_peer_udp.cpp | 9 +-------- core/io/packet_peer_udp.h | 3 --- core/io/stream_peer_tcp.cpp | 10 +--------- core/io/stream_peer_tcp.h | 1 - core/io/tcp_server.cpp | 7 ------- core/io/tcp_server.h | 3 --- drivers/unix/packet_peer_udp_posix.cpp | 3 +-- drivers/unix/stream_peer_tcp_posix.cpp | 6 ++---- drivers/unix/stream_peer_tcp_posix.h | 2 +- drivers/unix/tcp_server_posix.cpp | 3 +-- platform/windows/packet_peer_udp_winsock.cpp | 3 +-- platform/windows/stream_peer_winsock.cpp | 6 ++---- platform/windows/stream_peer_winsock.h | 2 +- platform/windows/tcp_server_winsock.cpp | 3 +-- scene/main/http_request.cpp | 5 ----- scene/main/http_request.h | 1 - 18 files changed, 13 insertions(+), 65 deletions(-) diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index adc95e962..dc541a513 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -29,14 +29,9 @@ #include "http_client.h" #include "io/stream_peer_ssl.h" -void HTTPClient::set_ip_type(IP::Type p_type) { - ip_type = p_type; -} - Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) { close(); - tcp_connection->set_ip_type(ip_type); conn_port = p_port; conn_host = p_host; @@ -63,7 +58,7 @@ Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl, bool p_v status = STATUS_CONNECTING; } else { //is hostname - resolving = IP::get_singleton()->resolve_hostname_queue_item(conn_host, ip_type); + resolving = IP::get_singleton()->resolve_hostname_queue_item(conn_host); status = STATUS_RESOLVING; } @@ -618,7 +613,6 @@ Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received void HTTPClient::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &HTTPClient::set_ip_type); ObjectTypeDB::bind_method(_MD("connect:Error", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect, DEFVAL(false), DEFVAL(true)); ObjectTypeDB::bind_method(_MD("set_connection", "connection:StreamPeer"), &HTTPClient::set_connection); ObjectTypeDB::bind_method(_MD("get_connection:StreamPeer"), &HTTPClient::get_connection); @@ -742,7 +736,6 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { HTTPClient::HTTPClient() { - ip_type = IP::TYPE_ANY; tcp_connection = StreamPeerTCP::create_ref(); resolving = IP::RESOLVER_INVALID_ID; status = STATUS_DISCONNECTED; diff --git a/core/io/http_client.h b/core/io/http_client.h index 43d6dc721..ac2bd7417 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -130,7 +130,6 @@ public: }; private: - IP::Type ip_type; Status status; IP::ResolverID resolving; int conn_port; @@ -161,7 +160,6 @@ private: Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received); public: - void set_ip_type(IP::Type p_type); //Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request Error connect(const String &p_host, int p_port, bool p_ssl = false, bool p_verify_host = true); diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 0c008b6dc..067c1c1bd 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -42,7 +42,7 @@ Error PacketPeerUDP::_set_send_address(const String &p_address, int p_port) { if (p_address.is_valid_ip_address()) { ip = p_address; } else { - ip = IP::get_singleton()->resolve_hostname(p_address, ip_type); + ip = IP::get_singleton()->resolve_hostname(p_address); if (!ip.is_valid()) return ERR_CANT_RESOLVE; } @@ -51,14 +51,8 @@ Error PacketPeerUDP::_set_send_address(const String &p_address, int p_port) { return OK; } -void PacketPeerUDP::set_ip_type(IP::Type p_type) { - close(); - ip_type = p_type; -} - void PacketPeerUDP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &PacketPeerUDP::set_ip_type); ObjectTypeDB::bind_method(_MD("listen:Error", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), DEFVAL(65536)); ObjectTypeDB::bind_method(_MD("close"), &PacketPeerUDP::close); ObjectTypeDB::bind_method(_MD("wait:Error"), &PacketPeerUDP::wait); @@ -84,5 +78,4 @@ PacketPeerUDP *PacketPeerUDP::create() { } PacketPeerUDP::PacketPeerUDP() { - ip_type = IP::TYPE_ANY; } diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index e20863045..8fcbc9472 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -36,8 +36,6 @@ class PacketPeerUDP : public PacketPeer { OBJ_TYPE(PacketPeerUDP, PacketPeer); protected: - IP::Type ip_type; - static PacketPeerUDP *(*_create)(); static void _bind_methods(); @@ -46,7 +44,6 @@ protected: Error _set_send_address(const String &p_address, int p_port); public: - virtual void set_ip_type(IP::Type p_type); virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0; virtual void close() = 0; virtual Error wait() = 0; diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index f303d8fd1..032f58a4c 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -36,7 +36,7 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) { if (p_address.is_valid_ip_address()) { ip = p_address; } else { - ip = IP::get_singleton()->resolve_hostname(p_address, ip_type); + ip = IP::get_singleton()->resolve_hostname(p_address); if (!ip.is_valid()) return ERR_CANT_RESOLVE; } @@ -45,14 +45,8 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) { return OK; } -void StreamPeerTCP::set_ip_type(IP::Type p_type) { - disconnect(); - ip_type = p_type; -} - void StreamPeerTCP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &StreamPeerTCP::set_ip_type); ObjectTypeDB::bind_method(_MD("connect", "host", "port"), &StreamPeerTCP::_connect); ObjectTypeDB::bind_method(_MD("is_connected"), &StreamPeerTCP::is_connected); ObjectTypeDB::bind_method(_MD("get_status"), &StreamPeerTCP::get_status); @@ -81,8 +75,6 @@ StreamPeerTCP *StreamPeerTCP::create() { } StreamPeerTCP::StreamPeerTCP() { - - ip_type = IP::TYPE_ANY; } StreamPeerTCP::~StreamPeerTCP(){ diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index a97f42937..36ed9d1d7 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -56,7 +56,6 @@ protected: static void _bind_methods(); public: - virtual void set_ip_type(IP::Type p_type); virtual Error connect(const IP_Address &p_host, uint16_t p_port) = 0; //read/write from streampeer diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index 393dd363a..4514a0289 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -44,14 +44,8 @@ TCP_Server *TCP_Server::create() { return _create(); } -void TCP_Server::set_ip_type(IP::Type p_type) { - stop(); - ip_type = p_type; -} - void TCP_Server::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &TCP_Server::set_ip_type); ObjectTypeDB::bind_method(_MD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*")); ObjectTypeDB::bind_method(_MD("is_connection_available"), &TCP_Server::is_connection_available); ObjectTypeDB::bind_method(_MD("take_connection"), &TCP_Server::take_connection); @@ -59,5 +53,4 @@ void TCP_Server::_bind_methods() { } TCP_Server::TCP_Server() { - ip_type = IP::TYPE_ANY; } diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index 671b03308..13cc590ed 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -38,15 +38,12 @@ class TCP_Server : public Reference { OBJ_TYPE(TCP_Server, Reference); protected: - IP::Type ip_type; - static TCP_Server *(*_create)(); //bind helper static void _bind_methods(); public: - virtual void set_ip_type(IP::Type p_type); virtual Error listen(uint16_t p_port, const IP_Address p_bind_address = IP_Address("*")) = 0; virtual bool is_connection_available() const = 0; virtual Ref take_connection() = 0; diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index ea900062f..bfbbf6cce 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -127,7 +127,7 @@ Error PacketPeerUDPPosix::listen(int p_port, IP_Address p_bind_address, int p_re 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; + sock_type = IP::TYPE_ANY; if (p_bind_address.is_valid()) sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; @@ -265,7 +265,6 @@ PacketPeerUDPPosix::PacketPeerUDPPosix() { queue_count = 0; peer_port = 0; sock_type = IP::TYPE_NONE; - ip_type = IP::TYPE_ANY; } PacketPeerUDPPosix::~PacketPeerUDPPosix() { diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 779d9e427..9f551a8f4 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -122,10 +122,9 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { return OK; }; -void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type) { +void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type) { - ip_type = p_ip_type; - sock_type = p_ip_type; + sock_type = p_sock_type; sockfd = p_sockfd; #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); @@ -395,7 +394,6 @@ StreamPeerTCPPosix::StreamPeerTCPPosix() { sockfd = -1; status = STATUS_NONE; peer_port = 0; - ip_type = IP::TYPE_ANY; }; StreamPeerTCPPosix::~StreamPeerTCPPosix() { diff --git a/drivers/unix/stream_peer_tcp_posix.h b/drivers/unix/stream_peer_tcp_posix.h index c0ce62a7d..cd50d4167 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.h @@ -66,7 +66,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/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 79ebf1873..6aec5ad31 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -74,7 +74,7 @@ Error TCPServerPosix::listen(uint16_t p_port, const IP_Address p_bind_address) { ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER); int sockfd; - sock_type = ip_type; + sock_type = IP::TYPE_ANY; // If the bind address is valid use its type as the socket type if (p_bind_address.is_valid()) @@ -182,7 +182,6 @@ void TCPServerPosix::stop() { TCPServerPosix::TCPServerPosix() { listen_sockfd = -1; - ip_type = IP::TYPE_ANY; sock_type = IP::TYPE_NONE; }; diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 4ee94c264..e326a5a6f 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -122,7 +122,7 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_ 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; + sock_type = IP::TYPE_ANY; if (p_bind_address.is_valid()) sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; @@ -277,7 +277,6 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() { packet_port = 0; queue_count = 0; peer_port = 0; - ip_type = IP::TYPE_ANY; sock_type = IP::TYPE_NONE; } diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index 6723a6d0f..de79941e2 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -285,11 +285,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_ip_type; + sock_type = p_sock_type; status = STATUS_CONNECTING; peer_host = p_host; peer_port = p_port; @@ -366,7 +365,6 @@ StreamPeerWinsock::StreamPeerWinsock() { 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 7bea3c564..db27001c6 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -67,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 0f117bc6b..67713f5d1 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -68,7 +68,7 @@ Error TCPServerWinsock::listen(uint16_t p_port, const IP_Address p_bind_address) ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER); int sockfd; - sock_type = ip_type; + sock_type = IP::TYPE_ANY; // If the bind address is valid use its type as the socket type if (p_bind_address.is_valid()) @@ -173,7 +173,6 @@ void TCPServerWinsock::stop() { TCPServerWinsock::TCPServerWinsock() { listen_sockfd = INVALID_SOCKET; - ip_type = IP::TYPE_ANY; sock_type = IP::TYPE_NONE; }; diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index d977548d6..97832521c 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -28,10 +28,6 @@ /*************************************************************************/ #include "http_request.h" -void HTTPRequest::set_ip_type(IP::Type p_type) { - client->set_ip_type(p_type); -} - void HTTPRequest::_redirect_request(const String &p_new_url) { } @@ -519,7 +515,6 @@ int HTTPRequest::get_body_size() const { void HTTPRequest::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &HTTPRequest::set_ip_type); ObjectTypeDB::bind_method(_MD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(StringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); ObjectTypeDB::bind_method(_MD("cancel_request"), &HTTPRequest::cancel_request); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 6a63fa66a..e7da0e1e3 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -113,7 +113,6 @@ protected: static void _bind_methods(); public: - void set_ip_type(IP::Type p_type); Error request(const String &p_url, const Vector &p_custom_headers = Vector(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const String &p_request_data = ""); //connects to a full url and perform request void cancel_request(); HTTPClient::Status get_http_client_status() const; -- cgit v1.2.3-70-g09d2 From 86de0bd081669c40578b408e2f38fea76b0416ce Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 17:17:44 +0100 Subject: Bind to IPv4 on OpenBSD when using wildcard OpenBSD does not support binding on both IPv4 and IPv6 using the same socket (cherry picked from commit 619e7a2c8ba19d0dc45467e29d9d9aa8b3506ac8) --- drivers/unix/packet_peer_udp_posix.cpp | 4 ++++ drivers/unix/tcp_server_posix.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index bfbbf6cce..4040aaaf4 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -127,7 +127,11 @@ Error PacketPeerUDPPosix::listen(int p_port, IP_Address p_bind_address, int p_re 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); +#ifdef __OpenBSD__ + sock_type = IP::TYPE_IPV4; // OpenBSD does not support dual stacking, fallback to IPv4 only. +#else sock_type = IP::TYPE_ANY; +#endif if (p_bind_address.is_valid()) sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 6aec5ad31..9049faebb 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -74,7 +74,11 @@ Error TCPServerPosix::listen(uint16_t p_port, const IP_Address p_bind_address) { ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER); int sockfd; +#ifdef __OpenBSD__ + sock_type = IP::TYPE_IPV4; // OpenBSD does not support dual stacking, fallback to IPv4 only. +#else sock_type = IP::TYPE_ANY; +#endif // If the bind address is valid use its type as the socket type if (p_bind_address.is_valid()) -- cgit v1.2.3-70-g09d2 From 9f41c0a356c016a86418a44c35ad1fb3f5978fd2 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 19:04:37 +0100 Subject: Avoid deadlock when writing/reading data on a connecting TCP socket TCP status polling is always performed as non blocking. Trying to put a packet on a connecting socket will fail immediately. (cherry picked from commit fa0cb7da0e096e01476eabef37c225404c7f6f26) --- drivers/unix/stream_peer_tcp_posix.cpp | 13 ++++--------- drivers/unix/stream_peer_tcp_posix.h | 2 +- platform/windows/stream_peer_winsock.cpp | 13 ++++--------- platform/windows/stream_peer_winsock.h | 2 +- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 9f551a8f4..4063eb3a3 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -88,15 +88,10 @@ Error StreamPeerTCPPosix::_block(int p_sockfd, bool p_read, bool p_write) const return ret < 0 ? FAILED : OK; }; -Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { +Error StreamPeerTCPPosix::_poll_connection() const { ERR_FAIL_COND_V(status != STATUS_CONNECTING || sockfd == -1, 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, sock_type); @@ -191,7 +186,7 @@ Error StreamPeerTCPPosix::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; }; @@ -251,7 +246,7 @@ Error StreamPeerTCPPosix::read(uint8_t *p_buffer, int p_bytes, int &r_received, if (status == STATUS_CONNECTING) { - if (_poll_connection(p_block) != OK) { + if (_poll_connection() != OK) { return FAILED; }; @@ -330,7 +325,7 @@ bool StreamPeerTCPPosix::is_connected() const { StreamPeerTCP::Status StreamPeerTCPPosix::get_status() const { if (status == STATUS_CONNECTING) { - _poll_connection(false); + _poll_connection(); }; return status; diff --git a/drivers/unix/stream_peer_tcp_posix.h b/drivers/unix/stream_peer_tcp_posix.h index cd50d4167..3a53e5b26 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.h @@ -45,7 +45,7 @@ protected: 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; diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index de79941e2..7bf43e52f 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -77,15 +77,10 @@ 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, sock_type); @@ -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; diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h index db27001c6..04a820e7f 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -46,7 +46,7 @@ protected: 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; -- cgit v1.2.3-70-g09d2 From cab9ad76570760f170ae15026b57b2dcfe6431ff Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 20:14:51 +0100 Subject: Update docs reference for TCP_Server::listen and UDPPacketPeer::listen (cherry picked from commit e5e4e7b6a9be36bb9bf75da996c348ae2476010c) --- doc/base/classes.xml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index b2724811a..aad217b8e 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -24710,10 +24710,15 @@ - + + + - Make this [PacketPeerUDP] listen on the "port" with a buffer size "recv_buf_size". Listens on all available addresses. + Make this [PacketPeerUDP] listen on the "port" binding to "bind_address" with a buffer size "recv_buf_size". + If "bind_address" is set as "*" (default), the peer will listen on all available addresses (both IPv4 and IPv6). + If "bind_address" is set as "0.0.0.0" (for IPv4) or "::" (for IPv6), the peer will listen on all available addresses matching that IP type. + If "bind_address" is set to any valid address (e.g. "192.168.1.101", "::1", etc), the peer will only listen on the interface with that addresses (or fail if no interface with the given address exists). @@ -39827,10 +39832,13 @@ - + - Listen on a port using protocol, alternatively give a white-list of accepted hosts. + Listen on the "port" binding to "bind_address". + If "bind_address" is set as "*" (default), the server will listen on all available addresses (both IPv4 and IPv6). + If "bind_address" is set as "0.0.0.0" (for IPv4) or "::" (for IPv6), the server will listen on all available addresses matching that IP type. + If "bind_address" is set to any valid address (e.g. "192.168.1.101", "::1", etc), the server will only listen on the interface with that addresses (or fail if no interface with the given address exists). -- cgit v1.2.3-70-g09d2 From 7dbccc9a57c7579be7f3edcf99b35cf4804b4723 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 18 Jan 2017 21:33:55 +0100 Subject: Fix bug causing UDP socket to close after the first send if not listening The ring buffer for receiving packets was not resized in constructor (cherry picked from commit 68dc969f8ca242d0c4f927a417557288e4b1b75f) --- drivers/unix/packet_peer_udp_posix.cpp | 1 + platform/windows/packet_peer_udp_winsock.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 4040aaaf4..4e48e8350 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -269,6 +269,7 @@ PacketPeerUDPPosix::PacketPeerUDPPosix() { queue_count = 0; peer_port = 0; sock_type = IP::TYPE_NONE; + rb.resize(8); } PacketPeerUDPPosix::~PacketPeerUDPPosix() { diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index e326a5a6f..5290eebc4 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -278,6 +278,7 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() { queue_count = 0; peer_port = 0; sock_type = IP::TYPE_NONE; + rb.resize(8); } PacketPeerUDPWinsock::~PacketPeerUDPWinsock() { -- cgit v1.2.3-70-g09d2 From 994df5df5c1a0062582d39f944ac1857a4881c00 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 19 Jan 2017 13:33:10 +0100 Subject: Use default UDP ring buffer size of 65536 for clients We should probably create a specific function for setting the recv buffer anyway. UDP sockets does not need to bind (listen) to be able to call recvfrom. This is especially useful for clients who just call set_send_address and start communicating with a server. (cherry picked from commit 93368571326e3472522669b76998f58aed78864f) --- drivers/unix/packet_peer_udp_posix.cpp | 4 ++-- platform/windows/packet_peer_udp_winsock.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 4e48e8350..f7ca6f834 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -158,7 +158,7 @@ void PacketPeerUDPPosix::close() { ::close(sockfd); sockfd = -1; sock_type = IP::TYPE_NONE; - rb.resize(8); + rb.resize(16); queue_count = 0; } @@ -269,7 +269,7 @@ PacketPeerUDPPosix::PacketPeerUDPPosix() { queue_count = 0; peer_port = 0; sock_type = IP::TYPE_NONE; - rb.resize(8); + rb.resize(16); } PacketPeerUDPPosix::~PacketPeerUDPPosix() { diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 5290eebc4..00c317183 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -152,7 +152,7 @@ void PacketPeerUDPWinsock::close() { ::closesocket(sockfd); sockfd = -1; sock_type = IP::TYPE_NONE; - rb.resize(8); + rb.resize(16); queue_count = 0; } @@ -278,7 +278,7 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() { queue_count = 0; peer_port = 0; sock_type = IP::TYPE_NONE; - rb.resize(8); + rb.resize(16); } PacketPeerUDPWinsock::~PacketPeerUDPWinsock() { -- cgit v1.2.3-70-g09d2 From 15ecdb5f00da2f19974d70ddd8f2658d9f2f4903 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 19 Jan 2017 17:00:01 +0100 Subject: Fix buffer size check in UDP socket. We were reserving 12 bytes from the buffer for ip, port, and length, but since IPv6 introduction we should be reserving 24 (IPv6 are 16 bytes) (cherry picked from commit 5dc7c920bf1c4bb160d39e13ad6136d80badd7ae) --- drivers/unix/packet_peer_udp_posix.cpp | 2 +- platform/windows/packet_peer_udp_winsock.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index f7ca6f834..6dc762f04 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -176,7 +176,7 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) { struct sockaddr_storage from = { 0 }; socklen_t len = sizeof(struct sockaddr_storage); int ret; - while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 12, 0)), p_wait ? 0 : MSG_DONTWAIT, (struct sockaddr *)&from, &len)) > 0) { + while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), p_wait ? 0 : MSG_DONTWAIT, (struct sockaddr *)&from, &len)) > 0) { uint32_t port = 0; diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 00c317183..38c9d322e 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -171,7 +171,7 @@ Error PacketPeerUDPWinsock::_poll(bool 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; -- cgit v1.2.3-70-g09d2