Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc Rest of fix for PR#31184: getaddrinfo() now honors ...



details:   https://anonhg.NetBSD.org/src/rev/18ad9f7c21be
branches:  trunk
changeset: 584414:18ad9f7c21be
user:      tsarna <tsarna%NetBSD.org@localhost>
date:      Thu Sep 15 23:33:41 2005 +0000

description:
Rest of fix for PR#31184: getaddrinfo() now honors resolv.conf sortlist
directive for dns answers.

Also, unifdef the RESLVSORT (non-)option sillyness.

Reviewed by christos.

diffstat:

 lib/libc/net/getaddrinfo.c |  83 +++++++++++++++++++++++++++++++++------------
 lib/libc/net/gethnamaddr.c |  11 +----
 lib/libc/resolv/res_init.c |  17 +--------
 3 files changed, 64 insertions(+), 47 deletions(-)

diffs (truncated from 372 to 300 lines):

diff -r 70ab3ba883f0 -r 18ad9f7c21be lib/libc/net/getaddrinfo.c
--- a/lib/libc/net/getaddrinfo.c        Thu Sep 15 22:49:33 2005 +0000
+++ b/lib/libc/net/getaddrinfo.c        Thu Sep 15 23:33:41 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: getaddrinfo.c,v 1.72 2004/05/27 18:40:07 christos Exp $        */
+/*     $NetBSD: getaddrinfo.c,v 1.73 2005/09/15 23:33:41 tsarna Exp $  */
 /*     $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $    */
 
 /*
@@ -79,7 +79,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: getaddrinfo.c,v 1.72 2004/05/27 18:40:07 christos Exp $");
+__RCSID("$NetBSD: getaddrinfo.c,v 1.73 2005/09/15 23:33:41 tsarna Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -234,6 +234,7 @@
 
 static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
        const struct addrinfo *);
+static void aisort(struct addrinfo *s, res_state res);
 static int _dns_getaddrinfo(void *, void *, va_list);
 static void _sethtent(FILE **);
 static void _endhtent(FILE **);
@@ -246,7 +247,7 @@
 #endif
 
 static int res_queryN(const char *, struct res_target *, res_state);
-static int res_searchN(const char *, struct res_target *);
+static int res_searchN(const char *, struct res_target *, res_state);
 static int res_querydomainN(const char *, const char *,
        struct res_target *, res_state);
 
@@ -1241,6 +1242,37 @@
        return NULL;
 }
 
+#define SORTEDADDR(p)  (((struct sockaddr_in *)(void *)(p->ai_next->ai_addr))->sin_addr.s_addr)
+#define SORTMATCH(p, s) ((SORTEDADDR(p) & (s).mask) == (s).addr.s_addr)
+
+static void
+aisort(struct addrinfo *s, res_state res)
+{
+       struct addrinfo head, *t, *p;
+       int i;
+
+       head.ai_next = NULL;
+       t = &head;
+
+       for (i = 0; i < res->nsort; i++) {
+               p = s;
+               while (p->ai_next) {
+                       if ((p->ai_next->ai_family != AF_INET)
+                       || SORTMATCH(p, res->sort_list[i])) {
+                               t->ai_next = p->ai_next;
+                               t = t->ai_next;
+                               p->ai_next = p->ai_next->ai_next;
+                       } else {
+                               p = p->ai_next;
+                       }
+               }
+       }
+
+       /* add rest of list and reset s to the new list*/
+       t->ai_next = s->ai_next;
+       s->ai_next = head.ai_next;
+}
+
 /*ARGSUSED*/
 static int
 _dns_getaddrinfo(void *rv, void        *cb_data, va_list ap)
@@ -1251,6 +1283,7 @@
        const struct addrinfo *pai;
        struct addrinfo sentinel, *cur;
        struct res_target q, q2;
+       res_state res;
 
        name = va_arg(ap, char *);
        pai = va_arg(ap, const struct addrinfo *);
@@ -1306,7 +1339,16 @@
                free(buf2);
                return NS_UNAVAIL;
        }
-       if (res_searchN(name, &q) < 0) {
+
+       res = __res_get_state();
+       if (res == NULL) {
+               free(buf);
+               free(buf2);
+               return NS_NOTFOUND;
+       }
+
+       if (res_searchN(name, &q, res) < 0) {
+               __res_put_state(res);
                free(buf);
                free(buf2);
                return NS_NOTFOUND;
@@ -1324,7 +1366,8 @@
        }
        free(buf);
        free(buf2);
-       if (sentinel.ai_next == NULL)
+       if (sentinel.ai_next == NULL) {
+               __res_put_state(res);
                switch (h_errno) {
                case HOST_NOT_FOUND:
                        return NS_NOTFOUND;
@@ -1333,6 +1376,13 @@
                default:
                        return NS_UNAVAIL;
                }
+       }
+
+       if (res->nsort)
+               aisort(&sentinel, res);
+
+       __res_put_state(res);
+
        *((struct addrinfo **)rv) = sentinel.ai_next;
        return NS_SUCCESS;
 }
@@ -1712,17 +1762,13 @@
  * is detected.  Error code, if any, is left in h_errno.
  */
 static int
-res_searchN(const char *name,  /* domain name */ struct res_target *target)
+res_searchN(const char *name, struct res_target *target, res_state res)
 {
        const char *cp, * const *domain;
        HEADER *hp;
        u_int dots;
        int trailing_dot, ret, saved_herrno;
        int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
-       res_state res = __res_get_state();
-
-       if (res == NULL)
-               return -1;
 
        _DIAGASSERT(name != NULL);
        _DIAGASSERT(target != NULL);
@@ -1743,7 +1789,6 @@
         */
        if (!dots && (cp = __hostalias(name)) != NULL) {
                ret = res_queryN(cp, target, res);
-               __res_put_state(res);
                return ret;
        }
 
@@ -1754,10 +1799,8 @@
        saved_herrno = -1;
        if (dots >= res->ndots) {
                ret = res_querydomainN(name, NULL, target, res);
-               if (ret > 0) {
-                       __res_put_state(res);
+               if (ret > 0)
                        return (ret);
-               }
                saved_herrno = h_errno;
                tried_as_is++;
        }
@@ -1777,10 +1820,8 @@
                   domain++) {
 
                        ret = res_querydomainN(name, *domain, target, res);
-                       if (ret > 0) {
-                               __res_put_state(res);
+                       if (ret > 0)
                                return ret;
-                       }
 
                        /*
                         * If no server present, give up.
@@ -1797,7 +1838,6 @@
                         */
                        if (errno == ECONNREFUSED) {
                                h_errno = TRY_AGAIN;
-                               __res_put_state(res);
                                return -1;
                        }
 
@@ -1835,13 +1875,10 @@
         */
        if (!tried_as_is) {
                ret = res_querydomainN(name, NULL, target, res);
-               if (ret > 0) {
-                       __res_put_state(res);
+               if (ret > 0)
                        return ret;
-               }
        }
 
-       __res_put_state(res);
        /*
         * if we got here, we didn't satisfy the search.
         * if we did an initial full query, return that query's h_errno
@@ -1864,7 +1901,7 @@
  * removing a trailing dot from name if domain is NULL.
  */
 static int
-res_querydomainN(const char *name, const char *domain, 
+res_querydomainN(const char *name, const char *domain,
     struct res_target *target, res_state res)
 {
        char nbuf[MAXDNAME];
diff -r 70ab3ba883f0 -r 18ad9f7c21be lib/libc/net/gethnamaddr.c
--- a/lib/libc/net/gethnamaddr.c        Thu Sep 15 22:49:33 2005 +0000
+++ b/lib/libc/net/gethnamaddr.c        Thu Sep 15 23:33:41 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gethnamaddr.c,v 1.66 2005/09/15 15:25:40 tsarna Exp $  */
+/*     $NetBSD: gethnamaddr.c,v 1.67 2005/09/15 23:33:41 tsarna Exp $  */
 
 /*
  * ++Copyright++ 1985, 1988, 1993
@@ -57,7 +57,7 @@
 static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";
 static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp ";
 #else
-__RCSID("$NetBSD: gethnamaddr.c,v 1.66 2005/09/15 15:25:40 tsarna Exp $");
+__RCSID("$NetBSD: gethnamaddr.c,v 1.67 2005/09/15 23:33:41 tsarna Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -84,7 +84,6 @@
 #endif
 
 #define MULTI_PTRS_ARE_ALIASES 1       /* XXX - experimental */
-#define RESOLVSORT
 
 #include <nsswitch.h>
 #include <stdlib.h>
@@ -141,9 +140,7 @@
     res_state);
 static void map_v4v6_address(const char *, char *);
 static void map_v4v6_hostent(struct hostent *, char **, char *);
-#ifdef RESOLVSORT
 static void addrsort(char **, int, res_state);
-#endif
 
 void _sethtent(int);
 void _endhtent(void);
@@ -481,7 +478,6 @@
        if (haveanswer) {
                *ap = NULL;
                *hap = NULL;
-# if defined(RESOLVSORT)
                /*
                 * Note: we sort even if host can take only one address
                 * in its return structures - should give it the "best"
@@ -489,7 +485,6 @@
                 */
                if (res->nsort && haveanswer > 1 && qtype == T_A)
                        addrsort(h_addr_ptrs, haveanswer, res);
-# endif /*RESOLVSORT*/
                if (!host.h_name) {
                        n = strlen(qname) + 1;  /* for the \0 */
                        if (n > ep - bp || n >= MAXHOSTNAMELEN)
@@ -1020,7 +1015,6 @@
        }
 }
 
-#ifdef RESOLVSORT
 static void
 addrsort(char **ap, int num, res_state res)
 {
@@ -1063,7 +1057,6 @@
            needsort++;
        }
 }
-#endif
 
 struct hostent *
 gethostent(void)
diff -r 70ab3ba883f0 -r 18ad9f7c21be lib/libc/resolv/res_init.c
--- a/lib/libc/resolv/res_init.c        Thu Sep 15 22:49:33 2005 +0000
+++ b/lib/libc/resolv/res_init.c        Thu Sep 15 23:33:41 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_init.c,v 1.5 2004/05/21 16:03:05 christos Exp $    */
+/*     $NetBSD: res_init.c,v 1.6 2005/09/15 23:33:41 tsarna Exp $      */
 
 /*
  * Copyright (c) 1985, 1989, 1993
@@ -76,7 +76,7 @@
 static const char sccsid[] = "@(#)res_init.c   8.1 (Berkeley) 6/7/93";
 static const char rcsid[] = "Id: res_init.c,v 1.9.2.5.4.2 2004/03/16 12:34:18 marka Exp";
 #else
-__RCSID("$NetBSD: res_init.c,v 1.5 2004/05/21 16:03:05 christos Exp $");
+__RCSID("$NetBSD: res_init.c,v 1.6 2005/09/15 23:33:41 tsarna Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -121,16 +121,13 @@
 #include "res_private.h"
 
 /* Options.  Should all be left alone. */
-#define RESOLVSORT
 #define DEBUG
 
 static void res_setoptions __P((res_state, const char *, const char *));



Home | Main Index | Thread Index | Old Index