summaryrefslogtreecommitdiff
path: root/libc/inet/resolv.c
diff options
context:
space:
mode:
authorIngo van Lil <inguin@gmx.de>2016-06-23 21:36:36 +0200
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-06-24 18:57:03 +0200
commit03e03e71afc810265b0978f66d62f975bd4f5100 (patch)
tree270fa9a4e1a5e64629b635f88cd88f3c6465a9dd /libc/inet/resolv.c
parent2c3be84e73fa4013608e9b348386ddff91ae0c8c (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>
Diffstat (limited to 'libc/inet/resolv.c')
-rw-r--r--libc/inet/resolv.c12
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) {