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