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