condor_sockaddr get_local_ipaddr(condor_protocol proto) { init_local_hostname(); if ((proto == CP_IPV4) && local_ipv4addr.is_ipv4()) { return local_ipv4addr; } if ((proto == CP_IPV6) && local_ipv6addr.is_ipv6()) { return local_ipv6addr; } return local_ipaddr; }
bool condor_sockaddr::compare_address(const condor_sockaddr& addr) const { if (is_ipv4()) { if (!addr.is_ipv4()) return false; return v4.sin_addr.s_addr == addr.v4.sin_addr.s_addr; } else if (is_ipv6()) { if (!addr.is_ipv6()) return false; return memcmp((const void*)&v6.sin6_addr, (const void*)&addr.v6.sin6_addr, sizeof(in6_addr)) == 0; } return false; }
bool init_local_hostname_impl() { bool local_hostname_initialized = false; if (param(local_hostname, "NETWORK_HOSTNAME")) { local_hostname_initialized = true; dprintf(D_HOSTNAME, "NETWORK_HOSTNAME says we are %s\n", local_hostname.Value()); } if( ! local_hostname_initialized ) { // [TODO:IPV6] condor_gethostname is not IPv6 safe. Reimplement it. char hostname[MAXHOSTNAMELEN]; int ret = condor_gethostname(hostname, sizeof(hostname)); if (ret) { dprintf(D_ALWAYS, "condor_gethostname() failed. Cannot initialize " "local hostname, ip address, FQDN.\n"); return false; } local_hostname = hostname; } MyString test_hostname = local_hostname; bool local_ipaddr_initialized = false; bool local_ipv4addr_initialized = false; bool local_ipv6addr_initialized = false; MyString network_interface; if (param(network_interface, "NETWORK_INTERFACE")) { if(local_ipaddr_initialized == false && local_ipaddr.from_ip_string(network_interface)) { local_ipaddr_initialized = true; if(local_ipaddr.is_ipv4()) { local_ipv4addr = local_ipaddr; local_ipv4addr_initialized = true; } if(local_ipaddr.is_ipv6()) { local_ipv6addr = local_ipaddr; local_ipv6addr_initialized = true; } } } if( ! local_ipaddr_initialized ) { std::string ipv4, ipv6, ipbest; if( network_interface_to_ip("NETWORK_INTERFACE", network_interface.Value(), ipv4, ipv6, ipbest, NULL)) { ASSERT(local_ipaddr.from_ip_string(ipbest)); // If this fails, network_interface_to_ip returns something invalid. local_ipaddr_initialized = true; } else { dprintf(D_ALWAYS, "Unable to identify IP address from interfaces. None match NETWORK_INTERFACE=%s. Problems are likely.\n", network_interface.Value()); } if((!ipv4.empty()) && local_ipv4addr.from_ip_string(ipv4)) { local_ipv4addr_initialized = true; ASSERT(local_ipv4addr.is_ipv4()); } if((!ipv6.empty()) && local_ipv6addr.from_ip_string(ipv6)) { local_ipv6addr_initialized = true; ASSERT(local_ipv6addr.is_ipv6()); } } bool local_fqdn_initialized = false; if (nodns_enabled()) { // condor_gethostname() returns a hostname with // DEFAULT_DOMAIN_NAME. Thus, it is always fqdn local_fqdn = local_hostname; local_fqdn_initialized = true; if (!local_ipaddr_initialized) { local_ipaddr = convert_hostname_to_ipaddr(local_hostname); local_ipaddr_initialized = true; } } addrinfo_iterator ai; if( ! nodns_enabled() ) { const int MAX_TRIES = 20; const int SLEEP_DUR = 3; bool gai_success = false; for(int try_count = 1; true; try_count++) { addrinfo hint = get_default_hint(); hint.ai_family = AF_UNSPEC; int ret = ipv6_getaddrinfo(test_hostname.Value(), NULL, ai, hint); if(ret == 0) { gai_success = true; break; } if(ret != EAI_AGAIN ) { dprintf(D_ALWAYS, "init_local_hostname_impl: ipv6_getaddrinfo() could not look up '%s': %s (%d). Error is not recoverable; giving up. Problems are likely.\n", test_hostname.Value(), gai_strerror(ret), ret ); gai_success = false; break; } dprintf(D_ALWAYS, "init_local_hostname_impl: ipv6_getaddrinfo() returned EAI_AGAIN for '%s'. Will try again after sleeping %d seconds (try %d of %d).\n", test_hostname.Value(), SLEEP_DUR, try_count + 1, MAX_TRIES ); if(try_count == MAX_TRIES) { dprintf(D_ALWAYS, "init_local_hostname_impl: ipv6_getaddrinfo() never succeeded. Giving up. Problems are likely\n"); break; } sleep(SLEEP_DUR); } if(gai_success) { int local_hostname_desireability = 0; #ifdef TEST_DNS_TODO int local_ipaddr_desireability = 0; int local_ipv4addr_desireability = 0; int local_ipv6addr_desireability = 0; #endif while (addrinfo* info = ai.next()) { // TODO: the only time ai_canonname should be set is the first // record. Why are we testing its desirability? const char* name = info->ai_canonname; if (!name) continue; condor_sockaddr addr(info->ai_addr); int desireability = addr.desirability(); const char * result = "skipped for low score"; if(desireability > local_hostname_desireability) { result = "new winner"; dprintf(D_HOSTNAME, " I like it.\n"); local_hostname_desireability = desireability; const char* dotpos = strchr(name, '.'); if (dotpos) { // consider it as a FQDN local_fqdn = name; local_hostname = local_fqdn.Substr(0, dotpos-name-1); } else { local_hostname = name; local_fqdn = local_hostname; MyString default_domain; if (param(default_domain, "DEFAULT_DOMAIN_NAME")) { if (default_domain[0] != '.') local_fqdn += "."; local_fqdn += default_domain; } } } dprintf(D_HOSTNAME, "hostname: %s (score %d) %s\n", name, desireability, result); #ifdef TEST_DNS_TODO // Resist urge to set local_ip*addr_initialized=true, // We want to repeatedly retest this looking for // better results. if (!local_ipaddr_initialized) { replace_higher_scoring_addr("IP", local_ipaddr, local_ipaddr_desireability, addr, desireability); } if (addr.is_ipv4() && !local_ipv4addr_initialized) { replace_higher_scoring_addr("IPv4", local_ipv4addr, local_ipv4addr_desireability, addr, desireability); } if (addr.is_ipv6() && !local_ipv6addr_initialized) { replace_higher_scoring_addr("IPv6", local_ipv6addr, local_ipv6addr_desireability, addr, desireability); } #else // Make Fedora quit complaining. if( local_ipv4addr_initialized && local_ipv6addr_initialized && local_fqdn_initialized ) { local_ipv4addr_initialized = false; local_ipv6addr_initialized = false; local_fqdn_initialized = false; } #endif } } } return true; }