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