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