1 /* $NetBSD: resolver.h,v 1.12 2026/01/29 18:37:51 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 #pragma once 17 18 /***** 19 ***** Module Info 20 *****/ 21 22 /*! \file dns/resolver.h 23 * 24 * \brief 25 * This is the BIND 9 resolver, the module responsible for resolving DNS 26 * requests by iteratively querying authoritative servers and following 27 * referrals. This is a "full resolver", not to be confused with 28 * the stub resolvers most people associate with the word "resolver". 29 * The full resolver is part of the caching name server or resolver 30 * daemon the stub resolver talks to. 31 * 32 * MP: 33 *\li The module ensures appropriate synchronization of data structures it 34 * creates and manipulates. 35 * 36 * Reliability: 37 *\li No anticipated impact. 38 * 39 * Resources: 40 *\li TBS 41 * 42 * Security: 43 *\li No anticipated impact. 44 * 45 * Standards: 46 *\li RFCs: 1034, 1035, 2181, TBS 47 *\li Drafts: TBS 48 */ 49 50 #include <inttypes.h> 51 #include <netinet/in.h> 52 #include <stdbool.h> 53 54 #include <isc/lang.h> 55 #include <isc/loop.h> 56 #include <isc/refcount.h> 57 #include <isc/stats.h> 58 #include <isc/tls.h> 59 #include <isc/types.h> 60 61 #include <dns/ede.h> 62 #include <dns/fixedname.h> 63 #include <dns/message.h> 64 #include <dns/types.h> 65 66 /* Add -DDNS_RESOLVER_TRACE=1 to CFLAGS for detailed reference tracing */ 67 68 ISC_LANG_BEGINDECLS 69 70 /*% 71 * A dns_fetchresponse_t is sent to the caller when a fetch completes. 72 * Any of 'db', 'node', 'rdataset', and 'sigrdataset' may be bound; it 73 * is the receiver's responsibility to detach them, and also free the 74 * structure. 75 * 76 * \brief 77 * 'rdataset', 'sigrdataset', 'client' and 'id' are the values that were 78 * supplied when dns_resolver_createfetch() was called. They are returned 79 * to the caller so that they may be freed. 80 */ 81 typedef struct dns_fetchresponse dns_fetchresponse_t; 82 83 struct dns_fetchresponse { 84 dns_fetch_t *fetch; 85 isc_mem_t *mctx; 86 isc_result_t result; 87 isc_result_t vresult; 88 dns_edectx_t *edectx; 89 dns_rdatatype_t qtype; 90 dns_db_t *db; 91 dns_dbnode_t *node; 92 dns_rdataset_t *rdataset; 93 dns_rdataset_t *sigrdataset; 94 dns_fixedname_t fname; 95 dns_name_t *foundname; 96 const isc_sockaddr_t *client; 97 dns_messageid_t id; 98 isc_loop_t *loop; 99 isc_job_cb cb; 100 void *arg; 101 ISC_LINK(dns_fetchresponse_t) link; 102 }; 103 104 /*% 105 * The two quota types (fetches-per-zone and fetches-per-server) 106 */ 107 typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t; 108 109 /* 110 * Options that modify how a 'fetch' is done. 111 */ 112 enum { 113 DNS_FETCHOPT_TCP = 1 << 0, /*%< Use TCP. */ 114 DNS_FETCHOPT_UNSHARED = 1 << 1, /*%< See below. */ 115 DNS_FETCHOPT_RECURSIVE = 1 << 2, /*%< Set RD? */ 116 DNS_FETCHOPT_NOEDNS0 = 1 << 3, /*%< Do not use EDNS. */ 117 DNS_FETCHOPT_FORWARDONLY = 1 << 4, /*%< Only use forwarders. */ 118 DNS_FETCHOPT_NOVALIDATE = 1 << 5, /*%< Disable validation. */ 119 DNS_FETCHOPT_WANTNSID = 1 << 6, /*%< Request NSID */ 120 DNS_FETCHOPT_PREFETCH = 1 << 7, /*%< Do prefetch */ 121 DNS_FETCHOPT_NOCDFLAG = 1 << 8, /*%< Don't set CD flag. */ 122 DNS_FETCHOPT_NONTA = 1 << 9, /*%< Ignore NTA table. */ 123 DNS_FETCHOPT_NOCACHED = 1 << 10, /*%< Force cache update. */ 124 DNS_FETCHOPT_QMINIMIZE = 1 << 11, /*%< Use qname minimization. */ 125 DNS_FETCHOPT_NOFOLLOW = 1 << 12, /*%< Don't retrieve the NS RRset 126 * from the child zone when a 127 * delegation is returned in 128 * response to a NS query. */ 129 DNS_FETCHOPT_QMIN_STRICT = 1 << 13, /*%< Do not work around servers 130 * that return errors on 131 * non-empty terminals. */ 132 DNS_FETCHOPT_QMIN_SKIP_IP6A = 1 << 14, /*%< Skip some labels when 133 * doing qname minimization 134 * on ip6.arpa. */ 135 DNS_FETCHOPT_NOFORWARD = 1 << 15, /*%< Do not use forwarders if 136 * possible. */ 137 138 /*% EDNS version bits: */ 139 DNS_FETCHOPT_EDNSVERSIONSET = 1 << 23, 140 DNS_FETCHOPT_EDNSVERSIONSHIFT = 24, 141 DNS_FETCHOPT_EDNSVERSIONMASK = 0xff000000, 142 }; 143 144 /* 145 * Upper bounds of class of query RTT (ms). Corresponds to 146 * dns_resstatscounter_queryrttX statistics counters. 147 */ 148 #define DNS_RESOLVER_QRYRTTCLASS0 10 149 #define DNS_RESOLVER_QRYRTTCLASS0STR "10" 150 #define DNS_RESOLVER_QRYRTTCLASS1 100 151 #define DNS_RESOLVER_QRYRTTCLASS1STR "100" 152 #define DNS_RESOLVER_QRYRTTCLASS2 500 153 #define DNS_RESOLVER_QRYRTTCLASS2STR "500" 154 #define DNS_RESOLVER_QRYRTTCLASS3 800 155 #define DNS_RESOLVER_QRYRTTCLASS3STR "800" 156 #define DNS_RESOLVER_QRYRTTCLASS4 1600 157 #define DNS_RESOLVER_QRYRTTCLASS4STR "1600" 158 159 /* 160 * XXXRTH Should this API be made semi-private? (I.e. 161 * _dns_resolver_create()). 162 */ 163 164 #define DNS_RESOLVER_CHECKNAMES 0x01 165 #define DNS_RESOLVER_CHECKNAMESFAIL 0x02 166 167 #define DNS_QMIN_MAXLABELS 7 168 #define DNS_QMIN_MAX_NO_DELEGATION 3 169 170 isc_result_t 171 dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm, 172 unsigned int options, isc_tlsctx_cache_t *tlsctx_cache, 173 dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, 174 dns_resolver_t **resp); 175 176 /*%< 177 * Create a resolver. 178 * 179 * Notes: 180 * 181 *\li Generally, applications should not create a resolver directly, but 182 * should instead call dns_view_createresolver(). 183 * 184 * Requires: 185 * 186 *\li 'view' is a valid view. 187 * 188 *\li 'nm' is a valid network manager. 189 * 190 *\li 'tlsctx_cache' != NULL. 191 * 192 *\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL. 193 * If not NULL, clones per loop of it will be created by the resolver. 194 * 195 *\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL. 196 * If not NULL, clones per loop of it will be created by the resolver. 197 * 198 *\li resp != NULL && *resp == NULL. 199 * 200 * Returns: 201 * 202 *\li #ISC_R_SUCCESS On success. 203 * 204 *\li Anything else Failure. 205 */ 206 207 void 208 dns_resolver_freeze(dns_resolver_t *res); 209 /*%< 210 * Freeze resolver. 211 * 212 * Notes: 213 * 214 *\li Certain configuration changes cannot be made after the resolver 215 * is frozen. Fetches cannot be created until the resolver is frozen. 216 * 217 * Requires: 218 * 219 *\li 'res' is a valid resolver. 220 * 221 * Ensures: 222 * 223 *\li 'res' is frozen. 224 */ 225 226 void 227 dns_resolver_prime(dns_resolver_t *res); 228 /*%< 229 * Prime resolver. 230 * 231 * Notes: 232 * 233 *\li Resolvers which have a forwarding policy other than dns_fwdpolicy_only 234 * need to be primed with the root nameservers, otherwise the root 235 * nameserver hints data may be used indefinitely. This function requests 236 * that the resolver start a priming fetch, if it isn't already priming. 237 * 238 * Requires: 239 * 240 *\li 'res' is a valid, frozen resolver. 241 */ 242 243 void 244 dns_resolver_shutdown(dns_resolver_t *res); 245 /*%< 246 * Start the shutdown process for 'res'. 247 * 248 * Notes: 249 * 250 *\li This call has no effect if the resolver is already shutting down. 251 * 252 * Requires: 253 * 254 *\li 'res' is a valid resolver. 255 */ 256 257 #if DNS_RESOLVER_TRACE 258 #define dns_resolver_ref(ptr) \ 259 dns_resolver__ref(ptr, __func__, __FILE__, __LINE__) 260 #define dns_resolver_unref(ptr) \ 261 dns_resolver__unref(ptr, __func__, __FILE__, __LINE__) 262 #define dns_resolver_attach(ptr, ptrp) \ 263 dns_resolver__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 264 #define dns_resolver_detach(ptrp) \ 265 dns_resolver__detach(ptrp, __func__, __FILE__, __LINE__) 266 ISC_REFCOUNT_TRACE_DECL(dns_resolver); 267 #else 268 ISC_REFCOUNT_DECL(dns_resolver); 269 #endif 270 271 typedef struct fetchctx fetchctx_t; 272 273 isc_result_t 274 dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name, 275 dns_rdatatype_t type, const dns_name_t *domain, 276 dns_rdataset_t *nameservers, 277 dns_forwarders_t *forwarders, 278 const isc_sockaddr_t *client, dns_messageid_t id, 279 unsigned int options, unsigned int depth, 280 isc_counter_t *qc, isc_counter_t *gqc, 281 fetchctx_t *parent, isc_loop_t *loop, isc_job_cb cb, 282 void *arg, dns_edectx_t *edectx, 283 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 284 dns_fetch_t **fetchp); 285 /*%< 286 * Recurse to answer a question. 287 * 288 * Notes: 289 * 290 *\li This call starts a query for 'name', type 'type'. 291 * 292 *\li The 'domain' is a parent domain of 'name' for which 293 * a set of name servers 'nameservers' is known. If no 294 * such name server information is available, set 295 * 'domain' and 'nameservers' to NULL. 296 * 297 *\li 'forwarders' is unimplemented, and subject to change when 298 * we figure out how selective forwarding will work. 299 * 300 *\li When the fetch completes (successfully or otherwise), a 301 * dns_fetchresponse_t option is sent to callback 'cb'. 302 * 303 *\li The values of 'rdataset' and 'sigrdataset' will be returned in 304 * the fetch completion event. 305 * 306 *\li 'client' and 'id' are used for duplicate query detection. '*client' 307 * must remain stable until after 'action' has been called or 308 * dns_resolver_cancelfetch() is called. 309 * 310 * Requires: 311 * 312 *\li 'res' is a valid resolver that has been frozen. 313 * 314 *\li 'name' is a valid name. 315 * 316 *\li 'type' is not a meta type other than ANY. 317 * 318 *\li 'domain' is a valid name or NULL. 319 * 320 *\li 'nameservers' is a valid NS rdataset (whose owner name is 'domain') 321 * iff. 'domain' is not NULL. 322 * 323 *\li 'forwarders' is NULL. 324 * 325 *\li 'client' is a valid sockaddr or NULL. 326 * 327 *\li 'options' contains valid options. 328 * 329 *\li 'rdataset' is a valid, disassociated rdataset. 330 * 331 *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. 332 * 333 *\li fetchp != NULL && *fetchp == NULL. 334 * 335 * Returns: 336 * 337 *\li #ISC_R_SUCCESS Success 338 *\li #DNS_R_DUPLICATE 339 *\li #DNS_R_DROP 340 * 341 *\li Many other values are possible, all of which indicate failure. 342 */ 343 344 void 345 dns_resolver_cancelfetch(dns_fetch_t *fetch); 346 /*%< 347 * Cancel 'fetch'. 348 * 349 * Notes: 350 * 351 *\li If 'fetch' has not completed, post its completion event with a 352 * result code of #ISC_R_CANCELED. 353 * 354 * Requires: 355 * 356 *\li 'fetch' is a valid fetch. 357 */ 358 359 void 360 dns_resolver_destroyfetch(dns_fetch_t **fetchp); 361 /*%< 362 * Destroy 'fetch'. 363 * 364 * Requires: 365 * 366 *\li '*fetchp' is a valid fetch. 367 * 368 *\li The caller has received the fetch completion event (either because the 369 * fetch completed or because dns_resolver_cancelfetch() was called). 370 * 371 * Ensures: 372 * 373 *\li *fetchp == NULL. 374 */ 375 376 void 377 dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, 378 isc_logcategory_t *category, isc_logmodule_t *module, 379 int level, bool duplicateok); 380 /*%< 381 * Dump a log message on internal state at the completion of given 'fetch'. 382 * 'lctx', 'category', 'module', and 'level' are used to write the log message. 383 * By default, only one log message is written even if the corresponding fetch 384 * context serves multiple clients; if 'duplicateok' is true the suppression 385 * is disabled and the message can be written every time this function is 386 * called. 387 * 388 * Requires: 389 * 390 *\li 'fetch' is a valid fetch, and has completed. 391 */ 392 393 dns_dispatch_t * 394 dns_resolver_dispatchv4(dns_resolver_t *resolver); 395 396 dns_dispatch_t * 397 dns_resolver_dispatchv6(dns_resolver_t *resolver); 398 399 void 400 dns_resolver_addalternate(dns_resolver_t *resolver, const isc_sockaddr_t *alt, 401 const dns_name_t *name, in_port_t port); 402 /*%< 403 * Add alternate addresses to be tried in the event that the nameservers 404 * for a zone are not available in the address families supported by the 405 * operating system. 406 * 407 * Require: 408 * \li only one of 'name' or 'alt' to be valid. 409 */ 410 411 isc_result_t 412 dns_resolver_disable_algorithm(dns_resolver_t *resolver, const dns_name_t *name, 413 unsigned int alg); 414 /*%< 415 * Mark the given DNSSEC algorithm as disabled and below 'name'. 416 * Valid algorithms are less than 256. 417 * 418 * Returns: 419 *\li #ISC_R_SUCCESS 420 *\li #ISC_R_RANGE 421 *\li #ISC_R_NOMEMORY 422 */ 423 424 isc_result_t 425 dns_resolver_disable_ds_digest(dns_resolver_t *resolver, const dns_name_t *name, 426 unsigned int digest_type); 427 /*%< 428 * Mark the given DS digest type as disabled and below 'name'. 429 * Valid types are less than 256. 430 * 431 * Returns: 432 *\li #ISC_R_SUCCESS 433 *\li #ISC_R_RANGE 434 *\li #ISC_R_NOMEMORY 435 */ 436 437 bool 438 dns_resolver_algorithm_supported(dns_resolver_t *resolver, 439 const dns_name_t *name, unsigned int alg); 440 /*%< 441 * Check if the given algorithm is supported by this resolver. 442 * This checks whether the algorithm has been disabled via 443 * dns_resolver_disable_algorithm(), then checks the underlying 444 * crypto libraries if it was not specifically disabled. 445 */ 446 447 bool 448 dns_resolver_ds_digest_supported(dns_resolver_t *resolver, 449 const dns_name_t *name, 450 unsigned int digest_type); 451 /*%< 452 * Check if the given digest type is supported by this resolver. 453 * This checks whether the digest type has been disabled via 454 * dns_resolver_disable_ds_digest(), then checks the underlying 455 * crypto libraries if it was not specifically disabled. 456 */ 457 458 isc_result_t 459 dns_resolver_setmustbesecure(dns_resolver_t *resolver, const dns_name_t *name, 460 bool value); 461 462 bool 463 dns_resolver_getmustbesecure(dns_resolver_t *resolver, const dns_name_t *name); 464 465 void 466 dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int timeout); 467 /*%< 468 * Set the length of time the resolver will work on a query, in milliseconds. 469 * 470 * 'timeout' was originally defined in seconds, and later redefined to be in 471 * milliseconds. Values less than or equal to 300 are treated as seconds. 472 * 473 * If timeout is 0, the default timeout will be applied. 474 * 475 * Requires: 476 * \li resolver to be valid. 477 */ 478 479 unsigned int 480 dns_resolver_gettimeout(dns_resolver_t *resolver); 481 /*%< 482 * Get the current length of time the resolver will work on a query, 483 * in milliseconds. 484 * 485 * Requires: 486 * \li resolver to be valid. 487 */ 488 489 void 490 dns_resolver_setclientsperquery(dns_resolver_t *resolver, uint32_t min, 491 uint32_t max); 492 void 493 dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients); 494 495 uint32_t 496 dns_resolver_getfetchesperzone(dns_resolver_t *resolver); 497 498 void 499 dns_resolver_getclientsperquery(dns_resolver_t *resolver, uint32_t *cur, 500 uint32_t *min, uint32_t *max); 501 502 bool 503 dns_resolver_getzeronosoattl(dns_resolver_t *resolver); 504 505 void 506 dns_resolver_setzeronosoattl(dns_resolver_t *resolver, bool state); 507 508 unsigned int 509 dns_resolver_getoptions(dns_resolver_t *resolver); 510 /*%< 511 * Get the resolver options. 512 * 513 * Requires: 514 * \li resolver to be valid. 515 */ 516 517 void 518 dns_resolver_setmaxvalidations(dns_resolver_t *resolver, uint32_t max); 519 void 520 dns_resolver_setmaxvalidationfails(dns_resolver_t *resolver, uint32_t max); 521 /*% 522 * Set maximum numbers of validations and maximum validation failures per fetch. 523 */ 524 525 void 526 dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth); 527 unsigned int 528 dns_resolver_getmaxdepth(dns_resolver_t *resolver); 529 /*% 530 * Get and set how many NS indirections will be followed when looking for 531 * nameserver addresses. 532 * 533 * Requires: 534 * \li resolver to be valid. 535 */ 536 537 void 538 dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries); 539 unsigned int 540 dns_resolver_getmaxqueries(dns_resolver_t *resolver); 541 /*% 542 * Get and set how many iterative queries will be allowed before 543 * terminating a recursive query. 544 * 545 * Requires: 546 * \li resolver to be valid. 547 */ 548 549 void 550 dns_resolver_setquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which, 551 isc_result_t resp); 552 isc_result_t 553 dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which); 554 /*% 555 * Get and set the result code that will be used when quotas 556 * are exceeded. If 'which' is set to quotatype "zone", then the 557 * result specified in 'resp' will be used when the fetches-per-zone 558 * quota is exceeded by a fetch. If 'which' is set to quotatype "server", 559 * then the result specified in 'resp' will be used when the 560 * fetches-per-server quota has been exceeded for all the 561 * authoritative servers for a zone. Valid choices are 562 * DNS_R_DROP or DNS_R_SERVFAIL. 563 * 564 * Requires: 565 * \li 'resolver' to be valid. 566 * \li 'which' to be dns_quotatype_zone or dns_quotatype_server 567 * \li 'resp' to be DNS_R_DROP or DNS_R_SERVFAIL. 568 */ 569 570 void 571 dns_resolver_dumpfetches(dns_resolver_t *resolver, isc_statsformat_t format, 572 FILE *fp); 573 isc_result_t 574 dns_resolver_dumpquota(dns_resolver_t *res, isc_buffer_t **buf); 575 576 #ifdef ENABLE_AFL 577 /*% 578 * Enable fuzzing of resolver, changes behaviour and eliminates retries 579 */ 580 void 581 dns_resolver_setfuzzing(void); 582 #endif /* ifdef ENABLE_AFL */ 583 584 void 585 dns_resolver_setstats(dns_resolver_t *res, isc_stats_t *stats); 586 /*%< 587 * Set a general resolver statistics counter set 'stats' for 'res'. 588 * 589 * Requires: 590 * \li 'res' is valid. 591 * 592 *\li stats is a valid statistics supporting resolver statistics counters 593 * (see dns/stats.h). 594 */ 595 596 void 597 dns_resolver_getstats(dns_resolver_t *res, isc_stats_t **statsp); 598 /*%< 599 * Get the general statistics counter set for 'res'. If a statistics set is 600 * set '*statsp' will be attached to the set; otherwise, '*statsp' will be 601 * untouched. 602 * 603 * Requires: 604 * \li 'res' is valid. 605 * 606 *\li 'statsp' != NULL && '*statsp' != NULL 607 */ 608 609 void 610 dns_resolver_incstats(dns_resolver_t *res, isc_statscounter_t counter); 611 /*%< 612 * Increment the specified statistics counter in res->stats, if res->stats 613 * is set. 614 * 615 * Requires: 616 * \li 'res' is valid. 617 */ 618 619 void 620 dns_resolver_setquerystats(dns_resolver_t *res, dns_stats_t *stats); 621 /*%< 622 * Set a statistics counter set of rdata type, 'stats', for 'res'. Once the 623 * statistic set is installed, the resolver will count outgoing queries 624 * per rdata type. 625 * 626 * Requires: 627 * \li 'res' is valid. 628 * 629 *\li stats is a valid statistics created by dns_rdatatypestats_create(). 630 */ 631 632 void 633 dns_resolver_getquerystats(dns_resolver_t *res, dns_stats_t **statsp); 634 /*%< 635 * Get the rdatatype statistics counter set for 'res'. If a statistics set is 636 * set '*statsp' will be attached to the set; otherwise, '*statsp' will be 637 * untouched. 638 * 639 * Requires: 640 * \li 'res' is valid. 641 * 642 *\li 'statsp' != NULL && '*statsp' != NULL 643 */ 644 645 void 646 dns_resolver_freefresp(dns_fetchresponse_t **frespp); 647 /*%< 648 * Free a dns_fetchresponse_t object and internal owned object as 649 * well. 650 * 651 * Requires: 652 * \li 'frespp' is valid. No-op if *frespp == NULL 653 */ 654 655 ISC_LANG_ENDDECLS 656