* resolv/res_send.c (__libc_res_nsend): Take additional parameter. cvs/fedora-glibc-20080728T2320
authorUlrich Drepper <drepper@redhat.com>
Mon, 28 Jul 2008 22:55:10 +0000 (22:55 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 28 Jul 2008 22:55:10 +0000 (22:55 +0000)
Use it instead of locally defined resplen2 variable.
(res_nsend): Adjust for __libc_res_nsend interface change.
(send_vc): Initialize *resplen2 if necessary.  Read length of
package into an appropriately aligned variable.  Store converted length
in new variable and use it appropriately.
Add branch prediction help.
* resolv/res_query.c (__libc_res_nquery): Take additional parameter
and pass it on to __libc_res_nsend.  Adjust all callers.
(__libc_res_nsearch): Likewise.
(__libc_res_nqeurydomain): Likewise.
* resolv/nss_dns/dns-host.c: Adjust for __libc_res_nsearch interface
change.
(_nss_dns_gethostbyname4): Don't unconditionally allocate tmp array.
Define resplen2 variable and pass it to __libc_res_nsearch and then
to gaih_getanswer.
(getanswer_r): In case of incorrect DNS data don't overread buffer.
Add branch prediction.
(gaih_getanswer_slice): Likewise.  Check for invalid data types.
(gaih_getanswer): Don't decode second slice if first one failed due
to a too small buffer.  Don't let not found status of second
decoder shadow results of the first.
* resolv/gethnamaddr.c (gethostbyname2): Adjust for __libc_res_nsearch
and __libc_res_nquery interface changes
(gethostbyaddr): Adjust for __libc_res_nquery interface change.
* include/resolv.h: Adjust prototypes for __libc_res_nquery,
__libc_res_nsearch, and __libc_res_nsend.
* resolv/nss_dns/dns-canon.c: Adjust for __libc_res_nquery interface
change.
* resolv/nss_dns/dns-network.c: Adjust for __libc_res_nquery and
__libc_res_nsearch interface changes.

ChangeLog
include/resolv.h
resolv/gethnamaddr.c
resolv/nss_dns/dns-canon.c
resolv/nss_dns/dns-host.c
resolv/nss_dns/dns-network.c
resolv/res_query.c
resolv/res_send.c

index 4d5b530cf737fa544fa1f952fcbb75ce953706f7..d4cccb6837575f195c0c2852628eb354d8f29da7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2008-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * resolv/res_send.c (__libc_res_nsend): Take additional parameter.
+       Use it instead of locally defined resplen2 variable.
+       (res_nsend): Adjust for __libc_res_nsend interface change.
+       (send_vc): Initialize *resplen2 if necessary.  Read length of
+       package into an appropriately aligned variable.  Store converted length
+       in new variable and use it appropriately.
+       Add branch prediction help.
+       * resolv/res_query.c (__libc_res_nquery): Take additional parameter
+       and pass it on to __libc_res_nsend.  Adjust all callers.
+       (__libc_res_nsearch): Likewise.
+       (__libc_res_nqeurydomain): Likewise.
+       * resolv/nss_dns/dns-host.c: Adjust for __libc_res_nsearch interface
+       change.
+       (_nss_dns_gethostbyname4): Don't unconditionally allocate tmp array.
+       Define resplen2 variable and pass it to __libc_res_nsearch and then
+       to gaih_getanswer.
+       (getanswer_r): In case of incorrect DNS data don't overread buffer.
+       Add branch prediction.
+       (gaih_getanswer_slice): Likewise.  Check for invalid data types.
+       (gaih_getanswer): Don't decode second slice if first one failed due
+       to a too small buffer.  Don't let not found status of second
+       decoder shadow results of the first.
+       * resolv/gethnamaddr.c (gethostbyname2): Adjust for __libc_res_nsearch
+       and __libc_res_nquery interface changes
+       (gethostbyaddr): Adjust for __libc_res_nquery interface change.
+       * include/resolv.h: Adjust prototypes for __libc_res_nquery,
+       __libc_res_nsearch, and __libc_res_nsend.
+       * resolv/nss_dns/dns-canon.c: Adjust for __libc_res_nquery interface
+       change.
+       * resolv/nss_dns/dns-network.c: Adjust for __libc_res_nquery and
+       __libc_res_nsearch interface changes.
+
 2008-07-27  Ulrich Drepper  <drepper@redhat.com>
 
        * libio/iopopen.c (_IO_new_proc_open): Remove unnecessary volatile.
index 925746f685ebb4c93d57527f1a6153b7ae7daaab..6dae0495b2077476af0a41c96a41c4ff57e5dd2e 100644 (file)
@@ -58,11 +58,11 @@ libc_hidden_proto (__res_randomid)
 libc_hidden_proto (__res_state)
 
 int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
-                      u_char **, u_char **, int *);
+                      u_char **, u_char **, int *, int *);
 int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
-                       u_char **, u_char **, int *);
+                       u_char **, u_char **, int *, int *);
 int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
-                     u_char *, int, u_char **, u_char **, int *)
+                     u_char *, int, u_char **, u_char **, int *, int *)
   attribute_hidden;
 
 libresolv_hidden_proto (_sethtent)
index 2a9bd0b3c2a213588b43bff465f1bbd8c3f73152..5cf660a8d427319c1f17b3a9b288138d80041b3d 100644 (file)
@@ -621,7 +621,7 @@ gethostbyname2(name, af)
        buf.buf = origbuf = (querybuf *) alloca (1024);
 
        if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
-                                   &buf.ptr, NULL, NULL)) < 0) {
+                                   &buf.ptr, NULL, NULL, NULL)) < 0) {
                if (buf.buf != origbuf)
                        free (buf.buf);
                Dprintf("res_nsearch failed (%d)\n", n);
@@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af)
        buf.buf = orig_buf = (querybuf *) alloca (1024);
 
        n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
-                             &buf.ptr, NULL, NULL);
+                             &buf.ptr, NULL, NULL, NULL);
        if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
                strcpy(qp, "ip6.int");
                n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
                                      buf.buf != orig_buf ? MAXPACKET : 1024,
-                                     &buf.ptr, NULL, NULL);
+                                     &buf.ptr, NULL, NULL, NULL);
        }
        if (n < 0) {
                if (buf.buf != orig_buf)
index 47949b862fd9f518eb0dfa076cc30d35d88fc9c7..cee3d57bc104d917018edf4593e8dd92695c3495 100644 (file)
@@ -61,7 +61,8 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
   for (int i = 0; i < nqtypes; ++i)
     {
       int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
-                                buf, sizeof (buf), &ansp.ptr, NULL, NULL);
+                                buf, sizeof (buf), &ansp.ptr, NULL, NULL,
+                                NULL);
       if (r > 0)
        {
          /* We need to decode the response.  Just one question record.
index cae077445f800b3f8d3e208410be08363358867f..80c0bd9fa8406328aeff8d238849bd7fe62a143f 100644 (file)
@@ -195,7 +195,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
   host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
 
   n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
-                         1024, &host_buffer.ptr, NULL, NULL);
+                         1024, &host_buffer.ptr, NULL, NULL, NULL);
   if (n < 0)
     {
       status = (errno == ECONNREFUSED
@@ -213,7 +213,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
        n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
                                host_buffer.buf != orig_host_buffer
                                ? MAXPACKET : 1024, &host_buffer.ptr,
-                               NULL, NULL);
+                               NULL, NULL, NULL);
 
       if (n < 0)
        {
@@ -273,8 +273,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   if (__res_maybe_init (&_res, 0) == -1)
     return NSS_STATUS_UNAVAIL;
 
-  char tmp[NS_MAXDNAME];
-
   /*
    * if there aren't any dots, it could be a user-level alias.
    * this is also done in res_query() since we are not the only
@@ -282,7 +280,8 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
    */
   if (strchr (name, '.') == NULL)
     {
-      const char *cp = res_hostalias (&_res, name, tmp, sizeof (tmp));
+      char *tmp = alloca (NS_MAXDNAME);
+      const char *cp = res_hostalias (&_res, name, tmp, NS_MAXDNAME);
       if (cp != NULL)
        name = cp;
     }
@@ -296,12 +295,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
   u_char *ans2p = NULL;
   int nans2p = 0;
+  int resplen2 = 0;
 
   int olderr = errno;
   enum nss_status status;
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
                              host_buffer.buf->buf, 2048, &host_buffer.ptr,
-                             &ans2p, &nans2p);
+                             &ans2p, &nans2p, &resplen2);
   if (n < 0)
     {
       status = (errno == ECONNREFUSED
@@ -319,7 +319,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
     }
 
   status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
-                         nans2p, name, pat, buffer, buflen,
+                         resplen2, name, pat, buffer, buflen,
                          errnop, herrnop, ttlp);
 
   if (host_buffer.buf != orig_host_buffer)
@@ -417,7 +417,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
          strcpy (qp, "].ip6.arpa");
          n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
                                 host_buffer.buf->buf, 1024, &host_buffer.ptr,
-                                NULL, NULL);
+                                NULL, NULL, NULL);
          if (n >= 0)
            goto got_it_already;
        }
@@ -438,14 +438,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
     }
 
   n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
-                        1024, &host_buffer.ptr, NULL, NULL);
+                        1024, &host_buffer.ptr, NULL, NULL, NULL);
   if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
     {
       strcpy (qp, "ip6.int");
       n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
                             host_buffer.buf != orig_host_buffer
                             ? MAXPACKET : 1024, &host_buffer.ptr,
-                            NULL, NULL);
+                            NULL, NULL, NULL);
     }
   if (n < 0)
     {
@@ -685,12 +685,19 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
          n = -1;
        }
 
-      if (n < 0 || (*name_ok) (bp) == 0)
+      if (__builtin_expect (n < 0 || (*name_ok) (bp) == 0, 0))
        {
          ++had_error;
          continue;
        }
       cp += n;                         /* name */
+
+      if (__builtin_expect (cp + 10 > end_of_message, 0))
+       {
+         ++had_error;
+         continue;
+       }
+
       type = ns_get16 (cp);
       cp += INT16SZ;                   /* type */
       class = ns_get16 (cp);
@@ -699,7 +706,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
       cp += INT32SZ;                   /* TTL */
       n = ns_get16 (cp);
       cp += INT16SZ;                   /* len */
-      if (class != C_IN)
+      if (__builtin_expect (class != C_IN, 0))
        {
          /* XXX - debug? syslog? */
          cp += n;
@@ -711,7 +718,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
          if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
            continue;
          n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
-         if (n < 0 || (*name_ok) (tbuf) == 0)
+         if (__builtin_expect (n < 0 || (*name_ok) (tbuf) == 0, 0))
            {
              ++had_error;
              continue;
@@ -745,7 +752,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
       if (qtype == T_PTR && type == T_CNAME)
        {
          n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
-         if (n < 0 || res_dnok (tbuf) == 0)
+         if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0))
            {
              ++had_error;
              continue;
@@ -792,7 +799,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
       switch (type)
        {
        case T_PTR:
-         if (__strcasecmp (tname, bp) != 0)
+         if (__builtin_expect (__strcasecmp (tname, bp) != 0, 0))
            {
              syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
              cp += n;
@@ -809,7 +816,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
              n = -1;
            }
 
-         if (n < 0 || res_hnok (bp) == 0)
+         if (__builtin_expect (n < 0 || res_hnok (bp) == 0, 0))
            {
              ++had_error;
              break;
@@ -839,7 +846,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
          if (have_to_map)
            {
              n = strlen (bp) + 1;      /* for the \0 */
-             if (n >= MAXHOSTNAMELEN)
+             if (__builtin_expect (n >= MAXHOSTNAMELEN, 0))
                {
                  ++had_error;
                  break;
@@ -957,7 +964,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
       return NSS_STATUS_UNAVAIL;
     }
 
-   u_char packtmp[NS_MAXCDNAME];
+  u_char packtmp[NS_MAXCDNAME];
   int n = __ns_name_unpack (answer->buf, end_of_message, cp,
                            packtmp, sizeof packtmp);
   /* We unpack the name to check it for validity.  But we do not need
@@ -1005,7 +1012,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
 
          n = -1;
        }
-      if (n < 0 || res_hnok (buffer) == 0)
+      if (__builtin_expect (n < 0 || res_hnok (buffer) == 0, 0))
        {
          ++had_error;
          continue;
@@ -1018,6 +1025,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
        }
 
       cp += n;                         /* name */
+
+      if (__builtin_expect (cp + 10 > end_of_message, 0))
+       {
+         ++had_error;
+         continue;
+       }
+
       int type = ns_get16 (cp);
       cp += INT16SZ;                   /* type */
       int class = ns_get16 (cp);
@@ -1037,7 +1051,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
        {
          char tbuf[MAXDNAME];
          n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
-         if (n < 0 || res_hnok (tbuf) == 0)
+         if (__builtin_expect (n < 0 || res_hnok (tbuf) == 0, 0))
            {
              ++had_error;
              continue;
@@ -1130,6 +1144,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
        }
 
       (*pat)->family = type == T_A ? AF_INET : AF_INET6;
+      if (__builtin_expect ((type == T_A && n != INADDRSZ)
+                           || (type == T_AAAA && n != IN6ADDRSZ), 0))
+       {
+         ++had_error;
+         continue;
+       }
       memcpy ((*pat)->addr, cp, n);
       cp += n;
       (*pat)->scopeid = 0;
@@ -1172,14 +1192,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
                                  errnop, h_errnop, ttlp,
                                  &first);
   if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
-       || status == NSS_STATUS_TRYAGAIN)
+       || (status == NSS_STATUS_TRYAGAIN
+          && (errno != ERANGE || *h_errnop != NO_RECOVERY)))
       && answer2 != NULL && anslen2 > 0)
     {
       enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
                                                     &pat, &buffer, &buflen,
                                                     errnop, h_errnop, ttlp,
                                                     &first);
-      if (status != NSS_STATUS_SUCCESS)
+      if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
        status = status2;
     }
 
index 40736fbe94d4e501ff3e28b381a568f2b7e631cd..c9969e08dcdd694ec87f90adb2ba591e6967d450 100644 (file)
@@ -130,7 +130,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 
   anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-                              1024, &net_buffer.ptr, NULL, NULL);
+                              1024, &net_buffer.ptr, NULL, NULL, NULL);
   if (anslen < 0)
     {
       /* Nothing found.  */
@@ -206,7 +206,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 
   anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-                             1024, &net_buffer.ptr, NULL, NULL);
+                             1024, &net_buffer.ptr, NULL, NULL, NULL);
   if (anslen < 0)
     {
       /* Nothing found.  */
index b2b45acde7553006f420324236375ea7710886d4..7102ba948e34c228dde71c3847f95796d71d86e1 100644 (file)
@@ -97,7 +97,8 @@ static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vix
 static int
 __libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
                        int class, int type, u_char *answer, int anslen,
-                       u_char **answerp, u_char **answerp2, int *nanswerp2);
+                       u_char **answerp, u_char **answerp2, int *nanswerp2,
+                       int *resplen2);
 
 /*
  * Formulate a normal query, send, and await answer.
@@ -117,7 +118,8 @@ __libc_res_nquery(res_state statp,
                  int anslen,           /* size of answer buffer */
                  u_char **answerp,     /* if buffer needs to be enlarged */
                  u_char **answerp2,
-                 int *nanswerp2)
+                 int *nanswerp2,
+                 int *resplen2)
 {
        HEADER *hp = (HEADER *) answer;
        int n, use_malloc = 0;
@@ -221,7 +223,7 @@ __libc_res_nquery(res_state statp,
        }
        assert (answerp == NULL || (void *) *answerp == (void *) answer);
        n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
-                            anslen, answerp, answerp2, nanswerp2);
+                            anslen, answerp, answerp2, nanswerp2, resplen2);
        if (use_malloc)
                free (buf);
        if (n < 0) {
@@ -307,7 +309,7 @@ res_nquery(res_state statp,
           int anslen)          /* size of answer buffer */
 {
        return __libc_res_nquery(statp, name, class, type, answer, anslen,
-                                NULL, NULL, NULL);
+                                NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nquery)
 
@@ -325,7 +327,8 @@ __libc_res_nsearch(res_state statp,
                   int anslen,          /* size of answer */
                   u_char **answerp,
                   u_char **answerp2,
-                  int *nanswerp2)
+                  int *nanswerp2,
+                  int *resplen2)
 {
        const char *cp, * const *domain;
        HEADER *hp = (HEADER *) answer;
@@ -349,7 +352,7 @@ __libc_res_nsearch(res_state statp,
        if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
                return (__libc_res_nquery(statp, cp, class, type, answer,
                                          anslen, answerp, answerp2,
-                                         nanswerp2));
+                                         nanswerp2, resplen2));
 
 #ifdef DEBUG
        if (statp->options & RES_DEBUG)
@@ -366,7 +369,7 @@ __libc_res_nsearch(res_state statp,
        if (dots >= statp->ndots || trailing_dot) {
                ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
                                              answer, anslen, answerp,
-                                             answerp2, nanswerp2);
+                                             answerp2, nanswerp2, resplen2);
                if (ret > 0 || trailing_dot)
                        return (ret);
                saved_herrno = h_errno;
@@ -404,7 +407,8 @@ __libc_res_nsearch(res_state statp,
                        ret = __libc_res_nquerydomain(statp, name, *domain,
                                                      class, type,
                                                      answer, anslen, answerp,
-                                                     answerp2, nanswerp2);
+                                                     answerp2, nanswerp2,
+                                                     resplen2);
                        if (ret > 0)
                                return (ret);
 
@@ -473,7 +477,7 @@ __libc_res_nsearch(res_state statp,
        if (dots && !(tried_as_is || root_on_list)) {
                ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
                                              answer, anslen, answerp,
-                                             answerp2, nanswerp2);
+                                             answerp2, nanswerp2, resplen2);
                if (ret > 0)
                        return (ret);
        }
@@ -508,7 +512,7 @@ res_nsearch(res_state statp,
            int anslen)         /* size of answer */
 {
        return __libc_res_nsearch(statp, name, class, type, answer,
-                                 anslen, NULL, NULL, NULL);
+                                 anslen, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsearch)
 
@@ -525,7 +529,8 @@ __libc_res_nquerydomain(res_state statp,
                        int anslen,                     /* size of answer */
                        u_char **answerp,
                        u_char **answerp2,
-                       int *nanswerp2)
+                       int *nanswerp2,
+                       int *resplen2)
 {
        char nbuf[MAXDNAME];
        const char *longname = nbuf;
@@ -562,7 +567,8 @@ __libc_res_nquerydomain(res_state statp,
                sprintf(nbuf, "%s.%s", name, domain);
        }
        return (__libc_res_nquery(statp, longname, class, type, answer,
-                                 anslen, answerp, answerp2, nanswerp2));
+                                 anslen, answerp, answerp2, nanswerp2,
+                                 resplen2));
 }
 
 int
@@ -574,7 +580,7 @@ res_nquerydomain(res_state statp,
            int anslen)         /* size of answer */
 {
        return __libc_res_nquerydomain(statp, name, domain, class, type,
-                                      answer, anslen, NULL, NULL, NULL);
+                                      answer, anslen, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nquerydomain)
 
index dec3ac7a3fcc63331a5aa6f5c55fb2554e59e90d..3130f64281af69c576872adb34959e4b8f6a4031 100644 (file)
@@ -339,9 +339,9 @@ int
 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
                 const u_char *buf2, int buflen2,
                 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
-                int *nansp2)
+                int *nansp2, int *resplen2)
 {
-  int gotsomewhere, terrno, try, v_circuit, resplen, resplen2, ns, n;
+  int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 
        if (statp->nscount == 0) {
                __set_errno (ESRCH);
@@ -539,7 +539,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
                        try = statp->retry;
                        n = send_vc(statp, buf, buflen, buf2, buflen2,
                                    &ans, &anssiz, &terrno,
-                                   ns, ansp, ansp2, nansp2, &resplen2);
+                                   ns, ansp, ansp2, nansp2, resplen2);
                        if (n < 0)
                                return (-1);
                        if (n == 0)
@@ -549,14 +549,14 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
                        n = send_dg(statp, buf, buflen, buf2, buflen2,
                                    &ans, &anssiz, &terrno,
                                    ns, &v_circuit, &gotsomewhere, ansp,
-                                   ansp2, nansp2, &resplen2);
+                                   ansp2, nansp2, resplen2);
                        if (n < 0)
                                return (-1);
                        if (n == 0)
                                goto next_ns;
                        if (v_circuit)
                          // XXX Check whether both requests failed or
-                         // XXX whether one have been answered successfully
+                         // XXX whether one has been answered successfully
                                goto same_ns;
                }
 
@@ -575,7 +575,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
                  DprintQ((statp->options & RES_DEBUG) ||
                          (statp->pfcode & RES_PRF_REPLY),
                          (stdout, "%s", ""),
-                         *ansp2, (resplen2 > *nansp2) ? *nansp2 : resplen2);
+                         *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
 
                /*
                 * If we have temporarily opened a virtual circuit,
@@ -638,7 +638,7 @@ res_nsend(res_state statp,
          const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
   return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
-                         NULL, NULL, NULL);
+                         NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsend)
 
@@ -665,6 +665,8 @@ send_vc(res_state statp,
        u_short len2;
        u_char *cp;
 
+       if (resplen2 != NULL)
+         *resplen2 = 0;
        connreset = 0;
  same_ns:
        truncating = 0;
@@ -734,8 +736,9 @@ send_vc(res_state statp,
        int recvresp2 = buf2 == NULL;
  read_len:
        cp = ans;
-       len = INT16SZ;
-       while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, (char *)cp,
+       uint16_t rlen16;
+       len = sizeof(rlen16);
+       while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, &rlen16,
                                             (int)len))) > 0) {
                cp += n;
                if ((len -= n) <= 0)
@@ -760,11 +763,7 @@ send_vc(res_state statp,
                }
                return (0);
        }
-#ifdef _STRING_ARCH_unaligned
-       resplen = ntohs (*(uint16_t *) ans);
-#else
-       resplen = ns_get16(ans);
-#endif
+       int rlen = ntohs (rlen16);
 
        int *thisanssizp;
        u_char **thisansp;
@@ -795,11 +794,11 @@ send_vc(res_state statp,
        }
        anhp = (HEADER *) *thisansp;
 
-       *thisresplenp = resplen;
-       if (resplen > *thisanssizp) {
+       *thisresplenp = rlen;
+       if (rlen > *thisanssizp) {
                /* Yes, we test ANSCP here.  If we have two buffers
                   both will be allocatable.  */
-               if (anscp) {
+               if (__builtin_expect (anscp != NULL, 1)) {
                        u_char *newp = malloc (MAXPACKET);
                        if (newp == NULL) {
                                *terrno = ENOMEM;
@@ -809,7 +808,7 @@ send_vc(res_state statp,
                        *thisanssizp = MAXPACKET;
                        *thisansp = newp;
                        anhp = (HEADER *) newp;
-                       len = resplen;
+                       len = rlen;
                } else {
                        Dprint(statp->options & RES_DEBUG,
                                (stdout, ";; response truncated\n")
@@ -818,9 +817,9 @@ send_vc(res_state statp,
                        len = *thisanssizp;
                }
        } else
-               len = resplen;
+               len = rlen;
 
-       if (len < HFIXEDSZ) {
+       if (__builtin_expect (len < HFIXEDSZ, 0)) {
                /*
                 * Undersized message.
                 */
@@ -836,18 +835,18 @@ send_vc(res_state statp,
                cp += n;
                len -= n;
        }
-       if (n <= 0) {
+       if (__builtin_expect (n <= 0, 0)) {
                *terrno = errno;
                Perror(statp, stderr, "read(vc)", errno);
                __res_iclose(statp, false);
                return (0);
        }
-       if (truncating) {
+       if (__builtin_expect (truncating, 0)) {
                /*
                 * Flush rest of answer so connection stays in synch.
                 */
                anhp->tc = 1;
-               len = resplen - *thisanssizp;
+               len = rlen - *thisanssizp;
                while (len != 0) {
                        char junk[PACKETSZ];
 
@@ -872,7 +871,7 @@ send_vc(res_state statp,
                        (statp->pfcode & RES_PRF_REPLY),
                        (stdout, ";; old answer (unexpected):\n"),
                        *thisansp,
-                       (resplen > *thisanssiz) ? *thisanssiz: resplen);
+                       (rlen > *thisanssiz) ? *thisanssiz: rlen);
                goto read_len;
        }
 
@@ -889,7 +888,7 @@ send_vc(res_state statp,
         * All is well, or the error is fatal.  Signal that the
         * next nameserver ought not be tried.
         */
-       return (resplen);
+       return resplen;
 }
 
 static int
@@ -1084,7 +1083,7 @@ send_dg(res_state statp,
                *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
                                         *thisanssizp, 0,
                                        (struct sockaddr *)&from, &fromlen);
-               if (*thisresplenp <= 0) {
+               if (__builtin_expect (*thisresplenp <= 0, 0)) {
                        if (errno == EINTR || errno == EAGAIN) {
                                need_recompute = 1;
                                goto wait;
@@ -1093,7 +1092,7 @@ send_dg(res_state statp,
                        goto err_out;
                }
                *gotsomewhere = 1;
-               if (*thisresplenp < HFIXEDSZ) {
+               if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) {
                        /*
                         * Undersized message.
                         */