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