This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] fix resolving hostnames containing dots


Hi!

If I have in my resolv.conf
search redhat.com

and no explicit ndots line, then

ping devserv.devel

does not work with glibc 2.1.90 (but it does with glibc 2.1.3 and works the
same way on Solaris as well).
The reason is that res_nsearch tries to resolve the name only as is and if
that fails, simply returns error.
I've tried to restore the behaviour of glibc 2.1 in this patch, plus have
killed root_on_list variable which is just computed and never used.
Or was the change done on purpose to match some standard?
The glibc 2.1 behaviour makes much more sense to me...

2000-05-30  Jakub Jelinek  <jakub@redhat.com>

	* resolv/res_query.c (res_nsearch): Remove unused variable
	root_on_list. If dots >= statp->ndots and as is querydomain
	fails, keep searching.

--- libc/resolv/res_query.c.jj	Tue Jan  4 17:11:53 2000
+++ libc/resolv/res_query.c	Tue May 30 10:30:13 2000
@@ -184,8 +184,8 @@ res_nsearch(res_state statp,
 	HEADER *hp = (HEADER *) answer;
 	char tmp[NS_MAXDNAME];
 	u_int dots;
-	int trailing_dot, ret;
-	int got_nodata = 0, got_servfail = 0, root_on_list = 0;
+	int trailing_dot, ret, saved_herrno;
+	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
 
 	__set_errno (0);
 	RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);  /* True if we never query. */
@@ -205,9 +205,15 @@ res_nsearch(res_state statp,
 	 * If there are enough dots in the name, do no searching.
 	 * (The threshold can be set with the "ndots" option.)
 	 */
-	if (dots >= statp->ndots || trailing_dot)
-		return (res_nquerydomain(statp, name, NULL, class, type,
-					 answer, anslen));
+	saved_herrno = -1;
+	if (dots >= statp->ndots) {
+		ret = res_nquerydomain(statp, name, NULL, class, type,
+				       answer, anslen);
+		if (ret > 0)
+		    return ret;
+		saved_herrno = h_errno;
+		tried_as_is++;
+	}
 
 	/*
 	 * We do at least one level of search if
@@ -223,10 +229,6 @@ res_nsearch(res_state statp,
 		     *domain && !done;
 		     domain++) {
 
-			if (domain[0][0] == '\0' ||
-			    (domain[0][0] == '.' && domain[0][1] == '\0'))
-				root_on_list++;
-
 			ret = res_nquerydomain(statp, name, *domain,
 					       class, type,
 					       answer, anslen);
@@ -278,11 +280,11 @@ res_nsearch(res_state statp,
 		}
 	}
 
-	/*
-	 * If the name has any dots at all, and "." is not on the search
-	 * list, then try an as-is query now.
+        /* 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 (statp->ndots) {
+	if (!tried_as_is) {
 		ret = res_nquerydomain(statp, name, NULL, class, type,
 				       answer, anslen);
 		if (ret > 0)
@@ -296,6 +298,8 @@ res_nsearch(res_state statp,
 	 * else send back meaningless H_ERRNO, that being the one from
 	 * the last DNSRCH we did.
 	 */
+	if (saved_herrno != -1)
+		RES_SET_H_ERRNO(statp, saved_herrno);
 	if (got_nodata)
 		RES_SET_H_ERRNO(statp, NO_DATA);
 	else if (got_servfail)

	Jakub

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]