diff options
author | ume <ume@FreeBSD.org> | 2006-02-24 16:53:42 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2006-02-24 16:53:42 +0000 |
commit | d095cafa05f33d8230b4ad881605cb5ae8e8898d (patch) | |
tree | 93a96fc62b30532a3b8069e096486905f1b002b6 /lib | |
parent | 7ecbcaaea5f4b1a5084b4d5c43276ddb8a1f5f9b (diff) | |
download | FreeBSD-src-d095cafa05f33d8230b4ad881605cb5ae8e8898d.zip FreeBSD-src-d095cafa05f33d8230b4ad881605cb5ae8e8898d.tar.gz |
- Just query 'as is', if there is a trailing dot in the name.
- Don't query 'as is' twice.
PR: bin/62139
Reported by: Rostislav Krasny <rosti.bsd__at__gmail.com>
Tested by: Rostislav Krasny <rosti.bsd__at__gmail.com>
Obtained from: BIND9 (with some modification)
MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 29 | ||||
-rw-r--r-- | lib/libc/net/res_query.c | 29 |
2 files changed, 40 insertions, 18 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 45f8c87..f38a2a7 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -2405,7 +2405,9 @@ res_searchN(name, target) HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/ u_int dots; int trailing_dot, ret, saved_herrno; - int got_nodata = 0, got_servfail = 0, tried_as_is = 0; + int got_nodata = 0, got_servfail = 0, root_on_list = 0; + int tried_as_is = 0; + int searched = 0; char abuf[MAXDNAME]; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { @@ -2429,13 +2431,14 @@ res_searchN(name, target) return (res_queryN(cp, target)); /* - * If there are dots in the name already, let's just give it a try - * 'as is'. The threshold can be set with the "ndots" option. + * If there are enough dots in the name, let's just give it a + * try 'as is'. The threshold can be set with the "ndots" option. + * Also, query 'as is', if there is a trailing dot in the name. */ saved_herrno = -1; - if (dots >= _res.ndots) { + if (dots >= _res.ndots || trailing_dot) { ret = res_querydomainN(name, NULL, target); - if (ret > 0) + if (ret > 0 || trailing_dot) return (ret); saved_herrno = h_errno; tried_as_is++; @@ -2454,6 +2457,14 @@ res_searchN(name, target) for (domain = (const char * const *)_res.dnsrch; *domain && !done; domain++) { + searched = 1; + + if (domain[0][0] == '\0' || + (domain[0][0] == '.' && domain[0][1] == '\0')) + root_on_list++; + + if (root_on_list && tried_as_is) + continue; ret = res_querydomainN(name, *domain, target); if (ret > 0) @@ -2505,11 +2516,11 @@ res_searchN(name, target) } /* - * if we have not already tried the name "as is", do that now. - * note that we do this regardless of how many dots were in the - * name or whether it ends with a dot. + * If the query has not already been tried as is then try it + * unless RES_NOTLDQUERY is set and there were no dots. */ - if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) { + if ((dots || !searched || !(_res.options & RES_NOTLDQUERY)) && + !(tried_as_is || root_on_list)) { ret = res_querydomainN(name, NULL, target); if (ret > 0) return (ret); diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c index 4158f98..483ff8d 100644 --- a/lib/libc/net/res_query.c +++ b/lib/libc/net/res_query.c @@ -198,7 +198,9 @@ res_search(name, class, type, answer, anslen) char tmp[MAXDNAME]; u_int dots; int trailing_dot, ret, saved_herrno; - int got_nodata = 0, got_servfail = 0, tried_as_is = 0; + int got_nodata = 0, got_servfail = 0, root_on_list = 0; + int tried_as_is = 0; + int searched = 0; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; @@ -218,13 +220,14 @@ res_search(name, class, type, answer, anslen) return (res_query(cp, class, type, answer, anslen)); /* - * If there are dots in the name already, let's just give it a try - * 'as is'. The threshold can be set with the "ndots" option. + * If there are enough dots in the name, let's just give it a + * try 'as is'. The threshold can be set with the "ndots" option. + * Also, query 'as is', if there is a trailing dot in the name. */ saved_herrno = -1; - if (dots >= _res.ndots) { + if (dots >= _res.ndots || trailing_dot) { ret = res_querydomain(name, NULL, class, type, answer, anslen); - if (ret > 0) + if (ret > 0 || trailing_dot) return (ret); saved_herrno = h_errno; tried_as_is++; @@ -243,6 +246,14 @@ res_search(name, class, type, answer, anslen) for (domain = (const char * const *)_res.dnsrch; *domain && !done; domain++) { + searched = 1; + + if (domain[0][0] == '\0' || + (domain[0][0] == '.' && domain[0][1] == '\0')) + root_on_list++; + + if (root_on_list && tried_as_is) + continue; ret = res_querydomain(name, *domain, class, type, answer, anslen); @@ -308,11 +319,11 @@ res_search(name, class, type, answer, anslen) } /* - * If we have not already tried the name "as is", do that now. - * note that we do this regardless of how many dots were in the - * name or whether it ends with a dot unless NOTLDQUERY is set. + * If the query has not already been tried as is then try it + * unless RES_NOTLDQUERY is set and there were no dots. */ - if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) { + if ((dots || !searched || !(_res.options & RES_NOTLDQUERY)) && + !(tried_as_is || root_on_list)) { ret = res_querydomain(name, NULL, class, type, answer, anslen); if (ret > 0) return (ret); |