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