Support different IPv4 formats in IPAddress::init_host_port.
GitOrigin-RevId: 122239f0ba24a1274b0cc50913e8fac3ad25ddc3
This commit is contained in:
parent
4c618b6f92
commit
8e9c2721ef
@ -4,6 +4,8 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// 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/port/IPAddress.h"
|
||||||
|
|
||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
@ -170,6 +172,25 @@ Result<string> idn_to_ascii(CSlice host) {
|
|||||||
#endif
|
#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<char[]>(buf, buf_size);
|
||||||
|
|
||||||
|
const char *res = inet_ntop(family,
|
||||||
|
#if TD_WINDOWS
|
||||||
|
const_cast<PVOID>(addr),
|
||||||
|
#else
|
||||||
|
addr,
|
||||||
|
#endif
|
||||||
|
buf, buf_size);
|
||||||
|
if (res == nullptr) {
|
||||||
|
return CSlice();
|
||||||
|
} else {
|
||||||
|
return CSlice(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IPAddress::IPAddress() : is_valid_(false) {
|
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) {
|
Status IPAddress::init_host_port(CSlice host, CSlice port, bool prefer_ipv6) {
|
||||||
|
is_valid_ = false;
|
||||||
if (host.empty()) {
|
if (host.empty()) {
|
||||||
return Status::Error("Host is 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));
|
TRY_RESULT(ascii_host, idn_to_ascii(host));
|
||||||
host = 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 hints;
|
||||||
addrinfo *info = nullptr;
|
addrinfo *info = nullptr;
|
||||||
std::memset(&hints, 0, sizeof(hints));
|
std::memset(&hints, 0, sizeof(hints));
|
||||||
@ -437,25 +466,6 @@ Status IPAddress::init_peer_address(const SocketFd &socket_fd) {
|
|||||||
return Status::OK();
|
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<char[]>(buf, buf_size);
|
|
||||||
|
|
||||||
const char *res = inet_ntop(family,
|
|
||||||
#if TD_WINDOWS
|
|
||||||
const_cast<PVOID>(addr),
|
|
||||||
#else
|
|
||||||
addr,
|
|
||||||
#endif
|
|
||||||
buf, buf_size);
|
|
||||||
if (res == nullptr) {
|
|
||||||
return CSlice();
|
|
||||||
} else {
|
|
||||||
return CSlice(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CSlice IPAddress::ipv4_to_str(uint32 ipv4) {
|
CSlice IPAddress::ipv4_to_str(uint32 ipv4) {
|
||||||
ipv4 = ntohl(ipv4);
|
ipv4 = ntohl(ipv4);
|
||||||
return ::td::get_ip_str(AF_INET, &ipv4);
|
return ::td::get_ip_str(AF_INET, &ipv4);
|
||||||
|
Loading…
Reference in New Issue
Block a user