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