* resolv: Code updated from BIND-4.9.3P2C3.
authorRoland McGrath <roland@gnu.org>
Thu, 9 May 1996 15:59:18 +0000 (15:59 +0000)
committerRoland McGrath <roland@gnu.org>
Thu, 9 May 1996 15:59:18 +0000 (15:59 +0000)
ChangeLog
resolv/gethnamaddr.c
resolv/getnetbyaddr.c
resolv/getnetent.c
resolv/getnetnamadr.c
resolv/netdb.h
resolv/res_comp.c
resolv/res_debug.c
resolv/res_send.c
resolv/resolv.h

index f72444a..c4233e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 Thu May  9 09:17:46 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
+       * resolv: Code updated from BIND-4.9.3P2C3.
+
        * Rules (static-only-routines rule): Use dummy.o, not dummy.so.
 
 Wed May  8 20:04:29 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
index 41be4fc..6872be0 100644 (file)
@@ -158,10 +158,21 @@ getanswer(answer, anslen, qname, qclass, qtype)
        int toobig = 0;
        char tbuf[MAXDNAME+1];
        const char *tname;
+       int (*name_ok) __P((const char *));
 
        tname = qname;
        host.h_name = NULL;
        eom = answer->buf + anslen;
+       switch (qtype) {
+       case T_A:
+               name_ok = res_hnok;
+               break;
+       case T_PTR:
+               name_ok = dn_isvalid;
+               break;
+       default:
+               abort();
+       }
        /*
         * find first satisfactory answer
         */
@@ -175,7 +186,8 @@ getanswer(answer, anslen, qname, qclass, qtype)
                h_errno = NO_RECOVERY;
                return (NULL);
        }
-       if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
+       n = dn_expand(answer->buf, eom, cp, bp, buflen);
+       if ((n < 0) || !(*name_ok)(bp)) {
                h_errno = NO_RECOVERY;
                return (NULL);
        }
@@ -204,7 +216,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
        had_error = 0;
        while (ancount-- > 0 && cp < eom && !had_error) {
                n = dn_expand(answer->buf, eom, cp, bp, buflen);
-               if (n < 0) {
+               if ((n < 0) || !(*name_ok)(bp)) {
                        had_error++;
                        continue;
                }
@@ -224,7 +236,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
                        if (ap >= &host_aliases[MAXALIASES-1])
                                continue;
                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
-                       if (n < 0) {
+                       if ((n < 0) || !(*name_ok)(tbuf)) {
                                had_error++;
                                continue;
                        }
@@ -254,7 +266,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
                }
                if (qtype == T_PTR && type == T_CNAME) {
                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
-                       if (n < 0) {
+                       if ((n < 0) || !res_hnok(tbuf)) {
                                had_error++;
                                continue;
                        }
@@ -288,7 +300,7 @@ getanswer(answer, anslen, qname, qclass, qtype)
                                continue;       /* XXX - had_error++ ? */
                        }
                        n = dn_expand(answer->buf, eom, cp, bp, buflen);
-                       if (n < 0) {
+                       if ((n < 0) || !res_hnok(bp)) {
                                had_error++;
                                break;
                        }
@@ -517,7 +529,7 @@ gethostbyaddr(addr, len, type)
                h_errno = NETDB_INTERNAL;
                return (NULL);
        }
-       if (type != AF_INET) {
+       if (type != AF_INET || len != INADDRSZ) {
                errno = EAFNOSUPPORT;
                h_errno = NETDB_INTERNAL;
                return (NULL);
index 3bc01ad..32513cc 100644 (file)
@@ -42,7 +42,7 @@ extern int _net_stayopen;
 
 struct netent *
 _getnetbyaddr(net, type)
-       register long net;
+       register unsigned long net;
        register int type;
 {
        register struct netent *p;
index fb47c30..7ec5607 100644 (file)
@@ -143,18 +143,19 @@ again:
        net.n_net = inet_network(cp);
        net.n_addrtype = AF_INET;
        q = net.n_aliases = net_aliases;
-       if (p != NULL) 
+       if (p != NULL) {
                cp = p;
-       while (cp && *cp) {
-               if (*cp == ' ' || *cp == '\t') {
-                       cp++;
-                       continue;
+               while (cp && *cp) {
+                       if (*cp == ' ' || *cp == '\t') {
+                               cp++;
+                               continue;
+                       }
+                       if (q < &net_aliases[MAXALIASES - 1])
+                               *q++ = cp;
+                       cp = strpbrk(cp, " \t");
+                       if (cp != NULL)
+                               *cp++ = '\0';
                }
-               if (q < &net_aliases[MAXALIASES - 1])
-                       *q++ = cp;
-               cp = strpbrk(cp, " \t");
-               if (cp != NULL)
-                       *cp++ = '\0';
        }
        *q = NULL;
        return (&net);
index b2c9118..fad2b8c 100644 (file)
@@ -139,7 +139,7 @@ static      char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
        haveanswer = 0;
        while (--ancount >= 0 && cp < eom) {
                n = dn_expand(answer->buf, eom, cp, bp, buflen);
-               if (n < 0)
+               if ((n < 0) || !dn_isvalid(bp))
                        break;
                cp += n;
                ans[0] = '\0';
@@ -150,7 +150,7 @@ static      char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
                GETSHORT(n, cp);
                if (class == C_IN && type == T_PTR) {
                        n = dn_expand(answer->buf, eom, cp, bp, buflen);
-                       if (n < 0) {
+                       if ((n < 0) || !res_hnok(bp)) {
                                cp += n;
                                return (NULL);
                        }
@@ -202,7 +202,7 @@ static      char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
 
 struct netent *
 getnetbyaddr(net, net_type)
-       register long net;
+       register u_long net;
        register int net_type;
 {
        unsigned int netbr[4];
index 822b621..fd06e17 100644 (file)
@@ -135,7 +135,7 @@ struct hostent      *gethostbyaddr __P((const char *, int, int));
 struct hostent *gethostbyname __P((const char *));
 struct hostent *gethostbyname2 __P((const char *, int));
 struct hostent *gethostent __P((void));
-struct netent  *getnetbyaddr __P((long, int)); /* u_long? */
+struct netent  *getnetbyaddr __P((unsigned long, int));
 struct netent  *getnetbyname __P((const char *));
 struct netent  *getnetent __P((void));
 struct protoent        *getprotobyname __P((const char *));
index 1342205..f234772 100644 (file)
@@ -148,9 +148,6 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
                }
        }
        *dn = '\0';
-       for (dn = exp_dn; (c = *dn) != '\0'; dn++)
-               if (isascii(c) && isspace(c))
-                       return (-1);
        if (len < 0)
                len = cp - comp_dn;
        return (len);
@@ -340,6 +337,88 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
 }
 
 /*
+ * Verify that a domain name uses an acceptable character set.
+ */
+
+/****
+To: "Lawrence R. Rogers" <lrr@cert.org>
+cc: cert@cert.org, pvm@home.net
+Subject: Re: VU#14542 
+In-reply-to: Your message of "Mon, 19 Feb 1996 17:16:27 PST."
+Date: Tue, 20 Feb 1996 22:37:21 -0800
+From: Paul A Vixie <vixie@wisdom.home.vix.com>
+
+in retrospect,
+
+       hostname = firstlabel ( "." otherlabel )+
+       firstchar = [a-zA-Z0-9_]
+       otherchar = [a-zA-Z0-9_-/]
+       firstlabel = firstchar otherchar*
+       otherlabel = otherchar+
+
+should have been
+
+       hostname = label ( "." label )+
+       firstchar = [a-zA-Z0-9_]
+       otherchar = [a-zA-Z0-9_-]
+       label = firstchar otherchar*
+
+i know of no example of a real host name that needs the looser rule i sent
+earlier.  since i'm only trying to bend the spec to fit actual known uses,
+i should not have widened the rules as far as i did earlier.
+****/
+
+#define firstchar(c) ((isascii(c) && isalnum(c)) || (c) == '_')
+#define otherchar(c) (firstchar(c) || (c) == '-')
+#define        wildlabel(firstlabel, ch, nch) \
+       ((firstlabel) && (ch) == '*' && ((nch) == '.' || (nch) == '\0'))
+
+int
+res_hnok(dn)
+       const char *dn;
+{
+       int ppch = '\0', pch = '.', ch = *dn++, firstlabel = 1;
+
+       while (ch != '\0') {
+               int nch = *dn++;
+
+               if (ch == '.' || (ch == '\\' && nch == '.')) {
+                       NULL;
+               } else if (pch == '.' && ppch != '\\') {
+                       if (!firstchar(ch) && !wildlabel(firstlabel, ch, nch))
+                               return (0);
+               } else {
+                       if (!otherchar(ch))
+                               return (0);
+               }
+               ppch = pch, pch = ch, ch = nch;
+               firstlabel = 0;
+       }
+       return (1);
+}
+
+/*
+ * This function is quite liberal, since RFC 1034's character sets are only
+ * recommendations.
+ *
+ * Note that some char's are signed, so we have to cast to unsigned.
+ */
+int
+dn_isvalid(dn)
+       const char *dn;
+{
+       unsigned char *t = (unsigned char *)dn;
+       int ch;
+
+       while ((ch = *t++) != '\0')
+               if (ch <= 0x1f || ch >= 0x7f) {
+                       /* Unprintable in ASCII. */
+                       return (0);
+               }
+       return (1);
+}
+
+/*
  * Routines to insert/extract short/long's.
  */
 
index b3dfcdf..85ec628 100644 (file)
@@ -502,16 +502,28 @@ __p_rr(cp, msg, file)
 
        case T_HINFO:
        case T_ISDN:
+               (void) fputs("\t\"", file);
                cp2 = cp + dlen;
-               if (n = *cp++) {
-                       fprintf(file, "\t%.*s", n, cp);
-                       cp += n;
+               if ((n = (unsigned char) *cp++) != 0) {
+                       for (c = n; c > 0 && cp < cp2; c--) {
+                               if (strchr("\n\"\\", *cp))
+                                       (void) putc('\\', file);
+                               (void) putc(*cp++, file);
+                       }
+                       putc('"', file);
                }
-               if ((cp < cp2) && (n = *cp++)) {
-                       fprintf(file, "\t%.*s", n, cp);
-                       cp += n;
-               } else if (type == T_HINFO)
+               if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
+                       (void) fputs ("\t\"", file);
+                       for (c = n; c > 0 && cp < cp2; c--) {
+                               if (strchr("\n\"\\", *cp))
+                                       (void) putc('\\', file);
+                               (void) putc(*cp++, file);
+                       }
+                       putc('"', file);
+               } else if (type == T_HINFO) {
+                       (void) fputs("\"?\"", file);
                        fprintf(file, "\n;; *** Warning *** OS-type missing");
+               }
                break;
 
        case T_SOA:
@@ -563,12 +575,11 @@ __p_rr(cp, msg, file)
                cp2 = cp1 + dlen;
                while (cp < cp2) {
                        if (n = (unsigned char) *cp++) {
-                               for (c = n; c > 0 && cp < cp2; c--)
-                                       if ((*cp == '\n') || (*cp == '"')) {
-                                           (void) putc('\\', file);
-                                           (void) putc(*cp++, file);
-                                       } else
-                                           (void) putc(*cp++, file);
+                               for (c = n; c > 0 && cp < cp2; c--) {
+                                       if (strchr("\n\"\\", *cp))
+                                               (void) putc('\\', file);
+                                       (void) putc(*cp++, file);
+                               }
                        }
                }
                putc('"', file);
index 5a10faa..d2c97d0 100644 (file)
@@ -409,6 +409,7 @@ res_send(buf, buflen, ans, anssiz)
                        /*
                         * Receive length & response
                         */
+read_len:
                        cp = ans;
                        len = INT16SZ;
                        while ((n = read(s, (char *)cp, (int)len)) > 0) {
@@ -477,6 +478,20 @@ res_send(buf, buflen, ans, anssiz)
                                                break;
                                }
                        }
+                       /*
+                        * The calling applicating has bailed out of
+                        * a previous call and failed to arrange to have
+                        * the circuit closed or the server has got
+                        * itself confused. Anyway drop the packet and
+                        * wait for the correct one.
+                        */
+                       if (hp->id != anhp->id) {
+                               DprintQ((_res.options & RES_DEBUG) ||
+                                       (_res.pfcode & RES_PRF_REPLY),
+                                       (stdout, ";; old answer (unexpected):\n"),
+                                       ans, (resplen>anssiz)?anssiz:resplen);
+                               goto read_len;
+                       }
                } else {
                        /*
                         * Use datagrams.
@@ -593,6 +608,8 @@ res_send(buf, buflen, ans, anssiz)
                        n = select(s+1, &dsmask, (fd_set *)NULL,
                                   (fd_set *)NULL, &timeout);
                        if (n < 0) {
+                               if (errno == EINTR)
+                                       goto wait;
                                Perror(stderr, "select", errno);
                                _res_close();
                                goto next_ns;
@@ -626,7 +643,7 @@ res_send(buf, buflen, ans, anssiz)
                                DprintQ((_res.options & RES_DEBUG) ||
                                        (_res.pfcode & RES_PRF_REPLY),
                                        (stdout, ";; old answer:\n"),
-                                       ans, resplen);
+                                       ans, (resplen>anssiz)?anssiz:resplen);
                                goto wait;
                        }
 #if CHECK_SRVR_ADDR
@@ -640,7 +657,7 @@ res_send(buf, buflen, ans, anssiz)
                                DprintQ((_res.options & RES_DEBUG) ||
                                        (_res.pfcode & RES_PRF_REPLY),
                                        (stdout, ";; not our server:\n"),
-                                       ans, resplen);
+                                       ans, (resplen>anssiz)?anssiz:resplen);
                                goto wait;
                        }
 #endif
@@ -655,7 +672,7 @@ res_send(buf, buflen, ans, anssiz)
                                DprintQ((_res.options & RES_DEBUG) ||
                                        (_res.pfcode & RES_PRF_REPLY),
                                        (stdout, ";; wrong query name:\n"),
-                                       ans, resplen);
+                                       ans, (resplen>anssiz)?anssiz:resplen);
                                goto wait;
                        }
                        if (anhp->rcode == SERVFAIL ||
@@ -663,7 +680,7 @@ res_send(buf, buflen, ans, anssiz)
                            anhp->rcode == REFUSED) {
                                DprintQ(_res.options & RES_DEBUG,
                                        (stdout, "server rejected query:\n"),
-                                       ans, resplen);
+                                       ans, (resplen>anssiz)?anssiz:resplen);
                                badns |= (1 << ns);
                                _res_close();
                                /* don't retry if called from dig */
@@ -689,7 +706,7 @@ res_send(buf, buflen, ans, anssiz)
                DprintQ((_res.options & RES_DEBUG) ||
                        (_res.pfcode & RES_PRF_REPLY),
                        (stdout, ""),
-                       ans, resplen);
+                       ans, (resplen>anssiz)?anssiz:resplen);
                /*
                 * If using virtual circuits, we assume that the first server
                 * is preferred over the rest (i.e. it is on the local
index fb3de28..1a4a0de 100644 (file)
@@ -78,7 +78,7 @@
  * is new enough to contain a certain feature.
  */
 
-#define        __RES   19951031
+#define        __RES   19960229
 
 /*
  * Resolver configuration file.
@@ -184,6 +184,8 @@ typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns,
 extern struct __res_state _res;
 
 /* Private routines shared between libc/net, named, nslookup and others. */
+#define        res_hnok        __res_hnok
+#define        dn_isvalid      __dn_isvalid
 #define        dn_skipname     __dn_skipname
 #define        fp_query        __fp_query
 #define        fp_nquery       __fp_nquery
@@ -203,6 +205,8 @@ extern struct __res_state _res;
 #define        res_nameinquery __res_nameinquery
 #define        res_queriesmatch __res_queriesmatch
 __BEGIN_DECLS
+int     __res_hnok __P((const char *));
+int     __dn_isvalid __P((const char *));
 int     __dn_skipname __P((const u_char *, const u_char *));
 void    __fp_resstat __P((struct __res_state *, FILE *));
 void    __fp_query __P((const u_char *, FILE *));