diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 963e8a612ee..0d92961591e 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 e03dac8d342..594edbf8e27 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 200df57aafb..2ed77cc3b40 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 eb51a4207cd..8e5e46fd9cb 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 753d66734b1..f303d8fd181 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 faabe902f9c..13fef59218c 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 c7828ae94fa..80f02f623cd 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 7ebcc34c00b..779d9e427e2 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 99ee5ef4748..6723a6d0f8a 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);