non-fully qualified hostname resolution (__dns_lookup) failing 0.9.31

Shawn Authement Shawn.Authement at texmemsys.com
Tue Aug 31 16:14:27 UTC 2010


L H wrote:
> Since updating to 0.9.31 of uClibc, I'm finding my hostname resolution
> is failing for hosts without a fully qualified name despite having a
> (presumably) valid /etc/resolv.conf of the form:
>
> ---------------------------------
> search mydomain.com
> nameserver xx.xx.xx.xx
> ----------------------------------
>
>
> # ping myhost
> ping:  bad address 'myhost'
>
> # ping myhost.mydomain.com
> PING myhost.mydomain.com (x.x.x.x) ...    # i.e. works fine
>
>
> Looking at the 0.9.31 uClibc source: libc/inet/resolv.c, I found that
> if I altered the initialization of the variable, "variant", in
> function __dns_lookup) to ZERO instead of the present value -1, then
> non-fully qualified hostname lookups worked.  However, that of course
> broke name resolution for hostnames that had a fully qualified name to
> start with as it always added the search domain to the already fully
> qualified name (e.g. it would try myhost.mydomain.com.mydomain.com).
>
> I looked at bugzilla and here on the list, and was surprised to see no
> mention of this issue thinking I can't possibly be the first one to
> run into this.
>
> --LH
> _______________________________________________
> uClibc mailing list
> uClibc at uclibc.org
> http://lists.busybox.net/mailman/listinfo/uclibc
>   

Quite fortuitous timing.  I have recently run into this issue as well.  
While
investigating the issue, I noted that a change from 0.9.30 to 0.9.31
was to remove the fall-back case for trying the next search domain.
My solution was just to add that code snippet back.  I'm not sure if this
would be an acceptable patch to submit.

diff -Naur uClibc-0.9.31/libc/inet/resolv.c 
uClibc-0.9.31-new/libc/inet/resolv.c
--- uClibc-0.9.31/libc/inet/resolv.c    2010-04-02 10:34:27.000000000 -0500
+++ uClibc-0.9.31-new/libc/inet/resolv.c    2010-08-24 
11:15:18.000000000 -0500
@@ -1438,7 +1438,7 @@
  bogus_packet:
             if (reply_timeout)
                 goto wait_again;
-            goto try_next_server;
+            goto try_next_domain;
         }
         __decode_header(packet, &h);
         DPRINTF("len:%d id:%d qr:%d\n", packet_len, h.id, h.qr);
@@ -1474,9 +1474,10 @@
         /* Insert other non-fatal errors here, which do not warrant
          * switching to next nameserver */
 
-        /* Strange error, assuming this nameserver is feeling bad */
+        /* TMS GForge Bug [#19959] (RS-Flash)
+         * Try other search domains first no matter what error we get. */
         if (h.rcode != 0)
-            goto try_next_server;
+            goto try_next_domain;
 
         /* Code below won't work correctly with h.ancount == 0, so... */
         if (h.ancount <= 0) {
@@ -1489,8 +1490,8 @@
             i = __length_question(packet + pos, packet_len - pos);
             if (i < 0) {
                 DPRINTF("Packet'question section "
-                    "is truncated, trying next server\n");
-                goto try_next_server;
+                        "is truncated, trying next search domain\n");
+                goto try_next_domain;
             }
             pos += i;
             DPRINTF("Length of question %d is %d\n", j, i);
@@ -1506,7 +1507,7 @@
                  * decoded some answers, pretend it's OK */
                 if (j && h.tc)
                     break;
-                goto try_next_server;
+                goto try_next_domain;
             }
             pos += i;
 
@@ -1534,7 +1535,7 @@
                     free(a->dotted);
                     DPRINTF("Answer address len(%u) differs from 
original(%u)\n",
                             ma.rdlength, a->rdlength);
-                    goto try_next_server;
+                    goto try_next_domain;
                 }
                 memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, 
ma.rdlength);
                 ++a->add_count;
@@ -1553,6 +1554,28 @@
         free(lookup);
         return packet_len;
 
+ /*
+  * uClibc-0.9.30 used to have this block as part of the 
try_next_server goto.
+  * This verson (0.9.31) removed it.  Not having this check caused this 
code to
+  * skip any search domains in /etc/resolv.conf all together, meaning 
all DNS
+  * lookups on hostnames would fail unless given the fully qualified domain
+  * name. We have added this extra goto so that we can have a little extra
+  * control over when we try more search domains or just skip to the 
next name
+  * server.  For example, if we fail to connect to the first name server,
+  * there is no reason to try it again with the search domain 
appended.  Since
+  * version 0.9.30 had this block as part of the try_next_server goto, it
+  * would always try the next search domain causing them to have long,
+  * non-essential timeouts. */
+ try_next_domain:
+    if (!ends_with_dot) {
+        if (variant < sdomains - 1)
+            variant++;
+            continue;
+    }
+
+    /* If there is no search domain to try,
+     * fall through to try the next name server. */
+
  try_next_server:
         /* Try next nameserver */
         local_ns_num++;

-- 
Shawn Authement




CONFIDENTIALITY NOTICE: This email and any attachments are Texas Memory Systems' proprietary material for the exclusive and confidential use of the intended recipient.  If you are not the intended recipient, please do not read, distribute or take action in reliance upon this message. Any unauthorized disclosure is prohibited.  If you have received this in error, please notify us immediately by return email and promptly delete all copies of this message and its attachments from your computer system. 



More information about the uClibc mailing list