uclibc  

Re: Facing issue in dns timeout

Bernhard Reutner-Fischer
Fri, 29 Jan 2010 11:08:00 -0800

On Fri, Jan 29, 2010 at 11:55:18AM +0530, yathish chandru wrote:
>Ok, Thanks :)

Please do not top-post.
>
>On Fri, Jan 29, 2010 at 11:42 AM, Khem Raj <raj.k...@gmail.com> wrote:
>
>> On Thu, Jan 28, 2010 at 9:45 PM, yathish chandru
>> <yathish.an...@gmail.com> wrote:
>> > Thanks for the quick response Raj. Now,is there any plan to make it as
>> > configurable paramater according to the resolv.conf file man pages, for
>> the
>> > timeout:n and attempts:n in the next releases.
>>
>> I am not aware of any effort. But patches are welcome.
>>
>> > Thanks for the support.
>> >
>> > Regards
>> > Yathish
>> >
>> > On Thu, Jan 28, 2010 at 11:49 PM, Khem Raj <raj.k...@gmail.com> wrote:
>> >
>> >>  On (28/01/10 21:30), yathish chandru wrote:
>> >> > Hi All,
>> >> >
>> >> > I'm presently using uClibc-0.9.28.2 , in that the proble facing when I
>> >> make
>> >> > a call for getaddrinfo().
>> >> >
>> >> > Occasionaly the DNS server is taking long DNS response, so after
>> >> verifying
>> >> > the resolv.c file,
>> >> >
>> >> > Found that getaddrinfo,uClibc library and we found that it is hard
>> coded
>> >> to
>> >> > 10 Seconds. Attaching the file resolv.c from uclibc.
>> >> > Please look at the function __dns_lookup() and grep for REPLY_TIMEOUT,
>> so
>> >> in
>> >> > the function is in loop for MAX_RETRIES with REPLY_TIMOUT in the
>> select
>> >> > posix call.
>> >> > So, since the  REPLY_TIMEOUT is hard coded, and I didn't find any
>> >> function
>> >> > to override the timeout. To reduce the timeout we need to recompile
>> >> UClibc
>> >> > library.
>> >> >  So, the RES_TIMEOUT which is avalable in resolv.conf is of no use.
>> >> > Since, the problem in our application is the first dns request in
>> >> > getaddrinfo is failing and the second one passes, so wanted to retry
>> by
>> >> > reducing the timeout but foud no option.
>> >> > Is this the same behaviour in lthe latest uclibc. Please let us know
>> on
>> >> this
>> >> > issue.
>> >>
>> >> now it has been reduced to 5sec but is still hardcoded. For resolv.conf
>> >> I only see 'domain', 'search' and 'nameserver' keywords being handled so
>> >> timeout:n may not work

options are not implemented, as khem said.
If somebody can proof-read attached patch then we could install it to
master iff somebody else thinks it's benefical overall.

Two notes: First, it's completely untested and second it's probably a bit
bloated for what it does, i guess (reimplementations welcome). Stats:

bloat-o-meter lib.old/libuClibc-0.9.30-git.so lib/libuClibc-0.9.30-git.so 
function                                             old     new   delta
__open_nameservers                                   986    1121    +135
__dns_lookup                                        1812    1841     +29
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 164/0)             Total: 164 bytes

Opinions?

diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 4087f8d..e6c4d99 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -328,6 +328,13 @@ Domain name in a message can be represented as either:
 #else
 #define IF_HAS_BOTH(...)
 #endif
+#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
+# define _RES_RETRANS _res.retrans
+# define _RES_RETRY _res.retry
+#else
+# define _RES_RETRANS RES_TIMEOUT
+# define _RES_RETRY RES_DFLRETRY
+#endif
 
 #define MAX_RECURSE    5
 #define MAX_ALIASES    5
@@ -1047,6 +1054,26 @@ void attribute_hidden __open_nameservers(void)
 					goto next_word;
 				continue;
 			}
+#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
+			if (strcmp(keyword, "options") == 0) {
+				char *p1;
+				int *what;
+
+				if (p == NULL || (p1 = strchr(p, ':')) == NULL)
+					continue;
+				*p1++ = '\0';
+				if (p1 == NULL)
+					continue;
+				if (strcmp(p, "timeout") == 0)
+					what = &_res.retrans;
+				else if (strcmp(p, "attempts") == 0)
+					what = &_res.retry;
+				else
+					continue;
+				*what = atoi(p1);
+				DPRINTF("option %s:%d\n", p, *what);
+			}
+#endif
 			/* if (strcmp(keyword, "sortlist") == 0)... */
 			/* if (strcmp(keyword, "options") == 0)... */
 		}
@@ -1285,8 +1312,7 @@ int attribute_hidden __dns_lookup(const char *name,
 			local_ns_num = 0;
 			if (_res.options & RES_ROTATE) */
 				local_ns_num = last_ns_num;
-/*TODO: use _res.retry */
-			retries_left = __nameservers * RES_DFLRETRY;
+			retries_left = __nameservers * _RES_RETRY;
 		}
 		retries_left--;
 		if (local_ns_num >= __nameservers)
@@ -1345,8 +1371,7 @@ int attribute_hidden __dns_lookup(const char *name,
 		send(fd, packet, packet_len, 0);
 
 #ifdef USE_SELECT
-/*TODO: use _res.retrans*/
-		reply_timeout = RES_TIMEOUT;
+		reply_timeout = _RES_RETRANS;
  wait_again:
 		FD_ZERO(&fds);
 		FD_SET(fd, &fds);
@@ -1360,7 +1385,7 @@ int attribute_hidden __dns_lookup(const char *name,
 		}
 		reply_timeout--;
 #else
-		reply_timeout = RES_TIMEOUT * 1000;
+		reply_timeout = _RES_RETRANS * 1000;
  wait_again:
 		fds.fd = fd;
 		fds.events = POLLIN;
@@ -2906,7 +2931,7 @@ int res_init(void)
 	rp->options = RES_INIT;
 #ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
 	rp->retrans = RES_TIMEOUT;
-	rp->retry = 4;
+	rp->retry = RES_DFLRETRY;
 /*TODO: pulls in largish static buffers... use simpler one? */
 	rp->id = random();
 #endif
_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc