diff --git a/sfw/core/inet_address.cpp b/sfw/core/inet_address.cpp index 22ad856..679dbf1 100644 --- a/sfw/core/inet_address.cpp +++ b/sfw/core/inet_address.cpp @@ -109,17 +109,25 @@ static const in_addr_t kInaddrLoopback = INADDR_ANY; #endif */ +// Defined here so we don't need to include in the header +struct InetAddress::InetAddressData { + union { + struct sockaddr_in _addr; + struct sockaddr_in6 _addr6; + }; +}; + String InetAddress::to_ip_port() const { char buf[64] = ""; - uint16_t port = ntohs(_addr.sin_port); + uint16_t port = ntohs(_data->_addr.sin_port); snprintf(buf, sizeof(buf), ":%u", port); return to_ip() + String(buf); } bool InetAddress::is_intranet_ip() const { - if (_addr.sin_family == AF_INET) { - uint32_t ip_addr = ntohl(_addr.sin_addr.s_addr); + if (_data->_addr.sin_family == AF_INET) { + uint32_t ip_addr = ntohl(_data->_addr.sin_addr.s_addr); if ((ip_addr >= 0x0A000000 && ip_addr <= 0x0AFFFFFF) || (ip_addr >= 0xAC100000 && ip_addr <= 0xAC1FFFFF) || (ip_addr >= 0xC0A80000 && ip_addr <= 0xC0A8FFFF) || @@ -160,7 +168,7 @@ bool InetAddress::is_intranet_ip() const { bool InetAddress::is_loopback_ip() const { if (!is_ip_v6()) { - uint32_t ip_addr = ntohl(_addr.sin_addr.s_addr); + uint32_t ip_addr = ntohl(_data->_addr.sin_addr.s_addr); if (ip_addr == 0x7f000001) { return true; } @@ -180,32 +188,32 @@ bool InetAddress::is_loopback_ip() const { } const struct sockaddr *InetAddress::get_sock_addr() const { - return static_cast((void *)(&_addr6)); + return static_cast((void *)(&_data->_addr6)); } void InetAddress::set_sock_addr_inet6(const struct sockaddr_in6 &addr6) { - _addr6 = addr6; - _is_ip_v6 = (_addr6.sin6_family == AF_INET6); + _data->_addr6 = addr6; + _is_ip_v6 = (_data->_addr6.sin6_family == AF_INET6); _is_unspecified = false; } sa_family_t InetAddress::family() const { - return _addr.sin_family; + return _data->_addr.sin_family; } String InetAddress::to_ip() const { char buf[64]; - if (_addr.sin_family == AF_INET) { + if (_data->_addr.sin_family == AF_INET) { #if defined GCCWIN || (_MSC_VER && _MSC_VER >= 1900) - ::inet_ntop(AF_INET, (PVOID)&_addr.sin_addr, buf, sizeof(buf)); + ::inet_ntop(AF_INET, (PVOID)&_data->_addr.sin_addr, buf, sizeof(buf)); #else - ::inet_ntop(AF_INET, &_addr.sin_addr, buf, sizeof(buf)); + ::inet_ntop(AF_INET, &_data->_addr.sin_addr, buf, sizeof(buf)); #endif - } else if (_addr.sin_family == AF_INET6) { + } else if (_data->_addr.sin_family == AF_INET6) { #if defined GCCWIN || (_MSC_VER && _MSC_VER >= 1900) - ::inet_ntop(AF_INET6, (PVOID)&_addr6.sin6_addr, buf, sizeof(buf)); + ::inet_ntop(AF_INET6, (PVOID)&_data->_addr6.sin6_addr, buf, sizeof(buf)); #else - ::inet_ntop(AF_INET6, &_addr6.sin6_addr, buf, sizeof(buf)); + ::inet_ntop(AF_INET6, &_data->_addr6.sin6_addr, buf, sizeof(buf)); #endif } @@ -214,29 +222,29 @@ String InetAddress::to_ip() const { uint32_t InetAddress::ip_net_endian() const { // assert(family() == AF_INET); - return _addr.sin_addr.s_addr; + return _data->_addr.sin_addr.s_addr; } const uint32_t *InetAddress::ip6_net_endian() const { // assert(family() == AF_INET6); #if defined __linux__ || defined __HAIKU__ - return _addr6.sin6_addr.s6_addr32; + return _data->_addr6.sin6_addr.s6_addr32; #elif defined(_WIN64) || defined(_WIN32) // TODO is this OK ? const struct in6__addruint *_addrtemp = - reinterpret_cast(&_addr6.sin6_addr); + reinterpret_cast(&_data->_addr6.sin6_addr); return (*_addrtemp).uext.__s6_addr32; #else - return _addr6.sin6_addr.__u6_addr.__u6_addr32; + return _data->_addr6.sin6_addr.__u6_addr.__u6_addr32; #endif } uint16_t InetAddress::port_net_endian() const { - return _addr.sin_port; + return _data->_addr.sin_port; } void InetAddress::set_port_net_endian(uint16_t port) { - _addr.sin_port = port; + _data->_addr.sin_port = port; } inline bool InetAddress::is_unspecified() const { @@ -252,49 +260,72 @@ bool InetAddress::is_ip_v6() const { } InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6) { + _data = memnew(InetAddressData); + _is_ip_v6 = ipv6; if (ipv6) { - memset(&_addr6, 0, sizeof(_addr6)); - _addr6.sin6_family = AF_INET6; + memset(&_data->_addr6, 0, sizeof(_data->_addr6)); + _data->_addr6.sin6_family = AF_INET6; in6_addr ip = loopbackOnly ? in6addr_loopback : in6addr_any; - _addr6.sin6_addr = ip; - _addr6.sin6_port = htons(port); + _data->_addr6.sin6_addr = ip; + _data->_addr6.sin6_port = htons(port); } else { - memset(&_addr, 0, sizeof(_addr)); - _addr.sin_family = AF_INET; + memset(&_data->_addr, 0, sizeof(_data->_addr)); + _data->_addr.sin_family = AF_INET; in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny; - _addr.sin_addr.s_addr = htonl(ip); - _addr.sin_port = htons(port); + _data->_addr.sin_addr.s_addr = htonl(ip); + _data->_addr.sin_port = htons(port); } _is_unspecified = false; } InetAddress::InetAddress(const String &ip, uint16_t port, bool ipv6) { + _data = memnew(InetAddressData); + _is_ip_v6 = ipv6; if (ipv6) { - memset(&_addr6, 0, sizeof(_addr6)); - _addr6.sin6_family = AF_INET6; - _addr6.sin6_port = htons(port); + memset(&_data->_addr6, 0, sizeof(_data->_addr6)); + _data->_addr6.sin6_family = AF_INET6; + _data->_addr6.sin6_port = htons(port); - if (::inet_pton(AF_INET6, ip.utf8().get_data(), &_addr6.sin6_addr) <= 0) { + if (::inet_pton(AF_INET6, ip.utf8().get_data(), &_data->_addr6.sin6_addr) <= 0) { return; } } else { - memset(&_addr, 0, sizeof(_addr)); - _addr.sin_family = AF_INET; - _addr.sin_port = htons(port); + memset(&_data->_addr, 0, sizeof(_data->_addr)); + _data->_addr.sin_family = AF_INET; + _data->_addr.sin_port = htons(port); - if (::inet_pton(AF_INET, ip.utf8().get_data(), &_addr.sin_addr) <= 0) { + if (::inet_pton(AF_INET, ip.utf8().get_data(), &_data->_addr.sin_addr) <= 0) { return; } } _is_unspecified = false; } + +InetAddress::InetAddress(const struct sockaddr_in &addr) { + _data = memnew(InetAddressData); + + _data->_addr = addr; + _is_unspecified = false; +} + +InetAddress::InetAddress(const struct sockaddr_in6 &addr) { + _data = memnew(InetAddressData); + + _data->_addr6 = addr; + _is_ip_v6 = true; + _is_unspecified = false; +} + +InetAddress::~InetAddress() { + memdelete(_data); +} diff --git a/sfw/core/inet_address.h b/sfw/core/inet_address.h index 28125b2..20a83ac 100644 --- a/sfw/core/inet_address.h +++ b/sfw/core/inet_address.h @@ -31,7 +31,6 @@ //--STRIP #if defined(_WIN64) || defined(_WIN32) -#include using sa_family_t = unsigned short; using in_addr_t = uint32_t; using uint16_t = unsigned short; @@ -46,8 +45,13 @@ using uint16_t = unsigned short; #include "int_types.h" //--STRIP +struct sockaddr_in; +struct sockaddr_in6; + class InetAddress { public: + struct InetAddressData; + sa_family_t family() const; String to_ip() const; @@ -75,22 +79,13 @@ public: InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false); InetAddress(const String &ip, uint16_t port, bool ipv6 = false); - explicit InetAddress(const struct sockaddr_in &addr) { - _addr = addr; - _is_unspecified = false; - } + explicit InetAddress(const struct sockaddr_in &addr); + explicit InetAddress(const struct sockaddr_in6 &addr); - explicit InetAddress(const struct sockaddr_in6 &addr) { - _addr6 = addr; - _is_ip_v6 = true; - _is_unspecified = false; - } + ~InetAddress(); private: - union { - struct sockaddr_in _addr; - struct sockaddr_in6 _addr6; - }; + InetAddressData *_data; bool _is_ip_v6; bool _is_unspecified;