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]

Reply via email to