diff options
author | snaury <snaury@ydb.tech> | 2022-09-02 10:43:13 +0300 |
---|---|---|
committer | snaury <snaury@ydb.tech> | 2022-09-02 10:43:13 +0300 |
commit | e1130ed45c01575975413fc4fa1099d974c8db23 (patch) | |
tree | 53699a1dbc620e160ef518143a7b34692daf3ffc /util | |
parent | 40d4e4842f449c176faca9725f933f24180a277e (diff) | |
download | ydb-e1130ed45c01575975413fc4fa1099d974c8db23.tar.gz |
Fix incorrect fqdn on linux in some edge cases
Diffstat (limited to 'util')
-rw-r--r-- | util/system/hostname.cpp | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/util/system/hostname.cpp b/util/system/hostname.cpp index 386f646d6b..e377910d5c 100644 --- a/util/system/hostname.cpp +++ b/util/system/hostname.cpp @@ -34,8 +34,6 @@ namespace { struct TFQDNHostNameHolder { inline TFQDNHostNameHolder() { - struct addrinfo hints; - struct addrinfo* ais{nullptr}; char buf[1024]; memset(buf, 0, sizeof(buf)); @@ -44,20 +42,41 @@ namespace { ythrow TSystemError() << "can not get hostname"; } +#ifdef _darwin_ + // On Darwin gethostname returns fqdn, see hostname.c in shell_cmds: + // https://github.com/apple-oss-distributions/shell_cmds/blob/main/hostname/hostname.c + // There are macs in the wild that don't have fqdn hostnames, but + // which have search domains in their resolv.conf, so any attempt to + // resolve AI_CANONNAME for the short hostname will result in the + // EAI_NONAME error. + // It seems using gethostname is enough to emulate the result of + // `hostname -f`, which still works on those macs. + FQDNHostName = buf; +#else + // On Linux `hostname -f` calls getaddrinfo with AI_CANONNAME flag + // to find the fqdn and will fail on any error. + // Hosts often have a short hostname and fqdn is resolved over dns. + // It is also very common to have a short hostname alias in + // /etc/hosts, which works as a fallback (e.g. no fqdn in search + // domains, otherwise `hostname -f` fails with an error and it is + // obvious the host is not configured correctly). + // Note that getaddrinfo may sometimes return EAI_NONAME even when + // host actually has fqdn, but dns is temporary unavailable, so we + // cannot ignore any errors on Linux. + struct addrinfo hints; + struct addrinfo* ais{nullptr}; + memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_CANONNAME; res = getaddrinfo(buf, nullptr, &hints, &ais); if (res) { - if (res != EAI_NONAME) { - ythrow TSystemError() << "can not get FQDN (return code is " << res << ", hostname is \"" << buf << "\")"; - } - FQDNHostName = buf; - } else { - FQDNHostName = ais->ai_canonname; - freeaddrinfo(ais); + ythrow TSystemError() << "can not get FQDN (return code is " << res << ", hostname is \"" << buf << "\")"; } + FQDNHostName = ais->ai_canonname; FQDNHostName.to_lower(); + freeaddrinfo(ais); +#endif } TString FQDNHostName; |