diff options
| author | Ingo van Lil <inguin@gmx.de> | 2016-06-23 21:36:36 +0200 | 
|---|---|---|
| committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-06-24 18:57:03 +0200 | 
| commit | 03e03e71afc810265b0978f66d62f975bd4f5100 (patch) | |
| tree | 270fa9a4e1a5e64629b635f88cd88f3c6465a9dd | |
| parent | 2c3be84e73fa4013608e9b348386ddff91ae0c8c (diff) | |
inet/resolv: Try search domains first for unqualified names
When resolving an unqualified host name, the resolver tries the original
name first before appending the domains from the search list. If a TLD
with the same name exists, the query will succeed (but yield no A record)
and the resolver will return HOST_NOT_FOUND without trying the search
domains.
This patch changes the lookup order for unqualified host names (without
dots) to try the search domains first and the original name last.
Signed-off-by: Ingo van Lil <inguin@gmx.de>
| -rw-r--r-- | libc/inet/resolv.c | 12 | 
1 files changed, 10 insertions, 2 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index e3ad5131f..d380d4499 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1266,6 +1266,7 @@ int __dns_lookup(const char *name,  	int local_id = local_id; /* for compiler */  	int sdomains = 0;  	bool ends_with_dot; +	bool contains_dot;  	sockaddr46_t sa;  	fd = -1; @@ -1277,12 +1278,14 @@ int __dns_lookup(const char *name,  	if (!packet || !lookup || !name[0])  		goto fail;  	ends_with_dot = (name[name_len - 1] == '.'); +	contains_dot = strchr(name, '.') != NULL;  	/* no strcpy! paranoia, user might change name[] under us */  	memcpy(lookup, name, name_len);  	DPRINTF("Looking up type %d answer for '%s'\n", type, name);  	retries_left = 0; /* for compiler */  	do { +		unsigned act_variant;  		int pos;  		unsigned reply_timeout; @@ -1306,11 +1309,16 @@ int __dns_lookup(const char *name,  			sdomains = __searchdomains;  		}  		lookup[name_len] = '\0'; -		if ((unsigned)variant < sdomains) { +		/* For qualified names, act_variant = MAX_UINT, 0, .., sdomains-1 +		 *  => Try original name first, then append search domains +		 * For names without domain, act_variant = 0, 1, .., sdomains +		 *  => Try search domains first, original name last */ +		act_variant = contains_dot ? variant : variant + 1; +		if (act_variant < sdomains) {  			/* lookup is name_len + 1 + MAXLEN_searchdomain + 1 long */  			/* __searchdomain[] is not bigger than MAXLEN_searchdomain */  			lookup[name_len] = '.'; -			strcpy(&lookup[name_len + 1], __searchdomain[variant]); +			strcpy(&lookup[name_len + 1], __searchdomain[act_variant]);  		}  		/* first time? pick starting server etc */  		if (local_ns_num < 0) {  | 
