]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bind/bin/named/ns_resp.c
This commit was generated by cvs2svn to compensate for changes in r56639,
[FreeBSD/FreeBSD.git] / contrib / bind / bin / named / ns_resp.c
1 #if !defined(lint) && !defined(SABER)
2 static const char sccsid[] = "@(#)ns_resp.c     4.65 (Berkeley) 3/3/91";
3 static const char rcsid[] = "$Id: ns_resp.c,v 8.133 1999/11/05 04:40:57 vixie Exp $";
4 #endif /* not lint */
5
6 /*
7  * Copyright (c) 1986, 1988, 1990
8  *    The Regents of the University of California.  All rights reserved.
9  * 
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  * 
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 /*
40  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
41  * 
42  * Permission to use, copy, modify, and distribute this software for any
43  * purpose with or without fee is hereby granted, provided that the above
44  * copyright notice and this permission notice appear in all copies, and that
45  * the name of Digital Equipment Corporation not be used in advertising or
46  * publicity pertaining to distribution of the document or software without
47  * specific, written prior permission.
48  * 
49  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
50  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
51  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
52  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
53  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
54  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
55  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
56  * SOFTWARE.
57  */
58
59 /*
60  * Portions Copyright (c) 1995 by International Business Machines, Inc.
61  *
62  * International Business Machines, Inc. (hereinafter called IBM) grants
63  * permission under its copyrights to use, copy, modify, and distribute this
64  * Software with or without fee, provided that the above copyright notice and
65  * all paragraphs of this notice appear in all copies, and that the name of IBM
66  * not be used in connection with the marketing of any product incorporating
67  * the Software or modifications thereof, without specific, written prior
68  * permission.
69  *
70  * To the extent it has a right to do so, IBM grants an immunity from suit
71  * under its patents, if any, for the use, sale or manufacture of products to
72  * the extent that such products are used for performing Domain Name System
73  * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
74  * granted for any product per se or for any other function of any product.
75  *
76  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
77  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
78  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
79  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
80  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
81  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
82  */
83
84 /*
85  * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
86  *
87  * Permission to use, copy, modify, and distribute this software for any
88  * purpose with or without fee is hereby granted, provided that the above
89  * copyright notice and this permission notice appear in all copies.
90  *
91  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
92  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
93  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
94  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
95  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
96  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
97  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
98  * SOFTWARE.
99  */
100
101 #include "port_before.h"
102
103 #include <sys/types.h>
104 #include <sys/param.h>
105 #include <sys/socket.h>
106 #include <sys/file.h>
107 #include <sys/un.h>
108
109 #include <netinet/in.h>
110 #include <arpa/nameser.h>
111 #include <arpa/inet.h>
112
113 #include <errno.h>
114 #include <limits.h>
115 #include <resolv.h>
116 #include <stdio.h>
117 #include <stdlib.h>
118 #include <string.h>
119 #include <syslog.h>
120 #include <time.h>
121
122 #include <isc/eventlib.h>
123 #include <isc/logging.h>
124 #include <isc/memcluster.h>
125
126 #include <isc/dst.h>
127
128 #include "port_after.h"
129
130 #include "named.h"
131
132 static u_int8_t         norootlogged[MAXCLASS]; /* XXX- should be a bitmap */
133
134 static const char       skipnameFailedAnswer[] = "skipname failed in answer",
135                         skipnameFailedAuth[] =  "skipname failed in authority",
136                         skipnameFailedQuery[] = "skipname failed in query",
137                         outofDataQuery[] =      "ran out of data in query",
138                         outofDataAnswer[] =     "ran out of data in answer",
139                         notSingleQuery[] =      "not exactly one query",
140                         expandFailedQuery[] =   "dn_expand failed in query",
141                         expandFailedAnswer[] =  "dn_expand failed in answer",
142                         expandFailedAuth[] =    "dn_expand failed in authority",
143                         outofDataAuth[] =       "ran out of data in authority",
144                         dlenOverrunAnswer[] =   "dlen overrun in answer",
145                         dlenOverrunAuth[] =     "dlen overrun in authority",
146                         dlenUnderrunAnswer[] =  "dlen underrun in answer",
147                         outofDataFinal[] =      "out of data in final pass",
148                         outofDataAFinal[] =     "out of data after final pass",
149                         badNameFound[] =        "found an invalid domain name",
150                         wrongQuestion[] =       "answer to wrong question",
151                         danglingCname[] =       "dangling CNAME pointer";
152
153 struct db_list {
154         struct db_list *db_next;
155         struct databuf *db_dp;
156 };
157
158 struct flush_set {
159         char *          fs_name;
160         int             fs_type;
161         int             fs_class;
162         u_int           fs_cred;
163         struct db_list *fs_list;
164         struct db_list *fs_last;
165 };
166
167 static void             rrsetadd(struct flush_set *, const char *, 
168                                  struct databuf *),
169                         rrsetupdate(struct flush_set *, int flags,
170                                     struct sockaddr_in, int),
171                         flushrrset(struct flush_set *, struct sockaddr_in),
172                         free_flushset(struct flush_set *, int),
173                         check_hints(struct flush_set *);
174 static int              rrsetcmp(char *, struct db_list *, struct hashbuf *),
175                         check_root(void),
176                         check_ns(void),
177                         wanted(const struct databuf *, int, int),
178                         wantedsig(const struct databuf *, int, int),
179                         rrextract(u_char *, int, u_char *,
180                                   struct databuf **, char *, int,
181                                   struct sockaddr_in, char **);
182 static void             mark_bad(struct qinfo *qp, struct sockaddr_in from);
183 static void             mark_lame(struct qinfo *qp, struct sockaddr_in from);
184 static void             fast_retry(struct qinfo *qp, struct sockaddr_in from);
185 static void             add_related_additional(char *);
186 static void             free_related_additional(void);
187 static int              related_additional(char *);
188 static void             freestr_maybe(char **);
189 static enum ordering    match_order(const struct namebuf *, int, int);
190 static int              match_name(const struct namebuf *, const char *, size_t);
191
192 #define MAX_RELATED 100
193
194 static int num_related = 0;
195 static char *related[MAX_RELATED];
196
197 static char *
198 learntFrom(struct qinfo *qp, struct sockaddr_in *server) {
199         static char *buf = NULL;
200         char *a, *ns, *na;
201         struct databuf *db;
202         int i;
203         
204         a = ns = na = "<Not Available>";
205
206         for (i = 0; (u_int)i < qp->q_naddr; i++) {
207                 if (ina_equal(qp->q_addr[i].ns_addr.sin_addr,
208                               server->sin_addr)) {
209                         db = qp->q_addr[i].ns;
210                         if (db != NULL) {
211                                 if (NS_OPTION_P(OPTION_HOSTSTATS)) {
212                                         char nsbuf[20];
213
214                                         if (db->d_ns != NULL) {
215                                                 strcpy(nsbuf,
216                                                     inet_ntoa(db->d_ns->addr));
217                                                 ns = nsbuf;
218                                         } else {
219                                                 ns = zones[db->d_zone]
220                                                         .z_origin;
221                                         }
222                                 }
223                                 if (db->d_rcode == 0)
224                                         na = (char*)qp->q_addr[i].ns->d_data;
225                         }
226
227                         if (NS_OPTION_P(OPTION_HOSTSTATS)) {
228                                 char abuf[20];
229
230                                 db = qp->q_addr[i].nsdata;
231                                 if (db != NULL) {
232                                         if (db->d_ns != NULL) {
233                                                 strcpy(abuf,
234                                                     inet_ntoa(db->d_ns->addr));
235                                                 a = abuf;
236                                         } else {
237                                                 a = zones[db->d_zone].z_origin;
238                                         }
239                                 }
240                         }
241                         break;
242                 }
243         }
244
245         if (a == ns && ns == na)        /* all "UNKNOWN" */
246                 return (NULL);
247         
248         if (*a == '\0')
249                 a = "\".\"";
250         if (*ns == '\0')
251                 ns = "\".\"";
252         if (*na == '\0')
253                 na = "\".\"";
254
255         if (NS_OPTION_P(OPTION_HOSTSTATS)) {
256                 static const char fmt[] = " '%s': learnt (A=%s,NS=%s)";
257
258                 buf = newstr(sizeof fmt + strlen(na) + strlen(a) + strlen(ns),
259                              0);
260                 if (buf == NULL)
261                         return (NULL);
262                 sprintf(buf, fmt, na, a, ns);
263         } else {
264                 static const char fmt[] = " '%s'";
265
266                 buf = newstr(sizeof fmt + strlen(na), 0);
267                 if (buf == NULL)
268                         return (NULL);
269                 sprintf(buf, fmt, na);
270         }
271
272         return (buf);
273 }
274
275 void
276 ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp)
277 {
278         struct qinfo *qp;
279         HEADER *hp;
280         struct qserv *qs = NULL;
281         struct databuf *ns, *ns2;
282         u_char *cp, *answers, *eom = msg + msglen;
283         struct flush_set *flushset = NULL;
284         int flushset_size = 0;
285         struct sockaddr_in *nsa;
286         struct databuf *nsp[NSMAX];
287         int i, c, n, qdcount, ancount, aucount, nscount, arcount, arfirst;
288         int soacount;
289         u_int qtype, qclass;
290         int restart;    /* flag for processing cname response */
291         int validanswer, dbflags;
292         int cname, lastwascname, externalcname;
293         int count, founddata, foundname;
294         int buflen;
295         int newmsglen;
296         char name[MAXDNAME], qname[MAXDNAME], aname[MAXDNAME];
297         char msgbuf[MAXDNAME+100];
298         char *dname, tmpdomain[MAXDNAME];
299         const char *fname;
300         const char *formerrmsg = "brain damage";
301         u_char newmsg[PACKETSZ];
302         u_char **dpp, *tp;
303         time_t rtrip;
304         struct hashbuf *htp;
305         struct namebuf *np;
306         struct fwdinfo *fwd;
307         struct databuf *dp;
308         int forcecmsg = 0;
309         char *tname = NULL;
310         int sendto_errno = 0;
311         int has_tsig, oldqlen;
312         u_char *oldqbuf;
313         u_char *smsg;
314         int smsglen, smsgsize, siglen;
315         u_char sig[TSIG_SIG_SIZE];
316         time_t tsig_time;
317         DST_KEY *key;
318
319         nameserIncr(from.sin_addr, nssRcvdR);
320         nsp[0] = NULL;
321         hp = (HEADER *) msg;
322         if ((qp = qfindid(hp->id)) == NULL ) {
323                 ns_debug(ns_log_default, 1, "DUP? dropped (id %d)",
324                          ntohs(hp->id));
325                 nameserIncr(from.sin_addr, nssRcvdDupR);
326                 return;
327         }
328
329         if (ns_wouldlog(ns_log_default, 2)) {
330                 ns_debug(ns_log_default, 2, "Response (%s %s %s) nsid=%d id=%d",
331                          (qp->q_flags & Q_SYSTEM) ?"SYSTEM" :"USER",
332                          (qp->q_flags & Q_PRIMING) ?"PRIMING" :"NORMAL",
333                          (qp->q_flags & Q_ZSERIAL) ?"ZSERIAL" :"-",
334                          ntohs(qp->q_nsid), ntohs(qp->q_id));
335         }
336
337         if (qp->q_nstsig == NULL)
338                 has_tsig = 0;
339         else {
340                 int ret;
341
342                 ret = ns_verify(msg, &msglen, qp->q_nstsig->key,
343                                 qp->q_nstsig->sig, qp->q_nstsig->siglen,
344                                 NULL, NULL, &tsig_time, 0);
345                 if (ret == 0)
346                         has_tsig = 1;
347                 else {
348                         if (hp->rcode == NOERROR)
349                                 hp->rcode = NOTAUTH;
350                         ns_debug(ns_log_default, 1,
351                                  "resp: error bad tsig, record dropped");
352                         return;
353                 }
354         }
355
356         /*
357          * Here we handle high level formatting problems by parsing the header.
358          */
359         qdcount = ntohs(hp->qdcount);
360         ancount = ntohs(hp->ancount);
361         aucount = ntohs(hp->nscount);
362         arcount = ntohs(hp->arcount);
363         free_addinfo();         /* sets addcount to zero */
364         cp = msg + HFIXEDSZ;
365         dpp = dnptrs;
366         *dpp++ = msg;
367         if ((*cp & INDIR_MASK) == 0)
368                 *dpp++ = cp;
369         *dpp = NULL;
370         if (qdcount == 1) {
371                 n = dn_expand(msg, eom, cp, qname, sizeof(qname));
372                 if (n <= 0) {
373                         formerrmsg = expandFailedQuery;
374                         goto formerr;
375                 }
376                 cp += n;
377                 if (cp + 2 * INT16SZ > eom) {
378                         formerrmsg = outofDataQuery;
379                         goto formerr;
380                 }
381                 GETSHORT(qtype, cp);
382                 GETSHORT(qclass, cp);
383                 if (!ns_nameok(qp, qname, qclass, NULL, response_trans,
384                                ns_ownercontext(qtype, response_trans),
385                                qname, from.sin_addr)) {
386                         formerrmsg = badNameFound;
387                         goto refused;
388                 }
389                 if (cp > eom) {
390                         formerrmsg = outofDataQuery;
391                         goto formerr;
392                 }
393                 if (qp->q_msg && qp->q_msglen &&
394                     !res_nameinquery(qname, qtype, qclass,
395                                      qp->q_msg, qp->q_msg + qp->q_msglen)) {
396                         sprintf(msgbuf,
397                                 "query section mismatch (%s %s %s)",
398                                 qname, p_class(qclass), p_type(qtype));
399                         formerrmsg = msgbuf;
400                         goto formerr;
401                 }
402                 if (ns_samename(qp->q_name, qname) != 1 ||
403                     qp->q_class != qclass ||
404                     qp->q_type != qtype) {
405                         formerrmsg = wrongQuestion;
406                         goto formerr;
407                 }
408         } else {
409                 strcpy(qname, qp->q_name);
410                 qclass = qp->q_class;
411                 qtype = qp->q_type;
412         }
413
414         /* cp now points after the query section. */
415
416         /*
417          *  Here we handle bad responses from servers.
418          *  Several possibilities come to mind:
419          *      The server is sick and returns SERVFAIL
420          *      The server returns some garbage opcode (it's sick)
421          *      The server can't understand our query and return FORMERR
422          *  In all these cases, we drop the packet, disable retries on
423          *  this server and immediately force a retry.
424          */
425         if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN)
426             || (hp->opcode != QUERY
427 #ifdef BIND_NOTIFY
428                 && hp->opcode != NS_NOTIFY_OP
429 #endif
430                 )) {
431                 ns_debug(ns_log_default, 2,
432                          "resp: error (ret %d, op %d), dropped",
433                          hp->rcode, hp->opcode);
434                 switch (hp->rcode) {
435                 case SERVFAIL:
436                         nameserIncr(from.sin_addr, nssRcvdFail);
437                         break;
438                 case FORMERR:
439                         nameserIncr(from.sin_addr, nssRcvdFErr);
440                         break;
441                 default:
442                         nameserIncr(from.sin_addr, nssRcvdErr);
443                         break;
444                 }
445                 if (ns_samename(qp->q_name, qp->q_domain) == 1 &&
446                     hp->rcode == SERVFAIL && hp->opcode == QUERY)
447                         mark_lame(qp, from);
448                 mark_bad(qp, from);
449                 fast_retry(qp, from);
450                 return;
451         }
452
453         if (qdcount != 1) {
454                 /* We don't generate or forward these (yet). */
455                 formerrmsg = notSingleQuery;
456                 goto formerr;
457         }
458
459         /*
460          * Determine if the response came from a forwarder.  Packets from
461          * anyplace not listed as a forwarder or as a server to whom we
462          * might have forwarded the query will be dropped.
463          * XXX - should put this in STATS somewhere.
464          */
465         for (fwd = NS_ZFWDTAB(qp->q_fzone); fwd; fwd = fwd->next)
466                 if (ina_equal(fwd->fwdaddr.sin_addr, from.sin_addr))
467                         break;
468         /*
469          * XXX: note bad ambiguity here.  if one of our forwarders is also
470          *      a delegated server for some domain, then we will not update
471          *      the RTT information on any replies we get from those servers.
472          *      Workaround: disable recursion on authoritative servers so that
473          *      the ambiguity does not arise.
474          */
475         /*
476          * If we weren't using a forwarder, find the qinfo pointer and update
477          * the rtt and fact that we have called on this server before.
478          */
479         if (fwd == NULL) {
480                 struct timeval *stp;
481
482                 for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++)
483                         if (ina_equal(qs->ns_addr.sin_addr, from.sin_addr))
484                                 break;
485                 if ((u_int)n >= qp->q_naddr) {
486                         if (!haveComplained(ina_ulong(from.sin_addr),
487                                             (u_long)"unexpected source")) {
488                                 ns_info(ns_log_default,
489                                         "Response from unexpected source (%s)",
490                                         sin_ntoa(from));
491                         }
492                         /* 
493                          * We don't know who this response came from so it
494                          * gets dropped on the floor.
495                          */
496                         return;
497                 }
498                 stp = &qs->stime;
499
500                 /* Handle response from different (untried) interface. */
501                 if (qs->ns != NULL && stp->tv_sec == 0) {
502                         ns = qs->ns;
503                         while (qs > qp->q_addr
504                                && (qs->stime.tv_sec == 0 || qs->ns != ns))
505                                 qs--;
506                         *stp = qs->stime;
507                         /* XXX - sometimes stp still ends up pointing to
508                          * a zero timeval, in spite of the above attempt.
509                          * Why?  What should we do about it?
510                          */
511                         /* XXX - catch aliases here */
512                 }
513
514                 /* compute query round trip time */
515                 /* XXX - avoid integer overflow, which is quite likely if stp
516                  * points to a zero timeval (see above).
517                  * rtrip is of type time_t, which we assume is at least
518                  * as big as an int.
519                  */
520                 if ((tt.tv_sec - stp->tv_sec) > (INT_MAX-999)/1000) {
521                         rtrip = INT_MAX;
522                 } else {
523                         rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 +
524                                  (tt.tv_usec - stp->tv_usec) / 1000);
525                 }
526                 
527                 if (ns_wouldlog(ns_log_default,3)) {
528                         ns_debug(ns_log_default, 3,
529                                  "stime %lu/%lu  now %lu/%lu rtt %ld",
530                                  (u_long)stp->tv_sec, (u_long)stp->tv_usec,
531                                  (u_long)tt.tv_sec, (u_long)tt.tv_usec,
532                                  (long)rtrip);
533                 }
534
535                 /* prevent floating point overflow, limit to 1000 sec */
536                 if (rtrip > 1000000) {
537                         rtrip = 1000000;
538                 }
539                 ns = qs->nsdata;
540                 /*
541                  * Don't update nstime if this doesn't look
542                  * like an address databuf now.                 XXX
543                  */
544                 if (ns &&
545                     ns->d_type == T_A &&
546                     ns->d_class == qs->ns->d_class) {
547                         u_long t;
548
549                         if (ns->d_nstime == 0)
550                                 t = rtrip;
551                         else
552                                 t = ns->d_nstime * ALPHA
553                                         +
554                                     (1 - ALPHA) * rtrip;
555                         if (t > 65535)
556                                 t = 65535;
557                         ns->d_nstime = (u_int16_t)t;
558                 }
559
560                 /*
561                  * Record the source so that we do not use this NS again.
562                  */
563                 if (ns && qs->ns && (qp->q_nusedns < NSMAX)) {
564                         qp->q_usedns[qp->q_nusedns++] = qs->ns;
565                         if (ns_wouldlog(ns_log_default,2)) {
566                                 ns_debug(ns_log_default, 2,
567                                          "NS #%d addr %s used, rtt %d",
568                                          n, sin_ntoa(qs->ns_addr), ns->d_nstime);
569                         }
570                 }
571
572                 /*
573                  * Penalize those who had earlier chances but failed
574                  * by multiplying round-trip times by BETA (>1).
575                  * Improve nstime for unused addresses by applying GAMMA.
576                  * The GAMMA factor makes unused entries slowly
577                  * improve, so they eventually get tried again.
578                  * GAMMA should be slightly less than 1.
579                  * Watch out for records that may have timed out
580                  * and are no longer the correct type.                  XXX
581                  */
582                 
583                 for (n = 0, qs = qp->q_addr;
584                      (u_int)n < qp->q_naddr;
585                      n++, qs++) {
586                         u_long t;
587
588                         ns2 = qs->nsdata;
589                         if (!ns2 || ns2 == ns)
590                                 continue;
591                         if (ns2->d_type != T_A ||
592                             ns2->d_class != qs->ns->d_class)    /* XXX */
593                                 continue;
594                         if (qs->stime.tv_sec) {
595                                 if (ns2->d_nstime == 0)
596                                         t = (rtrip * BETA);
597                                 else
598                                         t = ns2->d_nstime * BETA
599                                                 +
600                                             (1 - ALPHA) * rtrip;
601                         } else
602                                 t = ns2->d_nstime * GAMMA;
603                         if (t > 65535)
604                                 t = 65535;
605                         ns2->d_nstime = (u_int16_t)t;
606                         if (ns_wouldlog(ns_log_default,2)) {
607                                 ns_debug(ns_log_default, 2, "NS #%d %s rtt now %d", n,
608                                          sin_ntoa(qs->ns_addr),
609                                          ns2->d_nstime);
610                         }
611                 }
612         }
613
614 #ifdef BIND_NOTIFY
615         /*
616          * For now, NOTIFY isn't defined for ANCOUNT!=0, AUCOUNT!=0,
617          * or ADCOUNT!=0.  Therefore the only real work to be done for
618          * a NOTIFY-QR is to remove it from the query queue.
619          */
620         if (hp->opcode == NS_NOTIFY_OP) {
621                 ns_info(ns_log_notify,
622                         "Received NOTIFY answer from %s for \"%s %s %s\"",
623                         inet_ntoa(from.sin_addr), 
624                         *(qp->q_name) ? qp->q_name : ".",
625                         p_class(qp->q_class), p_type(qp->q_type));
626                 qremove(qp);
627                 return;
628         }
629 #endif
630
631         if ((qp->q_flags & Q_ZSERIAL) != 0) {
632                 if (hp->aa && ancount > 0 && hp->rcode == NOERROR &&
633                     qtype == T_SOA && (qclass == C_IN || qclass == C_HS))
634                 {
635                         int n;
636                         u_int type, class, dlen;
637                         u_int32_t serial;
638                         u_char *tp = cp;
639                         u_char *rdatap;
640
641                         n = dn_expand(msg, eom, tp, name, sizeof name);
642                         if (n < 0) {
643                                 formerrmsg = expandFailedAnswer;
644                                 goto formerr;
645                         }
646                         tp += n;                /* name */
647                         if (tp + 3 * INT16SZ + INT32SZ > eom) {
648                                 formerrmsg = outofDataAnswer;
649                                 goto formerr;
650                         }
651                         GETSHORT(type, tp);     /* type */
652                         GETSHORT(class, tp);    /* class */
653                         tp += INT32SZ;          /* ttl */
654                         GETSHORT(dlen, tp);     /* dlen */
655                         rdatap = tp;            /* start of rdata */
656                         if (!ns_nameok(qp, name, class, NULL, response_trans,
657                                        ns_ownercontext(type, response_trans),
658                                        name, from.sin_addr)) {
659                                 formerrmsg = badNameFound;
660                                 goto refused;
661                         }
662                         if (ns_samename(qname, name) != 1 ||
663                             qtype != type || qclass != class) {
664                                 sprintf(msgbuf,
665                                         "qserial answer mismatch (%s %s %s)",
666                                         name, p_class(class), p_type(type));
667                                 formerrmsg = msgbuf;
668                                 goto formerr;
669                         }
670                         if (0 >= (n = dn_skipname(tp, eom))) {
671                                 formerrmsg = skipnameFailedAnswer;
672                                 goto formerr;
673                         }
674                         tp += n;                /* mname */
675                         if (0 >= (n = dn_skipname(tp, eom))) {
676                                 formerrmsg = skipnameFailedAnswer;
677                                 goto formerr;
678                         }
679                         tp += n;                /* rname */
680                         if (tp + 5 * INT32SZ > eom) {
681                                 formerrmsg = dlenUnderrunAnswer;
682                                 goto formerr;
683                         }
684                         GETLONG(serial, tp);
685                         tp += 4 * INT32SZ;      /* Skip rest of SOA. */
686                         if ((u_int)(tp - rdatap) != dlen) {
687                                 formerrmsg = dlenOverrunAnswer;
688                                 goto formerr;
689                         }
690                         for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr;
691                                         n++, qs++)
692                                 if (ina_equal(qs->ns_addr.sin_addr,
693                                               from.sin_addr))
694                                         break;
695                         if (n == qp->q_naddr) {
696                                 qserial_answer(qp);
697                                 qremove(qp);
698                                 return;
699                         }
700                         qs->serial = serial;
701                 }
702                 retry(qp);
703                 return;
704         }
705
706         /*
707          *  Non-authoritative, no answer, no error, with referral.
708          */
709         if (hp->rcode == NOERROR && !hp->aa && ancount == 0 && aucount > 0
710 #ifdef BIND_NOTIFY
711             && hp->opcode != NS_NOTIFY_OP
712 #endif
713             ) {
714                 u_char *tp;
715                 int type, class;
716 #ifdef DEBUG
717                 if (debug > 0)
718                         res_pquery(&res, msg, msglen,
719                                    log_get_stream(packet_channel));
720 #endif
721                 /*
722                  * Since there is no answer section (ancount == 0),
723                  * we must be pointing at the authority section (aucount > 0).
724                  */
725                 tp = cp;
726                 n = dn_expand(msg, eom, tp, name, sizeof name);
727                 if (n < 0) {
728                         formerrmsg = expandFailedAuth;
729                         goto formerr;
730                 }
731                 tp += n;
732                 if (tp + 2 * INT16SZ > eom) {
733                         formerrmsg = outofDataAuth;
734                         goto formerr;
735                 }
736                 GETSHORT(type, tp);
737                 GETSHORT(class, tp);
738                 if (!ns_nameok(qp, name, class, NULL, response_trans,
739                                ns_ownercontext(type, response_trans),
740                                name, from.sin_addr)) {
741                         formerrmsg = badNameFound;
742                         goto refused;
743                 }
744
745                 /*
746                  * If the answer delegates us either to the same level in
747                  * the hierarchy or closer to the root, we consider this
748                  * server lame.  Note that for now we only log the message
749                  * if the T_NS was C_IN, which is technically wrong (NS is
750                  * visible in all classes) but necessary anyway (non-IN
751                  * classes tend to not have good strong delegation graphs).
752                  */
753
754                 if (type == T_NS && ns_samedomain(qp->q_domain, name)) {
755                         nameserIncr(from.sin_addr, nssRcvdLDel);
756                         mark_lame(qp, from);
757                         mark_bad(qp, from);
758                         if (class == C_IN &&
759                             !haveComplained(ina_ulong(from.sin_addr),
760                                             nhash(qp->q_domain))) {
761                                 char *learnt_from = learntFrom(qp, &from);
762
763                                 ns_info(ns_log_lame_servers,
764                                         "Lame server on '%s' (in '%s'?): %s%s",
765                                         qname, qp->q_domain, 
766                                         sin_ntoa(from),
767                                         (learnt_from == NULL) ? "" :
768                                         learnt_from);
769                                 if (learnt_from != NULL)
770                                         freestr(learnt_from);
771                         }
772
773                         fast_retry(qp, from);
774                         return;
775                 }
776         }
777
778         /*
779          * Add the info received in the response to the data base.
780          */
781         arfirst = ancount + aucount;
782         c = arfirst + arcount;
783
784         /* Don't return if it's a TSIG signed truncated message */
785         if (has_tsig > 0 && hp->tc)
786                 goto tcp_retry;
787
788         /* -ve $ing non-existence of record, must handle non-authoritative
789          * NOERRORs with c == 0.
790          */
791         if (!hp->aa && hp->rcode == NOERROR && c == 0)
792                 goto return_msg;
793
794         if (qp->q_flags & Q_SYSTEM)
795                 dbflags = DB_NOTAUTH | DB_NODATA;
796         else
797                 dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS;
798         count = c;
799         if (qp->q_flags & Q_PRIMING)
800                 dbflags |= DB_PRIMING;
801         if (hp->tc) {
802                 count -= arcount;       /* truncation had to affect this */
803                 if (!arcount) {
804                         count -= aucount;       /* guess it got this too */
805                 }
806                 if (!(arcount || aucount)) {
807                         count -= ancount;       /* things are pretty grim */
808                 }
809
810 tcp_retry:
811                 /* retry using tcp provided this was not a tcp query */
812                 if (!(qp->q_flags & Q_USEVC)) {
813                         qp->q_flags |= Q_USEVC;
814                         unsched(qp);
815                         schedretry(qp, 60);
816
817                         nsa = Q_NEXTADDR(qp, 0);
818
819                         key = tsig_key_from_addr(nsa->sin_addr);
820                         if (key != NULL) {
821                                 smsgsize = qp->q_msglen + TSIG_BUF_SIZE;
822                                 smsg = memget(smsgsize);
823                                 smsglen = qp->q_msglen;
824                                 siglen = sizeof(sig);
825                                 memcpy(smsg, qp->q_msg, qp->q_msglen);
826                                 n = ns_sign(smsg, &smsglen, smsgsize,
827                                             NOERROR, key, NULL, 0,
828                                             sig, &siglen, 0);
829                                 if (n == 0) {
830                                         oldqbuf = qp->q_msg;
831                                         oldqlen = qp->q_msglen;
832                                         qp->q_msglen = smsglen;
833                                         qp->q_msg = smsg;
834                                         has_tsig = 1;
835                                         qp->q_nstsig = new_tsig(key, sig,
836                                                                 siglen);
837                                 }
838                                 else {
839                                         has_tsig = 0;
840                                         free_tsig(qp->q_nstsig);
841                                         qp->q_nstsig = NULL;
842                                         INSIST(0);
843                                 }
844                         }
845                         else {
846                                 has_tsig = 0;
847                                 free_tsig(qp->q_nstsig);
848                                 qp->q_nstsig = NULL;
849                         }
850
851                         if (tcp_send(qp) != NOERROR)
852                                 /*
853                                  * We're probably in trouble if tcp_send
854                                  * failed, but we'll try to press on because
855                                  * there isn't anything else to do.
856                                  */
857                                 retry(qp);
858
859                         if (has_tsig == 1) {
860                                 memput(qp->q_msg, smsgsize);
861                                 qp->q_msg = oldqbuf;
862                                 qp->q_msglen = oldqlen;
863                         }
864                         return;
865                 } else if (!qsp) {
866                         /* outstanding udp response */
867                         return;
868                 }
869
870                 /* XXX truncated tcp response */
871                 ns_error(ns_log_default,
872                          "ns_resp: TCP truncated: \"%s\" %s %s from %s",
873                          qname, p_class(qclass), p_type(qtype),
874                          sin_ntoa(from));
875                 /* mark this server as bad */
876                 mark_bad(qp, from);
877                 /* try another server, it may have a bigger write buffer */
878                 retry(qp);
879                 return;
880         }
881
882         tp = cp;
883
884         restart = 0;
885         validanswer = 0;
886         nscount = 0;
887         soacount = 0;
888         cname = 0;
889         lastwascname = 0;
890         externalcname = 0;
891         strcpy(aname, qname);
892
893         if (count) {
894                 /* allocate 1 extra record for end of set detection */
895                 flushset_size = (count + 1) * sizeof *flushset;
896                 flushset = memget(flushset_size);
897                 if (flushset == NULL)
898                         panic("flushset: out of memory", NULL);
899                 memset(flushset, 0, flushset_size);
900         } else
901                 flushset = NULL;
902
903         for (i = 0; i < count; i++) {
904                 struct databuf *dp;
905                 int type;
906
907                 freestr_maybe(&tname);
908                 if (cp >= eom) {
909                         free_related_additional();
910                         if (flushset != NULL)
911                                 free_flushset(flushset, flushset_size);
912                         formerrmsg = outofDataFinal;
913                         goto formerr;
914                 }
915                 n = rrextract(msg, msglen, cp, &dp, name, sizeof name, from,
916                               &tname);
917                 if (n < 0) {
918                         free_related_additional();
919                         freestr_maybe(&tname);
920                         if (flushset != NULL)
921                                 free_flushset(flushset, flushset_size);
922                         formerrmsg = outofDataFinal;
923                         if (hp->rcode == REFUSED)
924                                 goto refused;
925                         else
926                                 goto formerr;
927                 }
928                 cp += n;
929                 if (!dp)
930                         continue;
931                 type = dp->d_type;
932                 if (i < ancount) {
933                         /* Answer section. */
934                         if (externalcname || ns_samename(name, aname) != 1) {
935                                 if (!externalcname)
936                                         ns_info(ns_log_resp_checks,
937                                                 "wrong ans. name (%s != %s)",
938                                                 name[0] ? name : ".", 
939                                                 aname[0] ? aname : ".");
940                                 else
941                                         ns_debug(ns_log_resp_checks, 3,
942                                  "ignoring answer '%s' after external cname",
943                                                  name);
944                                 db_freedata(dp);
945                                 continue;
946                         }
947                         if (type == T_CNAME &&
948                             qtype != T_CNAME && qtype != T_ANY) {
949                                 strcpy(aname, (char *)dp->d_data);
950                                 if (!ns_samedomain(aname, qp->q_domain))
951                                         externalcname = 1;
952                                 cname++;
953                                 lastwascname = 1;
954                         } else {
955                                 validanswer = 1;
956                                 lastwascname = 0;
957                         }
958
959                         if (tname != NULL) {
960                                 add_related_additional(tname);
961                                 tname = NULL;
962                         }
963
964                         dp->d_cred = (hp->aa && ns_samename(name, qname) == 1)
965                                 ? DB_C_AUTH
966                                 : DB_C_ANSWER;
967                 } else {
968                         /* After answer section. */
969                         if (lastwascname) {
970                                 ns_debug(ns_log_resp_checks, 3,
971                                  "last was cname, ignoring auth. and add.");
972                                 db_freedata(dp);
973                                 break;
974                         }
975                         if (i < arfirst) {
976                                 /* Authority section. */
977                                 switch (type) {
978                                 case T_NS:
979                                 case T_SOA:
980                                         if (!ns_samedomain(aname, name)) {
981                                                 ns_info(ns_log_resp_checks,
982                                                     "bad referral (%s !< %s)",
983                                                         aname[0] ? aname : ".",
984                                                         name[0] ? name : ".");
985                                                 db_freedata(dp);
986                                                 continue;
987                                         } else if (!ns_samedomain(name,
988                                                                qp->q_domain)) {
989                                                 if (!externalcname)
990                                                     ns_info(ns_log_resp_checks,
991                                                     "bad referral (%s !< %s)",
992                                                          name[0] ? name : ".",
993                                                          qp->q_domain[0] ?
994                                                          qp->q_domain : ".");
995                                                 db_freedata(dp);
996                                                 continue;
997                                         }
998                                         if (type == T_NS) {
999                                                 nscount++;
1000                                                 add_related_additional(tname);
1001                                                 tname = NULL;
1002                                         }
1003                                         if (type == T_SOA) {
1004                                                 soacount++;
1005                                         }
1006                                         break;
1007                                 case T_NXT:
1008                                         /* XXX check */
1009                                         break;
1010                                 case T_SIG:
1011                                         /* XXX check that it relates to an
1012                                            NS or SOA or NXT */
1013                                         break;
1014                                 default:
1015                                         ns_info(ns_log_resp_checks,
1016         "invalid RR type '%s' in authority section (name = '%s') from %s",
1017                                                 p_type(type), name,
1018                                                 sin_ntoa(from));
1019                                         db_freedata(dp);
1020                                         continue;
1021                                 }
1022                                 dp->d_cred = (hp->aa && (cname == 0)) ?
1023                                         DB_C_AUTH : (qp->q_flags & Q_PRIMING)
1024                                                 ? DB_C_ANSWER
1025                                                 : DB_C_ADDITIONAL;
1026                         } else {
1027                                 /* Additional section. */
1028                                 switch (type) {
1029                                 case T_A:
1030                                 case T_AAAA:
1031                                         if (externalcname ||
1032                                             !ns_samedomain(name, qp->q_domain)) {
1033                                                 ns_debug(ns_log_resp_checks, 3,
1034                                        "ignoring additional info '%s' type %s",
1035                                                          name, p_type(type));
1036                                                 db_freedata(dp);
1037                                                 continue;
1038                                         }
1039                                         if (!related_additional(name)) {
1040                                                 ns_info(ns_log_resp_checks,
1041                              "unrelated additional info '%s' type %s from %s",
1042                                                          name, p_type(type),
1043                                                          sin_ntoa(from));
1044                                                 db_freedata(dp);
1045                                                 continue;
1046                                         }
1047                                         break;
1048                                 case T_KEY:
1049                                         /* XXX  check? */
1050                                         break;
1051                                 case T_SIG:
1052                                         /*
1053                                          * XXX  a SIG RR should relate
1054                                          * to some other RR in this section,
1055                                          * although if it's the last RR
1056                                          * it might be a transaction signature.
1057                                          */
1058                                         break;
1059                                 default:
1060                                         ns_info(ns_log_resp_checks,
1061         "invalid RR type '%s' in additional section (name = '%s') from %s",
1062                                                 p_type(type), name,
1063                                                 sin_ntoa(from));
1064                                         db_freedata(dp);
1065                                         continue;
1066                                 }
1067                                 dp->d_cred = (qp->q_flags & Q_PRIMING)
1068                                         ? DB_C_ANSWER
1069                                         : DB_C_ADDITIONAL;
1070                         }
1071                 }
1072                 rrsetadd(flushset, name, dp);
1073         }
1074         free_related_additional();
1075         freestr_maybe(&tname);
1076         if (flushset != NULL) {
1077                 if ((qp->q_flags & Q_SYSTEM) && (qp->q_flags & Q_PRIMING)) {
1078                         check_hints(flushset); /* before rrsetupdate */
1079                         rrsetupdate(flushset, dbflags, from, 1);
1080                 } else
1081                         rrsetupdate(flushset, dbflags, from, 0);
1082                 free_flushset(flushset, flushset_size);
1083         }
1084         if (lastwascname && !externalcname)
1085                 ns_debug(ns_log_cname, 3, "%s (%s) q(%s %s %s) %s qd(%s)",
1086                         danglingCname, aname,
1087                         (qname && *qname) ? qname : ".",
1088                         p_class(qclass), p_type(qtype),
1089                         sin_ntoa(from), qp->q_domain);
1090
1091         if (cp > eom) {
1092                 formerrmsg = outofDataAFinal;
1093                 goto formerr;
1094         }
1095
1096         if ((qp->q_flags & Q_SYSTEM) && ancount) {
1097                 if ((qp->q_flags & Q_PRIMING) && !check_root()) {
1098                         /* mark server as bad */
1099                         mark_bad(qp, from);
1100                         fast_retry(qp, from);
1101                         return;
1102                 }
1103                 ns_debug(ns_log_default, 3,
1104                          "resp: leaving, SYSQUERY ancount %d", ancount);
1105 #ifdef BIND_NOTIFY
1106                 if (qp->q_notifyzone != DB_Z_CACHE) {
1107                         struct zoneinfo *zp = &zones[qp->q_notifyzone];
1108
1109                         qp->q_notifyzone = DB_Z_CACHE;
1110                         ns_notify(zp->z_origin, zp->z_class, ns_t_soa);
1111                 }
1112 #endif
1113                 qremove(qp);
1114                 return;
1115         }
1116
1117         if (ancount && count && !validanswer) {
1118                 /*
1119                  * Everything passed validation but we didn't get the
1120                  * final answer.  The response must have contained
1121                  * a dangling CNAME.  Force a restart of the query.
1122                  *
1123                  * Don't set restart if count==0, since this means
1124                  * the response was truncated in the answer section,
1125                  * causing us to set count to 0 which will cause
1126                  * validanswer to be 0 as well even though the answer
1127                  * section probably contained valid RRs (just not
1128                  * a complete set).
1129                  * XXX - this works right if we can just forward this
1130                  * response to the client, but not if we found a CNAME
1131                  * in a prior response and restarted the query.
1132                  */
1133                 restart = 1;
1134         }
1135
1136         if (!restart && !qp->q_cmsglen && ancount > 1 && qtype == T_A)
1137                 sort_response(tp, eom, ancount, &qp->q_from);
1138
1139         /*
1140          * An answer to a T_ANY query or a successful answer to a
1141          * regular query with no indirection, then just return answer.
1142          */
1143         if (!restart && ancount && (qtype == T_ANY || !qp->q_cmsglen)) {
1144                 ns_debug(ns_log_default, 3,
1145                          "resp: got as much answer as there is");
1146                 goto return_msg;
1147         }
1148
1149         /*
1150          * We might want to cache this negative answer.
1151          *
1152          * if ancount != 0 and rcode == NOERROR we cannot determine if the
1153          * CNAME chain has been processed to completion or not, so just
1154          * restart the query. DNS needs a NODATA return code!
1155          *
1156          * As some servers incorrectly return a NODATA indication when
1157          * there is a CNAME chain instead of NXDOMAIN, we requery to get
1158          * a definitive answer.
1159          */
1160         if ((hp->rcode == NXDOMAIN && cname == ancount) ||
1161             (hp->rcode == NOERROR && ancount == 0 && 
1162              (nscount == 0 || soacount != 0)
1163              )
1164             )
1165         {
1166                 cache_n_resp(msg, msglen, from, qp->q_name,
1167                              qp->q_class, qp->q_type);
1168
1169                 if (!qp->q_cmsglen) {
1170                         ns_debug(ns_log_default, 3,
1171                                  "resp: leaving NO: auth = %d", hp->aa);
1172                         goto return_msg;
1173                 }
1174                 forcecmsg = 1;
1175         }
1176
1177         /*
1178          * All messages in here need further processing.  i.e. they
1179          * are either CNAMEs or we got referred again.
1180          */
1181         count = 0;
1182         founddata = 0;
1183         dname = name;
1184         /*
1185          * If restart==0 and ancount > 0, we should
1186          * have some valid data because because the data in the answer
1187          * section is owned by the query name and that passes the
1188          * validation test by definition
1189          *
1190          * XXX - the restart stuff doesn't work if any of the answer RRs
1191          * is not cacheable (TTL==0 or unknown RR type), since all of the
1192          * answer must pass through the cache and be re-assembled.
1193          */
1194         if ((forcecmsg && qp->q_cmsglen) ||
1195             ((!restart || !cname) && qp->q_cmsglen && ancount)) {
1196                 ns_debug(ns_log_default, 1, "Cname second pass");
1197                 newmsglen = MIN(PACKETSZ, qp->q_cmsglen);
1198                 memcpy(newmsg, qp->q_cmsg, newmsglen);
1199         } else {
1200                 newmsglen = MIN(PACKETSZ, msglen);
1201                 memcpy(newmsg, msg, newmsglen);
1202         }
1203         hp = (HEADER *) newmsg;
1204         hp->ancount = htons(0);
1205         hp->nscount = htons(0);
1206         hp->arcount = htons(0);
1207         hp->rcode = NOERROR;
1208         dnptrs[0] = newmsg;
1209         dnptrs[1] = NULL;
1210         cp = newmsg + HFIXEDSZ;
1211         /*
1212          * Keep in mind that none of this code works when QDCOUNT>1.
1213          * cp ends up pointed just past the query section in both cases.
1214          */
1215         /*
1216          * Arrange for dname to contain the query name. The query
1217          * name can be either the original query name if restart==0
1218          * or the target of the last CNAME if we are following a
1219          * CNAME chain and were referred.
1220          */
1221         n = dn_expand(newmsg, newmsg + newmsglen, cp, dname, sizeof name);
1222         if (n < 0) {
1223                 ns_debug(ns_log_default, 1, "dn_expand failed");
1224                 goto servfail;
1225         }
1226         if (!res_dnok(dname)) {
1227                 ns_debug(ns_log_default, 1, "bad name (%s)", dname);
1228                 goto servfail;
1229         }
1230         cp += n + QFIXEDSZ;
1231         buflen = sizeof(newmsg) - (cp - newmsg);
1232
1233         cname = 0;
1234
1235  try_again:
1236         ns_debug(ns_log_default, 1, "resp: nlookup(%s) qtype=%d", dname,
1237                  qtype);
1238         foundname = 0;
1239         fname = "";
1240         htp = hashtab;          /* lookup relative to root */
1241         np = nlookup(dname, &htp, &fname, 0);
1242         ns_debug(ns_log_default, 1, "resp: %s '%s' as '%s' (cname=%d)",
1243                  np == NULL ? "missed" : "found", dname, fname, cname);
1244         if (np == NULL || fname != dname)
1245                 goto fetch_ns;
1246
1247         foundname++;
1248         answers = cp;
1249         count = cp - newmsg;
1250         /*
1251          * Look for NXDOMAIN record.
1252          */
1253         for (dp = np->n_data; dp; dp = dp->d_next) {
1254                 if (!stale(dp) && (dp->d_rcode == NXDOMAIN) &&
1255                     (dp->d_class == (int)qclass)) {
1256 #ifdef RETURNSOA
1257                         n = finddata(np, qclass, T_SOA, hp, &dname,
1258                                      &buflen, &count);
1259                         if ( n != 0) {
1260                                 if (count) {
1261                                         cp += n;
1262                                         buflen -= n;
1263                                         newmsglen += n;
1264                                         hp->nscount = htons((u_int16_t)count);
1265                                 }
1266                                 if (hp->rcode == NOERROR_NODATA) {
1267                                         hp->rcode = NOERROR;
1268                                         goto return_newmsg;
1269                                 }
1270                         }
1271 #else
1272                         count = 0;
1273 #endif
1274                         hp->rcode = NXDOMAIN;
1275                         /* 
1276                          * XXX forcing AA all the time isn't right, but
1277                          * we have to work that way by default
1278                          * for compatibility with older servers.
1279                          */
1280                         if (!NS_OPTION_P(OPTION_NONAUTH_NXDOMAIN))
1281                                 hp->aa = 1;
1282                         ns_debug(ns_log_default, 3, "resp: NXDOMAIN aa = %d",
1283                                  hp->aa);
1284                         if ((count == 0) || NS_OPTION_P(OPTION_NORFC2308_TYPE1))
1285                                 goto return_newmsg;
1286                         founddata = 1;
1287                         goto fetch_ns;
1288                 }
1289         }
1290         n = finddata(np, qclass, qtype, hp, &dname, &buflen, &count);
1291         if (n == 0)
1292                 goto fetch_ns;          /* NO data available */
1293         if (hp->rcode) {
1294                 if (hp->rcode == NOERROR_NODATA)
1295                         hp->rcode = NOERROR;
1296 #ifdef RETURNSOA
1297                 if (count) {
1298                         cp += n;
1299                         buflen -= n;
1300                         hp->nscount = htons((u_int16_t)count);
1301                 }
1302 #endif
1303                 if ((count == 0) || NS_OPTION_P(OPTION_NORFC2308_TYPE1))
1304                         goto return_newmsg;
1305                 founddata = 1;
1306                 goto fetch_ns;
1307         }
1308         cp += n;
1309         buflen -= n;
1310         hp->ancount = htons(ntohs(hp->ancount) + (u_int16_t)count);
1311         if (fname != dname && qtype != T_CNAME && qtype != T_ANY) {
1312                 cname++;
1313                 goto try_again;
1314         }
1315         founddata = 1;
1316
1317         ns_debug(ns_log_default, 3,
1318                  "resp: foundname=%d, count=%d, founddata=%d, cname=%d",
1319                  foundname, count, founddata, cname);
1320
1321         if (count > 1 && qtype == T_A)
1322                 sort_response(answers, cp, count, &qp->q_from);
1323
1324  fetch_ns:
1325         if (hp->tc)
1326                 goto return_newmsg;
1327
1328         /*
1329          * Look for name servers to refer to and fill in the authority
1330          * section or record the address for forwarding the query
1331          * (recursion desired).
1332          */
1333         free_nsp(nsp);
1334         switch (findns(&np, qclass, nsp, &count, 0)) {
1335         case NXDOMAIN:          /* shouldn't happen */
1336                 ns_debug(ns_log_default, 3, "req: leaving (%s, rcode %d)",
1337                          dname, hp->rcode);
1338                 if (!foundname)
1339                         hp->rcode = NXDOMAIN;
1340                 if (qclass != C_ANY) {
1341                         hp->aa = 1;
1342                         if (np && (!foundname || !founddata)) {
1343                                 n = doaddauth(hp, cp, buflen, np, nsp[0]);
1344                                 cp += n;
1345                                 buflen -= n;
1346                         }
1347                 }
1348                 goto return_newmsg;
1349
1350         case SERVFAIL:
1351                 goto servfail;
1352         }
1353
1354         if (founddata) {
1355                 hp = (HEADER *)newmsg;
1356                 n = add_data(np, nsp, cp, buflen, &count);
1357                 if (n < 0) {
1358                         hp->tc = 1;
1359                         n = (-n);
1360                 }
1361                 cp += n;
1362                 buflen -= n;
1363                 hp->nscount = htons((u_int16_t)count + ntohs(hp->nscount));
1364                 goto return_newmsg;
1365         }
1366
1367         /*
1368          *  If we get here, we don't have the answer yet and are about
1369          *  to iterate to try and get it.  First, infinite loop avoidance.
1370          */
1371         if (qp->q_nqueries++ > MAXQUERIES) {
1372                 ns_debug(ns_log_default, 1,
1373                          "resp: MAXQUERIES exceeded (%s %s %s)",
1374                          dname, p_class(qclass), p_type(qtype));
1375                 ns_info(ns_log_default,
1376                    "MAXQUERIES exceeded, possible data loop in resolving (%s)",
1377                         dname);
1378                 goto servfail;
1379         }
1380
1381         /* Reset the query control structure */
1382
1383         ns_freeqns(qp, "ns_resp");
1384         qp->q_naddr = 0;
1385         qp->q_curaddr = 0;
1386         nsfwdadd(qp, NS_ZFWDTAB(qp->q_fzone));
1387
1388         if (qp->q_domain != NULL)
1389                 freestr(qp->q_domain);
1390         getname(np, tmpdomain, sizeof tmpdomain);
1391         qp->q_domain = savestr(tmpdomain, 1);
1392
1393         if (NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY))
1394                 n = 0;
1395         else if ((n = nslookup(nsp, qp, dname, "ns_resp")) <= 0) {
1396                 if (n < 0) {
1397                         if (n == -1)
1398                                 ns_debug(ns_log_default, 3,
1399                                          "resp: nslookup reports danger");
1400                         if (cname) /* a remote CNAME that does not have data */
1401                                 goto return_newmsg;
1402                         goto servfail;
1403                 } else {
1404                         ns_debug(ns_log_default, 3,
1405                                  "resp: no addrs found for NS's");
1406                         /*
1407                          * Timeout while sysquery looks up the NS addresses.
1408                          *
1409                          * Hopefully we'll have them when the client asks
1410                          * again.
1411                          *
1412                          * too bad we can't just wait for the sysquery
1413                          * response to restart this query (it's too hard).
1414                          *
1415                          * We could try to crawl back up the tree looking
1416                          * for reachable servers, but we may have just
1417                          * gotten delegated down here by a response with
1418                          * no A RRs for the servers.  If we blindly tried
1419                          * this strategy, we bang on the same server forever.
1420                          */
1421                         goto timeout;
1422                 }
1423         }
1424         for (n = 0; (u_int)n < qp->q_naddr; n++)
1425                 qp->q_addr[n].stime.tv_sec = 0;
1426         qp->q_addr[0].stime = tt;
1427         if (cname) {
1428                 if (qp->q_cname++ == MAXCNAMES) {
1429                         ns_debug(ns_log_default, 3,
1430                                  "resp: leaving, MAXCNAMES exceeded");
1431                         goto servfail;
1432                 }
1433                 ns_debug(ns_log_default, 1, "q_cname = %d", qp->q_cname);
1434                 ns_debug(ns_log_default, 3,
1435                          "resp: building recursive query; nslookup");
1436                 if (qp->q_cmsg == NULL) {
1437                         qp->q_cmsg = qp->q_msg;
1438                         qp->q_cmsglen = qp->q_msglen;
1439                         qp->q_cmsgsize = qp->q_msgsize;
1440                 } else if (qp->q_msg != NULL)
1441                         memput(qp->q_msg, qp->q_msgsize);
1442                 qp->q_msg = (u_char *)memget(PACKETSZ);
1443                 if (qp->q_msg == NULL) {
1444                         ns_notice(ns_log_default, "resp: memget error");
1445                         goto servfail;
1446                 }
1447                 qp->q_msgsize = PACKETSZ;
1448                 n = res_nmkquery(&res, QUERY, dname, qclass, qtype,
1449                                  NULL, 0, NULL, qp->q_msg, PACKETSZ);
1450                 if (n < 0) {
1451                         ns_info(ns_log_default, "resp: res_mkquery(%s) failed",
1452                                 dname);
1453                         goto servfail;
1454                 }
1455                 if (qp->q_name != NULL)
1456                         freestr(qp->q_name);
1457                 qp->q_name = savestr(dname, 1);
1458                 qp->q_msglen = n;
1459                 hp = (HEADER *) qp->q_msg;
1460                 hp->rd = 0;
1461         } else
1462                 hp = (HEADER *) qp->q_msg;
1463         hp->id = qp->q_nsid = htons(nsid_next());
1464         if (qp->q_addr[0].forwarder)
1465                 hp->rd = 1;
1466         unsched(qp);
1467         schedretry(qp, retrytime(qp));
1468         nsa = Q_NEXTADDR(qp, 0);
1469         if (ns_wouldlog(ns_log_default,1)) {
1470             ns_debug(ns_log_default, 1,
1471                      "resp: forw -> %s ds=%d nsid=%d id=%d %dms",
1472                      sin_ntoa(*nsa), ds,
1473                      ntohs(qp->q_nsid), ntohs(qp->q_id),
1474                      (qp->q_addr[0].nsdata != NULL)
1475                             ? qp->q_addr[0].nsdata->d_nstime
1476                             : -1);
1477         }
1478 #ifdef DEBUG
1479         if (debug >= 10)
1480                 res_pquery(&res, qp->q_msg, qp->q_msglen,
1481                            log_get_stream(packet_channel));
1482 #endif
1483         key = tsig_key_from_addr(nsa->sin_addr);
1484         if (key != NULL) {
1485                 smsgsize = qp->q_msglen + TSIG_BUF_SIZE;
1486                 smsg = memget(smsgsize);
1487                 smsglen = qp->q_msglen;
1488                 siglen = sizeof(sig);
1489                 memcpy(smsg, qp->q_msg, qp->q_msglen);
1490                 n = ns_sign(smsg, &smsglen, smsgsize, NOERROR, key, NULL, 0,
1491                             sig, &siglen, 0);
1492                 if (n == 0) {
1493                         oldqbuf = qp->q_msg;
1494                         oldqlen = qp->q_msglen;
1495                         qp->q_msglen = smsglen;
1496                         qp->q_msg = smsg;
1497                         has_tsig = 1;
1498                         qp->q_nstsig = new_tsig(key, sig, siglen);
1499                 }
1500                 else {
1501                         has_tsig = 0;
1502                         free_tsig(qp->q_nstsig);
1503                         qp->q_nstsig = NULL;
1504                         INSIST(0);
1505                 }
1506         }
1507         else {
1508                 has_tsig = 0;
1509                 free_tsig(qp->q_nstsig);
1510                 qp->q_nstsig = NULL;
1511         }
1512
1513         if (qp->q_flags & Q_USEVC) {
1514                 if (tcp_send(qp) != NOERROR) {
1515                         if (!haveComplained(ina_ulong(nsa->sin_addr),
1516                                             (u_long)tcpsendStr))
1517                                 ns_info(ns_log_default,
1518                                         "ns_forw: tcp_send(%s) failed: %s",
1519                                         sin_ntoa(*nsa), strerror(errno));
1520                 }
1521         } else if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
1522                    (struct sockaddr *)nsa,
1523                    sizeof(struct sockaddr_in)) < 0)
1524         {
1525                 sendto_errno = errno;
1526                 if (!haveComplained(ina_ulong(nsa->sin_addr),
1527                                     (u_long)sendtoStr))
1528                         ns_info(ns_log_default, "ns_resp: sendto(%s): %s",
1529                                 sin_ntoa(*nsa), strerror(errno));
1530                 nameserIncr(nsa->sin_addr, nssSendtoErr);
1531         }
1532         if (has_tsig == 1) {
1533                 memput(qp->q_msg, smsgsize);
1534                 qp->q_msg = oldqbuf;
1535                 qp->q_msglen = oldqlen;
1536         }
1537         hp->rd = 0;     /* leave set to 0 for dup detection */
1538         nameserIncr(nsa->sin_addr, nssSentFwdR);
1539         nameserIncr(qp->q_from.sin_addr, nssRcvdFwdR);
1540         ns_debug(ns_log_default, 3, "resp: Query sent.");
1541         free_nsp(nsp);
1542         switch (sendto_errno) {
1543         case ENETDOWN:
1544         case ENETUNREACH:
1545         case EHOSTDOWN:
1546         case EHOSTUNREACH:
1547                 unsched(qp);
1548                 schedretry(qp, (time_t) 0);
1549         }
1550         return;
1551
1552  formerr:
1553         if (!haveComplained(ina_ulong(from.sin_addr), (u_long)formerrmsg))
1554                 ns_info(ns_log_resp_checks, "Malformed response from %s (%s)",
1555                         sin_ntoa(from), formerrmsg);
1556         fast_retry(qp, from);
1557         free_nsp(nsp);
1558         return;
1559
1560  return_msg:
1561         nameserIncr(from.sin_addr, nssRcvdFwdR);
1562         nameserIncr(qp->q_from.sin_addr, nssSentFwdR);
1563         /* The "standard" return code */
1564         hp->qr = 1;
1565         hp->id = qp->q_id;
1566         hp->rd = 1;
1567         hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
1568         (void) send_msg(msg, msglen, qp);
1569         qremove(qp);
1570         free_nsp(nsp);
1571         return;
1572
1573  return_newmsg:
1574         nameserIncr(qp->q_from.sin_addr, nssSentAns);
1575
1576         if (!hp->aa)
1577                 nameserIncr(qp->q_from.sin_addr, nssSentNaAns);
1578         if (hp->rcode == NXDOMAIN) 
1579                 nameserIncr(qp->q_from.sin_addr, nssSentNXD);
1580         n = doaddinfo(hp, cp, buflen);
1581         cp += n;
1582         buflen -= n;
1583         hp->qr = 1;
1584         hp->id = qp->q_id;
1585         hp->rd = 1;
1586         hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
1587         (void) send_msg(newmsg, cp - newmsg, qp);
1588         qremove(qp);
1589         free_nsp(nsp);
1590         return;
1591
1592  refused:
1593         hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
1594         hp->rcode = REFUSED;
1595         hp->qr = 1;
1596         hp->id = qp->q_id;
1597         hp->rd = 1;
1598         hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
1599         (void) send_msg((u_char *)hp,
1600                         (qp->q_cmsglen ? qp->q_cmsglen : qp->q_msglen),
1601                         qp);
1602         qremove(qp);
1603         free_nsp(nsp);
1604         return;
1605         
1606  servfail:
1607         nameserIncr(qp->q_from.sin_addr, nssSentFail);
1608         hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
1609         hp->rcode = SERVFAIL;
1610         hp->qr = 1;
1611         hp->id = qp->q_id;
1612         hp->rd = 1;
1613         hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
1614         (void) send_msg((u_char *)hp,
1615                         (qp->q_cmsglen ? qp->q_cmsglen : qp->q_msglen),
1616                         qp);
1617         qremove(qp);
1618         free_nsp(nsp);
1619         return;
1620
1621  timeout:
1622         if (qp->q_stream)
1623                 sq_remove(qp->q_stream);
1624         qremove(qp);
1625         free_nsp(nsp);
1626         return;
1627 }
1628
1629 #define BOUNDS_CHECK(ptr, count) \
1630         do { \
1631                 if ((ptr) + (count) > eom) { \
1632                         hp->rcode = FORMERR; \
1633                         return (-1); \
1634                 } \
1635         } while (0)
1636
1637 static int
1638 rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
1639           char *dname, int namelen, struct sockaddr_in from, char **tnamep)
1640 {
1641         u_char *cp, *eom, *rdatap;
1642         u_int class, type, dlen;
1643         int n, n1, n2;
1644         u_int32_t ttl;
1645         u_char *cp1, data[MAXDATA*2];
1646         HEADER *hp = (HEADER *)msg;
1647         enum context context;
1648
1649         if (tnamep != NULL)
1650                 *tnamep = NULL;
1651
1652         *dpp = NULL;
1653         cp = rrp;
1654         eom = msg + msglen;
1655         if ((n = dn_expand(msg, eom, cp, dname, namelen)) < 0) {
1656                 hp->rcode = FORMERR;
1657                 return (-1);
1658         }
1659         cp += n;
1660         BOUNDS_CHECK(cp, 2*INT16SZ + INT32SZ + INT16SZ);
1661         GETSHORT(type, cp);
1662         GETSHORT(class, cp);
1663         if (class > CLASS_MAX) {
1664                 ns_debug(ns_log_default, 3, "bad class in rrextract");
1665                 hp->rcode = FORMERR;
1666                 return (-1);
1667         }
1668         GETLONG(ttl, cp);
1669         if (ttl > MAXIMUM_TTL) {
1670                 ns_debug(ns_log_default, 5, "%s: converted TTL > %u to 0",
1671                          dname, MAXIMUM_TTL);
1672                 ttl = 0;
1673         }
1674         GETSHORT(dlen, cp);
1675         BOUNDS_CHECK(cp, dlen);
1676         rdatap = cp;
1677         if (!ns_nameok(NULL, dname, class, NULL, response_trans,
1678                        ns_ownercontext(type, response_trans),
1679                        dname, from.sin_addr)) {
1680                 hp->rcode = REFUSED;
1681                 return (-1);
1682         }
1683         ns_debug(ns_log_default, 3,
1684                  "rrextract: dname %s type %d class %d ttl %d",
1685                  dname, type, class, ttl);
1686         /*
1687          * Convert the resource record data into the internal
1688          * database format.
1689          *
1690          * On entry to the switch:
1691          *   CP points to the RDATA section of the wire-format RR.
1692          *   DLEN is its length.
1693          *   The memory area at DATA is available for processing.
1694          * 
1695          * On exit from the switch:
1696          *   CP has been incremented past the RR.
1697          *   CP1 points to the RDATA section of the database-format RR.
1698          *   N contains the length of the RDATA section of the dbase-format RR.
1699          *
1700          * The new data at CP1 for length N will be copied into the database,
1701          * so it need not be in any particular storage location.
1702          */
1703         switch (type) {
1704         case T_A:
1705                 if (dlen != INT32SZ) {
1706                         hp->rcode = FORMERR;
1707                         return (-1);
1708                 }
1709                 /*FALLTHROUGH*/
1710         case T_WKS:
1711         case T_HINFO:
1712         case T_TXT:
1713         case T_X25:
1714         case T_ISDN:
1715         case T_NSAP:
1716         case T_AAAA:
1717         case T_LOC:
1718         case T_KEY:
1719         case ns_t_cert:
1720                 cp1 = cp;
1721                 n = dlen;
1722                 cp += n;
1723                 break;
1724
1725         case T_CNAME:
1726         case T_MB:
1727         case T_MG:
1728         case T_MR:
1729         case T_NS:
1730         case T_PTR:
1731                 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
1732                 if (n < 0) {
1733                         hp->rcode = FORMERR;
1734                         return (-1);
1735                 }
1736                 if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans,
1737                                type == T_PTR ?ns_ptrcontext(dname) :domain_ctx,
1738                                dname, from.sin_addr)) {
1739                         hp->rcode = FORMERR;
1740                         return (-1);
1741                 }
1742                 cp += n;
1743                 cp1 = data;
1744                 n = strlen((char *)data) + 1;
1745                 if (tnamep != NULL && (type == T_NS || type == T_MB))
1746                         *tnamep = savestr((char *)cp1, 1);
1747                 break;
1748
1749         case T_SOA:
1750                 context = hostname_ctx;
1751                 goto soa_rp_minfo;
1752         case T_RP:
1753         case T_MINFO:
1754                 context = mailname_ctx;
1755                 /* FALLTHROUGH */
1756         soa_rp_minfo:
1757                 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
1758                 if (n < 0) {
1759                         hp->rcode = FORMERR;
1760                         return (-1);
1761                 }
1762                 if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans,
1763                                context, dname, from.sin_addr)) {
1764                         hp->rcode = FORMERR;
1765                         return (-1);
1766                 }
1767                 cp += n;
1768                 /*
1769                  * The next use of 'cp' is dn_expand(), so we don't have
1770                  * to BOUNDS_CHECK() here.
1771                  */
1772                 cp1 = data + (n = strlen((char *)data) + 1);
1773                 n1 = sizeof(data) - n;
1774                 if (type == T_SOA)
1775                         n1 -= 5 * INT32SZ;
1776                 n = dn_expand(msg, eom, cp, (char *)cp1, n1);
1777                 if (n < 0) {
1778                         hp->rcode = FORMERR;
1779                         return (-1);
1780                 }
1781                 if (type == T_RP)
1782                         context = domain_ctx;
1783                 else
1784                         context = mailname_ctx;
1785                 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1786                                context, dname, from.sin_addr)) {
1787                         hp->rcode = FORMERR;
1788                         return (-1);
1789                 }
1790                 cp += n;
1791                 cp1 += strlen((char *)cp1) + 1;
1792                 if (type == T_SOA) {
1793                         n = 5 * INT32SZ;
1794                         BOUNDS_CHECK(cp, n);
1795                         memcpy(cp1, cp, n);
1796                         cp += n;
1797                         cp1 += n;
1798                 }
1799                 n = cp1 - data;
1800                 cp1 = data;
1801                 break;
1802
1803         case T_NAPTR:
1804                 /* Grab weight and port. */
1805                 BOUNDS_CHECK(cp, INT16SZ*2);
1806                 memcpy(data, cp, INT16SZ*2);
1807                 cp1 = data + INT16SZ*2;
1808                 cp += INT16SZ*2;
1809
1810                 /* Flags */
1811                 BOUNDS_CHECK(cp, 1);
1812                 n = *cp++;
1813                 BOUNDS_CHECK(cp, n);
1814                 *cp1++ = n;
1815                 memcpy(cp1, cp, n);
1816                 cp += n; cp1 += n;
1817
1818                 /* Service */
1819                 BOUNDS_CHECK(cp, 1);
1820                 n = *cp++;
1821                 BOUNDS_CHECK(cp, n);
1822                 *cp1++ = n;
1823                 memcpy(cp1, cp, n);
1824                 cp += n; cp1 += n;
1825
1826                 /* Regexp */
1827                 BOUNDS_CHECK(cp, 1);
1828                 n = *cp++;
1829                 BOUNDS_CHECK(cp, n);
1830                 *cp1++ = n;
1831                 memcpy(cp1, cp, n);
1832                 cp += n; cp1 += n;
1833
1834                 /* Replacement */
1835                 n = dn_expand(msg, eom, cp, (char *)cp1,
1836                               sizeof data - (cp1 - data));
1837                 if (n < 0) {
1838                         hp->rcode = FORMERR;
1839                         return (-1);
1840                 }
1841                 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1842                                hostname_ctx, dname, from.sin_addr)) {
1843                         hp->rcode = FORMERR;
1844                         return (-1);
1845                 }
1846                 cp += n;
1847
1848                 /* compute end of data */
1849                 cp1 += strlen((char *)cp1) + 1;
1850                 /* compute size of data */
1851                 n = cp1 - data;
1852                 cp1 = data;
1853                 break;
1854
1855         case T_MX:
1856         case T_AFSDB:
1857         case T_RT:
1858         case T_SRV:
1859                 /* grab preference */
1860                 BOUNDS_CHECK(cp, INT16SZ);
1861                 memcpy(data, cp, INT16SZ);
1862                 cp1 = data + INT16SZ;
1863                 cp += INT16SZ;
1864
1865                 if (type == T_SRV) {
1866                         /* Grab weight and port. */
1867                         BOUNDS_CHECK(cp, INT16SZ*2);
1868                         memcpy(cp1, cp, INT16SZ*2);
1869                         cp1 += INT16SZ*2;
1870                         cp += INT16SZ*2;
1871                 }
1872
1873                 /* get name */
1874                 n = dn_expand(msg, eom, cp, (char *)cp1,
1875                               sizeof data - (cp1 - data));
1876                 if (n < 0) {
1877                         hp->rcode = FORMERR;
1878                         return (-1);
1879                 }
1880                 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1881                                hostname_ctx, dname, from.sin_addr)) {
1882                         hp->rcode = FORMERR;
1883                         return (-1);
1884                 }
1885                 cp += n;
1886
1887                 if (tnamep != NULL)
1888                         *tnamep = savestr((char *)cp1, 1);
1889
1890                 /* compute end of data */
1891                 cp1 += strlen((char *)cp1) + 1;
1892                 /* compute size of data */
1893                 n = cp1 - data;
1894                 cp1 = data;
1895                 break;
1896
1897         case T_PX:
1898                 /* grab preference */
1899                 BOUNDS_CHECK(cp, INT16SZ);
1900                 memcpy(data, cp, INT16SZ);
1901                 cp1 = data + INT16SZ;
1902                 cp += INT16SZ;
1903
1904                 /* get MAP822 name */
1905                 n = dn_expand(msg, eom, cp, (char *)cp1,
1906                               sizeof data - INT16SZ);
1907                 if (n < 0) {
1908                         hp->rcode = FORMERR;
1909                         return (-1);
1910                 }
1911                 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1912                                domain_ctx, dname, from.sin_addr)) {
1913                         hp->rcode = FORMERR;
1914                         return (-1);
1915                 }
1916                 cp += n;
1917                 /*
1918                  * The next use of 'cp' is dn_expand(), so we don't have
1919                  * to BOUNDS_CHECK() here.
1920                  */
1921                 cp1 += (n = strlen((char *)cp1) + 1);
1922                 n1 = sizeof(data) - n;
1923                 n = dn_expand(msg, eom, cp, (char *)cp1, n1);
1924                 if (n < 0) {
1925                         hp->rcode = FORMERR;
1926                         return (-1);
1927                 }
1928                 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1929                                domain_ctx, dname, from.sin_addr)) {
1930                         hp->rcode = FORMERR;
1931                         return (-1);
1932                 }
1933                 cp += n;
1934                 cp1 += strlen((char *)cp1) + 1;
1935                 n = cp1 - data;
1936                 cp1 = data;
1937                 break;
1938
1939         case T_SIG: {
1940                 u_long origTTL, exptime, signtime, timetilexp, now;
1941                 u_int8_t alg;
1942
1943                 /* Check signature time, expiration, and adjust TTL.  */
1944                 /* This code is similar to that in db_load.c.  */
1945
1946                 /* Skip coveredType, save alg, skip labels */
1947                 BOUNDS_CHECK(cp, INT16SZ + 1 + 1 + 3*INT32SZ);
1948                 cp1 = cp + INT16SZ;
1949                 alg = *cp1++;
1950                 cp1++;
1951                 GETLONG(origTTL, cp1);
1952                 GETLONG(exptime, cp1);
1953                 GETLONG(signtime, cp1);
1954                 now = time(NULL);       /* Get current time in GMT/UTC */
1955
1956                 /* Don't let bogus name servers increase the signed TTL */
1957                 if (ttl > origTTL) {
1958                         ns_debug(ns_log_default, 3,
1959                                  "shrinking SIG TTL from %d to origTTL %d",
1960                                  ttl, origTTL);
1961                         ttl = origTTL;
1962                 }
1963
1964                 /* Don't let bogus signers "sign" in the future.  */
1965                 if (signtime > now) {
1966                         ns_debug(ns_log_default, 3,
1967                           "ignoring SIG: signature date %s is in the future",
1968                                  p_secstodate (signtime));
1969                         return ((cp - rrp) + dlen);
1970                 }
1971                 
1972                 /* Ignore received SIG RR's that are already expired.  */
1973                 if (exptime <= now) {
1974                         ns_debug(ns_log_default, 3,
1975                                 "ignoring SIG: expiration %s is in the past",
1976                                  p_secstodate (exptime));
1977                         return ((cp - rrp) + dlen);
1978                 }
1979
1980                 /* Lop off the TTL at the expiration time.  */
1981                 timetilexp = exptime - now;
1982                 if (timetilexp < ttl) {
1983                         ns_debug(ns_log_default, 3,
1984                                  "shrinking expiring %s SIG TTL from %d to %d",
1985                                  p_secstodate (exptime), ttl, timetilexp);
1986                         ttl = timetilexp;
1987                 }
1988
1989                 /* The following code is copied from named-xfer.c.  */
1990                 cp1 = (u_char *)data;
1991
1992                 /* first just copy over the type_covered, algorithm, */
1993                 /* labels, orig ttl, two timestamps, and the footprint */
1994                 BOUNDS_CHECK(cp, 18);
1995                 memcpy(cp1, cp, 18);
1996                 cp  += 18;
1997                 cp1 += 18;
1998
1999                 /* then the signer's name */
2000                 n = dn_expand(msg, eom, cp, (char *)cp1, (sizeof data) - 18);
2001                 if (n < 0 || n + NS_SIG_SIGNER > dlen) {
2002                         hp->rcode = FORMERR;
2003                         return (-1);
2004                 }
2005                 cp += n;
2006                 cp1 += strlen((char*)cp1)+1;
2007
2008                 /* finally, we copy over the variable-length signature.
2009                    Its size is the total data length, minus what we copied. */
2010                 n = dlen - (NS_SIG_SIGNER + n);
2011
2012                 if (n > (sizeof data) - (cp1 - (u_char *)data)) {
2013                         hp->rcode = FORMERR;
2014                         return (-1);  /* out of room! */
2015                 }
2016
2017                 switch (alg) {
2018                     case NS_ALG_MD5RSA:
2019                         if (n < NS_MD5RSA_MIN_SIZE || n > NS_MD5RSA_MAX_SIZE)
2020                                 hp->rcode = FORMERR;
2021                         break;
2022
2023                     case NS_ALG_DSA:
2024                         if (n != NS_DSA_SIG_SIZE)
2025                                 hp->rcode = FORMERR;
2026                         break;
2027
2028                     default:
2029                         break;
2030                 }
2031
2032                 if (hp->rcode == FORMERR)
2033                         return (-1);
2034
2035                 memcpy(cp1, cp, n);
2036                 cp += n;
2037                 cp1 += n;
2038                 
2039                 /* compute size of data */
2040                 n = cp1 - (u_char *)data;
2041                 cp1 = (u_char *)data;
2042                 break;
2043             }
2044
2045         case T_NXT:
2046                 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
2047                 /*
2048                  * By testing if n >= dlen, we are requiring that the type
2049                  * bitmap be at least one octet.  This is reasonable
2050                  * because we always have to look at the 0 bit to see if
2051                  * this is a "different format" NXT or not.
2052                  */
2053                 if (n < 0 || n >= dlen) {
2054                         hp->rcode = FORMERR;
2055                         return (-1);
2056                 }
2057                 if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans,
2058                                domain_ctx, dname, from.sin_addr)) {
2059                         hp->rcode = FORMERR;
2060                         return (-1);
2061                 }
2062                 cp += n;
2063                 n1 = strlen((char *)data) + 1;
2064                 cp1 = data + n1;
2065                 /*
2066                  * We don't need to BOUNDS_CHECK() cp here because we've
2067                  * previously checked that 'dlen' bytes are in bounds, and
2068                  * we know that n < dlen.
2069                  */
2070                 n2 = dlen - n;
2071                 /*
2072                  * The first bit of the first octet determines the format
2073                  * of the NXT record.  A format for types >= 128 has not
2074                  * yet been defined, so if bit zero is set, we just copy
2075                  * what's there because we don't understand it.
2076                  */
2077                 if ((*cp & 0x80) == 0) {
2078                         /*
2079                          * Bit zero is not set; this is an ordinary NXT
2080                          * record.  The bitmap must be at least 4 octets
2081                          * because the NXT bit should be set.  It should be
2082                          * less than or equal to 16 octets because this NXT
2083                          * format is only defined for types < 128.
2084                          */
2085                         if (n2 < 4 || n2 > 16) {
2086                                 hp->rcode = FORMERR;
2087                                 return (-1);
2088                         }
2089                 }
2090                 if (n2 > sizeof data - n1) {
2091                         hp->rcode = FORMERR;
2092                         return (-1);
2093                 }
2094                 memcpy(cp1, cp, n2);
2095                 cp += n2;
2096
2097                 /* compute size of data */
2098                 n = cp1 - (u_char *)data;
2099                 cp1 = (u_char *)data;
2100                 break;
2101         
2102         default:
2103                 ns_debug(ns_log_default, 3, "unknown type %d", type);
2104                 return ((cp - rrp) + dlen);
2105         }
2106
2107         if (cp > eom) {
2108                 hp->rcode = FORMERR;
2109                 return (-1);
2110         }
2111         if ((u_int)(cp - rdatap) != dlen) {
2112                 ns_debug(ns_log_default, 3,
2113                      "encoded rdata length is %u, but actual length was %u",
2114                          dlen, (u_int)(cp - rdatap));
2115                 hp->rcode = FORMERR;
2116                 return (-1);
2117         }
2118         if (n > MAXDATA) {
2119                 ns_debug(ns_log_default, 1,
2120                          "update type %d: %d bytes is too much data",
2121                          type, n);
2122                 hp->rcode = FORMERR;
2123                 return (-1);
2124         }
2125
2126         ttl += tt.tv_sec;
2127         *dpp = savedata(class, type, ttl, cp1, n);
2128         return (cp - rrp);
2129 }
2130
2131 int
2132 send_msg(u_char *msg, int msglen, struct qinfo *qp) {
2133         HEADER *hp = (HEADER *) msg;
2134         u_char *oldmsg;
2135         int oldlen;
2136         int msgsize;
2137         int ret;
2138
2139         if (qp->q_flags & Q_SYSTEM)
2140                 return (1);
2141         if (!qp->q_stream && (msglen > PACKETSZ))
2142                 msglen = trunc_adjust(msg, msglen, PACKETSZ);
2143         if (ns_wouldlog(ns_log_default, 1)) {
2144                 ns_debug(ns_log_default, 1, "send_msg -> %s (%s %d) id=%d",
2145                          sin_ntoa(qp->q_from), 
2146                          qp->q_stream == NULL ? "UDP" : "TCP",
2147                          qp->q_stream == NULL ? qp->q_dfd : qp->q_stream->s_rfd,
2148                          ntohs(qp->q_id));
2149         }
2150 #ifdef DEBUG
2151         if (ns_wouldlog(ns_log_default, 4)) {
2152                 struct qinfo *tqp;
2153
2154                 for (tqp = nsqhead; tqp != NULL; tqp = tqp->q_link) {
2155                         ns_debug(ns_log_default, 4,
2156                                  "qp %#lx q_id: %d  q_nsid: %d q_msglen: %d",
2157                                  (u_long)tqp, tqp->q_id,
2158                                  tqp->q_nsid, tqp->q_msglen);
2159                         ns_debug(ns_log_default, 4,
2160                                  "\tq_naddr: %d q_curaddr: %d",
2161                                  tqp->q_naddr, tqp->q_curaddr);
2162                         ns_debug(ns_log_default, 4,
2163                                  "\tq_next: %#lx q_link: %#lx",
2164                                  (u_long)qp->q_next, (u_long)qp->q_link);
2165                 }
2166         }
2167         if (debug >= 6)
2168                 res_pquery(&res, msg, msglen, log_get_stream(packet_channel));
2169 #endif /* DEBUG */
2170
2171         if (qp->q_tsig != NULL) {
2172                 u_char sig[TSIG_SIG_SIZE];
2173                 int siglen = sizeof(sig);
2174
2175                 oldmsg = msg;
2176                 oldlen = msglen;
2177
2178                 msgsize = msglen + TSIG_BUF_SIZE;
2179                 msg = memget(msgsize);
2180                 memcpy(msg, oldmsg, oldlen);
2181  
2182                 ret = ns_sign(msg, &msglen, msgsize, NOERROR, qp->q_tsig->key,
2183                               qp->q_tsig->sig, qp->q_tsig->siglen,
2184                               sig, &siglen, 0);
2185
2186                 if (ret != 0) {
2187                         INSIST(0);
2188                 }
2189         }
2190         
2191         if (qp->q_stream == NULL) {
2192                 /*
2193                  * Don't send FORMERR to these well known ports
2194                  * (loop avoidance).
2195                  */
2196                 switch (ntohs(qp->q_from.sin_port)) {
2197                 case 7: /* echo */
2198                 case 13: /* daytime */
2199                 case 19: /* chargen */
2200                 case 37: /* time */
2201                         if (hp->rcode == FORMERR)
2202                                 return (-1);
2203                 default:
2204                         break;
2205                 }
2206                 if (sendto(qp->q_dfd, (char*)msg, msglen, 0,
2207                            (struct sockaddr *)&qp->q_from,
2208                            sizeof(qp->q_from)) < 0) {
2209                         if (!haveComplained(ina_ulong(qp->q_from.sin_addr),
2210                                             (u_long)sendtoStr))
2211 #if defined(SPURIOUS_ECONNREFUSED)
2212                            if (errno != ECONNREFUSED)
2213 #endif
2214                                 ns_info(ns_log_default,
2215                                         "send_msg: sendto(%s): %s",
2216                                         sin_ntoa(qp->q_from),
2217                                         strerror(errno));
2218                         nameserIncr(qp->q_from.sin_addr, nssSendtoErr);
2219                         return (1);
2220                 }
2221         } else
2222                 writestream(qp->q_stream, (u_char*)msg, msglen);
2223
2224         if (qp->q_tsig != NULL) 
2225                 memput(msg, oldlen + TSIG_BUF_SIZE);
2226
2227         return (0);
2228 }
2229
2230 static int
2231 root_server_p(ns_class class) {
2232         struct zoneinfo *zp = find_zone("", class);
2233
2234         return (zp != NULL &&
2235                 (zp->z_type == z_master || zp->z_type == z_slave));
2236 }
2237
2238 void
2239 prime_cache(void) {
2240         int root = root_server_p(ns_c_in);
2241
2242         ns_debug(ns_log_default, 1, "prime_cache: priming = %d, root = %d",
2243                  priming, root);
2244         if (!priming && !root) {
2245                 struct qinfo *qp = sysquery("", ns_c_in, ns_t_ns,
2246                                             NULL, 0, ns_port, ns_o_query);
2247
2248                 if (qp != NULL) {
2249                         qp->q_flags |= (Q_SYSTEM | Q_PRIMING);
2250                         priming++;
2251                 }
2252         }
2253         needs_prime_cache = 0;
2254 }
2255
2256 struct qinfo *
2257 sysquery(const char *dname, int class, int type,
2258          struct in_addr *nss, int nsc, u_int16_t port, int opcode)
2259 {
2260         struct qinfo *qp, *oqp;
2261         HEADER *hp;
2262         char tmpdomain[MAXDNAME];
2263         struct namebuf *np = NULL;
2264         struct databuf *nsp[NSMAX];
2265         struct hashbuf *htp1;
2266         struct hashbuf *htp2;
2267         struct hashbuf *htp3;
2268         struct sockaddr_in *nsa;
2269         const char *fname;
2270         int n, count;
2271         int sendto_errno = 0;
2272         u_char *oldqbuf;
2273         int oldqlen, has_tsig;
2274         u_char *smsg;
2275         int smsglen, smsgsize, siglen;
2276         u_char sig[TSIG_SIG_SIZE];
2277         DST_KEY *key;
2278
2279         nsp[0] = NULL;
2280         ns_debug(ns_log_default, 3, "sysquery(%s, %d, %d, %#x, %d, %d)",
2281                  dname, class, type, nss, nsc, ntohs(port));
2282         qp = qnew(dname, class, type);
2283
2284         if (nss != NULL && nsc != 0)
2285                 np = NULL;
2286         else if (!NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) {
2287                 htp1 = hashtab;
2288                 htp2 = hashtab;
2289                 htp3 = fcachetab;
2290                 if (priming && dname[0] == '\0') {
2291                         np = NULL;
2292                 } else if (((np = nlookup(dname, &htp1, &fname, 0)) == NULL) &&
2293                            ((np = nlookup("", &htp2, &fname, 0)) == NULL) &&
2294                            ((np = nlookup("", &htp3, &fname, 0)) == NULL)) {
2295                         ns_info(ns_log_default,
2296                                 "sysquery: nlookup error on %s?",
2297                                 dname);
2298  err1:
2299                         ns_freeqry(qp);
2300                         return (NULL);
2301                 }
2302
2303                 n = findns(&np, class, nsp, &count, 0);
2304                 switch (n) {
2305                 case NXDOMAIN:
2306                 case SERVFAIL:
2307                         ns_info(ns_log_default,
2308                                 "sysquery: findns error (%s) on %s?",
2309                                 n == NXDOMAIN ? "NXDOMAIN" : "SERVFAIL",
2310                                 dname);
2311  err2:
2312                         free_nsp(nsp);
2313                         goto err1;
2314                 }
2315         }
2316
2317         /* Build new qinfo struct. */
2318         qp->q_cmsg = qp->q_msg = NULL;
2319         qp->q_dfd = ds;
2320         if (nss == NULL || nsc == 0)
2321                 nsfwdadd(qp, NS_ZFWDTAB(qp->q_fzone));
2322         qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2;
2323         qp->q_flags |= Q_SYSTEM;
2324
2325         getname(np, tmpdomain, sizeof tmpdomain);
2326         qp->q_domain = savestr(tmpdomain, 1);
2327
2328         if ((qp->q_msg = (u_char *)memget(PACKETSZ)) == NULL) {
2329                 ns_notice(ns_log_default, "sysquery: memget failed");
2330                 goto err2;
2331         }
2332         qp->q_msgsize = PACKETSZ;
2333         n = res_nmkquery(&res, opcode, dname, class,
2334                          type, NULL, 0, NULL,
2335                          qp->q_msg, PACKETSZ);
2336         if (n < 0) {
2337                 ns_info(ns_log_default,
2338                         "sysquery: res_mkquery(%s) failed", dname);
2339                 goto err2;
2340         }
2341         qp->q_msglen = n;
2342         hp = (HEADER *) qp->q_msg;
2343         hp->id = qp->q_nsid = htons(nsid_next());
2344         hp->rd = (qp->q_addr[qp->q_curaddr].forwarder ? 1 : 0);
2345
2346         /* First check for an already pending query for this data. */
2347         for (oqp = nsqhead; oqp != NULL; oqp = oqp->q_link) {
2348                 if ((oqp != qp)
2349                     && (oqp->q_msglen == qp->q_msglen)
2350                     && memcmp(oqp->q_msg+2, qp->q_msg + 2,
2351                               qp->q_msglen - 2) == 0
2352                     ) {
2353 #ifdef BIND_NOTIFY
2354                         /* XXX - need fancier test to suppress duplicate
2355                          *       NOTIFYs to the same server (compare nss?)
2356                          */
2357                         if (opcode != NS_NOTIFY_OP)
2358 #endif /*BIND_NOTIFY*/
2359                         {
2360                             ns_debug(ns_log_default, 3,
2361                                      "sysquery: duplicate");
2362                             goto err2;
2363                         }
2364                 }
2365         }
2366
2367         if (nss != NULL && nsc != 0) {
2368                 int i;
2369                 struct qserv *qs;
2370
2371                 for (i = 0, qs = qp->q_addr; i < nsc; i++, qs++) {
2372                         qs->ns_addr.sin_family = AF_INET;
2373                         qs->ns_addr.sin_addr = nss[i];
2374                         qs->ns_addr.sin_port = port;
2375                         qs->ns = NULL;
2376                         qs->nsdata = NULL;
2377                         qs->stime = tt;
2378                         qs->forwarder = 0;
2379                         qs->nretry = 0;
2380                 }
2381                 qp->q_naddr = nsc;
2382         } else if (!NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) {
2383  fetch_a:
2384                 count = nslookup(nsp, qp, dname, "sysquery");
2385                 if (count <= 0) {
2386                         if (count < 0) {
2387                                 if (n == -1)
2388                                         ns_info(ns_log_default,
2389                                       "sysquery: nslookup reports danger (%s)",
2390                                                 dname);
2391                                 goto err2;
2392                         } else if (np && NAME(*np)[0] == '\0') {
2393                                 /*
2394                                  * It's not too serious if we don't have
2395                                  * the root server addresses if we have to
2396                                  * go through a forwarder anyway.  Don't
2397                                  * bother to log it, since prime_cache()
2398                                  * won't do anything about it as currently
2399                                  * implemented.
2400                                  *
2401                                  * XXX - should we skip setting
2402                                  *       needs_prime_cache as well?
2403                                  *
2404                                  * XXX - what happens when we implement
2405                                  *       selective forwarding?
2406                                  */
2407                                 if (!NS_OPTION_P(OPTION_FORWARD_ONLY))
2408                                         ns_warning(ns_log_default,
2409                                    "sysquery: no addrs found for root NS (%s)",
2410                                                    dname);
2411                                 if (class == C_IN && !priming)
2412                                         needs_prime_cache = 1;
2413                                 goto err2;
2414                         }
2415                         if (np) {
2416                                 free_nsp(nsp);
2417                                 nsp[0] = NULL;
2418                                 np = np_parent(np);
2419                                 n = findns(&np, class, nsp, &count, 0);
2420                                 switch (n) {
2421                                 case NXDOMAIN: /*FALLTHROUGH*/
2422                                 case SERVFAIL:
2423                                         ns_info(ns_log_default,
2424                                           "sysquery: findns error (%d) on %s?",
2425                                                 n, dname);
2426                                         goto err2;
2427                                 }
2428                                 getname(np, tmpdomain, sizeof tmpdomain);
2429                                 if (qp->q_domain != NULL)
2430                                         freestr(qp->q_domain);
2431                                 qp->q_domain = savestr(tmpdomain, 1);
2432                                 goto fetch_a;
2433                         }
2434                         goto err2;
2435                 }
2436         }
2437
2438         schedretry(qp, retrytime(qp));
2439         qp->q_addr[0].stime = tt;       /* XXX - why not every? */
2440         nsa = Q_NEXTADDR(qp, 0);
2441
2442         ns_debug(ns_log_default, 1,
2443                  "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld",
2444                  sin_ntoa(*nsa), qp->q_dfd, 
2445                  ntohs(qp->q_nsid), ntohs(qp->q_id),
2446                  (long)qp->q_time);
2447 #ifdef DEBUG
2448         if (debug >= 10)
2449                 res_pquery(&res, qp->q_msg, qp->q_msglen,
2450                            log_get_stream(packet_channel));
2451 #endif
2452
2453         key = tsig_key_from_addr(nsa->sin_addr);
2454         if (key != NULL) {
2455                 smsgsize = qp->q_msglen + TSIG_BUF_SIZE;
2456                 smsg = memget(smsgsize);
2457                 smsglen = qp->q_msglen;
2458                 siglen = sizeof(sig);
2459                 memcpy(smsg, qp->q_msg, qp->q_msglen);
2460                 n = ns_sign(smsg, &smsglen, smsgsize, NOERROR, key, NULL, 0,
2461                             sig, &siglen, 0);
2462                 if (n == 0) {
2463                         oldqbuf = qp->q_msg;
2464                         oldqlen = qp->q_msglen;
2465                         qp->q_msglen = smsglen;
2466                         qp->q_msg = smsg;
2467                         has_tsig = 1;
2468                         qp->q_nstsig = new_tsig(key, sig, siglen); /* BEW? */
2469
2470                 }
2471                 else {
2472                         INSIST(0);
2473                         has_tsig = 0;
2474                         free_tsig(qp->q_nstsig);
2475                         qp->q_nstsig = NULL;
2476                 }
2477         }
2478         else {
2479                 has_tsig = 0;
2480                 free_tsig(qp->q_nstsig);
2481                 qp->q_nstsig = NULL;
2482         }
2483
2484         if (sendto(qp->q_dfd, (char*)qp->q_msg, qp->q_msglen, 0,
2485                    (struct sockaddr *)nsa,
2486                    sizeof(struct sockaddr_in)) < 0) {
2487                 sendto_errno = errno;
2488                 if (!haveComplained(ina_ulong(nsa->sin_addr),
2489                                     (u_long)sendtoStr))
2490                         ns_info(ns_log_default, "sysquery: sendto(%s): %s",
2491                                 sin_ntoa(*nsa), strerror(errno));
2492                 nameserIncr(nsa->sin_addr, nssSendtoErr);
2493         }
2494         if (has_tsig == 1) {
2495                 memput(qp->q_msg, smsgsize);
2496                 qp->q_msg = oldqbuf;
2497                 qp->q_msglen = oldqlen;
2498         }
2499
2500         nameserIncr(nsa->sin_addr, nssSentSysQ);
2501         free_nsp(nsp);
2502         switch (sendto_errno) {
2503         case ENETDOWN:
2504         case ENETUNREACH:
2505         case EHOSTDOWN:
2506         case EHOSTUNREACH:
2507                 unsched(qp);
2508                 schedretry(qp, (time_t) 0);
2509         }
2510         return (qp);
2511 }
2512
2513 /*
2514  * Check the list of root servers after receiving a response
2515  * to a query for the root servers.
2516  */
2517 static int
2518 check_root() {
2519         struct databuf *dp, *pdp;
2520         struct namebuf *np;
2521         int count = 0;
2522
2523         priming = 0;
2524         for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next)
2525                 if (NAME(*np)[0] == '\0')
2526                         break;
2527         if (np == NULL) {
2528                 ns_notice(ns_log_default, "check_root: Can't find root!");
2529                 return (0);
2530         }
2531         for (dp = np->n_data; dp != NULL; dp = dp->d_next)
2532                 if (dp->d_type == T_NS)
2533                         count++;
2534         ns_debug(ns_log_default, 1, "%d root servers", count);
2535         if (count < server_options->minroots) {
2536                 ns_notice(ns_log_default,
2537                 "check_root: %d root servers after query to root server < min",
2538                           count);
2539                 return (0);
2540         }
2541         pdp = NULL;
2542         dp = np->n_data;
2543         while (dp != NULL) {
2544                 if (dp->d_type == T_NS && dp->d_zone == DB_Z_CACHE &&
2545                     dp->d_ttl < (u_int32_t)tt.tv_sec) {
2546                         ns_debug(ns_log_default, 1,
2547                                  "deleting old root server '%s'",
2548                                  dp->d_data);
2549                         dp = rm_datum(dp, np, pdp, NULL);
2550                         /* SHOULD DELETE FROM HINTS ALSO */
2551                         continue;
2552                 }
2553                 pdp = dp;
2554                 dp = dp->d_next;
2555         }
2556         if (check_ns())
2557                 return (1);
2558         else {
2559                 priming = 1;
2560                 return (0);
2561         }
2562 }
2563
2564 /* 
2565  * Check the root to make sure that for each NS record we have a A RR
2566  */
2567 static int
2568 check_ns() {
2569         struct databuf *dp, *tdp;
2570         struct namebuf *np, *tnp;
2571         struct hashbuf *htp;
2572         char *dname;
2573         int found_arr;
2574         const char *fname;
2575         time_t curtime;
2576         int servers = 0, rrsets = 0;
2577
2578         ns_debug(ns_log_default, 2, "check_ns()");
2579
2580         curtime = (u_int32_t) tt.tv_sec;
2581         for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) {
2582                 if (NAME(*np)[0] != '\0')
2583                         continue;
2584                 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2585                         int cnames = 0;
2586
2587                         if (dp->d_rcode)
2588                                 continue;
2589
2590                         if (dp->d_type != T_NS)
2591                                 continue;
2592
2593                         servers++;
2594
2595                         /* look for A records */
2596                         dname = (caddr_t) dp->d_data;
2597                         htp = hashtab;
2598                         tnp = nlookup(dname, &htp, &fname, 0);
2599                         if (tnp == NULL || fname != dname) {
2600                                 ns_debug(ns_log_default, 3,
2601                                          "check_ns: %s: not found %s %#lx",
2602                                          dname, fname, (u_long)tnp);
2603                                 sysquery(dname, dp->d_class, T_A, NULL,
2604                                          0, ns_port, QUERY);
2605                                 continue;
2606                         }
2607                         /* look for name server addresses */
2608                         found_arr = 0;
2609                         (void)delete_stale(tnp);
2610                         for (tdp = tnp->n_data;
2611                              tdp != NULL;
2612                              tdp = tdp->d_next) {
2613                                 if (tdp->d_rcode)
2614                                         continue;
2615                                 if (tdp->d_type == T_CNAME)
2616                                         cnames++;
2617                                 if (tdp->d_type != T_A ||
2618                                     tdp->d_class != dp->d_class)
2619                                         continue;
2620                                 if ((tdp->d_zone == DB_Z_CACHE) &&
2621                                     (tdp->d_ttl < (u_int32_t)curtime)) {
2622                                         ns_debug(ns_log_default, 3, 
2623                                                  "check_ns: stale entry '%s'",
2624                                                  NAME(*tnp));
2625                                         found_arr = 0;
2626                                         break;
2627                                 }
2628                                 found_arr++;
2629                         }
2630                         if (found_arr)
2631                                 rrsets++;
2632                         else if (cnames > 0)
2633                                 ns_info(ns_log_default,
2634                                         "Root NS %s -> CNAME %s",
2635                                         NAME(*np), NAME(*tnp));
2636                         else
2637                                 sysquery(dname, dp->d_class, T_A, NULL,
2638                                          0, ns_port, QUERY);
2639                 }
2640         }
2641
2642         ns_debug(ns_log_default, 2, "check_ns: %d %d", servers, rrsets);
2643         return ((servers <= 2)
2644                 ? (rrsets == servers)
2645                 : ((rrsets * 2) >= servers)
2646                 );
2647 }
2648
2649 /* int findns(npp, class, nsp, countp, flag)
2650  *      Find NS's or an SOA
2651  * npp, class:
2652  *      dname whose most enclosing NS is wanted
2653  * nsp, countp:
2654  *      result array and count; array will also be NULL terminated
2655  * flag:
2656  *      boolean: we're being called from ADDAUTH, bypass authority checks
2657  * return value:
2658  *      NXDOMAIN: we are authoritative for this {dname,class}
2659  *                *countp is bogus, but nsp[] has a single SOA returned in it.
2660  *      SERVFAIL: we are auth but zone isn't loaded; or, no root servers found
2661  *                *countp and nsp[] are bogus.
2662  *      OK: we are not authoritative, and here are the NS records we found.
2663  *                *countp and nsp[] return NS records of interest.
2664  */
2665 int
2666 findns(struct namebuf **npp, int class,
2667        struct databuf **nsp, int *countp, int flag)
2668 {
2669         struct namebuf *np = *npp;
2670         struct databuf *dp;
2671         struct  databuf **nspp;
2672         struct hashbuf *htp;
2673         
2674         nsp[0] = NULL;
2675
2676         if (priming && (np == NULL || NAME(*np)[0] == '\0'))
2677                 htp = fcachetab;
2678         else
2679                 htp = hashtab;
2680
2681  try_again:
2682         if (htp == fcachetab && class == C_IN && !priming)
2683                 /*
2684                  * XXX - do we want to set needs_prime_cache if
2685                  *       OPTION_FORWARD_ONLY?
2686                  */
2687                 needs_prime_cache = 1;
2688         if (np == NULL) {
2689                 /* find the root */
2690                 for (np = htp->h_tab[0]; np != NULL; np = np->n_next)
2691                         if (NAME(*np)[0] == '\0')
2692                                 break;
2693         }
2694         while (np != NULL) {
2695                 ns_debug(ns_log_default, 5, "findns: np %#x '%s'", np,
2696                          NAME(*np));
2697                 /* Look first for SOA records. */
2698 #ifdef ADDAUTH
2699                 if (!flag)
2700 #endif
2701                 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2702                         if (dp->d_zone != DB_Z_CACHE &&
2703                             ((zones[dp->d_zone].z_type == Z_PRIMARY) ||
2704                              (zones[dp->d_zone].z_type == Z_SECONDARY)) &&
2705                             match(dp, class, T_SOA) && dp->d_type == T_SOA) {
2706                                 ns_debug(ns_log_default, 3,
2707                                          "findns: SOA found");
2708                                 if (zones[dp->d_zone].z_flags & Z_AUTH) {
2709                                         *npp = np;
2710                                         nsp[0] = dp;
2711                                         nsp[1] = NULL;
2712                                         DRCNTINC(dp);
2713                                         return (NXDOMAIN);
2714                                 } else {
2715                                         /* XXX: zone isn't loaded but we're
2716                                          *      primary or secondary for it.
2717                                          *      should we fwd this?
2718                                          */
2719                                         return (SERVFAIL);
2720                                 }
2721                         }
2722                 }
2723
2724                 /* If no SOA records, look for NS records. */
2725                 nspp = &nsp[0];
2726                 *nspp = NULL;
2727                 (void)delete_stale(np);
2728                 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2729                         if (!match(dp, class, T_NS))
2730                                 continue;
2731                         if (dp->d_rcode)
2732                                 continue;
2733                         /*
2734                          * Don't use records that may become invalid to
2735                          * reference later when we do the rtt computation.
2736                          * Never delete our safety-belt information!
2737                          *
2738                          * XXX: this is horribly bogus.
2739                          */
2740                         if ((dp->d_zone == DB_Z_CACHE) &&
2741                             (dp->d_ttl < (u_int32_t)tt.tv_sec) &&
2742                             !(dp->d_flags & DB_F_HINT)) {
2743                                 ns_debug(ns_log_default, 1,
2744                                          "findns: stale entry '%s'",
2745                                          NAME(*np));
2746                                 /*
2747                                  * We may have already added NS databufs
2748                                  * and are going to throw them away. Fix
2749                                  * reference counts. We don't need to free
2750                                  * them here as we just got them from the
2751                                  * cache.
2752                                  */
2753                                 while (nspp > &nsp[0]) {
2754                                         nspp--;
2755                                         DRCNTDEC(*nspp);
2756                                 }
2757                                 nsp[0] = NULL;
2758                                 goto try_parent;
2759                         }
2760                         if (nspp < &nsp[NSMAX-1]) {
2761                                 *nspp++ = dp;
2762                                 DRCNTINC(dp);
2763                         }
2764                 }
2765
2766                 *countp = nspp - nsp;
2767                 if (*countp > 0) {
2768                         ns_debug(ns_log_default, 3,
2769                                  "findns: %d NS's added for '%s'",
2770                                  *countp, NAME(*np));
2771                         *nspp = NULL;
2772                         *npp = np;
2773                         return (OK);    /* Success, got some NS's */
2774                 }
2775  try_parent:
2776                 np = np_parent(np);
2777         }
2778         if (htp == hashtab) {
2779                 htp = fcachetab;
2780                 goto try_again;
2781         }
2782         ns_debug(ns_log_default, 1,
2783                  "findns: No root nameservers for class %s?", p_class(class));
2784         if ((unsigned)class < MAXCLASS && norootlogged[class] == 0) {
2785                 norootlogged[class] = 1;
2786                 ns_info(ns_log_default, "No root nameservers for class %s",
2787                         p_class(class));
2788         }
2789         return (SERVFAIL);
2790 }
2791
2792
2793 /*
2794  * Extract RR's from the given node that match class and type.
2795  * Return number of bytes added to response.
2796  * If no matching data is found, then 0 is returned.
2797  */
2798 int
2799 finddata(struct namebuf *np, int class, int type,
2800          HEADER *hp, char **dnamep, int *lenp, int *countp)
2801 {
2802         struct databuf *dp;
2803         char *cp;
2804         int buflen, n, count = 0;
2805         char *new_dnamep = NULL;
2806         int defer = 0, found_count = 0, choice, i;
2807         struct databuf **found = NULL;
2808         struct databuf **tmpfound = NULL;
2809         int foundcname;
2810         int stalecount;
2811         int ret = 0;
2812
2813         stalecount = delete_stale(np);
2814
2815         /* We don't want to return cached SIG records when asked for SIGs,
2816          * since we may have an incomplete set.
2817          */
2818         if (type == T_SIG && findMyZone(np, class) == DB_Z_CACHE)
2819                 return(0);
2820
2821         if (type != T_ANY && type != T_PTR && type != T_NXT) {
2822                 found = memget((stalecount + 1) * sizeof *found);
2823                 tmpfound = memget((stalecount + 1) * sizeof *tmpfound);
2824                 if (found == NULL || tmpfound == NULL)
2825                         ns_panic(ns_log_default, 1, "finddata: out of memory");
2826                 defer = 1;
2827         }
2828
2829         buflen = *lenp;
2830         
2831 #ifdef DEBUG
2832         if (buflen > PACKETSZ)
2833                 ns_debug(ns_log_default, 1, "finddata(): buflen=%d", buflen);
2834 #endif
2835         cp = ((char *)hp) + *countp;
2836         foundcname = 0;
2837         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2838                 if (!wanted(dp, class, type)) {
2839                         if (type == T_CNAME && class == dp->d_class) {
2840                                 /* any data means no CNAME exists */
2841                                 if (dp->d_type != T_NXT &&
2842                                     dp->d_type != T_KEY &&
2843                                     dp->d_type != T_SIG) {
2844                                         ret = 0;
2845                                         goto done;
2846                                 }
2847                         }
2848                         continue;
2849                 }
2850                 if (dp->d_cred == DB_C_ADDITIONAL) {
2851 #ifdef NOADDITIONAL
2852                         continue;
2853 #else
2854                         /* we want to expire additional data very
2855                          * quickly.  current strategy is to cut 5%
2856                          * off each time it is accessed.  this makes
2857                          * stale(dp) true earlier when this datum is
2858                          * used often.
2859                          */
2860                         dp->d_ttl = tt.tv_sec
2861                                         +
2862                                 0.95 * (int) (dp->d_ttl - tt.tv_sec);
2863 #endif
2864                 }
2865                 /* -ve $ing stuff, anant@isi.edu
2866                  * if we have a -ve $ed record, change the rcode on the
2867                  * header to reflect that
2868                  */
2869                 if (dp->d_rcode == NOERROR_NODATA) {
2870                         if (count != 0) {
2871                                 /*
2872                                  * This should not happen, yet it does...
2873                                  */
2874                                 ns_info(ns_log_default,
2875                                    "NODATA & data for \"%s\" type %d class %d",
2876                                         *dnamep, type, class);
2877                                 continue;
2878                         }
2879                         if (type == T_ANY)
2880                                 continue;
2881                         hp->rcode = NOERROR_NODATA;
2882                         if (dp->d_size == 0) { /* !RETURNSOA */
2883                                 ret = 1;
2884                                 goto done;
2885                         }
2886                 }
2887                 if (dp->d_rcode == NXDOMAIN) {
2888                         if (count != 0) {
2889                                 /*
2890                                  * This should not happen, yet it might...
2891                                  */
2892                                 ns_info(ns_log_default,
2893                           "NXDOMAIN & data for \"%s\" type %d class %d",
2894                                         *dnamep, type, class);
2895                                 continue;
2896                         }
2897                         hp->rcode = NXDOMAIN;
2898                         if (dp->d_size == 0) { /* !RETURNSOA */ 
2899                                 ret = 1;
2900                                 goto done;
2901                         }
2902                 }
2903
2904                 /* Don't put anything but key or sig RR's in response to
2905                              requests for key or sig */
2906                 if (((type == T_SIG) || (type == T_KEY)) &&
2907                     (!((dp->d_type == T_SIG) || (dp->d_type == T_KEY))) )
2908                         continue;
2909
2910                 if (!defer) {
2911                         if (foundcname != 0 && dp->d_type == T_CNAME)
2912                                 continue;
2913
2914                         if ((n = make_rr(*dnamep, dp, (u_char *)cp, buflen, 1,
2915                                          dnptrs, dnptrs_end, 0)) < 0) {
2916                                 hp->tc = 1;
2917                                 ret = *lenp - buflen;
2918                                 goto done;
2919                         }
2920                         if (dp->d_secure != DB_S_SECURE)
2921                                 hp->ad = 0;
2922                         cp += n;
2923                         buflen -= n;
2924                         count++;
2925                 
2926                         if (dp->d_type == T_CNAME) {
2927                                 foundcname = 1;
2928 #define FOLLOWCNAME(type) \
2929         (type != T_KEY) && (type != T_SIG) && (type != T_NXT) && (type != T_ANY)
2930                         /* don't alias if querying for key, sig, nxt, or any */
2931
2932                                 if (FOLLOWCNAME(type))
2933                                         new_dnamep = (char *)dp->d_data;
2934                         }
2935                 } else {
2936                         if (dp->d_type == T_CNAME)
2937                                 foundcname = 1;
2938                         found[found_count++] = dp;
2939                 }
2940         }
2941
2942         if (found_count == 0 && count == 0) {
2943                 ret = 0;
2944                 goto done;
2945         }
2946
2947         /*
2948          * If the query type was SIG or ANY we will have returned the SIG
2949          * records already.
2950          */
2951         if (type != T_SIG && type != T_ANY) {
2952                 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2953                         if (!wantedsig(dp, class, type))
2954                                 continue;
2955                         if (dp->d_cred == DB_C_ADDITIONAL) {
2956 #ifdef NOADDITIONAL
2957                                 continue;
2958 #else
2959                                 /* we want to expire additional data very
2960                                  * quickly.  current strategy is to cut 5%
2961                                  * off each time it is accessed.  this makes
2962                                  * stale(dp) true earlier when this datum is
2963                                  * used often.
2964                                  */
2965                                 dp->d_ttl = tt.tv_sec
2966                                                 +
2967                                         0.95 * (int) (dp->d_ttl - tt.tv_sec);
2968 #endif
2969                         }
2970                         if (!defer) {
2971                                 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
2972                                                  buflen, 1, dnptrs, dnptrs_end,
2973                                                  0)) < 0) {
2974                                         hp->tc = 1;
2975                                         ret = *lenp - buflen;
2976                                         goto done;
2977                                 }
2978                                 if (dp->d_secure != DB_S_SECURE)
2979                                         hp->ad = 0;
2980                                 cp += n;
2981                                 buflen -= n;
2982                                 count++;
2983                         } else
2984                                 found[found_count++] = dp;
2985                 }
2986         }
2987
2988         if (defer && found_count > 0) {
2989                 int first_sig;
2990                 int non_sig_count;
2991                 int sig_count;          /* number of SIG records in found */
2992                 int idx, jdx;
2993                 enum ordering order;
2994
2995                 order = match_order(np, class, foundcname ? T_CNAME : type);
2996
2997                 /* shuffle the SIG records down to the bottom of the array
2998                  * as we need to make sure they get packed last, no matter
2999                  * what the ordering is. We're sure to maintain the
3000                  * original ordering within the two sets of records (so
3001                  * that fixed_order can work).
3002                  * First we pack the non-SIG records into the temp array.
3003                  */
3004                 for (idx = jdx = 0 ; idx < found_count ; idx++) {
3005                         if (found[idx]->d_type != T_SIG) {
3006                                 tmpfound[jdx++] = found[idx];
3007                         }
3008                 }
3009                 non_sig_count = jdx;
3010                 sig_count = found_count - jdx;
3011                 first_sig = jdx ;
3012                 
3013                 /* now shift the SIG records down to the end of the array
3014                  *  and copy in the non-SIG records
3015                  */
3016                 for (i = idx = found_count - 1 ; idx >= 0 ; idx--) {
3017                         if (i < non_sig_count) {
3018                                 found[i] = tmpfound[i];
3019                                 i--;
3020                         } else if (found[idx]->d_type == T_SIG) {
3021                                 found[i--] = found[idx] ;
3022                         }
3023                 }
3024
3025                 foundcname = 0;
3026                 switch (order) {
3027                 case fixed_order:
3028                         for (i = 0; i < found_count; i++) {
3029                                 dp = found[i];
3030                                 if (foundcname != 0 && dp->d_type == T_CNAME)
3031                                         continue;
3032                                 if (dp->d_type == T_CNAME) {
3033                                         foundcname = 1;
3034                                         if (FOLLOWCNAME(type)) {
3035                                                 new_dnamep = (char *)dp->d_data;
3036                                         }
3037                                 }
3038                                 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3039                                                  buflen, 1,
3040                                                  dnptrs, dnptrs_end, 0)) < 0) {
3041                                         hp->tc = 1;
3042                                         ret = *lenp - buflen;
3043                                         goto done;
3044                                 }
3045                                 if (dp->d_secure != DB_S_SECURE)
3046                                         hp->ad = 0;
3047                                 cp += n;
3048                                 buflen -= n;
3049                                 count++;
3050                         }
3051                         break;
3052
3053                 case random_order: {
3054                         /* first we shuffle the non-SIG records */
3055                         int iters = non_sig_count;
3056                         for (i = 0; i < iters; i++) {
3057                                 choice = ((u_int)rand()>>3) % non_sig_count;
3058                                 non_sig_count--;
3059                                 dp = found[choice];
3060                                 found[choice] = found[non_sig_count];
3061                                 if (foundcname != 0 && dp->d_type == T_CNAME)
3062                                         continue;
3063                                 if (dp->d_type == T_CNAME) {
3064                                         foundcname = 1;
3065                                         if (FOLLOWCNAME(type)) {
3066                                                 new_dnamep = (char *)dp->d_data;
3067                                         }
3068                                 }
3069                                 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3070                                                  buflen, 1,
3071                                                  dnptrs, dnptrs_end, 0)) < 0) {
3072                                         hp->tc = 1;
3073                                         ret = *lenp - buflen;
3074                                         goto done;
3075                                 }
3076                                 if (dp->d_secure != DB_S_SECURE)
3077                                         hp->ad = 0;
3078                                 cp += n;
3079                                 buflen -= n;
3080                                 count++;
3081                         }
3082
3083                         /* now shuffle the SIG records */
3084                         iters = sig_count;
3085                         for (i = 0; i < iters; i++) {
3086                                 choice = ((u_int)rand()>>3) % sig_count;
3087                                 choice += first_sig;
3088                                 sig_count--;
3089                                 dp = found[choice];
3090                                 found[choice] = found[sig_count + first_sig];
3091                                 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3092                                                  buflen, 1,
3093                                                  dnptrs, dnptrs_end, 0)) < 0) {
3094                                         hp->tc = 1;
3095                                         ret = *lenp - buflen;
3096                                         goto done;
3097                                 }
3098                                 if (dp->d_secure != DB_S_SECURE)
3099                                         hp->ad = 0;
3100                                 cp += n;
3101                                 buflen -= n;
3102                                 count++;
3103                         }
3104                         break;
3105                 }
3106
3107                 case cyclic_order:
3108                         /* first we do the non-SIG records */
3109                         choice = ((u_int)rand()>>3) % non_sig_count;
3110                         for (i = 0; i < non_sig_count ; i++) {
3111                                 dp = found[(i + choice) % non_sig_count];
3112                                 if (foundcname != 0 && dp->d_type == T_CNAME)
3113                                         continue;
3114                                 if (dp->d_type == T_CNAME) {
3115                                         foundcname = 1;
3116                                         if (FOLLOWCNAME(type)) {
3117                                                 new_dnamep = (char *)dp->d_data;
3118                                         }
3119                                 }
3120                                 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3121                                                  buflen, 1,
3122                                                  dnptrs, dnptrs_end, 0)) < 0) {
3123                                         hp->tc = 1;
3124                                         ret = *lenp - buflen;
3125                                         goto done;
3126                                 }
3127                                 if (dp->d_secure != DB_S_SECURE)
3128                                         hp->ad = 0;
3129                                 cp += n;
3130                                 buflen -= n;
3131                                 count++;
3132                         }
3133
3134                         /* now do the SIG record rotation. */
3135                         if (sig_count > 0) {
3136                                 choice = ((u_int)rand()>>3) % sig_count;
3137                                 choice += first_sig;
3138                                 i = choice;
3139                                 do {
3140                                         dp = found[i];
3141                                         if ((n = make_rr(*dnamep, dp,
3142                                                          (u_char *)cp,
3143                                                          buflen, 1,
3144                                                          dnptrs,
3145                                                          dnptrs_end, 0)) < 0) {
3146                                                 hp->tc = 1;
3147                                                 ret = *lenp - buflen;
3148                                                 goto done;
3149                                         }
3150                                         if (dp->d_secure != DB_S_SECURE)
3151                                                 hp->ad = 0;
3152                                         cp += n;
3153                                         buflen -= n;
3154                                         count++;
3155                                         i++;
3156                                         if (i >= found_count)
3157                                                 i = first_sig;
3158                                 } while (i != choice);
3159                         }
3160                         
3161                         break;
3162
3163                 default:
3164                         ns_warning(ns_log_default, "finddata: unknown ordering: %d",
3165                                    order);
3166                         break;
3167                 }
3168         }
3169         
3170         if (new_dnamep != NULL)
3171                 *dnamep = new_dnamep;
3172
3173         ns_debug(ns_log_default, 3, "finddata: added %d class %d type %d RRs",
3174                  count, class, type);
3175         ret = *lenp - buflen;
3176  done:
3177         if (found != NULL)
3178                 memput(found, (stalecount + 1) * sizeof *found);
3179         if (tmpfound != NULL)
3180                 memput(tmpfound, (stalecount + 1) * sizeof *tmpfound);
3181         *countp = count;
3182         return (ret);
3183 }
3184
3185 /*
3186  * Do we want this data record based on the class and type?
3187  */
3188 static int
3189 wanted(const struct databuf *dp, int class, int type) {
3190         const u_char *cp;
3191         int coveredType;
3192         time_t expiration;
3193 #ifdef DEBUG
3194         char pclass[15], ptype[15];
3195 #endif
3196
3197 #ifdef DEBUG
3198         strcpy(pclass, p_class(class));
3199         strcpy(ptype, p_type(type));
3200         ns_debug(ns_log_default, 3, "wanted(%#x, %s %s) [%s %s]",
3201                  dp, pclass, ptype,
3202                  p_class(dp->d_class), p_type(dp->d_type));
3203 #endif
3204
3205         if (dp->d_class != class && class != C_ANY)
3206                 return (0);
3207         /*
3208          * Must check SIG for expiration below, other matches
3209          * return OK here.
3210          */
3211         if (type == dp->d_type && (type != T_SIG))
3212                 return (1);
3213         /* For a T_ANY query, we do not want to return -ve $ed RRs. */
3214         if (type == T_ANY && dp->d_rcode == NOERROR_NODATA)
3215                 return (0);
3216
3217         /* First, look at the type of RR.  */
3218         switch (dp->d_type) {
3219
3220                 /* Cases to deal with:
3221                         T_ANY search, return all unexpired SIGs.
3222                         T_SIG search, return all unexpired SIGs.
3223                         T_<foo> search, return all unexp SIG <FOO>s.
3224                  */
3225         case T_SIG:
3226                 cp = dp->d_data;
3227                 GETSHORT(coveredType, cp);
3228                 cp += INT16SZ + INT32SZ; /* skip alg, labels, & orig TTL */
3229                 GETLONG(expiration,cp);
3230
3231                 if (type == T_ANY || type == T_SIG) {
3232                         if (expiration > time(0))
3233                                 return (1);     /* Unexpired matching SIG */
3234                 }
3235                 return (0);             /* We don't return this SIG. */
3236
3237         case T_ANY:
3238                 return (1);
3239         case T_CNAME:
3240                 if (dp->d_rcode != NOERROR_NODATA)
3241                         return (1);
3242                 else
3243                         break;
3244         }
3245         /* OK, now look at the type of query.  */
3246         if (type == ns_t_any)
3247                 return (1);
3248         else if (type == ns_t_mailb)
3249                 switch (dp->d_type) {
3250                 case T_MR:
3251                 case T_MB:
3252                 case T_MG:
3253                 case T_MINFO:
3254                         return (1);
3255                 }
3256         else if (ns_t_xfr_p(type)) {
3257                 /*
3258                  * This is used to validate transfer requests, not
3259                  * generate transfer responses.  Is there an SOA?
3260                  */
3261                 if (dp->d_type == ns_t_soa && dp->d_zone != DB_Z_CACHE
3262                     && (zones[dp->d_zone].z_flags & Z_AUTH))
3263                         return (1);
3264         }
3265         return (0);
3266 }
3267
3268 static int
3269 wantedsig(const struct databuf *dp, int class, int type) {
3270         const u_char *cp;
3271         int coveredType;
3272         time_t expiration;
3273 #ifdef DEBUG
3274         char pclass[15], ptype[15];
3275 #endif
3276
3277 #ifdef DEBUG
3278         strcpy(pclass, p_class(class));
3279         strcpy(ptype, p_type(type));
3280         ns_debug(ns_log_default, 3, "wantedtsig(%#x, %s %s) [%s %s]",
3281                  dp, pclass, ptype,
3282                  p_class(dp->d_class), p_type(dp->d_type));
3283 #endif
3284
3285         if (dp->d_class != class && class != C_ANY)
3286                 return (0);
3287         if (dp->d_type != T_SIG || dp->d_rcode != 0)
3288                 return (0);
3289
3290         cp = dp->d_data;
3291         GETSHORT(coveredType, cp);
3292         cp += INT16SZ + INT32SZ; /* skip alg, labels, & orig TTL */
3293         GETLONG(expiration,cp);
3294         if (expiration < time(0))
3295                 return (0);
3296
3297         if (type == T_ANY || type == T_SIG || type == coveredType)
3298                         return (1);
3299         if (type == ns_t_mailb) {
3300                 switch (coveredType) {
3301                 case T_MR:
3302                 case T_MB:
3303                 case T_MG:
3304                 case T_MINFO:
3305                         return (1);
3306                 }
3307         }
3308         return (0);
3309 }
3310
3311 /*
3312  *  Add RR entries from dpp array to a query/response.
3313  *  Return the number of bytes added or negative the amount
3314  *  added if truncation occured.  Typically you are
3315  *  adding NS records to a response.
3316  */
3317 int
3318 add_data(struct namebuf *np, struct databuf **dpp,
3319          u_char *cp, int buflen, int *countp)
3320 {
3321         struct databuf *dp;
3322         char dname[MAXDNAME];
3323         int n, bytes;
3324
3325         bytes = *countp = 0;
3326         getname(np, dname, sizeof(dname));
3327         for (dp = *dpp++; dp != NULL; dp = *dpp++) {
3328                 if (stale(dp))
3329                         continue;       /* ignore old cache entry */
3330                 if (dp->d_rcode)
3331                         continue;
3332                 if ((n = make_rr(dname, dp, cp, buflen, 1,
3333                                  dnptrs, dnptrs_end, 0)) < 0)
3334                         return (-bytes);        /* Truncation */
3335                 cp += n;
3336                 buflen -= n;
3337                 bytes += n;
3338                 (*countp)++;
3339         }
3340         return (bytes);
3341 }
3342
3343 static void
3344 rrsetadd(struct flush_set *flushset, const char *name, struct databuf *dp) {
3345         struct flush_set *fs = flushset;
3346         struct db_list *dbl;
3347
3348         while (fs->fs_name && (
3349                 ns_samename(fs->fs_name,name) != 1 ||
3350                 (fs->fs_class != dp->d_class) ||
3351                 (fs->fs_type != dp->d_type) ||
3352                 (fs->fs_cred != dp->d_cred))) {
3353                 fs++;
3354         }
3355         if (!fs->fs_name) {
3356                 fs->fs_name = savestr(name, 1);
3357                 fs->fs_class = dp->d_class;
3358                 fs->fs_type = dp->d_type;
3359                 fs->fs_cred = dp->d_cred;
3360                 fs->fs_list = NULL;
3361                 fs->fs_last = NULL;
3362         }
3363         dbl = (struct db_list *)memget(sizeof(struct db_list));
3364         if (!dbl)
3365                 panic("rrsetadd: out of memory", NULL);
3366         dbl->db_next = NULL;
3367         dbl->db_dp = dp;
3368         if (fs->fs_last == NULL)
3369                 fs->fs_list = dbl;
3370         else
3371                 fs->fs_last->db_next = dbl;
3372         fs->fs_last = dbl;
3373 }
3374
3375 static int
3376 ttlcheck(const char *name, struct db_list *dbl, int update) {
3377         int type = dbl->db_dp->d_type;
3378         int class = dbl->db_dp->d_class;
3379         struct hashbuf *htp = hashtab;
3380         const char *fname;
3381         struct namebuf *np;
3382         struct db_list *dbp = dbl;
3383         struct databuf *dp;
3384         u_int32_t ttl = 0;      /* Make gcc happy. */
3385         int first;
3386
3387
3388         np = nlookup(name, &htp, &fname, 0);
3389         if (np == NULL || fname != name || ns_wildcard(NAME(*np)))
3390                 return (1);
3391
3392         /* check that all the ttl's we have are the same, if not return 1 */
3393         first = 1;
3394         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3395                 if (!match(dp, class, type))
3396                         continue;
3397                 if (first) {
3398                         /* we can't update zone data so return early */
3399                         if (dp->d_zone != DB_Z_CACHE)
3400                                 return (0);
3401                         ttl = dp->d_ttl;
3402                         first = 0;
3403                 } else if (ttl != dp->d_ttl)
3404                         return (1);
3405         }
3406
3407         /* there are no records of this type in the cache */
3408         if (first)
3409                 return(1);
3410
3411         /*
3412          * the ttls of all records we have in the cache are the same
3413          * if the ttls differ in the new set we don't want it.
3414          */
3415
3416         /* check that all the ttl's we have are the same, if not return 0 */
3417         first = 1;
3418         while (dbp) {
3419                 if (first) {
3420                         ttl = dbp->db_dp->d_ttl;
3421                         first = 0;
3422                 } else if (ttl != dbp->db_dp->d_ttl) {
3423                         return(0);
3424                 }
3425                 dbp = dbp->db_next;
3426         }
3427
3428         /* update ttl if required */
3429         if (update) {
3430                 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3431                         if (!match(dp, class, type))
3432                                 continue;
3433                         if (dp->d_ttl > ttl)
3434                                 break;
3435                         dp->d_ttl = ttl;
3436                         fixttl(dp);
3437                 }
3438         }
3439
3440         return(1);
3441 }
3442
3443 /*
3444  * lookup rrset in table and compare to dbl
3445  * tri state result
3446  * -1: lookup failed
3447  * 0: rrsets same
3448  * 1: rrsets differ
3449  */
3450
3451 static int
3452 rrsetcmp(char * name, struct db_list * dbl, struct hashbuf * table) {
3453         int type = dbl->db_dp->d_type;
3454         int class = dbl->db_dp->d_class;
3455         struct hashbuf *htp = table;
3456         const char *fname;
3457         struct namebuf *np;
3458         struct db_list *dbp = dbl;
3459         struct databuf *dp;
3460         int exists = 0;
3461
3462
3463         np = nlookup(name, &htp, &fname, 0);
3464         if (np == NULL || fname != name || ns_wildcard(NAME(*np))) {
3465                 ns_debug(ns_log_default, 3, "rrsetcmp: name not in database");
3466                 return (-1);
3467         }
3468
3469         /* check that all entries in dbl are in the cache */
3470         while (dbp) {
3471                 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3472                         if (!match(dp, class, type))
3473                                 continue;
3474                         exists = 1;
3475                         if (!db_cmp(dp, dbp->db_dp) 
3476 #ifdef NOADDITIONAL
3477                         && ((dp->d_cred == dbp->db_dp->d_cred) ||
3478                                  (dp->d_cred != DB_C_ADDITIONAL))
3479 #endif
3480                                  )
3481                                 break;
3482                 }
3483                 if (!dp) {
3484                         ns_debug(ns_log_default, 3,
3485                                  "rrsetcmp: %srecord%s in database",
3486                                  exists ? "" : "no ", exists ? " not" : "s");
3487                         return (exists ? 1 : -1);
3488                 }
3489                 dbp = dbp->db_next;
3490         }
3491
3492         /* Check that all cache entries are in the list. */
3493         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3494                 if (!match(dp, class, type))
3495                         continue;
3496 #ifdef NCACHE
3497                 if (dp->d_rcode)
3498                         return (1);
3499 #endif
3500                 dbp = dbl;
3501                 while (dbp) {
3502                         if (!db_cmp(dp, dbp->db_dp))
3503                                 break;
3504                         dbp = dbp->db_next;
3505                 }
3506                 if (!dbp) {
3507                         ns_debug(ns_log_default, 3,
3508                                  "rrsetcmp: record not in rrset");
3509                         return (1);
3510                 }
3511         }
3512         ns_debug(ns_log_default, 3, "rrsetcmp: rrsets matched");
3513         return (0);
3514 }
3515
3516 /*
3517  * verify incoming answer against what we already have in the hints
3518  * issue warnings / errors if differences detected.
3519  */
3520
3521 static void
3522 check_hints(struct flush_set * flushset) {
3523         struct zoneinfo *zp;
3524         struct flush_set *fs;
3525         struct db_list *dbp;
3526
3527         /* We don't use hints when in forward only mode */
3528         if (NS_OPTION_P(OPTION_FORWARD_ONLY))
3529                 return;
3530
3531         /* find "." NS rrset and hence class */
3532         for (fs = flushset; fs->fs_name != NULL; fs++) {
3533                 if ((fs->fs_name[0] != '\0') || (fs->fs_type != ns_t_ns))
3534                         continue;
3535
3536                 /* see if we are a root server */
3537                 zp = find_zone(fs->fs_name, fs->fs_class);
3538                 if (zp != NULL &&
3539                     (zp->z_type == z_master || zp->z_type == z_slave))
3540                         return;
3541                 switch (rrsetcmp(fs->fs_name, fs->fs_list, fcachetab)) {
3542                 case -1:
3543                         ns_error(ns_log_default,
3544                             "check_hints: no NS records for class %d in hints",
3545                                 fs->fs_class);
3546                         break;
3547                 case 1:
3548                         ns_warning(ns_log_default,
3549  "check_hints: root NS list in hints for class %d does not match root NS list",
3550                                 fs->fs_class);
3551                         break;
3552                 case 0:
3553                         break;
3554                 default:
3555                         ns_error(ns_log_default,
3556                             "check_hints: unexpected response from rrsetcmp");
3557                         break;
3558                 }
3559                 break;
3560         }
3561
3562         if (fs->fs_name == NULL)        /* no root NS records */
3563                 return;
3564
3565         dbp = fs->fs_list;
3566         while (dbp) {
3567                 /* for each NS find A rrset in answer and check */
3568                 for (fs = flushset; fs->fs_name != NULL; fs++) {
3569                         if (ns_samename(fs->fs_name, (char *)dbp->db_dp->d_data) != 1
3570                             || fs->fs_type != ns_t_a)
3571                                 continue;
3572                         switch (rrsetcmp(fs->fs_name, fs->fs_list, fcachetab)) {
3573                         case -1:
3574                                 ns_error(ns_log_default,
3575                         "check_hints: no A records for %s class %d in hints",
3576                                         fs->fs_name[0] ? fs->fs_name : ".",
3577                                         fs->fs_class);
3578                                 break;
3579                         case 1:
3580                                 ns_warning(ns_log_default,
3581          "check_hints: A records for %s class %d do not match hint records",
3582                                         fs->fs_name[0] ? fs->fs_name : ".",
3583                                         fs->fs_class);
3584                                 break;
3585                         case 0:
3586                                 break;
3587                         default:
3588                                 ns_error(ns_log_default,
3589                                     "check_hints: unexpected response from rrsetcmp");
3590                                 break;
3591                         }
3592                         break;
3593                 }
3594
3595                 if (fs->fs_name == NULL)
3596                         ns_debug(ns_log_default, 2,
3597                                 "check_hints: no A records for %s",
3598                                 dbp->db_dp->d_data);
3599
3600                 dbp = dbp->db_next;
3601         }
3602 }
3603
3604 static void
3605 rrsetupdate(struct flush_set * flushset, int flags, struct sockaddr_in from,
3606             int updatettl) {
3607         struct flush_set *fs = flushset;
3608         struct db_list *dbp, *odbp;
3609         int n;
3610         void *state = NULL;
3611
3612         while (fs->fs_name) {
3613                 ns_debug(ns_log_default, 2, "rrsetupdate: %s",
3614                          fs->fs_name[0] ? fs->fs_name : ".");
3615                 if ((n = rrsetcmp(fs->fs_name, fs->fs_list, hashtab)) &&
3616                     ttlcheck(fs->fs_name, fs->fs_list, 0)) {
3617                         if (n > 0)
3618                                 flushrrset(fs, from);
3619
3620                         dbp = fs->fs_list;
3621                         while (dbp) {
3622                                 n = db_set_update(fs->fs_name, dbp->db_dp,
3623                                                   &state, flags,
3624                                                   &hashtab, from, NULL,
3625                                                   0, NULL);
3626                                 ns_debug(ns_log_default, 3,
3627                                          "rrsetupdate: %s %d",
3628                                          fs->fs_name[0] ? fs->fs_name : ".",
3629                                          n);
3630                                 odbp = dbp;
3631                                 dbp = dbp->db_next;
3632                                 memput(odbp, sizeof *odbp);
3633                         }    
3634                         ns_debug(ns_log_default, 3,
3635                                  "rrsetupdate: %s %d",
3636                                  fs->fs_name[0] ? fs->fs_name : ".", n);
3637                 } else {
3638                         if ((n == 0) && updatettl)
3639                                 (void)ttlcheck(fs->fs_name,fs->fs_list, 1);
3640                         dbp = fs->fs_list;
3641                         while (dbp) {
3642                                 db_freedata(dbp->db_dp);
3643                                 odbp = dbp;
3644                                 dbp = dbp->db_next;
3645                                 memput(odbp, sizeof *odbp);
3646                         }
3647                 }
3648                 fs->fs_list = NULL;
3649                 fs++;
3650         }
3651         n = db_set_update(NULL, NULL, &state, flags, &hashtab, from,
3652                           NULL, 0, NULL);
3653 }
3654
3655 static void
3656 flushrrset(struct flush_set * fs, struct sockaddr_in from) {
3657         struct databuf *dp;
3658         int n;
3659
3660         ns_debug(ns_log_default, 2, "flushrrset(%s, %s, %s, %d)",
3661                  fs->fs_name[0]?fs->fs_name:".", p_type(fs->fs_type),
3662                  p_class(fs->fs_class), fs->fs_cred);
3663         dp = savedata(fs->fs_class, fs->fs_type, 0, NULL, 0);
3664         dp->d_zone = DB_Z_CACHE;
3665         dp->d_cred = fs->fs_cred;
3666         dp->d_clev = 0; 
3667         do {
3668                 n = db_update(fs->fs_name, dp, NULL, NULL, DB_DELETE, hashtab,
3669                               from);
3670                 ns_debug(ns_log_default, 3, "flushrrset: %d", n);
3671         } while (n == OK);
3672         db_freedata(dp);
3673 }
3674
3675 static void
3676 free_flushset(struct flush_set *flushset, int flushset_size) {
3677         struct flush_set *fs;
3678
3679         for (fs = flushset; fs->fs_name != NULL; fs++)
3680                 freestr(fs->fs_name);
3681         memput(flushset, flushset_size);
3682 }
3683
3684 /*
3685  *  This is best thought of as a "cache invalidate" function.
3686  *  It is called whenever a piece of data is determined to have
3687  *  become invalid either through a timeout or a validation
3688  *  failure.  It is better to have no information, than to
3689  *  have partial information you pass off as complete.
3690  */
3691 void
3692 delete_all(struct namebuf *np, int class, int type) {
3693         struct databuf *dp, *pdp;
3694
3695         ns_debug(ns_log_default, 3, "delete_all(%#x:\"%s\" %s %s)",
3696                  np, NAME(*np), p_class(class), p_type(type));
3697         pdp = NULL;
3698         dp = np->n_data;
3699         while (dp != NULL) {
3700                 if (dp->d_zone == DB_Z_CACHE && (dp->d_flags & DB_F_HINT) == 0
3701                     && match(dp, class, type)) {
3702                         dp = rm_datum(dp, np, pdp, NULL);
3703                         continue;
3704                 }
3705                 pdp = dp;
3706                 dp = dp->d_next;
3707         }
3708 }
3709
3710 /* delete_stale(np)
3711  *      for all RRs associated with this name, check for staleness (& delete)
3712  * arguments:
3713  *      np = pointer to namebuf to be cleaned.
3714  * returns:
3715  *      number of RRs associated with this name.
3716  * side effects:
3717  *      delete_all() can be called, freeing memory and relinking chains.
3718  */
3719 int 
3720 delete_stale(np)
3721         struct namebuf *np;
3722 {
3723         struct databuf *dp;
3724         int count;
3725  again:
3726         count = 0;
3727         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3728                 if (dp->d_zone == DB_Z_CACHE && stale(dp)) {
3729                         delete_all(np, dp->d_class, dp->d_type);
3730                         goto again;
3731                 }
3732                 count++;
3733         }
3734         return (count);
3735 }
3736
3737
3738 /*
3739  * Adjust answer message so that it fits in outlen. Set tc if required.
3740  *
3741  * If outlen = msglen, can be used to verify qdcount, ancount, nscount
3742  * and arcount.
3743  *
3744  * return new length
3745  */
3746
3747 int
3748 trunc_adjust(u_char *msg, int msglen, int outlen) {
3749         register HEADER *hp;
3750         u_int qdcount, ancount, nscount, arcount, dlen;
3751         u_char *cp = msg, *cp1, *eom_in, *eom_out;
3752         int n;
3753
3754         eom_in = msg + msglen;
3755         eom_out = msg + outlen;
3756
3757         hp = (HEADER *)msg;
3758         qdcount = ntohs(hp->qdcount);
3759         ancount = ntohs(hp->ancount);
3760         nscount = ntohs(hp->nscount);
3761         arcount = ntohs(hp->arcount);
3762         cp += HFIXEDSZ;
3763
3764         while ((qdcount || ancount || nscount || arcount) &&
3765                cp < eom_in && cp < eom_out) {
3766
3767                 cp1 = cp; /* use temporary in case we break */
3768
3769                 n = dn_skipname(cp1, eom_in);
3770                 if (n < 0)
3771                         break;
3772                 cp1 += n + 2 * INT16SZ; /* type, class */
3773
3774                 if (!qdcount) {
3775                         cp1 += INT32SZ;     /* ttl */
3776                         if (cp1 + INT16SZ > eom_in)
3777                                 break;
3778                         GETSHORT(dlen, cp1);
3779                         cp1 += dlen;
3780                 }
3781
3782                 if (cp1 > eom_in || cp1 > eom_out)
3783                         break;
3784
3785                 cp = cp1;
3786
3787                 if (qdcount)
3788                         qdcount--;
3789                 else if (ancount)
3790                         ancount--;
3791                 else if (nscount)
3792                         nscount--;
3793                 else
3794                         arcount--;
3795         }
3796
3797         if (qdcount || ancount || nscount || arcount) {
3798                 ns_debug(ns_log_default, 1,
3799                          "trunc_adjust:%s %d %d %d %d %d, %d %d %d %d %d",
3800                          hp->tc?" tc":"", msglen,
3801                          ntohs(hp->qdcount), ntohs(hp->ancount),
3802                          ntohs(hp->nscount), ntohs(hp->arcount),
3803                          cp-msg, qdcount, ancount, nscount, arcount);
3804                 hp->tc = 1;
3805                 hp->qdcount = htons(ntohs(hp->qdcount) - qdcount);
3806                 hp->ancount = htons(ntohs(hp->ancount) - ancount);
3807                 hp->nscount = htons(ntohs(hp->nscount) - nscount);
3808                 hp->arcount = htons(ntohs(hp->arcount) - arcount);
3809         }
3810         ENSURE(cp <= eom_out);
3811         return (cp - msg);
3812 }
3813
3814 /*
3815  * mark the server "from" bad in the qp structure so it won't be retried.
3816  */
3817 static void
3818 mark_bad(struct qinfo *qp, struct sockaddr_in from) {
3819         int i;
3820
3821         for (i = 0; i < (int)qp->q_naddr; i++)
3822                 if (ina_equal(qp->q_addr[i].ns_addr.sin_addr, from.sin_addr))
3823                         qp->q_addr[i].nretry = MAXRETRY;
3824 }
3825
3826 static void
3827 mark_lame(struct qinfo *qp, struct sockaddr_in from) {
3828         int i;
3829
3830         for (i = 0; i < (int)qp->q_naddr; i++)
3831                 if (ina_equal(qp->q_addr[i].ns_addr.sin_addr, from.sin_addr) &&
3832                     qp->q_addr[i].ns != NULL) {
3833                         qp->q_addr[i].ns->d_flags |= DB_F_LAME;
3834                         db_lame_add(qp->q_domain,
3835                                     (char*)qp->q_addr[i].ns->d_data, 
3836                                     tt.tv_sec + server_options->lame_ttl);
3837                 }
3838 }
3839
3840 /*
3841  * Retry the message if and only if from matches where the query was
3842  * last sent to.  The code does not handle responses sent from the
3843  * wrong interface an a multihomed server.
3844  */
3845 static void
3846 fast_retry(struct qinfo *qp, struct sockaddr_in from) {
3847         if (ina_equal(qp->q_addr[qp->q_curaddr].ns_addr.sin_addr,
3848                    from.sin_addr))
3849                 retry(qp);
3850 }
3851
3852 static void
3853 add_related_additional(char *name) {
3854         int i;
3855
3856         if (num_related >= MAX_RELATED - 1)
3857                 return;
3858         for (i = 0; i < num_related; i++)
3859                 if (ns_samename(name, related[i]) == 1) {
3860                         freestr(name);
3861                         return;
3862                 }
3863         related[num_related++] = name;
3864 }
3865
3866 static void
3867 free_related_additional() {
3868         int i;
3869
3870         for (i = 0; i < num_related; i++)
3871                 freestr(related[i]);
3872         num_related = 0;
3873 }
3874
3875 static int
3876 related_additional(char *name) {
3877         int i;
3878
3879         for (i = 0; i < num_related; i++)
3880                 if (ns_samename(name, related[i]) == 1)
3881                         return (1);
3882         return (0);
3883 }
3884
3885 static void
3886 freestr_maybe(char **tname) {
3887         if (tname == NULL || *tname == NULL)
3888                 return;
3889         freestr(*tname);
3890         *tname = NULL;
3891 }
3892
3893 /*
3894  * Match a request namebuf against the configured rrset-order info.  First
3895  * match wins.  There is an implicit '*.' at the front to the ordering names.
3896  */
3897 static enum ordering
3898 match_order(const struct namebuf *np, int class, int type) {
3899         rrset_order_list orders = server_options->ordering;
3900         rrset_order_element roe;
3901         
3902         if (orders == NULL)
3903                 return (DEFAULT_ORDERING);
3904         
3905         for (roe = orders->first ; roe != NULL ; roe = roe->next) {
3906                 if (roe->class != C_ANY && roe->class != class)
3907                         continue;
3908                 if (roe->type != T_ANY && roe->type != type)
3909                         continue;
3910
3911                 if (match_name(np, roe->name, strlen(roe->name)) == 0) {
3912                         return (roe->order);
3913                 }
3914         }
3915
3916         /* none matched so use default */
3917         return (DEFAULT_ORDERING);
3918 }
3919
3920 /* Do a simple compare of the NP data against the given NAME, recursively
3921  * looking at the NP parent if necessary. NAMELEN is the length of the NAME
3922  * that needs to be matched. Matching happen from right to left. Returns -1
3923  * on failure, on success the index of the first character of the matched
3924  * portion of the string is returned. In the first level call a return
3925  * value of 0 is of interest.
3926  */
3927 static int
3928 match_name(const struct namebuf *np, const char *name, size_t namelen)
3929 {
3930         int matched ;
3931         
3932         if (name[0] == '*' && name[1] == '\0')
3933                 return 0;
3934
3935         if (np->n_parent != NULL) { /* recurse to end of np list */
3936                 matched = match_name(np->n_parent,name,namelen);
3937         } else {
3938                 matched = namelen;
3939         }
3940         
3941         if (matched > 0) {
3942                 int labellen = NAMELEN(*np);
3943                 char pch;
3944                 const char *start;
3945                 
3946                 if (labellen > matched) {
3947                         return -1;
3948                 } else if (labellen < matched) {
3949                         /* string is longer than this namebuf's data, so
3950                            make sure there's a period before the end of the 
3951                            match so we don't just match a suffix. */
3952                         start = name + (matched - labellen);
3953                         pch = start[-1];
3954                         if (pch != '.') {
3955                                 return -1;
3956                         }
3957                 } else {
3958                         start = name ;
3959                 }
3960
3961                 if (strncasecmp(start, NAME(*np), labellen) == 0) {
3962                         /* looking good. tell our caller what portion of
3963                            the tail of string has been matched */
3964                         if (start == name)
3965                                 return (0) ;
3966                         else 
3967                                 return (start - name - 1); /* matched '.' too */
3968                 } else {
3969                         return (-1);
3970                 }
3971         }
3972
3973         return (matched);
3974 }
3975