From 8e9c2721ef02a043b98fd8d79a79029fb5cf9e19 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 27 Nov 2018 21:26:32 +0300 Subject: [PATCH] Support different IPv4 formats in IPAddress::init_host_port. GitOrigin-RevId: 122239f0ba24a1274b0cc50913e8fac3ad25ddc3 --- tdutils/td/utils/port/IPAddress.cpp | 48 +++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/tdutils/td/utils/port/IPAddress.cpp b/tdutils/td/utils/port/IPAddress.cpp index d773ec2a..6c147fd8 100644 --- a/tdutils/td/utils/port/IPAddress.cpp +++ b/tdutils/td/utils/port/IPAddress.cpp @@ -4,6 +4,8 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#define _WINSOCK_DEPRECATED_NO_WARNINGS // we need to use inet_addr instead of inet_pton + #include "td/utils/port/IPAddress.h" #include "td/utils/format.h" @@ -170,6 +172,25 @@ Result idn_to_ascii(CSlice host) { #endif } +static CSlice get_ip_str(int family, const void *addr) { + const int buf_size = INET6_ADDRSTRLEN; + static TD_THREAD_LOCAL char *buf; + init_thread_local(buf, buf_size); + + const char *res = inet_ntop(family, +#if TD_WINDOWS + const_cast(addr), +#else + addr, +#endif + buf, buf_size); + if (res == nullptr) { + return CSlice(); + } else { + return CSlice(res); + } +} + IPAddress::IPAddress() : is_valid_(false) { } @@ -327,6 +348,7 @@ Status IPAddress::init_host_port(CSlice host, int port, bool prefer_ipv6) { } Status IPAddress::init_host_port(CSlice host, CSlice port, bool prefer_ipv6) { + is_valid_ = false; if (host.empty()) { return Status::Error("Host is empty"); } @@ -338,6 +360,13 @@ Status IPAddress::init_host_port(CSlice host, CSlice port, bool prefer_ipv6) { TRY_RESULT(ascii_host, idn_to_ascii(host)); host = ascii_host; + // some getaddrinfo implementations use inet_pton instead of inet_aton and support only decimal-dotted IPv4 form, + // and so doesn't recognize 0x12.0x34.0x56.0x78, or 0x12345678, or 0x7f.001 as valid IPv4 addresses + auto ipv4_numeric_addr = inet_addr(host.c_str()); + if (ipv4_numeric_addr != INADDR_NONE) { + host = ::td::get_ip_str(AF_INET, &ipv4_numeric_addr); + } + addrinfo hints; addrinfo *info = nullptr; std::memset(&hints, 0, sizeof(hints)); @@ -437,25 +466,6 @@ Status IPAddress::init_peer_address(const SocketFd &socket_fd) { return Status::OK(); } -static CSlice get_ip_str(int family, const void *addr) { - const int buf_size = INET6_ADDRSTRLEN; - static TD_THREAD_LOCAL char *buf; - init_thread_local(buf, buf_size); - - const char *res = inet_ntop(family, -#if TD_WINDOWS - const_cast(addr), -#else - addr, -#endif - buf, buf_size); - if (res == nullptr) { - return CSlice(); - } else { - return CSlice(res); - } -} - CSlice IPAddress::ipv4_to_str(uint32 ipv4) { ipv4 = ntohl(ipv4); return ::td::get_ip_str(AF_INET, &ipv4);