Source-Changes-HG archive

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

[src/trunk]: src/lib/libc/net cleanup nsaddr_list handling.



details:   https://anonhg.NetBSD.org/src/rev/7bd574d84f2c
branches:  trunk
changeset: 485331:7bd574d84f2c
user:      itojun <itojun%NetBSD.org@localhost>
date:      Tue Apr 25 08:51:39 2000 +0000

description:
cleanup nsaddr_list handling.
- be more backward compatible with apps that update _res.nsaddr_list[n].
- allow scoped IPv6 addresses in /etc/resolv.conf (like fe80::1%lo0).
- simplify #ifdefs.

diffstat:

 lib/libc/net/res_init.c |  97 ++++++++++++++++++++----------------------------
 lib/libc/net/res_send.c |  75 +++++++++++++++++++++----------------
 2 files changed, 83 insertions(+), 89 deletions(-)

diffs (300 lines):

diff -r 208d392b158b -r 7bd574d84f2c lib/libc/net/res_init.c
--- a/lib/libc/net/res_init.c   Tue Apr 25 06:20:14 2000 +0000
+++ b/lib/libc/net/res_init.c   Tue Apr 25 08:51:39 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_init.c,v 1.29 2000/01/22 23:32:13 mycroft Exp $    */
+/*     $NetBSD: res_init.c,v 1.30 2000/04/25 08:51:39 itojun Exp $     */
 
 /*-
  * Copyright (c) 1985, 1989, 1993
@@ -59,7 +59,7 @@
 static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
 static char rcsid[] = "Id: res_init.c,v 8.8 1997/06/01 20:34:37 vixie Exp ";
 #else
-__RCSID("$NetBSD: res_init.c,v 1.29 2000/01/22 23:32:13 mycroft Exp $");
+__RCSID("$NetBSD: res_init.c,v 1.30 2000/04/25 08:51:39 itojun Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -140,22 +140,8 @@
 #ifdef SEARCH_LOCAL_DOMAINS
        int dots;
 #endif
-#ifdef INET6
-       struct sockaddr_in6 *sin6;
-#endif
 
        _res.id = res_randomid();
-#ifdef INET6
-       sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr;
-       sin6->sin6_len = sizeof(struct sockaddr_in6);
-       sin6->sin6_family = AF_INET6;
-       sin6->sin6_port = htons(NAMESERVER_PORT);
-#ifdef USELOOPBACK
-       sin6->sin6_addr = in6addr_loopback;
-#else
-       sin6->sin6_addr = in6addr_any;
-#endif
-#endif
        _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
        _res.nsaddr.sin_family = AF_INET;
        _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
@@ -164,6 +150,10 @@
 #else
        _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
 #endif
+#ifdef INET6
+       if (sizeof(_res_ext.nsaddr) >= sizeof(_res.nsaddr))
+               memcpy(&_res_ext.nsaddr, &_res.nsaddr, _res.nsaddr.sin_len);
+#endif
        _res.nscount = 1;
        _res.ndots = 1;
        _res.pfcode = 0;
@@ -273,16 +263,18 @@
                }
                /* read nameservers to query */
                if (MATCH(buf, "nameserver") && nserv < MAXNS) {
-#ifdef INET6
+                   struct addrinfo hints, *res;
+                   char pbuf[NI_MAXSERV];
                    char *q;
-                   struct in6_addr a6;
-#endif /* INET6 */
-                   struct in_addr a;
+#ifdef INET6
+                   const size_t minsiz = sizeof(_res_ext.nsaddr_list[0]);
+#else
+                   const size_t minsiz = sizeof(_res.nsaddr_list[0]);
+#endif
 
                    cp = buf + sizeof("nameserver") - 1;
                    while (*cp == ' ' || *cp == '\t')
                        cp++;
-#ifdef INET6
                    if ((*cp == '\0') || (*cp == '\n'))
                        continue;
                    for (q = cp; *q; q++) {
@@ -291,45 +283,36 @@
                            break;
                        }
                    }
-                   if (inet_pton(AF_INET6, cp, &a6) == 1) {
-                       sin6 = (struct sockaddr_in6 *)
-                               &_res_ext.nsaddr_list[nserv];
-                       memset(sin6, 0, sizeof(*sin6));
-                       sin6->sin6_family = AF_INET6;
-                       sin6->sin6_len = sizeof(struct sockaddr_in6);
-                       memcpy(&sin6->sin6_addr, &a6, sizeof(sin6->sin6_addr));
-                       sin6->sin6_port = htons(NAMESERVER_PORT);
-                       /* just for safety */
+                   memset(&hints, 0, sizeof(hints));
+                   hints.ai_family = PF_UNSPEC;
+                   hints.ai_socktype = SOCK_DGRAM;
+                   hints.ai_flags = AI_NUMERICHOST;
+                   snprintf(pbuf, sizeof(pbuf), "%d", NAMESERVER_PORT);
+                   res = NULL;
+                   if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
+                       minsiz >= res->ai_addrlen) {
                        memset(&_res.nsaddr_list[nserv], 0,
-                               sizeof(_res.nsaddr_list[nserv]));
-                       _res.nsaddr_list[nserv].sin_family = AF_INET;
-                       _res.nsaddr_list[nserv].sin_len =
-                               sizeof(struct sockaddr_in);
-                       nserv++;
-                   } else if (inet_pton(AF_INET, cp, &a) == 1) {
-                       struct sockaddr_in *sin;
-                       sin = (struct sockaddr_in *)
-                               &_res_ext.nsaddr_list[nserv];
-                       memset(sin, 0, sizeof(*sin));
-                       sin->sin_family = AF_INET;
-                       sin->sin_len = sizeof(struct sockaddr_in);
-                       memcpy(&sin->sin_addr, &a, sizeof(sin->sin_addr));
-                       sin->sin_port = htons(NAMESERVER_PORT);
-                       /* backward compat */
-                       memcpy(&_res.nsaddr_list[nserv], sin,
-                           (size_t)sin->sin_len);
+                           sizeof(_res.nsaddr_list[nserv]));
+#ifdef INET6
+                       /*
+                        * we copy the address to _res.nsaddr_list for
+                        * backward compatibility only.
+                        */
+#endif
+                       if (sizeof(_res.nsaddr_list[nserv]) >= res->ai_addrlen) {
+                           memcpy(&_res.nsaddr_list[nserv], res->ai_addr,
+                               res->ai_addrlen);
+                       }
+#ifdef INET6
+                       memset(&_res_ext.nsaddr_list[nserv], 0,
+                           sizeof(_res_ext.nsaddr_list[nserv]));
+                       memcpy(&_res_ext.nsaddr_list[nserv], res->ai_addr,
+                           res->ai_addrlen);
+#endif
                        nserv++;
                    }
-#else /* INET6 */
-                   if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
-                       _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in);
-                       _res.nsaddr_list[nserv].sin_family = AF_INET;
-                       _res.nsaddr_list[nserv].sin_port =
-                               htons(NAMESERVER_PORT);
-                       _res.nsaddr_list[nserv].sin_addr = a;
-                       nserv++;
-                   }
-#endif /* INET6 */
+                   if (res)
+                       freeaddrinfo(res);
                    continue;
                }
                if (MATCH(buf, "sortlist")) {
diff -r 208d392b158b -r 7bd574d84f2c lib/libc/net/res_send.c
--- a/lib/libc/net/res_send.c   Tue Apr 25 06:20:14 2000 +0000
+++ b/lib/libc/net/res_send.c   Tue Apr 25 08:51:39 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_send.c,v 1.24 2000/01/23 01:55:17 mycroft Exp $    */
+/*     $NetBSD: res_send.c,v 1.25 2000/04/25 08:51:39 itojun Exp $     */
 
 /*-
  * Copyright (c) 1985, 1989, 1993
@@ -59,7 +59,7 @@
 static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
 static char rcsid[] = "Id: res_send.c,v 8.13 1997/06/01 20:34:37 vixie Exp ";
 #else
-__RCSID("$NetBSD: res_send.c,v 1.24 2000/01/23 01:55:17 mycroft Exp $");
+__RCSID("$NetBSD: res_send.c,v 1.25 2000/04/25 08:51:39 itojun Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -128,7 +128,7 @@
                        fprintf args;\
                        __fp_nquery(query, size, stdout);\
                } else {}
-    static char abuf[INET6_ADDRSTRLEN];
+    static char abuf[NI_MAXHOST];
     static char pbuf[32];
     static void Aerror __P((FILE *, char *, int, struct sockaddr *));
     static void Perror __P((FILE *, char *, int));
@@ -145,7 +145,7 @@
        if (_res.options & RES_DEBUG) {
                getnameinfo(address, (size_t)address->sa_len, abuf,
                    sizeof(abuf), pbuf, sizeof(pbuf),
-                   NI_NUMERICHOST|NI_NUMERICSERV);
+                   NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID);
                fprintf(file, "res_send: %s ([%s].%s): %s\n",
                        string, abuf, pbuf, strerror(error));
        }
@@ -189,6 +189,37 @@
        Rhook = hook;
 }
 
+#ifdef INET6
+static struct sockaddr * get_nsaddr __P((size_t));
+
+/*
+ * pick appropriate nsaddr_list for use.  see res_init() for initialization.
+ */
+static struct sockaddr *
+get_nsaddr(n)
+       size_t n;
+{
+
+       if (!_res.nsaddr_list[n].sin_family) {
+               /*
+                * - _res_ext.nsaddr_list[n] holds an address that is larger
+                *   than struct sockaddr, and
+                * - user code did not update _res.nsaddr_list[n].
+                */
+               return (struct sockaddr *)&_res_ext.nsaddr_list[n];
+       } else {
+               /*
+                * - user code updated _res.nsaddr_list[n], or
+                * - _res.nsaddr_list[n] has the same content as
+                *   _res_ext.nsaddr_list[n].
+                */
+               return (struct sockaddr *)&_res.nsaddr_list[n];
+       }
+}
+#else
+#define get_nsaddr(n)  ((struct sockaddr *)&_res.nsaddr_list[(n)])
+#endif
+
 /* int
  * res_isourserver(ina)
  *     looks up "ina" in _res.ns_addr_list[]
@@ -205,22 +236,21 @@
 #ifdef INET6
        const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
        const struct sockaddr_in6 *srv6;
+#endif
        const struct sockaddr_in *srv;
-#else /* INET6 */
-       struct sockaddr_in ina;
-#endif /* INET6 */
        int ns, ret;
 
        _DIAGASSERT(inp != NULL);
 
-#ifdef INET6
        ret = 0;
        switch (inp->sin_family) {
+#ifdef INET6
        case AF_INET6:
                for (ns = 0; ns < _res.nscount; ns++) {
-                       srv6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[ns];
+                       srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
                        if (srv6->sin6_family == in6p->sin6_family &&
                            srv6->sin6_port == in6p->sin6_port &&
+                           srv6->sin6_scope_id == in6p->sin6_scope_id &&
                            (memcmp(&srv6->sin6_addr, &in6addr_any,
                                    sizeof(struct in6_addr)) == 0 ||
                             memcmp(&srv6->sin6_addr, &in6p->sin6_addr,
@@ -230,9 +260,10 @@
                        }
                }
                break;
+#endif
        case AF_INET:
                for (ns = 0; ns < _res.nscount; ns++) {
-                       srv = (struct sockaddr_in *)&_res_ext.nsaddr_list[ns];
+                       srv = (struct sockaddr_in *)get_nsaddr(ns);
                        if (srv->sin_family == inp->sin_family &&
                            srv->sin_port == inp->sin_port &&
                            (srv->sin_addr.s_addr == INADDR_ANY ||
@@ -243,21 +274,6 @@
                }
                break;
        }
-#else /* INET6 */
-       ina = *inp;
-       ret = 0;
-       for (ns = 0;  ns < _res.nscount;  ns++) {
-               const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
-
-               if (srv->sin_family == ina.sin_family &&
-                   srv->sin_port == ina.sin_port &&
-                   (srv->sin_addr.s_addr == INADDR_ANY ||
-                    srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
-                       ret++;
-                       break;
-               }
-       }
-#endif /* INET6 */
        return (ret);
 }
 
@@ -377,13 +393,8 @@
         */
        for (try = 0; try < _res.retry; try++) {
            for (ns = 0; ns < _res.nscount; ns++) {
-#ifdef INET6
-               struct sockaddr *nsap = (struct sockaddr *)
-                               &_res_ext.nsaddr_list[ns];
-#else /* INET6 */
-               struct sockaddr *nsap = (struct sockaddr *)
-                               &_res.nsaddr_list[ns];
-#endif
+               struct sockaddr *nsap = get_nsaddr(ns);
+
     same_ns:
                if (badns & (1 << ns)) {
                        res_close();



Home | Main Index | Thread Index | Old Index