Home | History | Annotate | Line # | Download | only in ns
query.c revision 1.1
      1 /*	$NetBSD: query.c,v 1.1 2018/08/12 12:08:07 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * This Source Code Form is subject to the terms of the Mozilla Public
      7  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9  *
     10  * See the COPYRIGHT file distributed with this work for additional
     11  * information regarding copyright ownership.
     12  */
     13 
     14 /*! \file */
     15 
     16 #include <config.h>
     17 
     18 #include <string.h>
     19 
     20 #include <isc/hex.h>
     21 #include <isc/mem.h>
     22 #include <isc/print.h>
     23 #include <isc/random.h>
     24 #include <isc/rwlock.h>
     25 #include <isc/serial.h>
     26 #include <isc/stats.h>
     27 #include <isc/string.h>
     28 #include <isc/thread.h>
     29 #include <isc/util.h>
     30 
     31 #include <dns/adb.h>
     32 #include <dns/badcache.h>
     33 #include <dns/byaddr.h>
     34 #include <dns/cache.h>
     35 #include <dns/db.h>
     36 #include <dns/dlz.h>
     37 #include <dns/dns64.h>
     38 #include <dns/dnsrps.h>
     39 #include <dns/dnssec.h>
     40 #include <dns/events.h>
     41 #include <dns/keytable.h>
     42 #include <dns/message.h>
     43 #include <dns/ncache.h>
     44 #include <dns/nsec.h>
     45 #include <dns/nsec3.h>
     46 #include <dns/order.h>
     47 #include <dns/rdata.h>
     48 #include <dns/rdataclass.h>
     49 #include <dns/rdatalist.h>
     50 #include <dns/rdataset.h>
     51 #include <dns/rdatasetiter.h>
     52 #include <dns/rdatastruct.h>
     53 #include <dns/rdatatype.h>
     54 #include <dns/resolver.h>
     55 #include <dns/result.h>
     56 #include <dns/stats.h>
     57 #include <dns/tkey.h>
     58 #include <dns/types.h>
     59 #include <dns/view.h>
     60 #include <dns/zone.h>
     61 #include <dns/zt.h>
     62 
     63 #include <ns/client.h>
     64 #include <ns/interfacemgr.h>
     65 #include <ns/log.h>
     66 #include <ns/server.h>
     67 #include <ns/sortlist.h>
     68 #include <ns/stats.h>
     69 #include <ns/xfrout.h>
     70 
     71 #include "hooks.h"
     72 
     73 #if 0
     74 /*
     75  * It has been recommended that DNS64 be changed to return excluded
     76  * AAAA addresses if DNS64 synthesis does not occur.  This minimises
     77  * the impact on the lookup results.  While most DNS AAAA lookups are
     78  * done to send IP packets to a host, not all of them are and filtering
     79  * excluded addresses has a negative impact on those uses.
     80  */
     81 #define dns64_bis_return_excluded_addresses 1
     82 #endif
     83 
     84 /*%
     85  * Maximum number of chained queries before we give up
     86  * to prevent CNAME loops.
     87  */
     88 #define MAX_RESTARTS 16
     89 
     90 #define QUERY_ERROR(qctx, r) \
     91 do { \
     92 	qctx->result = r; \
     93 	qctx->want_restart = ISC_FALSE; \
     94 	qctx->line = __LINE__; \
     95 } while (0)
     96 
     97 #define RECURSE_ERROR(qctx, r) \
     98 do { \
     99 	if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \
    100 		QUERY_ERROR(qctx, r); \
    101 	else \
    102 		QUERY_ERROR(qctx, DNS_R_SERVFAIL); \
    103 } while (0)
    104 
    105 /*% Partial answer? */
    106 #define PARTIALANSWER(c)	(((c)->query.attributes & \
    107 				  NS_QUERYATTR_PARTIALANSWER) != 0)
    108 /*% Use Cache? */
    109 #define USECACHE(c)		(((c)->query.attributes & \
    110 				  NS_QUERYATTR_CACHEOK) != 0)
    111 /*% Recursion OK? */
    112 #define RECURSIONOK(c)		(((c)->query.attributes & \
    113 				  NS_QUERYATTR_RECURSIONOK) != 0)
    114 /*% Recursing? */
    115 #define RECURSING(c)		(((c)->query.attributes & \
    116 				  NS_QUERYATTR_RECURSING) != 0)
    117 /*% Cache glue ok? */
    118 #define CACHEGLUEOK(c)		(((c)->query.attributes & \
    119 				  NS_QUERYATTR_CACHEGLUEOK) != 0)
    120 /*% Want Recursion? */
    121 #define WANTRECURSION(c)	(((c)->query.attributes & \
    122 				  NS_QUERYATTR_WANTRECURSION) != 0)
    123 /*% Is TCP? */
    124 #define TCP(c)			(((c)->attributes & NS_CLIENTATTR_TCP) != 0)
    125 
    126 /*% Want DNSSEC? */
    127 #define WANTDNSSEC(c)		(((c)->attributes & \
    128 				  NS_CLIENTATTR_WANTDNSSEC) != 0)
    129 /*% Want WANTAD? */
    130 #define WANTAD(c)		(((c)->attributes & \
    131 				  NS_CLIENTATTR_WANTAD) != 0)
    132 /*% Client presented a valid COOKIE. */
    133 #define HAVECOOKIE(c)		(((c)->attributes & \
    134 				  NS_CLIENTATTR_HAVECOOKIE) != 0)
    135 /*% Client presented a COOKIE. */
    136 #define WANTCOOKIE(c)		(((c)->attributes & \
    137 				  NS_CLIENTATTR_WANTCOOKIE) != 0)
    138 /*% Client presented a CLIENT-SUBNET option. */
    139 #define HAVEECS(c)		(((c)->attributes & \
    140 				  NS_CLIENTATTR_HAVEECS) != 0)
    141 /*% No authority? */
    142 #define NOAUTHORITY(c)		(((c)->query.attributes & \
    143 				  NS_QUERYATTR_NOAUTHORITY) != 0)
    144 /*% No additional? */
    145 #define NOADDITIONAL(c)		(((c)->query.attributes & \
    146 				  NS_QUERYATTR_NOADDITIONAL) != 0)
    147 /*% Secure? */
    148 #define SECURE(c)		(((c)->query.attributes & \
    149 				  NS_QUERYATTR_SECURE) != 0)
    150 /*% DNS64 A lookup? */
    151 #define DNS64(c)		(((c)->query.attributes & \
    152 				  NS_QUERYATTR_DNS64) != 0)
    153 
    154 #define DNS64EXCLUDE(c)		(((c)->query.attributes & \
    155 				  NS_QUERYATTR_DNS64EXCLUDE) != 0)
    156 
    157 #define REDIRECT(c)		(((c)->query.attributes & \
    158 				  NS_QUERYATTR_REDIRECT) != 0)
    159 
    160 /*% Does the rdataset 'r' have an attached 'No QNAME Proof'? */
    161 #define NOQNAME(r)		(((r)->attributes & \
    162 				  DNS_RDATASETATTR_NOQNAME) != 0)
    163 
    164 /*% Does the rdataset 'r' contains a stale answer? */
    165 #define STALE(r)		(((r)->attributes & \
    166 				  DNS_RDATASETATTR_STALE) != 0)
    167 
    168 #ifdef WANT_QUERYTRACE
    169 static inline void
    170 client_trace(ns_client_t *client, int level, const char *message) {
    171 	if (client != NULL && client->query.qname != NULL) {
    172 		if (isc_log_wouldlog(ns_lctx, level)) {
    173 			char qbuf[DNS_NAME_FORMATSIZE];
    174 			char tbuf[DNS_RDATATYPE_FORMATSIZE];
    175 			dns_name_format(client->query.qname,
    176 					qbuf, sizeof(qbuf));
    177 			dns_rdatatype_format(client->query.qtype,
    178 					     tbuf, sizeof(tbuf));
    179 			isc_log_write(ns_lctx,
    180 				      NS_LOGCATEGORY_CLIENT,
    181 				      NS_LOGMODULE_QUERY, level,
    182 				      "query client=%p thread=0x%lx "
    183 				      "(%s/%s): %s",
    184 				      client,
    185 				      (unsigned long) isc_thread_self(),
    186 				      qbuf, tbuf, message);
    187 		}
    188 	 } else {
    189 		isc_log_write(ns_lctx,
    190 			      NS_LOGCATEGORY_CLIENT,
    191 			      NS_LOGMODULE_QUERY, level,
    192 			      "query client=%p thread=0x%lx "
    193 			      "(<unknown-query>): %s",
    194 			      client,
    195 			      (unsigned long) isc_thread_self(),
    196 			      message);
    197 	}
    198 }
    199 #define CTRACE(l,m)	  client_trace(client, l, m)
    200 #define CCTRACE(l,m)	  client_trace(qctx->client, l, m)
    201 #else
    202 #define CTRACE(l,m) ((void)m)
    203 #define CCTRACE(l,m) ((void)m)
    204 #endif /* WANT_QUERYTRACE */
    205 
    206 
    207 #define DNS_GETDB_NOEXACT 0x01U
    208 #define DNS_GETDB_NOLOG 0x02U
    209 #define DNS_GETDB_PARTIAL 0x04U
    210 #define DNS_GETDB_IGNOREACL 0x08U
    211 
    212 #define PENDINGOK(x)	(((x) & DNS_DBFIND_PENDINGOK) != 0)
    213 
    214 #define SFCACHE_CDFLAG 0x1
    215 
    216 /*
    217  * These have the same semantics as:
    218  *
    219  * 	foo_attach(b, a);
    220  *	foo_detach(&a);
    221  *
    222  * without the locking and magic testing.
    223  *
    224  * We use SAVE and RESTORE as that shows the operation being performed.
    225  */
    226 #define SAVE(a, b) do { INSIST(a == NULL); a = b; b = NULL; } while (0)
    227 #define RESTORE(a, b) SAVE(a, b)
    228 
    229 static isc_boolean_t
    230 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
    231 	 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
    232 
    233 static void
    234 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
    235 		       dns_dbversion_t *version, ns_client_t *client,
    236 		       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
    237 		       dns_name_t *fname, isc_boolean_t exact,
    238 		       dns_name_t *found);
    239 
    240 static inline void
    241 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
    242 
    243 static void
    244 rpz_st_clear(ns_client_t *client);
    245 
    246 static isc_boolean_t
    247 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
    248 	      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
    249 
    250 static void
    251 log_noexistnodata(void *val, int level, const char *fmt, ...)
    252 	ISC_FORMAT_PRINTF(3, 4);
    253 
    254 #ifdef NS_HOOKS_ENABLE
    255 
    256 LIBNS_EXTERNAL_DATA ns_hook_t *ns__hook_table = NULL;
    257 
    258 #define PROCESS_HOOK(...) \
    259 	NS_PROCESS_HOOK(ns__hook_table, __VA_ARGS__)
    260 #define PROCESS_HOOK_VOID(...) \
    261 	NS_PROCESS_HOOK_VOID(ns__hook_table, __VA_ARGS__)
    262 
    263 #else
    264 
    265 #define PROCESS_HOOK(...)	do {} while (0)
    266 #define PROCESS_HOOK_VOID(...)	do {} while (0)
    267 
    268 #endif
    269 
    270 /*
    271  * The functions defined below implement the query logic that previously lived
    272  * in the single very complex function query_find().  The query_ctx_t structure
    273  * defined in <ns/query.h> maintains state from function to function.  The call
    274  * flow for the general query processing algorithm is described below:
    275  *
    276  * 1. Set up query context and other resources for a client
    277  *    query (query_setup())
    278  *
    279  * 2. Start the search (ns__query_start())
    280  *
    281  * 3. Identify authoritative data sources which may have an answer;
    282  *    search them (query_lookup()). If an answer is found, go to 7.
    283  *
    284  * 4. If recursion or cache access are allowed, search the cache
    285  *    (query_lookup() again, using the cache database) to find a better
    286  *    answer. If an answer is found, go to 7.
    287  *
    288  * 5. If recursion is allowed, begin recursion (query_recurse()).
    289  *    Go to 15 to clean up this phase of the query. When recursion
    290  *    is complete, processing will resume at 6.
    291  *
    292  * 6. Resume from recursion; set up query context for resumed processing.
    293  *
    294  * 7. Determine what sort of answer we've found (query_gotanswer())
    295  *    and call other functions accordingly:
    296  *      - not found (auth or cache), go to 8
    297  *      - delegation, go to 9
    298  *      - no such domain (auth), go to 10
    299  *      - empty answer (auth), go to 11
    300  *      - negative response (cache), go to 12
    301  *      - answer found, go to 13
    302  *
    303  * 8. The answer was not found in the database (query_notfound().
    304  *    Set up a referral and go to 9.
    305  *
    306  * 9. Handle a delegation response (query_delegation()). If we are
    307  *    allowed to recurse, go to 5, otherwise go to 15 to clean up and
    308  *    return the delegation to the client.
    309  *
    310  * 10. No such domain (query_nxdomain()). Attempt redirection; if
    311  *     unsuccessful, add authority section records (query_addsoa(),
    312  *     query_addauth()), then go to 15 to return NXDOMAIN to client.
    313  *
    314  * 11. Empty answer (query_nodata()). Add authority section records
    315  *     (query_addsoa(), query_addauth()) and signatures if authoritative
    316  *     (query_sign_nodata()) then go to 15 and return
    317  *     NOERROR/ANCOUNT=0 to client.
    318  *
    319  * 12. No such domain or empty answer returned from cache (query_ncache()).
    320  *     Set response code appropriately, go to 11.
    321  *
    322  * 13. Prepare a response (query_prepresponse()) and then fill it
    323  *     appropriately (query_respond(), or for type ANY,
    324  *     query_respond_any()).
    325  *
    326  * 14. If a restart is needed due to CNAME/DNAME chaining, go to 2.
    327  *
    328  * 15. Clean up resources. If recursing, stop and wait for the event
    329  *     handler to be called back (step 6).  If an answer is ready,
    330  *     return it to the client.
    331  *
    332  * (XXX: This description omits several special cases including
    333  * DNS64, filter-aaaa, RPZ, RRL, and the SERVFAIL cache.)
    334  */
    335 
    336 static void
    337 query_trace(query_ctx_t *qctx);
    338 
    339 static void
    340 qctx_init(ns_client_t *client, dns_fetchevent_t *event,
    341 	  dns_rdatatype_t qtype, query_ctx_t *qctx);
    342 
    343 static isc_result_t
    344 query_setup(ns_client_t *client, dns_rdatatype_t qtype);
    345 
    346 static isc_result_t
    347 query_lookup(query_ctx_t *qctx);
    348 
    349 static void
    350 fetch_callback(isc_task_t *task, isc_event_t *event);
    351 
    352 static void
    353 recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype,
    354 		const dns_name_t *qname, const dns_name_t *qdomain);
    355 
    356 static isc_result_t
    357 query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
    358 	      dns_name_t *qdomain, dns_rdataset_t *nameservers,
    359 	      isc_boolean_t resuming);
    360 
    361 static isc_result_t
    362 query_resume(query_ctx_t *qctx);
    363 
    364 static isc_result_t
    365 query_checkrrl(query_ctx_t *qctx, isc_result_t result);
    366 
    367 static isc_result_t
    368 query_checkrpz(query_ctx_t *qctx, isc_result_t result);
    369 
    370 static isc_result_t
    371 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname);
    372 
    373 static isc_result_t
    374 query_gotanswer(query_ctx_t *qctx, isc_result_t result);
    375 
    376 static void
    377 query_addnoqnameproof(query_ctx_t *qctx);
    378 
    379 static isc_result_t
    380 query_respond_any(query_ctx_t *qctx);
    381 
    382 static isc_result_t
    383 query_respond(query_ctx_t *qctx);
    384 
    385 static isc_result_t
    386 query_dns64(query_ctx_t *qctx);
    387 
    388 static void
    389 query_filter64(query_ctx_t *qctx);
    390 
    391 static isc_result_t
    392 query_notfound(query_ctx_t *qctx);
    393 
    394 static isc_result_t
    395 query_zone_delegation(query_ctx_t *qctx);
    396 
    397 static isc_result_t
    398 query_delegation(query_ctx_t *qctx);
    399 
    400 static void
    401 query_addds(query_ctx_t *qctx);
    402 
    403 static isc_result_t
    404 query_nodata(query_ctx_t *qctx, isc_result_t result);
    405 
    406 static isc_result_t
    407 query_sign_nodata(query_ctx_t *qctx);
    408 
    409 static void
    410 query_addnxrrsetnsec(query_ctx_t *qctx);
    411 
    412 static isc_result_t
    413 query_nxdomain(query_ctx_t *qctx, isc_boolean_t empty_wild);
    414 
    415 static isc_result_t
    416 query_redirect(query_ctx_t *qctx);
    417 
    418 static isc_result_t
    419 query_ncache(query_ctx_t *qctx, isc_result_t result);
    420 
    421 static isc_result_t
    422 query_coveringnsec(query_ctx_t *qctx);
    423 
    424 static isc_result_t
    425 query_cname(query_ctx_t *qctx);
    426 
    427 static isc_result_t
    428 query_dname(query_ctx_t *qctx);
    429 
    430 static isc_result_t
    431 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl);
    432 
    433 static isc_result_t
    434 query_prepresponse(query_ctx_t *qctx);
    435 
    436 static isc_result_t
    437 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl,
    438 	     dns_section_t section);
    439 
    440 static isc_result_t
    441 query_addns(query_ctx_t *qctx);
    442 
    443 static void
    444 query_addbestns(query_ctx_t *qctx);
    445 
    446 static void
    447 query_addwildcardproof(query_ctx_t *qctx, isc_boolean_t ispositive,
    448 		       isc_boolean_t nodata);
    449 
    450 static void
    451 query_addauth(query_ctx_t *qctx);
    452 
    453 static isc_result_t
    454 query_done(query_ctx_t *qctx);
    455 
    456 /*%
    457  * Increment query statistics counters.
    458  */
    459 static inline void
    460 inc_stats(ns_client_t *client, isc_statscounter_t counter) {
    461 	dns_zone_t *zone = client->query.authzone;
    462 	dns_rdatatype_t qtype;
    463 	dns_rdataset_t *rdataset;
    464 	isc_stats_t *zonestats;
    465 	dns_stats_t *querystats = NULL;
    466 
    467 	ns_stats_increment(client->sctx->nsstats, counter);
    468 
    469 	if (zone == NULL)
    470 		return;
    471 
    472 	/* Do regular response type stats */
    473 	zonestats = dns_zone_getrequeststats(zone);
    474 
    475 	if (zonestats != NULL)
    476 		isc_stats_increment(zonestats, counter);
    477 
    478 	/* Do query type statistics
    479 	 *
    480 	 * We only increment per-type if we're using the authoritative
    481 	 * answer counter, preventing double-counting.
    482 	 */
    483 	if (counter == ns_statscounter_authans) {
    484 		querystats = dns_zone_getrcvquerystats(zone);
    485 		if (querystats != NULL) {
    486 			rdataset = ISC_LIST_HEAD(client->query.qname->list);
    487 			if (rdataset != NULL) {
    488 				qtype = rdataset->type;
    489 				dns_rdatatypestats_increment(querystats, qtype);
    490 			}
    491 		}
    492 	}
    493 }
    494 
    495 static void
    496 query_send(ns_client_t *client) {
    497 	isc_statscounter_t counter;
    498 
    499 	if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0)
    500 		inc_stats(client, ns_statscounter_nonauthans);
    501 	else
    502 		inc_stats(client, ns_statscounter_authans);
    503 
    504 	if (client->message->rcode == dns_rcode_noerror) {
    505 		dns_section_t answer = DNS_SECTION_ANSWER;
    506 		if (ISC_LIST_EMPTY(client->message->sections[answer])) {
    507 			if (client->query.isreferral)
    508 				counter = ns_statscounter_referral;
    509 			else
    510 				counter = ns_statscounter_nxrrset;
    511 		} else
    512 			counter = ns_statscounter_success;
    513 	} else if (client->message->rcode == dns_rcode_nxdomain)
    514 		counter = ns_statscounter_nxdomain;
    515 	else if (client->message->rcode == dns_rcode_badcookie)
    516 		counter = ns_statscounter_badcookie;
    517 	else /* We end up here in case of YXDOMAIN, and maybe others */
    518 		counter = ns_statscounter_failure;
    519 
    520 	inc_stats(client, counter);
    521 	ns_client_send(client);
    522 }
    523 
    524 static void
    525 query_error(ns_client_t *client, isc_result_t result, int line) {
    526 	int loglevel = ISC_LOG_DEBUG(3);
    527 
    528 	switch (result) {
    529 	case DNS_R_SERVFAIL:
    530 		loglevel = ISC_LOG_DEBUG(1);
    531 		inc_stats(client, ns_statscounter_servfail);
    532 		break;
    533 	case DNS_R_FORMERR:
    534 		inc_stats(client, ns_statscounter_formerr);
    535 		break;
    536 	default:
    537 		inc_stats(client, ns_statscounter_failure);
    538 		break;
    539 	}
    540 
    541 	if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0)
    542 		loglevel = ISC_LOG_INFO;
    543 
    544 	log_queryerror(client, result, line, loglevel);
    545 
    546 	ns_client_error(client, result);
    547 }
    548 
    549 static void
    550 query_next(ns_client_t *client, isc_result_t result) {
    551 	if (result == DNS_R_DUPLICATE)
    552 		inc_stats(client, ns_statscounter_duplicate);
    553 	else if (result == DNS_R_DROP)
    554 		inc_stats(client, ns_statscounter_dropped);
    555 	else
    556 		inc_stats(client, ns_statscounter_failure);
    557 	ns_client_next(client, result);
    558 }
    559 
    560 static inline void
    561 query_freefreeversions(ns_client_t *client, isc_boolean_t everything) {
    562 	ns_dbversion_t *dbversion, *dbversion_next;
    563 	unsigned int i;
    564 
    565 	for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;
    566 	     dbversion != NULL;
    567 	     dbversion = dbversion_next, i++)
    568 	{
    569 		dbversion_next = ISC_LIST_NEXT(dbversion, link);
    570 		/*
    571 		 * If we're not freeing everything, we keep the first three
    572 		 * dbversions structures around.
    573 		 */
    574 		if (i > 3 || everything) {
    575 			ISC_LIST_UNLINK(client->query.freeversions, dbversion,
    576 					link);
    577 			isc_mem_put(client->mctx, dbversion,
    578 				    sizeof(*dbversion));
    579 		}
    580 	}
    581 }
    582 
    583 void
    584 ns_query_cancel(ns_client_t *client) {
    585 	REQUIRE(NS_CLIENT_VALID(client));
    586 
    587 	LOCK(&client->query.fetchlock);
    588 	if (client->query.fetch != NULL) {
    589 		dns_resolver_cancelfetch(client->query.fetch);
    590 
    591 		client->query.fetch = NULL;
    592 	}
    593 	UNLOCK(&client->query.fetchlock);
    594 }
    595 
    596 static inline void
    597 query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
    598 	dns_rdataset_t *rdataset = *rdatasetp;
    599 
    600 	CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset");
    601 	if (rdataset != NULL) {
    602 		if (dns_rdataset_isassociated(rdataset))
    603 			dns_rdataset_disassociate(rdataset);
    604 		dns_message_puttemprdataset(client->message, rdatasetp);
    605 	}
    606 	CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset: done");
    607 }
    608 
    609 static inline void
    610 query_reset(ns_client_t *client, isc_boolean_t everything) {
    611 	isc_buffer_t *dbuf, *dbuf_next;
    612 	ns_dbversion_t *dbversion, *dbversion_next;
    613 
    614 	CTRACE(ISC_LOG_DEBUG(3), "query_reset");
    615 
    616 	/*%
    617 	 * Reset the query state of a client to its default state.
    618 	 */
    619 
    620 	/*
    621 	 * Cancel the fetch if it's running.
    622 	 */
    623 	ns_query_cancel(client);
    624 
    625 	/*
    626 	 * Cleanup any active versions.
    627 	 */
    628 	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
    629 	     dbversion != NULL;
    630 	     dbversion = dbversion_next) {
    631 		dbversion_next = ISC_LIST_NEXT(dbversion, link);
    632 		dns_db_closeversion(dbversion->db, &dbversion->version,
    633 				    ISC_FALSE);
    634 		dns_db_detach(&dbversion->db);
    635 		ISC_LIST_INITANDAPPEND(client->query.freeversions,
    636 				      dbversion, link);
    637 	}
    638 	ISC_LIST_INIT(client->query.activeversions);
    639 
    640 	if (client->query.authdb != NULL)
    641 		dns_db_detach(&client->query.authdb);
    642 	if (client->query.authzone != NULL)
    643 		dns_zone_detach(&client->query.authzone);
    644 
    645 	if (client->query.dns64_aaaa != NULL)
    646 		query_putrdataset(client, &client->query.dns64_aaaa);
    647 	if (client->query.dns64_sigaaaa != NULL)
    648 		query_putrdataset(client, &client->query.dns64_sigaaaa);
    649 	if (client->query.dns64_aaaaok != NULL) {
    650 		isc_mem_put(client->mctx, client->query.dns64_aaaaok,
    651 			    client->query.dns64_aaaaoklen *
    652 			    sizeof(isc_boolean_t));
    653 		client->query.dns64_aaaaok =  NULL;
    654 		client->query.dns64_aaaaoklen =  0;
    655 	}
    656 
    657 	query_putrdataset(client, &client->query.redirect.rdataset);
    658 	query_putrdataset(client, &client->query.redirect.sigrdataset);
    659 	if (client->query.redirect.db != NULL) {
    660 		if (client->query.redirect.node != NULL)
    661 			dns_db_detachnode(client->query.redirect.db,
    662 					  &client->query.redirect.node);
    663 		dns_db_detach(&client->query.redirect.db);
    664 	}
    665 	if (client->query.redirect.zone != NULL)
    666 		dns_zone_detach(&client->query.redirect.zone);
    667 
    668 	query_freefreeversions(client, everything);
    669 
    670 	for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
    671 	     dbuf != NULL;
    672 	     dbuf = dbuf_next) {
    673 		dbuf_next = ISC_LIST_NEXT(dbuf, link);
    674 		if (dbuf_next != NULL || everything) {
    675 			ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);
    676 			isc_buffer_free(&dbuf);
    677 		}
    678 	}
    679 
    680 	if (client->query.restarts > 0) {
    681 		/*
    682 		 * client->query.qname was dynamically allocated.
    683 		 */
    684 		dns_message_puttempname(client->message,
    685 					&client->query.qname);
    686 	}
    687 	client->query.qname = NULL;
    688 	client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
    689 				    NS_QUERYATTR_CACHEOK |
    690 				    NS_QUERYATTR_SECURE);
    691 	client->query.restarts = 0;
    692 	client->query.timerset = ISC_FALSE;
    693 	if (client->query.rpz_st != NULL) {
    694 		rpz_st_clear(client);
    695 		if (everything) {
    696 			INSIST(client->query.rpz_st->rpsdb == NULL);
    697 			isc_mem_put(client->mctx, client->query.rpz_st,
    698 				    sizeof(*client->query.rpz_st));
    699 			client->query.rpz_st = NULL;
    700 		}
    701 	}
    702 	client->query.origqname = NULL;
    703 	client->query.dboptions = 0;
    704 	client->query.fetchoptions = 0;
    705 	client->query.gluedb = NULL;
    706 	client->query.authdbset = ISC_FALSE;
    707 	client->query.isreferral = ISC_FALSE;
    708 	client->query.dns64_options = 0;
    709 	client->query.dns64_ttl = ISC_UINT32_MAX;
    710 	client->query.root_key_sentinel_keyid = 0;
    711 	client->query.root_key_sentinel_is_ta = ISC_FALSE;
    712 	client->query.root_key_sentinel_not_ta = ISC_FALSE;
    713 	recparam_update(&client->query.recparam, 0, NULL, NULL);
    714 }
    715 
    716 static void
    717 query_next_callback(ns_client_t *client) {
    718 	query_reset(client, ISC_FALSE);
    719 }
    720 
    721 void
    722 ns_query_free(ns_client_t *client) {
    723 	REQUIRE(NS_CLIENT_VALID(client));
    724 
    725 	query_reset(client, ISC_TRUE);
    726 }
    727 
    728 /*%
    729  * Allocate a name buffer.
    730  */
    731 static inline isc_result_t
    732 query_newnamebuf(ns_client_t *client) {
    733 	isc_buffer_t *dbuf;
    734 	isc_result_t result;
    735 
    736 	CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf");
    737 
    738 	dbuf = NULL;
    739 	result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
    740 	if (result != ISC_R_SUCCESS) {
    741 		CTRACE(ISC_LOG_DEBUG(3),
    742 		       "query_newnamebuf: isc_buffer_allocate failed: done");
    743 		return (result);
    744 	}
    745 	ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
    746 
    747 	CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf: done");
    748 	return (ISC_R_SUCCESS);
    749 }
    750 
    751 /*%
    752  * Get a name buffer from the pool, or allocate a new one if needed.
    753  */
    754 static inline isc_buffer_t *
    755 query_getnamebuf(ns_client_t *client) {
    756 	isc_buffer_t *dbuf;
    757 	isc_result_t result;
    758 	isc_region_t r;
    759 
    760 	CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf");
    761 	/*%
    762 	 * Return a name buffer with space for a maximal name, allocating
    763 	 * a new one if necessary.
    764 	 */
    765 
    766 	if (ISC_LIST_EMPTY(client->query.namebufs)) {
    767 		result = query_newnamebuf(client);
    768 		if (result != ISC_R_SUCCESS) {
    769 		    CTRACE(ISC_LOG_DEBUG(3),
    770 			   "query_getnamebuf: query_newnamebuf failed: done");
    771 			return (NULL);
    772 		}
    773 	}
    774 
    775 	dbuf = ISC_LIST_TAIL(client->query.namebufs);
    776 	INSIST(dbuf != NULL);
    777 	isc_buffer_availableregion(dbuf, &r);
    778 	if (r.length < DNS_NAME_MAXWIRE) {
    779 		result = query_newnamebuf(client);
    780 		if (result != ISC_R_SUCCESS) {
    781 		    CTRACE(ISC_LOG_DEBUG(3),
    782 			   "query_getnamebuf: query_newnamebuf failed: done");
    783 			return (NULL);
    784 
    785 		}
    786 		dbuf = ISC_LIST_TAIL(client->query.namebufs);
    787 		isc_buffer_availableregion(dbuf, &r);
    788 		INSIST(r.length >= 255);
    789 	}
    790 	CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf: done");
    791 	return (dbuf);
    792 }
    793 
    794 static inline void
    795 query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
    796 	isc_region_t r;
    797 
    798 	CTRACE(ISC_LOG_DEBUG(3), "query_keepname");
    799 	/*%
    800 	 * 'name' is using space in 'dbuf', but 'dbuf' has not yet been
    801 	 * adjusted to take account of that.  We do the adjustment.
    802 	 */
    803 
    804 	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
    805 
    806 	dns_name_toregion(name, &r);
    807 	isc_buffer_add(dbuf, r.length);
    808 	dns_name_setbuffer(name, NULL);
    809 	client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
    810 }
    811 
    812 static inline void
    813 query_releasename(ns_client_t *client, dns_name_t **namep) {
    814 	dns_name_t *name = *namep;
    815 
    816 	/*%
    817 	 * 'name' is no longer needed.  Return it to our pool of temporary
    818 	 * names.  If it is using a name buffer, relinquish its exclusive
    819 	 * rights on the buffer.
    820 	 */
    821 
    822 	CTRACE(ISC_LOG_DEBUG(3), "query_releasename");
    823 	if (dns_name_hasbuffer(name)) {
    824 		INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)
    825 		       != 0);
    826 		client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
    827 	}
    828 	dns_message_puttempname(client->message, namep);
    829 	CTRACE(ISC_LOG_DEBUG(3), "query_releasename: done");
    830 }
    831 
    832 static inline dns_name_t *
    833 query_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) {
    834 	dns_name_t *name;
    835 	isc_region_t r;
    836 	isc_result_t result;
    837 
    838 	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
    839 
    840 	CTRACE(ISC_LOG_DEBUG(3), "query_newname");
    841 	name = NULL;
    842 	result = dns_message_gettempname(client->message, &name);
    843 	if (result != ISC_R_SUCCESS) {
    844 		CTRACE(ISC_LOG_DEBUG(3),
    845 		       "query_newname: dns_message_gettempname failed: done");
    846 		return (NULL);
    847 	}
    848 	isc_buffer_availableregion(dbuf, &r);
    849 	isc_buffer_init(nbuf, r.base, r.length);
    850 	dns_name_init(name, NULL);
    851 	dns_name_setbuffer(name, nbuf);
    852 	client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
    853 
    854 	CTRACE(ISC_LOG_DEBUG(3), "query_newname: done");
    855 	return (name);
    856 }
    857 
    858 static inline dns_rdataset_t *
    859 query_newrdataset(ns_client_t *client) {
    860 	dns_rdataset_t *rdataset;
    861 	isc_result_t result;
    862 
    863 	CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset");
    864 	rdataset = NULL;
    865 	result = dns_message_gettemprdataset(client->message, &rdataset);
    866 	if (result != ISC_R_SUCCESS) {
    867 		CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset: "
    868 		       "dns_message_gettemprdataset failed: done");
    869 		return (NULL);
    870 	}
    871 
    872 	CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset: done");
    873 	return (rdataset);
    874 }
    875 
    876 static inline isc_result_t
    877 query_newdbversion(ns_client_t *client, unsigned int n) {
    878 	unsigned int i;
    879 	ns_dbversion_t *dbversion;
    880 
    881 	for (i = 0; i < n; i++) {
    882 		dbversion = isc_mem_get(client->mctx, sizeof(*dbversion));
    883 		if (dbversion != NULL) {
    884 			dbversion->db = NULL;
    885 			dbversion->version = NULL;
    886 			ISC_LIST_INITANDAPPEND(client->query.freeversions,
    887 					      dbversion, link);
    888 		} else {
    889 			/*
    890 			 * We only return ISC_R_NOMEMORY if we couldn't
    891 			 * allocate anything.
    892 			 */
    893 			if (i == 0)
    894 				return (ISC_R_NOMEMORY);
    895 			else
    896 				return (ISC_R_SUCCESS);
    897 		}
    898 	}
    899 
    900 	return (ISC_R_SUCCESS);
    901 }
    902 
    903 static inline ns_dbversion_t *
    904 query_getdbversion(ns_client_t *client) {
    905 	isc_result_t result;
    906 	ns_dbversion_t *dbversion;
    907 
    908 	if (ISC_LIST_EMPTY(client->query.freeversions)) {
    909 		result = query_newdbversion(client, 1);
    910 		if (result != ISC_R_SUCCESS)
    911 			return (NULL);
    912 	}
    913 	dbversion = ISC_LIST_HEAD(client->query.freeversions);
    914 	INSIST(dbversion != NULL);
    915 	ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);
    916 
    917 	return (dbversion);
    918 }
    919 
    920 isc_result_t
    921 ns_query_init(ns_client_t *client) {
    922 	isc_result_t result;
    923 
    924 	REQUIRE(NS_CLIENT_VALID(client));
    925 
    926 	ISC_LIST_INIT(client->query.namebufs);
    927 	ISC_LIST_INIT(client->query.activeversions);
    928 	ISC_LIST_INIT(client->query.freeversions);
    929 	client->query.restarts = 0;
    930 	client->query.timerset = ISC_FALSE;
    931 	client->query.rpz_st = NULL;
    932 	client->query.qname = NULL;
    933 	/*
    934 	 * This mutex is destroyed when the client is destroyed in
    935 	 * exit_check().
    936 	 */
    937 	result = isc_mutex_init(&client->query.fetchlock);
    938 	if (result != ISC_R_SUCCESS)
    939 		return (result);
    940 	client->query.fetch = NULL;
    941 	client->query.prefetch = NULL;
    942 	client->query.authdb = NULL;
    943 	client->query.authzone = NULL;
    944 	client->query.authdbset = ISC_FALSE;
    945 	client->query.isreferral = ISC_FALSE;
    946 	client->query.dns64_aaaa = NULL;
    947 	client->query.dns64_sigaaaa = NULL;
    948 	client->query.dns64_aaaaok = NULL;
    949 	client->query.dns64_aaaaoklen = 0;
    950 	client->query.redirect.db = NULL;
    951 	client->query.redirect.node = NULL;
    952 	client->query.redirect.zone = NULL;
    953 	client->query.redirect.qtype = dns_rdatatype_none;
    954 	client->query.redirect.result = ISC_R_SUCCESS;
    955 	client->query.redirect.rdataset = NULL;
    956 	client->query.redirect.sigrdataset = NULL;
    957 	client->query.redirect.authoritative = ISC_FALSE;
    958 	client->query.redirect.is_zone = ISC_FALSE;
    959 	client->query.redirect.fname =
    960 		dns_fixedname_initname(&client->query.redirect.fixed);
    961 	query_reset(client, ISC_FALSE);
    962 	result = query_newdbversion(client, 3);
    963 	if (result != ISC_R_SUCCESS) {
    964 		DESTROYLOCK(&client->query.fetchlock);
    965 		return (result);
    966 	}
    967 	result = query_newnamebuf(client);
    968 	if (result != ISC_R_SUCCESS) {
    969 		query_freefreeversions(client, ISC_TRUE);
    970 		DESTROYLOCK(&client->query.fetchlock);
    971 	}
    972 
    973 	return (result);
    974 }
    975 
    976 static ns_dbversion_t *
    977 query_findversion(ns_client_t *client, dns_db_t *db) {
    978 	ns_dbversion_t *dbversion;
    979 
    980 	/*%
    981 	 * We may already have done a query related to this
    982 	 * database.  If so, we must be sure to make subsequent
    983 	 * queries from the same version.
    984 	 */
    985 	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
    986 	     dbversion != NULL;
    987 	     dbversion = ISC_LIST_NEXT(dbversion, link)) {
    988 		if (dbversion->db == db)
    989 			break;
    990 	}
    991 
    992 	if (dbversion == NULL) {
    993 		/*
    994 		 * This is a new zone for this query.  Add it to
    995 		 * the active list.
    996 		 */
    997 		dbversion = query_getdbversion(client);
    998 		if (dbversion == NULL)
    999 			return (NULL);
   1000 		dns_db_attach(db, &dbversion->db);
   1001 		dns_db_currentversion(db, &dbversion->version);
   1002 		dbversion->acl_checked = ISC_FALSE;
   1003 		dbversion->queryok = ISC_FALSE;
   1004 		ISC_LIST_APPEND(client->query.activeversions,
   1005 				dbversion, link);
   1006 	}
   1007 
   1008 	return (dbversion);
   1009 }
   1010 
   1011 static inline isc_result_t
   1012 query_validatezonedb(ns_client_t *client, const dns_name_t *name,
   1013 		     dns_rdatatype_t qtype, unsigned int options,
   1014 		     dns_zone_t *zone, dns_db_t *db,
   1015 		     dns_dbversion_t **versionp)
   1016 {
   1017 	isc_result_t result;
   1018 	dns_acl_t *queryacl, *queryonacl;
   1019 	ns_dbversion_t *dbversion;
   1020 
   1021 	REQUIRE(zone != NULL);
   1022 	REQUIRE(db != NULL);
   1023 
   1024 	/*
   1025 	 * This limits our searching to the zone where the first name
   1026 	 * (the query target) was looked for.  This prevents following
   1027 	 * CNAMES or DNAMES into other zones and prevents returning
   1028 	 * additional data from other zones. This does not apply if we're
   1029 	 * answering a query where recursion is requested and allowed.
   1030 	 */
   1031 	if (client->query.rpz_st == NULL &&
   1032 	    !(WANTRECURSION(client) && RECURSIONOK(client)) &&
   1033 	    client->query.authdbset && db != client->query.authdb)
   1034 	{
   1035 		return (DNS_R_REFUSED);
   1036 	}
   1037 
   1038 	/*
   1039 	 * Non recursive query to a static-stub zone is prohibited; its
   1040 	 * zone content is not public data, but a part of local configuration
   1041 	 * and should not be disclosed.
   1042 	 */
   1043 	if (dns_zone_gettype(zone) == dns_zone_staticstub &&
   1044 	    !RECURSIONOK(client)) {
   1045 		return (DNS_R_REFUSED);
   1046 	}
   1047 
   1048 	/*
   1049 	 * If the zone has an ACL, we'll check it, otherwise
   1050 	 * we use the view's "allow-query" ACL.  Each ACL is only checked
   1051 	 * once per query.
   1052 	 *
   1053 	 * Also, get the database version to use.
   1054 	 */
   1055 
   1056 	/*
   1057 	 * Get the current version of this database.
   1058 	 */
   1059 	dbversion = query_findversion(client, db);
   1060 	if (dbversion == NULL) {
   1061 		CTRACE(ISC_LOG_ERROR, "unable to get db version");
   1062 		return (DNS_R_SERVFAIL);
   1063 	}
   1064 
   1065 	if ((options & DNS_GETDB_IGNOREACL) != 0)
   1066 		goto approved;
   1067 	if (dbversion->acl_checked) {
   1068 		if (!dbversion->queryok)
   1069 			return (DNS_R_REFUSED);
   1070 		goto approved;
   1071 	}
   1072 
   1073 	queryacl = dns_zone_getqueryacl(zone);
   1074 	if (queryacl == NULL) {
   1075 		queryacl = client->view->queryacl;
   1076 		if ((client->query.attributes &
   1077 		     NS_QUERYATTR_QUERYOKVALID) != 0) {
   1078 			/*
   1079 			 * We've evaluated the view's queryacl already.  If
   1080 			 * NS_QUERYATTR_QUERYOK is set, then the client is
   1081 			 * allowed to make queries, otherwise the query should
   1082 			 * be refused.
   1083 			 */
   1084 			dbversion->acl_checked = ISC_TRUE;
   1085 			if ((client->query.attributes &
   1086 			     NS_QUERYATTR_QUERYOK) == 0) {
   1087 				dbversion->queryok = ISC_FALSE;
   1088 				return (DNS_R_REFUSED);
   1089 			}
   1090 			dbversion->queryok = ISC_TRUE;
   1091 			goto approved;
   1092 		}
   1093 	}
   1094 
   1095 	result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
   1096 	if ((options & DNS_GETDB_NOLOG) == 0) {
   1097 		char msg[NS_CLIENT_ACLMSGSIZE("query")];
   1098 		if (result == ISC_R_SUCCESS) {
   1099 			if (isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(3))) {
   1100 				ns_client_aclmsg("query", name, qtype,
   1101 						 client->view->rdclass,
   1102 						 msg, sizeof(msg));
   1103 				ns_client_log(client,
   1104 					      DNS_LOGCATEGORY_SECURITY,
   1105 					      NS_LOGMODULE_QUERY,
   1106 					      ISC_LOG_DEBUG(3),
   1107 					      "%s approved", msg);
   1108 			}
   1109 		} else {
   1110 			ns_client_aclmsg("query", name, qtype,
   1111 					 client->view->rdclass,
   1112 					 msg, sizeof(msg));
   1113 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
   1114 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   1115 				      "%s denied", msg);
   1116 		}
   1117 	}
   1118 
   1119 	if (queryacl == client->view->queryacl) {
   1120 		if (result == ISC_R_SUCCESS) {
   1121 			/*
   1122 			 * We were allowed by the default
   1123 			 * "allow-query" ACL.  Remember this so we
   1124 			 * don't have to check again.
   1125 			 */
   1126 			client->query.attributes |= NS_QUERYATTR_QUERYOK;
   1127 		}
   1128 		/*
   1129 		 * We've now evaluated the view's query ACL, and
   1130 		 * the NS_QUERYATTR_QUERYOK attribute is now valid.
   1131 		 */
   1132 		client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
   1133 	}
   1134 
   1135 	/* If and only if we've gotten this far, check allow-query-on too */
   1136 	if (result == ISC_R_SUCCESS) {
   1137 		queryonacl = dns_zone_getqueryonacl(zone);
   1138 		if (queryonacl == NULL)
   1139 			queryonacl = client->view->queryonacl;
   1140 
   1141 		result = ns_client_checkaclsilent(client, &client->destaddr,
   1142 						  queryonacl, ISC_TRUE);
   1143 		if ((options & DNS_GETDB_NOLOG) == 0 &&
   1144 		    result != ISC_R_SUCCESS)
   1145 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
   1146 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   1147 				      "query-on denied");
   1148 	}
   1149 
   1150 	dbversion->acl_checked = ISC_TRUE;
   1151 	if (result != ISC_R_SUCCESS) {
   1152 		dbversion->queryok = ISC_FALSE;
   1153 		return (DNS_R_REFUSED);
   1154 	}
   1155 	dbversion->queryok = ISC_TRUE;
   1156 
   1157  approved:
   1158 	/* Transfer ownership, if necessary. */
   1159 	if (versionp != NULL)
   1160 		*versionp = dbversion->version;
   1161 	return (ISC_R_SUCCESS);
   1162 }
   1163 
   1164 static inline isc_result_t
   1165 query_getzonedb(ns_client_t *client, const dns_name_t *name,
   1166 		dns_rdatatype_t qtype, unsigned int options,
   1167 		dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp)
   1168 {
   1169 	isc_result_t result;
   1170 	unsigned int ztoptions;
   1171 	dns_zone_t *zone = NULL;
   1172 	dns_db_t *db = NULL;
   1173 	isc_boolean_t partial = ISC_FALSE;
   1174 
   1175 	REQUIRE(zonep != NULL && *zonep == NULL);
   1176 	REQUIRE(dbp != NULL && *dbp == NULL);
   1177 
   1178 	/*%
   1179 	 * Find a zone database to answer the query.
   1180 	 */
   1181 	ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ?
   1182 		DNS_ZTFIND_NOEXACT : 0;
   1183 
   1184 	result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL,
   1185 			     &zone);
   1186 
   1187 	if (result == DNS_R_PARTIALMATCH)
   1188 		partial = ISC_TRUE;
   1189 	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
   1190 		result = dns_zone_getdb(zone, &db);
   1191 
   1192 	if (result != ISC_R_SUCCESS)
   1193 		goto fail;
   1194 
   1195 	result = query_validatezonedb(client, name, qtype, options, zone, db,
   1196 				      versionp);
   1197 
   1198 	if (result != ISC_R_SUCCESS)
   1199 		goto fail;
   1200 
   1201 	/* Transfer ownership. */
   1202 	*zonep = zone;
   1203 	*dbp = db;
   1204 
   1205 	if (partial && (options & DNS_GETDB_PARTIAL) != 0)
   1206 		return (DNS_R_PARTIALMATCH);
   1207 	return (ISC_R_SUCCESS);
   1208 
   1209  fail:
   1210 	if (zone != NULL)
   1211 		dns_zone_detach(&zone);
   1212 	if (db != NULL)
   1213 		dns_db_detach(&db);
   1214 
   1215 	return (result);
   1216 }
   1217 
   1218 static void
   1219 rpz_log_rewrite(ns_client_t *client, isc_boolean_t disabled,
   1220 		dns_rpz_policy_t policy, dns_rpz_type_t type,
   1221 		dns_zone_t *p_zone, dns_name_t *p_name,
   1222 		dns_name_t *cname, dns_rpz_num_t rpz_num)
   1223 {
   1224 	isc_stats_t *zonestats;
   1225 	char qname_buf[DNS_NAME_FORMATSIZE];
   1226 	char p_name_buf[DNS_NAME_FORMATSIZE];
   1227 	char cname_buf[DNS_NAME_FORMATSIZE] = { 0 };
   1228 	const char *s1 = cname_buf, *s2 = cname_buf;
   1229 	dns_rpz_st_t *st;
   1230 
   1231 	/*
   1232 	 * Count enabled rewrites in the global counter.
   1233 	 * Count both enabled and disabled rewrites for each zone.
   1234 	 */
   1235 	if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) {
   1236 		ns_stats_increment(client->sctx->nsstats,
   1237 				   ns_statscounter_rpz_rewrites);
   1238 	}
   1239 	if (p_zone != NULL) {
   1240 		zonestats = dns_zone_getrequeststats(p_zone);
   1241 		if (zonestats != NULL)
   1242 			isc_stats_increment(zonestats,
   1243 					    ns_statscounter_rpz_rewrites);
   1244 	}
   1245 
   1246 	if (!isc_log_wouldlog(ns_lctx, DNS_RPZ_INFO_LEVEL))
   1247 		return;
   1248 
   1249 	st = client->query.rpz_st;
   1250 	if ((st->popt.no_log & DNS_RPZ_ZBIT(rpz_num)) != 0)
   1251 		return;
   1252 
   1253 	dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf));
   1254 	dns_name_format(p_name, p_name_buf, sizeof(p_name_buf));
   1255 	if (cname != NULL) {
   1256 		s1 = " (CNAME to: ";
   1257 		dns_name_format(cname, cname_buf, sizeof(cname_buf));
   1258 		s2 = ")";
   1259 	}
   1260 
   1261 	ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY,
   1262 		      DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s via %s%s%s%s",
   1263 		      disabled ? "disabled " : "",
   1264 		      dns_rpz_type2str(type), dns_rpz_policy2str(policy),
   1265 		      qname_buf, p_name_buf, s1, cname_buf, s2);
   1266 }
   1267 
   1268 static void
   1269 rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name,
   1270 		    dns_rpz_type_t rpz_type1, dns_rpz_type_t rpz_type2,
   1271 		    const char *str, isc_result_t result)
   1272 {
   1273 	char qnamebuf[DNS_NAME_FORMATSIZE];
   1274 	char p_namebuf[DNS_NAME_FORMATSIZE];
   1275 	const char *failed, *via, *slash, *str_blank;
   1276 	const char *rpztypestr1;
   1277 	const char *rpztypestr2;
   1278 
   1279 	if (!isc_log_wouldlog(ns_lctx, level))
   1280 		return;
   1281 
   1282 	/*
   1283 	 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems.
   1284 	 */
   1285 	if (level <= DNS_RPZ_DEBUG_LEVEL1)
   1286 		failed = "failed: ";
   1287 	else
   1288 		failed = ": ";
   1289 
   1290 	rpztypestr1 = dns_rpz_type2str(rpz_type1);
   1291 	if (rpz_type2 != DNS_RPZ_TYPE_BAD) {
   1292 		slash = "/";
   1293 		rpztypestr2 = dns_rpz_type2str(rpz_type2);
   1294 	} else {
   1295 		slash = "";
   1296 		rpztypestr2 = "";
   1297 	}
   1298 
   1299 	str_blank = (*str != ' ' && *str != '\0') ? " " : "";
   1300 
   1301 	dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf));
   1302 
   1303 	if (p_name != NULL) {
   1304 		via = " via ";
   1305 		dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
   1306 	} else {
   1307 		via = "";
   1308 		p_namebuf[0] = '\0';
   1309 	}
   1310 
   1311 	ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS,
   1312 		      NS_LOGMODULE_QUERY, level,
   1313 		      "rpz %s%s%s rewrite %s%s%s%s%s%s : %s",
   1314 		      rpztypestr1, slash, rpztypestr2,
   1315 		      qnamebuf, via, p_namebuf, str_blank,
   1316 		      str, failed, isc_result_totext(result));
   1317 }
   1318 
   1319 static void
   1320 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name,
   1321 	     dns_rpz_type_t rpz_type, const char *str, isc_result_t result)
   1322 {
   1323 	rpz_log_fail_helper(client, level, p_name,
   1324 			    rpz_type, DNS_RPZ_TYPE_BAD, str, result);
   1325 }
   1326 
   1327 /*
   1328  * Get a policy rewrite zone database.
   1329  */
   1330 static isc_result_t
   1331 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type,
   1332 	  dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp)
   1333 {
   1334 	char qnamebuf[DNS_NAME_FORMATSIZE];
   1335 	char p_namebuf[DNS_NAME_FORMATSIZE];
   1336 	dns_dbversion_t *rpz_version = NULL;
   1337 	isc_result_t result;
   1338 
   1339 	CTRACE(ISC_LOG_DEBUG(3), "rpz_getdb");
   1340 
   1341 	result = query_getzonedb(client, p_name, dns_rdatatype_any,
   1342 				 DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version);
   1343 	if (result == ISC_R_SUCCESS) {
   1344 		dns_rpz_st_t *st = client->query.rpz_st;
   1345 
   1346 		/*
   1347 		 * It isn't meaningful to log this message when
   1348 		 * logging is disabled for some policy zones.
   1349 		 */
   1350 		if (st->popt.no_log == 0 &&
   1351 		    isc_log_wouldlog(ns_lctx, DNS_RPZ_DEBUG_LEVEL2))
   1352 		{
   1353 			dns_name_format(client->query.qname, qnamebuf,
   1354 					sizeof(qnamebuf));
   1355 			dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
   1356 			ns_client_log(client, DNS_LOGCATEGORY_RPZ,
   1357 				      NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
   1358 				      "try rpz %s rewrite %s via %s",
   1359 				      dns_rpz_type2str(rpz_type),
   1360 				      qnamebuf, p_namebuf);
   1361 		}
   1362 		*versionp = rpz_version;
   1363 		return (ISC_R_SUCCESS);
   1364 	}
   1365 	rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
   1366 		     " query_getzonedb()", result);
   1367 	return (result);
   1368 }
   1369 
   1370 static inline isc_result_t
   1371 query_getcachedb(ns_client_t *client, const dns_name_t *name,
   1372 		 dns_rdatatype_t qtype, dns_db_t **dbp, unsigned int options)
   1373 {
   1374 	isc_result_t result;
   1375 	isc_boolean_t check_acl;
   1376 	dns_db_t *db = NULL;
   1377 
   1378 	REQUIRE(dbp != NULL && *dbp == NULL);
   1379 
   1380 	/*%
   1381 	 * Find a cache database to answer the query.
   1382 	 * This may fail with DNS_R_REFUSED if the client
   1383 	 * is not allowed to use the cache.
   1384 	 */
   1385 
   1386 	if (!USECACHE(client))
   1387 		return (DNS_R_REFUSED);
   1388 	dns_db_attach(client->view->cachedb, &db);
   1389 
   1390 	if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) {
   1391 		/*
   1392 		 * We've evaluated the view's cacheacl already.  If
   1393 		 * NS_QUERYATTR_CACHEACLOK is set, then the client is
   1394 		 * allowed to make queries, otherwise the query should
   1395 		 * be refused.
   1396 		 */
   1397 		check_acl = ISC_FALSE;
   1398 		if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0)
   1399 			goto refuse;
   1400 	} else {
   1401 		/*
   1402 		 * We haven't evaluated the view's queryacl yet.
   1403 		 */
   1404 		check_acl = ISC_TRUE;
   1405 	}
   1406 
   1407 	if (check_acl) {
   1408 		isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0);
   1409 		char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")];
   1410 
   1411 		result = ns_client_checkaclsilent(client, NULL,
   1412 						  client->view->cacheacl,
   1413 						  ISC_TRUE);
   1414 		if (result == ISC_R_SUCCESS) {
   1415 			/*
   1416 			 * We were allowed by the "allow-query-cache" ACL.
   1417 			 * Remember this so we don't have to check again.
   1418 			 */
   1419 			client->query.attributes |=
   1420 				NS_QUERYATTR_CACHEACLOK;
   1421 			if (log && isc_log_wouldlog(ns_lctx,
   1422 						     ISC_LOG_DEBUG(3)))
   1423 			{
   1424 				ns_client_aclmsg("query (cache)", name, qtype,
   1425 						 client->view->rdclass,
   1426 						 msg, sizeof(msg));
   1427 				ns_client_log(client,
   1428 					      DNS_LOGCATEGORY_SECURITY,
   1429 					      NS_LOGMODULE_QUERY,
   1430 					      ISC_LOG_DEBUG(3),
   1431 					      "%s approved", msg);
   1432 			}
   1433 		} else if (log) {
   1434 			ns_client_aclmsg("query (cache)", name, qtype,
   1435 					 client->view->rdclass, msg,
   1436 					 sizeof(msg));
   1437 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
   1438 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   1439 				      "%s denied", msg);
   1440 		}
   1441 		/*
   1442 		 * We've now evaluated the view's query ACL, and
   1443 		 * the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid.
   1444 		 */
   1445 		client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
   1446 
   1447 		if (result != ISC_R_SUCCESS)
   1448 			goto refuse;
   1449 	}
   1450 
   1451 	/* Approved. */
   1452 
   1453 	/* Transfer ownership. */
   1454 	*dbp = db;
   1455 
   1456 	return (ISC_R_SUCCESS);
   1457 
   1458  refuse:
   1459 	result = DNS_R_REFUSED;
   1460 
   1461 	if (db != NULL)
   1462 		dns_db_detach(&db);
   1463 
   1464 	return (result);
   1465 }
   1466 
   1467 static inline isc_result_t
   1468 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
   1469 	    unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
   1470 	    dns_dbversion_t **versionp, isc_boolean_t *is_zonep)
   1471 {
   1472 	isc_result_t result;
   1473 
   1474 	isc_result_t tresult;
   1475 	unsigned int namelabels;
   1476 	unsigned int zonelabels;
   1477 	dns_zone_t *zone = NULL;
   1478 
   1479 	REQUIRE(zonep != NULL && *zonep == NULL);
   1480 
   1481 	/* Calculate how many labels are in name. */
   1482 	namelabels = dns_name_countlabels(name);
   1483 	zonelabels = 0;
   1484 
   1485 	/* Try to find name in bind's standard database. */
   1486 	result = query_getzonedb(client, name, qtype, options, &zone,
   1487 				 dbp, versionp);
   1488 
   1489 	/* See how many labels are in the zone's name.	  */
   1490 	if (result == ISC_R_SUCCESS && zone != NULL)
   1491 		zonelabels = dns_name_countlabels(dns_zone_getorigin(zone));
   1492 
   1493 	/*
   1494 	 * If # zone labels < # name labels, try to find an even better match
   1495 	 * Only try if DLZ drivers are loaded for this view
   1496 	 */
   1497 	if (ISC_UNLIKELY(zonelabels < namelabels &&
   1498 			 !ISC_LIST_EMPTY(client->view->dlz_searched)))
   1499 	{
   1500 		dns_clientinfomethods_t cm;
   1501 		dns_clientinfo_t ci;
   1502 		dns_db_t *tdbp;
   1503 
   1504 		dns_clientinfomethods_init(&cm, ns_client_sourceip);
   1505 		dns_clientinfo_init(&ci, client, NULL);
   1506 
   1507 		tdbp = NULL;
   1508 		tresult = dns_view_searchdlz(client->view, name,
   1509 					     zonelabels, &cm, &ci, &tdbp);
   1510 		 /* If we successful, we found a better match. */
   1511 		if (tresult == ISC_R_SUCCESS) {
   1512 			ns_dbversion_t *dbversion;
   1513 
   1514 			/*
   1515 			 * If the previous search returned a zone, detach it.
   1516 			 */
   1517 			if (zone != NULL)
   1518 				dns_zone_detach(&zone);
   1519 
   1520 			/*
   1521 			 * If the previous search returned a database,
   1522 			 * detach it.
   1523 			 */
   1524 			if (*dbp != NULL)
   1525 				dns_db_detach(dbp);
   1526 
   1527 			/*
   1528 			 * If the previous search returned a version, clear it.
   1529 			 */
   1530 			*versionp = NULL;
   1531 
   1532 			dbversion = query_findversion(client, tdbp);
   1533 			if (dbversion == NULL) {
   1534 				tresult = ISC_R_NOMEMORY;
   1535 			} else {
   1536 				/*
   1537 				 * Be sure to return our database.
   1538 				 */
   1539 				*dbp = tdbp;
   1540 				*versionp = dbversion->version;
   1541 			}
   1542 
   1543 			/*
   1544 			 * We return a null zone, No stats for DLZ zones.
   1545 			 */
   1546 			zone = NULL;
   1547 			result = tresult;
   1548 		}
   1549 	}
   1550 
   1551 	/* If successful, Transfer ownership of zone. */
   1552 	if (result == ISC_R_SUCCESS) {
   1553 		*zonep = zone;
   1554 		/*
   1555 		 * If neither attempt above succeeded, return the cache instead
   1556 		 */
   1557 		*is_zonep = ISC_TRUE;
   1558 	} else if (result == ISC_R_NOTFOUND) {
   1559 		result = query_getcachedb(client, name, qtype, dbp, options);
   1560 		*is_zonep = ISC_FALSE;
   1561 	}
   1562 	return (result);
   1563 }
   1564 
   1565 static inline isc_boolean_t
   1566 query_isduplicate(ns_client_t *client, dns_name_t *name,
   1567 		  dns_rdatatype_t type, dns_name_t **mnamep)
   1568 {
   1569 	dns_section_t section;
   1570 	dns_name_t *mname = NULL;
   1571 	isc_result_t result;
   1572 
   1573 	CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate");
   1574 
   1575 	for (section = DNS_SECTION_ANSWER;
   1576 	     section <= DNS_SECTION_ADDITIONAL;
   1577 	     section++) {
   1578 		result = dns_message_findname(client->message, section,
   1579 					      name, type, 0, &mname, NULL);
   1580 		if (result == ISC_R_SUCCESS) {
   1581 			/*
   1582 			 * We've already got this RRset in the response.
   1583 			 */
   1584 			CTRACE(ISC_LOG_DEBUG(3),
   1585 			       "query_isduplicate: true: done");
   1586 			return (ISC_TRUE);
   1587 		} else if (result == DNS_R_NXRRSET) {
   1588 			/*
   1589 			 * The name exists, but the rdataset does not.
   1590 			 */
   1591 			if (section == DNS_SECTION_ADDITIONAL)
   1592 				break;
   1593 		} else
   1594 			RUNTIME_CHECK(result == DNS_R_NXDOMAIN);
   1595 		mname = NULL;
   1596 	}
   1597 
   1598 	if (mnamep != NULL)
   1599 		*mnamep = mname;
   1600 
   1601 	CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done");
   1602 	return (ISC_FALSE);
   1603 }
   1604 
   1605 static isc_result_t
   1606 query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
   1607 	ns_client_t *client = arg;
   1608 	isc_result_t result, eresult;
   1609 	dns_dbnode_t *node;
   1610 	dns_db_t *db;
   1611 	dns_name_t *fname, *mname;
   1612 	dns_rdataset_t *rdataset, *sigrdataset, *trdataset;
   1613 	isc_buffer_t *dbuf;
   1614 	isc_buffer_t b;
   1615 	ns_dbversion_t *dbversion;
   1616 	dns_dbversion_t *version;
   1617 	isc_boolean_t added_something, need_addname;
   1618 	dns_rdatatype_t type;
   1619 	dns_clientinfomethods_t cm;
   1620 	dns_clientinfo_t ci;
   1621 	dns_rdatasetadditional_t additionaltype;
   1622 
   1623 	REQUIRE(NS_CLIENT_VALID(client));
   1624 	REQUIRE(qtype != dns_rdatatype_any);
   1625 
   1626 	if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype))
   1627 		return (ISC_R_SUCCESS);
   1628 
   1629 	CTRACE(ISC_LOG_DEBUG(3), "query_addadditional");
   1630 
   1631 	/*
   1632 	 * Initialization.
   1633 	 */
   1634 	eresult = ISC_R_SUCCESS;
   1635 	fname = NULL;
   1636 	rdataset = NULL;
   1637 	sigrdataset = NULL;
   1638 	trdataset = NULL;
   1639 	db = NULL;
   1640 	version = NULL;
   1641 	node = NULL;
   1642 	added_something = ISC_FALSE;
   1643 	need_addname = ISC_FALSE;
   1644 	additionaltype = dns_rdatasetadditional_fromauth;
   1645 
   1646 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   1647 	dns_clientinfo_init(&ci, client, NULL);
   1648 
   1649 	/*
   1650 	 * We treat type A additional section processing as if it
   1651 	 * were "any address type" additional section processing.
   1652 	 * To avoid multiple lookups, we do an 'any' database
   1653 	 * lookup and iterate over the node.
   1654 	 */
   1655 	if (qtype == dns_rdatatype_a)
   1656 		type = dns_rdatatype_any;
   1657 	else
   1658 		type = qtype;
   1659 
   1660 	/*
   1661 	 * Get some resources.
   1662 	 */
   1663 	dbuf = query_getnamebuf(client);
   1664 	if (dbuf == NULL)
   1665 		goto cleanup;
   1666 	fname = query_newname(client, dbuf, &b);
   1667 	rdataset = query_newrdataset(client);
   1668 	if (fname == NULL || rdataset == NULL)
   1669 		goto cleanup;
   1670 	if (WANTDNSSEC(client)) {
   1671 		sigrdataset = query_newrdataset(client);
   1672 		if (sigrdataset == NULL)
   1673 			goto cleanup;
   1674 	}
   1675 
   1676 	/*
   1677 	 * If we want only minimal responses and are here, then it must
   1678 	 * be for glue.
   1679 	 */
   1680 	if (client->view->minimalresponses == dns_minimal_yes)
   1681 		goto try_glue;
   1682 
   1683 	/*
   1684 	 * Look within the same zone database for authoritative
   1685 	 * additional data.
   1686 	 */
   1687 	if (!client->query.authdbset || client->query.authdb == NULL)
   1688 		goto try_cache;
   1689 
   1690 	dbversion = query_findversion(client, client->query.authdb);
   1691 	if (dbversion == NULL)
   1692 		goto try_cache;
   1693 
   1694 	dns_db_attach(client->query.authdb, &db);
   1695 	version = dbversion->version;
   1696 
   1697 	CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: db_find");
   1698 
   1699 	/*
   1700 	 * Since we are looking for authoritative data, we do not set
   1701 	 * the GLUEOK flag.  Glue will be looked for later, but not
   1702 	 * necessarily in the same database.
   1703 	 */
   1704 	result = dns_db_findext(db, name, version, type,
   1705 				client->query.dboptions,
   1706 				client->now, &node, fname, &cm, &ci,
   1707 				rdataset, sigrdataset);
   1708 	if (result == ISC_R_SUCCESS) {
   1709 		if (sigrdataset != NULL && !dns_db_issecure(db) &&
   1710 		    dns_rdataset_isassociated(sigrdataset))
   1711 			dns_rdataset_disassociate(sigrdataset);
   1712 		goto found;
   1713 	}
   1714 
   1715 	if (dns_rdataset_isassociated(rdataset))
   1716 		dns_rdataset_disassociate(rdataset);
   1717 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
   1718 		dns_rdataset_disassociate(sigrdataset);
   1719 	if (node != NULL)
   1720 		dns_db_detachnode(db, &node);
   1721 	version = NULL;
   1722 	dns_db_detach(&db);
   1723 
   1724 	/*
   1725 	 * No authoritative data was found.  The cache is our next best bet.
   1726 	 */
   1727 
   1728  try_cache:
   1729 	if (!client->view->recursion)
   1730 		goto try_glue;
   1731 
   1732 	additionaltype = dns_rdatasetadditional_fromcache;
   1733 	result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
   1734 	if (result != ISC_R_SUCCESS) {
   1735 		/*
   1736 		 * Most likely the client isn't allowed to query the cache.
   1737 		 */
   1738 		goto try_glue;
   1739 	}
   1740 	/*
   1741 	 * Attempt to validate glue.
   1742 	 */
   1743 	if (sigrdataset == NULL) {
   1744 		sigrdataset = query_newrdataset(client);
   1745 		if (sigrdataset == NULL)
   1746 			goto cleanup;
   1747 	}
   1748 
   1749 	version = NULL;
   1750 	result = dns_db_findext(db, name, version, type,
   1751 				client->query.dboptions |
   1752 				DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
   1753 				client->now, &node, fname, &cm, &ci,
   1754 				rdataset, sigrdataset);
   1755 
   1756 	dns_cache_updatestats(client->view->cache, result);
   1757 	if (!WANTDNSSEC(client))
   1758 		query_putrdataset(client, &sigrdataset);
   1759 	if (result == ISC_R_SUCCESS)
   1760 		goto found;
   1761 
   1762 	if (dns_rdataset_isassociated(rdataset))
   1763 		dns_rdataset_disassociate(rdataset);
   1764 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
   1765 		dns_rdataset_disassociate(sigrdataset);
   1766 	if (node != NULL)
   1767 		dns_db_detachnode(db, &node);
   1768 	dns_db_detach(&db);
   1769 
   1770  try_glue:
   1771 	/*
   1772 	 * No cached data was found.  Glue is our last chance.
   1773 	 * RFC1035 sayeth:
   1774 	 *
   1775 	 *	NS records cause both the usual additional section
   1776 	 *	processing to locate a type A record, and, when used
   1777 	 *	in a referral, a special search of the zone in which
   1778 	 *	they reside for glue information.
   1779 	 *
   1780 	 * This is the "special search".  Note that we must search
   1781 	 * the zone where the NS record resides, not the zone it
   1782 	 * points to, and that we only do the search in the delegation
   1783 	 * case (identified by client->query.gluedb being set).
   1784 	 */
   1785 
   1786 	if (client->query.gluedb == NULL)
   1787 		goto cleanup;
   1788 
   1789 	/*
   1790 	 * Don't poison caches using the bailiwick protection model.
   1791 	 */
   1792 	if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
   1793 		goto cleanup;
   1794 
   1795 	dbversion = query_findversion(client, client->query.gluedb);
   1796 	if (dbversion == NULL)
   1797 		goto cleanup;
   1798 
   1799 	dns_db_attach(client->query.gluedb, &db);
   1800 	version = dbversion->version;
   1801 	additionaltype = dns_rdatasetadditional_fromglue;
   1802 	result = dns_db_findext(db, name, version, type,
   1803 				client->query.dboptions | DNS_DBFIND_GLUEOK,
   1804 				client->now, &node, fname, &cm, &ci,
   1805 				rdataset, sigrdataset);
   1806 	if (!(result == ISC_R_SUCCESS ||
   1807 	      result == DNS_R_ZONECUT ||
   1808 	      result == DNS_R_GLUE))
   1809 		goto cleanup;
   1810 
   1811  found:
   1812 	/*
   1813 	 * We have found a potential additional data rdataset, or
   1814 	 * at least a node to iterate over.
   1815 	 */
   1816 	query_keepname(client, fname, dbuf);
   1817 
   1818 	/*
   1819 	 * If we have an rdataset, add it to the additional data
   1820 	 * section.
   1821 	 */
   1822 	mname = NULL;
   1823 	if (dns_rdataset_isassociated(rdataset) &&
   1824 	    !query_isduplicate(client, fname, type, &mname)) {
   1825 		if (mname != NULL) {
   1826 			INSIST(mname != fname);
   1827 			query_releasename(client, &fname);
   1828 			fname = mname;
   1829 		} else
   1830 			need_addname = ISC_TRUE;
   1831 		ISC_LIST_APPEND(fname->list, rdataset, link);
   1832 		trdataset = rdataset;
   1833 		rdataset = NULL;
   1834 		added_something = ISC_TRUE;
   1835 		/*
   1836 		 * Note: we only add SIGs if we've added the type they cover,
   1837 		 * so we do not need to check if the SIG rdataset is already
   1838 		 * in the response.
   1839 		 */
   1840 		if (sigrdataset != NULL &&
   1841 		    dns_rdataset_isassociated(sigrdataset))
   1842 		{
   1843 			ISC_LIST_APPEND(fname->list, sigrdataset, link);
   1844 			sigrdataset = NULL;
   1845 		}
   1846 	}
   1847 
   1848 	if (qtype == dns_rdatatype_a) {
   1849 		isc_boolean_t have_a = ISC_FALSE;
   1850 
   1851 		/*
   1852 		 * We now go looking for A and AAAA records, along with
   1853 		 * their signatures.
   1854 		 *
   1855 		 * XXXRTH  This code could be more efficient.
   1856 		 */
   1857 		if (rdataset != NULL) {
   1858 			if (dns_rdataset_isassociated(rdataset))
   1859 				dns_rdataset_disassociate(rdataset);
   1860 		} else {
   1861 			rdataset = query_newrdataset(client);
   1862 			if (rdataset == NULL)
   1863 				goto addname;
   1864 		}
   1865 		if (sigrdataset != NULL) {
   1866 			if (dns_rdataset_isassociated(sigrdataset))
   1867 				dns_rdataset_disassociate(sigrdataset);
   1868 		} else if (WANTDNSSEC(client)) {
   1869 			sigrdataset = query_newrdataset(client);
   1870 			if (sigrdataset == NULL)
   1871 				goto addname;
   1872 		}
   1873 		if (query_isduplicate(client, fname, dns_rdatatype_a, NULL))
   1874 			goto aaaa_lookup;
   1875 		result = dns_db_findrdataset(db, node, version,
   1876 					     dns_rdatatype_a, 0,
   1877 					     client->now,
   1878 					     rdataset, sigrdataset);
   1879 		if (result == DNS_R_NCACHENXDOMAIN) {
   1880 			goto addname;
   1881 		} else if (result == DNS_R_NCACHENXRRSET) {
   1882 			dns_rdataset_disassociate(rdataset);
   1883 			if (sigrdataset != NULL &&
   1884 			    dns_rdataset_isassociated(sigrdataset))
   1885 				dns_rdataset_disassociate(sigrdataset);
   1886 		} else if (result == ISC_R_SUCCESS) {
   1887 			isc_boolean_t invalid = ISC_FALSE;
   1888 			mname = NULL;
   1889 			have_a = ISC_TRUE;
   1890 			if (additionaltype ==
   1891 			    dns_rdatasetadditional_fromcache &&
   1892 			    (DNS_TRUST_PENDING(rdataset->trust) ||
   1893 			     DNS_TRUST_GLUE(rdataset->trust)))
   1894 			{
   1895 				/* validate() may change rdataset->trust */
   1896 				invalid = ISC_TF(!!validate(client, db, fname,
   1897 							rdataset, sigrdataset));
   1898 			}
   1899 			if (invalid && DNS_TRUST_PENDING(rdataset->trust)) {
   1900 				dns_rdataset_disassociate(rdataset);
   1901 				if (sigrdataset != NULL &&
   1902 				    dns_rdataset_isassociated(sigrdataset))
   1903 					dns_rdataset_disassociate(sigrdataset);
   1904 			} else if (!query_isduplicate(client, fname,
   1905 					       dns_rdatatype_a, &mname)) {
   1906 				if (mname != fname) {
   1907 					if (mname != NULL) {
   1908 						query_releasename(client,
   1909 								  &fname);
   1910 						fname = mname;
   1911 					} else
   1912 						need_addname = ISC_TRUE;
   1913 				}
   1914 				ISC_LIST_APPEND(fname->list, rdataset, link);
   1915 				added_something = ISC_TRUE;
   1916 				if (sigrdataset != NULL &&
   1917 				    dns_rdataset_isassociated(sigrdataset))
   1918 				{
   1919 					ISC_LIST_APPEND(fname->list,
   1920 							sigrdataset, link);
   1921 					sigrdataset =
   1922 						query_newrdataset(client);
   1923 				}
   1924 				rdataset = query_newrdataset(client);
   1925 				if (rdataset == NULL)
   1926 					goto addname;
   1927 				if (WANTDNSSEC(client) && sigrdataset == NULL)
   1928 					goto addname;
   1929 			} else {
   1930 				dns_rdataset_disassociate(rdataset);
   1931 				if (sigrdataset != NULL &&
   1932 				    dns_rdataset_isassociated(sigrdataset))
   1933 					dns_rdataset_disassociate(sigrdataset);
   1934 			}
   1935 		}
   1936  aaaa_lookup:
   1937 		if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
   1938 			goto addname;
   1939 		result = dns_db_findrdataset(db, node, version,
   1940 					     dns_rdatatype_aaaa, 0,
   1941 					     client->now,
   1942 					     rdataset, sigrdataset);
   1943 		if (result == DNS_R_NCACHENXDOMAIN) {
   1944 			goto addname;
   1945 		} else if (result == DNS_R_NCACHENXRRSET) {
   1946 			dns_rdataset_disassociate(rdataset);
   1947 			if (sigrdataset != NULL &&
   1948 			    dns_rdataset_isassociated(sigrdataset))
   1949 				dns_rdataset_disassociate(sigrdataset);
   1950 		} else if (result == ISC_R_SUCCESS) {
   1951 			isc_boolean_t invalid = ISC_FALSE;
   1952 			mname = NULL;
   1953 			/*
   1954 			 * There's an A; check whether we're filtering AAAA
   1955 			 */
   1956 			if (have_a &&
   1957 			    (client->filter_aaaa == dns_aaaa_break_dnssec ||
   1958 			    (client->filter_aaaa == dns_aaaa_filter &&
   1959 			     (!WANTDNSSEC(client) || sigrdataset == NULL ||
   1960 			      !dns_rdataset_isassociated(sigrdataset)))))
   1961 				goto addname;
   1962 			if (additionaltype ==
   1963 			    dns_rdatasetadditional_fromcache &&
   1964 			    (DNS_TRUST_PENDING(rdataset->trust) ||
   1965 			     DNS_TRUST_GLUE(rdataset->trust)))
   1966 			{
   1967 				/* validate() may change rdataset->trust */
   1968 				invalid = ISC_TF(!!validate(client, db, fname,
   1969 							rdataset, sigrdataset));
   1970 			}
   1971 
   1972 			if (invalid && DNS_TRUST_PENDING(rdataset->trust)) {
   1973 				dns_rdataset_disassociate(rdataset);
   1974 				if (sigrdataset != NULL &&
   1975 				    dns_rdataset_isassociated(sigrdataset))
   1976 					dns_rdataset_disassociate(sigrdataset);
   1977 			} else if (!query_isduplicate(client, fname,
   1978 					       dns_rdatatype_aaaa, &mname)) {
   1979 				if (mname != fname) {
   1980 					if (mname != NULL) {
   1981 						query_releasename(client,
   1982 								  &fname);
   1983 						fname = mname;
   1984 					} else
   1985 						need_addname = ISC_TRUE;
   1986 				}
   1987 				ISC_LIST_APPEND(fname->list, rdataset, link);
   1988 				added_something = ISC_TRUE;
   1989 				if (sigrdataset != NULL &&
   1990 				    dns_rdataset_isassociated(sigrdataset))
   1991 				{
   1992 					ISC_LIST_APPEND(fname->list,
   1993 							sigrdataset, link);
   1994 					sigrdataset = NULL;
   1995 				}
   1996 				rdataset = NULL;
   1997 			}
   1998 		}
   1999 	}
   2000 
   2001  addname:
   2002 	CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: addname");
   2003 	/*
   2004 	 * If we haven't added anything, then we're done.
   2005 	 */
   2006 	if (!added_something)
   2007 		goto cleanup;
   2008 
   2009 	/*
   2010 	 * We may have added our rdatasets to an existing name, if so, then
   2011 	 * need_addname will be ISC_FALSE.  Whether we used an existing name
   2012 	 * or a new one, we must set fname to NULL to prevent cleanup.
   2013 	 */
   2014 	if (need_addname)
   2015 		dns_message_addname(client->message, fname,
   2016 				    DNS_SECTION_ADDITIONAL);
   2017 	fname = NULL;
   2018 
   2019 	/*
   2020 	 * In a few cases, we want to add additional data for additional
   2021 	 * data.  It's simpler to just deal with special cases here than
   2022 	 * to try to create a general purpose mechanism and allow the
   2023 	 * rdata implementations to do it themselves.
   2024 	 *
   2025 	 * This involves recursion, but the depth is limited.  The
   2026 	 * most complex case is adding a SRV rdataset, which involves
   2027 	 * recursing to add address records, which in turn can cause
   2028 	 * recursion to add KEYs.
   2029 	 */
   2030 	if (type == dns_rdatatype_srv && trdataset != NULL) {
   2031 		/*
   2032 		 * If we're adding SRV records to the additional data
   2033 		 * section, it's helpful if we add the SRV additional data
   2034 		 * as well.
   2035 		 */
   2036 		eresult = dns_rdataset_additionaldata(trdataset,
   2037 						      query_addadditional,
   2038 						      client);
   2039 	}
   2040 
   2041  cleanup:
   2042 	CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: cleanup");
   2043 	query_putrdataset(client, &rdataset);
   2044 	if (sigrdataset != NULL)
   2045 		query_putrdataset(client, &sigrdataset);
   2046 	if (fname != NULL)
   2047 		query_releasename(client, &fname);
   2048 	if (node != NULL)
   2049 		dns_db_detachnode(db, &node);
   2050 	if (db != NULL)
   2051 		dns_db_detach(&db);
   2052 
   2053 	CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: done");
   2054 	return (eresult);
   2055 }
   2056 
   2057 static void
   2058 query_addrdataset(ns_client_t *client, dns_section_t section,
   2059 		  dns_name_t *fname, dns_rdataset_t *rdataset)
   2060 {
   2061 	UNUSED(section);
   2062 
   2063 	/*
   2064 	 * Add 'rdataset' and any pertinent additional data to
   2065 	 * 'fname', a name in the response message for 'client'.
   2066 	 */
   2067 
   2068 	CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset");
   2069 
   2070 	ISC_LIST_APPEND(fname->list, rdataset, link);
   2071 
   2072 	if (client->view->order != NULL)
   2073 		rdataset->attributes |= dns_order_find(client->view->order,
   2074 						       fname, rdataset->type,
   2075 						       rdataset->rdclass);
   2076 	rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
   2077 
   2078 	if (NOADDITIONAL(client))
   2079 		return;
   2080 
   2081 	/*
   2082 	 * Try to process glue directly.
   2083 	 */
   2084 	if (client->view->use_glue_cache &&
   2085 	    (rdataset->type == dns_rdatatype_ns) &&
   2086 	    (client->query.gluedb != NULL) &&
   2087 	    dns_db_iszone(client->query.gluedb))
   2088 	{
   2089 		isc_result_t result;
   2090 		ns_dbversion_t *dbversion;
   2091 		unsigned int options = 0;
   2092 
   2093 		dbversion = query_findversion(client, client->query.gluedb);
   2094 		if (dbversion == NULL)
   2095 			goto regular;
   2096 
   2097 		if (client->filter_aaaa == dns_aaaa_filter ||
   2098 		    client->filter_aaaa == dns_aaaa_break_dnssec)
   2099 		{
   2100 			options |= DNS_RDATASETADDGLUE_FILTERAAAA;
   2101 		}
   2102 
   2103 		result = dns_rdataset_addglue(rdataset, dbversion->version,
   2104 					      options, client->message);
   2105 		if (result == ISC_R_SUCCESS)
   2106 			return;
   2107 	}
   2108 
   2109 regular:
   2110 	/*
   2111 	 * Add additional data.
   2112 	 *
   2113 	 * We don't care if dns_rdataset_additionaldata() fails.
   2114 	 */
   2115 	(void)dns_rdataset_additionaldata(rdataset, query_addadditional,
   2116 					  client);
   2117 	CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done");
   2118 }
   2119 
   2120 static void
   2121 query_addrrset(ns_client_t *client, dns_name_t **namep,
   2122 	       dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
   2123 	       isc_buffer_t *dbuf, dns_section_t section)
   2124 {
   2125 	dns_name_t *name = *namep, *mname = NULL;
   2126 	dns_rdataset_t *rdataset = *rdatasetp, *mrdataset = NULL;
   2127 	dns_rdataset_t *sigrdataset = NULL;
   2128 	isc_result_t result;
   2129 
   2130 	CTRACE(ISC_LOG_DEBUG(3), "query_addrrset");
   2131 
   2132 	if (sigrdatasetp != NULL)
   2133 		sigrdataset = *sigrdatasetp;
   2134 
   2135 	/*%
   2136 	 * To the current response for 'client', add the answer RRset
   2137 	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
   2138 	 * owner name '*namep', to section 'section', unless they are
   2139 	 * already there.  Also add any pertinent additional data.
   2140 	 *
   2141 	 * If 'dbuf' is not NULL, then '*namep' is the name whose data is
   2142 	 * stored in 'dbuf'.  In this case, query_addrrset() guarantees that
   2143 	 * when it returns the name will either have been kept or released.
   2144 	 */
   2145 	result = dns_message_findname(client->message, section,
   2146 				      name, rdataset->type, rdataset->covers,
   2147 				      &mname, &mrdataset);
   2148 	if (result == ISC_R_SUCCESS) {
   2149 		/*
   2150 		 * We've already got an RRset of the given name and type.
   2151 		 */
   2152 		CTRACE(ISC_LOG_DEBUG(3),
   2153 		       "query_addrrset: dns_message_findname succeeded: done");
   2154 		if (dbuf != NULL)
   2155 			query_releasename(client, namep);
   2156 		if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0)
   2157 			mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
   2158 		return;
   2159 	} else if (result == DNS_R_NXDOMAIN) {
   2160 		/*
   2161 		 * The name doesn't exist.
   2162 		 */
   2163 		if (dbuf != NULL)
   2164 			query_keepname(client, name, dbuf);
   2165 		dns_message_addname(client->message, name, section);
   2166 		*namep = NULL;
   2167 		mname = name;
   2168 	} else {
   2169 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
   2170 		if (dbuf != NULL)
   2171 			query_releasename(client, namep);
   2172 	}
   2173 
   2174 	if (rdataset->trust != dns_trust_secure &&
   2175 	    (section == DNS_SECTION_ANSWER ||
   2176 	     section == DNS_SECTION_AUTHORITY))
   2177 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
   2178 
   2179 	/*
   2180 	 * Note: we only add SIGs if we've added the type they cover, so
   2181 	 * we do not need to check if the SIG rdataset is already in the
   2182 	 * response.
   2183 	 */
   2184 	query_addrdataset(client, section, mname, rdataset);
   2185 	*rdatasetp = NULL;
   2186 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
   2187 		/*
   2188 		 * We have a signature.  Add it to the response.
   2189 		 */
   2190 		ISC_LIST_APPEND(mname->list, sigrdataset, link);
   2191 		*sigrdatasetp = NULL;
   2192 	}
   2193 
   2194 	CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done");
   2195 }
   2196 
   2197 /*
   2198  * Mark the RRsets as secure.  Update the cache (db) to reflect the
   2199  * change in trust level.
   2200  */
   2201 static void
   2202 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name,
   2203 	    dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset,
   2204 	    dns_rdataset_t *sigrdataset)
   2205 {
   2206 	isc_result_t result;
   2207 	dns_dbnode_t *node = NULL;
   2208 	dns_clientinfomethods_t cm;
   2209 	dns_clientinfo_t ci;
   2210 	isc_stdtime_t now;
   2211 
   2212 	rdataset->trust = dns_trust_secure;
   2213 	sigrdataset->trust = dns_trust_secure;
   2214 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   2215 	dns_clientinfo_init(&ci, client, NULL);
   2216 
   2217 	/*
   2218 	 * Save the updated secure state.  Ignore failures.
   2219 	 */
   2220 	result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node);
   2221 	if (result != ISC_R_SUCCESS)
   2222 		return;
   2223 
   2224 	isc_stdtime_get(&now);
   2225 	dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now,
   2226 			     client->view->acceptexpired);
   2227 
   2228 	(void)dns_db_addrdataset(db, node, NULL, client->now, rdataset,
   2229 				 0, NULL);
   2230 	(void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset,
   2231 				 0, NULL);
   2232 	dns_db_detachnode(db, &node);
   2233 }
   2234 
   2235 /*
   2236  * Find the secure key that corresponds to rrsig.
   2237  * Note: 'keyrdataset' maintains state between successive calls,
   2238  * there may be multiple keys with the same keyid.
   2239  * Return ISC_FALSE if we have exhausted all the possible keys.
   2240  */
   2241 static isc_boolean_t
   2242 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
   2243 	dns_rdataset_t *keyrdataset, dst_key_t **keyp)
   2244 {
   2245 	isc_result_t result;
   2246 	dns_dbnode_t *node = NULL;
   2247 	isc_boolean_t secure = ISC_FALSE;
   2248 	dns_clientinfomethods_t cm;
   2249 	dns_clientinfo_t ci;
   2250 
   2251 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   2252 	dns_clientinfo_init(&ci, client, NULL);
   2253 
   2254 	if (!dns_rdataset_isassociated(keyrdataset)) {
   2255 		result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE,
   2256 					    &cm, &ci, &node);
   2257 		if (result != ISC_R_SUCCESS)
   2258 			return (ISC_FALSE);
   2259 
   2260 		result = dns_db_findrdataset(db, node, NULL,
   2261 					     dns_rdatatype_dnskey, 0,
   2262 					     client->now, keyrdataset, NULL);
   2263 		dns_db_detachnode(db, &node);
   2264 		if (result != ISC_R_SUCCESS)
   2265 			return (ISC_FALSE);
   2266 
   2267 		if (keyrdataset->trust != dns_trust_secure)
   2268 			return (ISC_FALSE);
   2269 
   2270 		result = dns_rdataset_first(keyrdataset);
   2271 	} else
   2272 		result = dns_rdataset_next(keyrdataset);
   2273 
   2274 	for ( ; result == ISC_R_SUCCESS;
   2275 	     result = dns_rdataset_next(keyrdataset)) {
   2276 		dns_rdata_t rdata = DNS_RDATA_INIT;
   2277 		isc_buffer_t b;
   2278 
   2279 		dns_rdataset_current(keyrdataset, &rdata);
   2280 		isc_buffer_init(&b, rdata.data, rdata.length);
   2281 		isc_buffer_add(&b, rdata.length);
   2282 		result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b,
   2283 					 client->mctx, keyp);
   2284 		if (result != ISC_R_SUCCESS)
   2285 			continue;
   2286 		if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) &&
   2287 		    rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) &&
   2288 		    dst_key_iszonekey(*keyp)) {
   2289 			secure = ISC_TRUE;
   2290 			break;
   2291 		}
   2292 		dst_key_free(keyp);
   2293 	}
   2294 	return (secure);
   2295 }
   2296 
   2297 static isc_boolean_t
   2298 verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
   2299        dns_rdata_t *rdata, ns_client_t *client)
   2300 {
   2301 	isc_result_t result;
   2302 	dns_fixedname_t fixed;
   2303 	isc_boolean_t ignore = ISC_FALSE;
   2304 
   2305 	dns_fixedname_init(&fixed);
   2306 
   2307 again:
   2308 	result = dns_dnssec_verify3(name, rdataset, key, ignore,
   2309 				    client->view->maxbits, client->mctx,
   2310 				    rdata, NULL);
   2311 	if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
   2312 		ignore = ISC_TRUE;
   2313 		goto again;
   2314 	}
   2315 	if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD)
   2316 		return (ISC_TRUE);
   2317 	return (ISC_FALSE);
   2318 }
   2319 
   2320 /*
   2321  * Validate the rdataset if possible with available records.
   2322  */
   2323 static isc_boolean_t
   2324 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
   2325 	 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
   2326 {
   2327 	isc_result_t result;
   2328 	dns_rdata_t rdata = DNS_RDATA_INIT;
   2329 	dns_rdata_rrsig_t rrsig;
   2330 	dst_key_t *key = NULL;
   2331 	dns_rdataset_t keyrdataset;
   2332 
   2333 	if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset))
   2334 		return (ISC_FALSE);
   2335 
   2336 	for (result = dns_rdataset_first(sigrdataset);
   2337 	     result == ISC_R_SUCCESS;
   2338 	     result = dns_rdataset_next(sigrdataset)) {
   2339 
   2340 		dns_rdata_reset(&rdata);
   2341 		dns_rdataset_current(sigrdataset, &rdata);
   2342 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   2343 		if (result != ISC_R_SUCCESS)
   2344 			return (ISC_FALSE);
   2345 		if (!dns_resolver_algorithm_supported(client->view->resolver,
   2346 						      name, rrsig.algorithm))
   2347 			continue;
   2348 		if (!dns_name_issubdomain(name, &rrsig.signer))
   2349 			continue;
   2350 		dns_rdataset_init(&keyrdataset);
   2351 		do {
   2352 			if (!get_key(client, db, &rrsig, &keyrdataset, &key))
   2353 				break;
   2354 			if (verify(key, name, rdataset, &rdata, client)) {
   2355 				dst_key_free(&key);
   2356 				dns_rdataset_disassociate(&keyrdataset);
   2357 				mark_secure(client, db, name, &rrsig,
   2358 					    rdataset, sigrdataset);
   2359 				return (ISC_TRUE);
   2360 			}
   2361 			dst_key_free(&key);
   2362 		} while (1);
   2363 		if (dns_rdataset_isassociated(&keyrdataset))
   2364 			dns_rdataset_disassociate(&keyrdataset);
   2365 	}
   2366 	return (ISC_FALSE);
   2367 }
   2368 
   2369 static void
   2370 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) {
   2371 	if (*rdataset == NULL)
   2372 		*rdataset = query_newrdataset(client);
   2373 	else  if (dns_rdataset_isassociated(*rdataset))
   2374 		dns_rdataset_disassociate(*rdataset);
   2375 }
   2376 
   2377 static void
   2378 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf,
   2379 	 isc_buffer_t *nbuf)
   2380 {
   2381 	if (*fname == NULL) {
   2382 		*dbuf = query_getnamebuf(client);
   2383 		if (*dbuf == NULL)
   2384 			return;
   2385 		*fname = query_newname(client, *dbuf, nbuf);
   2386 	}
   2387 }
   2388 
   2389 static void
   2390 free_devent(ns_client_t *client, isc_event_t **eventp,
   2391 	    dns_fetchevent_t **deventp)
   2392 {
   2393 	dns_fetchevent_t *devent = *deventp;
   2394 
   2395 	REQUIRE((void*)(*eventp) == (void *)(*deventp));
   2396 
   2397 	if (devent->fetch != NULL)
   2398 		dns_resolver_destroyfetch(&devent->fetch);
   2399 	if (devent->node != NULL)
   2400 		dns_db_detachnode(devent->db, &devent->node);
   2401 	if (devent->db != NULL)
   2402 		dns_db_detach(&devent->db);
   2403 	if (devent->rdataset != NULL)
   2404 		query_putrdataset(client, &devent->rdataset);
   2405 	if (devent->sigrdataset != NULL)
   2406 		query_putrdataset(client, &devent->sigrdataset);
   2407 	/*
   2408 	 * If the two pointers are the same then leave the setting of
   2409 	 * (*deventp) to NULL to isc_event_free.
   2410 	 */
   2411 	if ((void *)eventp != (void *)deventp)
   2412 		(*deventp) = NULL;
   2413 	isc_event_free(eventp);
   2414 }
   2415 
   2416 static void
   2417 prefetch_done(isc_task_t *task, isc_event_t *event) {
   2418 	dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
   2419 	ns_client_t *client;
   2420 
   2421 	UNUSED(task);
   2422 
   2423 	REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
   2424 	client = devent->ev_arg;
   2425 	REQUIRE(NS_CLIENT_VALID(client));
   2426 	REQUIRE(task == client->task);
   2427 
   2428 	LOCK(&client->query.fetchlock);
   2429 	if (client->query.prefetch != NULL) {
   2430 		INSIST(devent->fetch == client->query.prefetch);
   2431 		client->query.prefetch = NULL;
   2432 	}
   2433 	UNLOCK(&client->query.fetchlock);
   2434 	free_devent(client, &event, &devent);
   2435 	ns_client_detach(&client);
   2436 }
   2437 
   2438 static void
   2439 query_prefetch(ns_client_t *client, dns_name_t *qname,
   2440 	       dns_rdataset_t *rdataset)
   2441 {
   2442 	isc_result_t result;
   2443 	isc_sockaddr_t *peeraddr;
   2444 	dns_rdataset_t *tmprdataset;
   2445 	ns_client_t *dummy = NULL;
   2446 	unsigned int options;
   2447 
   2448 	if (client->query.prefetch != NULL ||
   2449 	    client->view->prefetch_trigger == 0U ||
   2450 	    rdataset->ttl > client->view->prefetch_trigger ||
   2451 	    (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0)
   2452 		return;
   2453 
   2454 	if (client->recursionquota == NULL) {
   2455 		result = isc_quota_attach(&client->sctx->recursionquota,
   2456 					  &client->recursionquota);
   2457 		if (result == ISC_R_SUCCESS && !client->mortal && !TCP(client))
   2458 			result = ns_client_replace(client);
   2459 		if (result != ISC_R_SUCCESS)
   2460 			return;
   2461 		ns_stats_increment(client->sctx->nsstats,
   2462 				   ns_statscounter_recursclients);
   2463 	}
   2464 
   2465 	tmprdataset = query_newrdataset(client);
   2466 	if (tmprdataset == NULL)
   2467 		return;
   2468 	if (!TCP(client))
   2469 		peeraddr = &client->peeraddr;
   2470 	else
   2471 		peeraddr = NULL;
   2472 	ns_client_attach(client, &dummy);
   2473 	options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
   2474 	result = dns_resolver_createfetch3(client->view->resolver,
   2475 					   qname, rdataset->type, NULL, NULL,
   2476 					   NULL, peeraddr, client->message->id,
   2477 					   options, 0, NULL, client->task,
   2478 					   prefetch_done, client,
   2479 					   tmprdataset, NULL,
   2480 					   &client->query.prefetch);
   2481 	if (result != ISC_R_SUCCESS) {
   2482 		query_putrdataset(client, &tmprdataset);
   2483 		ns_client_detach(&dummy);
   2484 	}
   2485 	dns_rdataset_clearprefetch(rdataset);
   2486 	ns_stats_increment(client->sctx->nsstats,
   2487 			   ns_statscounter_prefetch);
   2488 }
   2489 
   2490 static inline void
   2491 rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
   2492 	  dns_rdataset_t **rdatasetp)
   2493 {
   2494 	if (nodep != NULL && *nodep != NULL) {
   2495 		REQUIRE(dbp != NULL && *dbp != NULL);
   2496 		dns_db_detachnode(*dbp, nodep);
   2497 	}
   2498 	if (dbp != NULL && *dbp != NULL)
   2499 		dns_db_detach(dbp);
   2500 	if (zonep != NULL && *zonep != NULL)
   2501 		dns_zone_detach(zonep);
   2502 	if (rdatasetp != NULL && *rdatasetp != NULL &&
   2503 	    dns_rdataset_isassociated(*rdatasetp))
   2504 		dns_rdataset_disassociate(*rdatasetp);
   2505 }
   2506 
   2507 static inline void
   2508 rpz_match_clear(dns_rpz_st_t *st) {
   2509 	rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
   2510 	st->m.version = NULL;
   2511 }
   2512 
   2513 static inline isc_result_t
   2514 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) {
   2515 	REQUIRE(rdatasetp != NULL);
   2516 
   2517 	CTRACE(ISC_LOG_DEBUG(3), "rpz_ready");
   2518 
   2519 	if (*rdatasetp == NULL) {
   2520 		*rdatasetp = query_newrdataset(client);
   2521 		if (*rdatasetp == NULL) {
   2522 			CTRACE(ISC_LOG_ERROR,
   2523 			       "rpz_ready: query_newrdataset failed");
   2524 			return (DNS_R_SERVFAIL);
   2525 		}
   2526 	} else if (dns_rdataset_isassociated(*rdatasetp)) {
   2527 		dns_rdataset_disassociate(*rdatasetp);
   2528 	}
   2529 	return (ISC_R_SUCCESS);
   2530 }
   2531 
   2532 static void
   2533 rpz_st_clear(ns_client_t *client) {
   2534 	dns_rpz_st_t *st = client->query.rpz_st;
   2535 
   2536 	CTRACE(ISC_LOG_DEBUG(3), "rpz_st_clear");
   2537 
   2538 	if (st->m.rdataset != NULL) {
   2539 		query_putrdataset(client, &st->m.rdataset);
   2540 	}
   2541 	rpz_match_clear(st);
   2542 
   2543 	rpz_clean(NULL, &st->r.db, NULL, NULL);
   2544 	if (st->r.ns_rdataset != NULL) {
   2545 		query_putrdataset(client, &st->r.ns_rdataset);
   2546 	}
   2547 	if (st->r.r_rdataset != NULL) {
   2548 		query_putrdataset(client, &st->r.r_rdataset);
   2549 	}
   2550 
   2551 	rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL);
   2552 	if (st->q.rdataset != NULL) {
   2553 		query_putrdataset(client, &st->q.rdataset);
   2554 	}
   2555 	if (st->q.sigrdataset != NULL) {
   2556 		query_putrdataset(client, &st->q.sigrdataset);
   2557 	}
   2558 	st->state = 0;
   2559 	st->m.type = DNS_RPZ_TYPE_BAD;
   2560 	st->m.policy = DNS_RPZ_POLICY_MISS;
   2561 	if (st->rpsdb != NULL) {
   2562 		dns_db_detach(&st->rpsdb);
   2563 	}
   2564 
   2565 }
   2566 
   2567 static dns_rpz_zbits_t
   2568 rpz_get_zbits(ns_client_t *client,
   2569 	      dns_rdatatype_t ip_type, dns_rpz_type_t rpz_type)
   2570 {
   2571 	dns_rpz_st_t *st;
   2572 	dns_rpz_zbits_t zbits;
   2573 
   2574 	REQUIRE(client != NULL);
   2575 	REQUIRE(client->query.rpz_st != NULL);
   2576 
   2577 	st = client->query.rpz_st;
   2578 
   2579 #ifdef USE_DNSRPS
   2580 	if (st->popt.dnsrps_enabled) {
   2581 		if (st->rpsdb == NULL ||
   2582 		    librpz->have_trig(dns_dnsrps_type2trig(rpz_type),
   2583 				      ip_type == dns_rdatatype_aaaa,
   2584 				      ((rpsdb_t *)st->rpsdb)->rsp))
   2585 		{
   2586 			return (DNS_RPZ_ALL_ZBITS);
   2587 		}
   2588 		return (0);
   2589 	}
   2590 #endif
   2591 
   2592 	switch (rpz_type) {
   2593 	case DNS_RPZ_TYPE_CLIENT_IP:
   2594 		zbits = st->have.client_ip;
   2595 		break;
   2596 	case DNS_RPZ_TYPE_QNAME:
   2597 		zbits = st->have.qname;
   2598 		break;
   2599 	case DNS_RPZ_TYPE_IP:
   2600 		if (ip_type == dns_rdatatype_a) {
   2601 			zbits = st->have.ipv4;
   2602 		} else if (ip_type == dns_rdatatype_aaaa) {
   2603 			zbits = st->have.ipv6;
   2604 		} else {
   2605 			zbits = st->have.ip;
   2606 		}
   2607 		break;
   2608 	case DNS_RPZ_TYPE_NSDNAME:
   2609 		zbits = st->have.nsdname;
   2610 		break;
   2611 	case DNS_RPZ_TYPE_NSIP:
   2612 		if (ip_type == dns_rdatatype_a) {
   2613 			zbits = st->have.nsipv4;
   2614 		} else if (ip_type == dns_rdatatype_aaaa) {
   2615 			zbits = st->have.nsipv6;
   2616 		} else {
   2617 			zbits = st->have.nsip;
   2618 		}
   2619 		break;
   2620 	default:
   2621 		INSIST(0);
   2622 		break;
   2623 	}
   2624 
   2625 	/*
   2626 	 * Choose
   2627 	 *	the earliest configured policy zone (rpz->num)
   2628 	 *	QNAME over IP over NSDNAME over NSIP (rpz_type)
   2629 	 *	the smallest name,
   2630 	 *	the longest IP address prefix,
   2631 	 *	the lexically smallest address.
   2632 	 */
   2633 	if (st->m.policy != DNS_RPZ_POLICY_MISS) {
   2634 		if (st->m.type >= rpz_type) {
   2635 			zbits &= DNS_RPZ_ZMASK(st->m.rpz->num);
   2636 		} else{
   2637 			zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1;
   2638 		}
   2639 	}
   2640 
   2641 	/*
   2642 	 * If the client wants recursion, allow only compatible policies.
   2643 	 */
   2644 	if (!RECURSIONOK(client))
   2645 		zbits &= st->popt.no_rd_ok;
   2646 
   2647 	return (zbits);
   2648 }
   2649 
   2650 static void
   2651 query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) {
   2652 	isc_result_t result;
   2653 	isc_sockaddr_t *peeraddr;
   2654 	dns_rdataset_t *tmprdataset;
   2655 	ns_client_t *dummy = NULL;
   2656 	unsigned int options;
   2657 
   2658 	if (client->query.prefetch != NULL)
   2659 		return;
   2660 
   2661 	if (client->recursionquota == NULL) {
   2662 		result = isc_quota_attach(&client->sctx->recursionquota,
   2663 					  &client->recursionquota);
   2664 		if (result == ISC_R_SUCCESS && !client->mortal && !TCP(client))
   2665 			result = ns_client_replace(client);
   2666 		if (result != ISC_R_SUCCESS)
   2667 			return;
   2668 		ns_stats_increment(client->sctx->nsstats,
   2669 				   ns_statscounter_recursclients);
   2670 	}
   2671 
   2672 	tmprdataset = query_newrdataset(client);
   2673 	if (tmprdataset == NULL)
   2674 		return;
   2675 	if (!TCP(client))
   2676 		peeraddr = &client->peeraddr;
   2677 	else
   2678 		peeraddr = NULL;
   2679 	ns_client_attach(client, &dummy);
   2680 	options = client->query.fetchoptions;
   2681 	result = dns_resolver_createfetch3(client->view->resolver, qname, type,
   2682 					   NULL, NULL, NULL, peeraddr,
   2683 					   client->message->id, options, 0,
   2684 					   NULL, client->task, prefetch_done,
   2685 					   client, tmprdataset, NULL,
   2686 					   &client->query.prefetch);
   2687 	if (result != ISC_R_SUCCESS) {
   2688 		query_putrdataset(client, &tmprdataset);
   2689 		ns_client_detach(&dummy);
   2690 	}
   2691 }
   2692 
   2693 /*
   2694  * Get an NS, A, or AAAA rrset related to the response for the client
   2695  * to check the contents of that rrset for hits by eligible policy zones.
   2696  */
   2697 static isc_result_t
   2698 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
   2699 	       dns_rpz_type_t rpz_type, dns_db_t **dbp,
   2700 	       dns_dbversion_t *version, dns_rdataset_t **rdatasetp,
   2701 	       isc_boolean_t resuming)
   2702 {
   2703 	dns_rpz_st_t *st;
   2704 	isc_boolean_t is_zone;
   2705 	dns_dbnode_t *node;
   2706 	dns_fixedname_t fixed;
   2707 	dns_name_t *found;
   2708 	isc_result_t result;
   2709 	dns_clientinfomethods_t cm;
   2710 	dns_clientinfo_t ci;
   2711 
   2712 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rrset_find");
   2713 
   2714 	st = client->query.rpz_st;
   2715 	if ((st->state & DNS_RPZ_RECURSING) != 0) {
   2716 		INSIST(st->r.r_type == type);
   2717 		INSIST(dns_name_equal(name, st->r_name));
   2718 		INSIST(*rdatasetp == NULL ||
   2719 		       !dns_rdataset_isassociated(*rdatasetp));
   2720 		st->state &= ~DNS_RPZ_RECURSING;
   2721 		RESTORE(*dbp, st->r.db);
   2722 		if (*rdatasetp != NULL)
   2723 			query_putrdataset(client, rdatasetp);
   2724 		RESTORE(*rdatasetp, st->r.r_rdataset);
   2725 		result = st->r.r_result;
   2726 		if (result == DNS_R_DELEGATION) {
   2727 			CTRACE(ISC_LOG_ERROR, "RPZ recursing");
   2728 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
   2729 				     rpz_type, " rpz_rrset_find(1)", result);
   2730 			st->m.policy = DNS_RPZ_POLICY_ERROR;
   2731 			result = DNS_R_SERVFAIL;
   2732 		}
   2733 		return (result);
   2734 	}
   2735 
   2736 	result = rpz_ready(client, rdatasetp);
   2737 	if (result != ISC_R_SUCCESS) {
   2738 		st->m.policy = DNS_RPZ_POLICY_ERROR;
   2739 		return (result);
   2740 	}
   2741 	if (*dbp != NULL) {
   2742 		is_zone = ISC_FALSE;
   2743 	} else {
   2744 		dns_zone_t *zone;
   2745 
   2746 		version = NULL;
   2747 		zone = NULL;
   2748 		result = query_getdb(client, name, type, 0, &zone, dbp,
   2749 				     &version, &is_zone);
   2750 		if (result != ISC_R_SUCCESS) {
   2751 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
   2752 				     rpz_type, " rpz_rrset_find(2)", result);
   2753 			st->m.policy = DNS_RPZ_POLICY_ERROR;
   2754 			if (zone != NULL)
   2755 				dns_zone_detach(&zone);
   2756 			return (result);
   2757 		}
   2758 		if (zone != NULL)
   2759 			dns_zone_detach(&zone);
   2760 	}
   2761 
   2762 	node = NULL;
   2763 	found = dns_fixedname_initname(&fixed);
   2764 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   2765 	dns_clientinfo_init(&ci, client, NULL);
   2766 	result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
   2767 				client->now, &node, found,
   2768 				&cm, &ci, *rdatasetp, NULL);
   2769 	if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
   2770 		/*
   2771 		 * Try the cache if we're authoritative for an
   2772 		 * ancestor but not the domain itself.
   2773 		 */
   2774 		rpz_clean(NULL, dbp, &node, rdatasetp);
   2775 		version = NULL;
   2776 		dns_db_attach(client->view->cachedb, dbp);
   2777 		result = dns_db_findext(*dbp, name, version, type,
   2778 					0, client->now, &node, found,
   2779 					&cm, &ci, *rdatasetp, NULL);
   2780 	}
   2781 	rpz_clean(NULL, dbp, &node, NULL);
   2782 	if (result == DNS_R_DELEGATION) {
   2783 		rpz_clean(NULL, NULL, NULL, rdatasetp);
   2784 		/*
   2785 		 * Recurse for NS rrset or A or AAAA rrset for an NS.
   2786 		 * Do not recurse for addresses for the query name.
   2787 		 */
   2788 		if (rpz_type == DNS_RPZ_TYPE_IP) {
   2789 			result = DNS_R_NXRRSET;
   2790 		} else if (!client->view->rpzs->p.nsip_wait_recurse) {
   2791 			query_rpzfetch(client, name, type);
   2792 			result = DNS_R_NXRRSET;
   2793 		} else {
   2794 			dns_name_copy(name, st->r_name, NULL);
   2795 			result = query_recurse(client, type, st->r_name,
   2796 					       NULL, NULL, resuming);
   2797 			if (result == ISC_R_SUCCESS) {
   2798 				st->state |= DNS_RPZ_RECURSING;
   2799 				result = DNS_R_DELEGATION;
   2800 			}
   2801 		}
   2802 	}
   2803 	return (result);
   2804 }
   2805 
   2806 /*
   2807  * Compute a policy owner name, p_name, in a policy zone given the needed
   2808  * policy type and the trigger name.
   2809  */
   2810 static isc_result_t
   2811 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name,
   2812 	       dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
   2813 	       dns_name_t *trig_name)
   2814 {
   2815 	dns_offsets_t prefix_offsets;
   2816 	dns_name_t prefix, *suffix;
   2817 	unsigned int first, labels;
   2818 	isc_result_t result;
   2819 
   2820 	CTRACE(ISC_LOG_DEBUG(3), "rpz_get_p_name");
   2821 
   2822 	/*
   2823 	 * The policy owner name consists of a suffix depending on the type
   2824 	 * and policy zone and a prefix that is the longest possible string
   2825 	 * from the trigger name that keesp the resulting policy owner name
   2826 	 * from being too long.
   2827 	 */
   2828 	switch (rpz_type) {
   2829 	case DNS_RPZ_TYPE_CLIENT_IP:
   2830 		suffix = &rpz->client_ip;
   2831 		break;
   2832 	case DNS_RPZ_TYPE_QNAME:
   2833 		suffix = &rpz->origin;
   2834 		break;
   2835 	case DNS_RPZ_TYPE_IP:
   2836 		suffix = &rpz->ip;
   2837 		break;
   2838 	case DNS_RPZ_TYPE_NSDNAME:
   2839 		suffix = &rpz->nsdname;
   2840 		break;
   2841 	case DNS_RPZ_TYPE_NSIP:
   2842 		suffix = &rpz->nsip;
   2843 		break;
   2844 	default:
   2845 		INSIST(0);
   2846 	}
   2847 
   2848 	/*
   2849 	 * Start with relative version of the full trigger name,
   2850 	 * and trim enough allow the addition of the suffix.
   2851 	 */
   2852 	dns_name_init(&prefix, prefix_offsets);
   2853 	labels = dns_name_countlabels(trig_name);
   2854 	first = 0;
   2855 	for (;;) {
   2856 		dns_name_getlabelsequence(trig_name, first, labels-first-1,
   2857 					  &prefix);
   2858 		result = dns_name_concatenate(&prefix, suffix, p_name, NULL);
   2859 		if (result == ISC_R_SUCCESS)
   2860 			break;
   2861 		INSIST(result == DNS_R_NAMETOOLONG);
   2862 		/*
   2863 		 * Trim the trigger name until the combination is not too long.
   2864 		 */
   2865 		if (labels-first < 2) {
   2866 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix,
   2867 				     rpz_type, " concatentate()", result);
   2868 			return (ISC_R_FAILURE);
   2869 		}
   2870 		/*
   2871 		 * Complain once about trimming the trigger name.
   2872 		 */
   2873 		if (first == 0) {
   2874 			rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix,
   2875 				     rpz_type, " concatentate()", result);
   2876 		}
   2877 		++first;
   2878 	}
   2879 	return (ISC_R_SUCCESS);
   2880 }
   2881 
   2882 /*
   2883  * Look in policy zone rpz for a policy of rpz_type by p_name.
   2884  * The self-name (usually the client qname or an NS name) is compared with
   2885  * the target of a CNAME policy for the old style passthru encoding.
   2886  * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep,
   2887  * *rdatasetp, and *policyp.
   2888  * The target DNS type, qtype, chooses the best rdataset for *rdatasetp.
   2889  * The caller must decide if the found policy is most suitable, including
   2890  * better than a previously found policy.
   2891  * If it is best, the caller records it in client->query.rpz_st->m.
   2892  */
   2893 static isc_result_t
   2894 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype,
   2895 	   dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
   2896 	   dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
   2897 	   dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
   2898 	   dns_rpz_policy_t *policyp)
   2899 {
   2900 	dns_fixedname_t foundf;
   2901 	dns_name_t *found;
   2902 	isc_result_t result;
   2903 	dns_clientinfomethods_t cm;
   2904 	dns_clientinfo_t ci;
   2905 
   2906 	REQUIRE(nodep != NULL);
   2907 
   2908 	CTRACE(ISC_LOG_DEBUG(3), "rpz_find_p");
   2909 
   2910 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   2911 	dns_clientinfo_init(&ci, client, NULL);
   2912 
   2913 	/*
   2914 	 * Try to find either a CNAME or the type of record demanded by the
   2915 	 * request from the policy zone.
   2916 	 */
   2917 	rpz_clean(zonep, dbp, nodep, rdatasetp);
   2918 	result = rpz_ready(client, rdatasetp);
   2919 	if (result != ISC_R_SUCCESS) {
   2920 		CTRACE(ISC_LOG_ERROR, "rpz_ready() failed");
   2921 		return (DNS_R_SERVFAIL);
   2922 	}
   2923 	*versionp = NULL;
   2924 	result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp);
   2925 	if (result != ISC_R_SUCCESS)
   2926 		return (DNS_R_NXDOMAIN);
   2927 	found = dns_fixedname_initname(&foundf);
   2928 
   2929 	result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0,
   2930 				client->now, nodep, found, &cm, &ci,
   2931 				*rdatasetp, NULL);
   2932 	/*
   2933 	 * Choose the best rdataset if we found something.
   2934 	 */
   2935 	if (result == ISC_R_SUCCESS) {
   2936 		dns_rdatasetiter_t *rdsiter;
   2937 
   2938 		rdsiter = NULL;
   2939 		result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0,
   2940 					     &rdsiter);
   2941 		if (result != ISC_R_SUCCESS) {
   2942 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name,
   2943 				     rpz_type, " allrdatasets()", result);
   2944 			CTRACE(ISC_LOG_ERROR,
   2945 			       "rpz_find_p: allrdatasets failed");
   2946 			return (DNS_R_SERVFAIL);
   2947 		}
   2948 		for (result = dns_rdatasetiter_first(rdsiter);
   2949 		     result == ISC_R_SUCCESS;
   2950 		     result = dns_rdatasetiter_next(rdsiter)) {
   2951 			dns_rdatasetiter_current(rdsiter, *rdatasetp);
   2952 			if ((*rdatasetp)->type == dns_rdatatype_cname ||
   2953 			    (*rdatasetp)->type == qtype)
   2954 				break;
   2955 			dns_rdataset_disassociate(*rdatasetp);
   2956 		}
   2957 		dns_rdatasetiter_destroy(&rdsiter);
   2958 		if (result != ISC_R_SUCCESS) {
   2959 			if (result != ISC_R_NOMORE) {
   2960 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
   2961 					     p_name, rpz_type,
   2962 					     " rdatasetiter", result);
   2963 				CTRACE(ISC_LOG_ERROR,
   2964 				       "rpz_find_p: rdatasetiter failed");
   2965 				return (DNS_R_SERVFAIL);
   2966 			}
   2967 			/*
   2968 			 * Ask again to get the right DNS_R_DNAME/NXRRSET/...
   2969 			 * result if there is neither a CNAME nor target type.
   2970 			 */
   2971 			if (dns_rdataset_isassociated(*rdatasetp))
   2972 				dns_rdataset_disassociate(*rdatasetp);
   2973 			dns_db_detachnode(*dbp, nodep);
   2974 
   2975 			if (qtype == dns_rdatatype_rrsig ||
   2976 			    qtype == dns_rdatatype_sig)
   2977 				result = DNS_R_NXRRSET;
   2978 			else
   2979 				result = dns_db_findext(*dbp, p_name, *versionp,
   2980 							qtype, 0, client->now,
   2981 							nodep, found, &cm, &ci,
   2982 							*rdatasetp, NULL);
   2983 		}
   2984 	}
   2985 	switch (result) {
   2986 	case ISC_R_SUCCESS:
   2987 		if ((*rdatasetp)->type != dns_rdatatype_cname) {
   2988 			*policyp = DNS_RPZ_POLICY_RECORD;
   2989 		} else {
   2990 			*policyp = dns_rpz_decode_cname(rpz, *rdatasetp,
   2991 							self_name);
   2992 			if ((*policyp == DNS_RPZ_POLICY_RECORD ||
   2993 			     *policyp == DNS_RPZ_POLICY_WILDCNAME) &&
   2994 			    qtype != dns_rdatatype_cname &&
   2995 			    qtype != dns_rdatatype_any)
   2996 				return (DNS_R_CNAME);
   2997 		}
   2998 		return (ISC_R_SUCCESS);
   2999 	case DNS_R_NXRRSET:
   3000 		*policyp = DNS_RPZ_POLICY_NODATA;
   3001 		return (result);
   3002 	case DNS_R_DNAME:
   3003 		/*
   3004 		 * DNAME policy RRs have very few if any uses that are not
   3005 		 * better served with simple wildcards.  Making them work would
   3006 		 * require complications to get the number of labels matched
   3007 		 * in the name or the found name to the main DNS_R_DNAME case
   3008 		 * in query_dname().  The domain also does not appear in the
   3009 		 * summary database at the right level, so this happens only
   3010 		 * with a single policy zone when we have no summary database.
   3011 		 * Treat it as a miss.
   3012 		 */
   3013 	case DNS_R_NXDOMAIN:
   3014 	case DNS_R_EMPTYNAME:
   3015 		return (DNS_R_NXDOMAIN);
   3016 	default:
   3017 		rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
   3018 			     "", result);
   3019 		CTRACE(ISC_LOG_ERROR,
   3020 		       "rpz_find_p: unexpected result");
   3021 		return (DNS_R_SERVFAIL);
   3022 	}
   3023 }
   3024 
   3025 static void
   3026 rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
   3027 	   dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix,
   3028 	   isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp,
   3029 	   dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
   3030 	   dns_dbversion_t *version)
   3031 {
   3032 	dns_rdataset_t *trdataset = NULL;
   3033 
   3034 	rpz_match_clear(st);
   3035 	st->m.rpz = rpz;
   3036 	st->m.type = rpz_type;
   3037 	st->m.policy = policy;
   3038 	dns_name_copy(p_name, st->p_name, NULL);
   3039 	st->m.prefix = prefix;
   3040 	st->m.result = result;
   3041 	SAVE(st->m.zone, *zonep);
   3042 	SAVE(st->m.db, *dbp);
   3043 	SAVE(st->m.node, *nodep);
   3044 	if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) {
   3045 		/*
   3046 		 * Save the replacement rdataset from the policy
   3047 		 * and make the previous replacement rdataset scratch.
   3048 		 */
   3049 		SAVE(trdataset, st->m.rdataset);
   3050 		SAVE(st->m.rdataset, *rdatasetp);
   3051 		SAVE(*rdatasetp, trdataset);
   3052 		st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl);
   3053 	} else {
   3054 		st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl);
   3055 	}
   3056 	SAVE(st->m.version, version);
   3057 }
   3058 
   3059 #ifdef USE_DNSRPS
   3060 /*
   3061  * Check the results of a RPZ service interface lookup.
   3062  * Stop after an error (<0) or not a hit on a disabled zone (0).
   3063  * Continue after a hit on a disabled zone (>0).
   3064  */
   3065 static int
   3066 dnsrps_ck(librpz_emsg_t *emsg, ns_client_t *client, rpsdb_t *rpsdb,
   3067 	  isc_boolean_t recursed)
   3068 {
   3069 	isc_region_t region;
   3070 	librpz_domain_buf_t pname_buf;
   3071 
   3072 	if (!librpz->rsp_result(emsg, &rpsdb->result, recursed, rpsdb->rsp)) {
   3073 		return (-1);
   3074 	}
   3075 
   3076 	/*
   3077 	 * Forget the state from before the IP address or domain check
   3078 	 * if the lookup hit nothing.
   3079 	 */
   3080 	if (rpsdb->result.policy == LIBRPZ_POLICY_UNDEFINED ||
   3081 	    rpsdb->result.hit_id != rpsdb->hit_id ||
   3082 	    rpsdb->result.policy != LIBRPZ_POLICY_DISABLED)
   3083 	{
   3084 		if (!librpz->rsp_pop_discard(emsg, rpsdb->rsp)) {
   3085 			return (-1);
   3086 		}
   3087 		return (0);
   3088 	}
   3089 
   3090 	/*
   3091 	 * Log a hit on a disabled zone.
   3092 	 * Forget the zone to not try it again, and restore the pre-hit state.
   3093 	 */
   3094 	if (!librpz->rsp_domain(emsg, &pname_buf, rpsdb->rsp)) {
   3095 		return (-1);
   3096 	}
   3097 	region.base = pname_buf.d;
   3098 	region.length = pname_buf.size;
   3099 	dns_name_fromregion(client->query.rpz_st->p_name, &region);
   3100 	rpz_log_rewrite(client, ISC_TRUE,
   3101 			dns_dnsrps_2policy(rpsdb->result.zpolicy),
   3102 			dns_dnsrps_trig2type(rpsdb->result.trig), NULL,
   3103 			client->query.rpz_st->p_name, NULL,
   3104 			rpsdb->result.cznum);
   3105 
   3106 	if (!librpz->rsp_forget_zone(emsg, rpsdb->result.cznum, rpsdb->rsp) ||
   3107 	    !librpz->rsp_pop(emsg, &rpsdb->result, rpsdb->rsp))
   3108 	{
   3109 		return (-1);
   3110 	}
   3111 	return (1);
   3112 }
   3113 
   3114 /*
   3115  * Ready the shim database and rdataset for a DNSRPS hit.
   3116  */
   3117 static isc_boolean_t
   3118 dnsrps_set_p(librpz_emsg_t *emsg, ns_client_t *client, dns_rpz_st_t *st,
   3119 	     dns_rdatatype_t qtype, dns_rdataset_t **p_rdatasetp,
   3120 	     isc_boolean_t recursed)
   3121 {
   3122 	rpsdb_t *rpsdb;
   3123 	librpz_domain_buf_t pname_buf;
   3124 	isc_region_t region;
   3125 	dns_zone_t *p_zone;
   3126 	dns_db_t *p_db;
   3127 	dns_dbnode_t *p_node;
   3128 	dns_rpz_policy_t policy;
   3129 	dns_fixedname_t foundf;
   3130 	dns_name_t *found;
   3131 	dns_rdatatype_t foundtype, searchtype;
   3132 	isc_result_t result;
   3133 
   3134 	rpsdb = (rpsdb_t *)st->rpsdb;
   3135 
   3136 	if (!librpz->rsp_result(emsg, &rpsdb->result, recursed, rpsdb->rsp)) {
   3137 		return (ISC_FALSE);
   3138 	}
   3139 
   3140 	if (rpsdb->result.policy == LIBRPZ_POLICY_UNDEFINED) {
   3141 		return (ISC_TRUE);
   3142 	}
   3143 
   3144 	/*
   3145 	 * Give the fake or shim DNSRPS database its new origin.
   3146 	 */
   3147 	if (!librpz->rsp_soa(emsg, NULL, NULL, &rpsdb->origin_buf,
   3148 			     &rpsdb->result, rpsdb->rsp))
   3149 	{
   3150 		return (ISC_FALSE);
   3151 	}
   3152 	region.base = rpsdb->origin_buf.d;
   3153 	region.length = rpsdb->origin_buf.size;
   3154 	dns_name_fromregion(&rpsdb->common.origin, &region);
   3155 
   3156 	if (!librpz->rsp_domain(emsg, &pname_buf, rpsdb->rsp)) {
   3157 		return (ISC_FALSE);
   3158 	}
   3159 	region.base = pname_buf.d;
   3160 	region.length = pname_buf.size;
   3161 	dns_name_fromregion(st->p_name, &region);
   3162 
   3163 	p_zone = NULL;
   3164 	p_db = NULL;
   3165 	p_node = NULL;
   3166 	rpz_ready(client, p_rdatasetp);
   3167 	dns_db_attach(st->rpsdb, &p_db);
   3168 	policy = dns_dnsrps_2policy(rpsdb->result.policy);
   3169 	if (policy != DNS_RPZ_POLICY_RECORD) {
   3170 		result = ISC_R_SUCCESS;
   3171 	} else if (qtype == dns_rdatatype_rrsig) {
   3172 		/*
   3173 		 * dns_find_db() refuses to look for and fail to
   3174 		 * find dns_rdatatype_rrsig.
   3175 		 */
   3176 		result = DNS_R_NXRRSET;
   3177 		policy = DNS_RPZ_POLICY_NODATA;
   3178 	} else {
   3179 		/*
   3180 		 * Get the next (and so first) RR from the policy node.
   3181 		 * If it is a CNAME, then look for it regardless of the
   3182 		 * query type.
   3183 		 */
   3184 		if (!librpz->rsp_rr(emsg, &foundtype, NULL, NULL, NULL,
   3185 				    &rpsdb->result, rpsdb->qname->ndata,
   3186 				    rpsdb->qname->length, rpsdb->rsp))
   3187 		{
   3188 			return (ISC_FALSE);
   3189 		}
   3190 		if (foundtype == dns_rdatatype_cname) {
   3191 			searchtype = dns_rdatatype_cname;
   3192 		} else {
   3193 			searchtype = qtype;
   3194 		}
   3195 		/*
   3196 		 * Get the DNSPRS imitation rdataset.
   3197 		 */
   3198 		found = dns_fixedname_initname(&foundf);
   3199 		result = dns_db_find(p_db, st->p_name, NULL, searchtype,
   3200 				     0, 0, &p_node, found, *p_rdatasetp, NULL);
   3201 
   3202 		if (result == ISC_R_SUCCESS) {
   3203 			if (searchtype == dns_rdatatype_cname &&
   3204 			    qtype != dns_rdatatype_cname)
   3205 			{
   3206 				result = DNS_R_CNAME;
   3207 			}
   3208 		} else if (result == DNS_R_NXRRSET) {
   3209 			policy = DNS_RPZ_POLICY_NODATA;
   3210 		} else {
   3211 			snprintf(emsg->c, sizeof(emsg->c), "dns_db_find(): %s",
   3212 				 isc_result_totext(result));
   3213 			return (ISC_FALSE);
   3214 		}
   3215 	}
   3216 
   3217 	rpz_save_p(st, client->view->rpzs->zones[rpsdb->result.cznum],
   3218 		   dns_dnsrps_trig2type(rpsdb->result.trig), policy,
   3219 		   st->p_name, 0, result, &p_zone, &p_db, &p_node,
   3220 		   p_rdatasetp, NULL);
   3221 
   3222 	rpz_clean(NULL, NULL, NULL, p_rdatasetp);
   3223 
   3224 	return (ISC_TRUE);
   3225 }
   3226 
   3227 static isc_result_t
   3228 dnsrps_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
   3229 		  dns_rpz_type_t rpz_type, dns_rdataset_t **p_rdatasetp)
   3230 {
   3231 	dns_rpz_st_t *st;
   3232 	rpsdb_t *rpsdb;
   3233 	librpz_trig_t trig = LIBRPZ_TRIG_CLIENT_IP;
   3234 	isc_boolean_t recursed = ISC_FALSE;
   3235 	int res;
   3236 	librpz_emsg_t emsg;
   3237 	isc_result_t result;
   3238 
   3239 	st = client->query.rpz_st;
   3240 	rpsdb = (rpsdb_t *)st->rpsdb;
   3241 
   3242 	result = rpz_ready(client, p_rdatasetp);
   3243 	if (result != ISC_R_SUCCESS) {
   3244 		st->m.policy = DNS_RPZ_POLICY_ERROR;
   3245 		return (result);
   3246 	}
   3247 
   3248 	switch (rpz_type) {
   3249 	case DNS_RPZ_TYPE_CLIENT_IP:
   3250 		trig = LIBRPZ_TRIG_CLIENT_IP;
   3251 		recursed = ISC_FALSE;
   3252 		break;
   3253 	case DNS_RPZ_TYPE_IP:
   3254 		trig = LIBRPZ_TRIG_IP;
   3255 		recursed = ISC_TRUE;
   3256 		break;
   3257 	case DNS_RPZ_TYPE_NSIP:
   3258 		trig = LIBRPZ_TRIG_NSIP;
   3259 		recursed = ISC_TRUE;
   3260 		break;
   3261 	default:
   3262 		INSIST(0);
   3263 	}
   3264 
   3265 	do {
   3266 		if (!librpz->rsp_push(&emsg, rpsdb->rsp) ||
   3267 		    !librpz->ck_ip(&emsg,
   3268 				   netaddr->family == AF_INET
   3269 				   ? (const void *)&netaddr->type.in
   3270 				   : (const void *)&netaddr->type.in6,
   3271 				   netaddr->family, trig, ++rpsdb->hit_id,
   3272 				   recursed, rpsdb->rsp) ||
   3273 		    (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0)
   3274 		{
   3275 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
   3276 				     rpz_type, emsg.c, DNS_R_SERVFAIL);
   3277 			st->m.policy = DNS_RPZ_POLICY_ERROR;
   3278 			return (DNS_R_SERVFAIL);
   3279 		}
   3280 	} while (res != 0);
   3281 	return (ISC_R_SUCCESS);
   3282 }
   3283 
   3284 static isc_result_t
   3285 dnsrps_rewrite_name(ns_client_t *client, dns_name_t *trig_name,
   3286 		    isc_boolean_t recursed, dns_rpz_type_t rpz_type,
   3287 		    dns_rdataset_t **p_rdatasetp)
   3288 {
   3289 	dns_rpz_st_t *st;
   3290 	rpsdb_t *rpsdb;
   3291 	librpz_trig_t trig = LIBRPZ_TRIG_CLIENT_IP;
   3292 	isc_region_t r;
   3293 	int res;
   3294 	librpz_emsg_t emsg;
   3295 	isc_result_t result;
   3296 
   3297 	st = client->query.rpz_st;
   3298 	rpsdb = (rpsdb_t *)st->rpsdb;
   3299 
   3300 	result = rpz_ready(client, p_rdatasetp);
   3301 	if (result != ISC_R_SUCCESS) {
   3302 		st->m.policy = DNS_RPZ_POLICY_ERROR;
   3303 		return (result);
   3304 	}
   3305 
   3306 	switch (rpz_type) {
   3307 	case DNS_RPZ_TYPE_QNAME:
   3308 		trig = LIBRPZ_TRIG_QNAME;
   3309 		break;
   3310 	case DNS_RPZ_TYPE_NSDNAME:
   3311 		trig = LIBRPZ_TRIG_NSDNAME;
   3312 		break;
   3313 	default:
   3314 		INSIST(0);
   3315 	}
   3316 
   3317 	dns_name_toregion(trig_name, &r);
   3318 	do {
   3319 		if (!librpz->rsp_push(&emsg, rpsdb->rsp) ||
   3320 		    !librpz->ck_domain(&emsg, r.base, r.length,
   3321 				       trig, ++rpsdb->hit_id,
   3322 				       recursed, rpsdb->rsp) ||
   3323 		    (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0)
   3324 		{
   3325 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
   3326 				     rpz_type, emsg.c, DNS_R_SERVFAIL);
   3327 			st->m.policy = DNS_RPZ_POLICY_ERROR;
   3328 			return (DNS_R_SERVFAIL);
   3329 		}
   3330 	} while (res != 0);
   3331 	return (ISC_R_SUCCESS);
   3332 }
   3333 #endif /* USE_DNSRPS */
   3334 
   3335 /*
   3336  * Check this address in every eligible policy zone.
   3337  */
   3338 static isc_result_t
   3339 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
   3340 	       dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
   3341 	       dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp)
   3342 {
   3343 	dns_rpz_zones_t *rpzs;
   3344 	dns_rpz_st_t *st;
   3345 	dns_rpz_zone_t *rpz;
   3346 	dns_rpz_prefix_t prefix;
   3347 	dns_rpz_num_t rpz_num;
   3348 	dns_fixedname_t ip_namef, p_namef;
   3349 	dns_name_t *ip_name, *p_name;
   3350 	dns_zone_t *p_zone;
   3351 	dns_db_t *p_db;
   3352 	dns_dbversion_t *p_version;
   3353 	dns_dbnode_t *p_node;
   3354 	dns_rpz_policy_t policy;
   3355 	isc_result_t result;
   3356 
   3357 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip");
   3358 
   3359 	rpzs = client->view->rpzs;
   3360 	st = client->query.rpz_st;
   3361 #ifdef USE_DNSRPS
   3362 	if (st->popt.dnsrps_enabled) {
   3363 		return (dnsrps_rewrite_ip(client, netaddr, rpz_type,
   3364 					 p_rdatasetp));
   3365 	}
   3366 #endif
   3367 
   3368 	ip_name = dns_fixedname_initname(&ip_namef);
   3369 
   3370 	p_zone = NULL;
   3371 	p_db = NULL;
   3372 	p_node = NULL;
   3373 
   3374 	while (zbits != 0) {
   3375 		rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr,
   3376 					  ip_name, &prefix);
   3377 		if (rpz_num == DNS_RPZ_INVALID_NUM)
   3378 			break;
   3379 		zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1);
   3380 
   3381 		/*
   3382 		 * Do not try applying policy zones that cannot replace a
   3383 		 * previously found policy zone.
   3384 		 * Stop looking if the next best choice cannot
   3385 		 * replace what we already have.
   3386 		 */
   3387 		rpz = rpzs->zones[rpz_num];
   3388 		if (st->m.policy != DNS_RPZ_POLICY_MISS) {
   3389 			if (st->m.rpz->num < rpz->num)
   3390 				break;
   3391 			if (st->m.rpz->num == rpz->num &&
   3392 			    (st->m.type < rpz_type ||
   3393 			     st->m.prefix > prefix))
   3394 				break;
   3395 		}
   3396 
   3397 		/*
   3398 		 * Get the policy for a prefix at least as long
   3399 		 * as the prefix of the entry we had before.
   3400 		 */
   3401 		p_name = dns_fixedname_initname(&p_namef);
   3402 		result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name);
   3403 		if (result != ISC_R_SUCCESS)
   3404 			continue;
   3405 		result = rpz_find_p(client, ip_name, qtype,
   3406 				    p_name, rpz, rpz_type,
   3407 				    &p_zone, &p_db, &p_version, &p_node,
   3408 				    p_rdatasetp, &policy);
   3409 		switch (result) {
   3410 		case DNS_R_NXDOMAIN:
   3411 			/*
   3412 			 * Continue after a policy record that is missing
   3413 			 * contrary to the summary data.  The summary
   3414 			 * data can out of date during races with and among
   3415 			 * policy zone updates.
   3416 			 */
   3417 			CTRACE(ISC_LOG_ERROR,
   3418 			       "rpz_rewrite_ip: mismatched summary data; "
   3419 			       "continuing");
   3420 			continue;
   3421 		case DNS_R_SERVFAIL:
   3422 			rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
   3423 			st->m.policy = DNS_RPZ_POLICY_ERROR;
   3424 			return (DNS_R_SERVFAIL);
   3425 		default:
   3426 			/*
   3427 			 * Forget this policy if it is not preferable
   3428 			 * to the previously found policy.
   3429 			 * If this policy is not good, then stop looking
   3430 			 * because none of the later policy zones would work.
   3431 			 *
   3432 			 * With more than one applicable policy, prefer
   3433 			 * the earliest configured policy,
   3434 			 * client-IP over QNAME over IP over NSDNAME over NSIP,
   3435 			 * the longest prefix
   3436 			 * the lexically smallest address.
   3437 			 * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num.
   3438 			 * We can compare new and current p_name because
   3439 			 * both are of the same type and in the same zone.
   3440 			 * The tests above eliminate other reasons to
   3441 			 * reject this policy.  If this policy can't work,
   3442 			 * then neither can later zones.
   3443 			 */
   3444 			if (st->m.policy != DNS_RPZ_POLICY_MISS &&
   3445 			    rpz->num == st->m.rpz->num &&
   3446 			     (st->m.type == rpz_type &&
   3447 			      st->m.prefix == prefix &&
   3448 			      0 > dns_name_rdatacompare(st->p_name, p_name)))
   3449 				break;
   3450 
   3451 			/*
   3452 			 * Stop checking after saving an enabled hit in this
   3453 			 * policy zone.  The radix tree in the policy zone
   3454 			 * ensures that we found the longest match.
   3455 			 */
   3456 			if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
   3457 				CTRACE(ISC_LOG_DEBUG(3),
   3458 				       "rpz_rewrite_ip: rpz_save_p");
   3459 				rpz_save_p(st, rpz, rpz_type,
   3460 					   policy, p_name, prefix, result,
   3461 					   &p_zone, &p_db, &p_node,
   3462 					   p_rdatasetp, p_version);
   3463 				break;
   3464 			}
   3465 
   3466 			/*
   3467 			 * Log DNS_RPZ_POLICY_DISABLED zones
   3468 			 * and try the next eligible policy zone.
   3469 			 */
   3470 			rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type,
   3471 					p_zone, p_name, NULL, rpz_num);
   3472 		}
   3473 	}
   3474 
   3475 	rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
   3476 	return (ISC_R_SUCCESS);
   3477 }
   3478 
   3479 /*
   3480  * Check the IP addresses in the A or AAAA rrsets for name against
   3481  * all eligible rpz_type (IP or NSIP) response policy rewrite rules.
   3482  */
   3483 static isc_result_t
   3484 rpz_rewrite_ip_rrset(ns_client_t *client,
   3485 		     dns_name_t *name, dns_rdatatype_t qtype,
   3486 		     dns_rpz_type_t rpz_type, dns_rdatatype_t ip_type,
   3487 		     dns_db_t **ip_dbp, dns_dbversion_t *ip_version,
   3488 		     dns_rdataset_t **ip_rdatasetp,
   3489 		     dns_rdataset_t **p_rdatasetp, isc_boolean_t resuming)
   3490 {
   3491 	dns_rpz_zbits_t zbits;
   3492 	isc_netaddr_t netaddr;
   3493 	struct in_addr ina;
   3494 	struct in6_addr in6a;
   3495 	isc_result_t result;
   3496 
   3497 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrset");
   3498 
   3499 	zbits = rpz_get_zbits(client, ip_type, rpz_type);
   3500 	if (zbits == 0)
   3501 		return (ISC_R_SUCCESS);
   3502 
   3503 	/*
   3504 	 * Get the A or AAAA rdataset.
   3505 	 */
   3506 	result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp,
   3507 				ip_version, ip_rdatasetp, resuming);
   3508 	switch (result) {
   3509 	case ISC_R_SUCCESS:
   3510 	case DNS_R_GLUE:
   3511 	case DNS_R_ZONECUT:
   3512 		break;
   3513 	case DNS_R_EMPTYNAME:
   3514 	case DNS_R_EMPTYWILD:
   3515 	case DNS_R_NXDOMAIN:
   3516 	case DNS_R_NCACHENXDOMAIN:
   3517 	case DNS_R_NXRRSET:
   3518 	case DNS_R_NCACHENXRRSET:
   3519 	case ISC_R_NOTFOUND:
   3520 		return (ISC_R_SUCCESS);
   3521 	case DNS_R_DELEGATION:
   3522 	case DNS_R_DUPLICATE:
   3523 	case DNS_R_DROP:
   3524 		return (result);
   3525 	case DNS_R_CNAME:
   3526 	case DNS_R_DNAME:
   3527 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type,
   3528 			     " NS address rewrite rrset", result);
   3529 		return (ISC_R_SUCCESS);
   3530 	default:
   3531 		if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
   3532 			client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR;
   3533 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
   3534 				     rpz_type, " NS address rewrite rrset",
   3535 				     result);
   3536 		}
   3537 		CTRACE(ISC_LOG_ERROR,
   3538 		       "rpz_rewrite_ip_rrset: unexpected result");
   3539 		return (DNS_R_SERVFAIL);
   3540 	}
   3541 
   3542 	/*
   3543 	 * Check all of the IP addresses in the rdataset.
   3544 	 */
   3545 	for (result = dns_rdataset_first(*ip_rdatasetp);
   3546 	     result == ISC_R_SUCCESS;
   3547 	     result = dns_rdataset_next(*ip_rdatasetp)) {
   3548 
   3549 		dns_rdata_t rdata = DNS_RDATA_INIT;
   3550 		dns_rdataset_current(*ip_rdatasetp, &rdata);
   3551 		switch (rdata.type) {
   3552 		case dns_rdatatype_a:
   3553 			INSIST(rdata.length == 4);
   3554 			memmove(&ina.s_addr, rdata.data, 4);
   3555 			isc_netaddr_fromin(&netaddr, &ina);
   3556 			break;
   3557 		case dns_rdatatype_aaaa:
   3558 			INSIST(rdata.length == 16);
   3559 			memmove(in6a.s6_addr, rdata.data, 16);
   3560 			isc_netaddr_fromin6(&netaddr, &in6a);
   3561 			break;
   3562 		default:
   3563 			continue;
   3564 		}
   3565 
   3566 		result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type,
   3567 					zbits, p_rdatasetp);
   3568 		if (result != ISC_R_SUCCESS)
   3569 			return (result);
   3570 	}
   3571 
   3572 	return (ISC_R_SUCCESS);
   3573 }
   3574 
   3575 /*
   3576  * Look for IP addresses in A and AAAA rdatasets
   3577  * that trigger all eligible IP or NSIP policy rules.
   3578  */
   3579 static isc_result_t
   3580 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name,
   3581 		      dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
   3582 		      dns_rdataset_t **ip_rdatasetp, isc_boolean_t resuming)
   3583 {
   3584 	dns_rpz_st_t *st;
   3585 	dns_dbversion_t *ip_version;
   3586 	dns_db_t *ip_db;
   3587 	dns_rdataset_t *p_rdataset;
   3588 	isc_result_t result;
   3589 
   3590 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrsets");
   3591 
   3592 	st = client->query.rpz_st;
   3593 	ip_version = NULL;
   3594 	ip_db = NULL;
   3595 	p_rdataset = NULL;
   3596 	if ((st->state & DNS_RPZ_DONE_IPv4) == 0 &&
   3597 	    (qtype == dns_rdatatype_a ||
   3598 	     qtype == dns_rdatatype_any ||
   3599 	     rpz_type == DNS_RPZ_TYPE_NSIP)) {
   3600 		/*
   3601 		 * Rewrite based on an IPv4 address that will appear
   3602 		 * in the ANSWER section or if we are checking IP addresses.
   3603 		 */
   3604 		result = rpz_rewrite_ip_rrset(client, name, qtype,
   3605 					      rpz_type, dns_rdatatype_a,
   3606 					      &ip_db, ip_version, ip_rdatasetp,
   3607 					      &p_rdataset, resuming);
   3608 		if (result == ISC_R_SUCCESS)
   3609 			st->state |= DNS_RPZ_DONE_IPv4;
   3610 	} else {
   3611 		result = ISC_R_SUCCESS;
   3612 	}
   3613 	if (result == ISC_R_SUCCESS &&
   3614 	    (qtype == dns_rdatatype_aaaa ||
   3615 	     qtype == dns_rdatatype_any ||
   3616 	     rpz_type == DNS_RPZ_TYPE_NSIP)) {
   3617 		/*
   3618 		 * Rewrite based on IPv6 addresses that will appear
   3619 		 * in the ANSWER section or if we are checking IP addresses.
   3620 		 */
   3621 		result = rpz_rewrite_ip_rrset(client, name,  qtype,
   3622 					      rpz_type, dns_rdatatype_aaaa,
   3623 					      &ip_db, ip_version, ip_rdatasetp,
   3624 					      &p_rdataset, resuming);
   3625 	}
   3626 	if (ip_db != NULL)
   3627 		dns_db_detach(&ip_db);
   3628 	query_putrdataset(client, &p_rdataset);
   3629 	return (result);
   3630 }
   3631 
   3632 /*
   3633  * Try to rewrite a request for a qtype rdataset based on the trigger name
   3634  * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME).
   3635  * Record the results including the replacement rdataset if any
   3636  * in client->query.rpz_st.
   3637  * *rdatasetp is a scratch rdataset.
   3638  */
   3639 static isc_result_t
   3640 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name,
   3641 		 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
   3642 		 dns_rpz_zbits_t allowed_zbits, isc_boolean_t recursed,
   3643 		 dns_rdataset_t **rdatasetp)
   3644 {
   3645 	dns_rpz_zones_t *rpzs;
   3646 	dns_rpz_zone_t *rpz;
   3647 	dns_rpz_st_t *st;
   3648 	dns_fixedname_t p_namef;
   3649 	dns_name_t *p_name;
   3650 	dns_rpz_zbits_t zbits;
   3651 	dns_rpz_num_t rpz_num;
   3652 	dns_zone_t *p_zone;
   3653 	dns_db_t *p_db;
   3654 	dns_dbversion_t *p_version;
   3655 	dns_dbnode_t *p_node;
   3656 	dns_rpz_policy_t policy;
   3657 	isc_result_t result;
   3658 
   3659 #ifndef USE_DNSRPS
   3660 	UNUSED(recursed);
   3661 #endif
   3662 
   3663 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name");
   3664 
   3665 	rpzs = client->view->rpzs;
   3666 	st = client->query.rpz_st;
   3667 
   3668 #ifdef USE_DNSRPS
   3669 	if (st->popt.dnsrps_enabled) {
   3670 		return (dnsrps_rewrite_name(client, trig_name, recursed,
   3671 					     rpz_type, rdatasetp));
   3672 	}
   3673 #endif
   3674 
   3675 	zbits = rpz_get_zbits(client, qtype, rpz_type);
   3676 	zbits &= allowed_zbits;
   3677 	if (zbits == 0)
   3678 		return (ISC_R_SUCCESS);
   3679 
   3680 	/*
   3681 	 * Use the summary database to find the bit mask of policy zones
   3682 	 * with policies for this trigger name. We do this even if there
   3683 	 * is only one eligible policy zone so that wildcard triggers
   3684 	 * are matched correctly, and not into their parent.
   3685 	 */
   3686 	zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name);
   3687 	if (zbits == 0)
   3688 		return (ISC_R_SUCCESS);
   3689 
   3690 	p_name = dns_fixedname_initname(&p_namef);
   3691 
   3692 	p_zone = NULL;
   3693 	p_db = NULL;
   3694 	p_node = NULL;
   3695 
   3696 	/*
   3697 	 * Check the trigger name in every policy zone that the summary data
   3698 	 * says has a hit for the trigger name.
   3699 	 * Most of the time there are no eligible zones and the summary data
   3700 	 * keeps us from getting this far.
   3701 	 * We check the most eligible zone first and so usually check only
   3702 	 * one policy zone.
   3703 	 */
   3704 	for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) {
   3705 		if ((zbits & 1) == 0)
   3706 			continue;
   3707 
   3708 		/*
   3709 		 * Do not check policy zones that cannot replace a previously
   3710 		 * found policy.
   3711 		 */
   3712 		rpz = rpzs->zones[rpz_num];
   3713 		if (st->m.policy != DNS_RPZ_POLICY_MISS) {
   3714 			if (st->m.rpz->num < rpz->num)
   3715 				break;
   3716 			if (st->m.rpz->num == rpz->num &&
   3717 			    st->m.type < rpz_type)
   3718 				break;
   3719 		}
   3720 
   3721 		/*
   3722 		 * Get the next policy zone's record for this trigger name.
   3723 		 */
   3724 		result = rpz_get_p_name(client, p_name, rpz, rpz_type,
   3725 					trig_name);
   3726 		if (result != ISC_R_SUCCESS)
   3727 			continue;
   3728 		result = rpz_find_p(client, trig_name, qtype, p_name,
   3729 				    rpz, rpz_type,
   3730 				    &p_zone, &p_db, &p_version, &p_node,
   3731 				    rdatasetp, &policy);
   3732 		switch (result) {
   3733 		case DNS_R_NXDOMAIN:
   3734 			/*
   3735 			 * Continue after a missing policy record
   3736 			 * contrary to the summary data.  The summary
   3737 			 * data can out of date during races with and among
   3738 			 * policy zone updates.
   3739 			 */
   3740 			CTRACE(ISC_LOG_ERROR,
   3741 			       "rpz_rewrite_name: mismatched summary data; "
   3742 			       "continuing");
   3743 			continue;
   3744 		case DNS_R_SERVFAIL:
   3745 			rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
   3746 			st->m.policy = DNS_RPZ_POLICY_ERROR;
   3747 			return (DNS_R_SERVFAIL);
   3748 		default:
   3749 			/*
   3750 			 * With more than one applicable policy, prefer
   3751 			 * the earliest configured policy,
   3752 			 * client-IP over QNAME over IP over NSDNAME over NSIP,
   3753 			 * and the smallest name.
   3754 			 * We known st->m.rpz->num >= rpz->num  and either
   3755 			 * st->m.rpz->num > rpz->num or st->m.type >= rpz_type
   3756 			 */
   3757 			if (st->m.policy != DNS_RPZ_POLICY_MISS &&
   3758 			    rpz->num == st->m.rpz->num &&
   3759 			    (st->m.type < rpz_type ||
   3760 			     (st->m.type == rpz_type &&
   3761 			      0 >= dns_name_compare(p_name, st->p_name))))
   3762 				continue;
   3763 #if 0
   3764 			/*
   3765 			 * This code would block a customer reported information
   3766 			 * leak of rpz rules by rewriting requests in the
   3767 			 * rpz-ip, rpz-nsip, rpz-nsdname,and rpz-passthru TLDs.
   3768 			 * Without this code, a bad guy could request
   3769 			 * 24.0.3.2.10.rpz-ip. to find the policy rule for
   3770 			 * 10.2.3.0/14.  It is an insignificant leak and this
   3771 			 * code is not worth its cost, because the bad guy
   3772 			 * could publish "evil.com A 10.2.3.4" and request
   3773 			 * evil.com to get the same information.
   3774 			 * Keep code with "#if 0" in case customer demand
   3775 			 * is irresistible.
   3776 			 *
   3777 			 * We have the less frequent case of a triggered
   3778 			 * policy.  Check that we have not trigger on one
   3779 			 * of the pretend RPZ TLDs.
   3780 			 * This test would make it impossible to rewrite
   3781 			 * names in TLDs that start with "rpz-" should
   3782 			 * ICANN ever allow such TLDs.
   3783 			 */
   3784 			unsigned int labels;
   3785 			labels = dns_name_countlabels(trig_name);
   3786 			if (labels >= 2) {
   3787 				dns_label_t label;
   3788 
   3789 				dns_name_getlabel(trig_name, labels-2, &label);
   3790 				if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 &&
   3791 				    strncasecmp((const char *)label.base+1,
   3792 						DNS_RPZ_PREFIX,
   3793 						sizeof(DNS_RPZ_PREFIX)-1) == 0)
   3794 					continue;
   3795 			}
   3796 #endif
   3797 			if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
   3798 				CTRACE(ISC_LOG_DEBUG(3),
   3799 				       "rpz_rewrite_name: rpz_save_p");
   3800 				rpz_save_p(st, rpz, rpz_type,
   3801 					   policy, p_name, 0, result,
   3802 					   &p_zone, &p_db, &p_node,
   3803 					   rdatasetp, p_version);
   3804 				/*
   3805 				 * After a hit, higher numbered policy zones
   3806 				 * are irrelevant
   3807 				 */
   3808 				rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
   3809 				return (ISC_R_SUCCESS);
   3810 			}
   3811 			/*
   3812 			 * Log DNS_RPZ_POLICY_DISABLED zones
   3813 			 * and try the next eligible policy zone.
   3814 			 */
   3815 			rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type,
   3816 					p_zone, p_name, NULL, rpz_num);
   3817 			break;
   3818 		}
   3819 	}
   3820 
   3821 	rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
   3822 	return (ISC_R_SUCCESS);
   3823 }
   3824 
   3825 static void
   3826 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname,
   3827 		    isc_result_t result, int level, const char *str)
   3828 {
   3829 	dns_rpz_st_t *st;
   3830 
   3831 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ns_skip");
   3832 
   3833 	st = client->query.rpz_st;
   3834 
   3835 	if (str != NULL)
   3836 		rpz_log_fail_helper(client, level, nsname,
   3837 				    DNS_RPZ_TYPE_NSIP, DNS_RPZ_TYPE_NSDNAME,
   3838 				    str, result);
   3839 	if (st->r.ns_rdataset != NULL &&
   3840 	    dns_rdataset_isassociated(st->r.ns_rdataset))
   3841 		dns_rdataset_disassociate(st->r.ns_rdataset);
   3842 
   3843 	st->r.label--;
   3844 }
   3845 
   3846 /*
   3847  * RPZ query result types
   3848  */
   3849 typedef enum {
   3850 	qresult_type_done = 0,
   3851 	qresult_type_restart = 1,
   3852 	qresult_type_recurse = 2
   3853 } qresult_type_t;
   3854 
   3855 /*
   3856  * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting.
   3857  */
   3858 static isc_result_t
   3859 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype,
   3860 	    isc_result_t qresult, isc_boolean_t resuming,
   3861 	    dns_rdataset_t *ordataset, dns_rdataset_t *osigset)
   3862 {
   3863 	dns_rpz_zones_t *rpzs;
   3864 	dns_rpz_st_t *st;
   3865 	dns_rdataset_t *rdataset;
   3866 	dns_fixedname_t nsnamef;
   3867 	dns_name_t *nsname;
   3868 	qresult_type_t qresult_type;
   3869 	dns_rpz_zbits_t zbits;
   3870 	isc_result_t result = ISC_R_SUCCESS;
   3871 	dns_rpz_have_t have;
   3872 	dns_rpz_popt_t popt;
   3873 	int rpz_ver;
   3874 #ifdef USE_DNSRPS
   3875 	librpz_emsg_t emsg;
   3876 #endif
   3877 
   3878 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite");
   3879 
   3880 	rpzs = client->view->rpzs;
   3881 	st = client->query.rpz_st;
   3882 
   3883 	if (rpzs == NULL ||
   3884 	    (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0))
   3885 		return (DNS_R_DISALLOWED);
   3886 
   3887 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
   3888 	if ((rpzs->p.num_zones == 0 && !rpzs->p.dnsrps_enabled) ||
   3889 	    (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) ||
   3890 	    !rpz_ck_dnssec(client, qresult, ordataset, osigset))
   3891 	{
   3892 		RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
   3893 		return (DNS_R_DISALLOWED);
   3894 	}
   3895 	have = rpzs->have;
   3896 	popt = rpzs->p;
   3897 	rpz_ver = rpzs->rpz_ver;
   3898 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
   3899 
   3900 #ifndef USE_DNSRPS
   3901 	INSIST(!popt.dnsrps_enabled);
   3902 #endif
   3903 
   3904 	if (st == NULL) {
   3905 		st = isc_mem_get(client->mctx, sizeof(*st));
   3906 		if (st == NULL)
   3907 			return (ISC_R_NOMEMORY);
   3908 		st->state = 0;
   3909 		st->rpsdb = NULL;
   3910 	}
   3911 	if (st->state == 0) {
   3912 		st->state |= DNS_RPZ_ACTIVE;
   3913 		memset(&st->m, 0, sizeof(st->m));
   3914 		st->m.type = DNS_RPZ_TYPE_BAD;
   3915 		st->m.policy = DNS_RPZ_POLICY_MISS;
   3916 		st->m.ttl = ~0;
   3917 		memset(&st->r, 0, sizeof(st->r));
   3918 		memset(&st->q, 0, sizeof(st->q));
   3919 		st->p_name = dns_fixedname_initname(&st->_p_namef);
   3920 		st->r_name = dns_fixedname_initname(&st->_r_namef);
   3921 		st->fname = dns_fixedname_initname(&st->_fnamef);
   3922 		st->have = have;
   3923 		st->popt = popt;
   3924 		st->rpz_ver = rpz_ver;
   3925 		client->query.rpz_st = st;
   3926 #ifdef USE_DNSRPS
   3927 		if (popt.dnsrps_enabled) {
   3928 			if (st->rpsdb != NULL) {
   3929 				dns_db_detach(&st->rpsdb);
   3930 			}
   3931 			result = dns_dnsrps_rewrite_init(&emsg, st, rpzs,
   3932 							  client->query.qname,
   3933 							  client->mctx,
   3934 							  RECURSIONOK(client));
   3935 			if (result != ISC_R_SUCCESS) {
   3936 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
   3937 					     NULL, DNS_RPZ_TYPE_QNAME,
   3938 					     emsg.c, result);
   3939 				st->m.policy = DNS_RPZ_POLICY_ERROR;
   3940 				return (ISC_R_SUCCESS);
   3941 			}
   3942 		}
   3943 #endif
   3944 	}
   3945 
   3946 	/*
   3947 	 * There is nothing to rewrite if the main query failed.
   3948 	 */
   3949 	switch (qresult) {
   3950 	case ISC_R_SUCCESS:
   3951 	case DNS_R_GLUE:
   3952 	case DNS_R_ZONECUT:
   3953 		qresult_type = qresult_type_done;
   3954 		break;
   3955 	case DNS_R_EMPTYNAME:
   3956 	case DNS_R_NXRRSET:
   3957 	case DNS_R_NXDOMAIN:
   3958 	case DNS_R_EMPTYWILD:
   3959 	case DNS_R_NCACHENXDOMAIN:
   3960 	case DNS_R_NCACHENXRRSET:
   3961 	case DNS_R_CNAME:
   3962 	case DNS_R_DNAME:
   3963 		qresult_type = qresult_type_restart;
   3964 		break;
   3965 	case DNS_R_DELEGATION:
   3966 	case ISC_R_NOTFOUND:
   3967 		/*
   3968 		 * If recursion is on, do only tentative rewriting.
   3969 		 * If recursion is off, this the normal and only time we
   3970 		 * can rewrite.
   3971 		 */
   3972 		if (RECURSIONOK(client))
   3973 			qresult_type = qresult_type_recurse;
   3974 		else
   3975 			qresult_type = qresult_type_restart;
   3976 		break;
   3977 	case ISC_R_FAILURE:
   3978 	case ISC_R_TIMEDOUT:
   3979 	case DNS_R_BROKENCHAIN:
   3980 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, NULL,
   3981 			     DNS_RPZ_TYPE_QNAME,
   3982 			     " stop on qresult in rpz_rewrite()", qresult);
   3983 		return (ISC_R_SUCCESS);
   3984 	default:
   3985 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, NULL,
   3986 			     DNS_RPZ_TYPE_QNAME,
   3987 			     " stop on unrecognized qresult in rpz_rewrite()",
   3988 			     qresult);
   3989 		return (ISC_R_SUCCESS);
   3990 	}
   3991 
   3992 	rdataset = NULL;
   3993 
   3994 	if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) !=
   3995 	    (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME))
   3996 	{
   3997 		isc_netaddr_t netaddr;
   3998 		dns_rpz_zbits_t allowed;
   3999 
   4000 		if (!st->popt.dnsrps_enabled &&
   4001 		    qresult_type == qresult_type_recurse)
   4002 		{
   4003 			/*
   4004 			 * This request needs recursion that has not been done.
   4005 			 * Get bits for the policy zones that do not need
   4006 			 * to wait for the results of recursion.
   4007 			 */
   4008 			allowed = st->have.qname_skip_recurse;
   4009 			if (allowed == 0) {
   4010 				return (ISC_R_SUCCESS);
   4011 			}
   4012 		} else {
   4013 			allowed = DNS_RPZ_ALL_ZBITS;
   4014 		}
   4015 
   4016 		/*
   4017 		 * Check once for triggers for the client IP address.
   4018 		 */
   4019 		if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) {
   4020 			zbits = rpz_get_zbits(client, dns_rdatatype_none,
   4021 					      DNS_RPZ_TYPE_CLIENT_IP);
   4022 			zbits &= allowed;
   4023 			if (zbits != 0) {
   4024 				isc_netaddr_fromsockaddr(&netaddr,
   4025 							 &client->peeraddr);
   4026 				result = rpz_rewrite_ip(client, &netaddr, qtype,
   4027 							DNS_RPZ_TYPE_CLIENT_IP,
   4028 							zbits, &rdataset);
   4029 				if (result != ISC_R_SUCCESS)
   4030 					goto cleanup;
   4031 			}
   4032 		}
   4033 
   4034 		/*
   4035 		 * Check triggers for the query name if this is the first time
   4036 		 * for the current qname.
   4037 		 * There is a first time for each name in a CNAME chain
   4038 		 */
   4039 		if ((st->state & DNS_RPZ_DONE_QNAME) == 0) {
   4040 			isc_boolean_t norec =
   4041 				ISC_TF(qresult_type != qresult_type_recurse);
   4042 			result = rpz_rewrite_name(client, client->query.qname,
   4043 						  qtype, DNS_RPZ_TYPE_QNAME,
   4044 						  allowed, norec,
   4045 						  &rdataset);
   4046 			if (result != ISC_R_SUCCESS)
   4047 				goto cleanup;
   4048 
   4049 			/*
   4050 			 * Check IPv4 addresses in A RRs next.
   4051 			 * Reset to the start of the NS names.
   4052 			 */
   4053 			st->r.label = dns_name_countlabels(client->query.qname);
   4054 			st->state &= ~(DNS_RPZ_DONE_QNAME_IP |
   4055 				       DNS_RPZ_DONE_IPv4);
   4056 
   4057 		}
   4058 
   4059 		/*
   4060 		 * Quit if this was an attempt to find a qname or
   4061 		 * client-IP trigger before recursion.
   4062 		 * We will be back if no pre-recursion triggers hit.
   4063 		 * For example, consider 2 policy zones, both with qname and
   4064 		 * IP address triggers.  If the qname misses the 1st zone,
   4065 		 * then we cannot know whether a hit for the qname in the
   4066 		 * 2nd zone matters until after recursing to get the A RRs and
   4067 		 * testing them in the first zone.
   4068 		 * Do not bother saving the work from this attempt,
   4069 		 * because recusion is so slow.
   4070 		 */
   4071 		if (qresult_type == qresult_type_recurse)
   4072 			goto cleanup;
   4073 
   4074 		/*
   4075 		 * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP
   4076 		 * is reset at the end of dealing with each CNAME.
   4077 		 */
   4078 		st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME);
   4079 	}
   4080 
   4081 	/*
   4082 	 * Check known IP addresses for the query name if the database lookup
   4083 	 * resulted in some addresses (qresult_type == qresult_type_done)
   4084 	 * and if we have not already checked them.
   4085 	 * Any recursion required for the query has already happened.
   4086 	 * Do not check addresses that will not be in the ANSWER section.
   4087 	 */
   4088 	if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 &&
   4089 	    qresult_type == qresult_type_done &&
   4090 	    rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) {
   4091 		result = rpz_rewrite_ip_rrsets(client,
   4092 					       client->query.qname, qtype,
   4093 					       DNS_RPZ_TYPE_IP,
   4094 					       &rdataset, resuming);
   4095 		if (result != ISC_R_SUCCESS)
   4096 			goto cleanup;
   4097 		/*
   4098 		 * We are finished checking the IP addresses for the qname.
   4099 		 * Start with IPv4 if we will check NS IP addesses.
   4100 		 */
   4101 		st->state |= DNS_RPZ_DONE_QNAME_IP;
   4102 		st->state &= ~DNS_RPZ_DONE_IPv4;
   4103 	}
   4104 
   4105 	/*
   4106 	 * Stop looking for rules if there are none of the other kinds
   4107 	 * that could override what we already have.
   4108 	 */
   4109 	if (rpz_get_zbits(client, dns_rdatatype_any,
   4110 			  DNS_RPZ_TYPE_NSDNAME) == 0 &&
   4111 	    rpz_get_zbits(client, dns_rdatatype_any,
   4112 			  DNS_RPZ_TYPE_NSIP) == 0) {
   4113 		result = ISC_R_SUCCESS;
   4114 		goto cleanup;
   4115 	}
   4116 
   4117 	dns_fixedname_init(&nsnamef);
   4118 	dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
   4119 	while (st->r.label > st->popt.min_ns_labels) {
   4120 		/*
   4121 		 * Get NS rrset for each domain in the current qname.
   4122 		 */
   4123 		if (st->r.label == dns_name_countlabels(client->query.qname)) {
   4124 			nsname = client->query.qname;
   4125 		} else {
   4126 			nsname = dns_fixedname_name(&nsnamef);
   4127 			dns_name_split(client->query.qname, st->r.label,
   4128 				       NULL, nsname);
   4129 		}
   4130 		if (st->r.ns_rdataset == NULL ||
   4131 		    !dns_rdataset_isassociated(st->r.ns_rdataset))
   4132 		{
   4133 			dns_db_t *db = NULL;
   4134 			result = rpz_rrset_find(client, nsname,
   4135 						dns_rdatatype_ns,
   4136 						DNS_RPZ_TYPE_NSDNAME,
   4137 						&db, NULL, &st->r.ns_rdataset,
   4138 						resuming);
   4139 			if (db != NULL)
   4140 				dns_db_detach(&db);
   4141 			if (st->m.policy == DNS_RPZ_POLICY_ERROR)
   4142 				goto cleanup;
   4143 			switch (result) {
   4144 			case ISC_R_SUCCESS:
   4145 				result = dns_rdataset_first(st->r.ns_rdataset);
   4146 				if (result != ISC_R_SUCCESS)
   4147 					goto cleanup;
   4148 				st->state &= ~(DNS_RPZ_DONE_NSDNAME |
   4149 					       DNS_RPZ_DONE_IPv4);
   4150 				break;
   4151 			case DNS_R_DELEGATION:
   4152 			case DNS_R_DUPLICATE:
   4153 			case DNS_R_DROP:
   4154 				goto cleanup;
   4155 			case DNS_R_EMPTYNAME:
   4156 			case DNS_R_NXRRSET:
   4157 			case DNS_R_EMPTYWILD:
   4158 			case DNS_R_NXDOMAIN:
   4159 			case DNS_R_NCACHENXDOMAIN:
   4160 			case DNS_R_NCACHENXRRSET:
   4161 			case ISC_R_NOTFOUND:
   4162 			case DNS_R_CNAME:
   4163 			case DNS_R_DNAME:
   4164 				rpz_rewrite_ns_skip(client, nsname, result,
   4165 						    0, NULL);
   4166 				continue;
   4167 			case ISC_R_TIMEDOUT:
   4168 			case DNS_R_BROKENCHAIN:
   4169 			case ISC_R_FAILURE:
   4170 				rpz_rewrite_ns_skip(client, nsname, result,
   4171 						DNS_RPZ_DEBUG_LEVEL3,
   4172 						" NS rpz_rrset_find()");
   4173 				continue;
   4174 			default:
   4175 				rpz_rewrite_ns_skip(client, nsname, result,
   4176 						DNS_RPZ_INFO_LEVEL,
   4177 						" unrecognized NS"
   4178 						" rpz_rrset_find()");
   4179 				continue;
   4180 			}
   4181 		}
   4182 		/*
   4183 		 * Check all NS names.
   4184 		 */
   4185 		do {
   4186 			dns_rdata_ns_t ns;
   4187 			dns_rdata_t nsrdata = DNS_RDATA_INIT;
   4188 
   4189 			dns_rdataset_current(st->r.ns_rdataset, &nsrdata);
   4190 			result = dns_rdata_tostruct(&nsrdata, &ns, NULL);
   4191 			dns_rdata_reset(&nsrdata);
   4192 			if (result != ISC_R_SUCCESS) {
   4193 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
   4194 					     nsname, DNS_RPZ_TYPE_NSIP,
   4195 					     " rdata_tostruct()", result);
   4196 				st->m.policy = DNS_RPZ_POLICY_ERROR;
   4197 				goto cleanup;
   4198 			}
   4199 			/*
   4200 			 * Do nothing about "NS ."
   4201 			 */
   4202 			if (dns_name_equal(&ns.name, dns_rootname)) {
   4203 				dns_rdata_freestruct(&ns);
   4204 				result = dns_rdataset_next(st->r.ns_rdataset);
   4205 				continue;
   4206 			}
   4207 			/*
   4208 			 * Check this NS name if we did not handle it
   4209 			 * during a previous recursion.
   4210 			 */
   4211 			if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) {
   4212 				result = rpz_rewrite_name(client, &ns.name,
   4213 							qtype,
   4214 							DNS_RPZ_TYPE_NSDNAME,
   4215 							DNS_RPZ_ALL_ZBITS,
   4216 							ISC_TRUE,
   4217 							&rdataset);
   4218 				if (result != ISC_R_SUCCESS) {
   4219 					dns_rdata_freestruct(&ns);
   4220 					goto cleanup;
   4221 				}
   4222 				st->state |= DNS_RPZ_DONE_NSDNAME;
   4223 			}
   4224 			/*
   4225 			 * Check all IP addresses for this NS name.
   4226 			 */
   4227 			result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype,
   4228 						       DNS_RPZ_TYPE_NSIP,
   4229 						       &rdataset, resuming);
   4230 			dns_rdata_freestruct(&ns);
   4231 			if (result != ISC_R_SUCCESS)
   4232 				goto cleanup;
   4233 			st->state &= ~(DNS_RPZ_DONE_NSDNAME |
   4234 				       DNS_RPZ_DONE_IPv4);
   4235 			result = dns_rdataset_next(st->r.ns_rdataset);
   4236 		} while (result == ISC_R_SUCCESS);
   4237 		dns_rdataset_disassociate(st->r.ns_rdataset);
   4238 		st->r.label--;
   4239 
   4240 		if (rpz_get_zbits(client, dns_rdatatype_any,
   4241 				  DNS_RPZ_TYPE_NSDNAME) == 0 &&
   4242 		    rpz_get_zbits(client, dns_rdatatype_any,
   4243 				  DNS_RPZ_TYPE_NSIP) == 0)
   4244 			break;
   4245 	}
   4246 
   4247 	/*
   4248 	 * Use the best hit, if any.
   4249 	 */
   4250 	result = ISC_R_SUCCESS;
   4251 
   4252 cleanup:
   4253 #ifdef USE_DNSRPS
   4254 	if (st->popt.dnsrps_enabled &&
   4255 	    st->m.policy != DNS_RPZ_POLICY_ERROR &&
   4256 	    !dnsrps_set_p(&emsg, client, st, qtype, &rdataset,
   4257 			  ISC_TF(qresult_type != qresult_type_recurse)))
   4258 	{
   4259 		rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
   4260 			     DNS_RPZ_TYPE_BAD, emsg.c, DNS_R_SERVFAIL);
   4261 		st->m.policy = DNS_RPZ_POLICY_ERROR;
   4262 	}
   4263 #endif
   4264 	if (st->m.policy != DNS_RPZ_POLICY_MISS &&
   4265 	    st->m.policy != DNS_RPZ_POLICY_ERROR &&
   4266 	    st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN)
   4267 		st->m.policy = st->m.rpz->policy;
   4268 	if (st->m.policy == DNS_RPZ_POLICY_MISS ||
   4269 	    st->m.policy == DNS_RPZ_POLICY_PASSTHRU ||
   4270 	    st->m.policy == DNS_RPZ_POLICY_ERROR) {
   4271 		if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU &&
   4272 		    result != DNS_R_DELEGATION)
   4273 			rpz_log_rewrite(client, ISC_FALSE, st->m.policy,
   4274 					st->m.type, st->m.zone, st->p_name,
   4275 					NULL, st->m.rpz->num);
   4276 		rpz_match_clear(st);
   4277 	}
   4278 	if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
   4279 		CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy");
   4280 		st->m.type = DNS_RPZ_TYPE_BAD;
   4281 		result = DNS_R_SERVFAIL;
   4282 	}
   4283 	query_putrdataset(client, &rdataset);
   4284 	if ((st->state & DNS_RPZ_RECURSING) == 0)
   4285 		rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset);
   4286 
   4287 	return (result);
   4288 }
   4289 
   4290 /*
   4291  * See if response policy zone rewriting is allowed by a lack of interest
   4292  * by the client in DNSSEC or a lack of signatures.
   4293  */
   4294 static isc_boolean_t
   4295 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
   4296 	      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
   4297 {
   4298 	dns_fixedname_t fixed;
   4299 	dns_name_t *found;
   4300 	dns_rdataset_t trdataset;
   4301 	dns_rdatatype_t type;
   4302 	isc_result_t result;
   4303 
   4304 	CTRACE(ISC_LOG_DEBUG(3), "rpz_ck_dnssec");
   4305 
   4306 	if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client))
   4307 		return (ISC_TRUE);
   4308 
   4309 	/*
   4310 	 * We do not know if there are signatures if we have not recursed
   4311 	 * for them.
   4312 	 */
   4313 	if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND)
   4314 		return (ISC_FALSE);
   4315 
   4316 	if (sigrdataset == NULL)
   4317 		return (ISC_TRUE);
   4318 	if (dns_rdataset_isassociated(sigrdataset))
   4319 		return (ISC_FALSE);
   4320 
   4321 	/*
   4322 	 * We are happy to rewrite nothing.
   4323 	 */
   4324 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset))
   4325 		return (ISC_TRUE);
   4326 	/*
   4327 	 * Do not rewrite if there is any sign of signatures.
   4328 	 */
   4329 	if (rdataset->type == dns_rdatatype_nsec ||
   4330 	    rdataset->type == dns_rdatatype_nsec3 ||
   4331 	    rdataset->type == dns_rdatatype_rrsig)
   4332 		return (ISC_FALSE);
   4333 
   4334 	/*
   4335 	 * Look for a signature in a negative cache rdataset.
   4336 	 */
   4337 	if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0)
   4338 		return (ISC_TRUE);
   4339 	found = dns_fixedname_initname(&fixed);
   4340 	dns_rdataset_init(&trdataset);
   4341 	for (result = dns_rdataset_first(rdataset);
   4342 	     result == ISC_R_SUCCESS;
   4343 	     result = dns_rdataset_next(rdataset)) {
   4344 		dns_ncache_current(rdataset, found, &trdataset);
   4345 		type = trdataset.type;
   4346 		dns_rdataset_disassociate(&trdataset);
   4347 		if (type == dns_rdatatype_nsec ||
   4348 		    type == dns_rdatatype_nsec3 ||
   4349 		    type == dns_rdatatype_rrsig)
   4350 			return (ISC_FALSE);
   4351 	}
   4352 	return (ISC_TRUE);
   4353 }
   4354 
   4355 /*
   4356  * Extract a network address from the RDATA of an A or AAAA
   4357  * record.
   4358  *
   4359  * Returns:
   4360  *	ISC_R_SUCCESS
   4361  *	ISC_R_NOTIMPLEMENTED	The rdata is not a known address type.
   4362  */
   4363 static isc_result_t
   4364 rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) {
   4365 	struct in_addr ina;
   4366 	struct in6_addr in6a;
   4367 
   4368 	switch (rdata->type) {
   4369 	case dns_rdatatype_a:
   4370 		INSIST(rdata->length == 4);
   4371 		memmove(&ina.s_addr, rdata->data, 4);
   4372 		isc_netaddr_fromin(netaddr, &ina);
   4373 		return (ISC_R_SUCCESS);
   4374 	case dns_rdatatype_aaaa:
   4375 		INSIST(rdata->length == 16);
   4376 		memmove(in6a.s6_addr, rdata->data, 16);
   4377 		isc_netaddr_fromin6(netaddr, &in6a);
   4378 		return (ISC_R_SUCCESS);
   4379 	default:
   4380 		return (ISC_R_NOTIMPLEMENTED);
   4381 	}
   4382 }
   4383 
   4384 static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
   4385 static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
   4386 static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
   4387 
   4388 static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
   4389 
   4390 static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
   4391 static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
   4392 static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
   4393 static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
   4394 static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
   4395 static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
   4396 static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
   4397 static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
   4398 static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
   4399 static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
   4400 static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
   4401 static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
   4402 static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
   4403 static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
   4404 static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
   4405 static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
   4406 
   4407 static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
   4408 
   4409 static dns_name_t rfc1918names[] = {
   4410 	DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets),
   4411 	DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets),
   4412 	DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets),
   4413 	DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets),
   4414 	DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets),
   4415 	DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets),
   4416 	DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets),
   4417 	DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets),
   4418 	DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets),
   4419 	DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets),
   4420 	DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets),
   4421 	DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets),
   4422 	DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets),
   4423 	DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets),
   4424 	DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets),
   4425 	DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets),
   4426 	DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets),
   4427 	DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets)
   4428 };
   4429 
   4430 
   4431 static unsigned char prisoner_data[] = "\010prisoner\004iana\003org";
   4432 static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org";
   4433 
   4434 static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 };
   4435 static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 };
   4436 
   4437 static dns_name_t const prisoner =
   4438 	DNS_NAME_INITABSOLUTE(prisoner_data, prisoner_offsets);
   4439 static dns_name_t const hostmaster =
   4440 	DNS_NAME_INITABSOLUTE(hostmaster_data, hostmaster_offsets);
   4441 
   4442 static void
   4443 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) {
   4444 	unsigned int i;
   4445 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4446 	dns_rdata_soa_t soa;
   4447 	dns_rdataset_t found;
   4448 	isc_result_t result;
   4449 
   4450 	for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) {
   4451 		if (dns_name_issubdomain(fname, &rfc1918names[i])) {
   4452 			dns_rdataset_init(&found);
   4453 			result = dns_ncache_getrdataset(rdataset,
   4454 							&rfc1918names[i],
   4455 							dns_rdatatype_soa,
   4456 							&found);
   4457 			if (result != ISC_R_SUCCESS)
   4458 				return;
   4459 
   4460 			result = dns_rdataset_first(&found);
   4461 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4462 			dns_rdataset_current(&found, &rdata);
   4463 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   4464 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4465 			if (dns_name_equal(&soa.origin, &prisoner) &&
   4466 			    dns_name_equal(&soa.contact, &hostmaster)) {
   4467 				char buf[DNS_NAME_FORMATSIZE];
   4468 				dns_name_format(fname, buf, sizeof(buf));
   4469 				ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
   4470 					      NS_LOGMODULE_QUERY,
   4471 					      ISC_LOG_WARNING,
   4472 					      "RFC 1918 response from "
   4473 					      "Internet for %s", buf);
   4474 			}
   4475 			dns_rdataset_disassociate(&found);
   4476 			return;
   4477 		}
   4478 	}
   4479 }
   4480 
   4481 static void
   4482 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
   4483 		       dns_dbversion_t *version, ns_client_t *client,
   4484 		       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
   4485 		       dns_name_t *fname, isc_boolean_t exact,
   4486 		       dns_name_t *found)
   4487 {
   4488 	unsigned char salt[256];
   4489 	size_t salt_length;
   4490 	isc_uint16_t iterations;
   4491 	isc_result_t result;
   4492 	unsigned int dboptions;
   4493 	dns_fixedname_t fixed;
   4494 	dns_hash_t hash;
   4495 	dns_name_t name;
   4496 	unsigned int skip = 0, labels;
   4497 	dns_rdata_nsec3_t nsec3;
   4498 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4499 	isc_boolean_t optout;
   4500 	dns_clientinfomethods_t cm;
   4501 	dns_clientinfo_t ci;
   4502 
   4503 	salt_length = sizeof(salt);
   4504 	result = dns_db_getnsec3parameters(db, version, &hash, NULL,
   4505 					   &iterations, salt, &salt_length);
   4506 	if (result != ISC_R_SUCCESS)
   4507 		return;
   4508 
   4509 	dns_name_init(&name, NULL);
   4510 	dns_name_clone(qname, &name);
   4511 	labels = dns_name_countlabels(&name);
   4512 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   4513 	dns_clientinfo_init(&ci, client, NULL);
   4514 
   4515 	/*
   4516 	 * Map unknown algorithm to known value.
   4517 	 */
   4518 	if (hash == DNS_NSEC3_UNKNOWNALG)
   4519 		hash = 1;
   4520 
   4521  again:
   4522 	dns_fixedname_init(&fixed);
   4523 	result = dns_nsec3_hashname(&fixed, NULL, NULL, &name,
   4524 				    dns_db_origin(db), hash,
   4525 				    iterations, salt, salt_length);
   4526 	if (result != ISC_R_SUCCESS)
   4527 		return;
   4528 
   4529 	dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3;
   4530 	result = dns_db_findext(db, dns_fixedname_name(&fixed), version,
   4531 				dns_rdatatype_nsec3, dboptions, client->now,
   4532 				NULL, fname, &cm, &ci, rdataset, sigrdataset);
   4533 
   4534 	if (result == DNS_R_NXDOMAIN) {
   4535 		if (!dns_rdataset_isassociated(rdataset)) {
   4536 			return;
   4537 		}
   4538 		result = dns_rdataset_first(rdataset);
   4539 		INSIST(result == ISC_R_SUCCESS);
   4540 		dns_rdataset_current(rdataset, &rdata);
   4541 		dns_rdata_tostruct(&rdata, &nsec3, NULL);
   4542 		dns_rdata_reset(&rdata);
   4543 		optout = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0);
   4544 		if (found != NULL && optout &&
   4545 		    dns_name_issubdomain(&name, dns_db_origin(db)))
   4546 		{
   4547 			dns_rdataset_disassociate(rdataset);
   4548 			if (dns_rdataset_isassociated(sigrdataset))
   4549 				dns_rdataset_disassociate(sigrdataset);
   4550 			skip++;
   4551 			dns_name_getlabelsequence(qname, skip, labels - skip,
   4552 						  &name);
   4553 			ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
   4554 				      NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3),
   4555 				      "looking for closest provable encloser");
   4556 			goto again;
   4557 		}
   4558 		if (exact)
   4559 			ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
   4560 				      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
   4561 				      "expected a exact match NSEC3, got "
   4562 				      "a covering record");
   4563 
   4564 	} else if (result != ISC_R_SUCCESS) {
   4565 		return;
   4566 	} else if (!exact)
   4567 		ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
   4568 			      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
   4569 			      "expected covering NSEC3, got an exact match");
   4570 	if (found == qname) {
   4571 		if (skip != 0U)
   4572 			dns_name_getlabelsequence(qname, skip, labels - skip,
   4573 						  found);
   4574 	} else if (found != NULL)
   4575 		dns_name_copy(&name, found, NULL);
   4576 	return;
   4577 }
   4578 
   4579 static isc_boolean_t
   4580 is_v4_client(ns_client_t *client) {
   4581 	if (isc_sockaddr_pf(&client->peeraddr) == AF_INET)
   4582 		return (ISC_TRUE);
   4583 	if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
   4584 	    IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
   4585 		return (ISC_TRUE);
   4586 	return (ISC_FALSE);
   4587 }
   4588 
   4589 static isc_boolean_t
   4590 is_v6_client(ns_client_t *client) {
   4591 	if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
   4592 	    !IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
   4593 		return (ISC_TRUE);
   4594 	return (ISC_FALSE);
   4595 }
   4596 
   4597 static isc_uint32_t
   4598 dns64_ttl(dns_db_t *db, dns_dbversion_t *version) {
   4599 	dns_dbnode_t *node = NULL;
   4600 	dns_rdata_soa_t soa;
   4601 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4602 	dns_rdataset_t rdataset;
   4603 	isc_result_t result;
   4604 	isc_uint32_t ttl = ISC_UINT32_MAX;
   4605 
   4606 	dns_rdataset_init(&rdataset);
   4607 
   4608 	result = dns_db_getoriginnode(db, &node);
   4609 	if (result != ISC_R_SUCCESS)
   4610 		goto cleanup;
   4611 
   4612 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
   4613 				     0, 0, &rdataset, NULL);
   4614 	if (result != ISC_R_SUCCESS)
   4615 		goto cleanup;
   4616 	result = dns_rdataset_first(&rdataset);
   4617 	if (result != ISC_R_SUCCESS)
   4618 		goto cleanup;
   4619 
   4620 	dns_rdataset_current(&rdataset, &rdata);
   4621 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   4622 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4623 	ttl = ISC_MIN(rdataset.ttl, soa.minimum);
   4624 
   4625 cleanup:
   4626 	if (dns_rdataset_isassociated(&rdataset))
   4627 		dns_rdataset_disassociate(&rdataset);
   4628 	if (node != NULL)
   4629 		dns_db_detachnode(db, &node);
   4630 	return (ttl);
   4631 }
   4632 
   4633 static isc_boolean_t
   4634 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
   4635 	     dns_rdataset_t *sigrdataset)
   4636 {
   4637 	isc_netaddr_t netaddr;
   4638 	dns_aclenv_t *env = ns_interfacemgr_getaclenv(client->interface->mgr);
   4639 	dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
   4640 	unsigned int flags = 0;
   4641 	unsigned int i, count;
   4642 	isc_boolean_t *aaaaok;
   4643 
   4644 	INSIST(client->query.dns64_aaaaok == NULL);
   4645 	INSIST(client->query.dns64_aaaaoklen == 0);
   4646 	INSIST(client->query.dns64_aaaa == NULL);
   4647 	INSIST(client->query.dns64_sigaaaa == NULL);
   4648 
   4649 	if (dns64 == NULL)
   4650 		return (ISC_TRUE);
   4651 
   4652 	if (RECURSIONOK(client))
   4653 		flags |= DNS_DNS64_RECURSIVE;
   4654 
   4655 	if (WANTDNSSEC(client) && sigrdataset != NULL &&
   4656 	    dns_rdataset_isassociated(sigrdataset))
   4657 		flags |= DNS_DNS64_DNSSEC;
   4658 
   4659 	count = dns_rdataset_count(rdataset);
   4660 	aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count);
   4661 
   4662 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
   4663 	if (dns_dns64_aaaaok(dns64, &netaddr, client->signer,
   4664 			     env, flags, rdataset, aaaaok, count))
   4665 	{
   4666 		for (i = 0; i < count; i++) {
   4667 			if (aaaaok != NULL && !aaaaok[i]) {
   4668 				SAVE(client->query.dns64_aaaaok, aaaaok);
   4669 				client->query.dns64_aaaaoklen = count;
   4670 				break;
   4671 			}
   4672 		}
   4673 		if (aaaaok != NULL)
   4674 			isc_mem_put(client->mctx, aaaaok,
   4675 				    sizeof(isc_boolean_t) * count);
   4676 		return (ISC_TRUE);
   4677 	}
   4678 	if (aaaaok != NULL)
   4679 		isc_mem_put(client->mctx, aaaaok,
   4680 			    sizeof(isc_boolean_t) * count);
   4681 	return (ISC_FALSE);
   4682 }
   4683 
   4684 /*
   4685  * Look for the name and type in the redirection zone.  If found update
   4686  * the arguments as appropriate.  Return ISC_TRUE if a update was
   4687  * performed.
   4688  *
   4689  * Only perform the update if the client is in the allow query acl and
   4690  * returning the update would not cause a DNSSEC validation failure.
   4691  */
   4692 static isc_result_t
   4693 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
   4694 	 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
   4695 	 dns_rdatatype_t qtype)
   4696 {
   4697 	dns_db_t *db = NULL;
   4698 	dns_dbnode_t *node = NULL;
   4699 	dns_fixedname_t fixed;
   4700 	dns_name_t *found;
   4701 	dns_rdataset_t trdataset;
   4702 	isc_result_t result;
   4703 	dns_rdatatype_t type;
   4704 	dns_clientinfomethods_t cm;
   4705 	dns_clientinfo_t ci;
   4706 	ns_dbversion_t *dbversion;
   4707 
   4708 	CTRACE(ISC_LOG_DEBUG(3), "redirect");
   4709 
   4710 	if (client->view->redirect == NULL)
   4711 		return (ISC_R_NOTFOUND);
   4712 
   4713 	found = dns_fixedname_initname(&fixed);
   4714 	dns_rdataset_init(&trdataset);
   4715 
   4716 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   4717 	dns_clientinfo_init(&ci, client, NULL);
   4718 
   4719 	if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
   4720 		return (ISC_R_NOTFOUND);
   4721 
   4722 	if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
   4723 		if (rdataset->trust == dns_trust_secure)
   4724 			return (ISC_R_NOTFOUND);
   4725 		if (rdataset->trust == dns_trust_ultimate &&
   4726 		    (rdataset->type == dns_rdatatype_nsec ||
   4727 		     rdataset->type == dns_rdatatype_nsec3))
   4728 			return (ISC_R_NOTFOUND);
   4729 		if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
   4730 			for (result = dns_rdataset_first(rdataset);
   4731 			     result == ISC_R_SUCCESS;
   4732 			     result = dns_rdataset_next(rdataset)) {
   4733 				dns_ncache_current(rdataset, found, &trdataset);
   4734 				type = trdataset.type;
   4735 				dns_rdataset_disassociate(&trdataset);
   4736 				if (type == dns_rdatatype_nsec ||
   4737 				    type == dns_rdatatype_nsec3 ||
   4738 				    type == dns_rdatatype_rrsig)
   4739 					return (ISC_R_NOTFOUND);
   4740 			}
   4741 		}
   4742 	}
   4743 
   4744 	result = ns_client_checkaclsilent(client, NULL,
   4745 				 dns_zone_getqueryacl(client->view->redirect),
   4746 					  ISC_TRUE);
   4747 	if (result != ISC_R_SUCCESS)
   4748 		return (ISC_R_NOTFOUND);
   4749 
   4750 	result = dns_zone_getdb(client->view->redirect, &db);
   4751 	if (result != ISC_R_SUCCESS)
   4752 		return (ISC_R_NOTFOUND);
   4753 
   4754 	dbversion = query_findversion(client, db);
   4755 	if (dbversion == NULL) {
   4756 		dns_db_detach(&db);
   4757 		return (ISC_R_NOTFOUND);
   4758 	}
   4759 
   4760 	/*
   4761 	 * Lookup the requested data in the redirect zone.
   4762 	 */
   4763 	result = dns_db_findext(db, client->query.qname, dbversion->version,
   4764 				qtype, DNS_DBFIND_NOZONECUT, client->now,
   4765 				&node, found, &cm, &ci, &trdataset, NULL);
   4766 	if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
   4767 		if (dns_rdataset_isassociated(rdataset))
   4768 			dns_rdataset_disassociate(rdataset);
   4769 		if (dns_rdataset_isassociated(&trdataset))
   4770 			dns_rdataset_disassociate(&trdataset);
   4771 		goto nxrrset;
   4772 	} else if (result != ISC_R_SUCCESS) {
   4773 		if (dns_rdataset_isassociated(&trdataset))
   4774 			dns_rdataset_disassociate(&trdataset);
   4775 		if (node != NULL)
   4776 			dns_db_detachnode(db, &node);
   4777 		dns_db_detach(&db);
   4778 		return (ISC_R_NOTFOUND);
   4779 	}
   4780 
   4781 	CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done");
   4782 	dns_name_copy(found, name, NULL);
   4783 	if (dns_rdataset_isassociated(rdataset))
   4784 		dns_rdataset_disassociate(rdataset);
   4785 	if (dns_rdataset_isassociated(&trdataset)) {
   4786 		dns_rdataset_clone(&trdataset, rdataset);
   4787 		dns_rdataset_disassociate(&trdataset);
   4788 	}
   4789  nxrrset:
   4790 	if (*nodep != NULL)
   4791 		dns_db_detachnode(*dbp, nodep);
   4792 	dns_db_detach(dbp);
   4793 	dns_db_attachnode(db, node, nodep);
   4794 	dns_db_attach(db, dbp);
   4795 	dns_db_detachnode(db, &node);
   4796 	dns_db_detach(&db);
   4797 	*versionp = dbversion->version;
   4798 
   4799 	client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
   4800 				     NS_QUERYATTR_NOADDITIONAL);
   4801 
   4802 	return (result);
   4803 }
   4804 
   4805 static isc_result_t
   4806 redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
   4807 	  dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
   4808 	  dns_rdatatype_t qtype, isc_boolean_t *is_zonep)
   4809 {
   4810 	dns_db_t *db = NULL;
   4811 	dns_dbnode_t *node = NULL;
   4812 	dns_fixedname_t fixed;
   4813 	dns_fixedname_t fixedredirect;
   4814 	dns_name_t *found, *redirectname;
   4815 	dns_rdataset_t trdataset;
   4816 	isc_result_t result;
   4817 	dns_rdatatype_t type;
   4818 	dns_clientinfomethods_t cm;
   4819 	dns_clientinfo_t ci;
   4820 	dns_dbversion_t *version = NULL;
   4821 	dns_zone_t *zone = NULL;
   4822 	isc_boolean_t is_zone;
   4823 	unsigned int options;
   4824 
   4825 	CTRACE(ISC_LOG_DEBUG(3), "redirect2");
   4826 
   4827 	if (client->view->redirectzone == NULL)
   4828 		return (ISC_R_NOTFOUND);
   4829 
   4830 	if (dns_name_issubdomain(name, client->view->redirectzone))
   4831 		return (ISC_R_NOTFOUND);
   4832 
   4833 	found = dns_fixedname_initname(&fixed);
   4834 	dns_rdataset_init(&trdataset);
   4835 
   4836 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   4837 	dns_clientinfo_init(&ci, client, NULL);
   4838 
   4839 	if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
   4840 		return (ISC_R_NOTFOUND);
   4841 
   4842 	if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
   4843 		if (rdataset->trust == dns_trust_secure)
   4844 			return (ISC_R_NOTFOUND);
   4845 		if (rdataset->trust == dns_trust_ultimate &&
   4846 		    (rdataset->type == dns_rdatatype_nsec ||
   4847 		     rdataset->type == dns_rdatatype_nsec3))
   4848 			return (ISC_R_NOTFOUND);
   4849 		if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
   4850 			for (result = dns_rdataset_first(rdataset);
   4851 			     result == ISC_R_SUCCESS;
   4852 			     result = dns_rdataset_next(rdataset)) {
   4853 				dns_ncache_current(rdataset, found, &trdataset);
   4854 				type = trdataset.type;
   4855 				dns_rdataset_disassociate(&trdataset);
   4856 				if (type == dns_rdatatype_nsec ||
   4857 				    type == dns_rdatatype_nsec3 ||
   4858 				    type == dns_rdatatype_rrsig)
   4859 					return (ISC_R_NOTFOUND);
   4860 			}
   4861 		}
   4862 	}
   4863 
   4864 	redirectname = dns_fixedname_initname(&fixedredirect);
   4865 	if (dns_name_countlabels(name) > 1U) {
   4866 		dns_name_t prefix;
   4867 		unsigned int labels = dns_name_countlabels(name) - 1;
   4868 
   4869 		dns_name_init(&prefix, NULL);
   4870 		dns_name_getlabelsequence(name, 0, labels, &prefix);
   4871 		result = dns_name_concatenate(&prefix,
   4872 					      client->view->redirectzone,
   4873 					      redirectname, NULL);
   4874 		if (result != ISC_R_SUCCESS)
   4875 			return (ISC_R_NOTFOUND);
   4876 	} else
   4877 		dns_name_copy(redirectname, client->view->redirectzone, NULL);
   4878 
   4879 	options = 0;
   4880 	result = query_getdb(client, redirectname, qtype, options, &zone,
   4881 			     &db, &version, &is_zone);
   4882 	if (result != ISC_R_SUCCESS)
   4883 		return (ISC_R_NOTFOUND);
   4884 	if (zone != NULL)
   4885 		dns_zone_detach(&zone);
   4886 
   4887 	/*
   4888 	 * Lookup the requested data in the redirect zone.
   4889 	 */
   4890 	result = dns_db_findext(db, redirectname, version,
   4891 				qtype, 0, client->now,
   4892 				&node, found, &cm, &ci, &trdataset, NULL);
   4893 	if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
   4894 		if (dns_rdataset_isassociated(rdataset))
   4895 			dns_rdataset_disassociate(rdataset);
   4896 		if (dns_rdataset_isassociated(&trdataset))
   4897 			dns_rdataset_disassociate(&trdataset);
   4898 		goto nxrrset;
   4899 	} else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) {
   4900 		/*
   4901 		 * Cleanup.
   4902 		 */
   4903 		if (dns_rdataset_isassociated(&trdataset))
   4904 			dns_rdataset_disassociate(&trdataset);
   4905 		if (node != NULL)
   4906 			dns_db_detachnode(db, &node);
   4907 		dns_db_detach(&db);
   4908 		/*
   4909 		 * Don't loop forever if the lookup failed last time.
   4910 		 */
   4911 		if (!REDIRECT(client)) {
   4912 			result = query_recurse(client, qtype, redirectname,
   4913 					       NULL, NULL, ISC_TRUE);
   4914 			if (result == ISC_R_SUCCESS) {
   4915 				client->query.attributes |=
   4916 						NS_QUERYATTR_RECURSING;
   4917 				client->query.attributes |=
   4918 						NS_QUERYATTR_REDIRECT;
   4919 				return (DNS_R_CONTINUE);
   4920 			}
   4921 		}
   4922 		return (ISC_R_NOTFOUND);
   4923 	} else if (result != ISC_R_SUCCESS) {
   4924 		if (dns_rdataset_isassociated(&trdataset))
   4925 			dns_rdataset_disassociate(&trdataset);
   4926 		if (node != NULL)
   4927 			dns_db_detachnode(db, &node);
   4928 		dns_db_detach(&db);
   4929 		return (ISC_R_NOTFOUND);
   4930 	}
   4931 
   4932 	CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done");
   4933 	/*
   4934 	 * Adjust the found name to not include the redirectzone suffix.
   4935 	 */
   4936 	dns_name_split(found, dns_name_countlabels(client->view->redirectzone),
   4937 		       found, NULL);
   4938 	/*
   4939 	 * Make the name absolute.
   4940 	 */
   4941 	result = dns_name_concatenate(found, dns_rootname, found, NULL);
   4942 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4943 
   4944 	dns_name_copy(found, name, NULL);
   4945 	if (dns_rdataset_isassociated(rdataset))
   4946 		dns_rdataset_disassociate(rdataset);
   4947 	if (dns_rdataset_isassociated(&trdataset)) {
   4948 		dns_rdataset_clone(&trdataset, rdataset);
   4949 		dns_rdataset_disassociate(&trdataset);
   4950 	}
   4951  nxrrset:
   4952 	if (*nodep != NULL)
   4953 		dns_db_detachnode(*dbp, nodep);
   4954 	dns_db_detach(dbp);
   4955 	dns_db_attachnode(db, node, nodep);
   4956 	dns_db_attach(db, dbp);
   4957 	dns_db_detachnode(db, &node);
   4958 	dns_db_detach(&db);
   4959 	*is_zonep = is_zone;
   4960 	*versionp = version;
   4961 
   4962 	client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
   4963 				     NS_QUERYATTR_NOADDITIONAL);
   4964 
   4965 	return (result);
   4966 }
   4967 
   4968 /*%
   4969  * Initialize query context 'qctx'. Run by query_setup() when
   4970  * first handling a client query, and by query_resume() when
   4971  * returning from recursion.
   4972  */
   4973 static void
   4974 qctx_init(ns_client_t *client, dns_fetchevent_t *event,
   4975 	  dns_rdatatype_t qtype, query_ctx_t *qctx)
   4976 {
   4977 	REQUIRE(qctx != NULL);
   4978 	REQUIRE(client != NULL);
   4979 
   4980 	/* Set this first so CCTRACE will work */
   4981 	qctx->client = client;
   4982 
   4983 	CCTRACE(ISC_LOG_DEBUG(3), "qctx_create");
   4984 
   4985 	qctx->event = event;
   4986 	qctx->qtype = qctx->type = qtype;
   4987 	qctx->result = ISC_R_SUCCESS;
   4988 	qctx->fname = NULL;
   4989 	qctx->zfname = NULL;
   4990 	qctx->rdataset = NULL;
   4991 	qctx->zrdataset = NULL;
   4992 	qctx->sigrdataset = NULL;
   4993 	qctx->zsigrdataset = NULL;
   4994 	qctx->zversion = NULL;
   4995 	qctx->node = NULL;
   4996 	qctx->db = NULL;
   4997 	qctx->zdb = NULL;
   4998 	qctx->version = NULL;
   4999 	qctx->zone = NULL;
   5000 	qctx->need_wildcardproof = ISC_FALSE;
   5001 	qctx->redirected = ISC_FALSE;
   5002 	qctx->dns64_exclude = qctx->dns64 = qctx->rpz = ISC_FALSE;
   5003 	qctx->options = 0;
   5004 	qctx->resuming = ISC_FALSE;
   5005 	qctx->is_zone = ISC_FALSE;
   5006 	qctx->findcoveringnsec = client->view->synthfromdnssec;
   5007 	qctx->is_staticstub_zone = ISC_FALSE;
   5008 	qctx->nxrewrite = ISC_FALSE;
   5009 	qctx->want_stale = ISC_FALSE;
   5010 	qctx->answer_has_ns = ISC_FALSE;
   5011 	qctx->authoritative = ISC_FALSE;
   5012 }
   5013 
   5014 /*%
   5015  * Clean up and disassociate the rdataset and node pointers in qctx.
   5016  */
   5017 static void
   5018 qctx_clean(query_ctx_t *qctx) {
   5019 	if (qctx->rdataset != NULL &&
   5020 	    dns_rdataset_isassociated(qctx->rdataset))
   5021 	{
   5022 		dns_rdataset_disassociate(qctx->rdataset);
   5023 	}
   5024 	if (qctx->sigrdataset != NULL &&
   5025 	    dns_rdataset_isassociated(qctx->sigrdataset))
   5026 	{
   5027 		dns_rdataset_disassociate(qctx->sigrdataset);
   5028 	}
   5029 	if (qctx->db != NULL && qctx->node != NULL) {
   5030 		dns_db_detachnode(qctx->db, &qctx->node);
   5031 	}
   5032 }
   5033 
   5034 /*%
   5035  * Free any allocated memory associated with qctx.
   5036  */
   5037 static void
   5038 qctx_freedata(query_ctx_t *qctx) {
   5039 	if (qctx->rdataset != NULL) {
   5040 		query_putrdataset(qctx->client, &qctx->rdataset);
   5041 	}
   5042 
   5043 	if (qctx->sigrdataset != NULL) {
   5044 		query_putrdataset(qctx->client, &qctx->sigrdataset);
   5045 	}
   5046 
   5047 	if (qctx->fname != NULL) {
   5048 		query_releasename(qctx->client, &qctx->fname);
   5049 	}
   5050 
   5051 	if (qctx->db != NULL) {
   5052 		INSIST(qctx->node == NULL);
   5053 		dns_db_detach(&qctx->db);
   5054 	}
   5055 
   5056 	if (qctx->zone != NULL) {
   5057 		dns_zone_detach(&qctx->zone);
   5058 	}
   5059 
   5060 	if (qctx->zdb != NULL) {
   5061 		query_putrdataset(qctx->client, &qctx->zrdataset);
   5062 		if (qctx->zsigrdataset != NULL)
   5063 			query_putrdataset(qctx->client, &qctx->zsigrdataset);
   5064 		if (qctx->zfname != NULL)
   5065 			query_releasename(qctx->client, &qctx->zfname);
   5066 		dns_db_detach(&qctx->zdb);
   5067 	}
   5068 
   5069 	if (qctx->event != NULL) {
   5070 		free_devent(qctx->client,
   5071 			    ISC_EVENT_PTR(&qctx->event), &qctx->event);
   5072 	}
   5073 }
   5074 
   5075 /*%
   5076  * Log detailed information about the query immediately after
   5077  * the client request or a return from recursion.
   5078  */
   5079 static void
   5080 query_trace(query_ctx_t *qctx) {
   5081 #ifdef WANT_QUERYTRACE
   5082 	char mbuf[BUFSIZ];
   5083 	char qbuf[DNS_NAME_FORMATSIZE];
   5084 
   5085 	if (qctx->client->query.origqname != NULL)
   5086 		dns_name_format(qctx->client->query.origqname, qbuf,
   5087 				sizeof(qbuf));
   5088 	else
   5089 		snprintf(qbuf, sizeof(qbuf), "<unset>");
   5090 
   5091 	snprintf(mbuf, sizeof(mbuf) - 1,
   5092 		 "client attr:0x%x, query attr:0x%X, restarts:%u, "
   5093 		 "origqname:%s, timer:%d, authdb:%d, referral:%d",
   5094 		 qctx->client->attributes,
   5095 		 qctx->client->query.attributes,
   5096 		 qctx->client->query.restarts, qbuf,
   5097 		 (int) qctx->client->query.timerset,
   5098 		 (int) qctx->client->query.authdbset,
   5099 		 (int) qctx->client->query.isreferral);
   5100 	CCTRACE(ISC_LOG_DEBUG(3), mbuf);
   5101 #else
   5102 	UNUSED(qctx);
   5103 #endif
   5104 }
   5105 
   5106 /*
   5107  * Set up query processing for the current query of 'client'.
   5108  * Calls qctx_init() to initialize a query context, checks
   5109  * the SERVFAIL cache, then hands off processing to ns__query_start().
   5110  *
   5111  * This is called only from ns_query_start(), to begin a query
   5112  * for the first time.  Restarting an existing query (for
   5113  * instance, to handle CNAME lookups), is done by calling
   5114  * ns__query_start() again with the same query context. Resuming from
   5115  * recursion is handled by query_resume().
   5116  */
   5117 static isc_result_t
   5118 query_setup(ns_client_t *client, dns_rdatatype_t qtype) {
   5119 	isc_result_t result;
   5120 	query_ctx_t qctx;
   5121 
   5122 	qctx_init(client, NULL, qtype, &qctx);
   5123 	query_trace(&qctx);
   5124 
   5125 	/*
   5126 	 * If it's a SIG query, we'll iterate the node.
   5127 	 */
   5128 	if (qctx.qtype == dns_rdatatype_rrsig ||
   5129 	    qctx.qtype == dns_rdatatype_sig)
   5130 	{
   5131 		qctx.type = dns_rdatatype_any;
   5132 	}
   5133 
   5134 	PROCESS_HOOK(NS_QUERY_SETUP_QCTX_INITIALIZED, &qctx);
   5135 
   5136 	/*
   5137 	 * Check SERVFAIL cache
   5138 	 */
   5139 	result = ns__query_sfcache(&qctx);
   5140 	if (result != ISC_R_COMPLETE) {
   5141 		return (result);
   5142 	}
   5143 
   5144 	return (ns__query_start(&qctx));
   5145 }
   5146 
   5147 static isc_boolean_t
   5148 get_root_key_sentinel_id(query_ctx_t *qctx, const char *ndata) {
   5149 	unsigned int v = 0;
   5150 	int i;
   5151 
   5152 	for (i = 0; i < 5; i++) {
   5153 		if (ndata[i] < '0' || ndata[i] > '9') {
   5154 			return (ISC_FALSE);
   5155 		}
   5156 		v *= 10;
   5157 		v += ndata[i] - '0';
   5158 	}
   5159 	if (v > 65535U) {
   5160 		return (ISC_FALSE);
   5161 	}
   5162 	qctx->client->query.root_key_sentinel_keyid = v;
   5163 	return (ISC_TRUE);
   5164 }
   5165 
   5166 /*%
   5167  * Find out if the query is for a root key sentinel and if so, record the type
   5168  * of root key sentinel query and the key id that is being checked for.
   5169  *
   5170  * The code is assuming a zero padded decimal field of width 5.
   5171  */
   5172 static void
   5173 root_key_sentinel_detect(query_ctx_t *qctx) {
   5174 	const char *ndata = (const char *)qctx->client->query.qname->ndata;
   5175 
   5176 	if (qctx->client->query.qname->length > 30 && ndata[0] == 29 &&
   5177 	    strncasecmp(ndata + 1, "root-key-sentinel-is-ta-", 24) == 0)
   5178 	{
   5179 		if (!get_root_key_sentinel_id(qctx, ndata + 25)) {
   5180 			return;
   5181 		}
   5182 		qctx->client->query.root_key_sentinel_is_ta = ISC_TRUE;
   5183 		/*
   5184 		 * Simplify processing by disabling agressive
   5185 		 * negative caching.
   5186 		 */
   5187 		qctx->findcoveringnsec = ISC_FALSE;
   5188 		ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
   5189 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   5190 			      "root-key-sentinel-is-ta query label found");
   5191 	} else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 &&
   5192 		   strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0)
   5193 	{
   5194 		if (!get_root_key_sentinel_id(qctx, ndata + 26)) {
   5195 			return;
   5196 		}
   5197 		qctx->client->query.root_key_sentinel_not_ta = ISC_TRUE;
   5198 		/*
   5199 		 * Simplify processing by disabling agressive
   5200 		 * negative caching.
   5201 		 */
   5202 		qctx->findcoveringnsec = ISC_FALSE;
   5203 		ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
   5204 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   5205 			      "root-key-sentinel-not-ta query label found");
   5206 	}
   5207 }
   5208 
   5209 /*%
   5210  * Starting point for a client query or a chaining query.
   5211  *
   5212  * Called first by query_setup(), and then again as often as needed to
   5213  * follow a CNAME chain.  Determines which authoritative database to
   5214  * search, then hands off processing to query_lookup().
   5215  */
   5216 isc_result_t
   5217 ns__query_start(query_ctx_t *qctx) {
   5218 	isc_result_t result;
   5219 	CCTRACE(ISC_LOG_DEBUG(3), "ns__query_start");
   5220 	qctx->want_restart = ISC_FALSE;
   5221 	qctx->authoritative = ISC_FALSE;
   5222 	qctx->version = NULL;
   5223 	qctx->zversion = NULL;
   5224 	qctx->need_wildcardproof = ISC_FALSE;
   5225 	qctx->rpz = ISC_FALSE;
   5226 
   5227 	if (qctx->client->view->checknames &&
   5228 	    !dns_rdata_checkowner(qctx->client->query.qname,
   5229 				  qctx->client->message->rdclass,
   5230 				  qctx->qtype, ISC_FALSE))
   5231 	{
   5232 		char namebuf[DNS_NAME_FORMATSIZE];
   5233 		char typename[DNS_RDATATYPE_FORMATSIZE];
   5234 		char classname[DNS_RDATACLASS_FORMATSIZE];
   5235 
   5236 		dns_name_format(qctx->client->query.qname,
   5237 				namebuf, sizeof(namebuf));
   5238 		dns_rdatatype_format(qctx->qtype, typename, sizeof(typename));
   5239 		dns_rdataclass_format(qctx->client->message->rdclass,
   5240 				      classname, sizeof(classname));
   5241 		ns_client_log(qctx->client, DNS_LOGCATEGORY_SECURITY,
   5242 			      NS_LOGMODULE_QUERY, ISC_LOG_ERROR,
   5243 			      "check-names failure %s/%s/%s", namebuf,
   5244 			      typename, classname);
   5245 		QUERY_ERROR(qctx, DNS_R_REFUSED);
   5246 		return (query_done(qctx));
   5247 	}
   5248 
   5249 	/*
   5250 	 * Setup for root key sentinel processing.
   5251 	 */
   5252 	if (qctx->client->view->root_key_sentinel &&
   5253 	    qctx->client->query.restarts == 0 &&
   5254 	    (qctx->qtype == dns_rdatatype_a ||
   5255 	     qctx->qtype == dns_rdatatype_aaaa) &&
   5256 	    (qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0)
   5257 	{
   5258 		 root_key_sentinel_detect(qctx);
   5259 	}
   5260 
   5261 	/*
   5262 	 * First we must find the right database.
   5263 	 */
   5264 	qctx->options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */
   5265 	if (dns_rdatatype_atparent(qctx->qtype) &&
   5266 	    !dns_name_equal(qctx->client->query.qname, dns_rootname))
   5267 	{
   5268 		/*
   5269 		 * If authoritative data for this QTYPE is supposed to live in
   5270 		 * the parent zone, do not look for an exact match for QNAME,
   5271 		 * but rather for its containing zone (unless the QNAME is
   5272 		 * root).
   5273 		 */
   5274 		qctx->options |= DNS_GETDB_NOEXACT;
   5275 	}
   5276 
   5277 	result = query_getdb(qctx->client, qctx->client->query.qname,
   5278 			     qctx->qtype, qctx->options, &qctx->zone,
   5279 			     &qctx->db, &qctx->version, &qctx->is_zone);
   5280 	if (ISC_UNLIKELY((result != ISC_R_SUCCESS || !qctx->is_zone) &&
   5281 			 qctx->qtype == dns_rdatatype_ds &&
   5282 			 !RECURSIONOK(qctx->client) &&
   5283 			 (qctx->options & DNS_GETDB_NOEXACT) != 0))
   5284 	{
   5285 		/*
   5286 		 * This is a non-recursive QTYPE=DS query with QNAME whose
   5287 		 * parent we are not authoritative for.  Check whether we are
   5288 		 * authoritative for QNAME, because if so, we need to send a
   5289 		 * "no data" response as required by RFC 4035, section 3.1.4.1.
   5290 		 */
   5291 		dns_db_t *tdb = NULL;
   5292 		dns_zone_t *tzone = NULL;
   5293 		dns_dbversion_t *tversion = NULL;
   5294 		isc_result_t tresult;
   5295 
   5296 		tresult = query_getzonedb(qctx->client,
   5297 					  qctx->client->query.qname,
   5298 					  qctx->qtype,
   5299 					  DNS_GETDB_PARTIAL,
   5300 					  &tzone, &tdb, &tversion);
   5301 		if (tresult == ISC_R_SUCCESS) {
   5302 			/*
   5303 			 * We are authoritative for QNAME.  Attach the relevant
   5304 			 * zone to query context, set result to ISC_R_SUCCESS.
   5305 			 */
   5306 			qctx->options &= ~DNS_GETDB_NOEXACT;
   5307 			query_putrdataset(qctx->client, &qctx->rdataset);
   5308 			if (qctx->db != NULL) {
   5309 				dns_db_detach(&qctx->db);
   5310 			}
   5311 			if (qctx->zone != NULL) {
   5312 				dns_zone_detach(&qctx->zone);
   5313 			}
   5314 			qctx->version = NULL;
   5315 			RESTORE(qctx->version, tversion);
   5316 			RESTORE(qctx->db, tdb);
   5317 			RESTORE(qctx->zone, tzone);
   5318 			qctx->is_zone = ISC_TRUE;
   5319 			result = ISC_R_SUCCESS;
   5320 		} else {
   5321 			/*
   5322 			 * We are not authoritative for QNAME.  Clean up and
   5323 			 * leave result as it was.
   5324 			 */
   5325 			if (tdb != NULL) {
   5326 				dns_db_detach(&tdb);
   5327 			}
   5328 			if (tzone != NULL) {
   5329 				dns_zone_detach(&tzone);
   5330 			}
   5331 		}
   5332 	}
   5333 	/*
   5334 	 * If we did not find a database from which we can answer the query,
   5335 	 * respond with either REFUSED or SERVFAIL, depending on what the
   5336 	 * result of query_getdb() was.
   5337 	 */
   5338 	if (result != ISC_R_SUCCESS) {
   5339 		if (result == DNS_R_REFUSED) {
   5340 			if (WANTRECURSION(qctx->client)) {
   5341 				inc_stats(qctx->client,
   5342 					  ns_statscounter_recurserej);
   5343 			} else {
   5344 				inc_stats(qctx->client,
   5345 					  ns_statscounter_authrej);
   5346 			}
   5347 			if (!PARTIALANSWER(qctx->client)) {
   5348 				QUERY_ERROR(qctx, DNS_R_REFUSED);
   5349 			}
   5350 		} else {
   5351 			CCTRACE(ISC_LOG_ERROR,
   5352 			       "ns__query_start: query_getdb failed");
   5353 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5354 		}
   5355 		return (query_done(qctx));
   5356 	}
   5357 
   5358 	/*
   5359 	 * We found a database from which we can answer the query.  Update
   5360 	 * relevant query context flags if the answer is to be prepared using
   5361 	 * authoritative data.
   5362 	 */
   5363 	qctx->is_staticstub_zone = ISC_FALSE;
   5364 	if (qctx->is_zone) {
   5365 		qctx->authoritative = ISC_TRUE;
   5366 		if (qctx->zone != NULL &&
   5367 		    dns_zone_gettype(qctx->zone) == dns_zone_staticstub)
   5368 		{
   5369 			qctx->is_staticstub_zone = ISC_TRUE;
   5370 		}
   5371 	}
   5372 
   5373 	/*
   5374 	 * Attach to the database which will be used to prepare the answer.
   5375 	 * Update query statistics.
   5376 	 */
   5377 	if (qctx->event == NULL && qctx->client->query.restarts == 0) {
   5378 		if (qctx->is_zone) {
   5379 			if (qctx->zone != NULL) {
   5380 				/*
   5381 				 * if is_zone = true, zone = NULL then this is
   5382 				 * a DLZ zone.  Don't attempt to attach zone.
   5383 				 */
   5384 				dns_zone_attach(qctx->zone,
   5385 						&qctx->client->query.authzone);
   5386 			}
   5387 			dns_db_attach(qctx->db, &qctx->client->query.authdb);
   5388 		}
   5389 		qctx->client->query.authdbset = ISC_TRUE;
   5390 
   5391 		/* Track TCP vs UDP stats per zone */
   5392 		if (TCP(qctx->client)) {
   5393 			inc_stats(qctx->client, ns_statscounter_tcp);
   5394 		} else {
   5395 			inc_stats(qctx->client, ns_statscounter_udp);
   5396 		}
   5397 	}
   5398 
   5399 	return (query_lookup(qctx));
   5400 }
   5401 
   5402 /*%
   5403  * Perform a local database lookup, in either an authoritative or
   5404  * cache database. If unable to answer, call query_done(); otherwise
   5405  * hand off processing to query_gotanswer().
   5406  */
   5407 static isc_result_t
   5408 query_lookup(query_ctx_t *qctx) {
   5409 	isc_buffer_t b;
   5410 	isc_result_t result;
   5411 	dns_clientinfomethods_t cm;
   5412 	dns_clientinfo_t ci;
   5413 	dns_name_t *rpzqname = NULL;
   5414 	unsigned int dboptions;
   5415 
   5416 	CCTRACE(ISC_LOG_DEBUG(3), "query_lookup");
   5417 
   5418 	PROCESS_HOOK(NS_QUERY_LOOKUP_BEGIN, qctx);
   5419 
   5420 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   5421 	dns_clientinfo_init(&ci, qctx->client, NULL);
   5422 
   5423 	/*
   5424 	 * We'll need some resources...
   5425 	 */
   5426 	qctx->dbuf = query_getnamebuf(qctx->client);
   5427 	if (ISC_UNLIKELY(qctx->dbuf == NULL)) {
   5428 		CCTRACE(ISC_LOG_ERROR,
   5429 		       "query_lookup: query_getnamebuf failed (2)");
   5430 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5431 		return (query_done(qctx));
   5432 	}
   5433 
   5434 	qctx->fname = query_newname(qctx->client, qctx->dbuf, &b);
   5435 	qctx->rdataset = query_newrdataset(qctx->client);
   5436 
   5437 	if (ISC_UNLIKELY(qctx->fname == NULL || qctx->rdataset == NULL)) {
   5438 		CCTRACE(ISC_LOG_ERROR,
   5439 		       "query_lookup: query_newname failed (2)");
   5440 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5441 		return (query_done(qctx));
   5442 	}
   5443 
   5444 	if ((WANTDNSSEC(qctx->client) || qctx->findcoveringnsec) &&
   5445 	    (!qctx->is_zone || dns_db_issecure(qctx->db)))
   5446 	{
   5447 		qctx->sigrdataset = query_newrdataset(qctx->client);
   5448 		if (qctx->sigrdataset == NULL) {
   5449 			CCTRACE(ISC_LOG_ERROR,
   5450 			       "query_lookup: query_newrdataset failed (2)");
   5451 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5452 			return (query_done(qctx));
   5453 		}
   5454 	}
   5455 
   5456 	/*
   5457 	 * Now look for an answer in the database.
   5458 	 */
   5459 	if (qctx->dns64 && qctx->rpz) {
   5460 		rpzqname = qctx->client->query.rpz_st->p_name;
   5461 	} else {
   5462 		rpzqname = qctx->client->query.qname;
   5463 	}
   5464 
   5465 	dboptions = qctx->client->query.dboptions;
   5466 	if (!qctx->is_zone && qctx->findcoveringnsec &&
   5467 	    (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname)))
   5468 		dboptions |= DNS_DBFIND_COVERINGNSEC;
   5469 
   5470 	result = dns_db_findext(qctx->db, rpzqname, qctx->version, qctx->type,
   5471 				dboptions, qctx->client->now, &qctx->node,
   5472 				qctx->fname, &cm, &ci,
   5473 				qctx->rdataset, qctx->sigrdataset);
   5474 
   5475 	/*
   5476 	 * Fixup fname and sigrdataset.
   5477 	 */
   5478 	if (qctx->dns64 && qctx->rpz) {
   5479 		isc_result_t rresult;
   5480 
   5481 		rresult = dns_name_copy(qctx->client->query.qname,
   5482 					qctx->fname, NULL);
   5483 		RUNTIME_CHECK(rresult == ISC_R_SUCCESS);
   5484 		if (qctx->sigrdataset != NULL &&
   5485 		    dns_rdataset_isassociated(qctx->sigrdataset))
   5486 		{
   5487 			dns_rdataset_disassociate(qctx->sigrdataset);
   5488 		}
   5489 	}
   5490 
   5491 	if (!qctx->is_zone) {
   5492 		dns_cache_updatestats(qctx->client->view->cache, result);
   5493 	}
   5494 
   5495 	if (qctx->want_stale) {
   5496 		char namebuf[DNS_NAME_FORMATSIZE];
   5497 		isc_boolean_t success;
   5498 
   5499 		qctx->client->query.dboptions &= ~DNS_DBFIND_STALEOK;
   5500 		qctx->want_stale = ISC_FALSE;
   5501 		if (dns_rdataset_isassociated(qctx->rdataset) &&
   5502 		    dns_rdataset_count(qctx->rdataset) > 0 &&
   5503 		    STALE(qctx->rdataset)) {
   5504 			qctx->rdataset->ttl =
   5505 					 qctx->client->view->staleanswerttl;
   5506 			success = ISC_TRUE;
   5507 		} else {
   5508 			success = ISC_FALSE;
   5509 		}
   5510 
   5511 		dns_name_format(qctx->client->query.qname,
   5512 				namebuf, sizeof(namebuf));
   5513 		isc_log_write(ns_lctx, NS_LOGCATEGORY_SERVE_STALE,
   5514 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   5515 			      "%s resolver failure, stale answer %s",
   5516 			      namebuf, success ? "used" : "unavailable");
   5517 
   5518 		if (!success) {
   5519 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5520 			return (query_done(qctx));
   5521 		}
   5522 	}
   5523 
   5524 	return (query_gotanswer(qctx, result));
   5525 }
   5526 
   5527 /*
   5528  * Event handler to resume processing a query after recursion.
   5529  * If the query has timed out or been canceled or the system
   5530  * is shutting down, clean up and exit; otherwise, call
   5531  * query_resume() to continue the ongoing work.
   5532  */
   5533 static void
   5534 fetch_callback(isc_task_t *task, isc_event_t *event) {
   5535 	dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
   5536 	dns_fetch_t *fetch = NULL;
   5537 	ns_client_t *client;
   5538 	isc_boolean_t fetch_canceled, client_shuttingdown;
   5539 	isc_result_t result;
   5540 	isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_ERRORS;
   5541 	int errorloglevel;
   5542 
   5543 	UNUSED(task);
   5544 
   5545 	REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
   5546 	client = devent->ev_arg;
   5547 	REQUIRE(NS_CLIENT_VALID(client));
   5548 	REQUIRE(task == client->task);
   5549 	REQUIRE(RECURSING(client));
   5550 
   5551 	LOCK(&client->query.fetchlock);
   5552 	if (client->query.fetch != NULL) {
   5553 		/*
   5554 		 * This is the fetch we've been waiting for.
   5555 		 */
   5556 		INSIST(devent->fetch == client->query.fetch);
   5557 		client->query.fetch = NULL;
   5558 		fetch_canceled = ISC_FALSE;
   5559 		/*
   5560 		 * Update client->now.
   5561 		 */
   5562 		isc_stdtime_get(&client->now);
   5563 	} else {
   5564 		/*
   5565 		 * This is a fetch completion event for a canceled fetch.
   5566 		 * Clean up and don't resume the find.
   5567 		 */
   5568 		fetch_canceled = ISC_TRUE;
   5569 	}
   5570 	UNLOCK(&client->query.fetchlock);
   5571 	INSIST(client->query.fetch == NULL);
   5572 
   5573 	client->query.attributes &= ~NS_QUERYATTR_RECURSING;
   5574 	SAVE(fetch, devent->fetch);
   5575 
   5576 	/*
   5577 	 * If this client is shutting down, or this transaction
   5578 	 * has timed out, do not resume the find.
   5579 	 */
   5580 	client_shuttingdown = ns_client_shuttingdown(client);
   5581 	if (fetch_canceled || client_shuttingdown) {
   5582 		free_devent(client, &event, &devent);
   5583 		if (fetch_canceled) {
   5584 			CTRACE(ISC_LOG_ERROR, "fetch cancelled");
   5585 			query_error(client, DNS_R_SERVFAIL, __LINE__);
   5586 		} else {
   5587 			query_next(client, ISC_R_CANCELED);
   5588 		}
   5589 		/*
   5590 		 * This may destroy the client.
   5591 		 */
   5592 		ns_client_detach(&client);
   5593 	} else {
   5594 		query_ctx_t qctx;
   5595 
   5596 		qctx_init(client, devent, 0, &qctx);
   5597 		query_trace(&qctx);
   5598 
   5599 		result = query_resume(&qctx);
   5600 		if (result != ISC_R_SUCCESS) {
   5601 			if (result == DNS_R_SERVFAIL) {
   5602 				errorloglevel = ISC_LOG_DEBUG(2);
   5603 			} else {
   5604 				errorloglevel = ISC_LOG_DEBUG(4);
   5605 			}
   5606 			if (isc_log_wouldlog(ns_lctx, errorloglevel)) {
   5607 				dns_resolver_logfetch(fetch, ns_lctx,
   5608 						      logcategory,
   5609 						      NS_LOGMODULE_QUERY,
   5610 						      errorloglevel, ISC_FALSE);
   5611 			}
   5612 		}
   5613 	}
   5614 
   5615 	dns_resolver_destroyfetch(&fetch);
   5616 }
   5617 
   5618 /*%
   5619  * Check whether the recursion parameters in 'param' match the current query's
   5620  * recursion parameters provided in 'qtype', 'qname', and 'qdomain'.
   5621  */
   5622 static isc_boolean_t
   5623 recparam_match(const ns_query_recparam_t *param, dns_rdatatype_t qtype,
   5624 	       const dns_name_t *qname, const dns_name_t *qdomain)
   5625 {
   5626 	REQUIRE(param != NULL);
   5627 
   5628 	return (ISC_TF(param->qtype == qtype &&
   5629 		       param->qname != NULL && qname != NULL &&
   5630 		       param->qdomain != NULL && qdomain != NULL &&
   5631 		       dns_name_equal(param->qname, qname) &&
   5632 		       dns_name_equal(param->qdomain, qdomain)));
   5633 }
   5634 
   5635 /*%
   5636  * Update 'param' with current query's recursion parameters provided in
   5637  * 'qtype', 'qname', and 'qdomain'.
   5638  */
   5639 static void
   5640 recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype,
   5641 		const dns_name_t *qname, const dns_name_t *qdomain)
   5642 {
   5643 	isc_result_t result;
   5644 
   5645 	REQUIRE(param != NULL);
   5646 
   5647 	param->qtype = qtype;
   5648 
   5649 	if (qname == NULL) {
   5650 		param->qname = NULL;
   5651 	} else {
   5652 		dns_fixedname_init(&param->fqname);
   5653 		param->qname = dns_fixedname_name(&param->fqname);
   5654 		result = dns_name_copy(qname, param->qname, NULL);
   5655 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5656 	}
   5657 
   5658 	if (qdomain == NULL) {
   5659 		param->qdomain = NULL;
   5660 	} else {
   5661 		dns_fixedname_init(&param->fqdomain);
   5662 		param->qdomain = dns_fixedname_name(&param->fqdomain);
   5663 		result = dns_name_copy(qdomain, param->qdomain, NULL);
   5664 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5665 	}
   5666 }
   5667 
   5668 /*%
   5669  * Prepare client for recursion, then create a resolver fetch, with
   5670  * the event callback set to fetch_callback(). Afterward we terminate
   5671  * this phase of the query, and resume with a new query context when
   5672  * recursion completes.
   5673  */
   5674 static isc_result_t
   5675 query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
   5676 	      dns_name_t *qdomain, dns_rdataset_t *nameservers,
   5677 	      isc_boolean_t resuming)
   5678 {
   5679 	isc_result_t result;
   5680 	dns_rdataset_t *rdataset, *sigrdataset;
   5681 	isc_sockaddr_t *peeraddr = NULL;
   5682 
   5683 	CTRACE(ISC_LOG_DEBUG(3), "query_recurse");
   5684 
   5685 	/*
   5686 	 * Check recursion parameters from the previous query to see if they
   5687 	 * match.  If not, update recursion parameters and proceed.
   5688 	 */
   5689 	if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) {
   5690 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
   5691 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
   5692 			      "recursion loop detected");
   5693 		return (ISC_R_FAILURE);
   5694 	}
   5695 
   5696 	recparam_update(&client->query.recparam, qtype, qname, qdomain);
   5697 
   5698 	if (!resuming)
   5699 		inc_stats(client, ns_statscounter_recursion);
   5700 
   5701 	/*
   5702 	 * We are about to recurse, which means that this client will
   5703 	 * be unavailable for serving new requests for an indeterminate
   5704 	 * amount of time.  If this client is currently responsible
   5705 	 * for handling incoming queries, set up a new client
   5706 	 * object to handle them while we are waiting for a
   5707 	 * response.  There is no need to replace TCP clients
   5708 	 * because those have already been replaced when the
   5709 	 * connection was accepted (if allowed by the TCP quota).
   5710 	 */
   5711 	if (client->recursionquota == NULL) {
   5712 		result = isc_quota_attach(&client->sctx->recursionquota,
   5713 					  &client->recursionquota);
   5714 
   5715 		ns_stats_increment(client->sctx->nsstats,
   5716 				   ns_statscounter_recursclients);
   5717 
   5718 		if  (result == ISC_R_SOFTQUOTA) {
   5719 			static isc_stdtime_t last = 0;
   5720 			isc_stdtime_t now;
   5721 			isc_stdtime_get(&now);
   5722 			if (now != last) {
   5723 				last = now;
   5724 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
   5725 					      NS_LOGMODULE_QUERY,
   5726 					      ISC_LOG_WARNING,
   5727 					      "recursive-clients soft limit "
   5728 					      "exceeded (%d/%d/%d), "
   5729 					      "aborting oldest query",
   5730 					      client->recursionquota->used,
   5731 					      client->recursionquota->soft,
   5732 					      client->recursionquota->max);
   5733 			}
   5734 			ns_client_killoldestquery(client);
   5735 			result = ISC_R_SUCCESS;
   5736 		} else if (result == ISC_R_QUOTA) {
   5737 			static isc_stdtime_t last = 0;
   5738 			isc_stdtime_t now;
   5739 			isc_stdtime_get(&now);
   5740 			if (now != last) {
   5741 				last = now;
   5742 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
   5743 					      NS_LOGMODULE_QUERY,
   5744 					      ISC_LOG_WARNING,
   5745 					      "no more recursive clients "
   5746 					      "(%d/%d/%d): %s",
   5747 					      client->sctx->recursionquota.used,
   5748 					      client->sctx->recursionquota.soft,
   5749 					      client->sctx->recursionquota.max,
   5750 					      isc_result_totext(result));
   5751 			}
   5752 			ns_client_killoldestquery(client);
   5753 		}
   5754 		if (result == ISC_R_SUCCESS && !client->mortal &&
   5755 		    !TCP(client)) {
   5756 			result = ns_client_replace(client);
   5757 			if (result != ISC_R_SUCCESS) {
   5758 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
   5759 					      NS_LOGMODULE_QUERY,
   5760 					      ISC_LOG_WARNING,
   5761 					      "ns_client_replace() failed: %s",
   5762 					      isc_result_totext(result));
   5763 				isc_quota_detach(&client->recursionquota);
   5764 				ns_stats_decrement(client->sctx->nsstats,
   5765 					   ns_statscounter_recursclients);
   5766 			}
   5767 		}
   5768 		if (result != ISC_R_SUCCESS)
   5769 			return (result);
   5770 		ns_client_recursing(client);
   5771 	}
   5772 
   5773 	/*
   5774 	 * Invoke the resolver.
   5775 	 */
   5776 	REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns);
   5777 	REQUIRE(client->query.fetch == NULL);
   5778 
   5779 	rdataset = query_newrdataset(client);
   5780 	if (rdataset == NULL) {
   5781 		return (ISC_R_NOMEMORY);
   5782 	}
   5783 
   5784 	if (WANTDNSSEC(client)) {
   5785 		sigrdataset = query_newrdataset(client);
   5786 		if (sigrdataset == NULL) {
   5787 			query_putrdataset(client, &rdataset);
   5788 			return (ISC_R_NOMEMORY);
   5789 		}
   5790 	} else {
   5791 		sigrdataset = NULL;
   5792 	}
   5793 
   5794 	if (client->query.timerset == ISC_FALSE) {
   5795 		ns_client_settimeout(client, 60);
   5796 	}
   5797 
   5798 	if (!TCP(client)) {
   5799 		peeraddr = &client->peeraddr;
   5800 	}
   5801 
   5802 	result = dns_resolver_createfetch3(client->view->resolver,
   5803 					   qname, qtype, qdomain, nameservers,
   5804 					   NULL, peeraddr, client->message->id,
   5805 					   client->query.fetchoptions, 0, NULL,
   5806 					   client->task, fetch_callback,
   5807 					   client, rdataset, sigrdataset,
   5808 					   &client->query.fetch);
   5809 	if (result != ISC_R_SUCCESS) {
   5810 		query_putrdataset(client, &rdataset);
   5811 		if (sigrdataset != NULL) {
   5812 			query_putrdataset(client, &sigrdataset);
   5813 		}
   5814 	}
   5815 
   5816 	/*
   5817 	 * We're now waiting for a fetch event. A client which is
   5818 	 * shutting down will not be destroyed until all the events
   5819 	 * have been received.
   5820 	 */
   5821 
   5822 	return (result);
   5823 }
   5824 
   5825 /*%
   5826  * Restores the query context after resuming from recursion, and
   5827  * continues the query processing if needed.
   5828  */
   5829 static isc_result_t
   5830 query_resume(query_ctx_t *qctx) {
   5831 	isc_result_t result;
   5832 	dns_name_t *tname;
   5833 	isc_buffer_t b;
   5834 #ifdef WANT_QUERYTRACE
   5835 	char mbuf[BUFSIZ];
   5836 	char qbuf[DNS_NAME_FORMATSIZE];
   5837 	char tbuf[DNS_RDATATYPE_FORMATSIZE];
   5838 #endif
   5839 
   5840 	qctx->want_restart = ISC_FALSE;
   5841 
   5842 	qctx->rpz_st = qctx->client->query.rpz_st;
   5843 	if (qctx->rpz_st != NULL &&
   5844 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0)
   5845 	{
   5846 		CCTRACE(ISC_LOG_DEBUG(3), "resume from RPZ recursion");
   5847 #ifdef WANT_QUERYTRACE
   5848 		{
   5849 			char pbuf[DNS_NAME_FORMATSIZE] = "<unset>";
   5850 			char fbuf[DNS_NAME_FORMATSIZE] = "<unset>";
   5851 			if (qctx->rpz_st->r_name != NULL)
   5852 				dns_name_format(qctx->rpz_st->r_name,
   5853 						qbuf, sizeof(qbuf));
   5854 			else
   5855 				snprintf(qbuf, sizeof(qbuf),
   5856 					 "<unset>");
   5857 			if (qctx->rpz_st->p_name != NULL)
   5858 				dns_name_format(qctx->rpz_st->p_name,
   5859 						pbuf, sizeof(pbuf));
   5860 			if (qctx->rpz_st->fname != NULL)
   5861 				dns_name_format(qctx->rpz_st->fname,
   5862 						fbuf, sizeof(fbuf));
   5863 
   5864 			snprintf(mbuf, sizeof(mbuf) - 1,
   5865 				 "rpz rname:%s, pname:%s, qctx->fname:%s",
   5866 				 qbuf, pbuf, fbuf);
   5867 			CCTRACE(ISC_LOG_DEBUG(3), mbuf);
   5868 		}
   5869 #endif
   5870 
   5871 		qctx->is_zone = qctx->rpz_st->q.is_zone;
   5872 		qctx->authoritative = qctx->rpz_st->q.authoritative;
   5873 		RESTORE(qctx->zone, qctx->rpz_st->q.zone);
   5874 		RESTORE(qctx->node, qctx->rpz_st->q.node);
   5875 		RESTORE(qctx->db, qctx->rpz_st->q.db);
   5876 		RESTORE(qctx->rdataset, qctx->rpz_st->q.rdataset);
   5877 		RESTORE(qctx->sigrdataset, qctx->rpz_st->q.sigrdataset);
   5878 		qctx->qtype = qctx->rpz_st->q.qtype;
   5879 
   5880 		if (qctx->event->node != NULL)
   5881 			dns_db_detachnode(qctx->event->db, &qctx->event->node);
   5882 		SAVE(qctx->rpz_st->r.db, qctx->event->db);
   5883 		qctx->rpz_st->r.r_type = qctx->event->qtype;
   5884 		SAVE(qctx->rpz_st->r.r_rdataset, qctx->event->rdataset);
   5885 		query_putrdataset(qctx->client, &qctx->event->sigrdataset);
   5886 	} else if (REDIRECT(qctx->client)) {
   5887 		/*
   5888 		 * Restore saved state.
   5889 		 */
   5890 		CCTRACE(ISC_LOG_DEBUG(3),
   5891 		       "resume from redirect recursion");
   5892 #ifdef WANT_QUERYTRACE
   5893 		dns_name_format(qctx->client->query.redirect.fname,
   5894 				qbuf, sizeof(qbuf));
   5895 		dns_rdatatype_format(qctx->client->query.redirect.qtype,
   5896 				     tbuf, sizeof(tbuf));
   5897 		snprintf(mbuf, sizeof(mbuf) - 1,
   5898 			 "redirect qctx->fname:%s, qtype:%s, auth:%d",
   5899 			 qbuf, tbuf,
   5900 			 qctx->client->query.redirect.authoritative);
   5901 		CCTRACE(ISC_LOG_DEBUG(3), mbuf);
   5902 #endif
   5903 		qctx->qtype = qctx->client->query.redirect.qtype;
   5904 		INSIST(qctx->client->query.redirect.rdataset != NULL);
   5905 		RESTORE(qctx->rdataset, qctx->client->query.redirect.rdataset);
   5906 		RESTORE(qctx->sigrdataset,
   5907 			qctx->client->query.redirect.sigrdataset);
   5908 		RESTORE(qctx->db, qctx->client->query.redirect.db);
   5909 		RESTORE(qctx->node, qctx->client->query.redirect.node);
   5910 		RESTORE(qctx->zone, qctx->client->query.redirect.zone);
   5911 		qctx->authoritative =
   5912 			qctx->client->query.redirect.authoritative;
   5913 		qctx->is_zone = qctx->client->query.redirect.is_zone;
   5914 
   5915 		/*
   5916 		 * Free resources used while recursing.
   5917 		 */
   5918 		query_putrdataset(qctx->client, &qctx->event->rdataset);
   5919 		query_putrdataset(qctx->client, &qctx->event->sigrdataset);
   5920 		if (qctx->event->node != NULL)
   5921 			dns_db_detachnode(qctx->event->db, &qctx->event->node);
   5922 		if (qctx->event->db != NULL)
   5923 			dns_db_detach(&qctx->event->db);
   5924 	} else {
   5925 		CCTRACE(ISC_LOG_DEBUG(3),
   5926 		       "resume from normal recursion");
   5927 		qctx->authoritative = ISC_FALSE;
   5928 
   5929 		qctx->qtype = qctx->event->qtype;
   5930 		SAVE(qctx->db, qctx->event->db);
   5931 		SAVE(qctx->node, qctx->event->node);
   5932 		SAVE(qctx->rdataset, qctx->event->rdataset);
   5933 		SAVE(qctx->sigrdataset, qctx->event->sigrdataset);
   5934 	}
   5935 	INSIST(qctx->rdataset != NULL);
   5936 
   5937 	if (qctx->qtype == dns_rdatatype_rrsig ||
   5938 	    qctx->qtype == dns_rdatatype_sig)
   5939 	{
   5940 		qctx->type = dns_rdatatype_any;
   5941 	} else {
   5942 		qctx->type = qctx->qtype;
   5943 	}
   5944 
   5945 	if (DNS64(qctx->client)) {
   5946 		qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64;
   5947 		qctx->dns64 = ISC_TRUE;
   5948 	}
   5949 
   5950 	if (DNS64EXCLUDE(qctx->client)) {
   5951 		qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
   5952 		qctx->dns64_exclude = ISC_TRUE;
   5953 	}
   5954 
   5955 	if (qctx->rpz_st != NULL &&
   5956 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0)
   5957 	{
   5958 		/*
   5959 		 * Has response policy changed out from under us?
   5960 		 */
   5961 		if (qctx->rpz_st->rpz_ver != qctx->client->view->rpzs->rpz_ver)
   5962 		{
   5963 			ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
   5964 				      NS_LOGMODULE_QUERY,
   5965 				      DNS_RPZ_INFO_LEVEL,
   5966 				      "query_resume: RPZ settings "
   5967 				      "out of date "
   5968 				      "(rpz_ver %d, expected %d)",
   5969 				      qctx->client->view->rpzs->rpz_ver,
   5970 				      qctx->rpz_st->rpz_ver);
   5971 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5972 			return (query_done(qctx));
   5973 		}
   5974 	}
   5975 
   5976 	/*
   5977 	 * We'll need some resources...
   5978 	 */
   5979 	qctx->dbuf = query_getnamebuf(qctx->client);
   5980 	if (qctx->dbuf == NULL) {
   5981 		CCTRACE(ISC_LOG_ERROR,
   5982 		       "query_resume: query_getnamebuf failed (1)");
   5983 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5984 		return (query_done(qctx));
   5985 	}
   5986 
   5987 	qctx->fname = query_newname(qctx->client, qctx->dbuf, &b);
   5988 	if (qctx->fname == NULL) {
   5989 		CCTRACE(ISC_LOG_ERROR,
   5990 		       "query_resume: query_newname failed (1)");
   5991 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   5992 		return (query_done(qctx));
   5993 	}
   5994 
   5995 	if (qctx->rpz_st != NULL &&
   5996 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) {
   5997 		tname = qctx->rpz_st->fname;
   5998 	} else if (REDIRECT(qctx->client)) {
   5999 		tname = qctx->client->query.redirect.fname;
   6000 	} else {
   6001 		tname = dns_fixedname_name(&qctx->event->foundname);
   6002 	}
   6003 
   6004 	result = dns_name_copy(tname, qctx->fname, NULL);
   6005 	if (result != ISC_R_SUCCESS) {
   6006 		CCTRACE(ISC_LOG_ERROR,
   6007 		       "query_resume: dns_name_copy failed");
   6008 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   6009 		return (query_done(qctx));
   6010 	}
   6011 
   6012 	if (qctx->rpz_st != NULL &&
   6013 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) {
   6014 		qctx->rpz_st->r.r_result = qctx->event->result;
   6015 		result = qctx->rpz_st->q.result;
   6016 		free_devent(qctx->client,
   6017 			    ISC_EVENT_PTR(&qctx->event), &qctx->event);
   6018 	} else if (REDIRECT(qctx->client)) {
   6019 		result = qctx->client->query.redirect.result;
   6020 		qctx->is_zone = qctx->client->query.redirect.is_zone;
   6021 	} else {
   6022 		result = qctx->event->result;
   6023 	}
   6024 
   6025 	qctx->resuming = ISC_TRUE;
   6026 
   6027 	return (query_gotanswer(qctx, result));
   6028 }
   6029 
   6030 /*%
   6031  * If the query is recursive, check the SERVFAIL cache to see whether
   6032  * identical queries have failed recently.  If we find a match, and it was
   6033  * from a query with CD=1, *or* if the current query has CD=0, then we just
   6034  * return SERVFAIL again.  This prevents a validation failure from eliciting a
   6035  * SERVFAIL response to a CD=1 query.
   6036  */
   6037 isc_result_t
   6038 ns__query_sfcache(query_ctx_t *qctx) {
   6039 	isc_boolean_t failcache;
   6040 	isc_uint32_t flags;
   6041 
   6042 	/*
   6043 	 * The SERVFAIL cache doesn't apply to authoritative queries.
   6044 	 */
   6045 	if (!RECURSIONOK(qctx->client)) {
   6046 		return (ISC_R_COMPLETE);
   6047 	}
   6048 
   6049 	flags = 0;
   6050 #ifdef ENABLE_AFL
   6051 	if (qctx->client->sctx->fuzztype == isc_fuzz_resolver) {
   6052 		failcache = ISC_FALSE;
   6053 	} else {
   6054 		failcache =
   6055 			dns_badcache_find(qctx->client->view->failcache,
   6056 					  qctx->client->query.qname,
   6057 					  qctx->qtype, &flags,
   6058 					  &qctx->client->tnow);
   6059 	}
   6060 #else
   6061 	failcache = dns_badcache_find(qctx->client->view->failcache,
   6062 				      qctx->client->query.qname,
   6063 				      qctx->qtype, &flags,
   6064 				      &qctx->client->tnow);
   6065 #endif
   6066 	if (failcache &&
   6067 	    (((flags & NS_FAILCACHE_CD) != 0) ||
   6068 	     ((qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0)))
   6069 	{
   6070 		if (isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(1))) {
   6071 			char namebuf[DNS_NAME_FORMATSIZE];
   6072 			char typename[DNS_RDATATYPE_FORMATSIZE];
   6073 
   6074 			dns_name_format(qctx->client->query.qname,
   6075 					namebuf, sizeof(namebuf));
   6076 			dns_rdatatype_format(qctx->qtype, typename,
   6077 					     sizeof(typename));
   6078 			ns_client_log(qctx->client,
   6079 				      NS_LOGCATEGORY_CLIENT,
   6080 				      NS_LOGMODULE_QUERY,
   6081 				      ISC_LOG_DEBUG(1),
   6082 				      "servfail cache hit %s/%s (%s)",
   6083 				      namebuf, typename,
   6084 				      ((flags & NS_FAILCACHE_CD) != 0)
   6085 				       ? "CD=1"
   6086 				       : "CD=0");
   6087 		}
   6088 
   6089 		qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
   6090 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   6091 		return (query_done(qctx));
   6092 	}
   6093 
   6094 	return (ISC_R_COMPLETE);
   6095 }
   6096 
   6097 /*%
   6098  * Handle response rate limiting (RRL).
   6099  */
   6100 static isc_result_t
   6101 query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
   6102 	/*
   6103 	 * Rate limit these responses to this client.
   6104 	 * Do not delay counting and handling obvious referrals,
   6105 	 *	since those won't come here again.
   6106 	 * Delay handling delegations for which we are certain to recurse and
   6107 	 *	return here (DNS_R_DELEGATION, not a child of one of our
   6108 	 *	own zones, and recursion enabled)
   6109 	 * Don't mess with responses rewritten by RPZ
   6110 	 * Count each response at most once.
   6111 	 */
   6112 	if (qctx->client->view->rrl != NULL &&
   6113 	    !HAVECOOKIE(qctx->client) &&
   6114 	    ((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) ||
   6115 	     (result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) &&
   6116 	    !(result == DNS_R_DELEGATION &&
   6117 	      !qctx->is_zone && RECURSIONOK(qctx->client)) &&
   6118 	    (qctx->client->query.rpz_st == NULL ||
   6119 	     (qctx->client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
   6120 	    (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0)
   6121 	{
   6122 		dns_rdataset_t nc_rdataset;
   6123 		isc_boolean_t wouldlog;
   6124 		dns_fixedname_t fixed;
   6125 		const dns_name_t *constname;
   6126 		char log_buf[DNS_RRL_LOG_BUF_LEN];
   6127 		isc_result_t nc_result, resp_result;
   6128 		dns_rrl_result_t rrl_result;
   6129 
   6130 		qctx->client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
   6131 
   6132 		wouldlog = isc_log_wouldlog(ns_lctx, DNS_RRL_LOG_DROP);
   6133 		constname = qctx->fname;
   6134 		if (result == DNS_R_NXDOMAIN) {
   6135 			/*
   6136 			 * Use the database origin name to rate limit NXDOMAIN
   6137 			 */
   6138 			if (qctx->db != NULL)
   6139 				constname = dns_db_origin(qctx->db);
   6140 			resp_result = result;
   6141 		} else if (result == DNS_R_NCACHENXDOMAIN &&
   6142 			   qctx->rdataset != NULL &&
   6143 			   dns_rdataset_isassociated(qctx->rdataset) &&
   6144 			   (qctx->rdataset->attributes &
   6145 			    DNS_RDATASETATTR_NEGATIVE) != 0) {
   6146 			/*
   6147 			 * Try to use owner name in the negative cache SOA.
   6148 			 */
   6149 			dns_fixedname_init(&fixed);
   6150 			dns_rdataset_init(&nc_rdataset);
   6151 			for (nc_result = dns_rdataset_first(qctx->rdataset);
   6152 			     nc_result == ISC_R_SUCCESS;
   6153 			     nc_result = dns_rdataset_next(qctx->rdataset))
   6154 			{
   6155 				dns_ncache_current(qctx->rdataset,
   6156 						   dns_fixedname_name(&fixed),
   6157 						   &nc_rdataset);
   6158 				if (nc_rdataset.type == dns_rdatatype_soa) {
   6159 					dns_rdataset_disassociate(&nc_rdataset);
   6160 					constname = dns_fixedname_name(&fixed);
   6161 					break;
   6162 				}
   6163 				dns_rdataset_disassociate(&nc_rdataset);
   6164 			}
   6165 			resp_result = DNS_R_NXDOMAIN;
   6166 		} else if (result == DNS_R_NXRRSET ||
   6167 			   result == DNS_R_EMPTYNAME) {
   6168 			resp_result = DNS_R_NXRRSET;
   6169 		} else if (result == DNS_R_DELEGATION) {
   6170 			resp_result = result;
   6171 		} else if (result == ISC_R_NOTFOUND) {
   6172 			/*
   6173 			 * Handle referral to ".", including when recursion
   6174 			 * is off or not requested and the hints have not
   6175 			 * been loaded or we have "additional-from-cache no".
   6176 			 */
   6177 			constname = dns_rootname;
   6178 			resp_result = DNS_R_DELEGATION;
   6179 		} else {
   6180 			resp_result = ISC_R_SUCCESS;
   6181 		}
   6182 
   6183 		rrl_result = dns_rrl(qctx->client->view,
   6184 				     &qctx->client->peeraddr,
   6185 				     TCP(qctx->client),
   6186 				     qctx->client->message->rdclass,
   6187 				     qctx->qtype, constname,
   6188 				     resp_result, qctx->client->now,
   6189 				     wouldlog, log_buf, sizeof(log_buf));
   6190 		if (rrl_result != DNS_RRL_RESULT_OK) {
   6191 			/*
   6192 			 * Log dropped or slipped responses in the query
   6193 			 * category so that requests are not silently lost.
   6194 			 * Starts of rate-limited bursts are logged in
   6195 			 * DNS_LOGCATEGORY_RRL.
   6196 			 *
   6197 			 * Dropped responses are counted with dropped queries
   6198 			 * in QryDropped while slipped responses are counted
   6199 			 * with other truncated responses in RespTruncated.
   6200 			 */
   6201 			if (wouldlog) {
   6202 				ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL,
   6203 					      NS_LOGMODULE_QUERY,
   6204 					      DNS_RRL_LOG_DROP,
   6205 					      "%s", log_buf);
   6206 			}
   6207 
   6208 			if (!qctx->client->view->rrl->log_only) {
   6209 				if (rrl_result == DNS_RRL_RESULT_DROP) {
   6210 					/*
   6211 					 * These will also be counted in
   6212 					 * ns_statscounter_dropped
   6213 					 */
   6214 					inc_stats(qctx->client,
   6215 						ns_statscounter_ratedropped);
   6216 					QUERY_ERROR(qctx, DNS_R_DROP);
   6217 				} else {
   6218 					/*
   6219 					 * These will also be counted in
   6220 					 * ns_statscounter_truncatedresp
   6221 					 */
   6222 					inc_stats(qctx->client,
   6223 						ns_statscounter_rateslipped);
   6224 					if (WANTCOOKIE(qctx->client)) {
   6225 						qctx->client->message->flags &=
   6226 							~DNS_MESSAGEFLAG_AA;
   6227 						qctx->client->message->flags &=
   6228 							~DNS_MESSAGEFLAG_AD;
   6229 						qctx->client->message->rcode =
   6230 							   dns_rcode_badcookie;
   6231 					} else {
   6232 						qctx->client->message->flags |=
   6233 							DNS_MESSAGEFLAG_TC;
   6234 						if (resp_result ==
   6235 						    DNS_R_NXDOMAIN)
   6236 						{
   6237 						  qctx->client->message->rcode =
   6238 							  dns_rcode_nxdomain;
   6239 						}
   6240 					}
   6241 				}
   6242 				return (DNS_R_DROP);
   6243 			}
   6244 		}
   6245 	} else if (!TCP(qctx->client) &&
   6246 		   qctx->client->view->requireservercookie &&
   6247 		   WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client))
   6248 	{
   6249 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
   6250 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
   6251 		qctx->client->message->rcode = dns_rcode_badcookie;
   6252 		return (DNS_R_DROP);
   6253 	}
   6254 
   6255 	return (ISC_R_SUCCESS);
   6256 }
   6257 
   6258 /*%
   6259  * Do any RPZ rewriting that may be needed for this query.
   6260  */
   6261 static isc_result_t
   6262 query_checkrpz(query_ctx_t *qctx, isc_result_t result) {
   6263 	isc_result_t rresult;
   6264 
   6265 	rresult = rpz_rewrite(qctx->client, qctx->qtype,
   6266 			      result, qctx->resuming,
   6267 			      qctx->rdataset, qctx->sigrdataset);
   6268 	qctx->rpz_st = qctx->client->query.rpz_st;
   6269 	switch (rresult) {
   6270 	case ISC_R_SUCCESS:
   6271 		break;
   6272 	case DNS_R_DISALLOWED:
   6273 		return (result);
   6274 	case DNS_R_DELEGATION:
   6275 		/*
   6276 		 * recursing for NS names or addresses,
   6277 		 * so save the main query state
   6278 		 */
   6279 		qctx->rpz_st->q.qtype = qctx->qtype;
   6280 		qctx->rpz_st->q.is_zone = qctx->is_zone;
   6281 		qctx->rpz_st->q.authoritative = qctx->authoritative;
   6282 		SAVE(qctx->rpz_st->q.zone, qctx->zone);
   6283 		SAVE(qctx->rpz_st->q.db, qctx->db);
   6284 		SAVE(qctx->rpz_st->q.node, qctx->node);
   6285 		SAVE(qctx->rpz_st->q.rdataset, qctx->rdataset);
   6286 		SAVE(qctx->rpz_st->q.sigrdataset, qctx->sigrdataset);
   6287 		dns_name_copy(qctx->fname, qctx->rpz_st->fname, NULL);
   6288 		qctx->rpz_st->q.result = result;
   6289 		qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
   6290 		return (ISC_R_COMPLETE);
   6291 	default:
   6292 		RECURSE_ERROR(qctx, rresult);
   6293 		return (ISC_R_COMPLETE);;
   6294 	}
   6295 
   6296 	if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS) {
   6297 		qctx->rpz_st->state |= DNS_RPZ_REWRITTEN;
   6298 	}
   6299 
   6300 	if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
   6301 	    qctx->rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU &&
   6302 	    (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY ||
   6303 	     !TCP(qctx->client)) &&
   6304 	    qctx->rpz_st->m.policy != DNS_RPZ_POLICY_ERROR)
   6305 	{
   6306 		/*
   6307 		 * We got a hit and are going to answer with our
   6308 		 * fiction. Ensure that we answer with the name
   6309 		 * we looked up even if we were stopped short
   6310 		 * in recursion or for a deferral.
   6311 		 */
   6312 		rresult = dns_name_copy(qctx->client->query.qname,
   6313 					qctx->fname, NULL);
   6314 		RUNTIME_CHECK(rresult == ISC_R_SUCCESS);
   6315 		rpz_clean(&qctx->zone, &qctx->db, &qctx->node, NULL);
   6316 		if (qctx->rpz_st->m.rdataset != NULL) {
   6317 			query_putrdataset(qctx->client, &qctx->rdataset);
   6318 			RESTORE(qctx->rdataset, qctx->rpz_st->m.rdataset);
   6319 		} else {
   6320 			qctx_clean(qctx);
   6321 		}
   6322 		qctx->version = NULL;
   6323 
   6324 		RESTORE(qctx->node, qctx->rpz_st->m.node);
   6325 		RESTORE(qctx->db, qctx->rpz_st->m.db);
   6326 		RESTORE(qctx->version, qctx->rpz_st->m.version);
   6327 		RESTORE(qctx->zone, qctx->rpz_st->m.zone);
   6328 
   6329 		/*
   6330 		 * Add SOA record to additional section
   6331 		 */
   6332 		rresult = query_addsoa(qctx,
   6333 			       dns_rdataset_isassociated(qctx->rdataset),
   6334 			       DNS_SECTION_ADDITIONAL);
   6335 		if (rresult != ISC_R_SUCCESS) {
   6336 			QUERY_ERROR(qctx, result);
   6337 			return (ISC_R_COMPLETE);
   6338 		}
   6339 
   6340 		switch (qctx->rpz_st->m.policy) {
   6341 		case DNS_RPZ_POLICY_TCP_ONLY:
   6342 			qctx->client->message->flags |= DNS_MESSAGEFLAG_TC;
   6343 			if (result == DNS_R_NXDOMAIN ||
   6344 					result == DNS_R_NCACHENXDOMAIN)
   6345 				qctx->client->message->rcode =
   6346 						dns_rcode_nxdomain;
   6347 			rpz_log_rewrite(qctx->client, ISC_FALSE,
   6348 					qctx->rpz_st->m.policy,
   6349 					qctx->rpz_st->m.type, qctx->zone,
   6350 					qctx->rpz_st->p_name, NULL,
   6351 					qctx->rpz_st->m.rpz->num);
   6352 			return (ISC_R_COMPLETE);
   6353 		case DNS_RPZ_POLICY_DROP:
   6354 			QUERY_ERROR(qctx, DNS_R_DROP);
   6355 			rpz_log_rewrite(qctx->client, ISC_FALSE,
   6356 					qctx->rpz_st->m.policy,
   6357 					qctx->rpz_st->m.type, qctx->zone,
   6358 					qctx->rpz_st->p_name, NULL,
   6359 					qctx->rpz_st->m.rpz->num);
   6360 			return (ISC_R_COMPLETE);
   6361 		case DNS_RPZ_POLICY_NXDOMAIN:
   6362 			result = DNS_R_NXDOMAIN;
   6363 			qctx->nxrewrite = ISC_TRUE;
   6364 			qctx->rpz = ISC_TRUE;
   6365 			break;
   6366 		case DNS_RPZ_POLICY_NODATA:
   6367 			result = DNS_R_NXRRSET;
   6368 			qctx->nxrewrite = ISC_TRUE;
   6369 			qctx->rpz = ISC_TRUE;
   6370 			break;
   6371 		case DNS_RPZ_POLICY_RECORD:
   6372 			result = qctx->rpz_st->m.result;
   6373 			if (qctx->qtype == dns_rdatatype_any &&
   6374 					result != DNS_R_CNAME) {
   6375 				/*
   6376 				 * We will add all of the rdatasets of
   6377 				 * the node by iterating later,
   6378 				 * and set the TTL then.
   6379 				 */
   6380 				if (dns_rdataset_isassociated(qctx->rdataset))
   6381 				      dns_rdataset_disassociate(qctx->rdataset);
   6382 			} else {
   6383 				/*
   6384 				 * We will add this rdataset.
   6385 				 */
   6386 				qctx->rdataset->ttl =
   6387 					ISC_MIN(qctx->rdataset->ttl,
   6388 						qctx->rpz_st->m.ttl);
   6389 			}
   6390 			qctx->rpz = ISC_TRUE;
   6391 			break;
   6392 		case DNS_RPZ_POLICY_WILDCNAME: {
   6393 			dns_rdata_t rdata = DNS_RDATA_INIT;
   6394 			dns_rdata_cname_t cname;
   6395 			result = dns_rdataset_first(qctx->rdataset);
   6396 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6397 			dns_rdataset_current(qctx->rdataset, &rdata);
   6398 			result = dns_rdata_tostruct(&rdata, &cname,
   6399 						    NULL);
   6400 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6401 			dns_rdata_reset(&rdata);
   6402 			result = query_rpzcname(qctx, &cname.cname);
   6403 			if (result != ISC_R_SUCCESS)
   6404 				return (ISC_R_COMPLETE);
   6405 			qctx->fname = NULL;
   6406 			qctx->want_restart = ISC_TRUE;
   6407 			return (ISC_R_COMPLETE);
   6408 		}
   6409 		case DNS_RPZ_POLICY_CNAME:
   6410 			/*
   6411 			 * Add overridding CNAME from a named.conf
   6412 			 * response-policy statement
   6413 			 */
   6414 			result = query_rpzcname(qctx,
   6415 						&qctx->rpz_st->m.rpz->cname);
   6416 			if (result != ISC_R_SUCCESS)
   6417 				return (ISC_R_COMPLETE);
   6418 			qctx->fname = NULL;
   6419 			qctx->want_restart = ISC_TRUE;
   6420 			return (ISC_R_COMPLETE);
   6421 		default:
   6422 			INSIST(0);
   6423 		}
   6424 
   6425 		/*
   6426 		 * Turn off DNSSEC because the results of a
   6427 		 * response policy zone cannot verify.
   6428 		 */
   6429 		qctx->client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
   6430 					      NS_CLIENTATTR_WANTAD);
   6431 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
   6432 		query_putrdataset(qctx->client, &qctx->sigrdataset);
   6433 		qctx->rpz_st->q.is_zone = qctx->is_zone;
   6434 		qctx->is_zone = ISC_TRUE;
   6435 		rpz_log_rewrite(qctx->client, ISC_FALSE,
   6436 				qctx->rpz_st->m.policy,
   6437 				qctx->rpz_st->m.type, qctx->zone,
   6438 				qctx->rpz_st->p_name, NULL,
   6439 				qctx->rpz_st->m.rpz->num);
   6440 	}
   6441 
   6442 	return (result);
   6443 }
   6444 
   6445 /*%
   6446  * Add a CNAME to a query response, including translating foo.evil.com and
   6447  *	*.evil.com CNAME *.example.com
   6448  * to
   6449  *	foo.evil.com CNAME foo.evil.com.example.com
   6450  */
   6451 static isc_result_t
   6452 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname) {
   6453 	ns_client_t *client = qctx->client;
   6454 	dns_fixedname_t prefix, suffix;
   6455 	unsigned int labels;
   6456 	isc_result_t result;
   6457 
   6458 	CTRACE(ISC_LOG_DEBUG(3), "query_rpzcname");
   6459 
   6460 	labels = dns_name_countlabels(cname);
   6461 	if (labels > 2 && dns_name_iswildcard(cname)) {
   6462 		dns_fixedname_init(&prefix);
   6463 		dns_name_split(client->query.qname, 1,
   6464 			       dns_fixedname_name(&prefix), NULL);
   6465 		dns_fixedname_init(&suffix);
   6466 		dns_name_split(cname, labels-1,
   6467 			       NULL, dns_fixedname_name(&suffix));
   6468 		result = dns_name_concatenate(dns_fixedname_name(&prefix),
   6469 					      dns_fixedname_name(&suffix),
   6470 					      qctx->fname, NULL);
   6471 		if (result == DNS_R_NAMETOOLONG) {
   6472 			client->message->rcode = dns_rcode_yxdomain;
   6473 		} else if (result != ISC_R_SUCCESS) {
   6474 			return (result);
   6475 		}
   6476 	} else {
   6477 		result = dns_name_copy(cname, qctx->fname, NULL);
   6478 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6479 	}
   6480 
   6481 	query_keepname(client, qctx->fname, qctx->dbuf);
   6482 	result = query_addcname(qctx, dns_trust_authanswer,
   6483 				qctx->rpz_st->m.ttl);
   6484 	if (result != ISC_R_SUCCESS) {
   6485 		return (result);
   6486 	}
   6487 
   6488 	rpz_log_rewrite(client, ISC_FALSE, qctx->rpz_st->m.policy,
   6489 			qctx->rpz_st->m.type, qctx->rpz_st->m.zone,
   6490 			qctx->rpz_st->p_name, qctx->fname,
   6491 			qctx->rpz_st->m.rpz->num);
   6492 
   6493 	ns_client_qnamereplace(client, qctx->fname);
   6494 
   6495 	/*
   6496 	 * Turn off DNSSEC because the results of a
   6497 	 * response policy zone cannot verify.
   6498 	 */
   6499 	client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
   6500 				NS_CLIENTATTR_WANTAD);
   6501 
   6502 	return (ISC_R_SUCCESS);
   6503 }
   6504 
   6505 /*%
   6506  * Check the configured trust anchors for a root zone trust anchor
   6507  * with a key id that matches qctx->client->query.root_key_sentinel_keyid.
   6508  *
   6509  * Return ISC_TRUE when found, otherwise return ISC_FALSE.
   6510  */
   6511 static isc_boolean_t
   6512 has_ta(query_ctx_t *qctx) {
   6513 	dns_keytable_t *keytable = NULL;
   6514 	dns_keynode_t *keynode = NULL;
   6515 	isc_result_t result;
   6516 
   6517 	result = dns_view_getsecroots(qctx->client->view, &keytable);
   6518 	if (result != ISC_R_SUCCESS) {
   6519 		return (ISC_FALSE);
   6520 	}
   6521 
   6522 	result = dns_keytable_find(keytable, dns_rootname, &keynode);
   6523 	while (result == ISC_R_SUCCESS) {
   6524 		dns_keynode_t *nextnode = NULL;
   6525 		dns_keytag_t keyid = dst_key_id(dns_keynode_key(keynode));
   6526 		if (keyid == qctx->client->query.root_key_sentinel_keyid) {
   6527 			dns_keytable_detachkeynode(keytable, &keynode);
   6528 			dns_keytable_detach(&keytable);
   6529 			return (ISC_TRUE);
   6530 		}
   6531 		result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
   6532 		dns_keytable_detachkeynode(keytable, &keynode);
   6533 		keynode = nextnode;
   6534 	}
   6535 	dns_keytable_detach(&keytable);
   6536 
   6537 	return (ISC_FALSE);
   6538 }
   6539 
   6540 /*%
   6541  * Check if a root key sentinel SERVFAIL should be returned.
   6542  */
   6543 static isc_boolean_t
   6544 root_key_sentinel_return_servfail(query_ctx_t *qctx, isc_result_t result) {
   6545 	/*
   6546 	 * Are we looking at a "root-key-sentinel" query?
   6547 	 */
   6548 	if (!qctx->client->query.root_key_sentinel_is_ta &&
   6549 	    !qctx->client->query.root_key_sentinel_not_ta)
   6550 	{
   6551 		return (ISC_FALSE);
   6552 	}
   6553 
   6554 	/*
   6555 	 * We only care about the query if 'result' indicates we have a cached
   6556 	 * answer.
   6557 	 */
   6558 	switch (result) {
   6559 	case ISC_R_SUCCESS:
   6560 	case DNS_R_CNAME:
   6561 	case DNS_R_DNAME:
   6562 	case DNS_R_NCACHENXDOMAIN:
   6563 	case DNS_R_NCACHENXRRSET:
   6564 		break;
   6565 	default:
   6566 		return (ISC_FALSE);
   6567 	}
   6568 
   6569 	/*
   6570 	 * Do we meet the specified conditions to return SERVFAIL?
   6571 	 */
   6572 	if (!qctx->is_zone &&
   6573 	    qctx->rdataset->trust == dns_trust_secure &&
   6574 	    ((qctx->client->query.root_key_sentinel_is_ta && !has_ta(qctx)) ||
   6575 	     (qctx->client->query.root_key_sentinel_not_ta && has_ta(qctx))))
   6576 	{
   6577 		return (ISC_TRUE);
   6578 	}
   6579 
   6580 	/*
   6581 	 * As special processing may only be triggered by the original QNAME,
   6582 	 * disable it after following a CNAME/DNAME.
   6583 	 */
   6584 	qctx->client->query.root_key_sentinel_is_ta = ISC_FALSE;
   6585 	qctx->client->query.root_key_sentinel_not_ta = ISC_FALSE;
   6586 
   6587 	return (ISC_FALSE);
   6588 }
   6589 
   6590 /*%
   6591  * Continue after doing a database lookup or returning from
   6592  * recursion, and call out to the next function depending on the
   6593  * result from the search.
   6594  */
   6595 static isc_result_t
   6596 query_gotanswer(query_ctx_t *qctx, isc_result_t result) {
   6597 	char errmsg[256];
   6598 
   6599 	CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer");
   6600 
   6601 	if (query_checkrrl(qctx, result) != ISC_R_SUCCESS) {
   6602 		return (query_done(qctx));
   6603 	}
   6604 
   6605 	if (!RECURSING(qctx->client) &&
   6606 	    !dns_name_equal(qctx->client->query.qname, dns_rootname))
   6607 	{
   6608 		result = query_checkrpz(qctx, result);
   6609 		if (result == ISC_R_COMPLETE)
   6610 			return (query_done(qctx));
   6611 	}
   6612 
   6613 	/*
   6614 	 * If required, handle special "root-key-sentinel-is-ta-<keyid>" and
   6615 	 * "root-key-sentinel-not-ta-<keyid>" labels by returning SERVFAIL.
   6616 	 */
   6617 	if (root_key_sentinel_return_servfail(qctx, result)) {
   6618 		/*
   6619 		 * Don't record this response in the SERVFAIL cache.
   6620 		 */
   6621 		qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
   6622 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   6623 		return (query_done(qctx));
   6624 	}
   6625 
   6626 	switch (result) {
   6627 	case ISC_R_SUCCESS:
   6628 		return (query_prepresponse(qctx));
   6629 
   6630 	case DNS_R_GLUE:
   6631 	case DNS_R_ZONECUT:
   6632 		INSIST(qctx->is_zone);
   6633 		qctx->authoritative = ISC_FALSE;
   6634 		return (query_prepresponse(qctx));
   6635 
   6636 	case ISC_R_NOTFOUND:
   6637 		return (query_notfound(qctx));
   6638 
   6639 	case DNS_R_DELEGATION:
   6640 		return (query_delegation(qctx));
   6641 
   6642 	case DNS_R_EMPTYNAME:
   6643 		return (query_nodata(qctx, DNS_R_EMPTYNAME));
   6644 	case DNS_R_NXRRSET:
   6645 		return (query_nodata(qctx, DNS_R_NXRRSET));
   6646 
   6647 	case DNS_R_EMPTYWILD:
   6648 		return (query_nxdomain(qctx, ISC_TRUE));
   6649 
   6650 	case DNS_R_NXDOMAIN:
   6651 		return (query_nxdomain(qctx, ISC_FALSE));
   6652 
   6653 	case DNS_R_COVERINGNSEC:
   6654 		return (query_coveringnsec(qctx));
   6655 
   6656 	case DNS_R_NCACHENXDOMAIN:
   6657 		result = query_redirect(qctx);
   6658 		if (result != ISC_R_COMPLETE)
   6659 			return (result);
   6660 		return (query_ncache(qctx, DNS_R_NCACHENXDOMAIN));
   6661 
   6662 	case DNS_R_NCACHENXRRSET:
   6663 		return (query_ncache(qctx, DNS_R_NCACHENXRRSET));
   6664 
   6665 	case DNS_R_CNAME:
   6666 		return (query_cname(qctx));
   6667 
   6668 	case DNS_R_DNAME:
   6669 		return (query_dname(qctx));
   6670 
   6671 	default:
   6672 		/*
   6673 		 * Something has gone wrong.
   6674 		 */
   6675 		snprintf(errmsg, sizeof(errmsg) - 1,
   6676 			 "query_gotanswer: unexpected error: %s",
   6677 			 isc_result_totext(result));
   6678 		CCTRACE(ISC_LOG_ERROR, errmsg);
   6679 		if (qctx->resuming) {
   6680 			qctx->want_stale = ISC_TRUE;
   6681 		} else {
   6682 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   6683 		}
   6684 		return (query_done(qctx));
   6685 	}
   6686 }
   6687 
   6688 static void
   6689 query_addnoqnameproof(query_ctx_t *qctx) {
   6690 	ns_client_t *client = qctx->client;
   6691 	isc_buffer_t *dbuf, b;
   6692 	dns_name_t *fname = NULL;
   6693 	dns_rdataset_t *neg = NULL, *negsig = NULL;
   6694 	isc_result_t result = ISC_R_NOMEMORY;
   6695 
   6696 	CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof");
   6697 
   6698 	if (qctx->noqname == NULL) {
   6699 		return;
   6700 	}
   6701 
   6702 	dbuf = query_getnamebuf(client);
   6703 	if (dbuf == NULL) {
   6704 		goto cleanup;
   6705 	}
   6706 
   6707 	fname = query_newname(client, dbuf, &b);
   6708 	neg = query_newrdataset(client);
   6709 	negsig = query_newrdataset(client);
   6710 	if (fname == NULL || neg == NULL || negsig == NULL) {
   6711 		goto cleanup;
   6712 	}
   6713 
   6714 	result = dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig);
   6715 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6716 
   6717 	query_addrrset(client, &fname, &neg, &negsig, dbuf,
   6718 		       DNS_SECTION_AUTHORITY);
   6719 
   6720 	if ((qctx->noqname->attributes & DNS_RDATASETATTR_CLOSEST) == 0) {
   6721 		goto cleanup;
   6722 	}
   6723 
   6724 	if (fname == NULL) {
   6725 		dbuf = query_getnamebuf(client);
   6726 		if (dbuf == NULL)
   6727 			goto cleanup;
   6728 		fname = query_newname(client, dbuf, &b);
   6729 	}
   6730 
   6731 	if (neg == NULL) {
   6732 		neg = query_newrdataset(client);
   6733 	} else if (dns_rdataset_isassociated(neg)) {
   6734 		dns_rdataset_disassociate(neg);
   6735 	}
   6736 
   6737 	if (negsig == NULL) {
   6738 		negsig = query_newrdataset(client);
   6739 	} else if (dns_rdataset_isassociated(negsig)) {
   6740 		dns_rdataset_disassociate(negsig);
   6741 	}
   6742 
   6743 	if (fname == NULL || neg == NULL || negsig == NULL)
   6744 		goto cleanup;
   6745 	result = dns_rdataset_getclosest(qctx->noqname, fname, neg, negsig);
   6746 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6747 
   6748 	query_addrrset(client, &fname, &neg, &negsig, dbuf,
   6749 		       DNS_SECTION_AUTHORITY);
   6750 
   6751  cleanup:
   6752 	if (neg != NULL) {
   6753 		query_putrdataset(client, &neg);
   6754 	}
   6755 	if (negsig != NULL) {
   6756 		query_putrdataset(client, &negsig);
   6757 	}
   6758 	if (fname != NULL) {
   6759 		query_releasename(client, &fname);
   6760 	}
   6761 }
   6762 
   6763 /*%
   6764  * Build the response for a query for type ANY.
   6765  */
   6766 static isc_result_t
   6767 query_respond_any(query_ctx_t *qctx) {
   6768 	dns_name_t *tname;
   6769 	int rdatasets_found = 0;
   6770 	dns_rdatasetiter_t *rdsiter = NULL;
   6771 	isc_result_t result;
   6772 	dns_rdatatype_t onetype = 0; 	/* type to use for minimal-any */
   6773 	isc_boolean_t have_aaaa, have_a, have_sig;
   6774 
   6775 	/*
   6776 	 * If we are not authoritative, assume there is an A record
   6777 	 * even in if it is not in our cache.  This assumption could
   6778 	 * be wrong but it is a good bet.
   6779 	 */
   6780 	have_aaaa = ISC_FALSE;
   6781 	have_a = !qctx->authoritative;
   6782 	have_sig = ISC_FALSE;
   6783 
   6784 	result = dns_db_allrdatasets(qctx->db, qctx->node,
   6785 				     qctx->version, 0, &rdsiter);
   6786 	if (result != ISC_R_SUCCESS) {
   6787 		CCTRACE(ISC_LOG_ERROR,
   6788 		       "query_respond_any: allrdatasets failed");
   6789 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   6790 		return (query_done(qctx));
   6791 	}
   6792 
   6793 	/*
   6794 	 * Calling query_addrrset() with a non-NULL dbuf is going
   6795 	 * to either keep or release the name.  We don't want it to
   6796 	 * release fname, since we may have to call query_addrrset()
   6797 	 * more than once.  That means we have to call query_keepname()
   6798 	 * now, and pass a NULL dbuf to query_addrrset().
   6799 	 *
   6800 	 * If we do a query_addrrset() below, we must set qctx->fname to
   6801 	 * NULL before leaving this block, otherwise we might try to
   6802 	 * cleanup qctx->fname even though we're using it!
   6803 	 */
   6804 	query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   6805 	tname = qctx->fname;
   6806 
   6807 	result = dns_rdatasetiter_first(rdsiter);
   6808 	while (result == ISC_R_SUCCESS) {
   6809 		dns_rdatasetiter_current(rdsiter, qctx->rdataset);
   6810 		/*
   6811 		 * Notice the presence of A and AAAAs so
   6812 		 * that AAAAs can be hidden from IPv4 clients.
   6813 		 */
   6814 		if (qctx->client->filter_aaaa != dns_aaaa_ok) {
   6815 			if (qctx->rdataset->type == dns_rdatatype_aaaa)
   6816 				have_aaaa = ISC_TRUE;
   6817 			else if (qctx->rdataset->type == dns_rdatatype_a)
   6818 				have_a = ISC_TRUE;
   6819 		}
   6820 
   6821 		/*
   6822 		 * We found an NS RRset; no need to add one later.
   6823 		 */
   6824 		if (qctx->qtype == dns_rdatatype_any &&
   6825 		    qctx->rdataset->type == dns_rdatatype_ns)
   6826 		{
   6827 			qctx->answer_has_ns = ISC_TRUE;
   6828 		}
   6829 
   6830 		/*
   6831 		 * Note: if we're in this function, then qctx->type
   6832 		 * is guaranteed to be ANY, but qctx->qtype (i.e. the
   6833 		 * original type requested) might have been RRSIG or
   6834 		 * SIG; we need to check for that.
   6835 		 */
   6836 		if (qctx->is_zone && qctx->qtype == dns_rdatatype_any &&
   6837 		    !dns_db_issecure(qctx->db) &&
   6838 		    dns_rdatatype_isdnssec(qctx->rdataset->type))
   6839 		{
   6840 			/*
   6841 			 * The zone is transitioning from insecure
   6842 			 * to secure. Hide the dnssec records from
   6843 			 * ANY queries.
   6844 			 */
   6845 			dns_rdataset_disassociate(qctx->rdataset);
   6846 		} else if (qctx->client->view->minimal_any &&
   6847 			   !TCP(qctx->client) && !WANTDNSSEC(qctx->client) &&
   6848 			   qctx->qtype == dns_rdatatype_any &&
   6849 			   (qctx->rdataset->type == dns_rdatatype_sig ||
   6850 			    qctx->rdataset->type == dns_rdatatype_rrsig))
   6851 		{
   6852 			CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: "
   6853 			       "minimal-any skip signature");
   6854 			dns_rdataset_disassociate(qctx->rdataset);
   6855 		} else if (qctx->client->view->minimal_any &&
   6856 			   !TCP(qctx->client) && onetype != 0 &&
   6857 			   qctx->rdataset->type != onetype &&
   6858 			   qctx->rdataset->covers != onetype)
   6859 		{
   6860 			CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: "
   6861 			       "minimal-any skip rdataset");
   6862 			dns_rdataset_disassociate(qctx->rdataset);
   6863 		} else if ((qctx->qtype == dns_rdatatype_any ||
   6864 			    qctx->rdataset->type == qctx->qtype) &&
   6865 			   qctx->rdataset->type != 0)
   6866 		{
   6867 			if (dns_rdatatype_isdnssec(qctx->rdataset->type))
   6868 				have_sig = ISC_TRUE;
   6869 
   6870 			if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client))
   6871 			{
   6872 				qctx->noqname = qctx->rdataset;
   6873 			} else {
   6874 				qctx->noqname = NULL;
   6875 			}
   6876 
   6877 			qctx->rpz_st = qctx->client->query.rpz_st;
   6878 			if (qctx->rpz_st != NULL)
   6879 				qctx->rdataset->ttl =
   6880 					ISC_MIN(qctx->rdataset->ttl,
   6881 						qctx->rpz_st->m.ttl);
   6882 
   6883 			if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
   6884 				dns_name_t *name;
   6885 				name = (qctx->fname != NULL)
   6886 					? qctx->fname
   6887 					: tname;
   6888 				query_prefetch(qctx->client, name,
   6889 					       qctx->rdataset);
   6890 			}
   6891 
   6892 			/*
   6893 			 * Remember the first RRtype we find so we
   6894 			 * can skip others with minimal-any.
   6895 			 */
   6896 			if (qctx->rdataset->type == dns_rdatatype_sig ||
   6897 			    qctx->rdataset->type == dns_rdatatype_rrsig)
   6898 				onetype = qctx->rdataset->covers;
   6899 			else
   6900 				onetype = qctx->rdataset->type;
   6901 
   6902 			query_addrrset(qctx->client,
   6903 				       (qctx->fname != NULL)
   6904 					? &qctx->fname
   6905 					: &tname,
   6906 				       &qctx->rdataset, NULL,
   6907 				       NULL, DNS_SECTION_ANSWER);
   6908 
   6909 			query_addnoqnameproof(qctx);
   6910 
   6911 			rdatasets_found++;
   6912 			INSIST(tname != NULL);
   6913 
   6914 			/*
   6915 			 * rdataset is non-NULL only in certain
   6916 			 * pathological cases involving DNAMEs.
   6917 			 */
   6918 			if (qctx->rdataset != NULL)
   6919 				query_putrdataset(qctx->client,
   6920 						  &qctx->rdataset);
   6921 
   6922 			qctx->rdataset = query_newrdataset(qctx->client);
   6923 			if (qctx->rdataset == NULL)
   6924 				break;
   6925 		} else {
   6926 			/*
   6927 			 * We're not interested in this rdataset.
   6928 			 */
   6929 			dns_rdataset_disassociate(qctx->rdataset);
   6930 		}
   6931 
   6932 		result = dns_rdatasetiter_next(rdsiter);
   6933 	}
   6934 
   6935 	/*
   6936 	 * Filter AAAAs if there is an A and there is no signature
   6937 	 * or we are supposed to break DNSSEC.
   6938 	 */
   6939 	if (qctx->client->filter_aaaa == dns_aaaa_break_dnssec)
   6940 		qctx->client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
   6941 	else if (qctx->client->filter_aaaa != dns_aaaa_ok &&
   6942 		 have_aaaa && have_a &&
   6943 		 (!have_sig || !WANTDNSSEC(qctx->client)))
   6944 		  qctx->client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
   6945 
   6946 	if (qctx->fname != NULL)
   6947 		dns_message_puttempname(qctx->client->message, &qctx->fname);
   6948 
   6949 	if (rdatasets_found == 0) {
   6950 		/*
   6951 		 * No matching rdatasets found in cache. If we were
   6952 		 * searching for RRSIG/SIG, that's probably okay;
   6953 		 * otherwise this is an error condition.
   6954 		 */
   6955 		if ((qctx->qtype == dns_rdatatype_rrsig ||
   6956 		     qctx->qtype == dns_rdatatype_sig) &&
   6957 		    result == ISC_R_NOMORE)
   6958 		{
   6959 			isc_buffer_t b;
   6960 			if (!qctx->is_zone) {
   6961 				qctx->authoritative = ISC_FALSE;
   6962 				dns_rdatasetiter_destroy(&rdsiter);
   6963 				qctx->client->attributes &= ~NS_CLIENTATTR_RA;
   6964 				query_addauth(qctx);
   6965 				return (query_done(qctx));
   6966 			}
   6967 
   6968 			if (qctx->qtype == dns_rdatatype_rrsig &&
   6969 			    dns_db_issecure(qctx->db)) {
   6970 				char namebuf[DNS_NAME_FORMATSIZE];
   6971 				dns_name_format(qctx->client->query.qname,
   6972 						namebuf,
   6973 						sizeof(namebuf));
   6974 				ns_client_log(qctx->client,
   6975 					      DNS_LOGCATEGORY_DNSSEC,
   6976 					      NS_LOGMODULE_QUERY,
   6977 					      ISC_LOG_WARNING,
   6978 					      "missing signature for %s",
   6979 					      namebuf);
   6980 			}
   6981 
   6982 			dns_rdatasetiter_destroy(&rdsiter);
   6983 			qctx->fname = query_newname(qctx->client,
   6984 						    qctx->dbuf, &b);
   6985 			return (query_sign_nodata(qctx));
   6986 		} else {
   6987 			CCTRACE(ISC_LOG_ERROR,
   6988 			       "query_respond_any: "
   6989 			       "no matching rdatasets in cache");
   6990 			result = DNS_R_SERVFAIL;
   6991 		}
   6992 	}
   6993 
   6994 	dns_rdatasetiter_destroy(&rdsiter);
   6995 	if (result != ISC_R_NOMORE) {
   6996 		CCTRACE(ISC_LOG_ERROR,
   6997 		       "query_respond_any: dns_rdatasetiter_destroy failed");
   6998 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   6999 	} else {
   7000 		query_addauth(qctx);
   7001 	}
   7002 
   7003 	return (query_done(qctx));
   7004 }
   7005 
   7006 /*
   7007  * Set the expire time, if requested, when answering from a
   7008  * slave or master zone.
   7009  */
   7010 static void
   7011 query_getexpire(query_ctx_t *qctx) {
   7012 	dns_zone_t *raw = NULL, *mayberaw;
   7013 
   7014 	if (qctx->zone == NULL || !qctx->is_zone ||
   7015 	    qctx->qtype != dns_rdatatype_soa ||
   7016 	    qctx->client->query.restarts != 0 ||
   7017 	    (qctx->client->attributes & NS_CLIENTATTR_WANTEXPIRE) == 0)
   7018 	{
   7019 		return;
   7020 	}
   7021 
   7022 	dns_zone_getraw(qctx->zone, &raw);
   7023 	mayberaw = (raw != NULL) ? raw : qctx->zone;
   7024 
   7025 	if (dns_zone_gettype(mayberaw) == dns_zone_slave) {
   7026 		isc_time_t expiretime;
   7027 		isc_uint32_t secs;
   7028 		dns_zone_getexpiretime(qctx->zone, &expiretime);
   7029 		secs = isc_time_seconds(&expiretime);
   7030 		if (secs >= qctx->client->now &&
   7031 		    qctx->result == ISC_R_SUCCESS)
   7032 		{
   7033 			qctx->client->attributes |=
   7034 				NS_CLIENTATTR_HAVEEXPIRE;
   7035 			qctx->client->expire = secs - qctx->client->now;
   7036 		}
   7037 	} else if (dns_zone_gettype(mayberaw) == dns_zone_master) {
   7038 		isc_result_t result;
   7039 		dns_rdata_t rdata = DNS_RDATA_INIT;
   7040 		dns_rdata_soa_t soa;
   7041 
   7042 		result = dns_rdataset_first(qctx->rdataset);
   7043 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   7044 
   7045 		dns_rdataset_current(qctx->rdataset, &rdata);
   7046 		result = dns_rdata_tostruct(&rdata, &soa, NULL);
   7047 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   7048 
   7049 		qctx->client->expire = soa.expire;
   7050 		qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
   7051 	}
   7052 
   7053 	if (raw != NULL) {
   7054 		dns_zone_detach(&raw);
   7055 	}
   7056 }
   7057 
   7058 /*
   7059  * Optionally hide AAAAs from IPv4 clients if there is an A.
   7060  *
   7061  * We add the AAAAs now, but might refuse to render them later
   7062  * after DNSSEC is figured out.
   7063  *
   7064  * This could be more efficient, but the whole idea is
   7065  * so fundamentally wrong, unavoidably inaccurate, and
   7066  * unneeded that it is best to keep it as short as possible.
   7067  */
   7068 static isc_result_t
   7069 query_filter_aaaa(query_ctx_t *qctx) {
   7070 	isc_result_t result;
   7071 
   7072 	if (qctx->client->filter_aaaa != dns_aaaa_break_dnssec &&
   7073 	    (qctx->client->filter_aaaa != dns_aaaa_filter ||
   7074 	     (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
   7075 	      dns_rdataset_isassociated(qctx->sigrdataset))))
   7076 	{
   7077 		return (ISC_R_COMPLETE);
   7078 	}
   7079 
   7080 	if (qctx->qtype == dns_rdatatype_aaaa) {
   7081 		dns_rdataset_t *trdataset;
   7082 		trdataset = query_newrdataset(qctx->client);
   7083 		result = dns_db_findrdataset(qctx->db, qctx->node,
   7084 					     qctx->version,
   7085 					     dns_rdatatype_a, 0,
   7086 					     qctx->client->now,
   7087 					     trdataset, NULL);
   7088 		if (dns_rdataset_isassociated(trdataset)) {
   7089 			dns_rdataset_disassociate(trdataset);
   7090 		}
   7091 		query_putrdataset(qctx->client, &trdataset);
   7092 
   7093 		/*
   7094 		 * We have an AAAA but the A is not in our cache.
   7095 		 * Assume any result other than DNS_R_DELEGATION
   7096 		 * or ISC_R_NOTFOUND means there is no A and
   7097 		 * so AAAAs are ok.
   7098 		 *
   7099 		 * Assume there is no A if we can't recurse
   7100 		 * for this client, although that could be
   7101 		 * the wrong answer. What else can we do?
   7102 		 * Besides, that we have the AAAA and are using
   7103 		 * this mechanism suggests that we care more
   7104 		 * about As than AAAAs and would have cached
   7105 		 * the A if it existed.
   7106 		 */
   7107 		if (result == ISC_R_SUCCESS) {
   7108 			qctx->client->attributes |=
   7109 				    NS_CLIENTATTR_FILTER_AAAA;
   7110 
   7111 		} else if (qctx->authoritative ||
   7112 			   !RECURSIONOK(qctx->client) ||
   7113 			   (result != DNS_R_DELEGATION &&
   7114 			    result != ISC_R_NOTFOUND))
   7115 		{
   7116 			qctx->client->attributes &=
   7117 				~NS_CLIENTATTR_FILTER_AAAA;
   7118 		} else {
   7119 			/*
   7120 			 * This is an ugly kludge to recurse
   7121 			 * for the A and discard the result.
   7122 			 *
   7123 			 * Continue to add the AAAA now.
   7124 			 * We'll make a note to not render it
   7125 			 * if the recursion for the A succeeds.
   7126 			 */
   7127 			INSIST(!REDIRECT(qctx->client));
   7128 			result = query_recurse(qctx->client,
   7129 					dns_rdatatype_a,
   7130 					qctx->client->query.qname,
   7131 					NULL, NULL, qctx->resuming);
   7132 			if (result == ISC_R_SUCCESS) {
   7133 				qctx->client->attributes |=
   7134 					NS_CLIENTATTR_FILTER_AAAA_RC;
   7135 				qctx->client->query.attributes |=
   7136 					NS_QUERYATTR_RECURSING;
   7137 			}
   7138 		}
   7139 	} else if (qctx->qtype == dns_rdatatype_a &&
   7140 		   (qctx->client->attributes &
   7141 		    NS_CLIENTATTR_FILTER_AAAA_RC) != 0)
   7142 	{
   7143 		qctx->client->attributes &= ~NS_CLIENTATTR_FILTER_AAAA_RC;
   7144 		qctx->client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
   7145 		qctx_clean(qctx);
   7146 
   7147 		return (query_done(qctx));
   7148 	}
   7149 
   7150 	return (ISC_R_COMPLETE);
   7151 }
   7152 
   7153 /*%
   7154  * Build a repsonse for a "normal" query, for a type other than ANY,
   7155  * for which we have an answer (either positive or negative).
   7156  */
   7157 static isc_result_t
   7158 query_respond(query_ctx_t *qctx) {
   7159 	dns_rdataset_t **sigrdatasetp = NULL;
   7160 	isc_result_t result;
   7161 
   7162 	/*
   7163 	 * If we have a zero ttl from the cache, refetch.
   7164 	 */
   7165 	if (!qctx->is_zone && !qctx->resuming && !STALE(qctx->rdataset) &&
   7166 	    qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client))
   7167 	{
   7168 		qctx_clean(qctx);
   7169 
   7170 		INSIST(!REDIRECT(qctx->client));
   7171 		result = query_recurse(qctx->client, qctx->qtype,
   7172 				       qctx->client->query.qname,
   7173 				       NULL, NULL, qctx->resuming);
   7174 		if (result == ISC_R_SUCCESS) {
   7175 			qctx->client->query.attributes |=
   7176 				NS_QUERYATTR_RECURSING;
   7177 			if (qctx->dns64)
   7178 				qctx->client->query.attributes |=
   7179 					NS_QUERYATTR_DNS64;
   7180 			if (qctx->dns64_exclude)
   7181 				qctx->client->query.attributes |=
   7182 				      NS_QUERYATTR_DNS64EXCLUDE;
   7183 		} else {
   7184 			RECURSE_ERROR(qctx, result);
   7185 		}
   7186 
   7187 		return (query_done(qctx));
   7188 	}
   7189 
   7190 	result = query_filter_aaaa(qctx);
   7191 	if (result != ISC_R_COMPLETE)
   7192 		return (result);
   7193 	/*
   7194 	 * Check to see if the AAAA RRset has non-excluded addresses
   7195 	 * in it.  If not look for a A RRset.
   7196 	 */
   7197 	INSIST(qctx->client->query.dns64_aaaaok == NULL);
   7198 
   7199 	if (qctx->qtype == dns_rdatatype_aaaa && !qctx->dns64_exclude &&
   7200 	    !ISC_LIST_EMPTY(qctx->client->view->dns64) &&
   7201 	    qctx->client->message->rdclass == dns_rdataclass_in &&
   7202 	    !dns64_aaaaok(qctx->client, qctx->rdataset, qctx->sigrdataset))
   7203 	{
   7204 		/*
   7205 		 * Look to see if there are A records for this name.
   7206 		 */
   7207 		qctx->client->query.dns64_ttl = qctx->rdataset->ttl;
   7208 		SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset);
   7209 		SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset);
   7210 		query_releasename(qctx->client, &qctx->fname);
   7211 		dns_db_detachnode(qctx->db, &qctx->node);
   7212 		qctx->type = qctx->qtype = dns_rdatatype_a;
   7213 		qctx->dns64_exclude = qctx->dns64 = ISC_TRUE;
   7214 
   7215 		return (query_lookup(qctx));
   7216 	}
   7217 
   7218 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
   7219 		sigrdatasetp = &qctx->sigrdataset;
   7220 	}
   7221 
   7222 	if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
   7223 		qctx->noqname = qctx->rdataset;
   7224 	} else {
   7225 		qctx->noqname = NULL;
   7226 	}
   7227 
   7228 	/*
   7229 	 * Special case NS handling
   7230 	 */
   7231 	if (qctx->is_zone && qctx->qtype == dns_rdatatype_ns) {
   7232 		/*
   7233 		 * We've already got an NS, no need to add one in
   7234 		 * the authority section
   7235 		 */
   7236 		if (dns_name_equal(qctx->client->query.qname,
   7237 				   dns_db_origin(qctx->db)))
   7238 		{
   7239 			qctx->answer_has_ns = ISC_TRUE;
   7240 		}
   7241 
   7242 		/*
   7243 		 * BIND 8 priming queries need the additional section.
   7244 		 */
   7245 		if (dns_name_equal(qctx->client->query.qname, dns_rootname)) {
   7246 			qctx->client->query.attributes &=
   7247 				~NS_QUERYATTR_NOADDITIONAL;
   7248 		}
   7249 	}
   7250 
   7251 	/*
   7252 	 * Set expire time
   7253 	 */
   7254 	query_getexpire(qctx);
   7255 
   7256 	if (qctx->dns64) {
   7257 		result = query_dns64(qctx);
   7258 		qctx->noqname = NULL;
   7259 		dns_rdataset_disassociate(qctx->rdataset);
   7260 		dns_message_puttemprdataset(qctx->client->message,
   7261 					    &qctx->rdataset);
   7262 		if (result == ISC_R_NOMORE) {
   7263 #ifndef dns64_bis_return_excluded_addresses
   7264 			if (qctx->dns64_exclude) {
   7265 				if (!qctx->is_zone)
   7266 					return (query_done(qctx));
   7267 				/*
   7268 				 * Add a fake SOA record.
   7269 				 */
   7270 				(void)query_addsoa(qctx, 600,
   7271 						   DNS_SECTION_AUTHORITY);
   7272 				return (query_done(qctx));
   7273 			}
   7274 #endif
   7275 			if (qctx->is_zone) {
   7276 				return (query_nodata(qctx, DNS_R_NXDOMAIN));
   7277 			} else {
   7278 				return (query_ncache(qctx, DNS_R_NXDOMAIN));
   7279 			}
   7280 		} else if (result != ISC_R_SUCCESS) {
   7281 			qctx->result = result;
   7282 			return (query_done(qctx));
   7283 		}
   7284 	} else if (qctx->client->query.dns64_aaaaok != NULL) {
   7285 		query_filter64(qctx);
   7286 		query_putrdataset(qctx->client, &qctx->rdataset);
   7287 	} else {
   7288 		if (!qctx->is_zone && RECURSIONOK(qctx->client))
   7289 			query_prefetch(qctx->client, qctx->fname,
   7290 				       qctx->rdataset);
   7291 		query_addrrset(qctx->client, &qctx->fname,
   7292 			       &qctx->rdataset, sigrdatasetp,
   7293 			       qctx->dbuf, DNS_SECTION_ANSWER);
   7294 	}
   7295 
   7296 	query_addnoqnameproof(qctx);
   7297 
   7298 	/*
   7299 	 * We shouldn't ever fail to add 'rdataset'
   7300 	 * because it's already in the answer.
   7301 	 */
   7302 	INSIST(qctx->rdataset == NULL);
   7303 
   7304 	query_addauth(qctx);
   7305 
   7306 	return (query_done(qctx));
   7307 }
   7308 
   7309 static isc_result_t
   7310 query_dns64(query_ctx_t *qctx) {
   7311 	ns_client_t *client = qctx->client;
   7312 	dns_aclenv_t *env = ns_interfacemgr_getaclenv(client->interface->mgr);
   7313 	dns_name_t *name, *mname;
   7314 	dns_rdata_t *dns64_rdata;
   7315 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7316 	dns_rdatalist_t *dns64_rdatalist;
   7317 	dns_rdataset_t *dns64_rdataset;
   7318 	dns_rdataset_t *mrdataset;
   7319 	isc_buffer_t *buffer;
   7320 	isc_region_t r;
   7321 	isc_result_t result;
   7322 	dns_view_t *view = client->view;
   7323 	isc_netaddr_t netaddr;
   7324 	dns_dns64_t *dns64;
   7325 	unsigned int flags = 0;
   7326 	const dns_section_t section = DNS_SECTION_ANSWER;
   7327 
   7328 	/*%
   7329 	 * To the current response for 'qctx->client', add the answer RRset
   7330 	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
   7331 	 * owner name '*namep', to the answer section, unless they are
   7332 	 * already there.  Also add any pertinent additional data.
   7333 	 *
   7334 	 * If 'qctx->dbuf' is not NULL, then 'qctx->fname' is the name
   7335 	 * whose data is stored 'qctx->dbuf'.  In this case,
   7336 	 * query_addrrset() guarantees that when it returns the name
   7337 	 * will either have been kept or released.
   7338 	 */
   7339 	CTRACE(ISC_LOG_DEBUG(3), "query_dns64");
   7340 
   7341 	qctx->qtype = qctx->type = dns_rdatatype_aaaa;
   7342 
   7343 	name = qctx->fname;
   7344 	mname = NULL;
   7345 	mrdataset = NULL;
   7346 	buffer = NULL;
   7347 	dns64_rdata = NULL;
   7348 	dns64_rdataset = NULL;
   7349 	dns64_rdatalist = NULL;
   7350 	result = dns_message_findname(client->message, section,
   7351 				      name, dns_rdatatype_aaaa,
   7352 				      qctx->rdataset->covers,
   7353 				      &mname, &mrdataset);
   7354 	if (result == ISC_R_SUCCESS) {
   7355 		/*
   7356 		 * We've already got an RRset of the given name and type.
   7357 		 * There's nothing else to do;
   7358 		 */
   7359 		CTRACE(ISC_LOG_DEBUG(3),
   7360 		       "query_dns64: dns_message_findname succeeded: done");
   7361 		if (qctx->dbuf != NULL)
   7362 			query_releasename(client, &qctx->fname);
   7363 		return (ISC_R_SUCCESS);
   7364 	} else if (result == DNS_R_NXDOMAIN) {
   7365 		/*
   7366 		 * The name doesn't exist.
   7367 		 */
   7368 		if (qctx->dbuf != NULL)
   7369 			query_keepname(client, name, qctx->dbuf);
   7370 		dns_message_addname(client->message, name, section);
   7371 		qctx->fname = NULL;
   7372 		mname = name;
   7373 	} else {
   7374 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
   7375 		if (qctx->dbuf != NULL)
   7376 			query_releasename(client, &qctx->fname);
   7377 	}
   7378 
   7379 	if (qctx->rdataset->trust != dns_trust_secure) {
   7380 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
   7381 	}
   7382 
   7383 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
   7384 
   7385 	result = isc_buffer_allocate(client->mctx, &buffer,
   7386 				     view->dns64cnt * 16 *
   7387 				     dns_rdataset_count(qctx->rdataset));
   7388 	if (result != ISC_R_SUCCESS)
   7389 		goto cleanup;
   7390 	result = dns_message_gettemprdataset(client->message,
   7391 					     &dns64_rdataset);
   7392 	if (result != ISC_R_SUCCESS)
   7393 		goto cleanup;
   7394 	result = dns_message_gettemprdatalist(client->message,
   7395 					      &dns64_rdatalist);
   7396 	if (result != ISC_R_SUCCESS)
   7397 		goto cleanup;
   7398 
   7399 	dns_rdatalist_init(dns64_rdatalist);
   7400 	dns64_rdatalist->rdclass = dns_rdataclass_in;
   7401 	dns64_rdatalist->type = dns_rdatatype_aaaa;
   7402 	if (client->query.dns64_ttl != ISC_UINT32_MAX)
   7403 		dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl,
   7404 					       client->query.dns64_ttl);
   7405 	else
   7406 		dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl, 600);
   7407 
   7408 	if (RECURSIONOK(client))
   7409 		flags |= DNS_DNS64_RECURSIVE;
   7410 
   7411 	/*
   7412 	 * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
   7413 	 * as this provides a easy way to see if the answer was signed.
   7414 	 */
   7415 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
   7416 	    dns_rdataset_isassociated(qctx->sigrdataset))
   7417 		flags |= DNS_DNS64_DNSSEC;
   7418 
   7419 	for (result = dns_rdataset_first(qctx->rdataset);
   7420 	     result == ISC_R_SUCCESS;
   7421 	     result = dns_rdataset_next(qctx->rdataset)) {
   7422 		for (dns64 = ISC_LIST_HEAD(client->view->dns64);
   7423 		     dns64 != NULL; dns64 = dns_dns64_next(dns64)) {
   7424 
   7425 			dns_rdataset_current(qctx->rdataset, &rdata);
   7426 			isc_buffer_availableregion(buffer, &r);
   7427 			INSIST(r.length >= 16);
   7428 			result = dns_dns64_aaaafroma(dns64, &netaddr,
   7429 						     client->signer, env, flags,
   7430 						     rdata.data, r.base);
   7431 			if (result != ISC_R_SUCCESS) {
   7432 				dns_rdata_reset(&rdata);
   7433 				continue;
   7434 			}
   7435 			isc_buffer_add(buffer, 16);
   7436 			isc_buffer_remainingregion(buffer, &r);
   7437 			isc_buffer_forward(buffer, 16);
   7438 			result = dns_message_gettemprdata(client->message,
   7439 							  &dns64_rdata);
   7440 			if (result != ISC_R_SUCCESS)
   7441 				goto cleanup;
   7442 			dns_rdata_init(dns64_rdata);
   7443 			dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
   7444 					     dns_rdatatype_aaaa, &r);
   7445 			ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
   7446 					link);
   7447 			dns64_rdata = NULL;
   7448 			dns_rdata_reset(&rdata);
   7449 		}
   7450 	}
   7451 	if (result != ISC_R_NOMORE)
   7452 		goto cleanup;
   7453 
   7454 	if (ISC_LIST_EMPTY(dns64_rdatalist->rdata))
   7455 		goto cleanup;
   7456 
   7457 	result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
   7458 	if (result != ISC_R_SUCCESS)
   7459 		goto cleanup;
   7460 	dns_rdataset_setownercase(dns64_rdataset, mname);
   7461 	client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
   7462 	dns64_rdataset->trust = qctx->rdataset->trust;
   7463 	query_addrdataset(client, section, mname, dns64_rdataset);
   7464 	dns64_rdataset = NULL;
   7465 	dns64_rdatalist = NULL;
   7466 	dns_message_takebuffer(client->message, &buffer);
   7467 	inc_stats(client, ns_statscounter_dns64);
   7468 	result = ISC_R_SUCCESS;
   7469 
   7470  cleanup:
   7471 	if (buffer != NULL)
   7472 		isc_buffer_free(&buffer);
   7473 
   7474 	if (dns64_rdata != NULL)
   7475 		dns_message_puttemprdata(client->message, &dns64_rdata);
   7476 
   7477 	if (dns64_rdataset != NULL)
   7478 		dns_message_puttemprdataset(client->message, &dns64_rdataset);
   7479 
   7480 	if (dns64_rdatalist != NULL) {
   7481 		for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
   7482 		     dns64_rdata != NULL;
   7483 		     dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
   7484 		{
   7485 			ISC_LIST_UNLINK(dns64_rdatalist->rdata,
   7486 					dns64_rdata, link);
   7487 			dns_message_puttemprdata(client->message, &dns64_rdata);
   7488 		}
   7489 		dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
   7490 	}
   7491 
   7492 	CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done");
   7493 	return (result);
   7494 }
   7495 
   7496 static void
   7497 query_filter64(query_ctx_t *qctx) {
   7498 	ns_client_t *client = qctx->client;
   7499 	dns_name_t *name, *mname;
   7500 	dns_rdata_t *myrdata;
   7501 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7502 	dns_rdatalist_t *myrdatalist;
   7503 	dns_rdataset_t *myrdataset;
   7504 	isc_buffer_t *buffer;
   7505 	isc_region_t r;
   7506 	isc_result_t result;
   7507 	unsigned int i;
   7508 	const dns_section_t section = DNS_SECTION_ANSWER;
   7509 
   7510 	CTRACE(ISC_LOG_DEBUG(3), "query_filter64");
   7511 
   7512 	INSIST(client->query.dns64_aaaaok != NULL);
   7513 	INSIST(client->query.dns64_aaaaoklen ==
   7514 	       dns_rdataset_count(qctx->rdataset));
   7515 
   7516 	name = qctx->fname;
   7517 	mname = NULL;
   7518 	buffer = NULL;
   7519 	myrdata = NULL;
   7520 	myrdataset = NULL;
   7521 	myrdatalist = NULL;
   7522 	result = dns_message_findname(client->message, section,
   7523 				      name, dns_rdatatype_aaaa,
   7524 				      qctx->rdataset->covers,
   7525 				      &mname, &myrdataset);
   7526 	if (result == ISC_R_SUCCESS) {
   7527 		/*
   7528 		 * We've already got an RRset of the given name and type.
   7529 		 * There's nothing else to do;
   7530 		 */
   7531 		CTRACE(ISC_LOG_DEBUG(3),
   7532 		       "query_filter64: dns_message_findname succeeded: done");
   7533 		if (qctx->dbuf != NULL)
   7534 			query_releasename(client, &qctx->fname);
   7535 		return;
   7536 	} else if (result == DNS_R_NXDOMAIN) {
   7537 		mname = name;
   7538 		qctx->fname = NULL;
   7539 	} else {
   7540 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
   7541 		if (qctx->dbuf != NULL)
   7542 			query_releasename(client, &qctx->fname);
   7543 		qctx->dbuf = NULL;
   7544 	}
   7545 
   7546 	if (qctx->rdataset->trust != dns_trust_secure) {
   7547 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
   7548 	}
   7549 
   7550 	result = isc_buffer_allocate(client->mctx, &buffer,
   7551 				     16 * dns_rdataset_count(qctx->rdataset));
   7552 	if (result != ISC_R_SUCCESS)
   7553 		goto cleanup;
   7554 	result = dns_message_gettemprdataset(client->message, &myrdataset);
   7555 	if (result != ISC_R_SUCCESS)
   7556 		goto cleanup;
   7557 	result = dns_message_gettemprdatalist(client->message, &myrdatalist);
   7558 	if (result != ISC_R_SUCCESS)
   7559 		goto cleanup;
   7560 
   7561 	dns_rdatalist_init(myrdatalist);
   7562 	myrdatalist->rdclass = dns_rdataclass_in;
   7563 	myrdatalist->type = dns_rdatatype_aaaa;
   7564 	myrdatalist->ttl = qctx->rdataset->ttl;
   7565 
   7566 	i = 0;
   7567 	for (result = dns_rdataset_first(qctx->rdataset);
   7568 	     result == ISC_R_SUCCESS;
   7569 	     result = dns_rdataset_next(qctx->rdataset)) {
   7570 		if (!client->query.dns64_aaaaok[i++])
   7571 			continue;
   7572 		dns_rdataset_current(qctx->rdataset, &rdata);
   7573 		INSIST(rdata.length == 16);
   7574 		isc_buffer_putmem(buffer, rdata.data, rdata.length);
   7575 		isc_buffer_remainingregion(buffer, &r);
   7576 		isc_buffer_forward(buffer, rdata.length);
   7577 		result = dns_message_gettemprdata(client->message, &myrdata);
   7578 		if (result != ISC_R_SUCCESS)
   7579 			goto cleanup;
   7580 		dns_rdata_init(myrdata);
   7581 		dns_rdata_fromregion(myrdata, dns_rdataclass_in,
   7582 				     dns_rdatatype_aaaa, &r);
   7583 		ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
   7584 		myrdata = NULL;
   7585 		dns_rdata_reset(&rdata);
   7586 	}
   7587 	if (result != ISC_R_NOMORE)
   7588 		goto cleanup;
   7589 
   7590 	result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
   7591 	if (result != ISC_R_SUCCESS)
   7592 		goto cleanup;
   7593 	dns_rdataset_setownercase(myrdataset, name);
   7594 	client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
   7595 	if (mname == name) {
   7596 		if (qctx->dbuf != NULL)
   7597 			query_keepname(client, name, qctx->dbuf);
   7598 		dns_message_addname(client->message, name,
   7599 				    section);
   7600 		qctx->dbuf = NULL;
   7601 	}
   7602 	myrdataset->trust = qctx->rdataset->trust;
   7603 	query_addrdataset(client, section, mname, myrdataset);
   7604 	myrdataset = NULL;
   7605 	myrdatalist = NULL;
   7606 	dns_message_takebuffer(client->message, &buffer);
   7607 
   7608  cleanup:
   7609 	if (buffer != NULL)
   7610 		isc_buffer_free(&buffer);
   7611 
   7612 	if (myrdata != NULL)
   7613 		dns_message_puttemprdata(client->message, &myrdata);
   7614 
   7615 	if (myrdataset != NULL)
   7616 		dns_message_puttemprdataset(client->message, &myrdataset);
   7617 
   7618 	if (myrdatalist != NULL) {
   7619 		for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
   7620 		     myrdata != NULL;
   7621 		     myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
   7622 		{
   7623 			ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
   7624 			dns_message_puttemprdata(client->message, &myrdata);
   7625 		}
   7626 		dns_message_puttemprdatalist(client->message, &myrdatalist);
   7627 	}
   7628 	if (qctx->dbuf != NULL)
   7629 		query_releasename(client, &name);
   7630 
   7631 	CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done");
   7632 }
   7633 
   7634 /*%
   7635  * Handle the case of a name not being found in a database lookup.
   7636  * Called from query_gotanswer(). Passes off processing to
   7637  * query_delegation() for a root referral if appropriate.
   7638  */
   7639 static isc_result_t
   7640 query_notfound(query_ctx_t *qctx) {
   7641 	isc_result_t result;
   7642 
   7643 	INSIST(!qctx->is_zone);
   7644 
   7645 	if (qctx->db != NULL)
   7646 		dns_db_detach(&qctx->db);
   7647 
   7648 	/*
   7649 	 * If the cache doesn't even have the root NS,
   7650 	 * try to get that from the hints DB.
   7651 	 */
   7652 	if (qctx->client->view->hints != NULL) {
   7653 		dns_clientinfomethods_t cm;
   7654 		dns_clientinfo_t ci;
   7655 
   7656 		dns_clientinfomethods_init(&cm, ns_client_sourceip);
   7657 		dns_clientinfo_init(&ci, qctx->client, NULL);
   7658 
   7659 		dns_db_attach(qctx->client->view->hints, &qctx->db);
   7660 		result = dns_db_findext(qctx->db, dns_rootname,
   7661 					NULL, dns_rdatatype_ns,
   7662 					0, qctx->client->now, &qctx->node,
   7663 					qctx->fname, &cm, &ci,
   7664 					qctx->rdataset, qctx->sigrdataset);
   7665 	} else {
   7666 		/* We have no hints. */
   7667 		result = ISC_R_FAILURE;
   7668 	}
   7669 	if (result != ISC_R_SUCCESS) {
   7670 		/*
   7671 		 * Nonsensical root hints may require cleanup.
   7672 		 */
   7673 		qctx_clean(qctx);
   7674 
   7675 		/*
   7676 		 * We don't have any root server hints, but
   7677 		 * we may have working forwarders, so try to
   7678 		 * recurse anyway.
   7679 		 */
   7680 		if (RECURSIONOK(qctx->client)) {
   7681 			INSIST(!REDIRECT(qctx->client));
   7682 			result = query_recurse(qctx->client, qctx->qtype,
   7683 					       qctx->client->query.qname,
   7684 					       NULL, NULL, qctx->resuming);
   7685 			if (result == ISC_R_SUCCESS) {
   7686 				qctx->client->query.attributes |=
   7687 						NS_QUERYATTR_RECURSING;
   7688 				if (qctx->dns64)
   7689 					qctx->client->query.attributes |=
   7690 						NS_QUERYATTR_DNS64;
   7691 				if (qctx->dns64_exclude)
   7692 					qctx->client->query.attributes |=
   7693 						NS_QUERYATTR_DNS64EXCLUDE;
   7694 			} else
   7695 				RECURSE_ERROR(qctx, result);
   7696 			return (query_done(qctx));
   7697 		} else {
   7698 			/* Unable to give root server referral. */
   7699 			CCTRACE(ISC_LOG_ERROR,
   7700 				"unable to give root server referral");
   7701 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   7702 			return (query_done(qctx));
   7703 		}
   7704 	}
   7705 
   7706 	return (query_delegation(qctx));
   7707 }
   7708 
   7709 /*%
   7710  * Handle a delegation response from an authoritative lookup. This
   7711  * may trigger additional lookups, e.g. from the cache database to
   7712  * see if we have a better answer; if that is not allowed, return the
   7713  * delegation to the client and call query_done().
   7714  */
   7715 static isc_result_t
   7716 query_zone_delegation(query_ctx_t *qctx) {
   7717 	isc_result_t result;
   7718 	dns_rdataset_t **sigrdatasetp = NULL;
   7719 	isc_boolean_t detach = ISC_FALSE;
   7720 
   7721 	/*
   7722 	 * If the query type is DS, look to see if we are
   7723 	 * authoritative for the child zone
   7724 	 */
   7725 	if (!RECURSIONOK(qctx->client) &&
   7726 	    (qctx->options & DNS_GETDB_NOEXACT) != 0 &&
   7727 	    qctx->qtype == dns_rdatatype_ds)
   7728 	{
   7729 		dns_db_t *tdb = NULL;
   7730 		dns_zone_t *tzone = NULL;
   7731 		dns_dbversion_t *tversion = NULL;
   7732 		result = query_getzonedb(qctx->client,
   7733 					 qctx->client->query.qname,
   7734 					 qctx->qtype,
   7735 					 DNS_GETDB_PARTIAL,
   7736 					 &tzone, &tdb,
   7737 					 &tversion);
   7738 		if (result != ISC_R_SUCCESS) {
   7739 			if (tdb != NULL)
   7740 				dns_db_detach(&tdb);
   7741 			if (tzone != NULL)
   7742 				dns_zone_detach(&tzone);
   7743 		} else {
   7744 			qctx->options &= ~DNS_GETDB_NOEXACT;
   7745 			query_putrdataset(qctx->client,
   7746 					  &qctx->rdataset);
   7747 			if (qctx->sigrdataset != NULL)
   7748 				query_putrdataset(qctx->client,
   7749 						  &qctx->sigrdataset);
   7750 			if (qctx->fname != NULL)
   7751 				query_releasename(qctx->client,
   7752 						  &qctx->fname);
   7753 			if (qctx->node != NULL)
   7754 				dns_db_detachnode(qctx->db,
   7755 						  &qctx->node);
   7756 			if (qctx->db != NULL)
   7757 				dns_db_detach(&qctx->db);
   7758 			if (qctx->zone != NULL)
   7759 				dns_zone_detach(&qctx->zone);
   7760 			qctx->version = NULL;
   7761 			RESTORE(qctx->version, tversion);
   7762 			RESTORE(qctx->db, tdb);
   7763 			RESTORE(qctx->zone, tzone);
   7764 			qctx->authoritative = ISC_TRUE;
   7765 
   7766 			return (query_lookup(qctx));
   7767 		}
   7768 	}
   7769 
   7770 	if (USECACHE(qctx->client) && RECURSIONOK(qctx->client)) {
   7771 		/*
   7772 		 * We might have a better answer or delegation in the
   7773 		 * cache.  We'll remember the current values of fname,
   7774 		 * rdataset, and sigrdataset.  We'll then go looking for
   7775 		 * QNAME in the cache.  If we find something better, we'll
   7776 		 * use it instead. If not, then query_lookup() calls
   7777 		 * query_notfound() which calls query_delegation(), and
   7778 		 * we'll restore these values there.
   7779 		 */
   7780 		query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   7781 		dns_db_detachnode(qctx->db, &qctx->node);
   7782 		SAVE(qctx->zdb, qctx->db);
   7783 		SAVE(qctx->zfname, qctx->fname);
   7784 		SAVE(qctx->zversion, qctx->version);
   7785 		SAVE(qctx->zrdataset, qctx->rdataset);
   7786 		SAVE(qctx->zsigrdataset, qctx->sigrdataset);
   7787 		dns_db_attach(qctx->client->view->cachedb, &qctx->db);
   7788 		qctx->is_zone = ISC_FALSE;
   7789 
   7790 		return (query_lookup(qctx));
   7791 	}
   7792 
   7793 	/*
   7794 	 * qctx->fname could be released in
   7795 	 * query_addrrset(), so save a copy of it
   7796 	 * here in case we need it
   7797 	 */
   7798 	dns_fixedname_init(&qctx->dsname);
   7799 	dns_name_copy(qctx->fname, dns_fixedname_name(&qctx->dsname), NULL);
   7800 
   7801 	/*
   7802 	 * If we don't have a cache, this is the best
   7803 	 * answer.
   7804 	 *
   7805 	 * If the client is making a nonrecursive
   7806 	 * query we always give out the authoritative
   7807 	 * delegation.  This way even if we get
   7808 	 * junk in our cache, we won't fail in our
   7809 	 * role as the delegating authority if another
   7810 	 * nameserver asks us about a delegated
   7811 	 * subzone.
   7812 	 *
   7813 	 * We enable the retrieval of glue for this
   7814 	 * database by setting client->query.gluedb.
   7815 	 */
   7816 	if (qctx->db != NULL && qctx->client->query.gluedb == NULL) {
   7817 		dns_db_attach(qctx->db, &qctx->client->query.gluedb);
   7818 		detach = ISC_TRUE;
   7819 	}
   7820 	qctx->client->query.isreferral = ISC_TRUE;
   7821 	/*
   7822 	 * We must ensure NOADDITIONAL is off,
   7823 	 * because the generation of
   7824 	 * additional data is required in
   7825 	 * delegations.
   7826 	 */
   7827 	qctx->client->query.attributes &=
   7828 		~NS_QUERYATTR_NOADDITIONAL;
   7829 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL)
   7830 		sigrdatasetp = &qctx->sigrdataset;
   7831 	query_addrrset(qctx->client, &qctx->fname,
   7832 		       &qctx->rdataset, sigrdatasetp,
   7833 		       qctx->dbuf, DNS_SECTION_AUTHORITY);
   7834 	if (detach) {
   7835 		dns_db_detach(&qctx->client->query.gluedb);
   7836 	}
   7837 
   7838 	/*
   7839 	 * Add a DS if needed
   7840 	 */
   7841 	query_addds(qctx);
   7842 
   7843 	return (query_done(qctx));
   7844 }
   7845 
   7846 /*%
   7847  * Handle delegation responses, including root referrals.
   7848  *
   7849  * If the delegation was returned from authoritative data,
   7850  * call query_zone_delgation().  Otherwise, we can start
   7851  * recursion if allowed; or else return the delegation to the
   7852  * client and call query_done().
   7853  */
   7854 static isc_result_t
   7855 query_delegation(query_ctx_t *qctx) {
   7856 	isc_result_t result;
   7857 	dns_rdataset_t **sigrdatasetp = NULL;
   7858 	isc_boolean_t detach = ISC_FALSE;
   7859 
   7860 	qctx->authoritative = ISC_FALSE;
   7861 
   7862 	if (qctx->is_zone) {
   7863 		return (query_zone_delegation(qctx));
   7864 	}
   7865 
   7866 	if (qctx->zfname != NULL &&
   7867 	    (!dns_name_issubdomain(qctx->fname, qctx->zfname) ||
   7868 	     (qctx->is_staticstub_zone &&
   7869 	      dns_name_equal(qctx->fname, qctx->zfname))))
   7870 	{
   7871 		/*
   7872 		 * In the following cases use "authoritative"
   7873 		 * data instead of the cache delegation:
   7874 		 * 1. We've already got a delegation from
   7875 		 *    authoritative data, and it is better
   7876 		 *    than what we found in the cache.
   7877 		 *    (See the comment above.)
   7878 		 * 2. The query name matches the origin name
   7879 		 *    of a static-stub zone.  This needs to be
   7880 		 *    considered for the case where the NS of
   7881 		 *    the static-stub zone and the cached NS
   7882 		 *    are different.  We still need to contact
   7883 		 *    the nameservers configured in the
   7884 		 *    static-stub zone.
   7885 		 */
   7886 		query_releasename(qctx->client, &qctx->fname);
   7887 
   7888 		/*
   7889 		 * We've already done query_keepname() on
   7890 		 * qctx->zfname, so we must set dbuf to NULL to
   7891 		 * prevent query_addrrset() from trying to
   7892 		 * call query_keepname() again.
   7893 		 */
   7894 		qctx->dbuf = NULL;
   7895 		query_putrdataset(qctx->client, &qctx->rdataset);
   7896 		if (qctx->sigrdataset != NULL)
   7897 			query_putrdataset(qctx->client,
   7898 					  &qctx->sigrdataset);
   7899 		qctx->version = NULL;
   7900 
   7901 		RESTORE(qctx->fname, qctx->zfname);
   7902 		RESTORE(qctx->version, qctx->zversion);
   7903 		RESTORE(qctx->rdataset, qctx->zrdataset);
   7904 		RESTORE(qctx->sigrdataset, qctx->zsigrdataset);
   7905 
   7906 		/*
   7907 		 * We don't clean up zdb here because we
   7908 		 * may still need it.  It will get cleaned
   7909 		 * up by the main cleanup code in query_done().
   7910 		 */
   7911 	}
   7912 
   7913 	if (RECURSIONOK(qctx->client)) {
   7914 		/*
   7915 		 * We have a delegation and recursion is allowed,
   7916 		 * so we call query_recurse() to follow it.
   7917 		 * This phase of the query processing is done;
   7918 		 * we'll resume via fetch_callback() and
   7919 		 * query_resume() when the recursion is complete.
   7920 		 */
   7921 		dns_name_t *qname = qctx->client->query.qname;
   7922 
   7923 		INSIST(!REDIRECT(qctx->client));
   7924 
   7925 		if (dns_rdatatype_atparent(qctx->type)) {
   7926 			/*
   7927 			 * Parent is recursive for this rdata
   7928 			 * type (i.e., DS)
   7929 			 */
   7930 			result = query_recurse(qctx->client,
   7931 					       qctx->qtype, qname,
   7932 					       NULL, NULL,
   7933 					       qctx->resuming);
   7934 		} else if (qctx->dns64) {
   7935 			/*
   7936 			 * Look up an A record so we can
   7937 			 * synthesize DNS64
   7938 			 */
   7939 			result = query_recurse(qctx->client,
   7940 					       dns_rdatatype_a, qname,
   7941 					       NULL, NULL,
   7942 					       qctx->resuming);
   7943 		} else {
   7944 			/*
   7945 			 * Any other recursion
   7946 			 */
   7947 			result = query_recurse(qctx->client,
   7948 					       qctx->qtype, qname,
   7949 					       qctx->fname,
   7950 					       qctx->rdataset,
   7951 					       qctx->resuming);
   7952 		}
   7953 		if (result == ISC_R_SUCCESS) {
   7954 			qctx->client->query.attributes |=
   7955 				NS_QUERYATTR_RECURSING;
   7956 			if (qctx->dns64)
   7957 				qctx->client->query.attributes |=
   7958 					NS_QUERYATTR_DNS64;
   7959 			if (qctx->dns64_exclude)
   7960 				qctx->client->query.attributes |=
   7961 				      NS_QUERYATTR_DNS64EXCLUDE;
   7962 		} else if (result == DNS_R_DUPLICATE || result == DNS_R_DROP) {
   7963 			QUERY_ERROR(qctx, result);
   7964 		} else {
   7965 			RECURSE_ERROR(qctx, result);
   7966 		}
   7967 
   7968 		return (query_done(qctx));
   7969 	}
   7970 
   7971 	/*
   7972 	 * We have a delegation but recursion is not
   7973 	 * allowed, so return the delegation to the client.
   7974 	 *
   7975 	 * qctx->fname could be released in
   7976 	 * query_addrrset(), so save a copy of it
   7977 	 * here in case we need it
   7978 	 */
   7979 	dns_fixedname_init(&qctx->dsname);
   7980 	dns_name_copy(qctx->fname, dns_fixedname_name(&qctx->dsname), NULL);
   7981 
   7982 	/*
   7983 	 * This is the best answer.
   7984 	 */
   7985 	qctx->client->query.attributes |= NS_QUERYATTR_CACHEGLUEOK;
   7986 	qctx->client->query.isreferral = ISC_TRUE;
   7987 
   7988 	if (qctx->zdb != NULL && qctx->client->query.gluedb == NULL) {
   7989 		dns_db_attach(qctx->zdb, &qctx->client->query.gluedb);
   7990 		detach = ISC_TRUE;
   7991 	}
   7992 
   7993 	/*
   7994 	 * We must ensure NOADDITIONAL is off,
   7995 	 * because the generation of
   7996 	 * additional data is required in
   7997 	 * delegations.
   7998 	 */
   7999 	qctx->client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
   8000 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
   8001 		sigrdatasetp = &qctx->sigrdataset;
   8002 	}
   8003 	query_addrrset(qctx->client, &qctx->fname,
   8004 		       &qctx->rdataset, sigrdatasetp,
   8005 		       qctx->dbuf, DNS_SECTION_AUTHORITY);
   8006 	qctx->client->query.attributes &= ~NS_QUERYATTR_CACHEGLUEOK;
   8007 	if (detach) {
   8008 		dns_db_detach(&qctx->client->query.gluedb);
   8009 	}
   8010 
   8011 	/*
   8012 	 * Add a DS if needed
   8013 	 */
   8014 	query_addds(qctx);
   8015 
   8016 	return (query_done(qctx));
   8017 }
   8018 
   8019 /*%
   8020  * Add a DS record if needed.
   8021  */
   8022 static void
   8023 query_addds(query_ctx_t *qctx) {
   8024 	ns_client_t *client = qctx->client;
   8025 	dns_fixedname_t fixed;
   8026 	dns_name_t *fname = NULL;
   8027 	dns_name_t *rname = NULL;
   8028 	dns_name_t *name;
   8029 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
   8030 	isc_buffer_t *dbuf, b;
   8031 	isc_result_t result;
   8032 	unsigned int count;
   8033 
   8034 	CTRACE(ISC_LOG_DEBUG(3), "query_addds");
   8035 
   8036 	/*
   8037 	 * DS not needed.
   8038 	 */
   8039 	if (!WANTDNSSEC(client)) {
   8040 		return;
   8041 	}
   8042 
   8043 	/*
   8044 	 * We'll need some resources...
   8045 	 */
   8046 	rdataset = query_newrdataset(client);
   8047 	sigrdataset = query_newrdataset(client);
   8048 	if (rdataset == NULL || sigrdataset == NULL)
   8049 		goto cleanup;
   8050 
   8051 	/*
   8052 	 * Look for the DS record, which may or may not be present.
   8053 	 */
   8054 	result = dns_db_findrdataset(qctx->db, qctx->node, qctx->version,
   8055 				     dns_rdatatype_ds, 0, client->now,
   8056 				     rdataset, sigrdataset);
   8057 	/*
   8058 	 * If we didn't find it, look for an NSEC.
   8059 	 */
   8060 	if (result == ISC_R_NOTFOUND)
   8061 		result = dns_db_findrdataset(qctx->db, qctx->node,
   8062 					     qctx->version,
   8063 					     dns_rdatatype_nsec,
   8064 					     0, client->now,
   8065 					     rdataset, sigrdataset);
   8066 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
   8067 		goto addnsec3;
   8068 	if (!dns_rdataset_isassociated(rdataset) ||
   8069 	    !dns_rdataset_isassociated(sigrdataset))
   8070 		goto addnsec3;
   8071 
   8072 	/*
   8073 	 * We've already added the NS record, so if the name's not there,
   8074 	 * we have other problems.  Use this name rather than calling
   8075 	 * query_addrrset().
   8076 	 */
   8077 	result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
   8078 	if (result != ISC_R_SUCCESS)
   8079 		goto cleanup;
   8080 
   8081 	rname = NULL;
   8082 	dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
   8083 				&rname);
   8084 	result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
   8085 	if (result != ISC_R_SUCCESS)
   8086 		goto cleanup;
   8087 
   8088 	ISC_LIST_APPEND(rname->list, rdataset, link);
   8089 	ISC_LIST_APPEND(rname->list, sigrdataset, link);
   8090 	rdataset = NULL;
   8091 	sigrdataset = NULL;
   8092 	return;
   8093 
   8094  addnsec3:
   8095 	if (!dns_db_iszone(qctx->db))
   8096 		goto cleanup;
   8097 	/*
   8098 	 * Add the NSEC3 which proves the DS does not exist.
   8099 	 */
   8100 	dbuf = query_getnamebuf(client);
   8101 	if (dbuf == NULL)
   8102 		goto cleanup;
   8103 	fname = query_newname(client, dbuf, &b);
   8104 	dns_fixedname_init(&fixed);
   8105 	if (dns_rdataset_isassociated(rdataset))
   8106 		dns_rdataset_disassociate(rdataset);
   8107 	if (dns_rdataset_isassociated(sigrdataset))
   8108 		dns_rdataset_disassociate(sigrdataset);
   8109 	name = dns_fixedname_name(&qctx->dsname);
   8110 	query_findclosestnsec3(name, qctx->db, qctx->version, client, rdataset,
   8111 			       sigrdataset, fname, ISC_TRUE,
   8112 			       dns_fixedname_name(&fixed));
   8113 	if (!dns_rdataset_isassociated(rdataset))
   8114 		goto cleanup;
   8115 	query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
   8116 		       DNS_SECTION_AUTHORITY);
   8117 	/*
   8118 	 * Did we find the closest provable encloser instead?
   8119 	 * If so add the nearest to the closest provable encloser.
   8120 	 */
   8121 	if (!dns_name_equal(name, dns_fixedname_name(&fixed))) {
   8122 		count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1;
   8123 		dns_name_getlabelsequence(name,
   8124 					  dns_name_countlabels(name) - count,
   8125 					  count, dns_fixedname_name(&fixed));
   8126 		fixfname(client, &fname, &dbuf, &b);
   8127 		fixrdataset(client, &rdataset);
   8128 		fixrdataset(client, &sigrdataset);
   8129 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
   8130 				goto cleanup;
   8131 		query_findclosestnsec3(dns_fixedname_name(&fixed),
   8132 				       qctx->db, qctx->version, client,
   8133 				       rdataset, sigrdataset, fname,
   8134 				       ISC_FALSE, NULL);
   8135 		if (!dns_rdataset_isassociated(rdataset))
   8136 			goto cleanup;
   8137 		query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
   8138 			       DNS_SECTION_AUTHORITY);
   8139 	}
   8140 
   8141  cleanup:
   8142 	if (rdataset != NULL)
   8143 		query_putrdataset(client, &rdataset);
   8144 	if (sigrdataset != NULL)
   8145 		query_putrdataset(client, &sigrdataset);
   8146 	if (fname != NULL)
   8147 		query_releasename(client, &fname);
   8148 }
   8149 
   8150 /*%
   8151  * Handle authoritative NOERROR/NODATA responses.
   8152  */
   8153 static isc_result_t
   8154 query_nodata(query_ctx_t *qctx, isc_result_t result) {
   8155 #ifdef dns64_bis_return_excluded_addresses
   8156 	if (qctx->dns64)
   8157 #else
   8158 	if (qctx->dns64 && !qctx->dns64_exclude)
   8159 #endif
   8160 	{
   8161 		isc_buffer_t b;
   8162 		/*
   8163 		 * Restore the answers from the previous AAAA lookup.
   8164 		 */
   8165 		if (qctx->rdataset != NULL)
   8166 			query_putrdataset(qctx->client, &qctx->rdataset);
   8167 		if (qctx->sigrdataset != NULL)
   8168 			query_putrdataset(qctx->client, &qctx->sigrdataset);
   8169 		RESTORE(qctx->rdataset, qctx->client->query.dns64_aaaa);
   8170 		RESTORE(qctx->sigrdataset, qctx->client->query.dns64_sigaaaa);
   8171 		if (qctx->fname == NULL) {
   8172 			qctx->dbuf = query_getnamebuf(qctx->client);
   8173 			if (qctx->dbuf == NULL) {
   8174 				CCTRACE(ISC_LOG_ERROR,
   8175 				       "query_nodata: "
   8176 				       "query_getnamebuf failed (3)");
   8177 				QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   8178 				return (query_done(qctx));;
   8179 			}
   8180 			qctx->fname = query_newname(qctx->client,
   8181 						    qctx->dbuf, &b);
   8182 			if (qctx->fname == NULL) {
   8183 				CCTRACE(ISC_LOG_ERROR,
   8184 				       "query_nodata: "
   8185 				       "query_newname failed (3)");
   8186 				QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   8187 				return (query_done(qctx));;
   8188 			}
   8189 		}
   8190 		dns_name_copy(qctx->client->query.qname, qctx->fname, NULL);
   8191 		qctx->dns64 = ISC_FALSE;
   8192 #ifdef dns64_bis_return_excluded_addresses
   8193 		/*
   8194 		 * Resume the diverted processing of the AAAA response?
   8195 		 */
   8196 		if (qctx->dns64_exclude)
   8197 			return (query_prepresponse(qctx));
   8198 #endif
   8199 	} else if ((result == DNS_R_NXRRSET ||
   8200 		    result == DNS_R_NCACHENXRRSET) &&
   8201 		   !ISC_LIST_EMPTY(qctx->client->view->dns64) &&
   8202 		   qctx->client->message->rdclass == dns_rdataclass_in &&
   8203 		   qctx->qtype == dns_rdatatype_aaaa)
   8204 	{
   8205 		/*
   8206 		 * Look to see if there are A records for this name.
   8207 		 */
   8208 		switch (result) {
   8209 		case DNS_R_NCACHENXRRSET:
   8210 			/*
   8211 			 * This is from the negative cache; if the ttl is
   8212 			 * zero, we need to work out whether we have just
   8213 			 * decremented to zero or there was no negative
   8214 			 * cache ttl in the answer.
   8215 			 */
   8216 			if (qctx->rdataset->ttl != 0) {
   8217 				qctx->client->query.dns64_ttl =
   8218 					qctx->rdataset->ttl;
   8219 				break;
   8220 			}
   8221 			if (dns_rdataset_first(qctx->rdataset) == ISC_R_SUCCESS)
   8222 				qctx->client->query.dns64_ttl = 0;
   8223 			break;
   8224 		case DNS_R_NXRRSET:
   8225 			qctx->client->query.dns64_ttl =
   8226 				dns64_ttl(qctx->db, qctx->version);
   8227 			break;
   8228 		default:
   8229 			INSIST(0);
   8230 		}
   8231 
   8232 		SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset);
   8233 		SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset);
   8234 		query_releasename(qctx->client, &qctx->fname);
   8235 		dns_db_detachnode(qctx->db, &qctx->node);
   8236 		qctx->type = qctx->qtype = dns_rdatatype_a;
   8237 		qctx->dns64 = ISC_TRUE;
   8238 		return (query_lookup(qctx));
   8239 	}
   8240 
   8241 	if (qctx->is_zone) {
   8242 		return (query_sign_nodata(qctx));
   8243 	} else {
   8244 		/*
   8245 		 * We don't call query_addrrset() because we don't need any
   8246 		 * of its extra features (and things would probably break!).
   8247 		 */
   8248 		if (dns_rdataset_isassociated(qctx->rdataset)) {
   8249 			query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   8250 			dns_message_addname(qctx->client->message,
   8251 					    qctx->fname,
   8252 					    DNS_SECTION_AUTHORITY);
   8253 			ISC_LIST_APPEND(qctx->fname->list,
   8254 					qctx->rdataset, link);
   8255 			qctx->fname = NULL;
   8256 			qctx->rdataset = NULL;
   8257 		}
   8258 	}
   8259 
   8260 	return (query_done(qctx));
   8261 }
   8262 
   8263 /*%
   8264  * Add RRSIGs for NOERROR/NODATA responses when answering authoritatively.
   8265  */
   8266 isc_result_t
   8267 query_sign_nodata(query_ctx_t *qctx) {
   8268 	isc_result_t result;
   8269 	/*
   8270 	 * Look for a NSEC3 record if we don't have a NSEC record.
   8271 	 */
   8272 	if (qctx->redirected)
   8273 		return (query_done(qctx));
   8274 	if (!dns_rdataset_isassociated(qctx->rdataset) &&
   8275 	     WANTDNSSEC(qctx->client))
   8276 	{
   8277 		if ((qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
   8278 			dns_name_t *found;
   8279 			dns_name_t *qname;
   8280 			dns_fixedname_t fixed;
   8281 			isc_buffer_t b;
   8282 
   8283 			found = dns_fixedname_initname(&fixed);
   8284 			qname = qctx->client->query.qname;
   8285 
   8286 			query_findclosestnsec3(qname, qctx->db, qctx->version,
   8287 					       qctx->client, qctx->rdataset,
   8288 					       qctx->sigrdataset, qctx->fname,
   8289 					       ISC_TRUE, found);
   8290 			/*
   8291 			 * Did we find the closest provable encloser
   8292 			 * instead? If so add the nearest to the
   8293 			 * closest provable encloser.
   8294 			 */
   8295 			if (dns_rdataset_isassociated(qctx->rdataset) &&
   8296 			    !dns_name_equal(qname, found) &&
   8297 			    (((qctx->client->sctx->options &
   8298 			       NS_SERVER_NONEAREST) == 0) ||
   8299 			     qctx->qtype == dns_rdatatype_ds))
   8300 			{
   8301 				unsigned int count;
   8302 				unsigned int skip;
   8303 
   8304 				/*
   8305 				 * Add the closest provable encloser.
   8306 				 */
   8307 				query_addrrset(qctx->client, &qctx->fname,
   8308 					       &qctx->rdataset,
   8309 					       &qctx->sigrdataset,
   8310 					       qctx->dbuf,
   8311 					       DNS_SECTION_AUTHORITY);
   8312 
   8313 				count = dns_name_countlabels(found)
   8314 						 + 1;
   8315 				skip = dns_name_countlabels(qname) -
   8316 						 count;
   8317 				dns_name_getlabelsequence(qname, skip,
   8318 							  count,
   8319 							  found);
   8320 
   8321 				fixfname(qctx->client, &qctx->fname,
   8322 					 &qctx->dbuf, &b);
   8323 				fixrdataset(qctx->client, &qctx->rdataset);
   8324 				fixrdataset(qctx->client, &qctx->sigrdataset);
   8325 				if (qctx->fname == NULL ||
   8326 				    qctx->rdataset == NULL ||
   8327 				    qctx->sigrdataset == NULL) {
   8328 					CCTRACE(ISC_LOG_ERROR,
   8329 					       "query_sign_nodata: "
   8330 					       "failure getting "
   8331 					       "closest encloser");
   8332 					QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   8333 					return (query_done(qctx));
   8334 				}
   8335 				/*
   8336 				 * 'nearest' doesn't exist so
   8337 				 * 'exist' is set to ISC_FALSE.
   8338 				 */
   8339 				query_findclosestnsec3(found, qctx->db,
   8340 						       qctx->version,
   8341 						       qctx->client,
   8342 						       qctx->rdataset,
   8343 						       qctx->sigrdataset,
   8344 						       qctx->fname,
   8345 						       ISC_FALSE,
   8346 						       NULL);
   8347 			}
   8348 		} else {
   8349 			query_releasename(qctx->client, &qctx->fname);
   8350 			query_addwildcardproof(qctx, ISC_FALSE, ISC_TRUE);
   8351 		}
   8352 	}
   8353 	if (dns_rdataset_isassociated(qctx->rdataset)) {
   8354 		/*
   8355 		 * If we've got a NSEC record, we need to save the
   8356 		 * name now because we're going call query_addsoa()
   8357 		 * below, and it needs to use the name buffer.
   8358 		 */
   8359 		query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   8360 	} else if (qctx->fname != NULL) {
   8361 		/*
   8362 		 * We're not going to use fname, and need to release
   8363 		 * our hold on the name buffer so query_addsoa()
   8364 		 * may use it.
   8365 		 */
   8366 		query_releasename(qctx->client, &qctx->fname);
   8367 	}
   8368 
   8369 	/*
   8370 	 * The RPZ SOA has already been added to the additional section
   8371 	 * if this was an RPZ rewrite, but if it wasn't, add it now.
   8372 	 */
   8373 	if (!qctx->nxrewrite) {
   8374 		result = query_addsoa(qctx, ISC_UINT32_MAX,
   8375 				      DNS_SECTION_AUTHORITY);
   8376 		if (result != ISC_R_SUCCESS) {
   8377 			QUERY_ERROR(qctx, result);
   8378 			return (query_done(qctx));
   8379 		}
   8380 	}
   8381 
   8382 	/*
   8383 	 * Add NSEC record if we found one.
   8384 	 */
   8385 	if (WANTDNSSEC(qctx->client) &&
   8386 	    dns_rdataset_isassociated(qctx->rdataset))
   8387 	{
   8388 		query_addnxrrsetnsec(qctx);
   8389 	}
   8390 
   8391 	return (query_done(qctx));
   8392 }
   8393 
   8394 static void
   8395 query_addnxrrsetnsec(query_ctx_t *qctx) {
   8396 	ns_client_t *client = qctx->client;
   8397 	dns_rdata_t sigrdata;
   8398 	dns_rdata_rrsig_t sig;
   8399 	unsigned int labels;
   8400 	isc_buffer_t *dbuf, b;
   8401 	dns_name_t *fname;
   8402 
   8403 	INSIST(qctx->fname != NULL);
   8404 
   8405 	if ((qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
   8406 		query_addrrset(client, &qctx->fname,
   8407 			       &qctx->rdataset, &qctx->sigrdataset,
   8408 			       NULL, DNS_SECTION_AUTHORITY);
   8409 		return;
   8410 	}
   8411 
   8412 	if (qctx->sigrdataset == NULL ||
   8413 	    !dns_rdataset_isassociated(qctx->sigrdataset))
   8414 	{
   8415 		return;
   8416 	}
   8417 
   8418 	if (dns_rdataset_first(qctx->sigrdataset) != ISC_R_SUCCESS) {
   8419 		return;
   8420 	}
   8421 
   8422 	dns_rdata_init(&sigrdata);
   8423 	dns_rdataset_current(qctx->sigrdataset, &sigrdata);
   8424 	if (dns_rdata_tostruct(&sigrdata, &sig, NULL) != ISC_R_SUCCESS) {
   8425 		return;
   8426 	}
   8427 
   8428 	labels = dns_name_countlabels(qctx->fname);
   8429 	if ((unsigned int)sig.labels + 1 >= labels) {
   8430 		return;
   8431 	}
   8432 
   8433 	query_addwildcardproof(qctx, ISC_TRUE, ISC_FALSE);
   8434 
   8435 	/*
   8436 	 * We'll need some resources...
   8437 	 */
   8438 	dbuf = query_getnamebuf(client);
   8439 	if (dbuf == NULL) {
   8440 		return;
   8441 	}
   8442 
   8443 	fname = query_newname(client, dbuf, &b);
   8444 	if (fname == NULL) {
   8445 		return;
   8446 	}
   8447 
   8448 	dns_name_split(qctx->fname, sig.labels + 1, NULL, fname);
   8449 	/* This will succeed, since we've stripped labels. */
   8450 	RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname,
   8451 					   NULL) == ISC_R_SUCCESS);
   8452 	query_addrrset(client, &fname, &qctx->rdataset, &qctx->sigrdataset,
   8453 		       dbuf, DNS_SECTION_AUTHORITY);
   8454 }
   8455 
   8456 /*%
   8457  * Handle NXDOMAIN and empty wildcard responses.
   8458  */
   8459 static isc_result_t
   8460 query_nxdomain(query_ctx_t *qctx, isc_boolean_t empty_wild) {
   8461 	dns_section_t section;
   8462 	isc_uint32_t ttl;
   8463 	isc_result_t result;
   8464 
   8465 	INSIST(qctx->is_zone || REDIRECT(qctx->client));
   8466 
   8467 	if (!empty_wild) {
   8468 		result = query_redirect(qctx);
   8469 		if (result != ISC_R_COMPLETE)
   8470 			return (result);
   8471 	}
   8472 
   8473 	if (dns_rdataset_isassociated(qctx->rdataset)) {
   8474 		/*
   8475 		 * If we've got a NSEC record, we need to save the
   8476 		 * name now because we're going call query_addsoa()
   8477 		 * below, and it needs to use the name buffer.
   8478 		 */
   8479 		query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   8480 	} else if (qctx->fname != NULL) {
   8481 		/*
   8482 		 * We're not going to use fname, and need to release
   8483 		 * our hold on the name buffer so query_addsoa()
   8484 		 * may use it.
   8485 		 */
   8486 		query_releasename(qctx->client, &qctx->fname);
   8487 	}
   8488 
   8489 	/*
   8490 	 * Add SOA to the additional section if generated by a
   8491 	 * RPZ rewrite.
   8492 	 *
   8493 	 * If the query was for a SOA record force the
   8494 	 * ttl to zero so that it is possible for clients to find
   8495 	 * the containing zone of an arbitrary name with a stub
   8496 	 * resolver and not have it cached.
   8497 	 */
   8498 	section = qctx->nxrewrite ? DNS_SECTION_ADDITIONAL
   8499 				  : DNS_SECTION_AUTHORITY;
   8500 	ttl = ISC_UINT32_MAX;
   8501 	if (!qctx->nxrewrite && qctx->qtype == dns_rdatatype_soa &&
   8502 	    qctx->zone != NULL && dns_zone_getzeronosoattl(qctx->zone))
   8503 	{
   8504 		ttl = 0;
   8505 	}
   8506 	result = query_addsoa(qctx, ttl, section);
   8507 	if (result != ISC_R_SUCCESS) {
   8508 		QUERY_ERROR(qctx, result);
   8509 		return (query_done(qctx));
   8510 	}
   8511 
   8512 	if (WANTDNSSEC(qctx->client)) {
   8513 		/*
   8514 		 * Add NSEC record if we found one.
   8515 		 */
   8516 		if (dns_rdataset_isassociated(qctx->rdataset))
   8517 			query_addrrset(qctx->client, &qctx->fname,
   8518 				       &qctx->rdataset, &qctx->sigrdataset,
   8519 				       NULL, DNS_SECTION_AUTHORITY);
   8520 		query_addwildcardproof(qctx, ISC_FALSE, ISC_FALSE);
   8521 	}
   8522 
   8523 	/*
   8524 	 * Set message rcode.
   8525 	 */
   8526 	if (empty_wild)
   8527 		qctx->client->message->rcode = dns_rcode_noerror;
   8528 	else
   8529 		qctx->client->message->rcode = dns_rcode_nxdomain;
   8530 
   8531 	return (query_done(qctx));
   8532 }
   8533 
   8534 /*
   8535  * Handle both types of NXDOMAIN redirection, calling redirect()
   8536  * (which implements type redirect zones) and redirect2() (which
   8537  * implements recursive nxdomain-redirect lookups).
   8538  *
   8539  * Any result code other than ISC_R_COMPLETE means redirection was
   8540  * successful and the result code should be returned up the call stack.
   8541  *
   8542  * ISC_R_COMPLETE means we reached the end of this function without
   8543  * redirecting, so query processing should continue past it.
   8544  */
   8545 static isc_result_t
   8546 query_redirect(query_ctx_t *qctx)  {
   8547 	isc_result_t result;
   8548 
   8549 	result = redirect(qctx->client, qctx->fname, qctx->rdataset,
   8550 			  &qctx->node, &qctx->db, &qctx->version,
   8551 			  qctx->type);
   8552 	switch (result) {
   8553 	case ISC_R_SUCCESS:
   8554 		inc_stats(qctx->client,
   8555 			  ns_statscounter_nxdomainredirect);
   8556 		return (query_prepresponse(qctx));
   8557 	case DNS_R_NXRRSET:
   8558 		qctx->redirected = ISC_TRUE;
   8559 		qctx->is_zone = ISC_TRUE;
   8560 		return (query_nodata(qctx, DNS_R_NXRRSET));
   8561 	case DNS_R_NCACHENXRRSET:
   8562 		qctx->redirected = ISC_TRUE;
   8563 		qctx->is_zone = ISC_FALSE;
   8564 		return (query_ncache(qctx, DNS_R_NCACHENXRRSET));
   8565 	default:
   8566 		break;
   8567 	}
   8568 
   8569 	result = redirect2(qctx->client, qctx->fname, qctx->rdataset,
   8570 			   &qctx->node, &qctx->db, &qctx->version,
   8571 			   qctx->type, &qctx->is_zone);
   8572 	switch (result) {
   8573 	case ISC_R_SUCCESS:
   8574 		inc_stats(qctx->client,
   8575 			  ns_statscounter_nxdomainredirect);
   8576 		return (query_prepresponse(qctx));
   8577 	case DNS_R_CONTINUE:
   8578 		inc_stats(qctx->client,
   8579 			  ns_statscounter_nxdomainredirect_rlookup);
   8580 		SAVE(qctx->client->query.redirect.db, qctx->db);
   8581 		SAVE(qctx->client->query.redirect.node, qctx->node);
   8582 		SAVE(qctx->client->query.redirect.zone, qctx->zone);
   8583 		qctx->client->query.redirect.qtype = qctx->qtype;
   8584 		INSIST(qctx->rdataset != NULL);
   8585 		SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
   8586 		SAVE(qctx->client->query.redirect.sigrdataset,
   8587 		     qctx->sigrdataset);
   8588 		qctx->client->query.redirect.result = DNS_R_NCACHENXDOMAIN;
   8589 		dns_name_copy(qctx->fname, qctx->client->query.redirect.fname,
   8590 			      NULL);
   8591 		qctx->client->query.redirect.authoritative =
   8592 			qctx->authoritative;
   8593 		qctx->client->query.redirect.is_zone = qctx->is_zone;
   8594 		return (query_done(qctx));
   8595 	case DNS_R_NXRRSET:
   8596 		qctx->redirected = ISC_TRUE;
   8597 		qctx->is_zone = ISC_TRUE;
   8598 		return (query_nodata(qctx, DNS_R_NXRRSET));
   8599 	case DNS_R_NCACHENXRRSET:
   8600 		qctx->redirected = ISC_TRUE;
   8601 		qctx->is_zone = ISC_FALSE;
   8602 		return (query_ncache(qctx, DNS_R_NCACHENXRRSET));
   8603 	default:
   8604 		break;
   8605 	}
   8606 
   8607 	return (ISC_R_COMPLETE);
   8608 }
   8609 
   8610 /*%
   8611  * Logging function to be passed to dns_nsec_noexistnodata.
   8612  */
   8613 static void
   8614 log_noexistnodata(void *val, int level, const char *fmt, ...) {
   8615 	query_ctx_t *qctx = val;
   8616 	va_list ap;
   8617 
   8618 	va_start(ap, fmt);
   8619 	ns_client_logv(qctx->client, NS_LOGCATEGORY_QUERIES,
   8620 		       NS_LOGMODULE_QUERY, level, fmt, ap);
   8621 	va_end(ap);
   8622 }
   8623 
   8624 static dns_ttl_t
   8625 query_synthttl(dns_rdataset_t *soardataset, dns_rdataset_t *sigsoardataset,
   8626 	       dns_rdataset_t *p1rdataset, dns_rdataset_t *sigp1rdataset,
   8627 	       dns_rdataset_t *p2rdataset, dns_rdataset_t *sigp2rdataset)
   8628 {
   8629 	dns_rdata_soa_t soa;
   8630 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8631 	dns_ttl_t ttl;
   8632 	isc_result_t result;
   8633 
   8634 	REQUIRE(soardataset != NULL);
   8635 	REQUIRE(sigsoardataset != NULL);
   8636 	REQUIRE(p1rdataset != NULL);
   8637 	REQUIRE(sigp1rdataset != NULL);
   8638 
   8639 	result = dns_rdataset_first(soardataset);
   8640 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8641 	dns_rdataset_current(soardataset, &rdata);
   8642 	dns_rdata_tostruct(&rdata, &soa, NULL);
   8643 
   8644 	ttl = ISC_MIN(soa.minimum, soardataset->ttl);
   8645 	ttl = ISC_MIN(ttl, sigsoardataset->ttl);
   8646 	ttl = ISC_MIN(ttl, p1rdataset->ttl);
   8647 	ttl = ISC_MIN(ttl, sigp1rdataset->ttl);
   8648 	if (p2rdataset != NULL)
   8649 		ttl = ISC_MIN(ttl, p2rdataset->ttl);
   8650 	if (sigp2rdataset != NULL)
   8651 		ttl = ISC_MIN(ttl, sigp2rdataset->ttl);
   8652 
   8653 	return (ttl);
   8654 }
   8655 
   8656 /*
   8657  * Synthesize a NODATA response from the SOA and covering NSEC in cache.
   8658  */
   8659 static isc_result_t
   8660 query_synthnodata(query_ctx_t *qctx, const dns_name_t *signer,
   8661 		  dns_rdataset_t **soardatasetp,
   8662 		  dns_rdataset_t **sigsoardatasetp)
   8663 {
   8664 	dns_name_t *name = NULL;
   8665 	dns_ttl_t ttl;
   8666 	isc_buffer_t *dbuf, b;
   8667 	isc_result_t result;
   8668 
   8669 	/*
   8670 	 * Detemine the correct TTL to use for the SOA and RRSIG
   8671 	 */
   8672 	ttl = query_synthttl(*soardatasetp, *sigsoardatasetp,
   8673 			     qctx->rdataset, qctx->sigrdataset,
   8674 			     NULL, NULL);
   8675 	(*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl;
   8676 
   8677 	/*
   8678 	 * We want the SOA record to be first, so save the
   8679 	 * NODATA proof's name now or else discard it.
   8680 	 */
   8681 	if (WANTDNSSEC(qctx->client)) {
   8682 		query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   8683 	} else {
   8684 		query_releasename(qctx->client, &qctx->fname);
   8685 	}
   8686 
   8687 	dbuf = query_getnamebuf(qctx->client);
   8688 	if (dbuf == NULL) {
   8689 		result = ISC_R_NOMEMORY;
   8690 		goto cleanup;
   8691 	}
   8692 
   8693 	name = query_newname(qctx->client, dbuf, &b);
   8694 	if (name == NULL) {
   8695 		result = ISC_R_NOMEMORY;
   8696 		goto cleanup;
   8697 	}
   8698 
   8699 	dns_name_copy(signer, name, NULL);
   8700 
   8701 	/*
   8702 	 * Add SOA record. Omit the RRSIG if DNSSEC was not requested.
   8703 	 */
   8704 	if (!WANTDNSSEC(qctx->client)) {
   8705 		sigsoardatasetp = NULL;
   8706 	}
   8707 	query_addrrset(qctx->client, &name, soardatasetp, sigsoardatasetp,
   8708 		       dbuf, DNS_SECTION_AUTHORITY);
   8709 
   8710 	if (WANTDNSSEC(qctx->client)) {
   8711 		/*
   8712 		 * Add NODATA proof.
   8713 		 */
   8714 		query_addrrset(qctx->client, &qctx->fname,
   8715 			       &qctx->rdataset, &qctx->sigrdataset,
   8716 			       NULL, DNS_SECTION_AUTHORITY);
   8717 	}
   8718 
   8719 	result = ISC_R_SUCCESS;
   8720 	inc_stats(qctx->client, ns_statscounter_nodatasynth);
   8721 
   8722 cleanup:
   8723 	if (name != NULL) {
   8724 		query_releasename(qctx->client, &name);
   8725 	}
   8726 	return (result);
   8727 }
   8728 
   8729 /*
   8730  * Synthesize a wildcard answer using the contents of 'rdataset'.
   8731  * qctx contains the NODATA proof.
   8732  */
   8733 static isc_result_t
   8734 query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
   8735 		    dns_rdataset_t *sigrdataset)
   8736 {
   8737 	dns_name_t *name = NULL;
   8738 	isc_buffer_t *dbuf, b;
   8739 	isc_result_t result;
   8740 	dns_rdataset_t *clone = NULL, *sigclone = NULL;
   8741 	dns_rdataset_t **sigrdatasetp;
   8742 
   8743 	/*
   8744 	 * We want the answer to be first, so save the
   8745 	 * NOQNAME proof's name now or else discard it.
   8746 	 */
   8747 	if (WANTDNSSEC(qctx->client)) {
   8748 		query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   8749 	} else {
   8750 		query_releasename(qctx->client, &qctx->fname);
   8751 	}
   8752 
   8753 	dbuf = query_getnamebuf(qctx->client);
   8754 	if (dbuf == NULL) {
   8755 		result = ISC_R_NOMEMORY;
   8756 		goto cleanup;
   8757 	}
   8758 
   8759 	name = query_newname(qctx->client, dbuf, &b);
   8760 	if (name == NULL) {
   8761 		result = ISC_R_NOMEMORY;
   8762 		goto cleanup;
   8763 	}
   8764 	dns_name_copy(qctx->client->query.qname, name, NULL);
   8765 
   8766 	clone = query_newrdataset(qctx->client);
   8767 	if (clone == NULL) {
   8768 		result = ISC_R_NOMEMORY;
   8769 		goto cleanup;
   8770 	}
   8771 	dns_rdataset_clone(rdataset, clone);
   8772 
   8773 	/*
   8774 	 * Add answer RRset. Omit the RRSIG if DNSSEC was not requested.
   8775 	 */
   8776 	if (WANTDNSSEC(qctx->client)) {
   8777 		sigclone = query_newrdataset(qctx->client);
   8778 		if (sigclone == NULL) {
   8779 			result = ISC_R_NOMEMORY;
   8780 			goto cleanup;
   8781 		}
   8782 		dns_rdataset_clone(sigrdataset, sigclone);
   8783 		sigrdatasetp = &sigclone;
   8784 	} else {
   8785 		sigrdatasetp = NULL;
   8786 	}
   8787 
   8788 	query_addrrset(qctx->client, &name, &clone, sigrdatasetp,
   8789 		       dbuf, DNS_SECTION_ANSWER);
   8790 
   8791 	if (WANTDNSSEC(qctx->client)) {
   8792 		/*
   8793 		 * Add NOQNAME proof.
   8794 		 */
   8795 		query_addrrset(qctx->client, &qctx->fname,
   8796 			       &qctx->rdataset, &qctx->sigrdataset,
   8797 			       NULL, DNS_SECTION_AUTHORITY);
   8798 	}
   8799 
   8800 	result = ISC_R_SUCCESS;
   8801 	inc_stats(qctx->client, ns_statscounter_wildcardsynth);
   8802 
   8803 cleanup:
   8804 	if (name != NULL) {
   8805 		query_releasename(qctx->client, &name);
   8806 	}
   8807 	if (clone != NULL) {
   8808 		query_putrdataset(qctx->client, &clone);
   8809 	}
   8810 	if (sigclone != NULL) {
   8811 		query_putrdataset(qctx->client, &sigclone);
   8812 	}
   8813 	return (result);
   8814 }
   8815 
   8816 /*
   8817  * Add a synthesized CNAME record from the wildard RRset (rdataset)
   8818  * and NODATA proof by calling query_synthwildcard then setup to
   8819  * follow the CNAME.
   8820  */
   8821 static isc_result_t
   8822 query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
   8823 			 dns_rdataset_t *sigrdataset)
   8824 {
   8825 	isc_result_t result;
   8826 	dns_name_t *tname = NULL;
   8827 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8828 	dns_rdata_cname_t cname;
   8829 
   8830 	result = query_synthwildcard(qctx, rdataset, sigrdataset);
   8831 	if (result != ISC_R_SUCCESS) {
   8832 		return (result);
   8833 	}
   8834 
   8835 	qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
   8836 
   8837 	/*
   8838 	 * Reset qname to be the target name of the CNAME and restart
   8839 	 * the query.
   8840 	 */
   8841 	result = dns_message_gettempname(qctx->client->message, &tname);
   8842 	if (result != ISC_R_SUCCESS) {
   8843 		return (result);
   8844 	}
   8845 
   8846 	result = dns_rdataset_first(rdataset);
   8847 	if (result != ISC_R_SUCCESS) {
   8848 		dns_message_puttempname(qctx->client->message, &tname);
   8849 		return (result);
   8850 	}
   8851 
   8852 	dns_rdataset_current(rdataset, &rdata);
   8853 	result = dns_rdata_tostruct(&rdata, &cname, NULL);
   8854 	dns_rdata_reset(&rdata);
   8855 	if (result != ISC_R_SUCCESS) {
   8856 		dns_message_puttempname(qctx->client->message, &tname);
   8857 		return (result);
   8858 	}
   8859 
   8860 	dns_name_init(tname, NULL);
   8861 	result = dns_name_dup(&cname.cname, qctx->client->mctx, tname);
   8862 	if (result != ISC_R_SUCCESS) {
   8863 		dns_message_puttempname(qctx->client->message, &tname);
   8864 		dns_rdata_freestruct(&cname);
   8865 		return (result);
   8866 	}
   8867 
   8868 	dns_rdata_freestruct(&cname);
   8869 	ns_client_qnamereplace(qctx->client, tname);
   8870 	qctx->want_restart = ISC_TRUE;
   8871 	if (!WANTRECURSION(qctx->client)) {
   8872 		qctx->options |= DNS_GETDB_NOLOG;
   8873 	}
   8874 
   8875 	return (result);
   8876 }
   8877 
   8878 /*
   8879  * Synthesize a NXDOMAIN response from qctx (which contains the
   8880  * NODATA proof), nowild + nowildrdataset + signowildrdataset (which
   8881  * contains the NOWILDCARD proof) and signer + soardatasetp + sigsoardatasetp
   8882  * which contain the SOA record + RRSIG for the negative answer.
   8883  */
   8884 static isc_result_t
   8885 query_synthnxdomain(query_ctx_t *qctx,
   8886 		    dns_name_t *nowild,
   8887 		    dns_rdataset_t *nowildrdataset,
   8888 		    dns_rdataset_t *signowildrdataset,
   8889 		    dns_name_t *signer,
   8890 		    dns_rdataset_t **soardatasetp,
   8891 		    dns_rdataset_t **sigsoardatasetp)
   8892 {
   8893 	dns_name_t *name = NULL;
   8894 	dns_ttl_t ttl;
   8895 	isc_buffer_t *dbuf, b;
   8896 	isc_result_t result;
   8897 	dns_rdataset_t *clone = NULL, *sigclone = NULL;
   8898 
   8899 	/*
   8900 	 * Detemine the correct TTL to use for the SOA and RRSIG
   8901 	 */
   8902 	ttl = query_synthttl(*soardatasetp, *sigsoardatasetp,
   8903 			     qctx->rdataset, qctx->sigrdataset,
   8904 			     nowildrdataset, signowildrdataset);
   8905 	(*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl;
   8906 
   8907 	/*
   8908 	 * We want the SOA record to be first, so save the
   8909 	 * NOQNAME proof's name now or else discard it.
   8910 	 */
   8911 	if (WANTDNSSEC(qctx->client)) {
   8912 		query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   8913 	} else {
   8914 		query_releasename(qctx->client, &qctx->fname);
   8915 	}
   8916 
   8917 	dbuf = query_getnamebuf(qctx->client);
   8918 	if (dbuf == NULL) {
   8919 		result = ISC_R_NOMEMORY;
   8920 		goto cleanup;
   8921 	}
   8922 
   8923 	name = query_newname(qctx->client, dbuf, &b);
   8924 	if (name == NULL) {
   8925 		result = ISC_R_NOMEMORY;
   8926 		goto cleanup;
   8927 	}
   8928 
   8929 	dns_name_copy(signer, name, NULL);
   8930 
   8931 	/*
   8932 	 * Add SOA record. Omit the RRSIG if DNSSEC was not requested.
   8933 	 */
   8934 	if (!WANTDNSSEC(qctx->client)) {
   8935 		sigsoardatasetp = NULL;
   8936 	}
   8937 	query_addrrset(qctx->client, &name, soardatasetp, sigsoardatasetp,
   8938 		       dbuf, DNS_SECTION_AUTHORITY);
   8939 
   8940 	if (WANTDNSSEC(qctx->client)) {
   8941 		/*
   8942 		 * Add NOQNAME proof.
   8943 		 */
   8944 		query_addrrset(qctx->client, &qctx->fname,
   8945 			       &qctx->rdataset, &qctx->sigrdataset,
   8946 			       NULL, DNS_SECTION_AUTHORITY);
   8947 
   8948 		dbuf = query_getnamebuf(qctx->client);
   8949 		if (dbuf == NULL) {
   8950 			result = ISC_R_NOMEMORY;
   8951 			goto cleanup;
   8952 		}
   8953 
   8954 		name = query_newname(qctx->client, dbuf, &b);
   8955 		if (name == NULL) {
   8956 			result = ISC_R_NOMEMORY;
   8957 			goto cleanup;
   8958 		}
   8959 
   8960 		dns_name_copy(nowild, name, NULL);
   8961 
   8962 		clone = query_newrdataset(qctx->client);
   8963 		sigclone = query_newrdataset(qctx->client);
   8964 		if (clone == NULL || sigclone == NULL) {
   8965 			result = ISC_R_NOMEMORY;
   8966 			goto cleanup;
   8967 		}
   8968 
   8969 		dns_rdataset_clone(nowildrdataset, clone);
   8970 		dns_rdataset_clone(signowildrdataset, sigclone);
   8971 
   8972 		/*
   8973 		 * Add NOWILDCARD proof.
   8974 		 */
   8975 		query_addrrset(qctx->client, &name, &clone, &sigclone,
   8976 			       dbuf, DNS_SECTION_AUTHORITY);
   8977 	}
   8978 
   8979 	qctx->client->message->rcode = dns_rcode_nxdomain;
   8980 	result = ISC_R_SUCCESS;
   8981 	inc_stats(qctx->client, ns_statscounter_nxdomainsynth);
   8982 
   8983 cleanup:
   8984 	if (name != NULL) {
   8985 		query_releasename(qctx->client, &name);
   8986 	}
   8987 	if (clone != NULL) {
   8988 		query_putrdataset(qctx->client, &clone);
   8989 	}
   8990 	if (sigclone != NULL) {
   8991 		query_putrdataset(qctx->client, &sigclone);
   8992 	}
   8993 	return (result);
   8994 }
   8995 
   8996 /*
   8997  * Check that all signer names in sigrdataset match the expected signer.
   8998  */
   8999 static isc_result_t
   9000 checksignames(dns_name_t *signer, dns_rdataset_t *sigrdataset) {
   9001 	isc_result_t result;
   9002 
   9003 	for (result = dns_rdataset_first(sigrdataset);
   9004 	     result == ISC_R_SUCCESS;
   9005 	     result = dns_rdataset_next(sigrdataset)) {
   9006 		dns_rdata_t rdata = DNS_RDATA_INIT;
   9007 		dns_rdata_rrsig_t rrsig;
   9008 
   9009 		dns_rdataset_current(sigrdataset, &rdata);
   9010 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   9011 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9012 		if (dns_name_countlabels(signer) == 0) {
   9013 			dns_name_copy(&rrsig.signer, signer, NULL);
   9014 		} else if (!dns_name_equal(signer, &rrsig.signer)) {
   9015 			return (ISC_R_FAILURE);
   9016 		}
   9017 	}
   9018 
   9019 	return (ISC_R_SUCCESS);
   9020 }
   9021 
   9022 /*%
   9023  * Handle covering NSEC responses.
   9024  *
   9025  * Verify the NSEC record is apropriate for the QNAME; if not,
   9026  * redo the initial query without DNS_DBFIND_COVERINGNSEC.
   9027  *
   9028  * If the covering NSEC proves that the name exists but not the type,
   9029  * synthesize a NODATA response.
   9030  *
   9031  * If the name doesn't exist, compute the wildcard record and check whether
   9032  * the wildcard name exists or not.  If we can't determine this, redo the
   9033  * initial query without DNS_DBFIND_COVERINGNSEC.
   9034  *
   9035  * If the wildcard name does not exist, compute the SOA name and look that
   9036  * up.  If the SOA record does not exist, redo the initial query without
   9037  * DNS_DBFIND_COVERINGNSEC.  If the SOA record exists, synthesize an
   9038  * NXDOMAIN response from the found records.
   9039  *
   9040  * If the wildcard name does exist, perform a lookup for the requested
   9041  * type at the wildcard name.
   9042  */
   9043 static isc_result_t
   9044 query_coveringnsec(query_ctx_t *qctx) {
   9045 	dns_db_t *db = NULL;
   9046 	dns_clientinfo_t ci;
   9047 	dns_clientinfomethods_t cm;
   9048 	dns_dbnode_t *node = NULL;
   9049 	dns_fixedname_t fixed;
   9050 	dns_fixedname_t fnowild;
   9051 	dns_fixedname_t fsigner;
   9052 	dns_fixedname_t fwild;
   9053 	dns_name_t *fname = NULL;
   9054 	dns_name_t *nowild = NULL;
   9055 	dns_name_t *signer = NULL;
   9056 	dns_name_t *wild = NULL;
   9057 	dns_rdataset_t *soardataset = NULL, *sigsoardataset = NULL;
   9058 	dns_rdataset_t rdataset, sigrdataset;
   9059 	isc_boolean_t done = ISC_FALSE;
   9060 	isc_boolean_t exists = ISC_TRUE, data = ISC_TRUE;
   9061 	isc_boolean_t redirected = ISC_FALSE;
   9062 	isc_result_t result = ISC_R_SUCCESS;
   9063 	unsigned int dboptions = qctx->client->query.dboptions;
   9064 
   9065 	dns_rdataset_init(&rdataset);
   9066 	dns_rdataset_init(&sigrdataset);
   9067 
   9068 	/*
   9069 	 * If we have no signer name, stop immediately.
   9070 	 */
   9071 	if (!dns_rdataset_isassociated(qctx->sigrdataset)) {
   9072 		goto cleanup;
   9073 	}
   9074 
   9075 	wild = dns_fixedname_initname(&fwild);
   9076 	fname = dns_fixedname_initname(&fixed);
   9077 	signer = dns_fixedname_initname(&fsigner);
   9078 	nowild = dns_fixedname_initname(&fnowild);
   9079 
   9080 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   9081 	dns_clientinfo_init(&ci, qctx->client, NULL);
   9082 
   9083 	/*
   9084 	 * All signer names must be the same to accept.
   9085 	 */
   9086 	result = checksignames(signer, qctx->sigrdataset);
   9087 	if (result != ISC_R_SUCCESS) {
   9088 		result = ISC_R_SUCCESS;
   9089 		goto cleanup;
   9090 	}
   9091 
   9092 	/*
   9093 	 * Check that we have the correct NOQNAME NSEC record.
   9094 	 */
   9095 	result = dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname,
   9096 					qctx->fname, qctx->rdataset,
   9097 					&exists, &data, wild,
   9098 					log_noexistnodata, qctx);
   9099 
   9100 	if (result != ISC_R_SUCCESS || (exists && data)) {
   9101 		goto cleanup;
   9102 	}
   9103 
   9104 	if (exists) {
   9105 		if (qctx->type == dns_rdatatype_any) {	/* XXX not yet */
   9106 			goto cleanup;
   9107 		}
   9108 		if (qctx->client->filter_aaaa != dns_aaaa_ok &&
   9109 		    (qctx->type == dns_rdatatype_a ||
   9110 		     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
   9111 		{
   9112 			goto cleanup;
   9113 		}
   9114 		if (!ISC_LIST_EMPTY(qctx->client->view->dns64) &&
   9115 		    (qctx->type == dns_rdatatype_a ||
   9116 		     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
   9117 		{
   9118 			goto cleanup;
   9119 		}
   9120 		if (!qctx->resuming && !STALE(qctx->rdataset) &&
   9121 		    qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client))
   9122 		{
   9123 			goto cleanup;
   9124 		}
   9125 
   9126 		soardataset = query_newrdataset(qctx->client);
   9127 		sigsoardataset = query_newrdataset(qctx->client);
   9128 		if (soardataset == NULL || sigsoardataset == NULL) {
   9129 			goto cleanup;
   9130 		}
   9131 
   9132 		/*
   9133 		 * Look for SOA record to construct NODATA response.
   9134 		 */
   9135 		dns_db_attach(qctx->db, &db);
   9136 		result = dns_db_findext(db, signer, qctx->version,
   9137 					dns_rdatatype_soa, dboptions,
   9138 					qctx->client->now, &node,
   9139 					fname, &cm, &ci, soardataset,
   9140 					sigsoardataset);
   9141 
   9142 		if (result != ISC_R_SUCCESS) {
   9143 			goto cleanup;
   9144 		}
   9145 		(void)query_synthnodata(qctx, signer,
   9146 					&soardataset, &sigsoardataset);
   9147 		done = ISC_TRUE;
   9148 		goto cleanup;
   9149 	}
   9150 
   9151 	/*
   9152 	 * Look up the no-wildcard proof.
   9153 	 */
   9154 	dns_db_attach(qctx->db, &db);
   9155 	result = dns_db_findext(db, wild, qctx->version, qctx->type,
   9156 				dboptions | DNS_DBFIND_COVERINGNSEC,
   9157 				qctx->client->now, &node, nowild,
   9158 				&cm, &ci, &rdataset, &sigrdataset);
   9159 
   9160 	if (rdataset.trust != dns_trust_secure ||
   9161 	    sigrdataset.trust != dns_trust_secure)
   9162 	{
   9163 		goto cleanup;
   9164 	}
   9165 
   9166 	/*
   9167 	 * Zero TTL handling of wildcard record.
   9168 	 *
   9169 	 * We don't yet have code to handle synthesis and type ANY,
   9170 	 * AAAA filtering or dns64 processing so we abort the
   9171 	 * synthesis here if there would be a interaction.
   9172 	 */
   9173 	switch (result) {
   9174 	case ISC_R_SUCCESS:
   9175 		if (qctx->type == dns_rdatatype_any) {	/* XXX not yet */
   9176 			goto cleanup;
   9177 		}
   9178 		if (qctx->client->filter_aaaa != dns_aaaa_ok &&
   9179 		    (qctx->type == dns_rdatatype_a ||
   9180 		     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
   9181 		{
   9182 			goto cleanup;
   9183 		}
   9184 		if (!ISC_LIST_EMPTY(qctx->client->view->dns64) &&
   9185 		    (qctx->type == dns_rdatatype_a ||
   9186 		     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
   9187 		{
   9188 			goto cleanup;
   9189 		}
   9190 		/* FALLTHROUGH */
   9191 	case DNS_R_CNAME:
   9192 		if (!qctx->resuming && !STALE(&rdataset) &&
   9193 		    rdataset.ttl == 0 && RECURSIONOK(qctx->client))
   9194 		{
   9195 			goto cleanup;
   9196 		}
   9197 	default:
   9198 		break;
   9199 	}
   9200 
   9201 	switch (result) {
   9202 	case DNS_R_COVERINGNSEC:
   9203 		result = dns_nsec_noexistnodata(qctx->qtype, wild,
   9204 						nowild, &rdataset,
   9205 						&exists, &data, NULL,
   9206 						log_noexistnodata, qctx);
   9207 		if (result != ISC_R_SUCCESS || exists) {
   9208 			goto cleanup;
   9209 		}
   9210 		break;
   9211 	case ISC_R_SUCCESS:		/* wild card match */
   9212 		(void)query_synthwildcard(qctx, &rdataset, &sigrdataset);
   9213 		done = ISC_TRUE;
   9214 		goto cleanup;
   9215 	case DNS_R_CNAME:		/* wild card cname */
   9216 		(void)query_synthcnamewildcard(qctx, &rdataset, &sigrdataset);
   9217 		done = ISC_TRUE;
   9218 		goto cleanup;
   9219 	case DNS_R_NCACHENXRRSET:	/* wild card nodata */
   9220 	case DNS_R_NCACHENXDOMAIN:	/* direct nxdomain */
   9221 	default:
   9222 		goto cleanup;
   9223 	}
   9224 
   9225 	/*
   9226 	 * We now have the proof that we have an NXDOMAIN.  Apply
   9227 	 * NXDOMAIN redirection if configured.
   9228 	 */
   9229 	result = query_redirect(qctx);
   9230 	if (result != ISC_R_COMPLETE) {
   9231 		redirected = ISC_TRUE;
   9232 		goto cleanup;
   9233 	}
   9234 
   9235 	/*
   9236 	 * Must be signed to accept.
   9237 	 */
   9238 	if (!dns_rdataset_isassociated(&sigrdataset)) {
   9239 		goto cleanup;
   9240 	}
   9241 
   9242 	/*
   9243 	 * Check signer signer names again.
   9244 	 */
   9245 	result = checksignames(signer, &sigrdataset);
   9246 	if (result != ISC_R_SUCCESS) {
   9247 		result = ISC_R_SUCCESS;
   9248 		goto cleanup;
   9249 	}
   9250 
   9251 	if (node != NULL) {
   9252 		dns_db_detachnode(db, &node);
   9253 	}
   9254 
   9255 	soardataset = query_newrdataset(qctx->client);
   9256 	sigsoardataset = query_newrdataset(qctx->client);
   9257 	if (soardataset == NULL || sigsoardataset == NULL) {
   9258 		goto cleanup;
   9259 	}
   9260 
   9261 	/*
   9262 	 * Look for SOA record to construct NXDOMAIN response.
   9263 	 */
   9264 	result = dns_db_findext(db, signer, qctx->version,
   9265 				dns_rdatatype_soa, dboptions,
   9266 				qctx->client->now, &node,
   9267 				fname, &cm, &ci, soardataset,
   9268 				sigsoardataset);
   9269 
   9270 	if (result != ISC_R_SUCCESS) {
   9271 		goto cleanup;
   9272 	}
   9273 
   9274 	(void)query_synthnxdomain(qctx, nowild, &rdataset, &sigrdataset,
   9275 				  signer, &soardataset, &sigsoardataset);
   9276 	done = ISC_TRUE;
   9277 
   9278  cleanup:
   9279 	if (dns_rdataset_isassociated(&rdataset)) {
   9280 		dns_rdataset_disassociate(&rdataset);
   9281 	}
   9282 	if (dns_rdataset_isassociated(&sigrdataset)) {
   9283 		dns_rdataset_disassociate(&sigrdataset);
   9284 	}
   9285 	if (soardataset != NULL) {
   9286 		query_putrdataset(qctx->client, &soardataset);
   9287 	}
   9288 	if (sigsoardataset != NULL) {
   9289 		query_putrdataset(qctx->client, &sigsoardataset);
   9290 	}
   9291 	if (db != NULL) {
   9292 		if (node != NULL) {
   9293 			dns_db_detachnode(db, &node);
   9294 		}
   9295 		dns_db_detach(&db);
   9296 	}
   9297 
   9298 	if (redirected) {
   9299 		return (result);
   9300 	}
   9301 
   9302 	if (!done) {
   9303 		/*
   9304 		 * No covering NSEC was found; proceed with recursion.
   9305 		 */
   9306 		qctx->findcoveringnsec = ISC_FALSE;
   9307 		if (qctx->fname != NULL) {
   9308 			query_releasename(qctx->client, &qctx->fname);
   9309 		}
   9310 		if (qctx->node != NULL) {
   9311 			dns_db_detachnode(qctx->db, &qctx->node);
   9312 		}
   9313 		query_putrdataset(qctx->client, &qctx->rdataset);
   9314 		if (qctx->sigrdataset != NULL) {
   9315 			query_putrdataset(qctx->client, &qctx->sigrdataset);
   9316 		}
   9317 		return (query_lookup(qctx));
   9318 	}
   9319 
   9320 	return (query_done(qctx));
   9321 }
   9322 
   9323 /*%
   9324  * Handle negative cache responses, DNS_R_NCACHENXRRSET or
   9325  * DNS_R_NCACHENXDOMAIN. (Note: may also be called with result
   9326  * set to DNS_R_NXDOMAIN when handling DNS64 lookups.)
   9327  */
   9328 static isc_result_t
   9329 query_ncache(query_ctx_t *qctx, isc_result_t result) {
   9330 	INSIST(!qctx->is_zone);
   9331 	INSIST(result == DNS_R_NCACHENXDOMAIN ||
   9332 	       result == DNS_R_NCACHENXRRSET ||
   9333 	       result == DNS_R_NXDOMAIN);
   9334 
   9335 	qctx->authoritative = ISC_FALSE;
   9336 
   9337 	if (result == DNS_R_NCACHENXDOMAIN) {
   9338 		/*
   9339 		 * Set message rcode. (This is not done when
   9340 		 * result == DNS_R_NXDOMAIN because that means we're
   9341 		 * being called after a DNS64 lookup and don't want
   9342 		 * to update the rcode now.)
   9343 		 */
   9344 		qctx->client->message->rcode = dns_rcode_nxdomain;
   9345 
   9346 		/* Look for RFC 1918 leakage from Internet. */
   9347 		if (qctx->qtype == dns_rdatatype_ptr &&
   9348 		    qctx->client->message->rdclass == dns_rdataclass_in &&
   9349 		    dns_name_countlabels(qctx->fname) == 7)
   9350 		{
   9351 			warn_rfc1918(qctx->client, qctx->fname, qctx->rdataset);
   9352 		}
   9353 	}
   9354 
   9355 	return (query_nodata(qctx, result));
   9356 }
   9357 
   9358 /*
   9359  * Handle CNAME responses.
   9360  */
   9361 static isc_result_t
   9362 query_cname(query_ctx_t *qctx) {
   9363 	isc_result_t result;
   9364 	dns_name_t *tname;
   9365 	dns_rdataset_t *trdataset;
   9366 	dns_rdataset_t **sigrdatasetp = NULL;
   9367 	dns_rdata_t rdata = DNS_RDATA_INIT;
   9368 	dns_rdata_cname_t cname;
   9369 
   9370 	/*
   9371 	 * If we have a zero ttl from the cache refetch it.
   9372 	 */
   9373 	if (!qctx->is_zone && !qctx->resuming && !STALE(qctx->rdataset) &&
   9374 	    qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client))
   9375 	{
   9376 		qctx_clean(qctx);
   9377 
   9378 		INSIST(!REDIRECT(qctx->client));
   9379 
   9380 		result = query_recurse(qctx->client, qctx->qtype,
   9381 				       qctx->client->query.qname,
   9382 				       NULL, NULL, qctx->resuming);
   9383 		if (result == ISC_R_SUCCESS) {
   9384 			qctx->client->query.attributes |=
   9385 				NS_QUERYATTR_RECURSING;
   9386 			if (qctx->dns64)
   9387 				qctx->client->query.attributes |=
   9388 					NS_QUERYATTR_DNS64;
   9389 			if (qctx->dns64_exclude)
   9390 				qctx->client->query.attributes |=
   9391 					NS_QUERYATTR_DNS64EXCLUDE;
   9392 		} else {
   9393 			RECURSE_ERROR(qctx, result);
   9394 		}
   9395 
   9396 		return (query_done(qctx));
   9397 	}
   9398 
   9399 	/*
   9400 	 * Keep a copy of the rdataset.  We have to do this because
   9401 	 * query_addrrset may clear 'rdataset' (to prevent the
   9402 	 * cleanup code from cleaning it up).
   9403 	 */
   9404 	trdataset = qctx->rdataset;
   9405 
   9406 	/*
   9407 	 * Add the CNAME to the answer section.
   9408 	 */
   9409 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL)
   9410 		sigrdatasetp = &qctx->sigrdataset;
   9411 
   9412 	if (WANTDNSSEC(qctx->client) &&
   9413 	    (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
   9414 	{
   9415 		dns_fixedname_init(&qctx->wildcardname);
   9416 		dns_name_copy(qctx->fname,
   9417 			      dns_fixedname_name(&qctx->wildcardname), NULL);
   9418 		qctx->need_wildcardproof = ISC_TRUE;
   9419 	}
   9420 
   9421 	if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
   9422 		qctx->noqname = qctx->rdataset;
   9423 	} else {
   9424 		qctx->noqname = NULL;
   9425 	}
   9426 
   9427 	if (!qctx->is_zone && RECURSIONOK(qctx->client))
   9428 		query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
   9429 
   9430 	query_addrrset(qctx->client, &qctx->fname,
   9431 		       &qctx->rdataset, sigrdatasetp, qctx->dbuf,
   9432 		       DNS_SECTION_ANSWER);
   9433 
   9434 	query_addnoqnameproof(qctx);
   9435 
   9436 	/*
   9437 	 * We set the PARTIALANSWER attribute so that if anything goes
   9438 	 * wrong later on, we'll return what we've got so far.
   9439 	 */
   9440 	qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
   9441 
   9442 	/*
   9443 	 * Reset qname to be the target name of the CNAME and restart
   9444 	 * the query.
   9445 	 */
   9446 	tname = NULL;
   9447 	result = dns_message_gettempname(qctx->client->message, &tname);
   9448 	if (result != ISC_R_SUCCESS)
   9449 		return (query_done(qctx));
   9450 
   9451 	result = dns_rdataset_first(trdataset);
   9452 	if (result != ISC_R_SUCCESS) {
   9453 		dns_message_puttempname(qctx->client->message, &tname);
   9454 		return (query_done(qctx));
   9455 	}
   9456 
   9457 	dns_rdataset_current(trdataset, &rdata);
   9458 	result = dns_rdata_tostruct(&rdata, &cname, NULL);
   9459 	dns_rdata_reset(&rdata);
   9460 	if (result != ISC_R_SUCCESS) {
   9461 		dns_message_puttempname(qctx->client->message, &tname);
   9462 		return (query_done(qctx));
   9463 	}
   9464 
   9465 	dns_name_init(tname, NULL);
   9466 	result = dns_name_dup(&cname.cname, qctx->client->mctx, tname);
   9467 	if (result != ISC_R_SUCCESS) {
   9468 		dns_message_puttempname(qctx->client->message, &tname);
   9469 		dns_rdata_freestruct(&cname);
   9470 		return (query_done(qctx));
   9471 	}
   9472 
   9473 	dns_rdata_freestruct(&cname);
   9474 	ns_client_qnamereplace(qctx->client, tname);
   9475 	qctx->want_restart = ISC_TRUE;
   9476 	if (!WANTRECURSION(qctx->client))
   9477 		qctx->options |= DNS_GETDB_NOLOG;
   9478 
   9479 	query_addauth(qctx);
   9480 
   9481 	return (query_done(qctx));
   9482 }
   9483 
   9484 /*
   9485  * Handle DNAME responses.
   9486  */
   9487 static isc_result_t
   9488 query_dname(query_ctx_t *qctx) {
   9489 	dns_name_t *tname, *prefix;
   9490 	dns_rdata_t rdata = DNS_RDATA_INIT;
   9491 	dns_rdata_dname_t dname;
   9492 	dns_fixedname_t fixed;
   9493 	dns_rdataset_t *trdataset;
   9494 	dns_rdataset_t **sigrdatasetp = NULL;
   9495 	dns_namereln_t namereln;
   9496 	isc_buffer_t b;
   9497 	int order;
   9498 	isc_result_t result;
   9499 	unsigned int nlabels;
   9500 
   9501 	/*
   9502 	 * Compare the current qname to the found name.  We need
   9503 	 * to know how many labels and bits are in common because
   9504 	 * we're going to have to split qname later on.
   9505 	 */
   9506 	namereln = dns_name_fullcompare(qctx->client->query.qname, qctx->fname,
   9507 					&order, &nlabels);
   9508 	INSIST(namereln == dns_namereln_subdomain);
   9509 
   9510 	/*
   9511 	 * Keep a copy of the rdataset.  We have to do this because
   9512 	 * query_addrrset may clear 'rdataset' (to prevent the
   9513 	 * cleanup code from cleaning it up).
   9514 	 */
   9515 	trdataset = qctx->rdataset;
   9516 
   9517 	/*
   9518 	 * Add the DNAME to the answer section.
   9519 	 */
   9520 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL)
   9521 		sigrdatasetp = &qctx->sigrdataset;
   9522 
   9523 	if (WANTDNSSEC(qctx->client) &&
   9524 	    (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
   9525 	{
   9526 		dns_fixedname_init(&qctx->wildcardname);
   9527 		dns_name_copy(qctx->fname,
   9528 			      dns_fixedname_name(&qctx->wildcardname), NULL);
   9529 		qctx->need_wildcardproof = ISC_TRUE;
   9530 	}
   9531 
   9532 	if (!qctx->is_zone && RECURSIONOK(qctx->client))
   9533 		query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
   9534 	query_addrrset(qctx->client, &qctx->fname,
   9535 		       &qctx->rdataset, sigrdatasetp, qctx->dbuf,
   9536 		       DNS_SECTION_ANSWER);
   9537 
   9538 	/*
   9539 	 * We set the PARTIALANSWER attribute so that if anything goes
   9540 	 * wrong later on, we'll return what we've got so far.
   9541 	 */
   9542 	qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
   9543 
   9544 	/*
   9545 	 * Get the target name of the DNAME.
   9546 	 */
   9547 	tname = NULL;
   9548 	result = dns_message_gettempname(qctx->client->message, &tname);
   9549 	if (result != ISC_R_SUCCESS)
   9550 		return (query_done(qctx));
   9551 
   9552 	result = dns_rdataset_first(trdataset);
   9553 	if (result != ISC_R_SUCCESS) {
   9554 		dns_message_puttempname(qctx->client->message, &tname);
   9555 		return (query_done(qctx));
   9556 	}
   9557 
   9558 	dns_rdataset_current(trdataset, &rdata);
   9559 	result = dns_rdata_tostruct(&rdata, &dname, NULL);
   9560 	dns_rdata_reset(&rdata);
   9561 	if (result != ISC_R_SUCCESS) {
   9562 		dns_message_puttempname(qctx->client->message, &tname);
   9563 		return (query_done(qctx));
   9564 	}
   9565 
   9566 	dns_name_clone(&dname.dname, tname);
   9567 	dns_rdata_freestruct(&dname);
   9568 
   9569 	/*
   9570 	 * Construct the new qname consisting of
   9571 	 * <found name prefix>.<dname target>
   9572 	 */
   9573 	prefix = dns_fixedname_initname(&fixed);
   9574 	dns_name_split(qctx->client->query.qname, nlabels, prefix, NULL);
   9575 	INSIST(qctx->fname == NULL);
   9576 	qctx->dbuf = query_getnamebuf(qctx->client);
   9577 	if (qctx->dbuf == NULL) {
   9578 		dns_message_puttempname(qctx->client->message, &tname);
   9579 		return (query_done(qctx));
   9580 	}
   9581 	qctx->fname = query_newname(qctx->client, qctx->dbuf, &b);
   9582 	if (qctx->fname == NULL) {
   9583 		dns_message_puttempname(qctx->client->message, &tname);
   9584 		return (query_done(qctx));
   9585 	}
   9586 	result = dns_name_concatenate(prefix, tname, qctx->fname, NULL);
   9587 	dns_message_puttempname(qctx->client->message, &tname);
   9588 
   9589 	/*
   9590 	 * RFC2672, section 4.1, subsection 3c says
   9591 	 * we should return YXDOMAIN if the constructed
   9592 	 * name would be too long.
   9593 	 */
   9594 	if (result == DNS_R_NAMETOOLONG)
   9595 		qctx->client->message->rcode = dns_rcode_yxdomain;
   9596 	if (result != ISC_R_SUCCESS)
   9597 		return (query_done(qctx));
   9598 
   9599 	query_keepname(qctx->client, qctx->fname, qctx->dbuf);
   9600 
   9601 	/*
   9602 	 * Synthesize a CNAME consisting of
   9603 	 *   <old qname> <dname ttl> CNAME <new qname>
   9604 	 *	    with <dname trust value>
   9605 	 *
   9606 	 * Synthesize a CNAME so old old clients that don't understand
   9607 	 * DNAME can chain.
   9608 	 *
   9609 	 * We do not try to synthesize a signature because we hope
   9610 	 * that security aware servers will understand DNAME.  Also,
   9611 	 * even if we had an online key, making a signature
   9612 	 * on-the-fly is costly, and not really legitimate anyway
   9613 	 * since the synthesized CNAME is NOT in the zone.
   9614 	 */
   9615 	result = query_addcname(qctx, trdataset->trust, trdataset->ttl);
   9616 	if (result != ISC_R_SUCCESS)
   9617 		return (query_done(qctx));
   9618 
   9619 	/*
   9620 	 * Switch to the new qname and restart.
   9621 	 */
   9622 	ns_client_qnamereplace(qctx->client, qctx->fname);
   9623 	qctx->fname = NULL;
   9624 	qctx->want_restart = ISC_TRUE;
   9625 	if (!WANTRECURSION(qctx->client))
   9626 		qctx->options |= DNS_GETDB_NOLOG;
   9627 
   9628 	query_addauth(qctx);
   9629 
   9630 	return (query_done(qctx));
   9631 }
   9632 
   9633 /*%
   9634  * Add CNAME to repsonse.
   9635  */
   9636 static isc_result_t
   9637 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) {
   9638 	ns_client_t *client = qctx->client;
   9639 	dns_rdataset_t *rdataset = NULL;
   9640 	dns_rdatalist_t *rdatalist = NULL;
   9641 	dns_rdata_t *rdata = NULL;
   9642 	isc_region_t r;
   9643 	dns_name_t *aname = NULL;
   9644 	isc_result_t result;
   9645 
   9646 	result = dns_message_gettempname(client->message, &aname);
   9647 	if (result != ISC_R_SUCCESS)
   9648 		return (result);
   9649 	result = dns_name_dup(client->query.qname, client->mctx, aname);
   9650 	if (result != ISC_R_SUCCESS) {
   9651 		dns_message_puttempname(client->message, &aname);
   9652 		return (result);
   9653 	}
   9654 
   9655 	result = dns_message_gettemprdatalist(client->message, &rdatalist);
   9656 	if (result != ISC_R_SUCCESS) {
   9657 		dns_message_puttempname(client->message, &aname);
   9658 		return (result);
   9659 	}
   9660 
   9661 	result = dns_message_gettemprdata(client->message, &rdata);
   9662 	if (result != ISC_R_SUCCESS) {
   9663 		dns_message_puttempname(client->message, &aname);
   9664 		dns_message_puttemprdatalist(client->message, &rdatalist);
   9665 		return (result);
   9666 	}
   9667 
   9668 	result = dns_message_gettemprdataset(client->message, &rdataset);
   9669 	if (result != ISC_R_SUCCESS) {
   9670 		dns_message_puttempname(client->message, &aname);
   9671 		dns_message_puttemprdatalist(client->message, &rdatalist);
   9672 		dns_message_puttemprdata(client->message, &rdata);
   9673 		return (result);
   9674 	}
   9675 
   9676 	rdatalist->type = dns_rdatatype_cname;
   9677 	rdatalist->rdclass = client->message->rdclass;
   9678 	rdatalist->ttl = ttl;
   9679 
   9680 	dns_name_toregion(qctx->fname, &r);
   9681 	rdata->data = r.base;
   9682 	rdata->length = r.length;
   9683 	rdata->rdclass = client->message->rdclass;
   9684 	rdata->type = dns_rdatatype_cname;
   9685 
   9686 	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
   9687 	RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
   9688 		      == ISC_R_SUCCESS);
   9689 	rdataset->trust = trust;
   9690 	dns_rdataset_setownercase(rdataset, aname);
   9691 
   9692 	query_addrrset(client, &aname, &rdataset, NULL, NULL,
   9693 		       DNS_SECTION_ANSWER);
   9694 	if (rdataset != NULL) {
   9695 		if (dns_rdataset_isassociated(rdataset))
   9696 			dns_rdataset_disassociate(rdataset);
   9697 		dns_message_puttemprdataset(client->message, &rdataset);
   9698 	}
   9699 	if (aname != NULL)
   9700 		dns_message_puttempname(client->message, &aname);
   9701 
   9702 	return (ISC_R_SUCCESS);
   9703 }
   9704 
   9705 /*%
   9706  * Prepare to respond: determine whether a wildcard proof is needed,
   9707  * check whether to filter AAAA answers, then hand off to query_respond()
   9708  * or (for type ANY queries) query_respond_any().
   9709  */
   9710 static isc_result_t
   9711 query_prepresponse(query_ctx_t *qctx) {
   9712 	if (WANTDNSSEC(qctx->client) &&
   9713 	    (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
   9714 	{
   9715 		dns_fixedname_init(&qctx->wildcardname);
   9716 		dns_name_copy(qctx->fname,
   9717 			      dns_fixedname_name(&qctx->wildcardname), NULL);
   9718 		qctx->need_wildcardproof = ISC_TRUE;
   9719 	}
   9720 
   9721 	/*
   9722 	 * The filter-aaaa-on-v4 option should suppress AAAAs for IPv4
   9723 	 * clients if there is an A; filter-aaaa-on-v6 option does the same
   9724 	 * for IPv6 clients.
   9725 	 */
   9726 	qctx->client->filter_aaaa = dns_aaaa_ok;
   9727 	if (qctx->client->view->v4_aaaa != dns_aaaa_ok ||
   9728 	    qctx->client->view->v6_aaaa != dns_aaaa_ok)
   9729 	{
   9730 		isc_result_t result;
   9731 		result = ns_client_checkaclsilent(qctx->client, NULL,
   9732 						  qctx->client->view->aaaa_acl,
   9733 						  ISC_TRUE);
   9734 		if (result == ISC_R_SUCCESS &&
   9735 		    qctx->client->view->v4_aaaa != dns_aaaa_ok &&
   9736 		    is_v4_client(qctx->client))
   9737 			qctx->client->filter_aaaa = qctx->client->view->v4_aaaa;
   9738 		else if (result == ISC_R_SUCCESS &&
   9739 			 qctx->client->view->v6_aaaa != dns_aaaa_ok &&
   9740 			 is_v6_client(qctx->client))
   9741 			qctx->client->filter_aaaa = qctx->client->view->v6_aaaa;
   9742 	}
   9743 
   9744 
   9745 	if (qctx->type == dns_rdatatype_any) {
   9746 		return (query_respond_any(qctx));
   9747 	} else {
   9748 		return (query_respond(qctx));
   9749 	}
   9750 }
   9751 
   9752 /*%
   9753  * Add SOA to the authority section when sending negative responses
   9754  * (or to the additional section if sending negative responses triggered
   9755  * by RPZ rewriting.)
   9756  */
   9757 static isc_result_t
   9758 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl,
   9759 	     dns_section_t section)
   9760 {
   9761 	ns_client_t *client = qctx->client;
   9762 	dns_name_t *name;
   9763 	dns_dbnode_t *node;
   9764 	isc_result_t result, eresult;
   9765 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
   9766 	dns_rdataset_t **sigrdatasetp = NULL;
   9767 	dns_clientinfomethods_t cm;
   9768 	dns_clientinfo_t ci;
   9769 
   9770 	CTRACE(ISC_LOG_DEBUG(3), "query_addsoa");
   9771 	/*
   9772 	 * Initialization.
   9773 	 */
   9774 	eresult = ISC_R_SUCCESS;
   9775 	name = NULL;
   9776 	rdataset = NULL;
   9777 	node = NULL;
   9778 
   9779 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   9780 	dns_clientinfo_init(&ci, client, NULL);
   9781 
   9782 	/*
   9783 	 * Don't add the SOA record for test which set "-T nosoa".
   9784 	 */
   9785 	if (((client->sctx->options & NS_SERVER_NOSOA) != 0) &&
   9786 	    (!WANTDNSSEC(client) || !dns_rdataset_isassociated(qctx->rdataset)))
   9787 	{
   9788 		return (ISC_R_SUCCESS);
   9789 	}
   9790 
   9791 	/*
   9792 	 * Get resources and make 'name' be the database origin.
   9793 	 */
   9794 	result = dns_message_gettempname(client->message, &name);
   9795 	if (result != ISC_R_SUCCESS)
   9796 		return (result);
   9797 	dns_name_init(name, NULL);
   9798 	dns_name_clone(dns_db_origin(qctx->db), name);
   9799 	rdataset = query_newrdataset(client);
   9800 	if (rdataset == NULL) {
   9801 		CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset");
   9802 		eresult = DNS_R_SERVFAIL;
   9803 		goto cleanup;
   9804 	}
   9805 	if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
   9806 		sigrdataset = query_newrdataset(client);
   9807 		if (sigrdataset == NULL) {
   9808 			CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset");
   9809 			eresult = DNS_R_SERVFAIL;
   9810 			goto cleanup;
   9811 		}
   9812 	}
   9813 
   9814 	/*
   9815 	 * Find the SOA.
   9816 	 */
   9817 	result = dns_db_getoriginnode(qctx->db, &node);
   9818 	if (result == ISC_R_SUCCESS) {
   9819 		result = dns_db_findrdataset(qctx->db, node, qctx->version,
   9820 					     dns_rdatatype_soa, 0,
   9821 					     client->now,
   9822 					     rdataset, sigrdataset);
   9823 	} else {
   9824 		dns_fixedname_t foundname;
   9825 		dns_name_t *fname;
   9826 
   9827 		fname = dns_fixedname_initname(&foundname);
   9828 
   9829 		result = dns_db_findext(qctx->db, name, qctx->version,
   9830 					dns_rdatatype_soa,
   9831 					client->query.dboptions,
   9832 					0, &node, fname, &cm, &ci,
   9833 					rdataset, sigrdataset);
   9834 	}
   9835 	if (result != ISC_R_SUCCESS) {
   9836 		/*
   9837 		 * This is bad.  We tried to get the SOA RR at the zone top
   9838 		 * and it didn't work!
   9839 		 */
   9840 		CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex");
   9841 		eresult = DNS_R_SERVFAIL;
   9842 	} else {
   9843 		/*
   9844 		 * Extract the SOA MINIMUM.
   9845 		 */
   9846 		dns_rdata_soa_t soa;
   9847 		dns_rdata_t rdata = DNS_RDATA_INIT;
   9848 		result = dns_rdataset_first(rdataset);
   9849 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9850 		dns_rdataset_current(rdataset, &rdata);
   9851 		result = dns_rdata_tostruct(&rdata, &soa, NULL);
   9852 		if (result != ISC_R_SUCCESS)
   9853 			goto cleanup;
   9854 
   9855 		if (override_ttl != ISC_UINT32_MAX &&
   9856 		    override_ttl < rdataset->ttl)
   9857 		{
   9858 			rdataset->ttl = override_ttl;
   9859 			if (sigrdataset != NULL)
   9860 				sigrdataset->ttl = override_ttl;
   9861 		}
   9862 
   9863 		/*
   9864 		 * Add the SOA and its SIG to the response, with the
   9865 		 * TTLs adjusted per RFC2308 section 3.
   9866 		 */
   9867 		if (rdataset->ttl > soa.minimum)
   9868 			rdataset->ttl = soa.minimum;
   9869 		if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum)
   9870 			sigrdataset->ttl = soa.minimum;
   9871 
   9872 		if (sigrdataset != NULL)
   9873 			sigrdatasetp = &sigrdataset;
   9874 		else
   9875 			sigrdatasetp = NULL;
   9876 
   9877 		if (section == DNS_SECTION_ADDITIONAL)
   9878 			rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
   9879 		query_addrrset(client, &name, &rdataset,
   9880 			       sigrdatasetp, NULL, section);
   9881 	}
   9882 
   9883  cleanup:
   9884 	query_putrdataset(client, &rdataset);
   9885 	if (sigrdataset != NULL)
   9886 		query_putrdataset(client, &sigrdataset);
   9887 	if (name != NULL)
   9888 		query_releasename(client, &name);
   9889 	if (node != NULL)
   9890 		dns_db_detachnode(qctx->db, &node);
   9891 
   9892 	return (eresult);
   9893 }
   9894 
   9895 /*%
   9896  * Add NS to authority section (used when the zone apex is already known).
   9897  */
   9898 static isc_result_t
   9899 query_addns(query_ctx_t *qctx) {
   9900 	ns_client_t *client = qctx->client;
   9901 	isc_result_t result, eresult;
   9902 	dns_name_t *name = NULL, *fname;
   9903 	dns_dbnode_t *node = NULL;
   9904 	dns_fixedname_t foundname;
   9905 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
   9906 	dns_rdataset_t **sigrdatasetp = NULL;
   9907 	dns_clientinfomethods_t cm;
   9908 	dns_clientinfo_t ci;
   9909 
   9910 	CTRACE(ISC_LOG_DEBUG(3), "query_addns");
   9911 
   9912 	/*
   9913 	 * Initialization.
   9914 	 */
   9915 	eresult = ISC_R_SUCCESS;
   9916 	fname = dns_fixedname_initname(&foundname);
   9917 
   9918 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   9919 	dns_clientinfo_init(&ci, client, NULL);
   9920 
   9921 	/*
   9922 	 * Get resources and make 'name' be the database origin.
   9923 	 */
   9924 	result = dns_message_gettempname(client->message, &name);
   9925 	if (result != ISC_R_SUCCESS) {
   9926 		CTRACE(ISC_LOG_DEBUG(3),
   9927 		       "query_addns: dns_message_gettempname failed: done");
   9928 		return (result);
   9929 	}
   9930 	dns_name_init(name, NULL);
   9931 	dns_name_clone(dns_db_origin(qctx->db), name);
   9932 	rdataset = query_newrdataset(client);
   9933 	if (rdataset == NULL) {
   9934 		CTRACE(ISC_LOG_ERROR,
   9935 		       "query_addns: query_newrdataset failed");
   9936 		eresult = DNS_R_SERVFAIL;
   9937 		goto cleanup;
   9938 	}
   9939 
   9940 	if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
   9941 		sigrdataset = query_newrdataset(client);
   9942 		if (sigrdataset == NULL) {
   9943 			CTRACE(ISC_LOG_ERROR,
   9944 			       "query_addns: query_newrdataset failed");
   9945 			eresult = DNS_R_SERVFAIL;
   9946 			goto cleanup;
   9947 		}
   9948 	}
   9949 
   9950 	/*
   9951 	 * Find the NS rdataset.
   9952 	 */
   9953 	result = dns_db_getoriginnode(qctx->db, &node);
   9954 	if (result == ISC_R_SUCCESS) {
   9955 		result = dns_db_findrdataset(qctx->db, node, qctx->version,
   9956 					     dns_rdatatype_ns, 0, client->now,
   9957 					     rdataset, sigrdataset);
   9958 	} else {
   9959 		CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find");
   9960 		result = dns_db_findext(qctx->db, name, NULL, dns_rdatatype_ns,
   9961 					client->query.dboptions, 0, &node,
   9962 					fname, &cm, &ci, rdataset, sigrdataset);
   9963 		CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete");
   9964 	}
   9965 	if (result != ISC_R_SUCCESS) {
   9966 		CTRACE(ISC_LOG_ERROR,
   9967 		       "query_addns: "
   9968 		       "dns_db_findrdataset or dns_db_find failed");
   9969 		/*
   9970 		 * This is bad.  We tried to get the NS rdataset at the zone
   9971 		 * top and it didn't work!
   9972 		 */
   9973 		eresult = DNS_R_SERVFAIL;
   9974 	} else {
   9975 		if (sigrdataset != NULL) {
   9976 			sigrdatasetp = &sigrdataset;
   9977 		}
   9978 		query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,
   9979 			       DNS_SECTION_AUTHORITY);
   9980 	}
   9981 
   9982  cleanup:
   9983 	CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup");
   9984 	query_putrdataset(client, &rdataset);
   9985 	if (sigrdataset != NULL) {
   9986 		query_putrdataset(client, &sigrdataset);
   9987 	}
   9988 	if (name != NULL) {
   9989 		query_releasename(client, &name);
   9990 	}
   9991 	if (node != NULL) {
   9992 		dns_db_detachnode(qctx->db, &node);
   9993 	}
   9994 
   9995 	CTRACE(ISC_LOG_DEBUG(3), "query_addns: done");
   9996 	return (eresult);
   9997 }
   9998 
   9999 /*%
   10000  * Find the zone cut and add the best NS rrset to the authority section.
   10001  */
   10002 static void
   10003 query_addbestns(query_ctx_t *qctx) {
   10004 	ns_client_t *client = qctx->client;
   10005 	dns_db_t *db = NULL, *zdb = NULL;
   10006 	dns_dbnode_t *node = NULL;
   10007 	dns_name_t *fname = NULL, *zfname = NULL;
   10008 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
   10009 	dns_rdataset_t *zrdataset = NULL, *zsigrdataset = NULL;
   10010 	isc_boolean_t is_zone = ISC_FALSE, use_zone = ISC_FALSE;
   10011 	isc_buffer_t *dbuf = NULL;
   10012 	isc_result_t result;
   10013 	dns_dbversion_t *version = NULL;
   10014 	dns_zone_t *zone = NULL;
   10015 	isc_buffer_t b;
   10016 	dns_clientinfomethods_t cm;
   10017 	dns_clientinfo_t ci;
   10018 
   10019 	CTRACE(ISC_LOG_DEBUG(3), "query_addbestns");
   10020 
   10021 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   10022 	dns_clientinfo_init(&ci, client, NULL);
   10023 
   10024 	/*
   10025 	 * Find the right database.
   10026 	 */
   10027 	result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0,
   10028 			     &zone, &db, &version, &is_zone);
   10029 	if (result != ISC_R_SUCCESS)
   10030 		goto cleanup;
   10031 
   10032  db_find:
   10033 	/*
   10034 	 * We'll need some resources...
   10035 	 */
   10036 	dbuf = query_getnamebuf(client);
   10037 	if (dbuf == NULL) {
   10038 		goto cleanup;
   10039 	}
   10040 	fname = query_newname(client, dbuf, &b);
   10041 	rdataset = query_newrdataset(client);
   10042 	if (fname == NULL || rdataset == NULL) {
   10043 		goto cleanup;
   10044 	}
   10045 
   10046 	/*
   10047 	 * Get the RRSIGs if the client requested them or if we may
   10048 	 * need to validate answers from the cache.
   10049 	 */
   10050 	if (WANTDNSSEC(client) || !is_zone) {
   10051 		sigrdataset = query_newrdataset(client);
   10052 		if (sigrdataset == NULL) {
   10053 			goto cleanup;
   10054 		}
   10055 	}
   10056 
   10057 	/*
   10058 	 * Now look for the zonecut.
   10059 	 */
   10060 	if (is_zone) {
   10061 		result = dns_db_findext(db, client->query.qname, version,
   10062 					dns_rdatatype_ns,
   10063 					client->query.dboptions,
   10064 					client->now, &node, fname,
   10065 					&cm, &ci, rdataset, sigrdataset);
   10066 		if (result != DNS_R_DELEGATION) {
   10067 			goto cleanup;
   10068 		}
   10069 		if (USECACHE(client)) {
   10070 			query_keepname(client, fname, dbuf);
   10071 			dns_db_detachnode(db, &node);
   10072 			SAVE(zdb, db);
   10073 			SAVE(zfname, fname);
   10074 			SAVE(zrdataset, rdataset);
   10075 			SAVE(zsigrdataset, sigrdataset);
   10076 			version = NULL;
   10077 			dns_db_attach(client->view->cachedb, &db);
   10078 			is_zone = ISC_FALSE;
   10079 			goto db_find;
   10080 		}
   10081 	} else {
   10082 		result = dns_db_findzonecut(db, client->query.qname,
   10083 					    client->query.dboptions,
   10084 					    client->now, &node, fname,
   10085 					    rdataset, sigrdataset);
   10086 		if (result == ISC_R_SUCCESS) {
   10087 			if (zfname != NULL &&
   10088 			    !dns_name_issubdomain(fname, zfname)) {
   10089 				/*
   10090 				 * We found a zonecut in the cache, but our
   10091 				 * zone delegation is better.
   10092 				 */
   10093 				use_zone = ISC_TRUE;
   10094 			}
   10095 		} else if (result == ISC_R_NOTFOUND && zfname != NULL) {
   10096 			/*
   10097 			 * We didn't find anything in the cache, but we
   10098 			 * have a zone delegation, so use it.
   10099 			 */
   10100 			use_zone = ISC_TRUE;
   10101 		} else {
   10102 			goto cleanup;
   10103 		}
   10104 	}
   10105 
   10106 	if (use_zone) {
   10107 		query_releasename(client, &fname);
   10108 		/*
   10109 		 * We've already done query_keepname() on
   10110 		 * zfname, so we must set dbuf to NULL to
   10111 		 * prevent query_addrrset() from trying to
   10112 		 * call query_keepname() again.
   10113 		 */
   10114 		dbuf = NULL;
   10115 		query_putrdataset(client, &rdataset);
   10116 		if (sigrdataset != NULL) {
   10117 			query_putrdataset(client, &sigrdataset);
   10118 		}
   10119 
   10120 		if (node != NULL) {
   10121 			dns_db_detachnode(db, &node);
   10122 		}
   10123 		dns_db_detach(&db);
   10124 
   10125 		RESTORE(db, zdb);
   10126 		RESTORE(fname, zfname);
   10127 		RESTORE(rdataset, zrdataset);
   10128 		RESTORE(sigrdataset, zsigrdataset);
   10129 	}
   10130 
   10131 	/*
   10132 	 * Attempt to validate RRsets that are pending or that are glue.
   10133 	 */
   10134 	if ((DNS_TRUST_PENDING(rdataset->trust) ||
   10135 	     (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) &&
   10136 	    !validate(client, db, fname, rdataset, sigrdataset) &&
   10137 	    !PENDINGOK(client->query.dboptions))
   10138 	{
   10139 		goto cleanup;
   10140 	}
   10141 
   10142 	if ((DNS_TRUST_GLUE(rdataset->trust) ||
   10143 	     (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
   10144 	    !validate(client, db, fname, rdataset, sigrdataset) &&
   10145 	    SECURE(client) && WANTDNSSEC(client))
   10146 	{
   10147 		goto cleanup;
   10148 	}
   10149 
   10150 	/*
   10151 	 * If the answer is secure only add NS records if they are secure
   10152 	 * when the client may be looking for AD in the response.
   10153 	 */
   10154 	if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) &&
   10155 	    ((rdataset->trust != dns_trust_secure) ||
   10156 	    (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure)))
   10157 	{
   10158 		goto cleanup;
   10159 	}
   10160 
   10161 	/*
   10162 	 * If the client doesn't want DNSSEC we can discard the sigrdataset
   10163 	 * now.
   10164 	 */
   10165 	if (!WANTDNSSEC(client)) {
   10166 		query_putrdataset(client, &sigrdataset);
   10167 	}
   10168 
   10169 	query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
   10170 		       DNS_SECTION_AUTHORITY);
   10171 
   10172  cleanup:
   10173 	if (rdataset != NULL) {
   10174 		query_putrdataset(client, &rdataset);
   10175 	}
   10176 	if (sigrdataset != NULL) {
   10177 		query_putrdataset(client, &sigrdataset);
   10178 	}
   10179 	if (fname != NULL) {
   10180 		query_releasename(client, &fname);
   10181 	}
   10182 	if (node != NULL) {
   10183 		dns_db_detachnode(db, &node);
   10184 	}
   10185 	if (db != NULL) {
   10186 		dns_db_detach(&db);
   10187 	}
   10188 	if (zone != NULL) {
   10189 		dns_zone_detach(&zone);
   10190 	}
   10191 	if (zdb != NULL) {
   10192 		query_putrdataset(client, &zrdataset);
   10193 		if (zsigrdataset != NULL)
   10194 			query_putrdataset(client, &zsigrdataset);
   10195 		if (zfname != NULL)
   10196 			query_releasename(client, &zfname);
   10197 		dns_db_detach(&zdb);
   10198 	}
   10199 }
   10200 
   10201 static void
   10202 query_addwildcardproof(query_ctx_t *qctx, isc_boolean_t ispositive,
   10203 		       isc_boolean_t nodata)
   10204 {
   10205 	ns_client_t *client = qctx->client;
   10206 	isc_buffer_t *dbuf, b;
   10207 	dns_name_t *name;
   10208 	dns_name_t *fname = NULL;
   10209 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
   10210 	dns_fixedname_t wfixed;
   10211 	dns_name_t *wname;
   10212 	dns_dbnode_t *node = NULL;
   10213 	unsigned int options;
   10214 	unsigned int olabels, nlabels, labels;
   10215 	isc_result_t result;
   10216 	dns_rdata_t rdata = DNS_RDATA_INIT;
   10217 	dns_rdata_nsec_t nsec;
   10218 	isc_boolean_t have_wname;
   10219 	int order;
   10220 	dns_fixedname_t cfixed;
   10221 	dns_name_t *cname;
   10222 	dns_clientinfomethods_t cm;
   10223 	dns_clientinfo_t ci;
   10224 
   10225 	CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof");
   10226 
   10227 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
   10228 	dns_clientinfo_init(&ci, client, NULL);
   10229 
   10230 	/*
   10231 	 * If a name has been specifically flagged as needing
   10232 	 * a wildcard proof then it will have been copied to
   10233 	 * qctx->wildcardname. Otherwise we just use the client
   10234 	 * QNAME.
   10235 	 */
   10236 	if (qctx->need_wildcardproof) {
   10237 		name = dns_fixedname_name(&qctx->wildcardname);
   10238 	} else {
   10239 		name = client->query.qname;
   10240 	}
   10241 
   10242 	/*
   10243 	 * Get the NOQNAME proof then if !ispositive
   10244 	 * get the NOWILDCARD proof.
   10245 	 *
   10246 	 * DNS_DBFIND_NOWILD finds the NSEC records that covers the
   10247 	 * name ignoring any wildcard.  From the owner and next names
   10248 	 * of this record you can compute which wildcard (if it exists)
   10249 	 * will match by finding the longest common suffix of the
   10250 	 * owner name and next names with the qname and prefixing that
   10251 	 * with the wildcard label.
   10252 	 *
   10253 	 * e.g.
   10254 	 *   Given:
   10255 	 *	example SOA
   10256 	 *	example NSEC b.example
   10257 	 *	b.example A
   10258 	 *	b.example NSEC a.d.example
   10259 	 *	a.d.example A
   10260 	 *	a.d.example NSEC g.f.example
   10261 	 *	g.f.example A
   10262 	 *	g.f.example NSEC z.i.example
   10263 	 *	z.i.example A
   10264 	 *	z.i.example NSEC example
   10265 	 *
   10266 	 *   QNAME:
   10267 	 *   a.example -> example NSEC b.example
   10268 	 *	owner common example
   10269 	 *	next common example
   10270 	 *	wild *.example
   10271 	 *   d.b.example -> b.example NSEC a.d.example
   10272 	 *	owner common b.example
   10273 	 *	next common example
   10274 	 *	wild *.b.example
   10275 	 *   a.f.example -> a.d.example NSEC g.f.example
   10276 	 *	owner common example
   10277 	 *	next common f.example
   10278 	 *	wild *.f.example
   10279 	 *  j.example -> z.i.example NSEC example
   10280 	 *	owner common example
   10281 	 *	next common example
   10282 	 *	wild *.example
   10283 	 */
   10284 	options = client->query.dboptions | DNS_DBFIND_NOWILD;
   10285 	wname = dns_fixedname_initname(&wfixed);
   10286  again:
   10287 	have_wname = ISC_FALSE;
   10288 	/*
   10289 	 * We'll need some resources...
   10290 	 */
   10291 	dbuf = query_getnamebuf(client);
   10292 	if (dbuf == NULL)
   10293 		goto cleanup;
   10294 	fname = query_newname(client, dbuf, &b);
   10295 	rdataset = query_newrdataset(client);
   10296 	sigrdataset = query_newrdataset(client);
   10297 	if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
   10298 		goto cleanup;
   10299 
   10300 	result = dns_db_findext(qctx->db, name, qctx->version,
   10301 				dns_rdatatype_nsec, options, 0, &node,
   10302 				fname, &cm, &ci, rdataset, sigrdataset);
   10303 	if (node != NULL)
   10304 		dns_db_detachnode(qctx->db, &node);
   10305 
   10306 	if (!dns_rdataset_isassociated(rdataset)) {
   10307 		/*
   10308 		 * No NSEC proof available, return NSEC3 proofs instead.
   10309 		 */
   10310 		cname = dns_fixedname_initname(&cfixed);
   10311 		/*
   10312 		 * Find the closest encloser.
   10313 		 */
   10314 		dns_name_copy(name, cname, NULL);
   10315 		while (result == DNS_R_NXDOMAIN) {
   10316 			labels = dns_name_countlabels(cname) - 1;
   10317 			/*
   10318 			 * Sanity check.
   10319 			 */
   10320 			if (labels == 0U)
   10321 				goto cleanup;
   10322 			dns_name_split(cname, labels, NULL, cname);
   10323 			result = dns_db_findext(qctx->db, cname, qctx->version,
   10324 						dns_rdatatype_nsec,
   10325 						options, 0, NULL, fname,
   10326 						&cm, &ci, NULL, NULL);
   10327 		}
   10328 		/*
   10329 		 * Add closest (provable) encloser NSEC3.
   10330 		 */
   10331 		query_findclosestnsec3(cname, qctx->db, qctx->version,
   10332 				       client, rdataset, sigrdataset,
   10333 				       fname, ISC_TRUE, cname);
   10334 		if (!dns_rdataset_isassociated(rdataset))
   10335 			goto cleanup;
   10336 		if (!ispositive)
   10337 			query_addrrset(client, &fname, &rdataset, &sigrdataset,
   10338 				       dbuf, DNS_SECTION_AUTHORITY);
   10339 
   10340 		/*
   10341 		 * Replace resources which were consumed by query_addrrset.
   10342 		 */
   10343 		if (fname == NULL) {
   10344 			dbuf = query_getnamebuf(client);
   10345 			if (dbuf == NULL)
   10346 				goto cleanup;
   10347 			fname = query_newname(client, dbuf, &b);
   10348 		}
   10349 
   10350 		if (rdataset == NULL)
   10351 			rdataset = query_newrdataset(client);
   10352 		else if (dns_rdataset_isassociated(rdataset))
   10353 			dns_rdataset_disassociate(rdataset);
   10354 
   10355 		if (sigrdataset == NULL)
   10356 			sigrdataset = query_newrdataset(client);
   10357 		else if (dns_rdataset_isassociated(sigrdataset))
   10358 			dns_rdataset_disassociate(sigrdataset);
   10359 
   10360 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
   10361 			goto cleanup;
   10362 		/*
   10363 		 * Add no qname proof.
   10364 		 */
   10365 		labels = dns_name_countlabels(cname) + 1;
   10366 		if (dns_name_countlabels(name) == labels)
   10367 			dns_name_copy(name, wname, NULL);
   10368 		else
   10369 			dns_name_split(name, labels, NULL, wname);
   10370 
   10371 		query_findclosestnsec3(wname, qctx->db, qctx->version,
   10372 				       client, rdataset, sigrdataset,
   10373 				       fname, ISC_FALSE, NULL);
   10374 		if (!dns_rdataset_isassociated(rdataset))
   10375 			goto cleanup;
   10376 		query_addrrset(client, &fname, &rdataset, &sigrdataset,
   10377 			       dbuf, DNS_SECTION_AUTHORITY);
   10378 
   10379 		if (ispositive)
   10380 			goto cleanup;
   10381 
   10382 		/*
   10383 		 * Replace resources which were consumed by query_addrrset.
   10384 		 */
   10385 		if (fname == NULL) {
   10386 			dbuf = query_getnamebuf(client);
   10387 			if (dbuf == NULL)
   10388 				goto cleanup;
   10389 			fname = query_newname(client, dbuf, &b);
   10390 		}
   10391 
   10392 		if (rdataset == NULL)
   10393 			rdataset = query_newrdataset(client);
   10394 		else if (dns_rdataset_isassociated(rdataset))
   10395 			dns_rdataset_disassociate(rdataset);
   10396 
   10397 		if (sigrdataset == NULL)
   10398 			sigrdataset = query_newrdataset(client);
   10399 		else if (dns_rdataset_isassociated(sigrdataset))
   10400 			dns_rdataset_disassociate(sigrdataset);
   10401 
   10402 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
   10403 			goto cleanup;
   10404 		/*
   10405 		 * Add the no wildcard proof.
   10406 		 */
   10407 		result = dns_name_concatenate(dns_wildcardname,
   10408 					      cname, wname, NULL);
   10409 		if (result != ISC_R_SUCCESS)
   10410 			goto cleanup;
   10411 
   10412 		query_findclosestnsec3(wname, qctx->db, qctx->version,
   10413 				       client, rdataset, sigrdataset,
   10414 				       fname, nodata, NULL);
   10415 		if (!dns_rdataset_isassociated(rdataset))
   10416 			goto cleanup;
   10417 		query_addrrset(client, &fname, &rdataset, &sigrdataset,
   10418 			       dbuf, DNS_SECTION_AUTHORITY);
   10419 
   10420 		goto cleanup;
   10421 	} else if (result == DNS_R_NXDOMAIN) {
   10422 		if (!ispositive)
   10423 			result = dns_rdataset_first(rdataset);
   10424 		if (result == ISC_R_SUCCESS) {
   10425 			dns_rdataset_current(rdataset, &rdata);
   10426 			result = dns_rdata_tostruct(&rdata, &nsec, NULL);
   10427 		}
   10428 		if (result == ISC_R_SUCCESS) {
   10429 			(void)dns_name_fullcompare(name, fname, &order,
   10430 						   &olabels);
   10431 			(void)dns_name_fullcompare(name, &nsec.next, &order,
   10432 						   &nlabels);
   10433 			/*
   10434 			 * Check for a pathological condition created when
   10435 			 * serving some malformed signed zones and bail out.
   10436 			 */
   10437 			if (dns_name_countlabels(name) == nlabels)
   10438 				goto cleanup;
   10439 
   10440 			if (olabels > nlabels)
   10441 				dns_name_split(name, olabels, NULL, wname);
   10442 			else
   10443 				dns_name_split(name, nlabels, NULL, wname);
   10444 			result = dns_name_concatenate(dns_wildcardname,
   10445 						      wname, wname, NULL);
   10446 			if (result == ISC_R_SUCCESS)
   10447 				have_wname = ISC_TRUE;
   10448 			dns_rdata_freestruct(&nsec);
   10449 		}
   10450 		query_addrrset(client, &fname, &rdataset, &sigrdataset,
   10451 			       dbuf, DNS_SECTION_AUTHORITY);
   10452 	}
   10453 	if (rdataset != NULL)
   10454 		query_putrdataset(client, &rdataset);
   10455 	if (sigrdataset != NULL)
   10456 		query_putrdataset(client, &sigrdataset);
   10457 	if (fname != NULL)
   10458 		query_releasename(client, &fname);
   10459 	if (have_wname) {
   10460 		ispositive = ISC_TRUE;	/* prevent loop */
   10461 		if (!dns_name_equal(name, wname)) {
   10462 			name = wname;
   10463 			goto again;
   10464 		}
   10465 	}
   10466  cleanup:
   10467 	if (rdataset != NULL)
   10468 		query_putrdataset(client, &rdataset);
   10469 	if (sigrdataset != NULL)
   10470 		query_putrdataset(client, &sigrdataset);
   10471 	if (fname != NULL)
   10472 		query_releasename(client, &fname);
   10473 }
   10474 
   10475 /*%
   10476  * Add NS records, and NSEC/NSEC3 wildcard proof records if needed,
   10477  * to the authority section.
   10478  */
   10479 static void
   10480 query_addauth(query_ctx_t *qctx) {
   10481 	CCTRACE(ISC_LOG_DEBUG(3), "query_addauth");
   10482 	/*
   10483 	 * Add NS records to the authority section (if we haven't already
   10484 	 * added them to the answer section).
   10485 	 */
   10486 	if (!qctx->want_restart && !NOAUTHORITY(qctx->client)) {
   10487 		if (qctx->is_zone) {
   10488 			if (!qctx->answer_has_ns) {
   10489 				(void)query_addns(qctx);
   10490 			}
   10491 		} else if (!qctx->answer_has_ns &&
   10492 			   qctx->qtype != dns_rdatatype_ns)
   10493 		{
   10494 			if (qctx->fname != NULL) {
   10495 				query_releasename(qctx->client, &qctx->fname);
   10496 			}
   10497 			query_addbestns(qctx);
   10498 		}
   10499 	}
   10500 
   10501 	/*
   10502 	 * Add NSEC records to the authority section if they're needed for
   10503 	 * DNSSEC wildcard proofs.
   10504 	 */
   10505 	if (qctx->need_wildcardproof && dns_db_issecure(qctx->db))
   10506 		query_addwildcardproof(qctx, ISC_TRUE, ISC_FALSE);
   10507 }
   10508 
   10509 /*
   10510  * Find the sort order of 'rdata' in the topology-like
   10511  * ACL forming the second element in a 2-element top-level
   10512  * sortlist statement.
   10513  */
   10514 static int
   10515 query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) {
   10516 	isc_netaddr_t netaddr;
   10517 
   10518 	if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
   10519 		return (INT_MAX);
   10520 	return (ns_sortlist_addrorder2(&netaddr, arg));
   10521 }
   10522 
   10523 /*
   10524  * Find the sort order of 'rdata' in the matching element
   10525  * of a 1-element top-level sortlist statement.
   10526  */
   10527 static int
   10528 query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) {
   10529 	isc_netaddr_t netaddr;
   10530 
   10531 	if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
   10532 		return (INT_MAX);
   10533 	return (ns_sortlist_addrorder1(&netaddr, arg));
   10534 }
   10535 
   10536 /*
   10537  * Find the sortlist statement that applies to 'client' and set up
   10538  * the sortlist info in in client->message appropriately.
   10539  */
   10540 static void
   10541 query_setup_sortlist(query_ctx_t *qctx) {
   10542 	isc_netaddr_t netaddr;
   10543 	ns_client_t *client = qctx->client;
   10544 	dns_aclenv_t *env = ns_interfacemgr_getaclenv(client->interface->mgr);
   10545 	const void *order_arg = NULL;
   10546 
   10547 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
   10548 	switch (ns_sortlist_setup(client->view->sortlist, env,
   10549 				  &netaddr, &order_arg))
   10550 	{
   10551 	case NS_SORTLISTTYPE_1ELEMENT:
   10552 		dns_message_setsortorder(client->message,
   10553 					 query_sortlist_order_1element,
   10554 					 env, NULL, order_arg);
   10555 		break;
   10556 	case NS_SORTLISTTYPE_2ELEMENT:
   10557 		dns_message_setsortorder(client->message,
   10558 					 query_sortlist_order_2element,
   10559 					 env, order_arg, NULL);
   10560 		break;
   10561 	case NS_SORTLISTTYPE_NONE:
   10562 		break;
   10563 	default:
   10564 		INSIST(0);
   10565 		break;
   10566 	}
   10567 }
   10568 
   10569 /*
   10570  * When sending a referral, if the answer to the question is
   10571  * in the glue, sort it to the start of the additional section.
   10572  */
   10573 static inline void
   10574 query_glueanswer(query_ctx_t *qctx) {
   10575 	const dns_namelist_t *secs = qctx->client->message->sections;
   10576 	const dns_section_t section = DNS_SECTION_ADDITIONAL;
   10577 	dns_name_t *name;
   10578 	dns_message_t *msg;
   10579 	dns_rdataset_t *rdataset = NULL;
   10580 
   10581 	if (!ISC_LIST_EMPTY(secs[DNS_SECTION_ANSWER]) ||
   10582 	    qctx->client->message->rcode != dns_rcode_noerror ||
   10583 	    (qctx->qtype != dns_rdatatype_a &&
   10584 	     qctx->qtype != dns_rdatatype_aaaa))
   10585 	{
   10586 		return;
   10587 	}
   10588 
   10589 	msg = qctx->client->message;
   10590 	for (name = ISC_LIST_HEAD(msg->sections[section]);
   10591 	     name != NULL;
   10592 	     name = ISC_LIST_NEXT(name, link))
   10593 		if (dns_name_equal(name, qctx->client->query.qname)) {
   10594 			for (rdataset = ISC_LIST_HEAD(name->list);
   10595 			     rdataset != NULL;
   10596 			     rdataset = ISC_LIST_NEXT(rdataset, link))
   10597 				if (rdataset->type == qctx->qtype)
   10598 					break;
   10599 			break;
   10600 		}
   10601 	if (rdataset != NULL) {
   10602 		ISC_LIST_UNLINK(msg->sections[section], name, link);
   10603 		ISC_LIST_PREPEND(msg->sections[section], name, link);
   10604 		ISC_LIST_UNLINK(name->list, rdataset, link);
   10605 		ISC_LIST_PREPEND(name->list, rdataset, link);
   10606 		rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
   10607 	}
   10608 }
   10609 
   10610 /*%
   10611  * Finalize this phase of the query process:
   10612  *
   10613  * - Clean up
   10614  * - If we have an answer ready (positive or negative), send it.
   10615  * - If we need to restart for a chaining query, call ns__query_start() again.
   10616  * - If we've started recursion, then just clean up; things will be
   10617  *   restarted via fetch_callback()/query_resume().
   10618  */
   10619 static isc_result_t
   10620 query_done(query_ctx_t *qctx) {
   10621 	const dns_namelist_t *secs = qctx->client->message->sections;
   10622 	CCTRACE(ISC_LOG_DEBUG(3), "query_done");
   10623 
   10624 	PROCESS_HOOK(NS_QUERY_DONE_BEGIN, qctx);
   10625 
   10626 	/*
   10627 	 * General cleanup.
   10628 	 */
   10629 	qctx->rpz_st = qctx->client->query.rpz_st;
   10630 	if (qctx->rpz_st != NULL &&
   10631 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) == 0)
   10632 	{
   10633 		rpz_match_clear(qctx->rpz_st);
   10634 		qctx->rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
   10635 	}
   10636 
   10637 	qctx_clean(qctx);
   10638 	qctx_freedata(qctx);
   10639 
   10640 	/*
   10641 	 * Clear the AA bit if we're not authoritative.
   10642 	 */
   10643 	if (qctx->client->query.restarts == 0 && !qctx->authoritative) {
   10644 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
   10645 	}
   10646 
   10647 	/*
   10648 	 * Do we need to restart the query (e.g. for CNAME chaining)?
   10649 	 */
   10650 	if (qctx->want_restart && qctx->client->query.restarts < MAX_RESTARTS) {
   10651 		qctx->client->query.restarts++;
   10652 		return (ns__query_start(qctx));
   10653 	}
   10654 
   10655 	if (qctx->want_stale) {
   10656 		dns_ttl_t stale_ttl = 0;
   10657 		isc_result_t result;
   10658 		isc_boolean_t staleanswersok = ISC_FALSE;
   10659 
   10660 		/*
   10661 		 * Stale answers only make sense if stale_ttl > 0 but
   10662 		 * we want rndc to be able to control returning stale
   10663 		 * answers if they are configured.
   10664 		 */
   10665 		dns_db_attach(qctx->client->view->cachedb, &qctx->db);
   10666 		result = dns_db_getservestalettl(qctx->db, &stale_ttl);
   10667 		if (result == ISC_R_SUCCESS && stale_ttl > 0)  {
   10668 			switch (qctx->client->view->staleanswersok) {
   10669 			case dns_stale_answer_yes:
   10670 				staleanswersok = ISC_TRUE;
   10671 				break;
   10672 			case dns_stale_answer_conf:
   10673 				staleanswersok =
   10674 					qctx->client->view->staleanswersenable;
   10675 				break;
   10676 			case dns_stale_answer_no:
   10677 				staleanswersok = ISC_FALSE;
   10678 				break;
   10679 			}
   10680 		} else {
   10681 			staleanswersok = ISC_FALSE;
   10682 		}
   10683 
   10684 		if (staleanswersok) {
   10685 			qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
   10686 			inc_stats(qctx->client, ns_statscounter_trystale);
   10687 			if (qctx->client->query.fetch != NULL)
   10688 				dns_resolver_destroyfetch(
   10689 						   &qctx->client->query.fetch);
   10690 			return (query_lookup(qctx));
   10691 		}
   10692 		dns_db_detach(&qctx->db);
   10693 		qctx->want_stale = ISC_FALSE;
   10694 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
   10695 		return (query_done(qctx));
   10696 	}
   10697 
   10698 	if (qctx->result != ISC_R_SUCCESS &&
   10699 	    (!PARTIALANSWER(qctx->client) || WANTRECURSION(qctx->client) ||
   10700 	     qctx->result == DNS_R_DROP))
   10701 	{
   10702 		if (qctx->result == DNS_R_DUPLICATE ||
   10703 		    qctx->result == DNS_R_DROP)
   10704 		{
   10705 			/*
   10706 			 * This was a duplicate query that we are
   10707 			 * recursing on or the result of rate limiting.
   10708 			 * Don't send a response now for a duplicate query,
   10709 			 * because the original will still cause a response.
   10710 			 */
   10711 			query_next(qctx->client, qctx->result);
   10712 		} else {
   10713 			/*
   10714 			 * If we don't have any answer to give the client,
   10715 			 * or if the client requested recursion and thus wanted
   10716 			 * the complete answer, send an error response.
   10717 			 */
   10718 			INSIST(qctx->line >= 0);
   10719 			query_error(qctx->client, qctx->result, qctx->line);
   10720 		}
   10721 
   10722 		ns_client_detach(&qctx->client);
   10723 		return (qctx->result);
   10724 	}
   10725 
   10726 	/*
   10727 	 * If we're recursing then just return; the query will
   10728 	 * resume when recursion ends.
   10729 	 */
   10730 	if (RECURSING(qctx->client)) {
   10731 		return (qctx->result);
   10732 	}
   10733 
   10734 	/*
   10735 	 * We are done.  Set up sortlist data for the message
   10736 	 * rendering code, sort the answer to the front of the
   10737 	 * additional section if necessary, make a final tweak
   10738 	 * to the AA bit if the auth-nxdomain config option
   10739 	 * says so, then render and send the response.
   10740 	 */
   10741 	query_setup_sortlist(qctx);
   10742 	query_glueanswer(qctx);
   10743 
   10744 	if (qctx->client->message->rcode == dns_rcode_nxdomain &&
   10745 	    qctx->client->view->auth_nxdomain == ISC_TRUE)
   10746 	{
   10747 		qctx->client->message->flags |= DNS_MESSAGEFLAG_AA;
   10748 	}
   10749 
   10750 	/*
   10751 	 * If the response is somehow unexpected for the client and this
   10752 	 * is a result of recursion, return an error to the caller
   10753 	 * to indicate it may need to be logged.
   10754 	 */
   10755 	if (qctx->resuming &&
   10756 	    (ISC_LIST_EMPTY(secs[DNS_SECTION_ANSWER]) ||
   10757 	     qctx->client->message->rcode != dns_rcode_noerror))
   10758 	{
   10759 		qctx->result = ISC_R_FAILURE;
   10760 	}
   10761 
   10762 	query_send(qctx->client);
   10763 
   10764 	ns_client_detach(&qctx->client);
   10765 	return (qctx->result);
   10766 }
   10767 
   10768 static inline void
   10769 log_tat(ns_client_t *client) {
   10770 	char namebuf[DNS_NAME_FORMATSIZE];
   10771 	char clientbuf[ISC_NETADDR_FORMATSIZE];
   10772 	char classname[DNS_RDATACLASS_FORMATSIZE];
   10773 	isc_netaddr_t netaddr;
   10774 	char *tags = NULL;
   10775 	size_t taglen = 0;
   10776 
   10777 	if (!isc_log_wouldlog(ns_lctx, ISC_LOG_INFO)) {
   10778 		return;
   10779 	}
   10780 
   10781 	if ((client->query.qtype != dns_rdatatype_null ||
   10782 	     !dns_name_istat(client->query.qname)) &&
   10783 	    (client->keytag == NULL ||
   10784 	     client->query.qtype != dns_rdatatype_dnskey))
   10785 	{
   10786 		return;
   10787 	}
   10788 
   10789 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
   10790 	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
   10791 	isc_netaddr_format(&client->destaddr, clientbuf, sizeof(clientbuf));
   10792 	dns_rdataclass_format(client->view->rdclass, classname,
   10793 			      sizeof(classname));
   10794 
   10795 	if (client->query.qtype == dns_rdatatype_dnskey) {
   10796 		isc_uint16_t keytags = client->keytag_len / 2;
   10797 		size_t len = taglen = sizeof("65000") * keytags + 1;
   10798 		char *cp = tags = isc_mem_get(client->mctx, taglen);
   10799 		int i = 0;
   10800 
   10801 		INSIST(client->keytag != NULL);
   10802 		if (tags != NULL) {
   10803 			while (keytags-- > 0U) {
   10804 				int n;
   10805 				isc_uint16_t keytag;
   10806 				keytag = (client->keytag[i * 2] << 8) |
   10807 					 client->keytag[i * 2 + 1];
   10808 				n = snprintf(cp, len, " %u", keytag);
   10809 				if (n > 0 && (size_t)n <= len) {
   10810 					cp += n;
   10811 					len -= n;
   10812 					i++;
   10813 				} else {
   10814 					break;
   10815 				}
   10816 			}
   10817 		}
   10818 	}
   10819 
   10820 	isc_log_write(ns_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY,
   10821 		      ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s",
   10822 		      namebuf, classname, clientbuf, tags != NULL? tags : "");
   10823 	if (tags != NULL) {
   10824 		isc_mem_put(client->mctx, tags, taglen);
   10825 	}
   10826 }
   10827 
   10828 static inline void
   10829 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
   10830 	char namebuf[DNS_NAME_FORMATSIZE];
   10831 	char typename[DNS_RDATATYPE_FORMATSIZE];
   10832 	char classname[DNS_RDATACLASS_FORMATSIZE];
   10833 	char onbuf[ISC_NETADDR_FORMATSIZE];
   10834 	char ecsbuf[DNS_ECS_FORMATSIZE + sizeof(" [ECS ]") - 1] = { 0 };
   10835 	char ednsbuf[sizeof("E(65535)")] = { 0 };
   10836 	dns_rdataset_t *rdataset;
   10837 	int level = ISC_LOG_INFO;
   10838 
   10839 	if (! isc_log_wouldlog(ns_lctx, level))
   10840 		return;
   10841 
   10842 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
   10843 	INSIST(rdataset != NULL);
   10844 	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
   10845 	dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname));
   10846 	dns_rdatatype_format(rdataset->type, typename, sizeof(typename));
   10847 	isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
   10848 
   10849 	if (client->ednsversion >= 0)
   10850 		snprintf(ednsbuf, sizeof(ednsbuf), "E(%hd)",
   10851 			 client->ednsversion);
   10852 
   10853 	if (HAVEECS(client)) {
   10854 		strlcpy(ecsbuf, " [ECS ", sizeof(ecsbuf));
   10855 		dns_ecs_format(&client->ecs, ecsbuf + 6, sizeof(ecsbuf) - 6);
   10856 		strlcat(ecsbuf, "]", sizeof(ecsbuf));
   10857 	}
   10858 
   10859 	ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
   10860 		      level, "query: %s %s %s %s%s%s%s%s%s%s (%s)%s",
   10861 		      namebuf, classname, typename,
   10862 		      WANTRECURSION(client) ? "+" : "-",
   10863 		      (client->signer != NULL) ? "S" : "", ednsbuf,
   10864 		      TCP(client) ? "T" : "",
   10865 		      ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
   10866 		      ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
   10867 		      HAVECOOKIE(client) ? "V" : WANTCOOKIE(client) ? "K" : "",
   10868 		      onbuf, ecsbuf);
   10869 }
   10870 
   10871 static inline void
   10872 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
   10873 	char namebuf[DNS_NAME_FORMATSIZE];
   10874 	char typename[DNS_RDATATYPE_FORMATSIZE];
   10875 	char classname[DNS_RDATACLASS_FORMATSIZE];
   10876 	const char *namep, *typep, *classp, *sep1, *sep2;
   10877 	dns_rdataset_t *rdataset;
   10878 
   10879 	if (!isc_log_wouldlog(ns_lctx, level))
   10880 		return;
   10881 
   10882 	namep = typep = classp = sep1 = sep2 = "";
   10883 
   10884 	/*
   10885 	 * Query errors can happen for various reasons.  In some cases we cannot
   10886 	 * even assume the query contains a valid question section, so we should
   10887 	 * expect exceptional cases.
   10888 	 */
   10889 	if (client->query.origqname != NULL) {
   10890 		dns_name_format(client->query.origqname, namebuf,
   10891 				sizeof(namebuf));
   10892 		namep = namebuf;
   10893 		sep1 = " for ";
   10894 
   10895 		rdataset = ISC_LIST_HEAD(client->query.origqname->list);
   10896 		if (rdataset != NULL) {
   10897 			dns_rdataclass_format(rdataset->rdclass, classname,
   10898 					      sizeof(classname));
   10899 			classp = classname;
   10900 			dns_rdatatype_format(rdataset->type, typename,
   10901 					     sizeof(typename));
   10902 			typep = typename;
   10903 			sep2 = "/";
   10904 		}
   10905 	}
   10906 
   10907 	ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY,
   10908 		      level, "query failed (%s)%s%s%s%s%s%s at %s:%d",
   10909 		      isc_result_totext(result), sep1, namep, sep2,
   10910 		      classp, sep2, typep, __FILE__, line);
   10911 }
   10912 
   10913 void
   10914 ns_query_start(ns_client_t *client) {
   10915 	isc_result_t result;
   10916 	dns_message_t *message = client->message;
   10917 	dns_rdataset_t *rdataset;
   10918 	ns_client_t *qclient;
   10919 	dns_rdatatype_t qtype;
   10920 	unsigned int saved_extflags = client->extflags;
   10921 	unsigned int saved_flags = client->message->flags;
   10922 
   10923 	REQUIRE(NS_CLIENT_VALID(client));
   10924 
   10925 	CTRACE(ISC_LOG_DEBUG(3), "ns_query_start");
   10926 
   10927 	/*
   10928 	 * Test only.
   10929 	 */
   10930 	if (((client->sctx->options & NS_SERVER_CLIENTTEST) != 0) &&
   10931 	    !TCP(client))
   10932 	{
   10933 		result = ns_client_replace(client);
   10934 		if (result == ISC_R_SHUTTINGDOWN) {
   10935 			ns_client_next(client, result);
   10936 			return;
   10937 		} else if (result != ISC_R_SUCCESS) {
   10938 			query_error(client, result, __LINE__);
   10939 			return;
   10940 		}
   10941 	}
   10942 
   10943 	/*
   10944 	 * Ensure that appropriate cleanups occur.
   10945 	 */
   10946 	client->next = query_next_callback;
   10947 
   10948 	/*
   10949 	 * Behave as if we don't support DNSSEC if not enabled.
   10950 	 */
   10951 	if (!client->view->enablednssec) {
   10952 		message->flags &= ~DNS_MESSAGEFLAG_CD;
   10953 		client->extflags &= ~DNS_MESSAGEEXTFLAG_DO;
   10954 	}
   10955 
   10956 	if ((message->flags & DNS_MESSAGEFLAG_RD) != 0)
   10957 		client->query.attributes |= NS_QUERYATTR_WANTRECURSION;
   10958 
   10959 	if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0)
   10960 		client->attributes |= NS_CLIENTATTR_WANTDNSSEC;
   10961 
   10962 	switch (client->view->minimalresponses) {
   10963 	case dns_minimal_no:
   10964 		break;
   10965 	case dns_minimal_yes:
   10966 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
   10967 					     NS_QUERYATTR_NOADDITIONAL);
   10968 		break;
   10969 	case dns_minimal_noauth:
   10970 		client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
   10971 		break;
   10972 	case dns_minimal_noauthrec:
   10973 		if ((message->flags & DNS_MESSAGEFLAG_RD) != 0)
   10974 			client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
   10975 		break;
   10976 	}
   10977 
   10978 	if (client->view->cachedb == NULL || !client->view->recursion) {
   10979 		/*
   10980 		 * We don't have a cache.  Turn off cache support and
   10981 		 * recursion.
   10982 		 */
   10983 		client->query.attributes &=
   10984 			~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK);
   10985 		client->attributes |= NS_CLIENTATTR_NOSETFC;
   10986 	} else if ((client->attributes & NS_CLIENTATTR_RA) == 0 ||
   10987 		   (message->flags & DNS_MESSAGEFLAG_RD) == 0) {
   10988 		/*
   10989 		 * If the client isn't allowed to recurse (due to
   10990 		 * "recursion no", the allow-recursion ACL, or the
   10991 		 * lack of a resolver in this view), or if it
   10992 		 * doesn't want recursion, turn recursion off.
   10993 		 */
   10994 		client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
   10995 		client->attributes |= NS_CLIENTATTR_NOSETFC;
   10996 	}
   10997 
   10998 	/*
   10999 	 * Check for multiple question queries, since edns1 is dead.
   11000 	 */
   11001 	if (message->counts[DNS_SECTION_QUESTION] > 1) {
   11002 		query_error(client, DNS_R_FORMERR, __LINE__);
   11003 		return;
   11004 	}
   11005 
   11006 	/*
   11007 	 * Get the question name.
   11008 	 */
   11009 	result = dns_message_firstname(message, DNS_SECTION_QUESTION);
   11010 	if (result != ISC_R_SUCCESS) {
   11011 		query_error(client, result, __LINE__);
   11012 		return;
   11013 	}
   11014 	dns_message_currentname(message, DNS_SECTION_QUESTION,
   11015 				&client->query.qname);
   11016 	client->query.origqname = client->query.qname;
   11017 	result = dns_message_nextname(message, DNS_SECTION_QUESTION);
   11018 	if (result != ISC_R_NOMORE) {
   11019 		if (result == ISC_R_SUCCESS) {
   11020 			/*
   11021 			 * There's more than one QNAME in the question
   11022 			 * section.
   11023 			 */
   11024 			query_error(client, DNS_R_FORMERR, __LINE__);
   11025 		} else
   11026 			query_error(client, result, __LINE__);
   11027 		return;
   11028 	}
   11029 
   11030 	if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0)
   11031 		log_query(client, saved_flags, saved_extflags);
   11032 
   11033 	/*
   11034 	 * Check for meta-queries like IXFR and AXFR.
   11035 	 */
   11036 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
   11037 	INSIST(rdataset != NULL);
   11038 	client->query.qtype = qtype = rdataset->type;
   11039 	dns_rdatatypestats_increment(client->sctx->rcvquerystats, qtype);
   11040 
   11041 	log_tat(client);
   11042 
   11043 	if (dns_rdatatype_ismeta(qtype)) {
   11044 		switch (qtype) {
   11045 		case dns_rdatatype_any:
   11046 			break; /* Let the query logic handle it. */
   11047 		case dns_rdatatype_ixfr:
   11048 		case dns_rdatatype_axfr:
   11049 			ns_xfr_start(client, rdataset->type);
   11050 			return;
   11051 		case dns_rdatatype_maila:
   11052 		case dns_rdatatype_mailb:
   11053 			query_error(client, DNS_R_NOTIMP, __LINE__);
   11054 			return;
   11055 		case dns_rdatatype_tkey:
   11056 			result = dns_tkey_processquery(client->message,
   11057 						    client->sctx->tkeyctx,
   11058 						    client->view->dynamickeys);
   11059 			if (result == ISC_R_SUCCESS)
   11060 				query_send(client);
   11061 			else
   11062 				query_error(client, result, __LINE__);
   11063 			return;
   11064 		default: /* TSIG, etc. */
   11065 			query_error(client, DNS_R_FORMERR, __LINE__);
   11066 			return;
   11067 		}
   11068 	}
   11069 
   11070 	/*
   11071 	 * Turn on minimal response for (C)DNSKEY and (C)DS queries.
   11072 	 */
   11073 	if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds ||
   11074 	    qtype == dns_rdatatype_cdnskey || qtype == dns_rdatatype_cds)
   11075 	{
   11076 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
   11077 					     NS_QUERYATTR_NOADDITIONAL);
   11078 	}
   11079 
   11080 	/*
   11081 	 * Maybe turn on minimal responses for ANY queries.
   11082 	 */
   11083 	if (qtype == dns_rdatatype_any &&
   11084 	    client->view->minimal_any && !TCP(client))
   11085 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
   11086 					     NS_QUERYATTR_NOADDITIONAL);
   11087 
   11088 	/*
   11089 	 * Turn on minimal responses for EDNS/UDP bufsize 512 queries.
   11090 	 */
   11091 	if (client->ednsversion >= 0 && client->udpsize <= 512U && !TCP(client))
   11092 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
   11093 					     NS_QUERYATTR_NOADDITIONAL);
   11094 
   11095 	/*
   11096 	 * If the client has requested that DNSSEC checking be disabled,
   11097 	 * allow lookups to return pending data and instruct the resolver
   11098 	 * to return data before validation has completed.
   11099 	 *
   11100 	 * We don't need to set DNS_DBFIND_PENDINGOK when validation is
   11101 	 * disabled as there will be no pending data.
   11102 	 */
   11103 	if (message->flags & DNS_MESSAGEFLAG_CD ||
   11104 	    qtype == dns_rdatatype_rrsig)
   11105 	{
   11106 		client->query.dboptions |= DNS_DBFIND_PENDINGOK;
   11107 		client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
   11108 	} else if (!client->view->enablevalidation)
   11109 		client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
   11110 
   11111 	/*
   11112 	 * Allow glue NS records to be added to the authority section
   11113 	 * if the answer is secure.
   11114 	 */
   11115 	if (message->flags & DNS_MESSAGEFLAG_CD)
   11116 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
   11117 
   11118 	/*
   11119 	 * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query.
   11120 	 * This allows AD to be returned on queries without DO set.
   11121 	 */
   11122 	if ((message->flags & DNS_MESSAGEFLAG_AD) != 0)
   11123 		client->attributes |= NS_CLIENTATTR_WANTAD;
   11124 
   11125 	/*
   11126 	 * This is an ordinary query.
   11127 	 */
   11128 	result = dns_message_reply(message, ISC_TRUE);
   11129 	if (result != ISC_R_SUCCESS) {
   11130 		query_next(client, result);
   11131 		return;
   11132 	}
   11133 
   11134 	/*
   11135 	 * Assume authoritative response until it is known to be
   11136 	 * otherwise.
   11137 	 *
   11138 	 * If "-T noaa" has been set on the command line don't set
   11139 	 * AA on authoritative answers.
   11140 	 */
   11141 	if ((client->sctx->options & NS_SERVER_NOAA) == 0)
   11142 		message->flags |= DNS_MESSAGEFLAG_AA;
   11143 
   11144 	/*
   11145 	 * Set AD.  We must clear it if we add non-validated data to a
   11146 	 * response.
   11147 	 */
   11148 	if (WANTDNSSEC(client) || WANTAD(client))
   11149 		message->flags |= DNS_MESSAGEFLAG_AD;
   11150 
   11151 	qclient = NULL;
   11152 	ns_client_attach(client, &qclient);
   11153 	(void)query_setup(qclient, qtype);
   11154 }
   11155