From: Rich Felker Date: Tue, 26 Jun 2018 20:17:05 +0000 (-0400) Subject: resolver: omit final dot (root/suppress-search) in canonical name X-Git-Tag: v1.1.20~58 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=63e2e40ee3aa3bdd160a7eeace98f3dfb89ddbe2;p=oweals%2Fmusl.git resolver: omit final dot (root/suppress-search) in canonical name if a final dot was included in the queried host name to anchor it to the dns root/suppress search domains, and the result was not a CNAME, the returned canonical name included the final dot. this was not consistent with other implementations, confused some applications, and does not seem desirable. POSIX specifies returning a pointer to, or to a copy of, the input nodename, when the canonical name is not available, but does not attempt to specify what constitutes "not available". in the case of search, we already have an implementation-defined "availability" of a canonical name as the fully-qualified name resulting from search, so defining it similarly in the no-search case seems reasonable in addition to being consistent with other implementations. as a bonus, fix the case where more than one trailing dot is included, since otherwise the changes made here would wrongly cause lookups with two trailing dots to succeed. previously this case resulted in malformed dns queries and produced EAI_AGAIN after a timeout. now it fails immediately with EAI_NONAME. --- diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c index 209c20f0..a1851f1f 100644 --- a/src/network/lookup_name.c +++ b/src/network/lookup_name.c @@ -184,6 +184,10 @@ static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[ for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++; if (dots >= conf.ndots || name[l-1]=='.') *search = 0; + /* Strip final dot for canon, fail if multiple trailing dots. */ + if (name[l-1]=='.') l--; + if (!l || name[l-1]=='.') return EAI_NONAME; + /* This can never happen; the caller already checked length. */ if (l >= 256) return EAI_NONAME;