summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-07 18:05:19 +0100
committerPetr Baudis <pasky@ucw.cz>2011-05-27 01:21:23 +0200
commit2363f73c9f88f20303b5dcb0effe1d8036e95f6e (patch)
treeb79db201e3eb165de8ef852052eef7d252c7f36f
parent2d028cbedbf2ed783d31f1873312ad0b9fac4047 (diff)
downloadglibc-2363f73c9f88f20303b5dcb0effe1d8036e95f6e.tar.gz
Backport BIND code to query name as TLD.
(cherry picked from commit f87dfb1f11c01f2ccdc40d81e134cd06b32e28e8)
-rw-r--r--ChangeLog10
-rw-r--r--resolv/res_debug.c5
-rw-r--r--resolv/res_init.c5
-rw-r--r--resolv/res_query.c14
-rw-r--r--resolv/resolv.h4
5 files changed, 29 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index e6529a690d..f3ed880781 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-05-07 Ulrich Drepper <drepper@gmail.com>
+
+ [BZ #12734]
+ * resolv/resolv.h: Define RES_NOTLDQUERY.
+ * resolv/res_init.c (res_setoptions): Recognize no_tld_query and
+ no-tld-query and set RES_NOTLDQUERY.
+ * resolv/res_debug.c (p_option): Handle RES_NOTLDQUERY.
+ * resolv/res_query.c (__libc_res_nsearch): Backport changes from
+ modern BIND to search name as TLD unless forbidden.
+
2011-05-07 Petr Baudis <pasky@suse.cz>
Ulrich Drepper <drepper@gmail.com>
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index f7996a71da..3daa44e273 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -189,7 +189,7 @@ do_section(const res_state statp,
buf = malloc(buflen += 1024);
if (buf == NULL) {
fprintf(file,
- ";; memory allocation failure\n");
+ ";; memory allocation failure\n");
return;
}
continue;
@@ -356,7 +356,7 @@ const struct res_sym __p_class_syms[] = {
{C_HS, "HESIOD"},
{C_ANY, "ANY"},
{C_NONE, "NONE"},
- {C_IN, (char *)0}
+ {C_IN, (char *)0}
};
libresolv_hidden_data_def (__p_class_syms)
@@ -588,6 +588,7 @@ p_option(u_long option) {
case RES_USEBSTRING: return "ip6-bytstring";
case RES_USE_EDNS0: return "edns0";
case RES_USE_DNSSEC: return "dnssec";
+ case RES_NOTLDQUERY: return "no-tld-query";
/* XXX nonreentrant */
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
return (nbuf);
diff --git a/resolv/res_init.c b/resolv/res_init.c
index 74715f34e9..7588432b22 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -545,6 +545,11 @@ res_setoptions(res_state statp, const char *options, const char *source) {
} else if (!strncmp(cp, "single-request",
sizeof("single-request") - 1)) {
statp->options |= RES_SNGLKUP;
+ } else if (!strncmp(cp, "no_tld_query",
+ sizeof("no_tld_query") - 1) ||
+ !strncmp(cp, "no-tld-query",
+ sizeof("no-tld-query") - 1)) {
+ statp->options |= RES_NOTLDQUERY;
} else {
/* XXX - print a warning here? */
}
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 5ff352e2fc..26daf0d87b 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -123,7 +123,7 @@ __libc_res_nquery(res_state statp,
{
HEADER *hp = (HEADER *) answer;
int n, use_malloc = 0;
- u_int oflags = statp->_flags;
+ u_int oflags = statp->_flags;
size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE;
u_char *buf = alloca (bufsize);
@@ -210,7 +210,7 @@ __libc_res_nquery(res_state statp,
if (statp->options & RES_DEBUG)
printf(";; res_nquery: retry without EDNS0\n");
#endif
- goto again;
+ goto again;
}
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -344,6 +344,7 @@ __libc_res_nsearch(res_state statp,
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, root_on_list = 0;
int tried_as_is = 0;
+ int searched = 0;
__set_errno (0);
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /* True if we never query. */
@@ -406,6 +407,7 @@ __libc_res_nsearch(res_state statp,
for (domain = (const char * const *)statp->dnsrch;
*domain && !done;
domain++) {
+ searched = 1;
if (domain[0][0] == '\0' ||
(domain[0][0] == '.' && domain[0][1] == '\0'))
@@ -477,11 +479,11 @@ __libc_res_nsearch(res_state statp,
}
/*
- * If the name has any dots at all, and no earlier 'as-is' query
- * for the name, and "." is not on the search list, then try an as-is
- * query now.
+ * f the query has not already been tried as is then try it
+ * unless RES_NOTLDQUERY is set and there were no dots.
*/
- if (dots && !(tried_as_is || root_on_list)) {
+ if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0)
+ && !(tried_as_is || root_on_list)) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
answerp2, nanswerp2, resplen2);
diff --git a/resolv/resolv.h b/resolv/resolv.h
index e49c29d2fe..ed15a702bf 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -102,7 +102,7 @@ typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *__ns,
# define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
struct __res_state {
- int retrans; /* retransmition time interval */
+ int retrans; /* retransmition time interval */
int retry; /* number of times to retransmit */
u_long options; /* option flags - see below. */
int nscount; /* number of name servers */
@@ -219,6 +219,8 @@ struct res_sym {
#define RES_SNGLKUPREOP 0x00400000 /* -"-, but open new socket for each
request */
#define RES_USE_DNSSEC 0x00800000 /* use DNSSEC using OK bit in OPT */
+#define RES_NOTLDQUERY 0x01000000 /* Do not look up unqualified name
+ as a TLD. */
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)