1 /* $NetBSD: adb.h,v 1.6 2022/09/23 12:15:30 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 #ifndef DNS_ADB_H 17 #define DNS_ADB_H 1 18 19 /***** 20 ***** Module Info 21 *****/ 22 23 /*! \file dns/adb.h 24 *\brief 25 * DNS Address Database 26 * 27 * This module implements an address database (ADB) for mapping a name 28 * to an isc_sockaddr_t. It also provides statistical information on 29 * how good that address might be. 30 * 31 * A client will pass in a dns_name_t, and the ADB will walk through 32 * the rdataset looking up addresses associated with the name. If it 33 * is found on the internal lists, a structure is filled in with the 34 * address information and stats for found addresses. 35 * 36 * If the name cannot be found on the internal lists, a new entry will 37 * be created for a name if all the information needed can be found 38 * in the zone table or cache. This new address will then be returned. 39 * 40 * If a request must be made to remote servers to satisfy a name lookup, 41 * this module will start fetches to try to complete these addresses. When 42 * at least one more completes, an event is sent to the caller. If none of 43 * them resolve before the fetch times out, an event indicating this is 44 * sent instead. 45 * 46 * Records are stored internally until a timer expires. The timer is the 47 * smaller of the TTL or signature validity period. 48 * 49 * Lameness is stored per <qname,qtype> tuple, and this data hangs off each 50 * address field. When an address is marked lame for a given tuple the address 51 * will not be returned to a caller. 52 * 53 * 54 * MP: 55 * 56 *\li The ADB takes care of all necessary locking. 57 * 58 *\li Only the task which initiated the name lookup can cancel the lookup. 59 * 60 * 61 * Security: 62 * 63 *\li None, since all data stored is required to be pre-filtered. 64 * (Cache needs to be sane, fetches return bounds-checked and sanity- 65 * checked data, caller passes a good dns_name_t for the zone, etc) 66 */ 67 68 /*** 69 *** Imports 70 ***/ 71 72 #include <inttypes.h> 73 #include <stdbool.h> 74 75 #include <isc/lang.h> 76 #include <isc/magic.h> 77 #include <isc/mem.h> 78 #include <isc/sockaddr.h> 79 80 #include <dns/types.h> 81 #include <dns/view.h> 82 83 ISC_LANG_BEGINDECLS 84 85 /*** 86 *** Magic number checks 87 ***/ 88 89 #define DNS_ADBFIND_MAGIC ISC_MAGIC('a', 'd', 'b', 'H') 90 #define DNS_ADBFIND_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFIND_MAGIC) 91 #define DNS_ADBADDRINFO_MAGIC ISC_MAGIC('a', 'd', 'A', 'I') 92 #define DNS_ADBADDRINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBADDRINFO_MAGIC) 93 94 /*** 95 *** TYPES 96 ***/ 97 98 typedef struct dns_adbname dns_adbname_t; 99 100 /*! 101 *\brief 102 * Represents a lookup for a single name. 103 * 104 * On return, the client can safely use "list", and can reorder the list. 105 * Items may not be _deleted_ from this list, however, or added to it 106 * other than by using the dns_adb_*() API. 107 */ 108 struct dns_adbfind { 109 /* Public */ 110 unsigned int magic; /*%< RO: magic */ 111 dns_adbaddrinfolist_t list; /*%< RO: list of addrs */ 112 unsigned int query_pending; /*%< RO: partial list */ 113 unsigned int partial_result; /*%< RO: addrs missing */ 114 unsigned int options; /*%< RO: options */ 115 isc_result_t result_v4; /*%< RO: v4 result */ 116 isc_result_t result_v6; /*%< RO: v6 result */ 117 ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */ 118 119 /* Private */ 120 isc_mutex_t lock; /* locks all below */ 121 in_port_t port; 122 int name_bucket; 123 unsigned int flags; 124 dns_adbname_t *adbname; 125 dns_adb_t *adb; 126 isc_event_t event; 127 ISC_LINK(dns_adbfind_t) plink; 128 }; 129 130 /* 131 * _INET: 132 * _INET6: 133 * return addresses of that type. 134 * 135 * _EMPTYEVENT: 136 * Only schedule an event if no addresses are known. 137 * Must set _WANTEVENT for this to be meaningful. 138 * 139 * _WANTEVENT: 140 * An event is desired. Check this bit in the returned find to see 141 * if one will actually be generated. 142 * 143 * _AVOIDFETCHES: 144 * If set, fetches will not be generated unless no addresses are 145 * available in any of the address families requested. 146 * 147 * _STARTATZONE: 148 * Fetches will start using the closest zone data or use the root servers. 149 * This is useful for reestablishing glue that has expired. 150 * 151 * _GLUEOK: 152 * _HINTOK: 153 * Glue or hints are ok. These are used when matching names already 154 * in the adb, and when dns databases are searched. 155 * 156 * _RETURNLAME: 157 * Return lame servers in a find, so that all addresses are returned. 158 * 159 * _LAMEPRUNED: 160 * At least one address was omitted from the list because it was lame. 161 * This bit will NEVER be set if _RETURNLAME is set in the createfind(). 162 */ 163 /*% Return addresses of type INET. */ 164 #define DNS_ADBFIND_INET 0x00000001 165 /*% Return addresses of type INET6. */ 166 #define DNS_ADBFIND_INET6 0x00000002 167 #define DNS_ADBFIND_ADDRESSMASK 0x00000003 168 /*% 169 * Only schedule an event if no addresses are known. 170 * Must set _WANTEVENT for this to be meaningful. 171 */ 172 #define DNS_ADBFIND_EMPTYEVENT 0x00000004 173 /*% 174 * An event is desired. Check this bit in the returned find to see 175 * if one will actually be generated. 176 */ 177 #define DNS_ADBFIND_WANTEVENT 0x00000008 178 /*% 179 * If set, fetches will not be generated unless no addresses are 180 * available in any of the address families requested. 181 */ 182 #define DNS_ADBFIND_AVOIDFETCHES 0x00000010 183 /*% 184 * Fetches will start using the closest zone data or use the root servers. 185 * This is useful for reestablishing glue that has expired. 186 */ 187 #define DNS_ADBFIND_STARTATZONE 0x00000020 188 /*% 189 * Glue or hints are ok. These are used when matching names already 190 * in the adb, and when dns databases are searched. 191 */ 192 #define DNS_ADBFIND_GLUEOK 0x00000040 193 /*% 194 * Glue or hints are ok. These are used when matching names already 195 * in the adb, and when dns databases are searched. 196 */ 197 #define DNS_ADBFIND_HINTOK 0x00000080 198 /*% 199 * Return lame servers in a find, so that all addresses are returned. 200 */ 201 #define DNS_ADBFIND_RETURNLAME 0x00000100 202 /*% 203 * Only schedule an event if no addresses are known. 204 * Must set _WANTEVENT for this to be meaningful. 205 */ 206 #define DNS_ADBFIND_LAMEPRUNED 0x00000200 207 /*% 208 * The server's fetch quota is exceeded; it will be treated as 209 * lame for this query. 210 */ 211 #define DNS_ADBFIND_OVERQUOTA 0x00000400 212 /*% 213 * Don't perform a fetch even if there are no address records available. 214 */ 215 #define DNS_ADBFIND_NOFETCH 0x00000800 216 217 /*% 218 * The answers to queries come back as a list of these. 219 */ 220 struct dns_adbaddrinfo { 221 unsigned int magic; /*%< private */ 222 223 isc_sockaddr_t sockaddr; /*%< [rw] */ 224 unsigned int srtt; /*%< [rw] microsecs */ 225 isc_dscp_t dscp; 226 227 unsigned int flags; /*%< [rw] */ 228 dns_adbentry_t *entry; /*%< private */ 229 ISC_LINK(dns_adbaddrinfo_t) publink; 230 }; 231 232 /*!< 233 * The event sent to the caller task is just a plain old isc_event_t. It 234 * contains no data other than a simple status, passed in the "type" field 235 * to indicate that another address resolved, or all partially resolved 236 * addresses have failed to resolve. 237 * 238 * "sender" is the dns_adbfind_t used to issue this query. 239 * 240 * This is simply a standard event, with the "type" set to: 241 * 242 *\li #DNS_EVENT_ADBMOREADDRESSES -- another address resolved. 243 *\li #DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed, 244 * were canceled, or otherwise will 245 * not be usable. 246 *\li #DNS_EVENT_ADBCANCELED -- The request was canceled by a 247 * 3rd party. 248 *\li #DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request 249 * was canceled. 250 * 251 * In each of these cases, the addresses returned by the initial call 252 * to dns_adb_createfind() can still be used until they are no longer needed. 253 */ 254 255 /**** 256 **** FUNCTIONS 257 ****/ 258 259 isc_result_t 260 dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *tmgr, 261 isc_taskmgr_t *taskmgr, dns_adb_t **newadb); 262 /*%< 263 * Create a new ADB. 264 * 265 * Notes: 266 * 267 *\li Generally, applications should not create an ADB directly, but 268 * should instead call dns_view_createresolver(). 269 * 270 * Requires: 271 * 272 *\li 'mem' must be a valid memory context. 273 * 274 *\li 'view' be a pointer to a valid view. 275 * 276 *\li 'tmgr' be a pointer to a valid timer manager. 277 * 278 *\li 'taskmgr' be a pointer to a valid task manager. 279 * 280 *\li 'newadb' != NULL && '*newadb' == NULL. 281 * 282 * Returns: 283 * 284 *\li #ISC_R_SUCCESS after happiness. 285 *\li #ISC_R_NOMEMORY after resource allocation failure. 286 */ 287 288 void 289 dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbp); 290 /*% 291 * Attach to an 'adb' to 'adbp'. 292 * 293 * Requires: 294 *\li 'adb' to be a valid dns_adb_t, created via dns_adb_create(). 295 *\li 'adbp' to be a valid pointer to a *dns_adb_t which is initialized 296 * to NULL. 297 */ 298 299 void 300 dns_adb_detach(dns_adb_t **adb); 301 /*% 302 * Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests. 303 * 304 * Requires: 305 * 306 *\li 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via 307 * dns_adb_create(). 308 */ 309 310 void 311 dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp); 312 /*% 313 * Send '*eventp' to 'task' when 'adb' has shutdown. 314 * 315 * Requires: 316 * 317 *\li '*adb' is a valid dns_adb_t. 318 * 319 *\li eventp != NULL && *eventp is a valid event. 320 * 321 * Ensures: 322 * 323 *\li *eventp == NULL 324 * 325 *\li The event's sender field is set to the value of adb when the event 326 * is sent. 327 */ 328 329 void 330 dns_adb_shutdown(dns_adb_t *adb); 331 /*%< 332 * Shutdown 'adb'. 333 * 334 * Requires: 335 * 336 * \li '*adb' is a valid dns_adb_t. 337 */ 338 339 isc_result_t 340 dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, 341 void *arg, const dns_name_t *name, const dns_name_t *qname, 342 dns_rdatatype_t qtype, unsigned int options, 343 isc_stdtime_t now, dns_name_t *target, in_port_t port, 344 unsigned int depth, isc_counter_t *qc, dns_adbfind_t **find); 345 /*%< 346 * Main interface for clients. The adb will look up the name given in 347 * "name" and will build up a list of found addresses, and perhaps start 348 * internal fetches to resolve names that are unknown currently. 349 * 350 * If other addresses resolve after this call completes, an event will 351 * be sent to the <task, taskaction, arg> with the sender of that event 352 * set to a pointer to the dns_adbfind_t returned by this function. 353 * 354 * If no events will be generated, the *find->result_v4 and/or result_v6 355 * members may be examined for address lookup status. The usual #ISC_R_SUCCESS, 356 * #ISC_R_FAILURE, #DNS_R_NXDOMAIN, and #DNS_R_NXRRSET are returned, along with 357 * #ISC_R_NOTFOUND meaning the ADB has not _yet_ found the values. In this 358 * latter case, retrying may produce more addresses. 359 * 360 * If events will be returned, the result_v[46] members are only valid 361 * when that event is actually returned. 362 * 363 * The list of addresses returned is unordered. The caller must impose 364 * any ordering required. The list will not contain "known bad" addresses, 365 * however. For instance, it will not return hosts that are known to be 366 * lame for the zone in question. 367 * 368 * The caller cannot (directly) modify the contents of the address list's 369 * fields other than the "link" field. All values can be read at any 370 * time, however. 371 * 372 * The "now" parameter is used only for determining which entries that 373 * have a specific time to live or expire time should be removed from 374 * the running database. If specified as zero, the current time will 375 * be retrieved and used. 376 * 377 * If 'target' is not NULL and 'name' is an alias (i.e. the name is 378 * CNAME'd or DNAME'd to another name), then 'target' will be updated with 379 * the domain name that 'name' is aliased to. 380 * 381 * All addresses returned will have the sockaddr's port set to 'port.' 382 * The caller may change them directly in the dns_adbaddrinfo_t since 383 * they are copies of the internal address only. 384 * 385 * XXXMLG Document options, especially the flags which control how 386 * events are sent. 387 * 388 * Requires: 389 * 390 *\li *adb be a valid isc_adb_t object. 391 * 392 *\li If events are to be sent, *task be a valid task, 393 * and isc_taskaction_t != NULL. 394 * 395 *\li *name is a valid dns_name_t. 396 * 397 *\li qname != NULL and *qname be a valid dns_name_t. 398 * 399 *\li target == NULL or target is a valid name with a buffer. 400 * 401 *\li find != NULL && *find == NULL. 402 * 403 * Returns: 404 * 405 *\li #ISC_R_SUCCESS Addresses might have been returned, and events will be 406 * delivered for unresolved addresses. 407 *\li #ISC_R_NOMORE Addresses might have been returned, but no events 408 * will ever be posted for this context. This is only 409 * returned if task != NULL. 410 *\li #ISC_R_NOMEMORY insufficient resources 411 *\li #DNS_R_ALIAS 'name' is an alias for another name. 412 * 413 * Calls, and returns error codes from: 414 * 415 *\li isc_stdtime_get() 416 * 417 * Notes: 418 * 419 *\li No internal reference to "name" exists after this function 420 * returns. 421 */ 422 423 void 424 dns_adb_cancelfind(dns_adbfind_t *find); 425 /*%< 426 * Cancels the find, and sends the event off to the caller. 427 * 428 * It is an error to call dns_adb_cancelfind() on a find where 429 * no event is wanted, or will ever be sent. 430 * 431 * Note: 432 * 433 *\li It is possible that the real completion event was posted just 434 * before the dns_adb_cancelfind() call was made. In this case, 435 * dns_adb_cancelfind() will do nothing. The event callback needs 436 * to be prepared to find this situation (i.e. result is valid but 437 * the caller expects it to be canceled). 438 * 439 * Requires: 440 * 441 *\li 'find' be a valid dns_adbfind_t pointer. 442 * 443 *\li events would have been posted to the task. This can be checked 444 * with (find->options & DNS_ADBFIND_WANTEVENT). 445 * 446 * Ensures: 447 * 448 *\li The event was posted to the task. 449 */ 450 451 void 452 dns_adb_destroyfind(dns_adbfind_t **find); 453 /*%< 454 * Destroys the find reference. 455 * 456 * Note: 457 * 458 *\li This can only be called after the event was delivered for a 459 * find. Additionally, the event MUST have been freed via 460 * isc_event_free() BEFORE this function is called. 461 * 462 * Requires: 463 * 464 *\li 'find' != NULL and *find be valid dns_adbfind_t pointer. 465 * 466 * Ensures: 467 * 468 *\li No "address found" events will be posted to the originating task 469 * after this function returns. 470 */ 471 472 void 473 dns_adb_dump(dns_adb_t *adb, FILE *f); 474 /*%< 475 * This function is only used for debugging. It will dump as much of the 476 * state of the running system as possible. 477 * 478 * Requires: 479 * 480 *\li adb be valid. 481 * 482 *\li f != NULL, and is a file open for writing. 483 */ 484 485 void 486 dns_adb_dumpfind(dns_adbfind_t *find, FILE *f); 487 /*%< 488 * This function is only used for debugging. Dump the data associated 489 * with a find. 490 * 491 * Requires: 492 * 493 *\li find is valid. 494 * 495 * \li f != NULL, and is a file open for writing. 496 */ 497 498 isc_result_t 499 dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, 500 const dns_name_t *qname, dns_rdatatype_t type, 501 isc_stdtime_t expire_time); 502 /*%< 503 * Mark the given address as lame for the <qname,qtype>. expire_time should 504 * be set to the time when the entry should expire. That is, if it is to 505 * expire 10 minutes in the future, it should set it to (now + 10 * 60). 506 * 507 * Requires: 508 * 509 *\li adb be valid. 510 * 511 *\li addr be valid. 512 * 513 *\li qname be the qname used in the dns_adb_createfind() call. 514 * 515 * Returns: 516 * 517 *\li #ISC_R_SUCCESS -- all is well. 518 *\li #ISC_R_NOMEMORY -- could not mark address as lame. 519 */ 520 521 /* 522 * Reasonable defaults for RTT adjustments 523 * 524 * (Note: these values function both as scaling factors and as 525 * indicators of the type of RTT adjustment operation taking place. 526 * Adjusting the scaling factors is fine, as long as they all remain 527 * unique values.) 528 */ 529 #define DNS_ADB_RTTADJDEFAULT 7 /*%< default scale */ 530 #define DNS_ADB_RTTADJREPLACE 0 /*%< replace with our rtt */ 531 #define DNS_ADB_RTTADJAGE 10 /*%< age this rtt */ 532 533 void 534 dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt, 535 unsigned int factor); 536 /*%< 537 * Mix the round trip time into the existing smoothed rtt. 538 * 539 * Requires: 540 * 541 *\li adb be valid. 542 * 543 *\li addr be valid. 544 * 545 *\li 0 <= factor <= 10 546 * 547 * Note: 548 * 549 *\li The srtt in addr will be updated to reflect the new global 550 * srtt value. This may include changes made by others. 551 */ 552 553 void 554 dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now); 555 /* 556 * dns_adb_agesrtt is equivalent to dns_adb_adjustsrtt with factor 557 * equal to DNS_ADB_RTTADJAGE and the current time passed in. 558 * 559 * Requires: 560 * 561 *\li adb be valid. 562 * 563 *\li addr be valid. 564 * 565 * Note: 566 * 567 *\li The srtt in addr will be updated to reflect the new global 568 * srtt value. This may include changes made by others. 569 */ 570 571 void 572 dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, 573 unsigned int mask); 574 /*% 575 * Change Flags. 576 * 577 * Set the flags as given by: 578 * 579 *\li newflags = (oldflags & ~mask) | (bits & mask); 580 * 581 * Requires: 582 * 583 *\li adb be valid. 584 * 585 *\li addr be valid. 586 */ 587 588 void 589 dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size); 590 /*% 591 * Update seen UDP response size. The largest seen will be returned by 592 * dns_adb_getudpsize(). 593 * 594 * Requires: 595 * 596 *\li adb be valid. 597 * 598 *\li addr be valid. 599 */ 600 601 unsigned int 602 dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr); 603 /*% 604 * Return the largest seen UDP response size. 605 * 606 * Requires: 607 * 608 *\li adb be valid. 609 * 610 *\li addr be valid. 611 */ 612 613 unsigned int 614 dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups); 615 /*% 616 * Return suggested EDNS UDP size based on observed responses / failures. 617 * 'lookups' is the number of times the current lookup has been attempted. 618 * 619 * Requires: 620 * 621 *\li adb be valid. 622 * 623 *\li addr be valid. 624 */ 625 626 void 627 dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr); 628 /*% 629 * Record a successful plain DNS response. 630 * 631 * Requires: 632 * 633 *\li adb be valid. 634 * 635 *\li addr be valid. 636 */ 637 638 void 639 dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr); 640 /*% 641 * Record a plain DNS UDP query failed. 642 * 643 * Requires: 644 * 645 *\li adb be valid. 646 * 647 *\li addr be valid. 648 */ 649 650 void 651 dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size); 652 /*% 653 * Record a failed EDNS UDP response and the advertised EDNS UDP buffer size 654 * used. 655 * 656 * Requires: 657 * 658 *\li adb be valid. 659 * 660 *\li addr be valid. 661 */ 662 663 bool 664 dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr); 665 /*% 666 * Return whether EDNS should be disabled for this server. 667 * 668 * Requires: 669 * 670 *\li adb be valid. 671 * 672 *\li addr be valid. 673 */ 674 675 isc_result_t 676 dns_adb_findaddrinfo(dns_adb_t *adb, const isc_sockaddr_t *sa, 677 dns_adbaddrinfo_t **addrp, isc_stdtime_t now); 678 /*%< 679 * Return a dns_adbaddrinfo_t that is associated with address 'sa'. 680 * 681 * Requires: 682 * 683 *\li adb is valid. 684 * 685 *\li sa is valid. 686 * 687 *\li addrp != NULL && *addrp == NULL 688 * 689 * Returns: 690 *\li #ISC_R_SUCCESS 691 *\li #ISC_R_NOMEMORY 692 *\li #ISC_R_SHUTTINGDOWN 693 */ 694 695 void 696 dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp); 697 /*%< 698 * Free a dns_adbaddrinfo_t allocated by dns_adb_findaddrinfo(). 699 * 700 * Requires: 701 * 702 *\li adb is valid. 703 * 704 *\li *addrp is a valid dns_adbaddrinfo_t *. 705 */ 706 707 void 708 dns_adb_flush(dns_adb_t *adb); 709 /*%< 710 * Flushes all cached data from the adb. 711 * 712 * Requires: 713 *\li adb is valid. 714 */ 715 716 void 717 dns_adb_setadbsize(dns_adb_t *adb, size_t size); 718 /*%< 719 * Set a target memory size. If memory usage exceeds the target 720 * size entries will be removed before they would have expired on 721 * a random basis. 722 * 723 * If 'size' is 0 then memory usage is unlimited. 724 * 725 * Requires: 726 *\li 'adb' is valid. 727 */ 728 729 void 730 dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name); 731 /*%< 732 * Flush 'name' from the adb cache. 733 * 734 * Requires: 735 *\li 'adb' is valid. 736 *\li 'name' is valid. 737 */ 738 739 void 740 dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name); 741 /*%< 742 * Flush 'name' and all subdomains from the adb cache. 743 * 744 * Requires: 745 *\li 'adb' is valid. 746 *\li 'name' is valid. 747 */ 748 749 void 750 dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, 751 const unsigned char *cookie, size_t len); 752 /*%< 753 * Record the COOKIE associated with this address. If 754 * cookie is NULL or len is zero the recorded COOKIE is cleared. 755 * 756 * Requires: 757 *\li 'adb' is valid. 758 *\li 'addr' is valid. 759 */ 760 761 size_t 762 dns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, 763 unsigned char *cookie, size_t len); 764 /* 765 * Retrieve the saved COOKIE value and store it in 'cookie' which has 766 * size 'len'. 767 * 768 * Requires: 769 *\li 'adb' is valid. 770 *\li 'addr' is valid. 771 * 772 * Returns: 773 * The size of the cookie or zero if it doesn't fit in the buffer 774 * or it doesn't exist. 775 */ 776 777 void 778 dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, double low, 779 double high, double discount); 780 /*%< 781 * Set the baseline ADB quota, and configure parameters for the 782 * quota adjustment algorithm. 783 * 784 * If the number of fetches currently waiting for responses from this 785 * address exceeds the current quota, then additional fetches are spilled. 786 * 787 * 'quota' is the highest permissible quota; it will adjust itself 788 * downward in response to detected congestion. 789 * 790 * After every 'freq' fetches have either completed or timed out, an 791 * exponentially weighted moving average of the ratio of timeouts 792 * to responses is calculated. If the EWMA goes above a 'high' 793 * threshold, then the quota is adjusted down one step; if it drops 794 * below a 'low' threshold, then the quota is adjusted back up one 795 * step. 796 * 797 * The quota adjustment is based on the function (1 / 1 + (n/10)^(3/2)), 798 * for values of n from 0 to 99. It starts at 100% of the baseline 799 * quota, and descends after 100 steps to 2%. 800 * 801 * 'discount' represents the discount rate of the moving average. Higher 802 * values cause older values to be discounted sooner, providing a faster 803 * response to changes in the timeout ratio. 804 * 805 * Requires: 806 *\li 'adb' is valid. 807 */ 808 809 bool 810 dns_adbentry_overquota(dns_adbentry_t *entry); 811 /*%< 812 * Returns true if the specified ADB has too many active fetches. 813 * 814 * Requires: 815 *\li 'entry' is valid. 816 */ 817 818 void 819 dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr); 820 void 821 dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr); 822 /*% 823 * Begin/end a UDP fetch on a particular address. 824 * 825 * These functions increment or decrement the fetch counter for 826 * the ADB entry so that the fetch quota can be enforced. 827 * 828 * Requires: 829 * 830 *\li adb be valid. 831 * 832 *\li addr be valid. 833 */ 834 835 ISC_LANG_ENDDECLS 836 837 #endif /* DNS_ADB_H */ 838