This is an automated email from the ASF dual-hosted git repository. kxiao pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/doris.git
commit 1e4d7446c39377f87a0a399f4d5cdca45f17947c Author: zhangdong <[email protected]> AuthorDate: Fri Aug 25 21:24:55 2023 +0800 [fix](fqdn)Fqdn with ipv6 (#22454) now,`hostname_to_ip` only can resolve `ipv4`,Therefore, a method is provided to parse ipv4 or ipv6 based on parameters。 when `_heartbeat` call `hostname_to_ip`,Resolve to ipv4 or ipv6, determined by `BackendOptions.is_bind_ipv6` Decision Additionally, a method is provided to first attempt to parse the host into ipv4, and then try ipv6 if it fails --- be/src/agent/heartbeat_server.cpp | 6 ++- be/src/util/network_util.cpp | 103 +++++++++++++++++++------------------- be/src/util/network_util.h | 11 ++-- 3 files changed, 61 insertions(+), 59 deletions(-) diff --git a/be/src/agent/heartbeat_server.cpp b/be/src/agent/heartbeat_server.cpp index d353692c9d..92b121414c 100644 --- a/be/src/agent/heartbeat_server.cpp +++ b/be/src/agent/heartbeat_server.cpp @@ -118,14 +118,16 @@ Status HeartbeatServer::_heartbeat(const TMasterInfo& master_info) { if (!is_valid_ip(master_info.backend_ip)) { //step2: resolve FQDN to IP std::string ip; - Status status = hostname_to_ip(master_info.backend_ip, ip); + Status status = + hostname_to_ip(master_info.backend_ip, ip, BackendOptions::is_bind_ipv6()); if (!status.ok()) { std::stringstream ss; ss << "can not get ip from fqdn: " << status.to_string(); LOG(WARNING) << ss.str(); return status; } - + LOG(INFO) << "master_info.backend_ip: " << master_info.backend_ip + << ", hostname_to_ip: " << ip; //step3: get all ips of the interfaces on this machine std::vector<InetAddress> hosts; status = get_hosts(&hosts); diff --git a/be/src/util/network_util.cpp b/be/src/util/network_util.cpp index 6841e257a3..d80682d21e 100644 --- a/be/src/util/network_util.cpp +++ b/be/src/util/network_util.cpp @@ -72,70 +72,69 @@ Status get_hostname(std::string* hostname) { return Status::OK(); } -Status hostname_to_ip_addrs(const std::string& name, std::vector<std::string>* addresses) { - addrinfo hints; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; // IPv4 addresses only - hints.ai_socktype = SOCK_STREAM; - - struct addrinfo* addr_info; +bool is_valid_ip(const std::string& ip) { + unsigned char buf[sizeof(struct in6_addr)]; + return (inet_pton(AF_INET6, ip.data(), buf) > 0) || (inet_pton(AF_INET, ip.data(), buf) > 0); +} - if (getaddrinfo(name.c_str(), nullptr, &hints, &addr_info) != 0) { - return Status::InternalError("Could not find IPv4 address for: {}", name); +Status hostname_to_ip(const std::string& host, std::string& ip) { + Status status = hostname_to_ipv4(host, ip); + if (status.ok()) { + return status; } + return hostname_to_ipv6(host, ip); +} - addrinfo* it = addr_info; - - while (it != nullptr) { - char addr_buf[64]; - const char* result = - inet_ntop(AF_INET, &((sockaddr_in*)it->ai_addr)->sin_addr, addr_buf, 64); +Status hostname_to_ip(const std::string& host, std::string& ip, bool ipv6) { + if (ipv6) { + return hostname_to_ipv6(host, ip); + } else { + return hostname_to_ipv4(host, ip); + } +} - if (result == nullptr) { - freeaddrinfo(addr_info); - return Status::InternalError("Could not convert IPv4 address for: {}", name); - } +Status hostname_to_ipv4(const std::string& host, std::string& ip) { + addrinfo hints, *res; + in_addr addr; - // add address if not exists - std::string address = std::string(addr_buf); - if (std::find(addresses->begin(), addresses->end(), address) != addresses->end()) { - LOG(WARNING) << "Repeated ip addresses has been found for host: " << name - << ", ip address:" << address - << ", please check your network configuration"; - } else { - addresses->push_back(address); - } - it = it->ai_next; + memset(&hints, 0, sizeof(addrinfo)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_INET; + int err = getaddrinfo(host.c_str(), NULL, &hints, &res); + if (err != 0) { + LOG(WARNING) << "failed to get ip from host: " << host << "err:" << gai_strerror(err); + return Status::InternalError("failed to get ip from host: {}, err: {}", host, + gai_strerror(err)); } - freeaddrinfo(addr_info); + addr.s_addr = ((sockaddr_in*)(res->ai_addr))->sin_addr.s_addr; + ip = inet_ntoa(addr); + + freeaddrinfo(res); return Status::OK(); } -bool is_valid_ip(const std::string& ip) { - unsigned char buf[sizeof(struct in6_addr)]; - return (inet_pton(AF_INET6, ip.data(), buf) > 0) || (inet_pton(AF_INET, ip.data(), buf) > 0); -} +Status hostname_to_ipv6(const std::string& host, std::string& ip) { + char ipstr2[128]; + struct sockaddr_in6* sockaddr_ipv6; -Status hostname_to_ip(const std::string& host, std::string& ip) { - std::vector<std::string> addresses; - Status status = hostname_to_ip_addrs(host, &addresses); - if (!status.ok()) { - LOG(WARNING) << "status of hostname_to_ip_addrs was not ok, err is " << status.to_string(); - return status; - } - if (addresses.size() != 1) { - std::stringstream ss; - std::copy(addresses.begin(), addresses.end(), std::ostream_iterator<std::string>(ss, ",")); - LOG(WARNING) - << "the number of addresses could only be equal to 1, failed to get ip from host:" - << host << ", addresses:" << ss.str(); - return Status::InternalError( - "the number of addresses could only be equal to 1, failed to get ip from host: " - "{}, addresses:{}", - host, ss.str()); + struct addrinfo *answer, hint; + bzero(&hint, sizeof(hint)); + hint.ai_family = AF_INET6; + hint.ai_socktype = SOCK_STREAM; + + int err = getaddrinfo(host.c_str(), NULL, &hint, &answer); + if (err != 0) { + LOG(WARNING) << "failed to get ip from host: " << host << "err:" << gai_strerror(err); + return Status::InternalError("failed to get ip from host: {}, err: {}", host, + gai_strerror(err)); } - ip = addresses[0]; + + sockaddr_ipv6 = reinterpret_cast<struct sockaddr_in6*>(answer->ai_addr); + inet_ntop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstr2, sizeof(ipstr2)); + ip = ipstr2; + fflush(NULL); + freeaddrinfo(answer); return Status::OK(); } diff --git a/be/src/util/network_util.h b/be/src/util/network_util.h index 55bbcd1130..a9541586ef 100644 --- a/be/src/util/network_util.h +++ b/be/src/util/network_util.h @@ -43,15 +43,16 @@ private: bool _is_loopback; }; -// Looks up all IP addresses associated with a given hostname. Returns -// an error status if any system call failed, otherwise OK. Even if OK -// is returned, addresses may still be of zero length. -Status hostname_to_ip_addrs(const std::string& name, std::vector<std::string>* addresses); - bool is_valid_ip(const std::string& ip); Status hostname_to_ip(const std::string& host, std::string& ip); +Status hostname_to_ipv4(const std::string& host, std::string& ip); + +Status hostname_to_ipv6(const std::string& host, std::string& ip); + +Status hostname_to_ip(const std::string& host, std::string& ip, bool ipv6); + // Finds the first non-localhost IP address in the given list. Returns // true if such an address was found, false otherwise. bool find_first_non_localhost(const std::vector<std::string>& addresses, std::string* addr); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
