SSH login takes very long time...sometimes

Hajimu UMEMOTO ume at freebsd.org
Wed Feb 22 09:11:11 PST 2006


Hi,

>>>>> On Wed, 22 Feb 2006 02:44:30 +0200
>>>>> Rostislav Krasny <rosti.bsd at gmail.com> said:

rosti> On Tue, 21 Feb 2006 19:59:59 +0300
rosti> Yar Tikhiy <yar at comp.chem.msu.su> wrote:

rosti> I forgot that a "search" resolver(5) parameter is useless for reverse
rosti> resolving. But that "doubling" of name->IP requests with an empty (or
rosti> root, according to resolver(5)) domain in the "search" is still a bug,
rosti> IMHO. Although it shouldn't affect the sshd.

I looked BIND9's resolver, and took the related part into our
resolver.  However, it seems to me that there is still same issue in
BIND9's resolver.  So, I change more bit.  Please try the following
patch and let me know the result:

Index: lib/libc/net/getaddrinfo.c
diff -u -p lib/libc/net/getaddrinfo.c.orig lib/libc/net/getaddrinfo.c
--- lib/libc/net/getaddrinfo.c.orig	Sat Jul 23 03:21:28 2005
+++ lib/libc/net/getaddrinfo.c	Thu Feb 23 01:43:49 2006
@@ -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);
Index: lib/libc/net/res_query.c
diff -u -p lib/libc/net/res_query.c.orig lib/libc/net/res_query.c
--- lib/libc/net/res_query.c.orig	Fri Apr 15 23:42:29 2005
+++ lib/libc/net/res_query.c	Thu Feb 23 01:43:49 2006
@@ -198,7 +198,9 @@ res_search(name, class, type, answer, an
 	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, an
 		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, an
 		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, an
 	}
 
 	/*
-	 * 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);


Sincerely,

--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume at mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/


More information about the freebsd-stable mailing list