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