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