about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-07 13:05:19 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-07 13:05:19 -0400
commitf87dfb1f11c01f2ccdc40d81e134cd06b32e28e8 (patch)
treea3576051b3e8e833c4035478d4f1ac1f946f3f29
parent47c3cd7a74e8c089d60d603afce6d9cf661178d6 (diff)
downloadglibc-f87dfb1f11c01f2ccdc40d81e134cd06b32e28e8.tar.gz
glibc-f87dfb1f11c01f2ccdc40d81e134cd06b32e28e8.tar.xz
glibc-f87dfb1f11c01f2ccdc40d81e134cd06b32e28e8.zip
Backport BIND code to query name as TLD.
-rw-r--r--ChangeLog10
-rw-r--r--NEWS2
-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
6 files changed, 30 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index e93c9a5643..76d790593a 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/NEWS b/NEWS
index 43da517254..952f32af17 100644
--- a/NEWS
+++ b/NEWS
@@ -24,7 +24,7 @@ Version 2.14
 
   11724, 12393, 12420, 12445, 12454, 12460, 12469, 12489, 12509, 12510,
   12518, 12583, 12587, 12597, 12631, 12650, 12653, 12655, 12685, 12714,
-  12717, 12723
+  12717, 12723, 12734
 
 Version 2.13
 
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)