From e4b9b37ccf8495be674bc15cf0bf9d76fe94e6be 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 --- drivers/unix/packet_peer_udp_posix.cpp | 4 ++++ platform/windows/packet_peer_udp_winsock.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 6adb3eea70..8cdfa03595 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -157,6 +157,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 5baa01c289..e091df6d00 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -152,6 +152,9 @@ Error PacketPeerUDPWinsock::wait() { } Error PacketPeerUDPWinsock::_poll(bool p_wait) { + if (sockfd==-1) { + return FAILED; + } _set_blocking(p_wait); -- cgit v1.2.3 From 98a7e2b4e09791705cd9dfd4d13611bc02fe47d4 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. --- core/io/ip.cpp | 2 +- core/io/ip_address.cpp | 22 ++++++++++++++++++---- 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, 32 insertions(+), 11 deletions(-) diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 0eb1f221c9..13e5494dd4 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -82,7 +82,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 1fda7fed7b..2d9708f5e5 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]); @@ -171,6 +174,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{ @@ -184,6 +188,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); } @@ -194,6 +199,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,14 +207,21 @@ 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.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) { @@ -222,6 +235,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 87f32b0ac2..3e86e0bcba 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -41,6 +41,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); @@ -48,12 +50,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; @@ -61,6 +67,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 9fec807bfb..4756d1699b 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -43,7 +43,7 @@ Error PacketPeerUDP::_set_dest_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 0a59c32995..1cf7842af7 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 8cdfa03595..3d01a23f94 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -96,7 +96,7 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size } 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 6d4f7e7519..7dc34811db 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 ae4bf77c36..96258e63f6 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_to_host(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 9d3e3623da..6edd9c62fe 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -299,7 +299,7 @@ void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, Error StreamPeerWinsock::connect_to_host(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 From 4198291cd45da7fce278d21cd5ef4a506086d5f8 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) --- core/io/ip_address.cpp | 7 ++++++- core/io/ip_address.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 2d9708f5e5..69c7df619d 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -175,6 +175,7 @@ void IP_Address::clear() { memset(&field8[0], 0, sizeof(field8)); valid = false; + wildcard = false; }; bool IP_Address::is_ipv4() const{ @@ -208,7 +209,11 @@ 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; diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 3e86e0bcba..257836601a 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -42,6 +42,7 @@ private: }; bool valid; + bool wildcard; protected: void _parse_ipv6(const String& p_string); @@ -67,6 +68,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 From b2839343cab66880f647c77da7b2e1826761776a 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 --- core/io/tcp_server.cpp | 12 +----------- 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 | 20 ++++++++++++++++---- platform/windows/tcp_server_winsock.h | 3 ++- 9 files changed, 50 insertions(+), 30 deletions(-) diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index bfa5dce58f..b8a783152a 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -44,16 +44,6 @@ TCP_Server* TCP_Server::create() { return _create(); } -Error TCP_Server::_listen(uint16_t p_port, PoolVector p_accepted_hosts) { - - List hosts; - for(int i=0;i())); + ClassDB::bind_method(_MD("listen","port","bind_address"),&TCP_Server::listen,DEFVAL("*")); ClassDB::bind_method(_MD("is_connection_available"),&TCP_Server::is_connection_available); ClassDB::bind_method(_MD("take_connection"),&TCP_Server::take_connection); ClassDB::bind_method(_MD("stop"),&TCP_Server::stop); diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index 3d7b3ddd8d..cf9a1e4a93 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, PoolVector p_accepted_hosts=PoolVector()); 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 3d01a23f94..f8a0f556b4 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -130,7 +130,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 7dc34811db..bb1a866552 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 0178f08b8c..5f3c46451a 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_host } 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) { @@ -157,7 +164,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; }; @@ -170,6 +177,7 @@ void TCPServerPosix::stop() { }; listen_sockfd = -1; + sock_type = IP::TYPE_NONE; }; @@ -177,6 +185,7 @@ 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 6f9fa8cb5b..ea42d0fc0c 100644 --- a/drivers/unix/tcp_server_posix.h +++ b/drivers/unix/tcp_server_posix.h @@ -35,12 +35,13 @@ 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 e091df6d00..14c181a897 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, 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 1c3682adfa..c29645cef7 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -63,10 +63,20 @@ 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; @@ -77,7 +87,7 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List *p_accepted_ho }; 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) { @@ -150,7 +160,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; }; @@ -162,6 +172,7 @@ void TCPServerWinsock::stop() { }; listen_sockfd = -1; + sock_type = IP::TYPE_NONE; }; @@ -169,6 +180,7 @@ 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 5c544436a7..afbd1e9c87 100644 --- a/platform/windows/tcp_server_winsock.h +++ b/platform/windows/tcp_server_winsock.h @@ -34,12 +34,13 @@ 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 From 2fe4ef66991b483640f59873c22b3af671626ccc 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 --- 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 4756d1699b..3ea5e878f6 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() { ClassDB::bind_method(_MD("set_ip_type","ip_type"),&PacketPeerUDP::set_ip_type); - ClassDB::bind_method(_MD("listen:Error","port", "recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(65536)); + ClassDB::bind_method(_MD("listen:Error","port", "bind_address", "recv_buf_size"),&PacketPeerUDP::listen,DEFVAL("*"),DEFVAL(65536)); ClassDB::bind_method(_MD("close"),&PacketPeerUDP::close); ClassDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait); ClassDB::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 17952b4ac1..e0e560de1e 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -45,12 +45,12 @@ protected: String _get_packet_ip() const; - virtual Error _set_dest_address(const String& p_address,int p_port); + Error _set_dest_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 f8a0f556b4..15c3b7dfe9 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -98,10 +98,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; @@ -121,16 +124,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(); @@ -145,6 +155,7 @@ void PacketPeerUDPPosix::close(){ if (sockfd != -1) ::close(sockfd); sockfd=-1; + sock_type = IP::TYPE_NONE; rb.resize(8); queue_count=0; } @@ -225,10 +236,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; } @@ -257,6 +270,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 ead7174a9d..ac68344d78 100644 --- a/drivers/unix/packet_peer_udp_posix.h +++ b/drivers/unix/packet_peer_udp_posix.h @@ -48,6 +48,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; @@ -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/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 14c181a897..9759f15195 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -73,10 +73,15 @@ 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){ + 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); @@ -114,15 +119,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(); @@ -141,6 +153,7 @@ void PacketPeerUDPWinsock::close(){ if (sockfd != -1) ::closesocket(sockfd); sockfd=-1; + sock_type = IP::TYPE_NONE; rb.resize(8); queue_count=0; } @@ -241,10 +254,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; } @@ -275,6 +290,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 18e6bd8f3d..dcd9da9a79 100644 --- a/platform/windows/packet_peer_udp_winsock.h +++ b/platform/windows/packet_peer_udp_winsock.h @@ -46,6 +46,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; @@ -67,7 +68,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 From 88a56ba783d36d52a1023759e69f026b1ae255b4 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) --- core/io/http_client.cpp | 9 +-------- core/io/http_client.h | 2 -- core/io/packet_peer_udp.cpp | 10 ++-------- core/io/packet_peer_udp.h | 3 --- core/io/stream_peer_tcp.cpp | 9 +-------- core/io/stream_peer_tcp.h | 3 --- core/io/tcp_server.cpp | 8 +------- 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, 15 insertions(+), 66 deletions(-) diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 63c8abbbad..6a16552b3c 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_to_host(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; @@ -66,7 +61,7 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,b 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; } @@ -639,7 +634,6 @@ Error HTTPClient::_get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received) void HTTPClient::_bind_methods() { - ClassDB::bind_method(_MD("set_ip_type","ip_type"),&HTTPClient::set_ip_type); ClassDB::bind_method(_MD("connect_to_host:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect_to_host,DEFVAL(false),DEFVAL(true)); ClassDB::bind_method(_MD("set_connection","connection:StreamPeer"),&HTTPClient::set_connection); ClassDB::bind_method(_MD("get_connection:StreamPeer"),&HTTPClient::get_connection); @@ -766,7 +760,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 496d22530b..4b0c1b730f 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -132,7 +132,6 @@ public: private: - IP::Type ip_type; Status status; IP::ResolverID resolving; int conn_port; @@ -165,7 +164,6 @@ private: 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_to_host(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 3ea5e878f6..769a513bb3 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -42,7 +42,7 @@ Error PacketPeerUDP::_set_dest_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_dest_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() { - ClassDB::bind_method(_MD("set_ip_type","ip_type"),&PacketPeerUDP::set_ip_type); ClassDB::bind_method(_MD("listen:Error","port", "bind_address", "recv_buf_size"),&PacketPeerUDP::listen,DEFVAL("*"),DEFVAL(65536)); ClassDB::bind_method(_MD("close"),&PacketPeerUDP::close); ClassDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait); @@ -87,5 +81,5 @@ 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 e0e560de1e..726406887c 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -38,8 +38,6 @@ class PacketPeerUDP : public PacketPeer { protected: - IP::Type ip_type; - static PacketPeerUDP* (*_create)(); static void _bind_methods(); @@ -49,7 +47,6 @@ protected: 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 1cf7842af7..96594ef65a 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_from_host(); - ip_type = p_type; -} - void StreamPeerTCP::_bind_methods() { - ClassDB::bind_method(_MD("set_ip_type","ip_type"),&StreamPeerTCP::set_ip_type); ClassDB::bind_method(_MD("connect_to_host","host","port"),&StreamPeerTCP::_connect); ClassDB::bind_method(_MD("is_connected_to_host"),&StreamPeerTCP::is_connected_to_host); ClassDB::bind_method(_MD("get_status"),&StreamPeerTCP::get_status); @@ -83,7 +77,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 2b25f31739..4401378743 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -51,15 +51,12 @@ public: protected: - IP::Type ip_type; - virtual Error _connect(const String& p_address, int p_port); static StreamPeerTCP* (*_create)(); static void _bind_methods(); public: - virtual void set_ip_type(IP::Type p_type); virtual Error connect_to_host(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 b8a783152a..cb82b3fc55 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() { - ClassDB::bind_method(_MD("set_ip_type","ip_type"),&TCP_Server::set_ip_type); ClassDB::bind_method(_MD("listen","port","bind_address"),&TCP_Server::listen,DEFVAL("*")); ClassDB::bind_method(_MD("is_connection_available"),&TCP_Server::is_connection_available); ClassDB::bind_method(_MD("take_connection"),&TCP_Server::take_connection); @@ -62,5 +56,5 @@ 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 cf9a1e4a93..3cbd8c58cf 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -38,15 +38,12 @@ class TCP_Server : public Reference { GDCLASS( 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 15c3b7dfe9..fdd1164fbe 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -129,7 +129,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; @@ -271,7 +271,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 96258e63f6..3e514db245 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); @@ -398,7 +397,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 d33883b159..0eaa7dff3e 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.h @@ -68,7 +68,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 5f3c46451a..24de7a68b1 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()) @@ -184,7 +184,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 9759f15195..ddcfa9cdf8 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -124,7 +124,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; @@ -289,7 +289,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 6edd9c62fe..69a6fc177a 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -287,11 +287,10 @@ void StreamPeerWinsock::disconnect_from_host() { 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; @@ -369,7 +368,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 59e4dc0d09..780f45f47c 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -69,7 +69,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 c29645cef7..883741b115 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -69,7 +69,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()) @@ -179,7 +179,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 63a81a139d..436bf3e972 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) { @@ -539,7 +535,6 @@ int HTTPRequest::get_body_size() const{ void HTTPRequest::_bind_methods() { - ClassDB::bind_method(_MD("set_ip_type","ip_type"),&HTTPRequest::set_ip_type); ClassDB::bind_method(_MD("request","url","custom_headers","ssl_validate_domain","method","request_data"),&HTTPRequest::request,DEFVAL(PoolStringArray()),DEFVAL(true),DEFVAL(HTTPClient::METHOD_GET),DEFVAL(String())); ClassDB::bind_method(_MD("cancel_request"),&HTTPRequest::cancel_request); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 51c5ddeb69..a9c495fd81 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -116,7 +116,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 From 619e7a2c8ba19d0dc45467e29d9d9aa8b3506ac8 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 --- 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 fdd1164fbe..88293fc513 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -129,7 +129,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 24de7a68b1..7e9970453f 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 From e5e4e7b6a9be36bb9bf75da996c348ae2476010c 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 --- 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 0b8c5cc11c..f9a10b13d8 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -25394,10 +25394,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). @@ -40576,10 +40581,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 From fa0cb7da0e096e01476eabef37c225404c7f6f26 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. --- 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 3e514db245..08a2954617 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, b if (status == STATUS_CONNECTING) { - if (_poll_connection(p_block) != OK) { + if (_poll_connection() != OK) { return FAILED; }; @@ -330,7 +325,7 @@ bool StreamPeerTCPPosix::is_connected_to_host() 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 0eaa7dff3e..7f8d90a448 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.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; diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index 69a6fc177a..106eb6a5f5 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -78,15 +78,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); @@ -122,7 +117,7 @@ Error StreamPeerWinsock::write(const uint8_t* p_data,int p_bytes, int &r_sent, b if (status != STATUS_CONNECTED) { - if (_poll_connection(p_block) != OK) { + if (_poll_connection() != OK) { return FAILED; }; @@ -180,7 +175,7 @@ Error StreamPeerWinsock::read(uint8_t* p_buffer, int p_bytes,int &r_received, bo if (status != STATUS_CONNECTED) { - if (_poll_connection(p_block) != OK) { + if (_poll_connection() != OK) { return FAILED; }; @@ -254,7 +249,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 780f45f47c..7cf60fc10e 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -47,7 +47,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 From 68dc969f8ca242d0c4f927a417557288e4b1b75f 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 --- 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 88293fc513..7de54df043 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -275,6 +275,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 ddcfa9cdf8..9f1617d540 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -290,6 +290,7 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() { queue_count=0; peer_port=0; sock_type = IP::TYPE_NONE; + rb.resize(8); } PacketPeerUDPWinsock::~PacketPeerUDPWinsock() { -- cgit v1.2.3 From 93368571326e3472522669b76998f58aed78864f 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. --- 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 7de54df043..a146a4a09f 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -160,7 +160,7 @@ void PacketPeerUDPPosix::close(){ ::close(sockfd); sockfd=-1; sock_type = IP::TYPE_NONE; - rb.resize(8); + rb.resize(16); queue_count=0; } @@ -275,7 +275,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 9f1617d540..e5eb062165 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -154,7 +154,7 @@ void PacketPeerUDPWinsock::close(){ ::closesocket(sockfd); sockfd=-1; sock_type = IP::TYPE_NONE; - rb.resize(8); + rb.resize(16); queue_count=0; } @@ -290,7 +290,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 From 5dc7c920bf1c4bb160d39e13ad6136d80badd7ae 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) --- 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 a146a4a09f..7696a5fcb5 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -179,7 +179,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 e5eb062165..276b9b6634 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -175,7 +175,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