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