home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / named / ns_resp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-24  |  40.0 KB  |  1,704 lines

  1. /*
  2.  * Copyright (c) 1986, 1988, 1990 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)ns_resp.c    4.65 (Berkeley) 3/3/91";
  36. #endif /* not lint */
  37.  
  38. #include <sys/param.h>
  39. #include <sys/time.h>
  40. #include <sys/socket.h>
  41. #include <sys/file.h>
  42. #include <netinet/in.h>
  43. #include <syslog.h>
  44. #include <arpa/nameser.h>
  45. #include <resolv.h>
  46. #include <stdio.h>
  47. #include "ns.h"
  48. #include "db.h"
  49.  
  50. extern    int    debug;
  51. extern    FILE    *ddt;
  52. extern    int errno;
  53. extern    u_char *dnptrs[];
  54. extern    time_t retrytime();
  55. extern    struct    fwdinfo *fwdtab;
  56. extern    struct    sockaddr_in from_addr;    /* Source addr of last packet */
  57. extern    int needs_prime_cache;
  58. extern    int priming;
  59.  
  60. struct qinfo *sysquery();
  61.  
  62. ns_resp(msg, msglen)
  63.     u_char *msg;
  64.     int msglen;
  65. {
  66.     register struct qinfo *qp;
  67.     register HEADER *hp;
  68.     register struct qserv *qs;
  69.     register struct databuf *ns, *ns2;
  70.     register u_char *cp;
  71.     struct    databuf *nsp[NSMAX], **nspp;
  72.     int i, c, n, ancount, aucount, nscount, arcount;
  73.     int type, class, dbflags;
  74.     int cname = 0; /* flag for processing cname response */
  75.     int count, founddata, foundname;
  76.     int buflen;
  77.     int newmsglen;
  78.     char name[MAXDNAME], *dname;
  79.     char *fname;
  80.     u_char newmsg[BUFSIZ];
  81.     u_char **dpp, *tp;
  82.     time_t rtrip;
  83.  
  84.     struct hashbuf *htp;
  85.     struct namebuf *np;
  86.     struct netinfo *lp;
  87.     extern struct netinfo *local();
  88.     extern int nsid;
  89.     extern int addcount;
  90.     struct fwdinfo *fwd;
  91.  
  92. #ifdef STATS
  93.     stats[S_RESPONSES].cnt++;
  94. #endif
  95.     hp = (HEADER *) msg;
  96.     if ((qp = qfindid(hp->id)) == NULL ) {
  97. #ifdef DEBUG
  98.         if (debug > 1)
  99.             fprintf(ddt,"DUP? dropped (id %d)\n", ntohs(hp->id));
  100. #endif
  101. #ifdef STATS
  102.         stats[S_DUPRESP].cnt++;
  103. #endif
  104.         return;
  105.     }
  106.  
  107. #ifdef DEBUG
  108.     if (debug >= 2)
  109.         fprintf(ddt,"%s response nsid=%d id=%d\n",
  110.             qp->q_system ? "SYSTEM" : "USER",
  111.             ntohs(qp->q_nsid), ntohs(qp->q_id));
  112. #endif
  113.  
  114.     /*
  115.      *  Here we handle bad responses from servers.
  116.      *  Several possibilities come to mind:
  117.      *    The server is sick and returns SERVFAIL
  118.      *    The server returns some garbage opcode (its sick)
  119.      *    The server can't understand our query and return FORMERR
  120.      *  In all these cases, we simply drop the packet and force
  121.      *  a retry.  This will make him look bad due to unresponsiveness.
  122.      *  Be sure not to include authoritative NXDOMAIN
  123.      */
  124.     if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN)
  125.         || (hp->rcode == NXDOMAIN && !hp->aa)
  126.         || hp->opcode != QUERY) {
  127. #ifdef DEBUG
  128.         if (debug >= 2)
  129.             fprintf(ddt,"resp: error (ret %d, op %d), dropped\n",
  130.                 hp->rcode, hp->opcode);
  131. #endif
  132. #ifdef STATS
  133.         stats[S_BADRESPONSES].cnt++;
  134. #endif
  135.         return;
  136.     }
  137.  
  138. #ifdef ALLOW_UPDATES
  139.     if ( (hp->rcode == NOERROR) &&
  140.          (hp->opcode == UPDATEA || hp->opcode == UPDATED ||
  141.           hp->opcode == UPDATEDA || hp->opcode == UPDATEM ||
  142.           hp->opcode == UPDATEMA) ) {
  143.         /*
  144.          * Update the secondary's copy, now that the primary
  145.          * successfully completed the update.  Zone doesn't matter
  146.          * for dyn. update -- doupdate calls findzone to find it
  147.          */
  148.         doupdate(qp->q_msg, qp->q_msglen, qp->q_msg + sizeof(HEADER),
  149.              0, (struct databuf *)0, 0);
  150. #ifdef DEBUG
  151.         if (debug >= 3)
  152.             fprintf(ddt,"resp: leaving, UPDATE*\n");
  153. #endif
  154.         /* return code filled in by doupdate */
  155.         goto return_msg;
  156.     }
  157. #endif ALLOW_UPDATES
  158.  
  159.     /*
  160.      * Determine if the response came from a forwarder.  Packets from
  161.      * anyplace not listed as a forwarder or as a server to whom we
  162.      * might have forwarded the query will be dropped.
  163.      */
  164.     for (fwd = fwdtab; fwd != (struct fwdinfo *)NULL; fwd = fwd->next)
  165.         if (bcmp((char *)&fwd->fwdaddr.sin_addr, &from_addr.sin_addr,
  166.             sizeof(struct in_addr)) == 0)
  167.             break;
  168.     /*
  169.      * If we were using nameservers, find the qinfo pointer and update
  170.      * the rtt and fact that we have called on this server before.
  171.      */
  172.     if (fwd == (struct fwdinfo *)NULL) {
  173.         struct timeval *stp;
  174.  
  175.         for (n = 0, qs = qp->q_addr; n < qp->q_naddr; n++, qs++)
  176.             if (bcmp((char *)&qs->ns_addr.sin_addr,
  177.                 &from_addr.sin_addr, sizeof(struct in_addr)) == 0)
  178.                 break;
  179.         if (n >= qp->q_naddr) {
  180. #ifdef DEBUG
  181.             if (debug)
  182.                 fprintf(ddt, "Response from unexpected source %s\n",
  183.                 inet_ntoa(from_addr.sin_addr));
  184. #endif DEBUG
  185. #ifdef STATS
  186.             stats[S_MARTIANS].cnt++;
  187. #endif
  188.             /* 
  189.              * We don't know who this response came from so it
  190.              * gets dropped on the floor.
  191.              */
  192.             return;
  193.         }
  194.         stp = &qs->stime;
  195.  
  196.         /* Handle response from different (untried) interface */
  197.         if (stp->tv_sec == 0) {
  198.             ns = qs->ns;
  199.             while (qs > qp->q_addr &&
  200.                 (qs->stime.tv_sec == 0 || qs->ns != ns))
  201.                 qs--;
  202.             *stp = qs->stime;
  203. #ifdef DEBUG
  204.             if (debug)
  205.                 fprintf(ddt,
  206.                 "Response from unused address %s, assuming %s\n",
  207.                 inet_ntoa(from_addr.sin_addr),
  208.                 inet_ntoa(qs->ns_addr.sin_addr));
  209. #endif DEBUG
  210.         }
  211.  
  212.         /* compute query round trip time */
  213.         rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 +
  214.             (tt.tv_usec - stp->tv_usec) / 1000);
  215.         
  216. #ifdef DEBUG
  217.         if (debug > 2)
  218.             fprintf(ddt,"stime %d/%d  now %d/%d rtt %d\n",
  219.                 stp->tv_sec, stp->tv_usec,
  220.                 tt.tv_sec, tt.tv_usec, rtrip);
  221. #endif
  222.         /* prevent floating point overflow, limit to 1000 sec */
  223.         if (rtrip > 1000000)
  224.                 rtrip = 1000000;
  225.         ns = qs->nsdata;
  226.         /*
  227.          * Don't update nstime if this doesn't look
  228.          * like an address databuf now.            XXX
  229.          */
  230.         if (ns->d_type == T_A && ns->d_class == qs->ns->d_class) {
  231.             if (ns->d_nstime == 0)
  232.                 ns->d_nstime = (u_long)rtrip;
  233.             else
  234.                 ns->d_nstime = ns->d_nstime * ALPHA +
  235.                     (1-ALPHA) * (u_long)rtrip;
  236.             /* prevent floating point overflow, limit to 1000 sec */
  237.             if (ns->d_nstime > 1000000)
  238.                 ns->d_nstime = 1000000;
  239.         }
  240.  
  241.         /*
  242.          * Record the source so that we do not use this NS again.
  243.          */
  244.         if(qp->q_nusedns < NSMAX) {
  245.             qp->q_usedns[qp->q_nusedns++] = qs->ns;
  246. #ifdef DEBUG
  247.             if(debug > 1)
  248.                 fprintf(ddt, "NS #%d addr %s used, rtt %d\n",
  249.                 n, inet_ntoa(qs->ns_addr.sin_addr),
  250.                 ns->d_nstime);
  251. #endif DEBUG
  252.         }
  253.  
  254.         /*
  255.          * Penalize those who had earlier chances but failed
  256.          * by multiplying round-trip times by BETA (>1).
  257.          * Improve nstime for unused addresses by applying GAMMA.
  258.          * The GAMMA factor makes unused entries slowly
  259.          * improve, so they eventually get tried again.
  260.          * GAMMA should be slightly less than 1.
  261.          * Watch out for records that may have timed out
  262.          * and are no longer the correct type.            XXX
  263.          */
  264.         
  265.         for (n = 0, qs = qp->q_addr; n < qp->q_naddr; n++, qs++) {
  266.             ns2 = qs->nsdata;
  267.             if (ns2 == ns)
  268.                 continue;
  269.             if (ns2->d_type != T_A ||
  270.                 ns2->d_class != qs->ns->d_class)    /* XXX */
  271.                 continue;
  272.             if (qs->stime.tv_sec) {
  273.                 if (ns2->d_nstime == 0)
  274.                 ns2->d_nstime = rtrip * BETA;
  275.                 else
  276.                 ns2->d_nstime =
  277.                     ns2->d_nstime * BETA + (1-ALPHA) * rtrip;
  278.                 if (ns2->d_nstime > 1000000)
  279.                 ns2->d_nstime = 1000000;
  280.             } else
  281.                 ns2->d_nstime = ns2->d_nstime * GAMMA;
  282. #ifdef DEBUG
  283.             if(debug > 1)
  284.                 fprintf(ddt, "NS #%d %s rtt now %d\n", n,
  285.                 inet_ntoa(qs->ns_addr.sin_addr),
  286.                 ns2->d_nstime);
  287. #endif DEBUG
  288.         }
  289.     }
  290.  
  291.     /*
  292.      * Skip query section
  293.      */
  294.     addcount = 0;
  295.     cp = msg + sizeof(HEADER);
  296.     dpp = dnptrs;
  297.     *dpp++ = msg;
  298.     if ((*cp & INDIR_MASK) == 0)
  299.         *dpp++ = cp;
  300.     *dpp = NULL;
  301.     if (hp->qdcount) {
  302.         n = dn_skipname(cp, msg + msglen);
  303.             if (n <= 0)
  304.             goto formerr;
  305.         cp += n;
  306.         GETSHORT(type, cp);
  307.         GETSHORT(class, cp);
  308.         if (cp - msg > msglen)
  309.             goto formerr;
  310.     }
  311.  
  312.     /*
  313.      * Save answers, authority, and additional records for future use.
  314.      */
  315.     ancount = ntohs(hp->ancount);
  316.     aucount = ntohs(hp->nscount);
  317.     arcount = ntohs(hp->arcount);
  318.     nscount = 0;
  319.     tp = cp;
  320. #ifdef DEBUG
  321.     if (debug >= 3)
  322.         fprintf(ddt,"resp: ancount %d, aucount %d, arcount %d\n",
  323.             ancount, aucount, arcount);
  324. #endif
  325.  
  326.     /*
  327.      *  If there's an answer, check if it's a CNAME response;
  328.      *  if no answer but aucount > 0, see if there is an NS
  329.      *  or just an SOA.  (NOTE: ancount might be 1 with a CNAME,
  330.      *  and NS records may still be in the authority section;
  331.      *  we don't bother counting them, as we only use nscount
  332.      *  if ancount == 0.)
  333.      */
  334.     if (ancount == 1 || (ancount == 0 && aucount > 0)) {
  335.         c = aucount;
  336.         do {
  337.             if (tp - msg >= msglen)
  338.                 goto formerr;
  339.             n = dn_skipname(tp, msg + msglen);
  340.             if (n <= 0)
  341.                 goto formerr;
  342.             tp += n;          /* name */
  343.             GETSHORT(i, tp);    /* type */
  344.             tp += sizeof(u_short);    /* class */
  345.             tp += sizeof(u_long);    /* ttl */
  346.             GETSHORT(count, tp);     /* dlen */
  347.             if (tp - msg > msglen - count)
  348.                 goto formerr;
  349.             tp += count;
  350.             if (ancount && i == T_CNAME) {
  351.                 cname++;
  352. #ifdef DEBUG
  353.                 if (debug)
  354.                     fprintf(ddt,"CNAME - needs more processing\n");
  355. #endif
  356.                 if (!qp->q_cmsglen) {
  357.                     qp->q_cmsg = qp->q_msg;
  358.                     qp->q_cmsglen = qp->q_msglen;
  359.                     qp->q_msg = NULL;
  360.                     qp->q_msglen = 0;
  361.                 }
  362.             }
  363.             /*
  364.              * See if authority record is a nameserver.
  365.              */
  366.             if (ancount == 0 && i == T_NS)
  367.                 nscount++;
  368.         } while (--c > 0);
  369.         tp = cp;
  370.     }
  371.  
  372.     /*
  373.      * Add the info received in the response to the Data Base
  374.      */
  375.     c = ancount + aucount + arcount;
  376. #ifdef notdef
  377.     /*
  378.      * If the request was for a CNAME that doesn't exist,
  379.      * but the name is valid, fetch any other data for the name.
  380.      * DON'T do this now, as it will requery if data are already
  381.      * in the cache (maybe later with negative caching).
  382.      */
  383.     if (hp->qdcount && type == T_CNAME && c == 0 && hp->rcode == NOERROR &&
  384.        !qp->q_system) {
  385. #ifdef DEBUG
  386.         if (debug >= 3)
  387.             fprintf(ddt,"resp: leaving, no CNAME\n");
  388. #endif
  389.         /* Cause us to put it in the cache later */
  390.         prime(class, T_ANY, qp);
  391.  
  392.         /* Nothing to store, just give user the answer */
  393.         goto return_msg;
  394.     }
  395. #endif /* notdef */
  396.  
  397.     nspp = nsp;
  398.     if (qp->q_system)
  399.         dbflags = DB_NOTAUTH | DB_NODATA;
  400.     else
  401.         dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS;
  402.     for (i = 0; i < c; i++) {
  403.         struct databuf *ns3;
  404.  
  405.         if (cp >= msg + msglen)
  406.             goto formerr;
  407.         ns3 = 0;
  408.         if ((n = doupdate(msg, msglen, cp, 0, &ns3, dbflags)) < 0) {
  409. #ifdef DEBUG
  410.             if (debug)
  411.                 fprintf(ddt,"resp: leaving, doupdate failed\n");
  412. #endif
  413.             /* return code filled in by doupdate */
  414.             goto return_msg;
  415.         }
  416.         /*
  417.          * Remember nameservers from the authority section
  418.          * for referrals.
  419.          * (This is usually overwritten by findns below(?). XXX
  420.          */
  421.         if (ns3 && i >= ancount && i < ancount + aucount &&
  422.             nspp < &nsp[NSMAX-1])
  423.             *nspp++ = ns3;
  424.         cp += n;
  425.     }
  426.  
  427.     if (qp->q_system && ancount) {
  428.         if (qp->q_system == PRIMING_CACHE)
  429.             check_root();
  430. #ifdef DEBUG
  431.         if (debug > 2)
  432.             fprintf(ddt,"resp: leaving, SYSQUERY ancount %d\n", ancount);
  433. #endif
  434.         qremove(qp);
  435.         return;
  436.     }
  437.  
  438.     if (cp > msg + msglen)
  439.         goto formerr;
  440.  
  441.     /*
  442.      *  If there are addresses and this is a local query,
  443.      *  sort them appropriately for the local context.
  444.      */
  445.     if (ancount > 1 && (lp = local(&qp->q_from)) != NULL) 
  446.         sort_response(tp, ancount, lp, msg + msglen);
  447.  
  448.     /*
  449.      * An answer to a T_ANY query or a successful answer to a
  450.      * regular query with no indirection, then just return answer.
  451.      */
  452.     if ((hp->qdcount && type == T_ANY && ancount) ||
  453.         (!cname && !qp->q_cmsglen && ancount)) {
  454. #ifdef DEBUG
  455.         if (debug >= 3)
  456.             fprintf(ddt,"resp: got as much answer as there is\n");
  457. #endif
  458.         goto return_msg;
  459.     }
  460.  
  461.     /*
  462.      * Eventually we will want to cache this negative answer.
  463.      */
  464.     if (ancount == 0 && nscount == 0 &&
  465.         (hp->aa || fwd || class == C_ANY)) {
  466.         /* We have an authoritative NO */
  467. #ifdef DEBUG
  468.         if (debug >= 3)
  469.             fprintf(ddt,"resp: leaving auth NO\n");
  470. #endif
  471.         if (qp->q_cmsglen) {
  472.             msg = (u_char *)qp->q_cmsg;
  473.             msglen = qp->q_cmsglen;
  474.             hp = (HEADER *)msg;
  475.         }
  476.         goto return_msg;
  477.     }
  478.  
  479.     /*
  480.      * All messages in here need further processing.  i.e. they
  481.      * are either CNAMEs or we got referred again.
  482.      */
  483.     count = 0;
  484.     founddata = 0;
  485.     foundname = 0;
  486.     dname = name;
  487.     if (!cname && qp->q_cmsglen && ancount) {
  488. #ifdef DEBUG
  489.         if (debug)
  490.             fprintf(ddt,"Cname second pass\n");
  491. #endif
  492.         newmsglen = qp->q_cmsglen;
  493.         bcopy(qp->q_cmsg, newmsg, newmsglen);
  494.     } else {
  495.         newmsglen = msglen;
  496.         bcopy(msg, newmsg, newmsglen);
  497.     }
  498.     hp = (HEADER *) newmsg;
  499.     hp->ancount = 0;
  500.     hp->nscount = 0;
  501.     hp->arcount = 0;
  502.     dnptrs[0] = newmsg;
  503.     dnptrs[1] = NULL;
  504.     cp = newmsg + sizeof(HEADER);
  505.     if (cname)
  506.         cp += dn_skipname(cp, newmsg + newmsglen) + QFIXEDSZ;
  507.     if ((n = dn_expand(newmsg, newmsg + newmsglen,
  508.         cp, (u_char *)dname, sizeof(name))) < 0) {
  509. #ifdef DEBUG
  510.         if (debug)
  511.             fprintf(ddt,"dn_expand failed\n" );
  512. #endif
  513.         goto servfail;
  514.     }
  515.     if (!cname)
  516.         cp += n + QFIXEDSZ;
  517.     buflen = sizeof(newmsg) - (cp - newmsg);
  518.  
  519. try_again:
  520. #ifdef DEBUG
  521.     if (debug)
  522.         fprintf(ddt,"resp: nlookup(%s) type=%d\n",dname, type);
  523. #endif
  524.     fname = "";
  525.     htp = hashtab;        /* lookup relative to root */
  526.     np = nlookup(dname, &htp, &fname, 0);
  527. #ifdef DEBUG
  528.     if (debug)
  529.         fprintf(ddt,"resp: %s '%s' as '%s' (cname=%d)\n",
  530.             np == NULL ? "missed" : "found", dname, fname, cname);
  531. #endif
  532.     if (np == NULL || fname != dname)
  533.         goto fetch_ns;
  534.  
  535.     foundname++;
  536.     count = cp - newmsg;
  537.     n = finddata(np, class, type, hp, &dname, &buflen, &count);
  538.     if (n == 0)
  539.         goto fetch_ns;        /* NO data available */
  540.     cp += n;
  541.     buflen -= n;
  542.     hp->ancount += count;
  543.     if (fname != dname && type != T_CNAME && type != T_ANY) {
  544.         cname++;
  545.         goto try_again;
  546.     }
  547.     founddata = 1;
  548.  
  549. #ifdef DEBUG
  550.     if (debug >= 3) {
  551.         fprintf(ddt,"resp: foundname = %d count = %d ", foundname, count);
  552.         fprintf(ddt,"founddata = %d cname = %d\n", founddata, cname);
  553.     }
  554. #endif
  555.  
  556. fetch_ns:
  557.     hp->ancount = htons(hp->ancount);
  558.     /*
  559.       * Look for name servers to refer to and fill in the authority
  560.       * section or record the address for forwarding the query
  561.       * (recursion desired).
  562.       */
  563.     switch (findns(&np, class, nsp, &count)) {
  564.     case NXDOMAIN:        /* shouldn't happen */
  565. #ifdef DEBUG
  566.         if (debug >= 3)
  567.             fprintf(ddt,"req: leaving (%s, rcode %d)\n",
  568.                 dname, hp->rcode);
  569. #endif
  570.         if (!foundname)
  571.             hp->rcode = NXDOMAIN;
  572.         if (class != C_ANY) {
  573.             hp->aa = 1;
  574.             /*
  575.              * should return SOA if founddata == 0,
  576.              * but old named's are confused by an SOA
  577.              * in the auth. section if there's no error.
  578.              */
  579.             if (foundname == 0 && np) {
  580.                 n = doaddauth(hp, cp, buflen, np, nsp[0]);
  581.                 cp += n;
  582.                 buflen -= n;
  583.             }
  584.         }
  585.         goto return_newmsg;
  586.  
  587.     case SERVFAIL:
  588.         goto servfail;
  589.     }
  590.  
  591.     if (founddata) {
  592.         hp = (HEADER *)newmsg;
  593.         n = add_data(np, nsp, cp, buflen);
  594.         if (n < 0) {
  595.             hp->tc = 1;
  596.             n = (-n);
  597.         }
  598.         cp += n;
  599.         buflen -= n;
  600.         hp->nscount = htons((u_short)count);
  601.         goto return_newmsg;
  602.     }
  603.  
  604.     /*
  605.      *  If we get here, we don't have the answer yet and are about
  606.      *  to iterate to try and get it.  First, infinite loop avoidance.
  607.      */
  608.     if (qp->q_nqueries++ > MAXQUERIES) {
  609. #ifdef DEBUG
  610.         if (debug)
  611.             fprintf(ddt,"resp: MAXQUERIES exceeded (%s, class %d, type %d)\n",
  612.             dname, class, type);
  613. #endif
  614.         syslog(LOG_NOTICE,
  615.                     "MAXQUERIES exceeded, possible data loop in resolving (%s)",
  616.                 dname);
  617.         goto servfail;
  618.     }
  619.  
  620.     /* Reset the query control structure */
  621.     qp->q_naddr = 0;
  622.     qp->q_curaddr = 0;
  623.     qp->q_fwd = fwdtab;
  624.     if (nslookup(nsp, qp) == 0) {
  625. #ifdef DEBUG
  626.         if (debug >= 3)
  627.             fprintf(ddt,"resp: no addrs found for NS's\n");
  628. #endif
  629.         goto servfail;
  630.     }
  631.     for (n = 0; n < qp->q_naddr; n++)
  632.         qp->q_addr[n].stime.tv_sec = 0;
  633.     if (!qp->q_fwd)
  634.         qp->q_addr[0].stime = tt;
  635.     if (cname) {
  636.          if (qp->q_cname++ == MAXCNAMES) {
  637. #ifdef DEBUG
  638.             if (debug >= 3)
  639.                 fprintf(ddt,"resp: leaving, MAXCNAMES exceeded\n");
  640. #endif
  641.             goto servfail;
  642.          }
  643. #ifdef DEBUG
  644.          if (debug)
  645.              fprintf(ddt,"q_cname = %d\n",qp->q_cname);
  646.         if (debug >= 3)
  647.                fprintf(ddt,"resp: building recursive query; nslookup\n");
  648. #endif
  649.         if (qp->q_msg)
  650.             (void) free(qp->q_msg);
  651.         if ((qp->q_msg = malloc(BUFSIZ)) == NULL) {
  652. #ifdef DEBUG
  653.             if (debug)
  654.                 fprintf(ddt,"resp: malloc error\n");
  655. #endif
  656.             goto servfail;
  657.         }
  658.         qp->q_msglen = res_mkquery(QUERY, dname, class,
  659.             type, (char *)NULL, 0, NULL, qp->q_msg, BUFSIZ);
  660.         hp = (HEADER *) qp->q_msg;
  661.             hp->rd = 0;
  662.     } else
  663.         hp = (HEADER *)qp->q_msg;
  664.     hp->id = qp->q_nsid = htons((u_short)++nsid);
  665.     if (qp->q_fwd)
  666.         hp->rd = 1;
  667.     unsched(qp);
  668.     schedretry(qp, retrytime(qp));
  669. #ifdef DEBUG
  670.     if (debug)
  671.         fprintf(ddt,"resp: forw -> %s %d (%d) nsid=%d id=%d %dms\n",
  672.             inet_ntoa(Q_NEXTADDR(qp,0)->sin_addr),
  673.             ds, ntohs(Q_NEXTADDR(qp,0)->sin_port),
  674.             ntohs(qp->q_nsid), ntohs(qp->q_id),
  675.             qp->q_addr[0].nsdata->d_nstime);
  676.     if ( debug >= 10)
  677.         fp_query((char *)msg, ddt);
  678. #endif
  679.     if (sendto(ds, qp->q_msg, qp->q_msglen, 0,
  680.         (struct sockaddr *)Q_NEXTADDR(qp,0),
  681.         sizeof(struct sockaddr_in)) < 0) {
  682. #ifdef DEBUG
  683.         if (debug >= 5)
  684.             fprintf(ddt, "sendto error = %d\n", errno);
  685. #endif
  686.     }
  687.     hp->rd = 0;    /* leave set to 0 for dup detection */
  688. #ifdef STATS
  689.     stats[S_OUTPKTS].cnt++;
  690. #endif
  691. #ifdef DEBUG
  692.     if (debug >= 3)
  693.         fprintf(ddt,"resp: Query sent.\n");
  694. #endif
  695.     return;
  696.  
  697. formerr:
  698. #ifdef DEBUG
  699.     if (debug)
  700.         fprintf(ddt,"FORMERR resp() from %s size err %d, msglen %d\n",
  701.         inet_ntoa(from_addr.sin_addr),
  702.         cp-msg, msglen);
  703. #endif
  704.     syslog(LOG_INFO, "Malformed response from %s\n",
  705.         inet_ntoa(from_addr.sin_addr));
  706. #ifdef STATS
  707.     stats[S_RESPFORMERR].cnt++;
  708. #endif
  709.     return;
  710.  
  711. return_msg:
  712. #ifdef STATS
  713.     stats[S_RESPOK].cnt++;
  714. #endif
  715.     /* The "standard" return code */
  716.     hp->qr = 1;
  717.     hp->id = qp->q_id;
  718.     hp->rd = 1;
  719.     hp->ra = 1;
  720.     (void) send_msg(msg, msglen, qp);
  721.     qremove(qp);
  722.     return;
  723.  
  724. return_newmsg:
  725. #ifdef STATS
  726.     stats[S_RESPOK].cnt++;
  727. #endif
  728.     if (addcount) {
  729.         n = doaddinfo(hp, cp, buflen);
  730.         cp += n;
  731.         buflen -= n;
  732.     }
  733.  
  734.     hp->id = qp->q_id;
  735.     hp->rd = 1;
  736.     hp->ra = 1;
  737.     hp->qr = 1;
  738.     (void) send_msg(newmsg, cp - newmsg, qp);
  739.     qremove(qp);
  740.     return;
  741.  
  742. servfail:
  743. #ifdef STATS
  744.     stats[S_RESPFAIL].cnt++;
  745. #endif
  746.     hp = (HEADER *)(cname ? qp->q_cmsg : qp->q_msg);
  747.     hp->rcode = SERVFAIL;
  748.     hp->id = qp->q_id;
  749.     hp->rd = 1;
  750.     hp->ra = 1;
  751.     hp->qr = 1;
  752.     (void) send_msg((char *)hp, (cname ? qp->q_cmsglen : qp->q_msglen), qp);
  753.     qremove(qp);
  754.     return;
  755. }
  756.  
  757. /*
  758.  * Decode the resource record 'rrp' and update the database.
  759.  * If savens is true, record pointer for forwarding queries a second time.
  760.  */
  761. doupdate(msg, msglen, rrp, zone, savens, flags)
  762.     char *msg;
  763.     u_char *rrp;
  764.     struct databuf **savens;
  765.     int  msglen, zone, flags;
  766. {
  767.     register u_char *cp;
  768.     register int n;
  769.     int class, type, dlen, n1;
  770.     u_long ttl;
  771.     struct databuf *dp;
  772.     char dname[MAXDNAME];
  773.     u_char *cp1;
  774.     u_char data[BUFSIZ];
  775.     register HEADER *hp = (HEADER *) msg;
  776. #ifdef ALLOW_UPDATES
  777.     int zonenum;
  778. #endif
  779.  
  780. #ifdef DEBUG
  781.     if (debug > 2)
  782.         fprintf(ddt,"doupdate(zone %d, savens %x, flags %x)\n",
  783.             zone, savens, flags);
  784. #endif
  785.  
  786.     cp = rrp;
  787.     if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen, cp,
  788.         (u_char *)dname, sizeof(dname))) < 0) {
  789.         hp->rcode = FORMERR;
  790.         return (-1);
  791.     }
  792.     cp += n;
  793.     GETSHORT(type, cp);
  794.     GETSHORT(class, cp);
  795.     GETLONG(ttl, cp);
  796.     GETSHORT(dlen, cp);
  797. #ifdef DEBUG
  798.     if (debug > 2)
  799.         fprintf(ddt,"doupdate: dname %s type %d class %d ttl %d\n",
  800.             dname, type, class, ttl);
  801. #endif
  802.     /*
  803.      * Convert the resource record data into the internal
  804.      * database format.
  805.      */
  806.     switch (type) {
  807.     case T_A:
  808.     case T_WKS:
  809.     case T_HINFO:
  810.     case T_UINFO:
  811.     case T_UID:
  812.     case T_GID:
  813.     case T_TXT:
  814. #ifdef ALLOW_T_UNSPEC
  815.     case T_UNSPEC:
  816. #endif ALLOW_T_UNSPEC
  817.         cp1 = cp;
  818.         n = dlen;
  819.         cp += n;
  820.         break;
  821.  
  822.     case T_CNAME:
  823.     case T_MB:
  824.     case T_MG:
  825.     case T_MR:
  826.     case T_NS:
  827.     case T_PTR:
  828.         if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,
  829.             cp, data, sizeof(data))) < 0) {
  830.             hp->rcode = FORMERR;
  831.             return (-1);
  832.         }
  833.         cp += n;
  834.         cp1 = data;
  835.         n = strlen((char *)data) + 1;
  836.         break;
  837.  
  838.     case T_MINFO:
  839.     case T_SOA:
  840.         if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,
  841.             cp, data, sizeof(data))) < 0) {
  842.             hp->rcode = FORMERR;
  843.             return (-1);
  844.         }
  845.         cp += n;
  846.         cp1 = data + (n = strlen((char *)data) + 1);
  847.         n1 = sizeof(data) - n;
  848.         if (type == T_SOA)
  849.             n1 -= 5 * sizeof(u_long);
  850.         if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,
  851.             cp, cp1, n1)) < 0) {
  852.             hp->rcode = FORMERR;
  853.             return (-1);
  854.         }
  855.         cp += n;
  856.         cp1 += strlen((char *)cp1) + 1;
  857.         if (type == T_SOA) {
  858.             bcopy(cp, cp1, n = 5 * sizeof(u_long));
  859.             cp += n;
  860.             cp1 += n;
  861.         }
  862.         n = cp1 - data;
  863.         cp1 = data;
  864.         break;
  865.  
  866.     case T_MX:
  867.         /* grab preference */
  868.         bcopy(cp,data,sizeof(u_short));
  869.         cp1 = data + sizeof(u_short);
  870.         cp += sizeof(u_short);
  871.  
  872.         /* get name */
  873.         if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,
  874.             cp, cp1, sizeof(data) - sizeof(u_short))) < 0)
  875.             return(-1);
  876.         cp += n;
  877.  
  878.         /* compute end of data */
  879.         cp1 += strlen((char *)cp1) + 1;
  880.         /* compute size of data */
  881.         n = cp1 - data;
  882.         cp1 = data;
  883.         break;
  884.  
  885.     default:
  886. #ifdef DEBUG
  887.         if (debug >= 3)
  888.             fprintf(ddt,"unknown type %d\n", type);
  889. #endif
  890.         return ((cp - rrp) + dlen);
  891.     }
  892.     if (n > MAXDATA) {
  893. #ifdef DEBUG
  894.         if (debug)
  895.             fprintf(ddt,
  896.             "update type %d: %d bytes is too much data\n",
  897.             type, n);
  898. #endif
  899.         hp->rcode = NOCHANGE;    /* XXX - FORMERR ??? */
  900.         return(-1);
  901.     }
  902.  
  903. #ifdef ALLOW_UPDATES
  904.     /*
  905.      * If this is a dynamic update request, process it specially; else,
  906.      * execute normal update code.
  907.      */
  908.     switch(hp->opcode) {
  909.  
  910.     /* For UPDATEM and UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA */
  911.     case UPDATEM:
  912.     case UPDATEMA:
  913.  
  914.     /*
  915.      * The named code for UPDATED and UPDATEDA is the same except that for
  916.      * UPDATEDA we we ignore any data that was passed: we just delete all
  917.      * RRs whose name, type, and class matches
  918.      */
  919.     case UPDATED:
  920.     case UPDATEDA:
  921.         if (type == T_SOA) {    /* Not allowed */
  922. #ifdef DEBUG
  923.             if (debug)
  924.                fprintf(ddt, "UDPATE: REFUSED - SOA delete\n");
  925. #endif
  926.             hp->rcode = REFUSED;
  927.             return(-1);
  928.         }
  929.         /*
  930.          * Don't check message length if doing UPDATEM/UPDATEMA,
  931.          * since the whole message wont have been demarshalled until
  932.          * we reach the code for UPDATEA
  933.          */
  934.         if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEDA) ) {
  935.             if (cp != (u_char *)(msg + msglen)) {
  936. #ifdef DEBUG
  937.                 if (debug)
  938.                     fprintf(ddt,"FORMERR UPDATE message length off\n");
  939. #endif
  940.                 hp->rcode = FORMERR;
  941.                 return(-1);
  942.             }
  943.         }
  944.         if ((zonenum = findzone(dname, class)) == 0) { 
  945.             hp->rcode = NXDOMAIN;
  946.             return(-1);
  947.         }
  948.         if (zones[zonenum].z_state & Z_DYNADDONLY) {
  949.             hp->rcode = NXDOMAIN;
  950.             return(-1);
  951.         }
  952.         if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEM) ) {
  953.             /* Make a dp for use in db_update, as old dp */
  954.             dp = savedata(class, type, 0, cp1, n);
  955.             dp->d_zone = zonenum;
  956.             n = db_update(dname, dp, NULL, DB_MEXIST | DB_DELETE,
  957.                       hashtab);
  958.             if (n != OK) {
  959. #ifdef DEBUG
  960.                 if (debug)
  961.                     fprintf(ddt,"UPDATE: db_update failed\n");
  962. #endif DEBUG
  963.                 free( (struct databuf *) dp);
  964.                 hp->rcode = NOCHANGE;
  965.                 return(-1);
  966.             }
  967.         } else {    /* UPDATEDA or UPDATEMA */
  968.             int DeletedOne = 0;
  969.             /* Make a dp for use in db_update, as old dp */
  970.             dp = savedata(class, type, 0, NULL, 0);
  971.             dp->d_zone = zonenum;
  972.             do {    /* Loop and delete all matching RR(s) */
  973.                 n = db_update(dname, dp, NULL, DB_DELETE,
  974.                           hashtab);
  975.                 if (n != OK)
  976.                     break;
  977.                 DeletedOne++;
  978.             } while (1);
  979.             free( (struct databuf *) dp);
  980.             /* Ok for UPDATEMA not to have deleted any RRs */
  981.             if (!DeletedOne && hp->opcode == UPDATEDA) {
  982. #ifdef DEBUG
  983.                 if (debug)
  984.                     fprintf(ddt,"UPDATE: db_update failed\n");
  985. #endif DEBUG
  986.                 hp->rcode = NOCHANGE;
  987.                 return(-1);
  988.             }
  989.         }
  990.         if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEDA) )
  991.             return (cp - rrp);;
  992.         /*
  993.          * Else unmarshal the RR to be added and continue on to
  994.          * UPDATEA code for UPDATEM/UPDATEMA
  995.          */
  996.         if ((n =
  997.            dn_expand(msg, msg+msglen, cp, dname, sizeof(dname))) < 0) {
  998. #ifdef DEBUG
  999.             if (debug)
  1000.                 fprintf(ddt,"FORMERR UPDATE expand name failed\n");
  1001. #endif
  1002.             hp->rcode = FORMERR;
  1003.             return(-1);
  1004.         }
  1005.         cp += n;
  1006.         GETSHORT(type, cp);
  1007.         GETSHORT(class, cp);
  1008.         GETLONG(ttl, cp);
  1009.         GETSHORT(n, cp);
  1010.         cp1 = cp;
  1011. /**** XXX - need bounds checking here ****/
  1012.         cp += n;
  1013.  
  1014.     case UPDATEA:
  1015.         if (n > MAXDATA) {
  1016. #ifdef DEBUG
  1017.             if (debug)
  1018.                 fprintf(ddt,"UPDATE: too much data\n");
  1019. #endif
  1020.             hp->rcode = NOCHANGE;
  1021.             return(-1);
  1022.         }
  1023.         if (cp != (u_char *)(msg + msglen)) {
  1024. #ifdef DEBUG
  1025.             if (debug)
  1026.                 fprintf(ddt,"FORMERR UPDATE message length off\n");
  1027. #endif
  1028.             hp->rcode = FORMERR;
  1029.             return(-1);
  1030.         }
  1031.         if ((zonenum = findzone(dname, class)) == 0) { 
  1032.             hp->rcode = NXDOMAIN;
  1033.             return(-1);
  1034.         }
  1035.         if (zones[zonenum].z_state & Z_DYNADDONLY) {
  1036.             struct hashbuf *htp = hashtab;
  1037.             char *fname;
  1038.             if (nlookup(dname, &htp, &fname, 0) &&
  1039.                 !strcmp(dname, fname)) {
  1040. #ifdef    DEBUG
  1041.                 if (debug)
  1042.                 fprintf(ddt,"refusing add of existing name\n");
  1043. #endif
  1044.                 hp->rcode = REFUSED;
  1045.                 return(-1);
  1046.             }
  1047.         }
  1048.         dp = savedata(class, type, ttl, cp1, n);
  1049.         dp->d_zone = zonenum;
  1050.         if ((n = db_update(dname, NULL, dp, DB_NODATA,
  1051.                    hashtab)) != OK) {
  1052. #ifdef DEBUG
  1053.             if (debug)
  1054.                 fprintf(ddt,"UPDATE: db_update failed\n");
  1055. #endif
  1056.             hp->rcode = NOCHANGE;
  1057.             return (-1);
  1058.         }
  1059.         else
  1060.             return (cp - rrp);
  1061.     }
  1062. #endif ALLOW_UPDATES
  1063.  
  1064.     if (zone == 0)
  1065.         ttl += tt.tv_sec;
  1066.     dp = savedata(class, type, ttl, cp1, n);
  1067.     dp->d_zone = zone;
  1068.     if ((n = db_update(dname, dp, dp, flags, hashtab)) < 0) {
  1069. #ifdef DEBUG
  1070.         if (debug && (n != DATAEXISTS))
  1071.             fprintf(ddt,"update failed (%d)\n", n);
  1072.         else if (debug >= 3)
  1073.             fprintf(ddt,"update failed (DATAEXISTS)\n");
  1074. #endif
  1075.         (void) free((char *)dp);
  1076.     } else if (type == T_NS && savens != NULL)
  1077.         *savens = dp;
  1078.     return (cp - rrp);
  1079. }
  1080.  
  1081. send_msg(msg, msglen, qp)
  1082.     char *msg;
  1083.     int msglen;
  1084.     struct qinfo *qp;
  1085. {
  1086.     extern struct qinfo *qhead;
  1087. #ifdef DEBUG
  1088.     struct qinfo *tqp;
  1089. #endif DEBUG
  1090.  
  1091.     if (qp->q_system)
  1092.         return(1);
  1093. #ifdef DEBUG
  1094.     if (debug) {
  1095.         fprintf(ddt,"send_msg -> %s (%s %d %d) id=%d\n",
  1096.             inet_ntoa(qp->q_from.sin_addr), 
  1097.             qp->q_stream == QSTREAM_NULL ? "UDP" : "TCP",
  1098.             qp->q_stream == QSTREAM_NULL ? qp->q_dfd
  1099.                              : qp->q_stream->s_rfd,
  1100.             ntohs(qp->q_from.sin_port),
  1101.             ntohs(qp->q_id));
  1102.     }
  1103.     if (debug>4)
  1104.         for (tqp = qhead; tqp!=QINFO_NULL; tqp = tqp->q_link) {
  1105.             fprintf(ddt, "qp %x q_id: %d  q_nsid: %d q_msglen: %d ",
  1106.                 tqp, tqp->q_id,tqp->q_nsid,tqp->q_msglen);
  1107.                 fprintf(ddt,"q_naddr: %d q_curaddr: %d\n", tqp->q_naddr,
  1108.             tqp->q_curaddr);
  1109.                 fprintf(ddt,"q_next: %x q_link: %x\n", qp->q_next,
  1110.                 qp->q_link);
  1111.         }
  1112.     if (debug >= 10)
  1113.         fp_query(msg, ddt);
  1114. #endif DEBUG
  1115.     if (qp->q_stream == QSTREAM_NULL) {
  1116.         if (sendto(qp->q_dfd, msg, msglen, 0,
  1117.             (struct sockaddr *)&qp->q_from, sizeof(qp->q_from)) < 0) {
  1118. #ifdef DEBUG
  1119.             if (debug)
  1120.                 fprintf(ddt, "sendto error errno= %d\n",errno);
  1121. #endif
  1122.             return(1);
  1123.         }
  1124. #ifdef STATS
  1125.         stats[S_OUTPKTS].cnt++;
  1126. #endif
  1127.     } else {
  1128.         (void) writemsg(qp->q_stream->s_rfd, msg, msglen);
  1129.         sq_done(qp->q_stream);
  1130.     }
  1131.     return(0);
  1132. }
  1133.  
  1134. prime(class, type, oqp)
  1135.     int class, type;
  1136.     register struct qinfo *oqp;
  1137. {
  1138.     char    dname[BUFSIZ];
  1139.  
  1140.     if (oqp->q_msg == NULL)
  1141.         return;
  1142.     if (dn_expand((u_char *)oqp->q_msg,
  1143.         (u_char *)oqp->q_msg + oqp->q_msglen,
  1144.         (u_char *)oqp->q_msg + sizeof(HEADER), (u_char *)dname,
  1145.         sizeof(dname)) < 0)
  1146.         return;
  1147. #ifdef DEBUG
  1148.     if (debug >= 2)
  1149.            fprintf(ddt,"prime: %s\n", dname);
  1150. #endif
  1151.     (void) sysquery(dname, class, type);
  1152. }
  1153.  
  1154.  
  1155. prime_cache()
  1156. {
  1157.     register struct qinfo *qp;
  1158.  
  1159. #ifdef DEBUG
  1160.     if (debug)
  1161.         fprintf(ddt,"prime_cache: priming = %d\n", priming);
  1162. #endif
  1163. #ifdef STATS
  1164.     stats[S_PRIMECACHE].cnt++;
  1165. #endif
  1166.     if (!priming && fcachetab->h_tab[0] != NULL && !forward_only) {
  1167.         priming++;
  1168.         if ((qp = sysquery("", C_IN, T_NS)) == NULL)
  1169.             priming = 0;
  1170.         else
  1171.             qp->q_system = PRIMING_CACHE;
  1172.     }
  1173.     needs_prime_cache = 0;
  1174.     return;
  1175. }
  1176.  
  1177. struct qinfo *
  1178. sysquery(dname, class, type)
  1179.     char *dname;
  1180.     int class, type;
  1181. {
  1182.     extern struct qinfo *qhead;
  1183.     extern int nsid;
  1184.     register struct qinfo *qp, *oqp;
  1185.     register HEADER *hp;
  1186.     struct namebuf *np;
  1187.     struct databuf *nsp[NSMAX];
  1188.     struct hashbuf *htp;
  1189.     char *fname;
  1190.     int count;
  1191.  
  1192. #ifdef DEBUG
  1193.     if (debug > 2)
  1194.            fprintf(ddt,"sysquery(%s, %d, %d)\n", dname, class, type);
  1195. #endif
  1196. #ifdef STATS
  1197.     stats[S_SYSQUERIES].cnt++;
  1198. #endif
  1199.     htp = hashtab;
  1200.     if (priming && dname[0] == '\0')
  1201.         np = NULL;
  1202.     else if ((np = nlookup(dname, &htp, &fname, 1)) == NULL) {
  1203. #ifdef DEBUG
  1204.         if (debug)
  1205.             fprintf(ddt,"sysquery: nlookup error on %s?\n", dname);
  1206. #endif
  1207.         return(0);
  1208.     }
  1209.  
  1210.     switch (findns(&np, class, nsp, &count)) {
  1211.     case NXDOMAIN:
  1212.     case SERVFAIL:
  1213. #ifdef DEBUG
  1214.         if (debug)
  1215.             fprintf(ddt,"sysquery: findns error on %s?\n", dname);
  1216. #endif
  1217.         return(0);
  1218.     }
  1219.  
  1220.     /* build new qinfo struct */
  1221.     qp = qnew();
  1222.     qp->q_cmsg = qp->q_msg = NULL;
  1223.     qp->q_dfd = ds;
  1224.     qp->q_fwd = fwdtab;
  1225.     qp->q_system++;
  1226.  
  1227.     if ((qp->q_msg = malloc(BUFSIZ)) == NULL) {
  1228.         qfree(qp);
  1229.         return(0);
  1230.     }
  1231.     qp->q_msglen = res_mkquery(QUERY, dname, class,
  1232.         type, (char *)NULL, 0, NULL, qp->q_msg, BUFSIZ);
  1233.     hp = (HEADER *) qp->q_msg;
  1234.     hp->id = qp->q_nsid = htons((u_short)++nsid);
  1235.     hp->rd = (qp->q_fwd ? 1 : 0);
  1236.  
  1237.     /* First check for an already pending query for this data */
  1238.     for (oqp = qhead; oqp!=QINFO_NULL; oqp = oqp->q_link) {
  1239.         if (oqp != qp && oqp->q_msglen == qp->q_msglen &&
  1240.          bcmp((char *)oqp->q_msg+2, qp->q_msg+2, qp->q_msglen-2) == 0) {
  1241. #ifdef DEBUG
  1242.             if (debug >= 3)
  1243.                 fprintf(ddt, "sysquery: duplicate\n");
  1244. #endif
  1245.             qfree(qp);
  1246.             return(0);
  1247.         }
  1248.     }
  1249.  
  1250.     if (nslookup(nsp, qp) == 0) {
  1251. #ifdef DEBUG
  1252.         if (debug)
  1253.             fprintf(ddt,"resp: no addrs found for NS's\n");
  1254. #endif
  1255.         qfree(qp);
  1256.         return(0);
  1257.     }
  1258.  
  1259.     schedretry(qp, retrytime(qp));
  1260.     if (qp->q_fwd == 0)
  1261.         qp->q_addr[0].stime = tt;
  1262.  
  1263. #ifdef DEBUG
  1264.     if (debug)
  1265.         fprintf(ddt,"sysquery: send -> %s %d (%d), nsid=%d id=%d %dms\n",
  1266.         inet_ntoa(Q_NEXTADDR(qp,0)->sin_addr),
  1267.         qp->q_dfd, ntohs(Q_NEXTADDR(qp,0)->sin_port),
  1268.         ntohs(qp->q_nsid), ntohs(qp->q_id),
  1269.         qp->q_addr[0].nsdata->d_nstime);
  1270.     if ( debug >= 10)
  1271.         fp_query(qp->q_msg, ddt);
  1272. #endif
  1273.     if (sendto(qp->q_dfd, qp->q_msg, qp->q_msglen, 0,
  1274.         (struct sockaddr *)Q_NEXTADDR(qp,0),
  1275.         sizeof(struct sockaddr_in)) < 0){
  1276. #ifdef DEBUG
  1277.         if (debug)
  1278.         fprintf(ddt, "sendto error errno= %d\n",errno);
  1279. #endif
  1280.     }
  1281. #ifdef STATS
  1282.     stats[S_OUTPKTS].cnt++;
  1283. #endif
  1284.     return(qp);
  1285. }
  1286.  
  1287. /*
  1288.  * Check the list of root servers after receiving a response
  1289.  * to a query for the root servers.
  1290.  */
  1291. check_root()
  1292. {
  1293.     register struct databuf *dp, *pdp;
  1294.     register struct namebuf *np;
  1295.     int count = 0;
  1296.  
  1297.     priming = 0;
  1298.     for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next)
  1299.         if (np->n_dname[0] == '\0')
  1300.             break;
  1301.     if (np == NULL) {
  1302.         syslog(LOG_ERR, "check_root: Can't find root!\n");
  1303.         return;
  1304.     }
  1305.     for (dp = np->n_data; dp != NULL; dp = dp->d_next)
  1306.         if (dp->d_type == T_NS)
  1307.             count++;
  1308. #ifdef DEBUG
  1309.     if (debug)
  1310.         fprintf(ddt,"%d root servers\n", count);
  1311. #endif
  1312.     if (count < MINROOTS) {
  1313.         syslog(LOG_WARNING,
  1314.         "check_root: %d root servers after query to root server < min",
  1315.             count);
  1316.         return;
  1317.     }
  1318.     pdp = NULL;
  1319.     dp = np->n_data;
  1320.     while (dp != NULL) {
  1321.         if (dp->d_type == T_NS && dp->d_zone == 0 &&
  1322.             dp->d_ttl < tt.tv_sec) {
  1323. #ifdef DEBUG
  1324.             if (debug)
  1325.                 fprintf(ddt,"deleting old root server '%s'\n",
  1326.                 dp->d_data);
  1327. #endif
  1328.             dp = rm_datum(dp, np, pdp);
  1329.             /* SHOULD DELETE FROM HINTS ALSO */
  1330.             continue;
  1331.         }
  1332.         pdp = dp;
  1333.         dp = dp->d_next;
  1334.     }
  1335.     check_ns();
  1336. }
  1337.  
  1338. /* 
  1339.  * Check the root to make sure that for each NS record we have a A RR
  1340.  */
  1341. check_ns()
  1342. {
  1343.     register struct databuf *dp, *tdp;
  1344.     register struct namebuf *np, *tnp;
  1345.     struct hashbuf *htp;
  1346.     char *dname;
  1347.     int found_arr;
  1348.     char *fname;
  1349.     time_t curtime;
  1350.  
  1351. #ifdef DEBUG
  1352.     if (debug >= 2)
  1353.            fprintf(ddt,"check_ns()\n");
  1354. #endif
  1355. #ifdef STATS
  1356.     stats[S_CHECKNS].cnt++;
  1357. #endif
  1358.  
  1359.     curtime = (u_long) tt.tv_sec;
  1360.     for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) {
  1361.         if (np->n_dname[0] != 0)
  1362.             continue;
  1363.             for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
  1364.                 if (dp->d_type != T_NS)
  1365.                     continue;
  1366.  
  1367.                 /* look for A records */
  1368.             dname = dp->d_data;
  1369.             htp = hashtab;
  1370.             tnp = nlookup(dname, &htp, &fname, 0);
  1371.             if (tnp == NULL || fname != dname) {
  1372. #ifdef DEBUG
  1373.                 if (debug >= 3)
  1374.                     fprintf(ddt,"check_ns: %s: not found %s %x\n",
  1375.                     dname, fname, tnp);
  1376. #endif
  1377.                 (void) sysquery(dname, dp->d_class, T_A);
  1378.                 continue;
  1379.             }
  1380.             /* look for name server addresses */
  1381.             found_arr = 0;
  1382.             for (tdp=tnp->n_data; tdp!=NULL; tdp=tdp->d_next) {
  1383.                 if (tdp->d_type != T_A ||
  1384.                    tdp->d_class != dp->d_class)
  1385.                 continue;
  1386.                 if ((tdp->d_zone == 0) &&
  1387.                 (tdp->d_ttl < curtime)) {
  1388. #ifdef DEBUG
  1389.                     if (debug >= 3)
  1390.                         fprintf(ddt,"check_ns: stale entry '%s'\n",
  1391.                             tnp->n_dname);
  1392. #endif
  1393.                 /* Cache invalidate the address RR's */
  1394.                 delete_all(tnp, dp->d_class, T_A);
  1395.                 found_arr = 0;
  1396.                     break;
  1397.                 }
  1398.                 found_arr++;
  1399.             }
  1400.             if (!found_arr)
  1401.                 (void) sysquery(dname, dp->d_class, T_A);
  1402.             }
  1403.     }
  1404. }
  1405.  
  1406. #define    MAXCLASS 255        /* belongs elsewhere */
  1407. int    norootlogged[MAXCLASS];
  1408.  
  1409. /*
  1410.  *  Find NS's or an SOA for the given dname (np) and fill in the
  1411.  *  nsp array.  Returns OK on success, and SERVFAIL on error.
  1412.  *  We return NXDOMAIN to indicate we are authoritative.
  1413.  */
  1414. findns(npp, class, nsp, countp)
  1415.     register struct namebuf **npp;
  1416.     struct databuf **nsp;
  1417.     int *countp;
  1418. {
  1419.     register struct namebuf *np = *npp;
  1420.     register struct databuf *dp;
  1421.     register struct    databuf **nspp;
  1422.     struct hashbuf *htp = hashtab;
  1423.     
  1424.     if (priming && (np == NULL || np->n_dname[0] == '\0'))
  1425.         htp = fcachetab;
  1426. try_again:
  1427.     if (htp == fcachetab)
  1428.         needs_prime_cache = 1;
  1429.     while (np == NULL && htp != NULL) {
  1430. #ifdef DEBUG
  1431.         if (debug > 2)
  1432.             fprintf(ddt, "findns: using %s\n", htp == hashtab ?
  1433.                 "cache" : "hints");
  1434. #endif
  1435.         for (np = htp->h_tab[0]; np != NULL; np = np->n_next)
  1436.             if (np->n_dname[0] == '\0')
  1437.                 break;
  1438.         htp = (htp == hashtab ? fcachetab : NULL);    /* Fallback */
  1439.     }
  1440.     while(np != NULL) {
  1441. #ifdef DEBUG
  1442.         if (debug >= 5)
  1443.             fprintf(ddt, "findns: np 0x%x\n", np);
  1444. #endif
  1445.         /* Look first for SOA records. */
  1446.         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
  1447.             if (dp->d_zone != 0 && match(dp, class, T_SOA)) {
  1448. #ifdef DEBUG
  1449.                 if (debug >= 3)
  1450.                     fprintf(ddt,"findns: SOA found\n");
  1451. #endif
  1452.                 if (zones[dp->d_zone].z_auth) {
  1453.                     *npp = np;
  1454.                     nsp[0] = dp;
  1455.                     return(NXDOMAIN);
  1456.                 } else
  1457.                     return (SERVFAIL);
  1458.             }
  1459.         }
  1460.  
  1461.         /* If no SOA records, look for NS records. */
  1462.         nspp = &nsp[0];
  1463.         *nspp = NULL;
  1464.         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
  1465.             if (dp->d_type != T_NS ||
  1466.                 (dp->d_class != class && class != C_ANY))
  1467.                 continue;
  1468.             /*
  1469.              * Don't use records that may become invalid to
  1470.              * reference later when we do the rtt computation.
  1471.              * Never delete our safety-belt information!
  1472.              */
  1473.             if ((dp->d_zone == 0) &&
  1474.                 (dp->d_ttl < (tt.tv_sec+900)) &&
  1475.                 !(dp->d_flags & DB_F_HINT)) {
  1476. #ifdef DEBUG
  1477.                 if (debug)
  1478.                     fprintf(ddt,"findns: stale entry '%s'\n",
  1479.                             np->n_dname);
  1480. #endif
  1481.                 /* Cache invalidate the NS RR's */
  1482.                 if (dp->d_ttl < tt.tv_sec)
  1483.                     delete_all(np, class, T_NS);
  1484.                 goto try_parent;
  1485.             }
  1486.             if (nspp < &nsp[NSMAX-1])
  1487.                 *nspp++ = dp;
  1488.         }
  1489.  
  1490.         *countp = nspp - nsp;
  1491.         if (*countp > 0) {
  1492. #ifdef DEBUG
  1493.             if (debug >= 3)
  1494.                 fprintf(ddt,"findns: %d NS's added for '%s'\n",
  1495.                     *countp, np->n_dname);
  1496. #endif
  1497.             *nspp = NULL;
  1498.             *npp = np;
  1499.             return(OK);    /* Success, got some NS's */
  1500.         }
  1501. try_parent:
  1502.         np = np->n_parent;
  1503.     }
  1504.     if (htp)
  1505.         goto try_again;
  1506. #ifdef DEBUG
  1507.     if (debug)
  1508.         fprintf(ddt, "findns: No root nameservers for class %d?\n",
  1509.             class);
  1510. #endif
  1511.     if ((unsigned)class < MAXCLASS && norootlogged[class] == 0) {
  1512.         norootlogged[class] = 1;
  1513.         syslog(LOG_ERR, "No root nameservers for class %d\n", class);
  1514.     }
  1515.     return(SERVFAIL);
  1516. }
  1517.  
  1518. /*
  1519.  *  Extract RR's from the given node that match class and type.
  1520.  *  Return number of bytes added to response.
  1521.  *  If no matching data is found, then 0 is returned.
  1522.  */
  1523. finddata(np, class, type, hp, dnamep, lenp, countp)
  1524.     struct namebuf *np;
  1525.     int class, type;
  1526.     register HEADER *hp;
  1527.     char **dnamep;
  1528.     int *lenp, *countp;
  1529. {
  1530.     register struct databuf *dp;
  1531.     register char *cp;
  1532.     int buflen, n, count = 0, foundstale = 0;
  1533.  
  1534.     buflen = *lenp;
  1535.     cp = ((char *)hp) + *countp;
  1536.     for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
  1537.         if (!wanted(dp, class, type)) {
  1538.             if (type == T_CNAME && class == dp->d_class) {
  1539.                 /* any data means no CNAME exists */
  1540.                 *countp = 0;
  1541.                 return(0);
  1542.             }
  1543.             continue;
  1544.         }
  1545.         if (stale(dp)) {
  1546.             /*
  1547.              * Don't use stale data.
  1548.              * Would like to call delete_all here
  1549.              * and continue, but the data chain would get
  1550.              * munged; can't restart, as make_rr has side
  1551.              * effects (leaving pointers in dnptr).
  1552.              * Just skip this entry for now
  1553.              * and call delete_all at the end.
  1554.              */
  1555. #ifdef DEBUG
  1556.             if (debug >=3)
  1557.                fprintf(ddt,"finddata: stale entry '%s'\n",np->n_dname);
  1558. #endif
  1559.             if (dp->d_zone == 0)
  1560.                 foundstale++;
  1561.             continue;
  1562.         }
  1563.         if ((n = make_rr(*dnamep, dp, cp, buflen, 1)) < 0) {
  1564.             hp->tc = 1;
  1565.             *countp = count;
  1566.             return(*lenp - buflen);
  1567.         }
  1568.  
  1569.         cp += n;
  1570.         buflen -= n;
  1571.         count++;
  1572. #ifdef notdef
  1573.         /* this isn't right for glue records, aa is set in ns_req */
  1574.         if (dp->d_zone && zones[dp->d_zone].z_auth && class != C_ANY)
  1575.             hp->aa = 1;            /* XXX */
  1576. #endif
  1577.         if (dp->d_type == T_CNAME) {
  1578.             if (type != T_ANY) {    /* or T_NS? */
  1579.                 *dnamep = dp->d_data;
  1580.                 if (dp->d_zone && zones[dp->d_zone].z_auth &&
  1581.                     class != C_ANY)        /* XXX */
  1582.                     hp->aa = 1;        /* XXX */
  1583.             }
  1584.             break;
  1585.         }
  1586.     }
  1587.     /*
  1588.      * Cache invalidate the other RR's of same type
  1589.      * if some have timed out
  1590.      */
  1591.     if (foundstale)
  1592.         delete_all(np, class, type);
  1593. #ifdef DEBUG
  1594.     if (debug >=3)
  1595.         fprintf(ddt,"finddata: added %d class %d type %d RRs\n",
  1596.             count, class, type);
  1597. #endif
  1598.     *countp = count;
  1599.     return(*lenp - buflen);
  1600. }
  1601.  
  1602. /*
  1603.  * Do we want this data record based on the class and type?
  1604.  */
  1605. wanted(dp, class, type)
  1606.     struct databuf *dp;
  1607.     int class, type;
  1608. {
  1609.  
  1610. #ifdef DEBUG
  1611.     if (debug > 3)
  1612.         fprintf(ddt,"wanted(%x, %d, %d) %d, %d\n", dp, class, type,
  1613.             dp->d_class, dp->d_type);
  1614. #endif
  1615.  
  1616.     if (dp->d_class != class && class != C_ANY)
  1617.         return (0);
  1618.     if (type == dp->d_type)
  1619.         return (1);
  1620.     switch (dp->d_type) {
  1621.     case T_ANY:
  1622.     case T_CNAME:
  1623.         return (1);
  1624.     }
  1625.     switch (type) {
  1626.     case T_ANY:
  1627.         return (1);
  1628.  
  1629.     case T_MAILB:
  1630.         switch (dp->d_type) {
  1631.         case T_MR:
  1632.         case T_MB:
  1633.         case T_MG:
  1634.         case T_MINFO:
  1635.             return (1);
  1636.         }
  1637.         break;
  1638.  
  1639.     case T_AXFR:
  1640.         if (dp->d_type == T_SOA)
  1641.             return (1);
  1642.     }
  1643.     return (0);
  1644. }
  1645.  
  1646. /*
  1647.  *  Add RR entries from dpp array to a query/response.
  1648.  *  Return the number of bytes added or negative the amount
  1649.  *  added if truncation was required.  Typically you are
  1650.  *  adding NS records to a response.
  1651.  */
  1652. add_data(np, dpp, cp, buflen)
  1653.     struct namebuf *np;
  1654.     struct databuf **dpp;
  1655.     register char *cp;
  1656.     int buflen;
  1657. {
  1658.     register struct databuf *dp;
  1659.     char dname[MAXDNAME];
  1660.     register int n, count = 0;
  1661.  
  1662.     getname(np, dname, sizeof(dname));
  1663.     for(dp = *dpp++; dp != NULL; dp = *dpp++) {
  1664.         if (stale(dp))
  1665.             continue;    /* ignore old cache entry */
  1666.         if ((n = make_rr(dname, dp, cp, buflen, 1)) < 0)
  1667.             return(-count);        /* Truncation */
  1668.         cp += n;
  1669.         buflen -= n;
  1670.         count += n;
  1671.     }
  1672.     return(count);
  1673. }
  1674.  
  1675. /*
  1676.  *  This is best thought of as a "cache invalidate" function.
  1677.  *  It is called whenever a piece of data is determined to have
  1678.  *  timed out.  It is better to have no information, than to
  1679.  *  have partial information you pass off as complete.
  1680.  */
  1681. delete_all(np, class, type)
  1682. register struct namebuf *np;
  1683. int class, type;
  1684. {
  1685.     register struct databuf *dp, *pdp;
  1686.  
  1687. #ifdef DEBUG
  1688.     if (debug > 2)
  1689.         fprintf(ddt,"delete_all: '%s' 0x%x class %d type %d\n",
  1690.                 np->n_dname, np, class, type);
  1691. #endif
  1692.     pdp = NULL;
  1693.     dp = np->n_data;
  1694.     while (dp != NULL) {
  1695.         if ((dp->d_zone == 0) && !(dp->d_flags & DB_F_HINT)
  1696.             && match(dp, class, type)) {
  1697.             dp = rm_datum(dp, np, pdp);
  1698.             continue;
  1699.         }
  1700.         pdp = dp;
  1701.         dp = dp->d_next;
  1702.     }
  1703. }
  1704.