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