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