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 $";
7 * Copyright (c) 1986, 1988, 1990
8 * The Regents of the University of California. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
40 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
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.
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
60 * Portions Copyright (c) 1995 by International Business Machines, Inc.
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
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.
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.
85 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
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.
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
101 #include "port_before.h"
103 #include <sys/types.h>
104 #include <sys/param.h>
105 #include <sys/socket.h>
106 #include <sys/file.h>
109 #include <netinet/in.h>
110 #include <arpa/nameser.h>
111 #include <arpa/inet.h>
122 #include <isc/eventlib.h>
123 #include <isc/logging.h>
124 #include <isc/memcluster.h>
128 #include "port_after.h"
132 static u_int8_t norootlogged[MAXCLASS]; /* XXX- should be a bitmap */
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";
154 struct db_list *db_next;
155 struct databuf *db_dp;
163 struct db_list *fs_list;
164 struct db_list *fs_last;
167 static void rrsetadd(struct flush_set *, const char *,
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 *),
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);
192 #define MAX_RELATED 100
194 static int num_related = 0;
195 static char *related[MAX_RELATED];
198 learntFrom(struct qinfo *qp, struct sockaddr_in *server) {
199 static char *buf = NULL;
204 a = ns = na = "<Not Available>";
206 for (i = 0; (u_int)i < qp->q_naddr; i++) {
207 if (ina_equal(qp->q_addr[i].ns_addr.sin_addr,
209 db = qp->q_addr[i].ns;
211 if (NS_OPTION_P(OPTION_HOSTSTATS)) {
214 if (db->d_ns != NULL) {
216 inet_ntoa(db->d_ns->addr));
219 ns = zones[db->d_zone]
223 if (db->d_rcode == 0)
224 na = (char*)qp->q_addr[i].ns->d_data;
227 if (NS_OPTION_P(OPTION_HOSTSTATS)) {
230 db = qp->q_addr[i].nsdata;
232 if (db->d_ns != NULL) {
234 inet_ntoa(db->d_ns->addr));
237 a = zones[db->d_zone].z_origin;
245 if (a == ns && ns == na) /* all "UNKNOWN" */
255 if (NS_OPTION_P(OPTION_HOSTSTATS)) {
256 static const char fmt[] = " '%s': learnt (A=%s,NS=%s)";
258 buf = newstr(sizeof fmt + strlen(na) + strlen(a) + strlen(ns),
262 sprintf(buf, fmt, na, a, ns);
264 static const char fmt[] = " '%s'";
266 buf = newstr(sizeof fmt + strlen(na), 0);
269 sprintf(buf, fmt, na);
276 ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp)
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;
290 int restart; /* flag for processing cname response */
291 int validanswer, dbflags;
292 int cname, lastwascname, externalcname;
293 int count, founddata, foundname;
296 char name[MAXDNAME], qname[MAXDNAME], aname[MAXDNAME];
297 char msgbuf[MAXDNAME+100];
298 char *dname, tmpdomain[MAXDNAME];
300 const char *formerrmsg = "brain damage";
301 u_char newmsg[PACKETSZ];
310 int sendto_errno = 0;
311 int has_tsig, oldqlen;
314 int smsglen, smsgsize, siglen;
315 u_char sig[TSIG_SIG_SIZE];
319 nameserIncr(from.sin_addr, nssRcvdR);
322 if ((qp = qfindid(hp->id)) == NULL ) {
323 ns_debug(ns_log_default, 1, "DUP? dropped (id %d)",
325 nameserIncr(from.sin_addr, nssRcvdDupR);
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));
337 if (qp->q_nstsig == NULL)
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);
348 if (hp->rcode == NOERROR)
350 ns_debug(ns_log_default, 1,
351 "resp: error bad tsig, record dropped");
357 * Here we handle high level formatting problems by parsing the header.
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 */
367 if ((*cp & INDIR_MASK) == 0)
371 n = dn_expand(msg, eom, cp, qname, sizeof(qname));
373 formerrmsg = expandFailedQuery;
377 if (cp + 2 * INT16SZ > eom) {
378 formerrmsg = outofDataQuery;
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;
390 formerrmsg = outofDataQuery;
393 if (qp->q_msg && qp->q_msglen &&
394 !res_nameinquery(qname, qtype, qclass,
395 qp->q_msg, qp->q_msg + qp->q_msglen)) {
397 "query section mismatch (%s %s %s)",
398 qname, p_class(qclass), p_type(qtype));
402 if (ns_samename(qp->q_name, qname) != 1 ||
403 qp->q_class != qclass ||
404 qp->q_type != qtype) {
405 formerrmsg = wrongQuestion;
409 strcpy(qname, qp->q_name);
410 qclass = qp->q_class;
414 /* cp now points after the query section. */
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.
425 if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN)
426 || (hp->opcode != QUERY
428 && hp->opcode != NS_NOTIFY_OP
431 ns_debug(ns_log_default, 2,
432 "resp: error (ret %d, op %d), dropped",
433 hp->rcode, hp->opcode);
436 nameserIncr(from.sin_addr, nssRcvdFail);
439 nameserIncr(from.sin_addr, nssRcvdFErr);
442 nameserIncr(from.sin_addr, nssRcvdErr);
445 if (ns_samename(qp->q_name, qp->q_domain) == 1 &&
446 hp->rcode == SERVFAIL && hp->opcode == QUERY)
449 fast_retry(qp, from);
454 /* We don't generate or forward these (yet). */
455 formerrmsg = notSingleQuery;
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.
465 for (fwd = NS_ZFWDTAB(qp->q_fzone); fwd; fwd = fwd->next)
466 if (ina_equal(fwd->fwdaddr.sin_addr, from.sin_addr))
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.
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.
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))
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)",
493 * We don't know who this response came from so it
494 * gets dropped on the floor.
500 /* Handle response from different (untried) interface. */
501 if (qs->ns != NULL && stp->tv_sec == 0) {
503 while (qs > qp->q_addr
504 && (qs->stime.tv_sec == 0 || qs->ns != ns))
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?
511 /* XXX - catch aliases here */
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
520 if ((tt.tv_sec - stp->tv_sec) > (INT_MAX-999)/1000) {
523 rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 +
524 (tt.tv_usec - stp->tv_usec) / 1000);
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,
535 /* prevent floating point overflow, limit to 1000 sec */
536 if (rtrip > 1000000) {
541 * Don't update nstime if this doesn't look
542 * like an address databuf now. XXX
546 ns->d_class == qs->ns->d_class) {
549 if (ns->d_nstime == 0)
552 t = ns->d_nstime * ALPHA
557 ns->d_nstime = (u_int16_t)t;
561 * Record the source so that we do not use this NS again.
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);
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
583 for (n = 0, qs = qp->q_addr;
584 (u_int)n < qp->q_naddr;
589 if (!ns2 || ns2 == ns)
591 if (ns2->d_type != T_A ||
592 ns2->d_class != qs->ns->d_class) /* XXX */
594 if (qs->stime.tv_sec) {
595 if (ns2->d_nstime == 0)
598 t = ns2->d_nstime * BETA
602 t = ns2->d_nstime * GAMMA;
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),
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.
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));
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))
636 u_int type, class, dlen;
641 n = dn_expand(msg, eom, tp, name, sizeof name);
643 formerrmsg = expandFailedAnswer;
647 if (tp + 3 * INT16SZ + INT32SZ > eom) {
648 formerrmsg = outofDataAnswer;
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;
662 if (ns_samename(qname, name) != 1 ||
663 qtype != type || qclass != class) {
665 "qserial answer mismatch (%s %s %s)",
666 name, p_class(class), p_type(type));
670 if (0 >= (n = dn_skipname(tp, eom))) {
671 formerrmsg = skipnameFailedAnswer;
675 if (0 >= (n = dn_skipname(tp, eom))) {
676 formerrmsg = skipnameFailedAnswer;
680 if (tp + 5 * INT32SZ > eom) {
681 formerrmsg = dlenUnderrunAnswer;
685 tp += 4 * INT32SZ; /* Skip rest of SOA. */
686 if ((u_int)(tp - rdatap) != dlen) {
687 formerrmsg = dlenOverrunAnswer;
690 for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr;
692 if (ina_equal(qs->ns_addr.sin_addr,
695 if (n == qp->q_naddr) {
707 * Non-authoritative, no answer, no error, with referral.
709 if (hp->rcode == NOERROR && !hp->aa && ancount == 0 && aucount > 0
711 && hp->opcode != NS_NOTIFY_OP
718 res_pquery(&res, msg, msglen,
719 log_get_stream(packet_channel));
722 * Since there is no answer section (ancount == 0),
723 * we must be pointing at the authority section (aucount > 0).
726 n = dn_expand(msg, eom, tp, name, sizeof name);
728 formerrmsg = expandFailedAuth;
732 if (tp + 2 * INT16SZ > eom) {
733 formerrmsg = outofDataAuth;
738 if (!ns_nameok(qp, name, class, NULL, response_trans,
739 ns_ownercontext(type, response_trans),
740 name, from.sin_addr)) {
741 formerrmsg = badNameFound;
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).
754 if (type == T_NS && ns_samedomain(qp->q_domain, name)) {
755 nameserIncr(from.sin_addr, nssRcvdLDel);
759 !haveComplained(ina_ulong(from.sin_addr),
760 nhash(qp->q_domain))) {
761 char *learnt_from = learntFrom(qp, &from);
763 ns_info(ns_log_lame_servers,
764 "Lame server on '%s' (in '%s'?): %s%s",
767 (learnt_from == NULL) ? "" :
769 if (learnt_from != NULL)
770 freestr(learnt_from);
773 fast_retry(qp, from);
779 * Add the info received in the response to the data base.
781 arfirst = ancount + aucount;
782 c = arfirst + arcount;
784 /* Don't return if it's a TSIG signed truncated message */
785 if (has_tsig > 0 && hp->tc)
788 /* -ve $ing non-existence of record, must handle non-authoritative
789 * NOERRORs with c == 0.
791 if (!hp->aa && hp->rcode == NOERROR && c == 0)
794 if (qp->q_flags & Q_SYSTEM)
795 dbflags = DB_NOTAUTH | DB_NODATA;
797 dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS;
799 if (qp->q_flags & Q_PRIMING)
800 dbflags |= DB_PRIMING;
802 count -= arcount; /* truncation had to affect this */
804 count -= aucount; /* guess it got this too */
806 if (!(arcount || aucount)) {
807 count -= ancount; /* things are pretty grim */
811 /* retry using tcp provided this was not a tcp query */
812 if (!(qp->q_flags & Q_USEVC)) {
813 qp->q_flags |= Q_USEVC;
817 nsa = Q_NEXTADDR(qp, 0);
819 key = tsig_key_from_addr(nsa->sin_addr);
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,
831 oldqlen = qp->q_msglen;
832 qp->q_msglen = smsglen;
835 qp->q_nstsig = new_tsig(key, sig,
840 free_tsig(qp->q_nstsig);
847 free_tsig(qp->q_nstsig);
851 if (tcp_send(qp) != NOERROR)
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.
860 memput(qp->q_msg, smsgsize);
862 qp->q_msglen = oldqlen;
866 /* outstanding udp response */
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),
875 /* mark this server as bad */
877 /* try another server, it may have a bigger write buffer */
891 strcpy(aname, qname);
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);
903 for (i = 0; i < count; i++) {
907 freestr_maybe(&tname);
909 free_related_additional();
910 if (flushset != NULL)
911 free_flushset(flushset, flushset_size);
912 formerrmsg = outofDataFinal;
915 n = rrextract(msg, msglen, cp, &dp, name, sizeof name, from,
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)
933 /* Answer section. */
934 if (externalcname || ns_samename(name, aname) != 1) {
936 ns_info(ns_log_resp_checks,
937 "wrong ans. name (%s != %s)",
938 name[0] ? name : ".",
939 aname[0] ? aname : ".");
941 ns_debug(ns_log_resp_checks, 3,
942 "ignoring answer '%s' after external cname",
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))
960 add_related_additional(tname);
964 dp->d_cred = (hp->aa && ns_samename(name, qname) == 1)
968 /* After answer section. */
970 ns_debug(ns_log_resp_checks, 3,
971 "last was cname, ignoring auth. and add.");
976 /* Authority section. */
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 : ".");
987 } else if (!ns_samedomain(name,
990 ns_info(ns_log_resp_checks,
991 "bad referral (%s !< %s)",
992 name[0] ? name : ".",
1000 add_related_additional(tname);
1003 if (type == T_SOA) {
1011 /* XXX check that it relates to an
1015 ns_info(ns_log_resp_checks,
1016 "invalid RR type '%s' in authority section (name = '%s') from %s",
1022 dp->d_cred = (hp->aa && (cname == 0)) ?
1023 DB_C_AUTH : (qp->q_flags & Q_PRIMING)
1027 /* Additional section. */
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));
1039 if (!related_additional(name)) {
1040 ns_info(ns_log_resp_checks,
1041 "unrelated additional info '%s' type %s from %s",
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.
1060 ns_info(ns_log_resp_checks,
1061 "invalid RR type '%s' in additional section (name = '%s') from %s",
1067 dp->d_cred = (qp->q_flags & Q_PRIMING)
1072 rrsetadd(flushset, name, dp);
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);
1081 rrsetupdate(flushset, dbflags, from, 0);
1082 free_flushset(flushset, flushset_size);
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);
1092 formerrmsg = outofDataAFinal;
1096 if ((qp->q_flags & Q_SYSTEM) && ancount) {
1097 if ((qp->q_flags & Q_PRIMING) && !check_root()) {
1098 /* mark server as bad */
1100 fast_retry(qp, from);
1103 ns_debug(ns_log_default, 3,
1104 "resp: leaving, SYSQUERY ancount %d", ancount);
1106 if (qp->q_notifyzone != DB_Z_CACHE) {
1107 struct zoneinfo *zp = &zones[qp->q_notifyzone];
1109 qp->q_notifyzone = DB_Z_CACHE;
1110 ns_notify(zp->z_origin, zp->z_class, ns_t_soa);
1117 if (ancount && count && !validanswer) {
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.
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
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.
1136 if (!restart && !qp->q_cmsglen && ancount > 1 && qtype == T_A)
1137 sort_response(tp, eom, ancount, &qp->q_from);
1140 * An answer to a T_ANY query or a successful answer to a
1141 * regular query with no indirection, then just return answer.
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");
1150 * We might want to cache this negative answer.
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!
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.
1160 if ((hp->rcode == NXDOMAIN && cname == ancount) ||
1161 (hp->rcode == NOERROR && ancount == 0 &&
1162 (nscount == 0 || soacount != 0)
1166 cache_n_resp(msg, msglen, from, qp->q_name,
1167 qp->q_class, qp->q_type);
1169 if (!qp->q_cmsglen) {
1170 ns_debug(ns_log_default, 3,
1171 "resp: leaving NO: auth = %d", hp->aa);
1178 * All messages in here need further processing. i.e. they
1179 * are either CNAMEs or we got referred again.
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
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.
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);
1200 newmsglen = MIN(PACKETSZ, msglen);
1201 memcpy(newmsg, msg, newmsglen);
1203 hp = (HEADER *) newmsg;
1204 hp->ancount = htons(0);
1205 hp->nscount = htons(0);
1206 hp->arcount = htons(0);
1207 hp->rcode = NOERROR;
1210 cp = newmsg + HFIXEDSZ;
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.
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.
1221 n = dn_expand(newmsg, newmsg + newmsglen, cp, dname, sizeof name);
1223 ns_debug(ns_log_default, 1, "dn_expand failed");
1226 if (!res_dnok(dname)) {
1227 ns_debug(ns_log_default, 1, "bad name (%s)", dname);
1231 buflen = sizeof(newmsg) - (cp - newmsg);
1236 ns_debug(ns_log_default, 1, "resp: nlookup(%s) qtype=%d", dname,
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)
1249 count = cp - newmsg;
1251 * Look for NXDOMAIN record.
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)) {
1257 n = finddata(np, qclass, T_SOA, hp, &dname,
1264 hp->nscount = htons((u_int16_t)count);
1266 if (hp->rcode == NOERROR_NODATA) {
1267 hp->rcode = NOERROR;
1274 hp->rcode = NXDOMAIN;
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.
1280 if (!NS_OPTION_P(OPTION_NONAUTH_NXDOMAIN))
1282 ns_debug(ns_log_default, 3, "resp: NXDOMAIN aa = %d",
1284 if ((count == 0) || NS_OPTION_P(OPTION_NORFC2308_TYPE1))
1290 n = finddata(np, qclass, qtype, hp, &dname, &buflen, &count);
1292 goto fetch_ns; /* NO data available */
1294 if (hp->rcode == NOERROR_NODATA)
1295 hp->rcode = NOERROR;
1300 hp->nscount = htons((u_int16_t)count);
1303 if ((count == 0) || NS_OPTION_P(OPTION_NORFC2308_TYPE1))
1310 hp->ancount = htons(ntohs(hp->ancount) + (u_int16_t)count);
1311 if (fname != dname && qtype != T_CNAME && qtype != T_ANY) {
1317 ns_debug(ns_log_default, 3,
1318 "resp: foundname=%d, count=%d, founddata=%d, cname=%d",
1319 foundname, count, founddata, cname);
1321 if (count > 1 && qtype == T_A)
1322 sort_response(answers, cp, count, &qp->q_from);
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).
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)",
1339 hp->rcode = NXDOMAIN;
1340 if (qclass != C_ANY) {
1342 if (np && (!foundname || !founddata)) {
1343 n = doaddauth(hp, cp, buflen, np, nsp[0]);
1355 hp = (HEADER *)newmsg;
1356 n = add_data(np, nsp, cp, buflen, &count);
1363 hp->nscount = htons((u_int16_t)count + ntohs(hp->nscount));
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.
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)",
1381 /* Reset the query control structure */
1383 ns_freeqns(qp, "ns_resp");
1386 nsfwdadd(qp, NS_ZFWDTAB(qp->q_fzone));
1388 if (qp->q_domain != NULL)
1389 freestr(qp->q_domain);
1390 getname(np, tmpdomain, sizeof tmpdomain);
1391 qp->q_domain = savestr(tmpdomain, 1);
1393 if (NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY))
1395 else if ((n = nslookup(nsp, qp, dname, "ns_resp")) <= 0) {
1398 ns_debug(ns_log_default, 3,
1399 "resp: nslookup reports danger");
1400 if (cname) /* a remote CNAME that does not have data */
1404 ns_debug(ns_log_default, 3,
1405 "resp: no addrs found for NS's");
1407 * Timeout while sysquery looks up the NS addresses.
1409 * Hopefully we'll have them when the client asks
1412 * too bad we can't just wait for the sysquery
1413 * response to restart this query (it's too hard).
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.
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;
1428 if (qp->q_cname++ == MAXCNAMES) {
1429 ns_debug(ns_log_default, 3,
1430 "resp: leaving, MAXCNAMES exceeded");
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");
1447 qp->q_msgsize = PACKETSZ;
1448 n = res_nmkquery(&res, QUERY, dname, qclass, qtype,
1449 NULL, 0, NULL, qp->q_msg, PACKETSZ);
1451 ns_info(ns_log_default, "resp: res_mkquery(%s) failed",
1455 if (qp->q_name != NULL)
1456 freestr(qp->q_name);
1457 qp->q_name = savestr(dname, 1);
1459 hp = (HEADER *) qp->q_msg;
1462 hp = (HEADER *) qp->q_msg;
1463 hp->id = qp->q_nsid = htons(nsid_next());
1464 if (qp->q_addr[0].forwarder)
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",
1473 ntohs(qp->q_nsid), ntohs(qp->q_id),
1474 (qp->q_addr[0].nsdata != NULL)
1475 ? qp->q_addr[0].nsdata->d_nstime
1480 res_pquery(&res, qp->q_msg, qp->q_msglen,
1481 log_get_stream(packet_channel));
1483 key = tsig_key_from_addr(nsa->sin_addr);
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,
1493 oldqbuf = qp->q_msg;
1494 oldqlen = qp->q_msglen;
1495 qp->q_msglen = smsglen;
1498 qp->q_nstsig = new_tsig(key, sig, siglen);
1502 free_tsig(qp->q_nstsig);
1503 qp->q_nstsig = NULL;
1509 free_tsig(qp->q_nstsig);
1510 qp->q_nstsig = NULL;
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));
1521 } else if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
1522 (struct sockaddr *)nsa,
1523 sizeof(struct sockaddr_in)) < 0)
1525 sendto_errno = errno;
1526 if (!haveComplained(ina_ulong(nsa->sin_addr),
1528 ns_info(ns_log_default, "ns_resp: sendto(%s): %s",
1529 sin_ntoa(*nsa), strerror(errno));
1530 nameserIncr(nsa->sin_addr, nssSendtoErr);
1532 if (has_tsig == 1) {
1533 memput(qp->q_msg, smsgsize);
1534 qp->q_msg = oldqbuf;
1535 qp->q_msglen = oldqlen;
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.");
1542 switch (sendto_errno) {
1548 schedretry(qp, (time_t) 0);
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);
1561 nameserIncr(from.sin_addr, nssRcvdFwdR);
1562 nameserIncr(qp->q_from.sin_addr, nssSentFwdR);
1563 /* The "standard" return code */
1567 hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
1568 (void) send_msg(msg, msglen, qp);
1574 nameserIncr(qp->q_from.sin_addr, nssSentAns);
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);
1586 hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0);
1587 (void) send_msg(newmsg, cp - newmsg, qp);
1593 hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
1594 hp->rcode = REFUSED;
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),
1607 nameserIncr(qp->q_from.sin_addr, nssSentFail);
1608 hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
1609 hp->rcode = SERVFAIL;
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),
1623 sq_remove(qp->q_stream);
1629 #define BOUNDS_CHECK(ptr, count) \
1631 if ((ptr) + (count) > eom) { \
1632 hp->rcode = FORMERR; \
1638 rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
1639 char *dname, int namelen, struct sockaddr_in from, char **tnamep)
1641 u_char *cp, *eom, *rdatap;
1642 u_int class, type, dlen;
1645 u_char *cp1, data[MAXDATA*2];
1646 HEADER *hp = (HEADER *)msg;
1647 enum context context;
1655 if ((n = dn_expand(msg, eom, cp, dname, namelen)) < 0) {
1656 hp->rcode = FORMERR;
1660 BOUNDS_CHECK(cp, 2*INT16SZ + INT32SZ + INT16SZ);
1662 GETSHORT(class, cp);
1663 if (class > CLASS_MAX) {
1664 ns_debug(ns_log_default, 3, "bad class in rrextract");
1665 hp->rcode = FORMERR;
1669 if (ttl > MAXIMUM_TTL) {
1670 ns_debug(ns_log_default, 5, "%s: converted TTL > %u to 0",
1671 dname, MAXIMUM_TTL);
1675 BOUNDS_CHECK(cp, dlen);
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;
1683 ns_debug(ns_log_default, 3,
1684 "rrextract: dname %s type %d class %d ttl %d",
1685 dname, type, class, ttl);
1687 * Convert the resource record data into the internal
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.
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.
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.
1705 if (dlen != INT32SZ) {
1706 hp->rcode = FORMERR;
1731 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
1733 hp->rcode = FORMERR;
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;
1744 n = strlen((char *)data) + 1;
1745 if (tnamep != NULL && (type == T_NS || type == T_MB))
1746 *tnamep = savestr((char *)cp1, 1);
1750 context = hostname_ctx;
1754 context = mailname_ctx;
1757 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
1759 hp->rcode = FORMERR;
1762 if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans,
1763 context, dname, from.sin_addr)) {
1764 hp->rcode = FORMERR;
1769 * The next use of 'cp' is dn_expand(), so we don't have
1770 * to BOUNDS_CHECK() here.
1772 cp1 = data + (n = strlen((char *)data) + 1);
1773 n1 = sizeof(data) - n;
1776 n = dn_expand(msg, eom, cp, (char *)cp1, n1);
1778 hp->rcode = FORMERR;
1782 context = domain_ctx;
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;
1791 cp1 += strlen((char *)cp1) + 1;
1792 if (type == T_SOA) {
1794 BOUNDS_CHECK(cp, n);
1804 /* Grab weight and port. */
1805 BOUNDS_CHECK(cp, INT16SZ*2);
1806 memcpy(data, cp, INT16SZ*2);
1807 cp1 = data + INT16SZ*2;
1811 BOUNDS_CHECK(cp, 1);
1813 BOUNDS_CHECK(cp, n);
1819 BOUNDS_CHECK(cp, 1);
1821 BOUNDS_CHECK(cp, n);
1827 BOUNDS_CHECK(cp, 1);
1829 BOUNDS_CHECK(cp, n);
1835 n = dn_expand(msg, eom, cp, (char *)cp1,
1836 sizeof data - (cp1 - data));
1838 hp->rcode = FORMERR;
1841 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1842 hostname_ctx, dname, from.sin_addr)) {
1843 hp->rcode = FORMERR;
1848 /* compute end of data */
1849 cp1 += strlen((char *)cp1) + 1;
1850 /* compute size of data */
1859 /* grab preference */
1860 BOUNDS_CHECK(cp, INT16SZ);
1861 memcpy(data, cp, INT16SZ);
1862 cp1 = data + INT16SZ;
1865 if (type == T_SRV) {
1866 /* Grab weight and port. */
1867 BOUNDS_CHECK(cp, INT16SZ*2);
1868 memcpy(cp1, cp, INT16SZ*2);
1874 n = dn_expand(msg, eom, cp, (char *)cp1,
1875 sizeof data - (cp1 - data));
1877 hp->rcode = FORMERR;
1880 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1881 hostname_ctx, dname, from.sin_addr)) {
1882 hp->rcode = FORMERR;
1888 *tnamep = savestr((char *)cp1, 1);
1890 /* compute end of data */
1891 cp1 += strlen((char *)cp1) + 1;
1892 /* compute size of data */
1898 /* grab preference */
1899 BOUNDS_CHECK(cp, INT16SZ);
1900 memcpy(data, cp, INT16SZ);
1901 cp1 = data + INT16SZ;
1904 /* get MAP822 name */
1905 n = dn_expand(msg, eom, cp, (char *)cp1,
1906 sizeof data - INT16SZ);
1908 hp->rcode = FORMERR;
1911 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1912 domain_ctx, dname, from.sin_addr)) {
1913 hp->rcode = FORMERR;
1918 * The next use of 'cp' is dn_expand(), so we don't have
1919 * to BOUNDS_CHECK() here.
1921 cp1 += (n = strlen((char *)cp1) + 1);
1922 n1 = sizeof(data) - n;
1923 n = dn_expand(msg, eom, cp, (char *)cp1, n1);
1925 hp->rcode = FORMERR;
1928 if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans,
1929 domain_ctx, dname, from.sin_addr)) {
1930 hp->rcode = FORMERR;
1934 cp1 += strlen((char *)cp1) + 1;
1940 u_long origTTL, exptime, signtime, timetilexp, now;
1943 /* Check signature time, expiration, and adjust TTL. */
1944 /* This code is similar to that in db_load.c. */
1946 /* Skip coveredType, save alg, skip labels */
1947 BOUNDS_CHECK(cp, INT16SZ + 1 + 1 + 3*INT32SZ);
1951 GETLONG(origTTL, cp1);
1952 GETLONG(exptime, cp1);
1953 GETLONG(signtime, cp1);
1954 now = time(NULL); /* Get current time in GMT/UTC */
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",
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);
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);
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);
1989 /* The following code is copied from named-xfer.c. */
1990 cp1 = (u_char *)data;
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);
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;
2006 cp1 += strlen((char*)cp1)+1;
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);
2012 if (n > (sizeof data) - (cp1 - (u_char *)data)) {
2013 hp->rcode = FORMERR;
2014 return (-1); /* out of room! */
2019 if (n < NS_MD5RSA_MIN_SIZE || n > NS_MD5RSA_MAX_SIZE)
2020 hp->rcode = FORMERR;
2024 if (n != NS_DSA_SIG_SIZE)
2025 hp->rcode = FORMERR;
2032 if (hp->rcode == FORMERR)
2039 /* compute size of data */
2040 n = cp1 - (u_char *)data;
2041 cp1 = (u_char *)data;
2046 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
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.
2053 if (n < 0 || n >= dlen) {
2054 hp->rcode = FORMERR;
2057 if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans,
2058 domain_ctx, dname, from.sin_addr)) {
2059 hp->rcode = FORMERR;
2063 n1 = strlen((char *)data) + 1;
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.
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.
2077 if ((*cp & 0x80) == 0) {
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.
2085 if (n2 < 4 || n2 > 16) {
2086 hp->rcode = FORMERR;
2090 if (n2 > sizeof data - n1) {
2091 hp->rcode = FORMERR;
2094 memcpy(cp1, cp, n2);
2097 /* compute size of data */
2098 n = cp1 - (u_char *)data;
2099 cp1 = (u_char *)data;
2103 ns_debug(ns_log_default, 3, "unknown type %d", type);
2104 return ((cp - rrp) + dlen);
2108 hp->rcode = FORMERR;
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;
2119 ns_debug(ns_log_default, 1,
2120 "update type %d: %d bytes is too much data",
2122 hp->rcode = FORMERR;
2127 *dpp = savedata(class, type, ttl, cp1, n);
2132 send_msg(u_char *msg, int msglen, struct qinfo *qp) {
2133 HEADER *hp = (HEADER *) msg;
2139 if (qp->q_flags & Q_SYSTEM)
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,
2151 if (ns_wouldlog(ns_log_default, 4)) {
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);
2168 res_pquery(&res, msg, msglen, log_get_stream(packet_channel));
2171 if (qp->q_tsig != NULL) {
2172 u_char sig[TSIG_SIG_SIZE];
2173 int siglen = sizeof(sig);
2178 msgsize = msglen + TSIG_BUF_SIZE;
2179 msg = memget(msgsize);
2180 memcpy(msg, oldmsg, oldlen);
2182 ret = ns_sign(msg, &msglen, msgsize, NOERROR, qp->q_tsig->key,
2183 qp->q_tsig->sig, qp->q_tsig->siglen,
2191 if (qp->q_stream == NULL) {
2193 * Don't send FORMERR to these well known ports
2196 switch (ntohs(qp->q_from.sin_port)) {
2198 case 13: /* daytime */
2199 case 19: /* chargen */
2201 if (hp->rcode == FORMERR)
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),
2211 #if defined(SPURIOUS_ECONNREFUSED)
2212 if (errno != ECONNREFUSED)
2214 ns_info(ns_log_default,
2215 "send_msg: sendto(%s): %s",
2216 sin_ntoa(qp->q_from),
2218 nameserIncr(qp->q_from.sin_addr, nssSendtoErr);
2222 writestream(qp->q_stream, (u_char*)msg, msglen);
2224 if (qp->q_tsig != NULL)
2225 memput(msg, oldlen + TSIG_BUF_SIZE);
2231 root_server_p(ns_class class) {
2232 struct zoneinfo *zp = find_zone("", class);
2234 return (zp != NULL &&
2235 (zp->z_type == z_master || zp->z_type == z_slave));
2240 int root = root_server_p(ns_c_in);
2242 ns_debug(ns_log_default, 1, "prime_cache: priming = %d, root = %d",
2244 if (!priming && !root) {
2245 struct qinfo *qp = sysquery("", ns_c_in, ns_t_ns,
2246 NULL, 0, ns_port, ns_o_query);
2249 qp->q_flags |= (Q_SYSTEM | Q_PRIMING);
2253 needs_prime_cache = 0;
2257 sysquery(const char *dname, int class, int type,
2258 struct in_addr *nss, int nsc, u_int16_t port, int opcode)
2260 struct qinfo *qp, *oqp;
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;
2271 int sendto_errno = 0;
2273 int oldqlen, has_tsig;
2275 int smsglen, smsgsize, siglen;
2276 u_char sig[TSIG_SIG_SIZE];
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);
2284 if (nss != NULL && nsc != 0)
2286 else if (!NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) {
2290 if (priming && dname[0] == '\0') {
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?",
2303 n = findns(&np, class, nsp, &count, 0);
2307 ns_info(ns_log_default,
2308 "sysquery: findns error (%s) on %s?",
2309 n == NXDOMAIN ? "NXDOMAIN" : "SERVFAIL",
2317 /* Build new qinfo struct. */
2318 qp->q_cmsg = qp->q_msg = NULL;
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;
2325 getname(np, tmpdomain, sizeof tmpdomain);
2326 qp->q_domain = savestr(tmpdomain, 1);
2328 if ((qp->q_msg = (u_char *)memget(PACKETSZ)) == NULL) {
2329 ns_notice(ns_log_default, "sysquery: memget failed");
2332 qp->q_msgsize = PACKETSZ;
2333 n = res_nmkquery(&res, opcode, dname, class,
2334 type, NULL, 0, NULL,
2335 qp->q_msg, PACKETSZ);
2337 ns_info(ns_log_default,
2338 "sysquery: res_mkquery(%s) failed", dname);
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);
2346 /* First check for an already pending query for this data. */
2347 for (oqp = nsqhead; oqp != NULL; oqp = oqp->q_link) {
2349 && (oqp->q_msglen == qp->q_msglen)
2350 && memcmp(oqp->q_msg+2, qp->q_msg + 2,
2351 qp->q_msglen - 2) == 0
2354 /* XXX - need fancier test to suppress duplicate
2355 * NOTIFYs to the same server (compare nss?)
2357 if (opcode != NS_NOTIFY_OP)
2358 #endif /*BIND_NOTIFY*/
2360 ns_debug(ns_log_default, 3,
2361 "sysquery: duplicate");
2367 if (nss != NULL && nsc != 0) {
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;
2382 } else if (!NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) {
2384 count = nslookup(nsp, qp, dname, "sysquery");
2388 ns_info(ns_log_default,
2389 "sysquery: nslookup reports danger (%s)",
2392 } else if (np && NAME(*np)[0] == '\0') {
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
2401 * XXX - should we skip setting
2402 * needs_prime_cache as well?
2404 * XXX - what happens when we implement
2405 * selective forwarding?
2407 if (!NS_OPTION_P(OPTION_FORWARD_ONLY))
2408 ns_warning(ns_log_default,
2409 "sysquery: no addrs found for root NS (%s)",
2411 if (class == C_IN && !priming)
2412 needs_prime_cache = 1;
2419 n = findns(&np, class, nsp, &count, 0);
2421 case NXDOMAIN: /*FALLTHROUGH*/
2423 ns_info(ns_log_default,
2424 "sysquery: findns error (%d) on %s?",
2428 getname(np, tmpdomain, sizeof tmpdomain);
2429 if (qp->q_domain != NULL)
2430 freestr(qp->q_domain);
2431 qp->q_domain = savestr(tmpdomain, 1);
2438 schedretry(qp, retrytime(qp));
2439 qp->q_addr[0].stime = tt; /* XXX - why not every? */
2440 nsa = Q_NEXTADDR(qp, 0);
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),
2449 res_pquery(&res, qp->q_msg, qp->q_msglen,
2450 log_get_stream(packet_channel));
2453 key = tsig_key_from_addr(nsa->sin_addr);
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,
2463 oldqbuf = qp->q_msg;
2464 oldqlen = qp->q_msglen;
2465 qp->q_msglen = smsglen;
2468 qp->q_nstsig = new_tsig(key, sig, siglen); /* BEW? */
2474 free_tsig(qp->q_nstsig);
2475 qp->q_nstsig = NULL;
2480 free_tsig(qp->q_nstsig);
2481 qp->q_nstsig = NULL;
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),
2490 ns_info(ns_log_default, "sysquery: sendto(%s): %s",
2491 sin_ntoa(*nsa), strerror(errno));
2492 nameserIncr(nsa->sin_addr, nssSendtoErr);
2494 if (has_tsig == 1) {
2495 memput(qp->q_msg, smsgsize);
2496 qp->q_msg = oldqbuf;
2497 qp->q_msglen = oldqlen;
2500 nameserIncr(nsa->sin_addr, nssSentSysQ);
2502 switch (sendto_errno) {
2508 schedretry(qp, (time_t) 0);
2514 * Check the list of root servers after receiving a response
2515 * to a query for the root servers.
2519 struct databuf *dp, *pdp;
2524 for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next)
2525 if (NAME(*np)[0] == '\0')
2528 ns_notice(ns_log_default, "check_root: Can't find root!");
2531 for (dp = np->n_data; dp != NULL; dp = dp->d_next)
2532 if (dp->d_type == T_NS)
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",
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'",
2549 dp = rm_datum(dp, np, pdp, NULL);
2550 /* SHOULD DELETE FROM HINTS ALSO */
2565 * Check the root to make sure that for each NS record we have a A RR
2569 struct databuf *dp, *tdp;
2570 struct namebuf *np, *tnp;
2571 struct hashbuf *htp;
2576 int servers = 0, rrsets = 0;
2578 ns_debug(ns_log_default, 2, "check_ns()");
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')
2584 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2590 if (dp->d_type != T_NS)
2595 /* look for A records */
2596 dname = (caddr_t) dp->d_data;
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,
2607 /* look for name server addresses */
2609 (void)delete_stale(tnp);
2610 for (tdp = tnp->n_data;
2612 tdp = tdp->d_next) {
2615 if (tdp->d_type == T_CNAME)
2617 if (tdp->d_type != T_A ||
2618 tdp->d_class != dp->d_class)
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'",
2632 else if (cnames > 0)
2633 ns_info(ns_log_default,
2634 "Root NS %s -> CNAME %s",
2635 NAME(*np), NAME(*tnp));
2637 sysquery(dname, dp->d_class, T_A, NULL,
2642 ns_debug(ns_log_default, 2, "check_ns: %d %d", servers, rrsets);
2643 return ((servers <= 2)
2644 ? (rrsets == servers)
2645 : ((rrsets * 2) >= servers)
2649 /* int findns(npp, class, nsp, countp, flag)
2650 * Find NS's or an SOA
2652 * dname whose most enclosing NS is wanted
2654 * result array and count; array will also be NULL terminated
2656 * boolean: we're being called from ADDAUTH, bypass authority checks
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.
2666 findns(struct namebuf **npp, int class,
2667 struct databuf **nsp, int *countp, int flag)
2669 struct namebuf *np = *npp;
2671 struct databuf **nspp;
2672 struct hashbuf *htp;
2676 if (priming && (np == NULL || NAME(*np)[0] == '\0'))
2682 if (htp == fcachetab && class == C_IN && !priming)
2684 * XXX - do we want to set needs_prime_cache if
2685 * OPTION_FORWARD_ONLY?
2687 needs_prime_cache = 1;
2690 for (np = htp->h_tab[0]; np != NULL; np = np->n_next)
2691 if (NAME(*np)[0] == '\0')
2694 while (np != NULL) {
2695 ns_debug(ns_log_default, 5, "findns: np %#x '%s'", np,
2697 /* Look first for SOA records. */
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) {
2715 /* XXX: zone isn't loaded but we're
2716 * primary or secondary for it.
2717 * should we fwd this?
2724 /* If no SOA records, look for NS records. */
2727 (void)delete_stale(np);
2728 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
2729 if (!match(dp, class, T_NS))
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!
2738 * XXX: this is horribly bogus.
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'",
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
2753 while (nspp > &nsp[0]) {
2760 if (nspp < &nsp[NSMAX-1]) {
2766 *countp = nspp - nsp;
2768 ns_debug(ns_log_default, 3,
2769 "findns: %d NS's added for '%s'",
2770 *countp, NAME(*np));
2773 return (OK); /* Success, got some NS's */
2778 if (htp == hashtab) {
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",
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.
2799 finddata(struct namebuf *np, int class, int type,
2800 HEADER *hp, char **dnamep, int *lenp, int *countp)
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;
2813 stalecount = delete_stale(np);
2815 /* We don't want to return cached SIG records when asked for SIGs,
2816 * since we may have an incomplete set.
2818 if (type == T_SIG && findMyZone(np, class) == DB_Z_CACHE)
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");
2832 if (buflen > PACKETSZ)
2833 ns_debug(ns_log_default, 1, "finddata(): buflen=%d", buflen);
2835 cp = ((char *)hp) + *countp;
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) {
2850 if (dp->d_cred == DB_C_ADDITIONAL) {
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
2860 dp->d_ttl = tt.tv_sec
2862 0.95 * (int) (dp->d_ttl - tt.tv_sec);
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
2869 if (dp->d_rcode == NOERROR_NODATA) {
2872 * This should not happen, yet it does...
2874 ns_info(ns_log_default,
2875 "NODATA & data for \"%s\" type %d class %d",
2876 *dnamep, type, class);
2881 hp->rcode = NOERROR_NODATA;
2882 if (dp->d_size == 0) { /* !RETURNSOA */
2887 if (dp->d_rcode == NXDOMAIN) {
2890 * This should not happen, yet it might...
2892 ns_info(ns_log_default,
2893 "NXDOMAIN & data for \"%s\" type %d class %d",
2894 *dnamep, type, class);
2897 hp->rcode = NXDOMAIN;
2898 if (dp->d_size == 0) { /* !RETURNSOA */
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))) )
2911 if (foundcname != 0 && dp->d_type == T_CNAME)
2914 if ((n = make_rr(*dnamep, dp, (u_char *)cp, buflen, 1,
2915 dnptrs, dnptrs_end, 0)) < 0) {
2917 ret = *lenp - buflen;
2920 if (dp->d_secure != DB_S_SECURE)
2926 if (dp->d_type == T_CNAME) {
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 */
2932 if (FOLLOWCNAME(type))
2933 new_dnamep = (char *)dp->d_data;
2936 if (dp->d_type == T_CNAME)
2938 found[found_count++] = dp;
2942 if (found_count == 0 && count == 0) {
2948 * If the query type was SIG or ANY we will have returned the SIG
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))
2955 if (dp->d_cred == DB_C_ADDITIONAL) {
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
2965 dp->d_ttl = tt.tv_sec
2967 0.95 * (int) (dp->d_ttl - tt.tv_sec);
2971 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
2972 buflen, 1, dnptrs, dnptrs_end,
2975 ret = *lenp - buflen;
2978 if (dp->d_secure != DB_S_SECURE)
2984 found[found_count++] = dp;
2988 if (defer && found_count > 0) {
2991 int sig_count; /* number of SIG records in found */
2993 enum ordering order;
2995 order = match_order(np, class, foundcname ? T_CNAME : type);
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.
3004 for (idx = jdx = 0 ; idx < found_count ; idx++) {
3005 if (found[idx]->d_type != T_SIG) {
3006 tmpfound[jdx++] = found[idx];
3009 non_sig_count = jdx;
3010 sig_count = found_count - jdx;
3013 /* now shift the SIG records down to the end of the array
3014 * and copy in the non-SIG records
3016 for (i = idx = found_count - 1 ; idx >= 0 ; idx--) {
3017 if (i < non_sig_count) {
3018 found[i] = tmpfound[i];
3020 } else if (found[idx]->d_type == T_SIG) {
3021 found[i--] = found[idx] ;
3028 for (i = 0; i < found_count; i++) {
3030 if (foundcname != 0 && dp->d_type == T_CNAME)
3032 if (dp->d_type == T_CNAME) {
3034 if (FOLLOWCNAME(type)) {
3035 new_dnamep = (char *)dp->d_data;
3038 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3040 dnptrs, dnptrs_end, 0)) < 0) {
3042 ret = *lenp - buflen;
3045 if (dp->d_secure != DB_S_SECURE)
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;
3060 found[choice] = found[non_sig_count];
3061 if (foundcname != 0 && dp->d_type == T_CNAME)
3063 if (dp->d_type == T_CNAME) {
3065 if (FOLLOWCNAME(type)) {
3066 new_dnamep = (char *)dp->d_data;
3069 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3071 dnptrs, dnptrs_end, 0)) < 0) {
3073 ret = *lenp - buflen;
3076 if (dp->d_secure != DB_S_SECURE)
3083 /* now shuffle the SIG records */
3085 for (i = 0; i < iters; i++) {
3086 choice = ((u_int)rand()>>3) % sig_count;
3087 choice += first_sig;
3090 found[choice] = found[sig_count + first_sig];
3091 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3093 dnptrs, dnptrs_end, 0)) < 0) {
3095 ret = *lenp - buflen;
3098 if (dp->d_secure != DB_S_SECURE)
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)
3114 if (dp->d_type == T_CNAME) {
3116 if (FOLLOWCNAME(type)) {
3117 new_dnamep = (char *)dp->d_data;
3120 if ((n = make_rr(*dnamep, dp, (u_char *)cp,
3122 dnptrs, dnptrs_end, 0)) < 0) {
3124 ret = *lenp - buflen;
3127 if (dp->d_secure != DB_S_SECURE)
3134 /* now do the SIG record rotation. */
3135 if (sig_count > 0) {
3136 choice = ((u_int)rand()>>3) % sig_count;
3137 choice += first_sig;
3141 if ((n = make_rr(*dnamep, dp,
3145 dnptrs_end, 0)) < 0) {
3147 ret = *lenp - buflen;
3150 if (dp->d_secure != DB_S_SECURE)
3156 if (i >= found_count)
3158 } while (i != choice);
3164 ns_warning(ns_log_default, "finddata: unknown ordering: %d",
3170 if (new_dnamep != NULL)
3171 *dnamep = new_dnamep;
3173 ns_debug(ns_log_default, 3, "finddata: added %d class %d type %d RRs",
3174 count, class, type);
3175 ret = *lenp - buflen;
3178 memput(found, (stalecount + 1) * sizeof *found);
3179 if (tmpfound != NULL)
3180 memput(tmpfound, (stalecount + 1) * sizeof *tmpfound);
3186 * Do we want this data record based on the class and type?
3189 wanted(const struct databuf *dp, int class, int type) {
3194 char pclass[15], ptype[15];
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]",
3202 p_class(dp->d_class), p_type(dp->d_type));
3205 if (dp->d_class != class && class != C_ANY)
3208 * Must check SIG for expiration below, other matches
3211 if (type == dp->d_type && (type != T_SIG))
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)
3217 /* First, look at the type of RR. */
3218 switch (dp->d_type) {
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.
3227 GETSHORT(coveredType, cp);
3228 cp += INT16SZ + INT32SZ; /* skip alg, labels, & orig TTL */
3229 GETLONG(expiration,cp);
3231 if (type == T_ANY || type == T_SIG) {
3232 if (expiration > time(0))
3233 return (1); /* Unexpired matching SIG */
3235 return (0); /* We don't return this SIG. */
3240 if (dp->d_rcode != NOERROR_NODATA)
3245 /* OK, now look at the type of query. */
3246 if (type == ns_t_any)
3248 else if (type == ns_t_mailb)
3249 switch (dp->d_type) {
3256 else if (ns_t_xfr_p(type)) {
3258 * This is used to validate transfer requests, not
3259 * generate transfer responses. Is there an SOA?
3261 if (dp->d_type == ns_t_soa && dp->d_zone != DB_Z_CACHE
3262 && (zones[dp->d_zone].z_flags & Z_AUTH))
3269 wantedsig(const struct databuf *dp, int class, int type) {
3274 char pclass[15], ptype[15];
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]",
3282 p_class(dp->d_class), p_type(dp->d_type));
3285 if (dp->d_class != class && class != C_ANY)
3287 if (dp->d_type != T_SIG || dp->d_rcode != 0)
3291 GETSHORT(coveredType, cp);
3292 cp += INT16SZ + INT32SZ; /* skip alg, labels, & orig TTL */
3293 GETLONG(expiration,cp);
3294 if (expiration < time(0))
3297 if (type == T_ANY || type == T_SIG || type == coveredType)
3299 if (type == ns_t_mailb) {
3300 switch (coveredType) {
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.
3318 add_data(struct namebuf *np, struct databuf **dpp,
3319 u_char *cp, int buflen, int *countp)
3322 char dname[MAXDNAME];
3325 bytes = *countp = 0;
3326 getname(np, dname, sizeof(dname));
3327 for (dp = *dpp++; dp != NULL; dp = *dpp++) {
3329 continue; /* ignore old cache entry */
3332 if ((n = make_rr(dname, dp, cp, buflen, 1,
3333 dnptrs, dnptrs_end, 0)) < 0)
3334 return (-bytes); /* Truncation */
3344 rrsetadd(struct flush_set *flushset, const char *name, struct databuf *dp) {
3345 struct flush_set *fs = flushset;
3346 struct db_list *dbl;
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))) {
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;
3363 dbl = (struct db_list *)memget(sizeof(struct db_list));
3365 panic("rrsetadd: out of memory", NULL);
3366 dbl->db_next = NULL;
3368 if (fs->fs_last == NULL)
3371 fs->fs_last->db_next = dbl;
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;
3382 struct db_list *dbp = dbl;
3384 u_int32_t ttl = 0; /* Make gcc happy. */
3388 np = nlookup(name, &htp, &fname, 0);
3389 if (np == NULL || fname != name || ns_wildcard(NAME(*np)))
3392 /* check that all the ttl's we have are the same, if not return 1 */
3394 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3395 if (!match(dp, class, type))
3398 /* we can't update zone data so return early */
3399 if (dp->d_zone != DB_Z_CACHE)
3403 } else if (ttl != dp->d_ttl)
3407 /* there are no records of this type in the cache */
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.
3416 /* check that all the ttl's we have are the same, if not return 0 */
3420 ttl = dbp->db_dp->d_ttl;
3422 } else if (ttl != dbp->db_dp->d_ttl) {
3428 /* update ttl if required */
3430 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3431 if (!match(dp, class, type))
3433 if (dp->d_ttl > ttl)
3444 * lookup rrset in table and compare to dbl
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;
3458 struct db_list *dbp = dbl;
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");
3469 /* check that all entries in dbl are in the cache */
3471 for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
3472 if (!match(dp, class, type))
3475 if (!db_cmp(dp, dbp->db_dp)
3477 && ((dp->d_cred == dbp->db_dp->d_cred) ||
3478 (dp->d_cred != DB_C_ADDITIONAL))
3484 ns_debug(ns_log_default, 3,
3485 "rrsetcmp: %srecord%s in database",
3486 exists ? "" : "no ", exists ? " not" : "s");
3487 return (exists ? 1 : -1);
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))
3502 if (!db_cmp(dp, dbp->db_dp))
3507 ns_debug(ns_log_default, 3,
3508 "rrsetcmp: record not in rrset");
3512 ns_debug(ns_log_default, 3, "rrsetcmp: rrsets matched");
3517 * verify incoming answer against what we already have in the hints
3518 * issue warnings / errors if differences detected.
3522 check_hints(struct flush_set * flushset) {
3523 struct zoneinfo *zp;
3524 struct flush_set *fs;
3525 struct db_list *dbp;
3527 /* We don't use hints when in forward only mode */
3528 if (NS_OPTION_P(OPTION_FORWARD_ONLY))
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))
3536 /* see if we are a root server */
3537 zp = find_zone(fs->fs_name, fs->fs_class);
3539 (zp->z_type == z_master || zp->z_type == z_slave))
3541 switch (rrsetcmp(fs->fs_name, fs->fs_list, fcachetab)) {
3543 ns_error(ns_log_default,
3544 "check_hints: no NS records for class %d in hints",
3548 ns_warning(ns_log_default,
3549 "check_hints: root NS list in hints for class %d does not match root NS list",
3555 ns_error(ns_log_default,
3556 "check_hints: unexpected response from rrsetcmp");
3562 if (fs->fs_name == NULL) /* no root NS records */
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)
3572 switch (rrsetcmp(fs->fs_name, fs->fs_list, fcachetab)) {
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 : ".",
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 : ".",
3588 ns_error(ns_log_default,
3589 "check_hints: unexpected response from rrsetcmp");
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);
3605 rrsetupdate(struct flush_set * flushset, int flags, struct sockaddr_in from,
3607 struct flush_set *fs = flushset;
3608 struct db_list *dbp, *odbp;
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)) {
3618 flushrrset(fs, from);
3622 n = db_set_update(fs->fs_name, dbp->db_dp,
3624 &hashtab, from, NULL,
3626 ns_debug(ns_log_default, 3,
3627 "rrsetupdate: %s %d",
3628 fs->fs_name[0] ? fs->fs_name : ".",
3632 memput(odbp, sizeof *odbp);
3634 ns_debug(ns_log_default, 3,
3635 "rrsetupdate: %s %d",
3636 fs->fs_name[0] ? fs->fs_name : ".", n);
3638 if ((n == 0) && updatettl)
3639 (void)ttlcheck(fs->fs_name,fs->fs_list, 1);
3642 db_freedata(dbp->db_dp);
3645 memput(odbp, sizeof *odbp);
3651 n = db_set_update(NULL, NULL, &state, flags, &hashtab, from,
3656 flushrrset(struct flush_set * fs, struct sockaddr_in from) {
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;
3668 n = db_update(fs->fs_name, dp, NULL, NULL, DB_DELETE, hashtab,
3670 ns_debug(ns_log_default, 3, "flushrrset: %d", n);
3676 free_flushset(struct flush_set *flushset, int flushset_size) {
3677 struct flush_set *fs;
3679 for (fs = flushset; fs->fs_name != NULL; fs++)
3680 freestr(fs->fs_name);
3681 memput(flushset, flushset_size);
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.
3692 delete_all(struct namebuf *np, int class, int type) {
3693 struct databuf *dp, *pdp;
3695 ns_debug(ns_log_default, 3, "delete_all(%#x:\"%s\" %s %s)",
3696 np, NAME(*np), p_class(class), p_type(type));
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);
3711 * for all RRs associated with this name, check for staleness (& delete)
3713 * np = pointer to namebuf to be cleaned.
3715 * number of RRs associated with this name.
3717 * delete_all() can be called, freeing memory and relinking chains.
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);
3739 * Adjust answer message so that it fits in outlen. Set tc if required.
3741 * If outlen = msglen, can be used to verify qdcount, ancount, nscount
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;
3754 eom_in = msg + msglen;
3755 eom_out = msg + outlen;
3758 qdcount = ntohs(hp->qdcount);
3759 ancount = ntohs(hp->ancount);
3760 nscount = ntohs(hp->nscount);
3761 arcount = ntohs(hp->arcount);
3764 while ((qdcount || ancount || nscount || arcount) &&
3765 cp < eom_in && cp < eom_out) {
3767 cp1 = cp; /* use temporary in case we break */
3769 n = dn_skipname(cp1, eom_in);
3772 cp1 += n + 2 * INT16SZ; /* type, class */
3775 cp1 += INT32SZ; /* ttl */
3776 if (cp1 + INT16SZ > eom_in)
3778 GETSHORT(dlen, cp1);
3782 if (cp1 > eom_in || cp1 > eom_out)
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);
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);
3810 ENSURE(cp <= eom_out);
3815 * mark the server "from" bad in the qp structure so it won't be retried.
3818 mark_bad(struct qinfo *qp, struct sockaddr_in from) {
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;
3827 mark_lame(struct qinfo *qp, struct sockaddr_in from) {
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);
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.
3846 fast_retry(struct qinfo *qp, struct sockaddr_in from) {
3847 if (ina_equal(qp->q_addr[qp->q_curaddr].ns_addr.sin_addr,
3853 add_related_additional(char *name) {
3856 if (num_related >= MAX_RELATED - 1)
3858 for (i = 0; i < num_related; i++)
3859 if (ns_samename(name, related[i]) == 1) {
3863 related[num_related++] = name;
3867 free_related_additional() {
3870 for (i = 0; i < num_related; i++)
3871 freestr(related[i]);
3876 related_additional(char *name) {
3879 for (i = 0; i < num_related; i++)
3880 if (ns_samename(name, related[i]) == 1)
3886 freestr_maybe(char **tname) {
3887 if (tname == NULL || *tname == NULL)
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.
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;
3903 return (DEFAULT_ORDERING);
3905 for (roe = orders->first ; roe != NULL ; roe = roe->next) {
3906 if (roe->class != C_ANY && roe->class != class)
3908 if (roe->type != T_ANY && roe->type != type)
3911 if (match_name(np, roe->name, strlen(roe->name)) == 0) {
3912 return (roe->order);
3916 /* none matched so use default */
3917 return (DEFAULT_ORDERING);
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.
3928 match_name(const struct namebuf *np, const char *name, size_t namelen)
3932 if (name[0] == '*' && name[1] == '\0')
3935 if (np->n_parent != NULL) { /* recurse to end of np list */
3936 matched = match_name(np->n_parent,name,namelen);
3942 int labellen = NAMELEN(*np);
3946 if (labellen > matched) {
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);
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 */
3967 return (start - name - 1); /* matched '.' too */