std::string GetHostIpByHostName()

in core/common/MachineInfoUtil.cpp [211:287]


std::string GetHostIpByHostName() {
    std::string hostname = GetHostName();

    // if hostname is invalid, other methods should be used to get correct ip.
    if (!IsDigitsDotsHostname(hostname.c_str())) {
        LOG_INFO(sLogger, ("invalid hostname", "will use other methods to obtain ip")("hostname", hostname));
        return "";
    }

    struct addrinfo hints, *res = nullptr;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    int status = getaddrinfo(hostname.c_str(), NULL, &hints, &res);
    if (status != 0 || res == nullptr) {
        LOG_WARNING(sLogger,
                    ("failed get address info", "will use other methods to obtain ip")("errMsg", gai_strerror(status)));
        return "";
    }

    std::vector<sockaddr_in> addrs;
    for (auto p = res; p != nullptr; p = p->ai_next) {
        if (p->ai_family == AF_INET) {
            addrs.emplace_back(*(struct sockaddr_in*)p->ai_addr);
        }
    }
    freeaddrinfo(res);

    std::string firstIp;
    char ipStr[INET_ADDRSTRLEN + 1] = "";
#if defined(__linux__)
    auto ipSet = GetNicIpv4IPSet();
    for (size_t i = 0; i < addrs.size(); ++i) {
        auto p = inet_ntop(AF_INET, &addrs[i].sin_addr, ipStr, INET_ADDRSTRLEN);
        if (p == nullptr) {
            continue;
        }
        auto tmp = std::string(ipStr);
        if (ipSet.find(tmp) != ipSet.end()) {
            return tmp;
        }
        if (i == 0) {
            firstIp = tmp;
            if (ipSet.empty()) {
                LOG_INFO(sLogger, ("no entry from getifaddrs", "use first entry from getaddrinfo"));
                return firstIp;
            }
        }
    }
#elif defined(_MSC_VER)
    for (size_t i = 0; i < addrs.size(); ++i) {
        auto p = inet_ntop(AF_INET, &addrs[i].sin_addr, ipStr, INET_ADDRSTRLEN);
        if (p == nullptr) {
            continue;
        }
        auto tmp = std::string(ipStr);
        // According to RFC 1918 (http://www.faqs.org/rfcs/rfc1918.html), private IP ranges are as below:
        //   10.0.0.0        -   10.255.255.255  (10/8 prefix)
        //   172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
        //   192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
        //   100.*.*.* , 30.*.*.* - alibaba office network
        if (tmp.find("10.") == 0 || tmp.find("100.") == 0 || tmp.find("30.") == 0 || tmp.find("192.168.") == 0
            || tmp.find("172.16.") == 0 || tmp.find("172.17.") == 0 || tmp.find("172.18.") == 0
            || tmp.find("172.19.") == 0 || tmp.find("172.20.") == 0 || tmp.find("172.21.") == 0
            || tmp.find("172.22.") == 0 || tmp.find("172.23.") == 0 || tmp.find("172.24.") == 0
            || tmp.find("172.25.") == 0 || tmp.find("172.26.") == 0 || tmp.find("172.27.") == 0
            || tmp.find("172.28.") == 0 || tmp.find("172.29.") == 0 || tmp.find("172.30.") == 0
            || tmp.find("172.31.") == 0) {
            return tmp;
        }
        if (i == 0) {
            firstIp = tmp;
        }
    }
#endif
    LOG_INFO(sLogger, ("no entry from getaddrinfo matches entry from getifaddrs", "use first entry from getaddrinfo"));
    return firstIp;
}