xref: /netbsd-src/external/mpl/bind/dist/lib/dns/adb.c (revision 9fb66d812c00ebfb445c0b47dea128f32aa6fe96)
1 /*	$NetBSD: adb.c,v 1.8 2021/04/05 11:27:01 rillig Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 /*! \file
15  *
16  * \note
17  * In finds, if task == NULL, no events will be generated, and no events
18  * have been sent.  If task != NULL but taskaction == NULL, an event has been
19  * posted but not yet freed.  If neither are NULL, no event was posted.
20  *
21  */
22 
23 #include <inttypes.h>
24 #include <limits.h>
25 #include <stdbool.h>
26 
27 #include <isc/mutexblock.h>
28 #include <isc/netaddr.h>
29 #include <isc/print.h>
30 #include <isc/random.h>
31 #include <isc/stats.h>
32 #include <isc/string.h> /* Required for HP/UX (and others?) */
33 #include <isc/task.h>
34 #include <isc/util.h>
35 
36 #include <dns/adb.h>
37 #include <dns/db.h>
38 #include <dns/events.h>
39 #include <dns/log.h>
40 #include <dns/rdata.h>
41 #include <dns/rdataset.h>
42 #include <dns/rdatastruct.h>
43 #include <dns/rdatatype.h>
44 #include <dns/resolver.h>
45 #include <dns/result.h>
46 #include <dns/stats.h>
47 
48 #define DNS_ADB_MAGIC		 ISC_MAGIC('D', 'a', 'd', 'b')
49 #define DNS_ADB_VALID(x)	 ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
50 #define DNS_ADBNAME_MAGIC	 ISC_MAGIC('a', 'd', 'b', 'N')
51 #define DNS_ADBNAME_VALID(x)	 ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
52 #define DNS_ADBNAMEHOOK_MAGIC	 ISC_MAGIC('a', 'd', 'N', 'H')
53 #define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
54 #define DNS_ADBLAMEINFO_MAGIC	 ISC_MAGIC('a', 'd', 'b', 'Z')
55 #define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC)
56 #define DNS_ADBENTRY_MAGIC	 ISC_MAGIC('a', 'd', 'b', 'E')
57 #define DNS_ADBENTRY_VALID(x)	 ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
58 #define DNS_ADBFETCH_MAGIC	 ISC_MAGIC('a', 'd', 'F', '4')
59 #define DNS_ADBFETCH_VALID(x)	 ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
60 #define DNS_ADBFETCH6_MAGIC	 ISC_MAGIC('a', 'd', 'F', '6')
61 #define DNS_ADBFETCH6_VALID(x)	 ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
62 
63 /*!
64  * For type 3 negative cache entries, we will remember that the address is
65  * broken for this long.  XXXMLG This is also used for actual addresses, too.
66  * The intent is to keep us from constantly asking about A/AAAA records
67  * if the zone has extremely low TTLs.
68  */
69 #define ADB_CACHE_MINIMUM 10	/*%< seconds */
70 #define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */
71 #define ADB_ENTRY_WINDOW  1800	/*%< seconds */
72 
73 /*%
74  * The period in seconds after which an ADB name entry is regarded as stale
75  * and forced to be cleaned up.
76  * TODO: This should probably be configurable at run-time.
77  */
78 #ifndef ADB_STALE_MARGIN
79 #define ADB_STALE_MARGIN 1800
80 #endif /* ifndef ADB_STALE_MARGIN */
81 
82 #define FREE_ITEMS 64 /*%< free count for memory pools */
83 #define FILL_COUNT 16 /*%< fill count for memory pools */
84 
85 #define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */
86 
87 #define DNS_ADB_MINADBSIZE (1024U * 1024U) /*%< 1 Megabyte */
88 
89 typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
90 typedef struct dns_adbnamehook dns_adbnamehook_t;
91 typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
92 typedef struct dns_adblameinfo dns_adblameinfo_t;
93 typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
94 typedef struct dns_adbfetch dns_adbfetch_t;
95 typedef struct dns_adbfetch6 dns_adbfetch6_t;
96 
97 /*% dns adb structure */
98 struct dns_adb {
99 	unsigned int magic;
100 
101 	isc_mutex_t lock;
102 	isc_mutex_t reflock;	 /*%< Covers irefcnt, erefcnt */
103 	isc_mutex_t overmemlock; /*%< Covers overmem */
104 	isc_mem_t *mctx;
105 	dns_view_t *view;
106 
107 	isc_taskmgr_t *taskmgr;
108 	isc_task_t *task;
109 	isc_task_t *excl;
110 
111 	isc_interval_t tick_interval;
112 	int next_cleanbucket;
113 
114 	unsigned int irefcnt;
115 	unsigned int erefcnt;
116 
117 	isc_mutex_t mplock;
118 	isc_mempool_t *nmp;  /*%< dns_adbname_t */
119 	isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */
120 	isc_mempool_t *limp; /*%< dns_adblameinfo_t */
121 	isc_mempool_t *emp;  /*%< dns_adbentry_t */
122 	isc_mempool_t *ahmp; /*%< dns_adbfind_t */
123 	isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */
124 	isc_mempool_t *afmp; /*%< dns_adbfetch_t */
125 
126 	/*!
127 	 * Bucketized locks and lists for names.
128 	 *
129 	 * XXXRTH  Have a per-bucket structure that contains all of these?
130 	 */
131 	unsigned int nnames;
132 	isc_mutex_t namescntlock;
133 	unsigned int namescnt;
134 	dns_adbnamelist_t *names;
135 	dns_adbnamelist_t *deadnames;
136 	isc_mutex_t *namelocks;
137 	bool *name_sd;
138 	unsigned int *name_refcnt;
139 
140 	/*!
141 	 * Bucketized locks and lists for entries.
142 	 *
143 	 * XXXRTH  Have a per-bucket structure that contains all of these?
144 	 */
145 	unsigned int nentries;
146 	isc_mutex_t entriescntlock;
147 	unsigned int entriescnt;
148 	dns_adbentrylist_t *entries;
149 	dns_adbentrylist_t *deadentries;
150 	isc_mutex_t *entrylocks;
151 	bool *entry_sd; /*%< shutting down */
152 	unsigned int *entry_refcnt;
153 
154 	isc_event_t cevent;
155 	bool cevent_out;
156 	bool shutting_down;
157 	isc_eventlist_t whenshutdown;
158 	isc_event_t growentries;
159 	bool growentries_sent;
160 	isc_event_t grownames;
161 	bool grownames_sent;
162 
163 	uint32_t quota;
164 	uint32_t atr_freq;
165 	double atr_low;
166 	double atr_high;
167 	double atr_discount;
168 };
169 
170 /*
171  * XXXMLG  Document these structures.
172  */
173 
174 /*% dns_adbname structure */
175 struct dns_adbname {
176 	unsigned int magic;
177 	dns_name_t name;
178 	dns_adb_t *adb;
179 	unsigned int partial_result;
180 	unsigned int flags;
181 	int lock_bucket;
182 	dns_name_t target;
183 	isc_stdtime_t expire_target;
184 	isc_stdtime_t expire_v4;
185 	isc_stdtime_t expire_v6;
186 	unsigned int chains;
187 	dns_adbnamehooklist_t v4;
188 	dns_adbnamehooklist_t v6;
189 	dns_adbfetch_t *fetch_a;
190 	dns_adbfetch_t *fetch_aaaa;
191 	unsigned int fetch_err;
192 	unsigned int fetch6_err;
193 	dns_adbfindlist_t finds;
194 	/* for LRU-based management */
195 	isc_stdtime_t last_used;
196 
197 	ISC_LINK(dns_adbname_t) plink;
198 };
199 
200 /*% The adbfetch structure */
201 struct dns_adbfetch {
202 	unsigned int magic;
203 	dns_fetch_t *fetch;
204 	dns_rdataset_t rdataset;
205 	unsigned int depth;
206 };
207 
208 /*%
209  * This is a small widget that dangles off a dns_adbname_t.  It contains a
210  * pointer to the address information about this host, and a link to the next
211  * namehook that will contain the next address this host has.
212  */
213 struct dns_adbnamehook {
214 	unsigned int magic;
215 	dns_adbentry_t *entry;
216 	ISC_LINK(dns_adbnamehook_t) plink;
217 };
218 
219 /*%
220  * This is a small widget that holds qname-specific information about an
221  * address.  Currently limited to lameness, but could just as easily be
222  * extended to other types of information about zones.
223  */
224 struct dns_adblameinfo {
225 	unsigned int magic;
226 
227 	dns_name_t qname;
228 	dns_rdatatype_t qtype;
229 	isc_stdtime_t lame_timer;
230 
231 	ISC_LINK(dns_adblameinfo_t) plink;
232 };
233 
234 /*%
235  * An address entry.  It holds quite a bit of information about addresses,
236  * including edns state (in "flags"), rtt, and of course the address of
237  * the host.
238  */
239 struct dns_adbentry {
240 	unsigned int magic;
241 
242 	int lock_bucket;
243 	unsigned int refcnt;
244 	unsigned int nh;
245 
246 	unsigned int flags;
247 	unsigned int srtt;
248 	uint16_t udpsize;
249 	unsigned int completed;
250 	unsigned int timeouts;
251 	unsigned char plain;
252 	unsigned char plainto;
253 	unsigned char edns;
254 	unsigned char to4096; /* Our max. */
255 
256 	uint8_t mode;
257 	atomic_uint_fast32_t quota;
258 	atomic_uint_fast32_t active;
259 	double atr;
260 
261 	/*
262 	 * Allow for encapsulated IPv4/IPv6 UDP packet over ethernet.
263 	 * Ethernet 1500 - IP(20) - IP6(40) - UDP(8) = 1432.
264 	 */
265 	unsigned char to1432; /* Ethernet */
266 	unsigned char to1232; /* IPv6 nofrag */
267 	unsigned char to512;  /* plain DNS */
268 	isc_sockaddr_t sockaddr;
269 	unsigned char *cookie;
270 	uint16_t cookielen;
271 
272 	isc_stdtime_t expires;
273 	isc_stdtime_t lastage;
274 	/*%<
275 	 * A nonzero 'expires' field indicates that the entry should
276 	 * persist until that time.  This allows entries found
277 	 * using dns_adb_findaddrinfo() to persist for a limited time
278 	 * even though they are not necessarily associated with a
279 	 * name.
280 	 */
281 
282 	ISC_LIST(dns_adblameinfo_t) lameinfo;
283 	ISC_LINK(dns_adbentry_t) plink;
284 };
285 
286 /*
287  * Internal functions (and prototypes).
288  */
289 static inline dns_adbname_t *
290 new_adbname(dns_adb_t *, const dns_name_t *);
291 static inline void
292 free_adbname(dns_adb_t *, dns_adbname_t **);
293 static inline dns_adbnamehook_t *
294 new_adbnamehook(dns_adb_t *, dns_adbentry_t *);
295 static inline void
296 free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
297 static inline dns_adblameinfo_t *
298 new_adblameinfo(dns_adb_t *, const dns_name_t *, dns_rdatatype_t);
299 static inline void
300 free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **);
301 static inline dns_adbentry_t *
302 new_adbentry(dns_adb_t *);
303 static inline void
304 free_adbentry(dns_adb_t *, dns_adbentry_t **);
305 static inline dns_adbfind_t *
306 new_adbfind(dns_adb_t *);
307 static inline bool
308 free_adbfind(dns_adb_t *, dns_adbfind_t **);
309 static inline dns_adbaddrinfo_t *
310 new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *, in_port_t);
311 static inline dns_adbfetch_t *
312 new_adbfetch(dns_adb_t *);
313 static inline void
314 free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
315 static inline dns_adbname_t *
316 find_name_and_lock(dns_adb_t *, const dns_name_t *, unsigned int, int *);
317 static inline dns_adbentry_t *
318 find_entry_and_lock(dns_adb_t *, const isc_sockaddr_t *, int *, isc_stdtime_t);
319 static void
320 dump_adb(dns_adb_t *, FILE *, bool debug, isc_stdtime_t);
321 static void
322 print_dns_name(FILE *, const dns_name_t *);
323 static void
324 print_namehook_list(FILE *, const char *legend, dns_adb_t *adb,
325 		    dns_adbnamehooklist_t *list, bool debug, isc_stdtime_t now);
326 static void
327 print_find_list(FILE *, dns_adbname_t *);
328 static void
329 print_fetch_list(FILE *, dns_adbname_t *);
330 static inline bool
331 dec_adb_irefcnt(dns_adb_t *);
332 static inline void
333 inc_adb_irefcnt(dns_adb_t *);
334 static inline void
335 inc_adb_erefcnt(dns_adb_t *);
336 static inline void
337 inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *, bool);
338 static inline bool
339 dec_entry_refcnt(dns_adb_t *, bool, dns_adbentry_t *, bool);
340 static inline void
341 violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
342 static bool
343 clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
344 static void
345 clean_target(dns_adb_t *, dns_name_t *);
346 static void
347 clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int);
348 static bool
349 check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
350 static bool
351 check_expire_entry(dns_adb_t *, dns_adbentry_t **, isc_stdtime_t);
352 static void
353 cancel_fetches_at_name(dns_adbname_t *);
354 static isc_result_t
355 dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t);
356 static isc_result_t
357 fetch_name(dns_adbname_t *, bool, unsigned int, isc_counter_t *qc,
358 	   dns_rdatatype_t);
359 static inline void
360 check_exit(dns_adb_t *);
361 static void
362 destroy(dns_adb_t *);
363 static bool
364 shutdown_names(dns_adb_t *);
365 static bool
366 shutdown_entries(dns_adb_t *);
367 static inline void
368 link_name(dns_adb_t *, int, dns_adbname_t *);
369 static inline bool
370 unlink_name(dns_adb_t *, dns_adbname_t *);
371 static inline void
372 link_entry(dns_adb_t *, int, dns_adbentry_t *);
373 static inline bool
374 unlink_entry(dns_adb_t *, dns_adbentry_t *);
375 static bool
376 kill_name(dns_adbname_t **, isc_eventtype_t);
377 static void
378 water(void *, int);
379 static void
380 dump_entry(FILE *, dns_adb_t *, dns_adbentry_t *, bool, isc_stdtime_t);
381 static void
382 adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
383 	   isc_stdtime_t now);
384 static void
385 shutdown_task(isc_task_t *task, isc_event_t *ev);
386 static void
387 log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
388 
389 /*
390  * MUST NOT overlap DNS_ADBFIND_* flags!
391  */
392 #define FIND_EVENT_SENT	   0x40000000
393 #define FIND_EVENT_FREED   0x80000000
394 #define FIND_EVENTSENT(h)  (((h)->flags & FIND_EVENT_SENT) != 0)
395 #define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
396 
397 #define NAME_NEEDS_POKE	  0x80000000
398 #define NAME_IS_DEAD	  0x40000000
399 #define NAME_HINT_OK	  DNS_ADBFIND_HINTOK
400 #define NAME_GLUE_OK	  DNS_ADBFIND_GLUEOK
401 #define NAME_STARTATZONE  DNS_ADBFIND_STARTATZONE
402 #define NAME_DEAD(n)	  (((n)->flags & NAME_IS_DEAD) != 0)
403 #define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
404 #define NAME_GLUEOK(n)	  (((n)->flags & NAME_GLUE_OK) != 0)
405 #define NAME_HINTOK(n)	  (((n)->flags & NAME_HINT_OK) != 0)
406 
407 /*
408  * Private flag(s) for entries.
409  * MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0.
410  */
411 #define ENTRY_IS_DEAD 0x00400000
412 
413 /*
414  * To the name, address classes are all that really exist.  If it has a
415  * V6 address it doesn't care if it came from a AAAA query.
416  */
417 #define NAME_HAS_V4(n)	  (!ISC_LIST_EMPTY((n)->v4))
418 #define NAME_HAS_V6(n)	  (!ISC_LIST_EMPTY((n)->v6))
419 #define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
420 
421 /*
422  * Fetches are broken out into A and AAAA types.  In some cases,
423  * however, it makes more sense to test for a particular class of fetches,
424  * like V4 or V6 above.
425  * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA
426  * are now equal to FETCH_V4 and FETCH_V6, respectively.
427  */
428 #define NAME_FETCH_A(n)	   ((n)->fetch_a != NULL)
429 #define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
430 #define NAME_FETCH_V4(n)   (NAME_FETCH_A(n))
431 #define NAME_FETCH_V6(n)   (NAME_FETCH_AAAA(n))
432 #define NAME_FETCH(n)	   (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
433 
434 /*
435  * Find options and tests to see if there are addresses on the list.
436  */
437 #define FIND_WANTEVENT(fn)	(((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
438 #define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
439 #define FIND_AVOIDFETCHES(fn)	(((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0)
440 #define FIND_STARTATZONE(fn)	(((fn)->options & DNS_ADBFIND_STARTATZONE) != 0)
441 #define FIND_HINTOK(fn)		(((fn)->options & DNS_ADBFIND_HINTOK) != 0)
442 #define FIND_GLUEOK(fn)		(((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
443 #define FIND_HAS_ADDRS(fn)	(!ISC_LIST_EMPTY((fn)->list))
444 #define FIND_RETURNLAME(fn)	(((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
445 #define FIND_NOFETCH(fn)	(((fn)->options & DNS_ADBFIND_NOFETCH) != 0)
446 
447 /*
448  * These are currently used on simple unsigned ints, so they are
449  * not really associated with any particular type.
450  */
451 #define WANT_INET(x)  (((x)&DNS_ADBFIND_INET) != 0)
452 #define WANT_INET6(x) (((x)&DNS_ADBFIND_INET6) != 0)
453 
454 #define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
455 
456 /*
457  * Find out if the flags on a name (nf) indicate if it is a hint or
458  * glue, and compare this to the appropriate bits set in o, to see if
459  * this is ok.
460  */
461 #define GLUE_OK(nf, o)	   (!NAME_GLUEOK(nf) || (((o)&DNS_ADBFIND_GLUEOK) != 0))
462 #define HINT_OK(nf, o)	   (!NAME_HINTOK(nf) || (((o)&DNS_ADBFIND_HINTOK) != 0))
463 #define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
464 #define STARTATZONE_MATCHES(nf, o) \
465 	(((nf)->flags & NAME_STARTATZONE) == ((o)&DNS_ADBFIND_STARTATZONE))
466 
467 #define ENTER_LEVEL  ISC_LOG_DEBUG(50)
468 #define EXIT_LEVEL   ENTER_LEVEL
469 #define CLEAN_LEVEL  ISC_LOG_DEBUG(100)
470 #define DEF_LEVEL    ISC_LOG_DEBUG(5)
471 #define NCACHE_LEVEL ISC_LOG_DEBUG(20)
472 
473 #define NCACHE_RESULT(r) \
474 	((r) == DNS_R_NCACHENXDOMAIN || (r) == DNS_R_NCACHENXRRSET)
475 #define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || (r) == DNS_R_NXRRSET)
476 #define NXDOMAIN_RESULT(r) \
477 	((r) == DNS_R_NXDOMAIN || (r) == DNS_R_NCACHENXDOMAIN)
478 #define NXRRSET_RESULT(r)                                      \
479 	((r) == DNS_R_NCACHENXRRSET || (r) == DNS_R_NXRRSET || \
480 	 (r) == DNS_R_HINTNXRRSET)
481 
482 /*
483  * Error state rankings.
484  */
485 
486 #define FIND_ERR_SUCCESS    0 /* highest rank */
487 #define FIND_ERR_CANCELED   1
488 #define FIND_ERR_FAILURE    2
489 #define FIND_ERR_NXDOMAIN   3
490 #define FIND_ERR_NXRRSET    4
491 #define FIND_ERR_UNEXPECTED 5
492 #define FIND_ERR_NOTFOUND   6
493 #define FIND_ERR_MAX	    7
494 
495 static const char *errnames[] = { "success",  "canceled", "failure",
496 				  "nxdomain", "nxrrset",  "unexpected",
497 				  "not_found" };
498 
499 #define NEWERR(old, new) (ISC_MIN((old), (new)))
500 
501 static isc_result_t find_err_map[FIND_ERR_MAX] = {
502 	ISC_R_SUCCESS, ISC_R_CANCELED,	 ISC_R_FAILURE, DNS_R_NXDOMAIN,
503 	DNS_R_NXRRSET, ISC_R_UNEXPECTED, ISC_R_NOTFOUND /* not YET found */
504 };
505 
506 static void
507 DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
508 
509 static void
510 DP(int level, const char *format, ...) {
511 	va_list args;
512 
513 	va_start(args, format);
514 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
515 		       level, format, args);
516 	va_end(args);
517 }
518 
519 /*%
520  * Increment resolver-related statistics counters.
521  */
522 static inline void
523 inc_stats(dns_adb_t *adb, isc_statscounter_t counter) {
524 	if (adb->view->resstats != NULL) {
525 		isc_stats_increment(adb->view->resstats, counter);
526 	}
527 }
528 
529 /*%
530  * Set adb-related statistics counters.
531  */
532 static inline void
533 set_adbstat(dns_adb_t *adb, uint64_t val, isc_statscounter_t counter) {
534 	if (adb->view->adbstats != NULL) {
535 		isc_stats_set(adb->view->adbstats, val, counter);
536 	}
537 }
538 
539 static inline void
540 dec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
541 	if (adb->view->adbstats != NULL) {
542 		isc_stats_decrement(adb->view->adbstats, counter);
543 	}
544 }
545 
546 static inline void
547 inc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
548 	if (adb->view->adbstats != NULL) {
549 		isc_stats_increment(adb->view->adbstats, counter);
550 	}
551 }
552 
553 static inline dns_ttl_t
554 ttlclamp(dns_ttl_t ttl) {
555 	if (ttl < ADB_CACHE_MINIMUM) {
556 		ttl = ADB_CACHE_MINIMUM;
557 	}
558 	if (ttl > ADB_CACHE_MAXIMUM) {
559 		ttl = ADB_CACHE_MAXIMUM;
560 	}
561 
562 	return (ttl);
563 }
564 
565 /*
566  * Hashing is most efficient if the number of buckets is prime.
567  * The sequence below is the closest previous primes to 2^n and
568  * 1.5 * 2^n, for values of n from 10 to 28.  (The tables will
569  * no longer grow beyond 2^28 entries.)
570  */
571 static const unsigned nbuckets[] = {
572 	1021,	   1531,     2039,     3067,	  4093,	     6143,
573 	8191,	   12281,    16381,    24571,	  32749,     49193,
574 	65521,	   98299,    131071,   199603,	  262139,    393209,
575 	524287,	   768431,   1048573,  1572853,	  2097143,   3145721,
576 	4194301,   6291449,  8388593,  12582893,  16777213,  25165813,
577 	33554393,  50331599, 67108859, 100663291, 134217689, 201326557,
578 	268535431, 0
579 };
580 
581 static void
582 grow_entries(isc_task_t *task, isc_event_t *ev) {
583 	dns_adb_t *adb;
584 	dns_adbentry_t *e;
585 	dns_adbentrylist_t *newdeadentries = NULL;
586 	dns_adbentrylist_t *newentries = NULL;
587 	bool *newentry_sd = NULL;
588 	isc_mutex_t *newentrylocks = NULL;
589 	isc_result_t result;
590 	unsigned int *newentry_refcnt = NULL;
591 	unsigned int i, n, bucket;
592 
593 	adb = ev->ev_arg;
594 	INSIST(DNS_ADB_VALID(adb));
595 
596 	isc_event_free(&ev);
597 
598 	result = isc_task_beginexclusive(task);
599 	if (result != ISC_R_SUCCESS) {
600 		goto check_exit;
601 	}
602 
603 	i = 0;
604 	while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i]) {
605 		i++;
606 	}
607 	if (nbuckets[i] != 0) {
608 		n = nbuckets[i];
609 	} else {
610 		goto done;
611 	}
612 
613 	DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n);
614 
615 	/*
616 	 * Are we shutting down?
617 	 */
618 	for (i = 0; i < adb->nentries; i++) {
619 		if (adb->entry_sd[i]) {
620 			goto cleanup;
621 
622 			/*
623 			 * Grab all the resources we need.
624 			 */
625 		}
626 	}
627 
628 	/*
629 	 * Grab all the resources we need.
630 	 */
631 	newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n);
632 	newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n);
633 	newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
634 	newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
635 	newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n);
636 	if (newentries == NULL || newdeadentries == NULL ||
637 	    newentrylocks == NULL || newentry_sd == NULL ||
638 	    newentry_refcnt == NULL)
639 	{
640 		goto cleanup;
641 	}
642 
643 	/*
644 	 * Initialise the new resources.
645 	 */
646 	isc_mutexblock_init(newentrylocks, n);
647 
648 	for (i = 0; i < n; i++) {
649 		ISC_LIST_INIT(newentries[i]);
650 		ISC_LIST_INIT(newdeadentries[i]);
651 		newentry_sd[i] = false;
652 		newentry_refcnt[i] = 0;
653 		adb->irefcnt++;
654 	}
655 
656 	/*
657 	 * Move entries to new arrays.
658 	 */
659 	for (i = 0; i < adb->nentries; i++) {
660 		e = ISC_LIST_HEAD(adb->entries[i]);
661 		while (e != NULL) {
662 			ISC_LIST_UNLINK(adb->entries[i], e, plink);
663 			bucket = isc_sockaddr_hash(&e->sockaddr, true) % n;
664 			e->lock_bucket = bucket;
665 			ISC_LIST_APPEND(newentries[bucket], e, plink);
666 			INSIST(adb->entry_refcnt[i] > 0);
667 			adb->entry_refcnt[i]--;
668 			newentry_refcnt[bucket]++;
669 			e = ISC_LIST_HEAD(adb->entries[i]);
670 		}
671 		e = ISC_LIST_HEAD(adb->deadentries[i]);
672 		while (e != NULL) {
673 			ISC_LIST_UNLINK(adb->deadentries[i], e, plink);
674 			bucket = isc_sockaddr_hash(&e->sockaddr, true) % n;
675 			e->lock_bucket = bucket;
676 			ISC_LIST_APPEND(newdeadentries[bucket], e, plink);
677 			INSIST(adb->entry_refcnt[i] > 0);
678 			adb->entry_refcnt[i]--;
679 			newentry_refcnt[bucket]++;
680 			e = ISC_LIST_HEAD(adb->deadentries[i]);
681 		}
682 		INSIST(adb->entry_refcnt[i] == 0);
683 		adb->irefcnt--;
684 	}
685 
686 	/*
687 	 * Cleanup old resources.
688 	 */
689 	isc_mutexblock_destroy(adb->entrylocks, adb->nentries);
690 	isc_mem_put(adb->mctx, adb->entries,
691 		    sizeof(*adb->entries) * adb->nentries);
692 	isc_mem_put(adb->mctx, adb->deadentries,
693 		    sizeof(*adb->deadentries) * adb->nentries);
694 	isc_mem_put(adb->mctx, adb->entrylocks,
695 		    sizeof(*adb->entrylocks) * adb->nentries);
696 	isc_mem_put(adb->mctx, adb->entry_sd,
697 		    sizeof(*adb->entry_sd) * adb->nentries);
698 	isc_mem_put(adb->mctx, adb->entry_refcnt,
699 		    sizeof(*adb->entry_refcnt) * adb->nentries);
700 
701 	/*
702 	 * Install new resources.
703 	 */
704 	adb->entries = newentries;
705 	adb->deadentries = newdeadentries;
706 	adb->entrylocks = newentrylocks;
707 	adb->entry_sd = newentry_sd;
708 	adb->entry_refcnt = newentry_refcnt;
709 	adb->nentries = n;
710 
711 	set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
712 
713 	/*
714 	 * Only on success do we set adb->growentries_sent to false.
715 	 * This will prevent us being continuously being called on error.
716 	 */
717 	adb->growentries_sent = false;
718 	goto done;
719 
720 cleanup:
721 	if (newentries != NULL) {
722 		isc_mem_put(adb->mctx, newentries, sizeof(*newentries) * n);
723 	}
724 	if (newdeadentries != NULL) {
725 		isc_mem_put(adb->mctx, newdeadentries,
726 			    sizeof(*newdeadentries) * n);
727 	}
728 	if (newentrylocks != NULL) {
729 		isc_mem_put(adb->mctx, newentrylocks,
730 			    sizeof(*newentrylocks) * n);
731 	}
732 	if (newentry_sd != NULL) {
733 		isc_mem_put(adb->mctx, newentry_sd, sizeof(*newentry_sd) * n);
734 	}
735 	if (newentry_refcnt != NULL) {
736 		isc_mem_put(adb->mctx, newentry_refcnt,
737 			    sizeof(*newentry_refcnt) * n);
738 	}
739 done:
740 	isc_task_endexclusive(task);
741 
742 check_exit:
743 	LOCK(&adb->lock);
744 	if (dec_adb_irefcnt(adb)) {
745 		check_exit(adb);
746 	}
747 	UNLOCK(&adb->lock);
748 	DP(ISC_LOG_INFO, "adb: grow_entries finished");
749 }
750 
751 static void
752 grow_names(isc_task_t *task, isc_event_t *ev) {
753 	dns_adb_t *adb;
754 	dns_adbname_t *name;
755 	dns_adbnamelist_t *newdeadnames = NULL;
756 	dns_adbnamelist_t *newnames = NULL;
757 	bool *newname_sd = NULL;
758 	isc_mutex_t *newnamelocks = NULL;
759 	isc_result_t result;
760 	unsigned int *newname_refcnt = NULL;
761 	unsigned int i, n;
762 	unsigned int bucket;
763 
764 	adb = ev->ev_arg;
765 	INSIST(DNS_ADB_VALID(adb));
766 
767 	isc_event_free(&ev);
768 
769 	result = isc_task_beginexclusive(task);
770 	if (result != ISC_R_SUCCESS) {
771 		goto check_exit;
772 	}
773 
774 	i = 0;
775 	while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i]) {
776 		i++;
777 	}
778 	if (nbuckets[i] != 0) {
779 		n = nbuckets[i];
780 	} else {
781 		goto done;
782 	}
783 
784 	DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n);
785 
786 	/*
787 	 * Are we shutting down?
788 	 */
789 	for (i = 0; i < adb->nnames; i++) {
790 		if (adb->name_sd[i]) {
791 			goto cleanup;
792 
793 			/*
794 			 * Grab all the resources we need.
795 			 */
796 		}
797 	}
798 
799 	/*
800 	 * Grab all the resources we need.
801 	 */
802 	newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n);
803 	newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n);
804 	newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
805 	newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
806 	newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
807 	if (newnames == NULL || newdeadnames == NULL || newnamelocks == NULL ||
808 	    newname_sd == NULL || newname_refcnt == NULL)
809 	{
810 		goto cleanup;
811 	}
812 
813 	/*
814 	 * Initialise the new resources.
815 	 */
816 	isc_mutexblock_init(newnamelocks, n);
817 
818 	for (i = 0; i < n; i++) {
819 		ISC_LIST_INIT(newnames[i]);
820 		ISC_LIST_INIT(newdeadnames[i]);
821 		newname_sd[i] = false;
822 		newname_refcnt[i] = 0;
823 		adb->irefcnt++;
824 	}
825 
826 	/*
827 	 * Move names to new arrays.
828 	 */
829 	for (i = 0; i < adb->nnames; i++) {
830 		name = ISC_LIST_HEAD(adb->names[i]);
831 		while (name != NULL) {
832 			ISC_LIST_UNLINK(adb->names[i], name, plink);
833 			bucket = dns_name_fullhash(&name->name, true) % n;
834 			name->lock_bucket = bucket;
835 			ISC_LIST_APPEND(newnames[bucket], name, plink);
836 			INSIST(adb->name_refcnt[i] > 0);
837 			adb->name_refcnt[i]--;
838 			newname_refcnt[bucket]++;
839 			name = ISC_LIST_HEAD(adb->names[i]);
840 		}
841 		name = ISC_LIST_HEAD(adb->deadnames[i]);
842 		while (name != NULL) {
843 			ISC_LIST_UNLINK(adb->deadnames[i], name, plink);
844 			bucket = dns_name_fullhash(&name->name, true) % n;
845 			name->lock_bucket = bucket;
846 			ISC_LIST_APPEND(newdeadnames[bucket], name, plink);
847 			INSIST(adb->name_refcnt[i] > 0);
848 			adb->name_refcnt[i]--;
849 			newname_refcnt[bucket]++;
850 			name = ISC_LIST_HEAD(adb->deadnames[i]);
851 		}
852 		INSIST(adb->name_refcnt[i] == 0);
853 		adb->irefcnt--;
854 	}
855 
856 	/*
857 	 * Cleanup old resources.
858 	 */
859 	isc_mutexblock_destroy(adb->namelocks, adb->nnames);
860 	isc_mem_put(adb->mctx, adb->names, sizeof(*adb->names) * adb->nnames);
861 	isc_mem_put(adb->mctx, adb->deadnames,
862 		    sizeof(*adb->deadnames) * adb->nnames);
863 	isc_mem_put(adb->mctx, adb->namelocks,
864 		    sizeof(*adb->namelocks) * adb->nnames);
865 	isc_mem_put(adb->mctx, adb->name_sd,
866 		    sizeof(*adb->name_sd) * adb->nnames);
867 	isc_mem_put(adb->mctx, adb->name_refcnt,
868 		    sizeof(*adb->name_refcnt) * adb->nnames);
869 
870 	/*
871 	 * Install new resources.
872 	 */
873 	adb->names = newnames;
874 	adb->deadnames = newdeadnames;
875 	adb->namelocks = newnamelocks;
876 	adb->name_sd = newname_sd;
877 	adb->name_refcnt = newname_refcnt;
878 	adb->nnames = n;
879 
880 	set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
881 
882 	/*
883 	 * Only on success do we set adb->grownames_sent to false.
884 	 * This will prevent us being continuously being called on error.
885 	 */
886 	adb->grownames_sent = false;
887 	goto done;
888 
889 cleanup:
890 	if (newnames != NULL) {
891 		isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n);
892 	}
893 	if (newdeadnames != NULL) {
894 		isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n);
895 	}
896 	if (newnamelocks != NULL) {
897 		isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n);
898 	}
899 	if (newname_sd != NULL) {
900 		isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n);
901 	}
902 	if (newname_refcnt != NULL) {
903 		isc_mem_put(adb->mctx, newname_refcnt,
904 			    sizeof(*newname_refcnt) * n);
905 	}
906 done:
907 	isc_task_endexclusive(task);
908 
909 check_exit:
910 	LOCK(&adb->lock);
911 	if (dec_adb_irefcnt(adb)) {
912 		check_exit(adb);
913 	}
914 	UNLOCK(&adb->lock);
915 	DP(ISC_LOG_INFO, "adb: grow_names finished");
916 }
917 
918 /*
919  * Requires the adbname bucket be locked and that no entry buckets be locked.
920  *
921  * This code handles A and AAAA rdatasets only.
922  */
923 static isc_result_t
924 import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
925 		isc_stdtime_t now) {
926 	isc_result_t result;
927 	dns_adb_t *adb;
928 	dns_adbnamehook_t *nh;
929 	dns_adbnamehook_t *anh;
930 	dns_rdata_t rdata = DNS_RDATA_INIT;
931 	struct in_addr ina;
932 	struct in6_addr in6a;
933 	isc_sockaddr_t sockaddr;
934 	dns_adbentry_t *foundentry; /* NO CLEAN UP! */
935 	int addr_bucket;
936 	bool new_addresses_added;
937 	dns_rdatatype_t rdtype;
938 	unsigned int findoptions;
939 	dns_adbnamehooklist_t *hookhead;
940 
941 	INSIST(DNS_ADBNAME_VALID(adbname));
942 	adb = adbname->adb;
943 	INSIST(DNS_ADB_VALID(adb));
944 
945 	rdtype = rdataset->type;
946 	INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
947 	if (rdtype == dns_rdatatype_a) {
948 		findoptions = DNS_ADBFIND_INET;
949 	} else {
950 		findoptions = DNS_ADBFIND_INET6;
951 	}
952 
953 	addr_bucket = DNS_ADB_INVALIDBUCKET;
954 	new_addresses_added = false;
955 
956 	nh = NULL;
957 	result = dns_rdataset_first(rdataset);
958 	while (result == ISC_R_SUCCESS) {
959 		dns_rdata_reset(&rdata);
960 		dns_rdataset_current(rdataset, &rdata);
961 		if (rdtype == dns_rdatatype_a) {
962 			INSIST(rdata.length == 4);
963 			memmove(&ina.s_addr, rdata.data, 4);
964 			isc_sockaddr_fromin(&sockaddr, &ina, 0);
965 			hookhead = &adbname->v4;
966 		} else {
967 			INSIST(rdata.length == 16);
968 			memmove(in6a.s6_addr, rdata.data, 16);
969 			isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
970 			hookhead = &adbname->v6;
971 		}
972 
973 		INSIST(nh == NULL);
974 		nh = new_adbnamehook(adb, NULL);
975 		if (nh == NULL) {
976 			adbname->partial_result |= findoptions;
977 			result = ISC_R_NOMEMORY;
978 			goto fail;
979 		}
980 
981 		foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket,
982 						 now);
983 		if (foundentry == NULL) {
984 			dns_adbentry_t *entry;
985 
986 			entry = new_adbentry(adb);
987 			if (entry == NULL) {
988 				adbname->partial_result |= findoptions;
989 				result = ISC_R_NOMEMORY;
990 				goto fail;
991 			}
992 
993 			entry->sockaddr = sockaddr;
994 			entry->refcnt = 1;
995 			entry->nh = 1;
996 
997 			nh->entry = entry;
998 
999 			link_entry(adb, addr_bucket, entry);
1000 		} else {
1001 			for (anh = ISC_LIST_HEAD(*hookhead); anh != NULL;
1002 			     anh = ISC_LIST_NEXT(anh, plink))
1003 			{
1004 				if (anh->entry == foundentry) {
1005 					break;
1006 				}
1007 			}
1008 			if (anh == NULL) {
1009 				foundentry->refcnt++;
1010 				foundentry->nh++;
1011 				nh->entry = foundentry;
1012 			} else {
1013 				free_adbnamehook(adb, &nh);
1014 			}
1015 		}
1016 
1017 		new_addresses_added = true;
1018 		if (nh != NULL) {
1019 			ISC_LIST_APPEND(*hookhead, nh, plink);
1020 		}
1021 		nh = NULL;
1022 		result = dns_rdataset_next(rdataset);
1023 	}
1024 
1025 fail:
1026 	if (nh != NULL) {
1027 		free_adbnamehook(adb, &nh);
1028 	}
1029 
1030 	if (addr_bucket != DNS_ADB_INVALIDBUCKET) {
1031 		UNLOCK(&adb->entrylocks[addr_bucket]);
1032 	}
1033 
1034 	if (rdataset->trust == dns_trust_glue ||
1035 	    rdataset->trust == dns_trust_additional)
1036 	{
1037 		rdataset->ttl = ADB_CACHE_MINIMUM;
1038 	} else if (rdataset->trust == dns_trust_ultimate) {
1039 		rdataset->ttl = 0;
1040 	} else {
1041 		rdataset->ttl = ttlclamp(rdataset->ttl);
1042 	}
1043 
1044 	if (rdtype == dns_rdatatype_a) {
1045 		DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
1046 		   adbname->expire_v4, now + rdataset->ttl);
1047 		adbname->expire_v4 = ISC_MIN(
1048 			adbname->expire_v4,
1049 			ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
1050 	} else {
1051 		DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
1052 		   adbname->expire_v6, now + rdataset->ttl);
1053 		adbname->expire_v6 = ISC_MIN(
1054 			adbname->expire_v6,
1055 			ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
1056 	}
1057 
1058 	if (new_addresses_added) {
1059 		/*
1060 		 * Lie a little here.  This is more or less so code that cares
1061 		 * can find out if any new information was added or not.
1062 		 */
1063 		return (ISC_R_SUCCESS);
1064 	}
1065 
1066 	return (result);
1067 }
1068 
1069 /*
1070  * Requires the name's bucket be locked.
1071  */
1072 static bool
1073 kill_name(dns_adbname_t **n, isc_eventtype_t ev) {
1074 	dns_adbname_t *name;
1075 	bool result = false;
1076 	bool result4, result6;
1077 	int bucket;
1078 	dns_adb_t *adb;
1079 
1080 	INSIST(n != NULL);
1081 	name = *n;
1082 	*n = NULL;
1083 	INSIST(DNS_ADBNAME_VALID(name));
1084 	adb = name->adb;
1085 	INSIST(DNS_ADB_VALID(adb));
1086 
1087 	DP(DEF_LEVEL, "killing name %p", name);
1088 
1089 	/*
1090 	 * If we're dead already, just check to see if we should go
1091 	 * away now or not.
1092 	 */
1093 	if (NAME_DEAD(name) && !NAME_FETCH(name)) {
1094 		result = unlink_name(adb, name);
1095 		free_adbname(adb, &name);
1096 		if (result) {
1097 			result = dec_adb_irefcnt(adb);
1098 		}
1099 		return (result);
1100 	}
1101 
1102 	/*
1103 	 * Clean up the name's various lists.  These two are destructive
1104 	 * in that they will always empty the list.
1105 	 */
1106 	clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
1107 	result4 = clean_namehooks(adb, &name->v4);
1108 	result6 = clean_namehooks(adb, &name->v6);
1109 	clean_target(adb, &name->target);
1110 	result = (result4 || result6);
1111 
1112 	/*
1113 	 * If fetches are running, cancel them.  If none are running, we can
1114 	 * just kill the name here.
1115 	 */
1116 	if (!NAME_FETCH(name)) {
1117 		INSIST(!result);
1118 		result = unlink_name(adb, name);
1119 		free_adbname(adb, &name);
1120 		if (result) {
1121 			result = dec_adb_irefcnt(adb);
1122 		}
1123 	} else {
1124 		cancel_fetches_at_name(name);
1125 		if (!NAME_DEAD(name)) {
1126 			bucket = name->lock_bucket;
1127 			ISC_LIST_UNLINK(adb->names[bucket], name, plink);
1128 			ISC_LIST_APPEND(adb->deadnames[bucket], name, plink);
1129 			name->flags |= NAME_IS_DEAD;
1130 		}
1131 	}
1132 	return (result);
1133 }
1134 
1135 /*
1136  * Requires the name's bucket be locked and no entry buckets be locked.
1137  */
1138 static bool
1139 check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
1140 	dns_adb_t *adb;
1141 	bool result4 = false;
1142 	bool result6 = false;
1143 
1144 	INSIST(DNS_ADBNAME_VALID(name));
1145 	adb = name->adb;
1146 	INSIST(DNS_ADB_VALID(adb));
1147 
1148 	/*
1149 	 * Check to see if we need to remove the v4 addresses
1150 	 */
1151 	if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) {
1152 		if (NAME_HAS_V4(name)) {
1153 			DP(DEF_LEVEL, "expiring v4 for name %p", name);
1154 			result4 = clean_namehooks(adb, &name->v4);
1155 			name->partial_result &= ~DNS_ADBFIND_INET;
1156 		}
1157 		name->expire_v4 = INT_MAX;
1158 		name->fetch_err = FIND_ERR_UNEXPECTED;
1159 	}
1160 
1161 	/*
1162 	 * Check to see if we need to remove the v6 addresses
1163 	 */
1164 	if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) {
1165 		if (NAME_HAS_V6(name)) {
1166 			DP(DEF_LEVEL, "expiring v6 for name %p", name);
1167 			result6 = clean_namehooks(adb, &name->v6);
1168 			name->partial_result &= ~DNS_ADBFIND_INET6;
1169 		}
1170 		name->expire_v6 = INT_MAX;
1171 		name->fetch6_err = FIND_ERR_UNEXPECTED;
1172 	}
1173 
1174 	/*
1175 	 * Check to see if we need to remove the alias target.
1176 	 */
1177 	if (EXPIRE_OK(name->expire_target, now)) {
1178 		clean_target(adb, &name->target);
1179 		name->expire_target = INT_MAX;
1180 	}
1181 	return (result4 || result6);
1182 }
1183 
1184 /*
1185  * Requires the name's bucket be locked.
1186  */
1187 static inline void
1188 link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
1189 	INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
1190 
1191 	ISC_LIST_PREPEND(adb->names[bucket], name, plink);
1192 	name->lock_bucket = bucket;
1193 	adb->name_refcnt[bucket]++;
1194 }
1195 
1196 /*
1197  * Requires the name's bucket be locked.
1198  */
1199 static inline bool
1200 unlink_name(dns_adb_t *adb, dns_adbname_t *name) {
1201 	int bucket;
1202 	bool result = false;
1203 
1204 	bucket = name->lock_bucket;
1205 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
1206 
1207 	if (NAME_DEAD(name)) {
1208 		ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink);
1209 	} else {
1210 		ISC_LIST_UNLINK(adb->names[bucket], name, plink);
1211 	}
1212 	name->lock_bucket = DNS_ADB_INVALIDBUCKET;
1213 	INSIST(adb->name_refcnt[bucket] > 0);
1214 	adb->name_refcnt[bucket]--;
1215 	if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0) {
1216 		result = true;
1217 	}
1218 	return (result);
1219 }
1220 
1221 /*
1222  * Requires the entry's bucket be locked.
1223  */
1224 static inline void
1225 link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
1226 	int i;
1227 	dns_adbentry_t *e;
1228 
1229 	if (isc_mem_isovermem(adb->mctx)) {
1230 		for (i = 0; i < 2; i++) {
1231 			e = ISC_LIST_TAIL(adb->entries[bucket]);
1232 			if (e == NULL) {
1233 				break;
1234 			}
1235 			if (e->refcnt == 0) {
1236 				unlink_entry(adb, e);
1237 				free_adbentry(adb, &e);
1238 				continue;
1239 			}
1240 			INSIST((e->flags & ENTRY_IS_DEAD) == 0);
1241 			e->flags |= ENTRY_IS_DEAD;
1242 			ISC_LIST_UNLINK(adb->entries[bucket], e, plink);
1243 			ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink);
1244 		}
1245 	}
1246 
1247 	ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
1248 	entry->lock_bucket = bucket;
1249 	adb->entry_refcnt[bucket]++;
1250 }
1251 
1252 /*
1253  * Requires the entry's bucket be locked.
1254  */
1255 static inline bool
1256 unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
1257 	int bucket;
1258 	bool result = false;
1259 
1260 	bucket = entry->lock_bucket;
1261 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
1262 
1263 	if ((entry->flags & ENTRY_IS_DEAD) != 0) {
1264 		ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink);
1265 	} else {
1266 		ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
1267 	}
1268 	entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
1269 	INSIST(adb->entry_refcnt[bucket] > 0);
1270 	adb->entry_refcnt[bucket]--;
1271 	if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0) {
1272 		result = true;
1273 	}
1274 	return (result);
1275 }
1276 
1277 static inline void
1278 violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
1279 	if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
1280 		UNLOCK(have);
1281 		LOCK(want);
1282 		LOCK(have);
1283 	}
1284 }
1285 
1286 /*
1287  * The ADB _MUST_ be locked before calling.  Also, exit conditions must be
1288  * checked after calling this function.
1289  */
1290 static bool
1291 shutdown_names(dns_adb_t *adb) {
1292 	unsigned int bucket;
1293 	bool result = false;
1294 	dns_adbname_t *name;
1295 	dns_adbname_t *next_name;
1296 
1297 	for (bucket = 0; bucket < adb->nnames; bucket++) {
1298 		LOCK(&adb->namelocks[bucket]);
1299 		adb->name_sd[bucket] = true;
1300 
1301 		name = ISC_LIST_HEAD(adb->names[bucket]);
1302 		if (name == NULL) {
1303 			/*
1304 			 * This bucket has no names.  We must decrement the
1305 			 * irefcnt ourselves, since it will not be
1306 			 * automatically triggered by a name being unlinked.
1307 			 */
1308 			INSIST(!result);
1309 			result = dec_adb_irefcnt(adb);
1310 		} else {
1311 			/*
1312 			 * Run through the list.  For each name, clean up finds
1313 			 * found there, and cancel any fetches running.  When
1314 			 * all the fetches are canceled, the name will destroy
1315 			 * itself.
1316 			 */
1317 			while (name != NULL) {
1318 				next_name = ISC_LIST_NEXT(name, plink);
1319 				INSIST(!result);
1320 				result = kill_name(&name,
1321 						   DNS_EVENT_ADBSHUTDOWN);
1322 				name = next_name;
1323 			}
1324 		}
1325 
1326 		UNLOCK(&adb->namelocks[bucket]);
1327 	}
1328 	return (result);
1329 }
1330 
1331 /*
1332  * The ADB _MUST_ be locked before calling.  Also, exit conditions must be
1333  * checked after calling this function.
1334  */
1335 static bool
1336 shutdown_entries(dns_adb_t *adb) {
1337 	unsigned int bucket;
1338 	bool result = false;
1339 	dns_adbentry_t *entry;
1340 	dns_adbentry_t *next_entry;
1341 
1342 	for (bucket = 0; bucket < adb->nentries; bucket++) {
1343 		LOCK(&adb->entrylocks[bucket]);
1344 		adb->entry_sd[bucket] = true;
1345 
1346 		entry = ISC_LIST_HEAD(adb->entries[bucket]);
1347 		if (adb->entry_refcnt[bucket] == 0) {
1348 			/*
1349 			 * This bucket has no entries.  We must decrement the
1350 			 * irefcnt ourselves, since it will not be
1351 			 * automatically triggered by an entry being unlinked.
1352 			 */
1353 			result = dec_adb_irefcnt(adb);
1354 		} else {
1355 			/*
1356 			 * Run through the list.  Cleanup any entries not
1357 			 * associated with names, and which are not in use.
1358 			 */
1359 			while (entry != NULL) {
1360 				next_entry = ISC_LIST_NEXT(entry, plink);
1361 				if (entry->refcnt == 0 && entry->expires != 0) {
1362 					result = unlink_entry(adb, entry);
1363 					free_adbentry(adb, &entry);
1364 					if (result) {
1365 						result = dec_adb_irefcnt(adb);
1366 					}
1367 				}
1368 				entry = next_entry;
1369 			}
1370 		}
1371 
1372 		UNLOCK(&adb->entrylocks[bucket]);
1373 	}
1374 	return (result);
1375 }
1376 
1377 /*
1378  * Name bucket must be locked
1379  */
1380 static void
1381 cancel_fetches_at_name(dns_adbname_t *name) {
1382 	if (NAME_FETCH_A(name)) {
1383 		dns_resolver_cancelfetch(name->fetch_a->fetch);
1384 	}
1385 
1386 	if (NAME_FETCH_AAAA(name)) {
1387 		dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
1388 	}
1389 }
1390 
1391 /*
1392  * Assumes the name bucket is locked.
1393  */
1394 static bool
1395 clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
1396 	dns_adbentry_t *entry;
1397 	dns_adbnamehook_t *namehook;
1398 	int addr_bucket;
1399 	bool result = false;
1400 	bool overmem = isc_mem_isovermem(adb->mctx);
1401 
1402 	addr_bucket = DNS_ADB_INVALIDBUCKET;
1403 	namehook = ISC_LIST_HEAD(*namehooks);
1404 	while (namehook != NULL) {
1405 		INSIST(DNS_ADBNAMEHOOK_VALID(namehook));
1406 
1407 		/*
1408 		 * Clean up the entry if needed.
1409 		 */
1410 		entry = namehook->entry;
1411 		if (entry != NULL) {
1412 			INSIST(DNS_ADBENTRY_VALID(entry));
1413 
1414 			if (addr_bucket != entry->lock_bucket) {
1415 				if (addr_bucket != DNS_ADB_INVALIDBUCKET) {
1416 					UNLOCK(&adb->entrylocks[addr_bucket]);
1417 				}
1418 				addr_bucket = entry->lock_bucket;
1419 				INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET);
1420 				LOCK(&adb->entrylocks[addr_bucket]);
1421 			}
1422 
1423 			entry->nh--;
1424 			result = dec_entry_refcnt(adb, overmem, entry, false);
1425 		}
1426 
1427 		/*
1428 		 * Free the namehook
1429 		 */
1430 		namehook->entry = NULL;
1431 		ISC_LIST_UNLINK(*namehooks, namehook, plink);
1432 		free_adbnamehook(adb, &namehook);
1433 
1434 		namehook = ISC_LIST_HEAD(*namehooks);
1435 	}
1436 
1437 	if (addr_bucket != DNS_ADB_INVALIDBUCKET) {
1438 		UNLOCK(&adb->entrylocks[addr_bucket]);
1439 	}
1440 	return (result);
1441 }
1442 
1443 static void
1444 clean_target(dns_adb_t *adb, dns_name_t *target) {
1445 	if (dns_name_countlabels(target) > 0) {
1446 		dns_name_free(target, adb->mctx);
1447 		dns_name_init(target, NULL);
1448 	}
1449 }
1450 
1451 static isc_result_t
1452 set_target(dns_adb_t *adb, const dns_name_t *name, const dns_name_t *fname,
1453 	   dns_rdataset_t *rdataset, dns_name_t *target) {
1454 	isc_result_t result;
1455 	dns_namereln_t namereln;
1456 	unsigned int nlabels;
1457 	int order;
1458 	dns_rdata_t rdata = DNS_RDATA_INIT;
1459 	dns_fixedname_t fixed1, fixed2;
1460 	dns_name_t *prefix, *new_target;
1461 
1462 	REQUIRE(dns_name_countlabels(target) == 0);
1463 
1464 	if (rdataset->type == dns_rdatatype_cname) {
1465 		dns_rdata_cname_t cname;
1466 
1467 		/*
1468 		 * Copy the CNAME's target into the target name.
1469 		 */
1470 		result = dns_rdataset_first(rdataset);
1471 		if (result != ISC_R_SUCCESS) {
1472 			return (result);
1473 		}
1474 		dns_rdataset_current(rdataset, &rdata);
1475 		result = dns_rdata_tostruct(&rdata, &cname, NULL);
1476 		if (result != ISC_R_SUCCESS) {
1477 			return (result);
1478 		}
1479 		dns_name_dup(&cname.cname, adb->mctx, target);
1480 		dns_rdata_freestruct(&cname);
1481 	} else {
1482 		dns_rdata_dname_t dname;
1483 
1484 		INSIST(rdataset->type == dns_rdatatype_dname);
1485 		namereln = dns_name_fullcompare(name, fname, &order, &nlabels);
1486 		INSIST(namereln == dns_namereln_subdomain);
1487 		/*
1488 		 * Get the target name of the DNAME.
1489 		 */
1490 		result = dns_rdataset_first(rdataset);
1491 		if (result != ISC_R_SUCCESS) {
1492 			return (result);
1493 		}
1494 		dns_rdataset_current(rdataset, &rdata);
1495 		result = dns_rdata_tostruct(&rdata, &dname, NULL);
1496 		if (result != ISC_R_SUCCESS) {
1497 			return (result);
1498 		}
1499 		/*
1500 		 * Construct the new target name.
1501 		 */
1502 		prefix = dns_fixedname_initname(&fixed1);
1503 		new_target = dns_fixedname_initname(&fixed2);
1504 		dns_name_split(name, nlabels, prefix, NULL);
1505 		result = dns_name_concatenate(prefix, &dname.dname, new_target,
1506 					      NULL);
1507 		dns_rdata_freestruct(&dname);
1508 		if (result != ISC_R_SUCCESS) {
1509 			return (result);
1510 		}
1511 		dns_name_dup(new_target, adb->mctx, target);
1512 	}
1513 
1514 	return (ISC_R_SUCCESS);
1515 }
1516 
1517 /*
1518  * Assumes nothing is locked, since this is called by the client.
1519  */
1520 static void
1521 event_free(isc_event_t *event) {
1522 	dns_adbfind_t *find;
1523 
1524 	INSIST(event != NULL);
1525 	find = event->ev_destroy_arg;
1526 	INSIST(DNS_ADBFIND_VALID(find));
1527 
1528 	LOCK(&find->lock);
1529 	find->flags |= FIND_EVENT_FREED;
1530 	event->ev_destroy_arg = NULL;
1531 	UNLOCK(&find->lock);
1532 }
1533 
1534 /*
1535  * Assumes the name bucket is locked.
1536  */
1537 static void
1538 clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
1539 		    unsigned int addrs) {
1540 	isc_event_t *ev;
1541 	isc_task_t *task;
1542 	dns_adbfind_t *find;
1543 	dns_adbfind_t *next_find;
1544 	bool process;
1545 	unsigned int wanted, notify;
1546 
1547 	DP(ENTER_LEVEL,
1548 	   "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x", name,
1549 	   evtype, addrs);
1550 
1551 	find = ISC_LIST_HEAD(name->finds);
1552 	while (find != NULL) {
1553 		LOCK(&find->lock);
1554 		next_find = ISC_LIST_NEXT(find, plink);
1555 
1556 		process = false;
1557 		wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
1558 		notify = wanted & addrs;
1559 
1560 		switch (evtype) {
1561 		case DNS_EVENT_ADBMOREADDRESSES:
1562 			DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
1563 			if ((notify) != 0) {
1564 				find->flags &= ~addrs;
1565 				process = true;
1566 			}
1567 			break;
1568 		case DNS_EVENT_ADBNOMOREADDRESSES:
1569 			DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
1570 			find->flags &= ~addrs;
1571 			wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
1572 			if (wanted == 0) {
1573 				process = true;
1574 			}
1575 			break;
1576 		default:
1577 			find->flags &= ~addrs;
1578 			process = true;
1579 		}
1580 
1581 		if (process) {
1582 			DP(DEF_LEVEL, "cfan: processing find %p", find);
1583 			/*
1584 			 * Unlink the find from the name, letting the caller
1585 			 * call dns_adb_destroyfind() on it to clean it up
1586 			 * later.
1587 			 */
1588 			ISC_LIST_UNLINK(name->finds, find, plink);
1589 			find->adbname = NULL;
1590 			find->name_bucket = DNS_ADB_INVALIDBUCKET;
1591 
1592 			INSIST(!FIND_EVENTSENT(find));
1593 
1594 			ev = &find->event;
1595 			task = ev->ev_sender;
1596 			ev->ev_sender = find;
1597 			find->result_v4 = find_err_map[name->fetch_err];
1598 			find->result_v6 = find_err_map[name->fetch6_err];
1599 			ev->ev_type = evtype;
1600 			ev->ev_destroy = event_free;
1601 			ev->ev_destroy_arg = find;
1602 
1603 			DP(DEF_LEVEL, "sending event %p to task %p for find %p",
1604 			   ev, task, find);
1605 
1606 			isc_task_sendanddetach(&task, (isc_event_t **)&ev);
1607 			find->flags |= FIND_EVENT_SENT;
1608 		} else {
1609 			DP(DEF_LEVEL, "cfan: skipping find %p", find);
1610 		}
1611 
1612 		UNLOCK(&find->lock);
1613 		find = next_find;
1614 	}
1615 	DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
1616 }
1617 
1618 static inline void
1619 check_exit(dns_adb_t *adb) {
1620 	isc_event_t *event;
1621 	/*
1622 	 * The caller must be holding the adb lock.
1623 	 */
1624 	if (adb->shutting_down) {
1625 		/*
1626 		 * If there aren't any external references either, we're
1627 		 * done.  Send the control event to initiate shutdown.
1628 		 */
1629 		INSIST(!adb->cevent_out); /* Sanity check. */
1630 		ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
1631 			       DNS_EVENT_ADBCONTROL, shutdown_task, adb, adb,
1632 			       NULL, NULL);
1633 		event = &adb->cevent;
1634 		isc_task_send(adb->task, &event);
1635 		adb->cevent_out = true;
1636 	}
1637 }
1638 
1639 static inline bool
1640 dec_adb_irefcnt(dns_adb_t *adb) {
1641 	isc_event_t *event;
1642 	isc_task_t *etask;
1643 	bool result = false;
1644 
1645 	LOCK(&adb->reflock);
1646 
1647 	INSIST(adb->irefcnt > 0);
1648 	adb->irefcnt--;
1649 
1650 	if (adb->irefcnt == 0) {
1651 		event = ISC_LIST_HEAD(adb->whenshutdown);
1652 		while (event != NULL) {
1653 			ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
1654 			etask = event->ev_sender;
1655 			event->ev_sender = adb;
1656 			isc_task_sendanddetach(&etask, &event);
1657 			event = ISC_LIST_HEAD(adb->whenshutdown);
1658 		}
1659 	}
1660 
1661 	if (adb->irefcnt == 0 && adb->erefcnt == 0) {
1662 		result = true;
1663 	}
1664 	UNLOCK(&adb->reflock);
1665 	return (result);
1666 }
1667 
1668 static inline void
1669 inc_adb_irefcnt(dns_adb_t *adb) {
1670 	LOCK(&adb->reflock);
1671 	adb->irefcnt++;
1672 	UNLOCK(&adb->reflock);
1673 }
1674 
1675 static inline void
1676 inc_adb_erefcnt(dns_adb_t *adb) {
1677 	LOCK(&adb->reflock);
1678 	adb->erefcnt++;
1679 	UNLOCK(&adb->reflock);
1680 }
1681 
1682 static inline void
1683 inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, bool lock) {
1684 	int bucket;
1685 
1686 	bucket = entry->lock_bucket;
1687 
1688 	if (lock) {
1689 		LOCK(&adb->entrylocks[bucket]);
1690 	}
1691 
1692 	entry->refcnt++;
1693 
1694 	if (lock) {
1695 		UNLOCK(&adb->entrylocks[bucket]);
1696 	}
1697 }
1698 
1699 static inline bool
1700 dec_entry_refcnt(dns_adb_t *adb, bool overmem, dns_adbentry_t *entry,
1701 		 bool lock) {
1702 	int bucket;
1703 	bool destroy_entry;
1704 	bool result = false;
1705 
1706 	bucket = entry->lock_bucket;
1707 
1708 	if (lock) {
1709 		LOCK(&adb->entrylocks[bucket]);
1710 	}
1711 
1712 	INSIST(entry->refcnt > 0);
1713 	entry->refcnt--;
1714 
1715 	destroy_entry = false;
1716 	if (entry->refcnt == 0 &&
1717 	    (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
1718 	     (entry->flags & ENTRY_IS_DEAD) != 0))
1719 	{
1720 		destroy_entry = true;
1721 		result = unlink_entry(adb, entry);
1722 	}
1723 
1724 	if (lock) {
1725 		UNLOCK(&adb->entrylocks[bucket]);
1726 	}
1727 
1728 	if (!destroy_entry) {
1729 		return (result);
1730 	}
1731 
1732 	entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
1733 
1734 	free_adbentry(adb, &entry);
1735 	if (result) {
1736 		result = dec_adb_irefcnt(adb);
1737 	}
1738 
1739 	return (result);
1740 }
1741 
1742 static inline dns_adbname_t *
1743 new_adbname(dns_adb_t *adb, const dns_name_t *dnsname) {
1744 	dns_adbname_t *name;
1745 
1746 	name = isc_mempool_get(adb->nmp);
1747 	if (name == NULL) {
1748 		return (NULL);
1749 	}
1750 
1751 	dns_name_init(&name->name, NULL);
1752 	dns_name_dup(dnsname, adb->mctx, &name->name);
1753 	dns_name_init(&name->target, NULL);
1754 	name->magic = DNS_ADBNAME_MAGIC;
1755 	name->adb = adb;
1756 	name->partial_result = 0;
1757 	name->flags = 0;
1758 	name->expire_v4 = INT_MAX;
1759 	name->expire_v6 = INT_MAX;
1760 	name->expire_target = INT_MAX;
1761 	name->chains = 0;
1762 	name->lock_bucket = DNS_ADB_INVALIDBUCKET;
1763 	ISC_LIST_INIT(name->v4);
1764 	ISC_LIST_INIT(name->v6);
1765 	name->fetch_a = NULL;
1766 	name->fetch_aaaa = NULL;
1767 	name->fetch_err = FIND_ERR_UNEXPECTED;
1768 	name->fetch6_err = FIND_ERR_UNEXPECTED;
1769 	ISC_LIST_INIT(name->finds);
1770 	ISC_LINK_INIT(name, plink);
1771 
1772 	LOCK(&adb->namescntlock);
1773 	adb->namescnt++;
1774 	inc_adbstats(adb, dns_adbstats_namescnt);
1775 	if (!adb->grownames_sent && adb->excl != NULL &&
1776 	    adb->namescnt > (adb->nnames * 8))
1777 	{
1778 		isc_event_t *event = &adb->grownames;
1779 		inc_adb_irefcnt(adb);
1780 		isc_task_send(adb->excl, &event);
1781 		adb->grownames_sent = true;
1782 	}
1783 	UNLOCK(&adb->namescntlock);
1784 
1785 	return (name);
1786 }
1787 
1788 static inline void
1789 free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
1790 	dns_adbname_t *n;
1791 
1792 	INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
1793 	n = *name;
1794 	*name = NULL;
1795 
1796 	INSIST(!NAME_HAS_V4(n));
1797 	INSIST(!NAME_HAS_V6(n));
1798 	INSIST(!NAME_FETCH(n));
1799 	INSIST(ISC_LIST_EMPTY(n->finds));
1800 	INSIST(!ISC_LINK_LINKED(n, plink));
1801 	INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
1802 	INSIST(n->adb == adb);
1803 
1804 	n->magic = 0;
1805 	dns_name_free(&n->name, adb->mctx);
1806 
1807 	isc_mempool_put(adb->nmp, n);
1808 	LOCK(&adb->namescntlock);
1809 	adb->namescnt--;
1810 	dec_adbstats(adb, dns_adbstats_namescnt);
1811 	UNLOCK(&adb->namescntlock);
1812 }
1813 
1814 static inline dns_adbnamehook_t *
1815 new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
1816 	dns_adbnamehook_t *nh;
1817 
1818 	nh = isc_mempool_get(adb->nhmp);
1819 	if (nh == NULL) {
1820 		return (NULL);
1821 	}
1822 
1823 	nh->magic = DNS_ADBNAMEHOOK_MAGIC;
1824 	nh->entry = entry;
1825 	ISC_LINK_INIT(nh, plink);
1826 
1827 	return (nh);
1828 }
1829 
1830 static inline void
1831 free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
1832 	dns_adbnamehook_t *nh;
1833 
1834 	INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
1835 	nh = *namehook;
1836 	*namehook = NULL;
1837 
1838 	INSIST(nh->entry == NULL);
1839 	INSIST(!ISC_LINK_LINKED(nh, plink));
1840 
1841 	nh->magic = 0;
1842 	isc_mempool_put(adb->nhmp, nh);
1843 }
1844 
1845 static inline dns_adblameinfo_t *
1846 new_adblameinfo(dns_adb_t *adb, const dns_name_t *qname,
1847 		dns_rdatatype_t qtype) {
1848 	dns_adblameinfo_t *li;
1849 
1850 	li = isc_mempool_get(adb->limp);
1851 	if (li == NULL) {
1852 		return (NULL);
1853 	}
1854 
1855 	dns_name_init(&li->qname, NULL);
1856 	dns_name_dup(qname, adb->mctx, &li->qname);
1857 	li->magic = DNS_ADBLAMEINFO_MAGIC;
1858 	li->lame_timer = 0;
1859 	li->qtype = qtype;
1860 	ISC_LINK_INIT(li, plink);
1861 
1862 	return (li);
1863 }
1864 
1865 static inline void
1866 free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
1867 	dns_adblameinfo_t *li;
1868 
1869 	INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
1870 	li = *lameinfo;
1871 	*lameinfo = NULL;
1872 
1873 	INSIST(!ISC_LINK_LINKED(li, plink));
1874 
1875 	dns_name_free(&li->qname, adb->mctx);
1876 
1877 	li->magic = 0;
1878 
1879 	isc_mempool_put(adb->limp, li);
1880 }
1881 
1882 static inline dns_adbentry_t *
1883 new_adbentry(dns_adb_t *adb) {
1884 	dns_adbentry_t *e;
1885 
1886 	e = isc_mempool_get(adb->emp);
1887 	if (e == NULL) {
1888 		return (NULL);
1889 	}
1890 
1891 	e->magic = DNS_ADBENTRY_MAGIC;
1892 	e->lock_bucket = DNS_ADB_INVALIDBUCKET;
1893 	e->refcnt = 0;
1894 	e->nh = 0;
1895 	e->flags = 0;
1896 	e->udpsize = 0;
1897 	e->edns = 0;
1898 	e->completed = 0;
1899 	e->timeouts = 0;
1900 	e->plain = 0;
1901 	e->plainto = 0;
1902 	e->to4096 = 0;
1903 	e->to1432 = 0;
1904 	e->to1232 = 0;
1905 	e->to512 = 0;
1906 	e->cookie = NULL;
1907 	e->cookielen = 0;
1908 	e->srtt = (isc_random_uniform(0x1f)) + 1;
1909 	e->lastage = 0;
1910 	e->expires = 0;
1911 	atomic_init(&e->active, 0);
1912 	e->mode = 0;
1913 	atomic_init(&e->quota, adb->quota);
1914 	e->atr = 0.0;
1915 	ISC_LIST_INIT(e->lameinfo);
1916 	ISC_LINK_INIT(e, plink);
1917 	LOCK(&adb->entriescntlock);
1918 	adb->entriescnt++;
1919 	inc_adbstats(adb, dns_adbstats_entriescnt);
1920 	if (!adb->growentries_sent && adb->excl != NULL &&
1921 	    adb->entriescnt > (adb->nentries * 8))
1922 	{
1923 		isc_event_t *event = &adb->growentries;
1924 		inc_adb_irefcnt(adb);
1925 		isc_task_send(adb->excl, &event);
1926 		adb->growentries_sent = true;
1927 	}
1928 	UNLOCK(&adb->entriescntlock);
1929 
1930 	return (e);
1931 }
1932 
1933 static inline void
1934 free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
1935 	dns_adbentry_t *e;
1936 	dns_adblameinfo_t *li;
1937 
1938 	INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
1939 	e = *entry;
1940 	*entry = NULL;
1941 
1942 	INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);
1943 	INSIST(e->refcnt == 0);
1944 	INSIST(!ISC_LINK_LINKED(e, plink));
1945 
1946 	e->magic = 0;
1947 
1948 	if (e->cookie != NULL) {
1949 		isc_mem_put(adb->mctx, e->cookie, e->cookielen);
1950 	}
1951 
1952 	li = ISC_LIST_HEAD(e->lameinfo);
1953 	while (li != NULL) {
1954 		ISC_LIST_UNLINK(e->lameinfo, li, plink);
1955 		free_adblameinfo(adb, &li);
1956 		li = ISC_LIST_HEAD(e->lameinfo);
1957 	}
1958 
1959 	isc_mempool_put(adb->emp, e);
1960 	LOCK(&adb->entriescntlock);
1961 	adb->entriescnt--;
1962 	dec_adbstats(adb, dns_adbstats_entriescnt);
1963 	UNLOCK(&adb->entriescntlock);
1964 }
1965 
1966 static inline dns_adbfind_t *
1967 new_adbfind(dns_adb_t *adb) {
1968 	dns_adbfind_t *h;
1969 
1970 	h = isc_mempool_get(adb->ahmp);
1971 	if (h == NULL) {
1972 		return (NULL);
1973 	}
1974 
1975 	/*
1976 	 * Public members.
1977 	 */
1978 	h->magic = 0;
1979 	h->adb = adb;
1980 	h->partial_result = 0;
1981 	h->options = 0;
1982 	h->flags = 0;
1983 	h->result_v4 = ISC_R_UNEXPECTED;
1984 	h->result_v6 = ISC_R_UNEXPECTED;
1985 	ISC_LINK_INIT(h, publink);
1986 	ISC_LINK_INIT(h, plink);
1987 	ISC_LIST_INIT(h->list);
1988 	h->adbname = NULL;
1989 	h->name_bucket = DNS_ADB_INVALIDBUCKET;
1990 
1991 	/*
1992 	 * private members
1993 	 */
1994 	isc_mutex_init(&h->lock);
1995 
1996 	ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
1997 		       NULL, NULL, h);
1998 
1999 	inc_adb_irefcnt(adb);
2000 	h->magic = DNS_ADBFIND_MAGIC;
2001 	return (h);
2002 }
2003 
2004 static inline dns_adbfetch_t *
2005 new_adbfetch(dns_adb_t *adb) {
2006 	dns_adbfetch_t *f;
2007 
2008 	f = isc_mempool_get(adb->afmp);
2009 	if (f == NULL) {
2010 		return (NULL);
2011 	}
2012 
2013 	f->magic = 0;
2014 	f->fetch = NULL;
2015 
2016 	dns_rdataset_init(&f->rdataset);
2017 
2018 	f->magic = DNS_ADBFETCH_MAGIC;
2019 
2020 	return (f);
2021 }
2022 
2023 static inline void
2024 free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
2025 	dns_adbfetch_t *f;
2026 
2027 	INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
2028 	f = *fetch;
2029 	*fetch = NULL;
2030 
2031 	f->magic = 0;
2032 
2033 	if (dns_rdataset_isassociated(&f->rdataset)) {
2034 		dns_rdataset_disassociate(&f->rdataset);
2035 	}
2036 
2037 	isc_mempool_put(adb->afmp, f);
2038 }
2039 
2040 static inline bool
2041 free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
2042 	dns_adbfind_t *find;
2043 
2044 	INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
2045 	find = *findp;
2046 	*findp = NULL;
2047 
2048 	INSIST(!FIND_HAS_ADDRS(find));
2049 	INSIST(!ISC_LINK_LINKED(find, publink));
2050 	INSIST(!ISC_LINK_LINKED(find, plink));
2051 	INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
2052 	INSIST(find->adbname == NULL);
2053 
2054 	find->magic = 0;
2055 
2056 	isc_mutex_destroy(&find->lock);
2057 	isc_mempool_put(adb->ahmp, find);
2058 	return (dec_adb_irefcnt(adb));
2059 }
2060 
2061 /*
2062  * Copy bits from the entry into the newly allocated addrinfo.  The entry
2063  * must be locked, and the reference count must be bumped up by one
2064  * if this function returns a valid pointer.
2065  */
2066 static inline dns_adbaddrinfo_t *
2067 new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
2068 	dns_adbaddrinfo_t *ai;
2069 
2070 	ai = isc_mempool_get(adb->aimp);
2071 	if (ai == NULL) {
2072 		return (NULL);
2073 	}
2074 
2075 	ai->magic = DNS_ADBADDRINFO_MAGIC;
2076 	ai->sockaddr = entry->sockaddr;
2077 	isc_sockaddr_setport(&ai->sockaddr, port);
2078 	ai->srtt = entry->srtt;
2079 	ai->flags = entry->flags;
2080 	ai->entry = entry;
2081 	ai->dscp = -1;
2082 	ISC_LINK_INIT(ai, publink);
2083 
2084 	return (ai);
2085 }
2086 
2087 static inline void
2088 free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
2089 	dns_adbaddrinfo_t *ai;
2090 
2091 	INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
2092 	ai = *ainfo;
2093 	*ainfo = NULL;
2094 
2095 	INSIST(ai->entry == NULL);
2096 	INSIST(!ISC_LINK_LINKED(ai, publink));
2097 
2098 	ai->magic = 0;
2099 
2100 	isc_mempool_put(adb->aimp, ai);
2101 }
2102 
2103 /*
2104  * Search for the name.  NOTE:  The bucket is kept locked on both
2105  * success and failure, so it must always be unlocked by the caller!
2106  *
2107  * On the first call to this function, *bucketp must be set to
2108  * DNS_ADB_INVALIDBUCKET.
2109  */
2110 static inline dns_adbname_t *
2111 find_name_and_lock(dns_adb_t *adb, const dns_name_t *name, unsigned int options,
2112 		   int *bucketp) {
2113 	dns_adbname_t *adbname;
2114 	int bucket;
2115 
2116 	bucket = dns_name_fullhash(name, false) % adb->nnames;
2117 
2118 	if (*bucketp == DNS_ADB_INVALIDBUCKET) {
2119 		LOCK(&adb->namelocks[bucket]);
2120 		*bucketp = bucket;
2121 	} else if (*bucketp != bucket) {
2122 		UNLOCK(&adb->namelocks[*bucketp]);
2123 		LOCK(&adb->namelocks[bucket]);
2124 		*bucketp = bucket;
2125 	}
2126 
2127 	adbname = ISC_LIST_HEAD(adb->names[bucket]);
2128 	while (adbname != NULL) {
2129 		if (!NAME_DEAD(adbname)) {
2130 			if (dns_name_equal(name, &adbname->name) &&
2131 			    GLUEHINT_OK(adbname, options) &&
2132 			    STARTATZONE_MATCHES(adbname, options))
2133 			{
2134 				return (adbname);
2135 			}
2136 		}
2137 		adbname = ISC_LIST_NEXT(adbname, plink);
2138 	}
2139 
2140 	return (NULL);
2141 }
2142 
2143 /*
2144  * Search for the address.  NOTE:  The bucket is kept locked on both
2145  * success and failure, so it must always be unlocked by the caller.
2146  *
2147  * On the first call to this function, *bucketp must be set to
2148  * DNS_ADB_INVALIDBUCKET.  This will cause a lock to occur.  On
2149  * later calls (within the same "lock path") it can be left alone, so
2150  * if this function is called multiple times locking is only done if
2151  * the bucket changes.
2152  */
2153 static inline dns_adbentry_t *
2154 find_entry_and_lock(dns_adb_t *adb, const isc_sockaddr_t *addr, int *bucketp,
2155 		    isc_stdtime_t now) {
2156 	dns_adbentry_t *entry, *entry_next;
2157 	int bucket;
2158 
2159 	bucket = isc_sockaddr_hash(addr, true) % adb->nentries;
2160 
2161 	if (*bucketp == DNS_ADB_INVALIDBUCKET) {
2162 		LOCK(&adb->entrylocks[bucket]);
2163 		*bucketp = bucket;
2164 	} else if (*bucketp != bucket) {
2165 		UNLOCK(&adb->entrylocks[*bucketp]);
2166 		LOCK(&adb->entrylocks[bucket]);
2167 		*bucketp = bucket;
2168 	}
2169 
2170 	/* Search the list, while cleaning up expired entries. */
2171 	for (entry = ISC_LIST_HEAD(adb->entries[bucket]); entry != NULL;
2172 	     entry = entry_next)
2173 	{
2174 		entry_next = ISC_LIST_NEXT(entry, plink);
2175 		(void)check_expire_entry(adb, &entry, now);
2176 		if (entry != NULL &&
2177 		    (entry->expires == 0 || entry->expires > now) &&
2178 		    isc_sockaddr_equal(addr, &entry->sockaddr))
2179 		{
2180 			ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
2181 			ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
2182 			return (entry);
2183 		}
2184 	}
2185 
2186 	return (NULL);
2187 }
2188 
2189 /*
2190  * Entry bucket MUST be locked!
2191  */
2192 static bool
2193 entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, const dns_name_t *qname,
2194 	      dns_rdatatype_t qtype, isc_stdtime_t now) {
2195 	dns_adblameinfo_t *li, *next_li;
2196 	bool is_bad;
2197 
2198 	is_bad = false;
2199 
2200 	li = ISC_LIST_HEAD(entry->lameinfo);
2201 	if (li == NULL) {
2202 		return (false);
2203 	}
2204 	while (li != NULL) {
2205 		next_li = ISC_LIST_NEXT(li, plink);
2206 
2207 		/*
2208 		 * Has the entry expired?
2209 		 */
2210 		if (li->lame_timer < now) {
2211 			ISC_LIST_UNLINK(entry->lameinfo, li, plink);
2212 			free_adblameinfo(adb, &li);
2213 		}
2214 
2215 		/*
2216 		 * Order tests from least to most expensive.
2217 		 *
2218 		 * We do not break out of the main loop here as
2219 		 * we use the loop for house keeping.
2220 		 */
2221 		if (li != NULL && !is_bad && li->qtype == qtype &&
2222 		    dns_name_equal(qname, &li->qname))
2223 		{
2224 			is_bad = true;
2225 		}
2226 
2227 		li = next_li;
2228 	}
2229 
2230 	return (is_bad);
2231 }
2232 
2233 static void
2234 log_quota(dns_adbentry_t *entry, const char *fmt, ...) {
2235 	va_list ap;
2236 	char msgbuf[2048];
2237 	char addrbuf[ISC_NETADDR_FORMATSIZE];
2238 	isc_netaddr_t netaddr;
2239 
2240 	va_start(ap, fmt);
2241 	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
2242 	va_end(ap);
2243 
2244 	isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
2245 	isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
2246 
2247 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
2248 		      ISC_LOG_INFO,
2249 		      "adb: quota %s (%" PRIuFAST32 "/%" PRIuFAST32 "): %s",
2250 		      addrbuf, atomic_load_relaxed(&entry->active),
2251 		      atomic_load_relaxed(&entry->quota), msgbuf);
2252 }
2253 
2254 static void
2255 copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find,
2256 		    const dns_name_t *qname, dns_rdatatype_t qtype,
2257 		    dns_adbname_t *name, isc_stdtime_t now) {
2258 	dns_adbnamehook_t *namehook;
2259 	dns_adbaddrinfo_t *addrinfo;
2260 	dns_adbentry_t *entry;
2261 	int bucket;
2262 
2263 	bucket = DNS_ADB_INVALIDBUCKET;
2264 
2265 	if ((find->options & DNS_ADBFIND_INET) != 0) {
2266 		namehook = ISC_LIST_HEAD(name->v4);
2267 		while (namehook != NULL) {
2268 			entry = namehook->entry;
2269 			bucket = entry->lock_bucket;
2270 			INSIST(bucket != DNS_ADB_INVALIDBUCKET);
2271 			LOCK(&adb->entrylocks[bucket]);
2272 
2273 			if (dns_adbentry_overquota(entry)) {
2274 				find->options |= (DNS_ADBFIND_LAMEPRUNED |
2275 						  DNS_ADBFIND_OVERQUOTA);
2276 				goto nextv4;
2277 			}
2278 
2279 			if (!FIND_RETURNLAME(find) &&
2280 			    entry_is_lame(adb, entry, qname, qtype, now)) {
2281 				find->options |= DNS_ADBFIND_LAMEPRUNED;
2282 				goto nextv4;
2283 			}
2284 			addrinfo = new_adbaddrinfo(adb, entry, find->port);
2285 			if (addrinfo == NULL) {
2286 				find->partial_result |= DNS_ADBFIND_INET;
2287 				goto out;
2288 			}
2289 			/*
2290 			 * Found a valid entry.  Add it to the find's list.
2291 			 */
2292 			inc_entry_refcnt(adb, entry, false);
2293 			ISC_LIST_APPEND(find->list, addrinfo, publink);
2294 			addrinfo = NULL;
2295 		nextv4:
2296 			UNLOCK(&adb->entrylocks[bucket]);
2297 			bucket = DNS_ADB_INVALIDBUCKET;
2298 			namehook = ISC_LIST_NEXT(namehook, plink);
2299 		}
2300 	}
2301 
2302 	if ((find->options & DNS_ADBFIND_INET6) != 0) {
2303 		namehook = ISC_LIST_HEAD(name->v6);
2304 		while (namehook != NULL) {
2305 			entry = namehook->entry;
2306 			bucket = entry->lock_bucket;
2307 			INSIST(bucket != DNS_ADB_INVALIDBUCKET);
2308 			LOCK(&adb->entrylocks[bucket]);
2309 
2310 			if (dns_adbentry_overquota(entry)) {
2311 				find->options |= (DNS_ADBFIND_LAMEPRUNED |
2312 						  DNS_ADBFIND_OVERQUOTA);
2313 				goto nextv6;
2314 			}
2315 
2316 			if (!FIND_RETURNLAME(find) &&
2317 			    entry_is_lame(adb, entry, qname, qtype, now)) {
2318 				find->options |= DNS_ADBFIND_LAMEPRUNED;
2319 				goto nextv6;
2320 			}
2321 			addrinfo = new_adbaddrinfo(adb, entry, find->port);
2322 			if (addrinfo == NULL) {
2323 				find->partial_result |= DNS_ADBFIND_INET6;
2324 				goto out;
2325 			}
2326 			/*
2327 			 * Found a valid entry.  Add it to the find's list.
2328 			 */
2329 			inc_entry_refcnt(adb, entry, false);
2330 			ISC_LIST_APPEND(find->list, addrinfo, publink);
2331 			addrinfo = NULL;
2332 		nextv6:
2333 			UNLOCK(&adb->entrylocks[bucket]);
2334 			bucket = DNS_ADB_INVALIDBUCKET;
2335 			namehook = ISC_LIST_NEXT(namehook, plink);
2336 		}
2337 	}
2338 
2339 out:
2340 	if (bucket != DNS_ADB_INVALIDBUCKET) {
2341 		UNLOCK(&adb->entrylocks[bucket]);
2342 	}
2343 }
2344 
2345 static void
2346 shutdown_task(isc_task_t *task, isc_event_t *ev) {
2347 	dns_adb_t *adb;
2348 
2349 	UNUSED(task);
2350 
2351 	adb = ev->ev_arg;
2352 	INSIST(DNS_ADB_VALID(adb));
2353 
2354 	isc_event_free(&ev);
2355 	/*
2356 	 * Wait for lock around check_exit() call to be released.
2357 	 */
2358 	LOCK(&adb->lock);
2359 	UNLOCK(&adb->lock);
2360 	destroy(adb);
2361 }
2362 
2363 /*
2364  * Name bucket must be locked; adb may be locked; no other locks held.
2365  */
2366 static bool
2367 check_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
2368 	dns_adbname_t *name;
2369 	bool result = false;
2370 
2371 	INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
2372 	name = *namep;
2373 
2374 	if (NAME_HAS_V4(name) || NAME_HAS_V6(name)) {
2375 		return (result);
2376 	}
2377 	if (NAME_FETCH(name)) {
2378 		return (result);
2379 	}
2380 	if (!EXPIRE_OK(name->expire_v4, now)) {
2381 		return (result);
2382 	}
2383 	if (!EXPIRE_OK(name->expire_v6, now)) {
2384 		return (result);
2385 	}
2386 	if (!EXPIRE_OK(name->expire_target, now)) {
2387 		return (result);
2388 	}
2389 
2390 	/*
2391 	 * The name is empty.  Delete it.
2392 	 */
2393 	*namep = NULL;
2394 	result = kill_name(&name, DNS_EVENT_ADBEXPIRED);
2395 
2396 	/*
2397 	 * Our caller, or one of its callers, will be calling check_exit() at
2398 	 * some point, so we don't need to do it here.
2399 	 */
2400 	return (result);
2401 }
2402 
2403 /*%
2404  * Examine the tail entry of the LRU list to see if it expires or is stale
2405  * (unused for some period); if so, the name entry will be freed.  If the ADB
2406  * is in the overmem condition, the tail and the next to tail entries
2407  * will be unconditionally removed (unless they have an outstanding fetch).
2408  * We don't care about a race on 'overmem' at the risk of causing some
2409  * collateral damage or a small delay in starting cleanup, so we don't bother
2410  * to lock ADB (if it's not locked).
2411  *
2412  * Name bucket must be locked; adb may be locked; no other locks held.
2413  */
2414 static void
2415 check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2416 	int victims, max_victims;
2417 	dns_adbname_t *victim, *next_victim;
2418 	bool overmem = isc_mem_isovermem(adb->mctx);
2419 	int scans = 0;
2420 
2421 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
2422 
2423 	max_victims = overmem ? 2 : 1;
2424 
2425 	/*
2426 	 * We limit the number of scanned entries to 10 (arbitrary choice)
2427 	 * in order to avoid examining too many entries when there are many
2428 	 * tail entries that have fetches (this should be rare, but could
2429 	 * happen).
2430 	 */
2431 	victim = ISC_LIST_TAIL(adb->names[bucket]);
2432 	for (victims = 0; victim != NULL && victims < max_victims && scans < 10;
2433 	     victim = next_victim)
2434 	{
2435 		INSIST(!NAME_DEAD(victim));
2436 		scans++;
2437 		next_victim = ISC_LIST_PREV(victim, plink);
2438 		(void)check_expire_name(&victim, now);
2439 		if (victim == NULL) {
2440 			victims++;
2441 			goto next;
2442 		}
2443 
2444 		if (!NAME_FETCH(victim) &&
2445 		    (overmem || victim->last_used + ADB_STALE_MARGIN <= now))
2446 		{
2447 			RUNTIME_CHECK(
2448 				!kill_name(&victim, DNS_EVENT_ADBCANCELED));
2449 			victims++;
2450 		}
2451 
2452 	next:
2453 		if (!overmem) {
2454 			break;
2455 		}
2456 	}
2457 }
2458 
2459 /*
2460  * Entry bucket must be locked; adb may be locked; no other locks held.
2461  */
2462 static bool
2463 check_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now) {
2464 	dns_adbentry_t *entry;
2465 	bool result = false;
2466 
2467 	INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
2468 	entry = *entryp;
2469 
2470 	if (entry->refcnt != 0) {
2471 		return (result);
2472 	}
2473 
2474 	if (entry->expires == 0 || entry->expires > now) {
2475 		return (result);
2476 	}
2477 
2478 	/*
2479 	 * The entry is not in use.  Delete it.
2480 	 */
2481 	*entryp = NULL;
2482 	DP(DEF_LEVEL, "killing entry %p", entry);
2483 	INSIST(ISC_LINK_LINKED(entry, plink));
2484 	result = unlink_entry(adb, entry);
2485 	free_adbentry(adb, &entry);
2486 	if (result) {
2487 		dec_adb_irefcnt(adb);
2488 	}
2489 	return (result);
2490 }
2491 
2492 /*
2493  * ADB must be locked, and no other locks held.
2494  */
2495 static bool
2496 cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2497 	dns_adbname_t *name;
2498 	dns_adbname_t *next_name;
2499 	bool result = false;
2500 
2501 	DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket);
2502 
2503 	LOCK(&adb->namelocks[bucket]);
2504 	if (adb->name_sd[bucket]) {
2505 		UNLOCK(&adb->namelocks[bucket]);
2506 		return (result);
2507 	}
2508 
2509 	name = ISC_LIST_HEAD(adb->names[bucket]);
2510 	while (name != NULL) {
2511 		next_name = ISC_LIST_NEXT(name, plink);
2512 		INSIST(!result);
2513 		result = check_expire_namehooks(name, now);
2514 		if (!result) {
2515 			result = check_expire_name(&name, now);
2516 		}
2517 		name = next_name;
2518 	}
2519 	UNLOCK(&adb->namelocks[bucket]);
2520 	return (result);
2521 }
2522 
2523 /*
2524  * ADB must be locked, and no other locks held.
2525  */
2526 static bool
2527 cleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2528 	dns_adbentry_t *entry, *next_entry;
2529 	bool result = false;
2530 
2531 	DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket);
2532 
2533 	LOCK(&adb->entrylocks[bucket]);
2534 	entry = ISC_LIST_HEAD(adb->entries[bucket]);
2535 	while (entry != NULL) {
2536 		next_entry = ISC_LIST_NEXT(entry, plink);
2537 		INSIST(!result);
2538 		result = check_expire_entry(adb, &entry, now);
2539 		entry = next_entry;
2540 	}
2541 	UNLOCK(&adb->entrylocks[bucket]);
2542 	return (result);
2543 }
2544 
2545 static void
2546 destroy(dns_adb_t *adb) {
2547 	adb->magic = 0;
2548 
2549 	isc_task_detach(&adb->task);
2550 	if (adb->excl != NULL) {
2551 		isc_task_detach(&adb->excl);
2552 	}
2553 
2554 	isc_mempool_destroy(&adb->nmp);
2555 	isc_mempool_destroy(&adb->nhmp);
2556 	isc_mempool_destroy(&adb->limp);
2557 	isc_mempool_destroy(&adb->emp);
2558 	isc_mempool_destroy(&adb->ahmp);
2559 	isc_mempool_destroy(&adb->aimp);
2560 	isc_mempool_destroy(&adb->afmp);
2561 
2562 	isc_mutexblock_destroy(adb->entrylocks, adb->nentries);
2563 	isc_mem_put(adb->mctx, adb->entries,
2564 		    sizeof(*adb->entries) * adb->nentries);
2565 	isc_mem_put(adb->mctx, adb->deadentries,
2566 		    sizeof(*adb->deadentries) * adb->nentries);
2567 	isc_mem_put(adb->mctx, adb->entrylocks,
2568 		    sizeof(*adb->entrylocks) * adb->nentries);
2569 	isc_mem_put(adb->mctx, adb->entry_sd,
2570 		    sizeof(*adb->entry_sd) * adb->nentries);
2571 	isc_mem_put(adb->mctx, adb->entry_refcnt,
2572 		    sizeof(*adb->entry_refcnt) * adb->nentries);
2573 
2574 	isc_mutexblock_destroy(adb->namelocks, adb->nnames);
2575 	isc_mem_put(adb->mctx, adb->names, sizeof(*adb->names) * adb->nnames);
2576 	isc_mem_put(adb->mctx, adb->deadnames,
2577 		    sizeof(*adb->deadnames) * adb->nnames);
2578 	isc_mem_put(adb->mctx, adb->namelocks,
2579 		    sizeof(*adb->namelocks) * adb->nnames);
2580 	isc_mem_put(adb->mctx, adb->name_sd,
2581 		    sizeof(*adb->name_sd) * adb->nnames);
2582 	isc_mem_put(adb->mctx, adb->name_refcnt,
2583 		    sizeof(*adb->name_refcnt) * adb->nnames);
2584 
2585 	isc_mutex_destroy(&adb->reflock);
2586 	isc_mutex_destroy(&adb->lock);
2587 	isc_mutex_destroy(&adb->mplock);
2588 	isc_mutex_destroy(&adb->overmemlock);
2589 	isc_mutex_destroy(&adb->entriescntlock);
2590 	isc_mutex_destroy(&adb->namescntlock);
2591 
2592 	isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
2593 }
2594 
2595 /*
2596  * Public functions.
2597  */
2598 
2599 isc_result_t
2600 dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
2601 	       isc_taskmgr_t *taskmgr, dns_adb_t **newadb) {
2602 	dns_adb_t *adb;
2603 	isc_result_t result;
2604 	unsigned int i;
2605 
2606 	REQUIRE(mem != NULL);
2607 	REQUIRE(view != NULL);
2608 	REQUIRE(timermgr != NULL); /* this is actually unused */
2609 	REQUIRE(taskmgr != NULL);
2610 	REQUIRE(newadb != NULL && *newadb == NULL);
2611 
2612 	UNUSED(timermgr);
2613 
2614 	adb = isc_mem_get(mem, sizeof(dns_adb_t));
2615 
2616 	/*
2617 	 * Initialize things here that cannot fail, and especially things
2618 	 * that must be NULL for the error return to work properly.
2619 	 */
2620 	adb->magic = 0;
2621 	adb->erefcnt = 1;
2622 	adb->irefcnt = 0;
2623 	adb->nmp = NULL;
2624 	adb->nhmp = NULL;
2625 	adb->limp = NULL;
2626 	adb->emp = NULL;
2627 	adb->ahmp = NULL;
2628 	adb->aimp = NULL;
2629 	adb->afmp = NULL;
2630 	adb->task = NULL;
2631 	adb->excl = NULL;
2632 	adb->mctx = NULL;
2633 	adb->view = view;
2634 	adb->taskmgr = taskmgr;
2635 	adb->next_cleanbucket = 0;
2636 	ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL, 0, NULL,
2637 		       NULL, NULL, NULL, NULL);
2638 	adb->cevent_out = false;
2639 	adb->shutting_down = false;
2640 	ISC_LIST_INIT(adb->whenshutdown);
2641 
2642 	adb->nentries = nbuckets[0];
2643 	adb->entriescnt = 0;
2644 	adb->entries = NULL;
2645 	adb->deadentries = NULL;
2646 	adb->entry_sd = NULL;
2647 	adb->entry_refcnt = NULL;
2648 	adb->entrylocks = NULL;
2649 	ISC_EVENT_INIT(&adb->growentries, sizeof(adb->growentries), 0, NULL,
2650 		       DNS_EVENT_ADBGROWENTRIES, grow_entries, adb, adb, NULL,
2651 		       NULL);
2652 	adb->growentries_sent = false;
2653 
2654 	adb->quota = 0;
2655 	adb->atr_freq = 0;
2656 	adb->atr_low = 0.0;
2657 	adb->atr_high = 0.0;
2658 	adb->atr_discount = 0.0;
2659 
2660 	adb->nnames = nbuckets[0];
2661 	adb->namescnt = 0;
2662 	adb->names = NULL;
2663 	adb->deadnames = NULL;
2664 	adb->name_sd = NULL;
2665 	adb->name_refcnt = NULL;
2666 	adb->namelocks = NULL;
2667 	ISC_EVENT_INIT(&adb->grownames, sizeof(adb->grownames), 0, NULL,
2668 		       DNS_EVENT_ADBGROWNAMES, grow_names, adb, adb, NULL,
2669 		       NULL);
2670 	adb->grownames_sent = false;
2671 
2672 	result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl);
2673 	if (result != ISC_R_SUCCESS) {
2674 		DP(DEF_LEVEL,
2675 		   "adb: task-exclusive mode unavailable, "
2676 		   "initializing table sizes to %u\n",
2677 		   nbuckets[11]);
2678 		adb->nentries = nbuckets[11];
2679 		adb->nnames = nbuckets[11];
2680 	}
2681 
2682 	isc_mem_attach(mem, &adb->mctx);
2683 
2684 	isc_mutex_init(&adb->lock);
2685 	isc_mutex_init(&adb->mplock);
2686 	isc_mutex_init(&adb->reflock);
2687 	isc_mutex_init(&adb->overmemlock);
2688 	isc_mutex_init(&adb->entriescntlock);
2689 	isc_mutex_init(&adb->namescntlock);
2690 
2691 #define ALLOCENTRY(adb, el)                                                    \
2692 	do {                                                                   \
2693 		(adb)->el = isc_mem_get((adb)->mctx,                           \
2694 					sizeof(*(adb)->el) * (adb)->nentries); \
2695 		if ((adb)->el == NULL) {                                       \
2696 			result = ISC_R_NOMEMORY;                               \
2697 			goto fail1;                                            \
2698 		}                                                              \
2699 	} while (0)
2700 	ALLOCENTRY(adb, entries);
2701 	ALLOCENTRY(adb, deadentries);
2702 	ALLOCENTRY(adb, entrylocks);
2703 	ALLOCENTRY(adb, entry_sd);
2704 	ALLOCENTRY(adb, entry_refcnt);
2705 #undef ALLOCENTRY
2706 
2707 #define ALLOCNAME(adb, el)                                                   \
2708 	do {                                                                 \
2709 		(adb)->el = isc_mem_get((adb)->mctx,                         \
2710 					sizeof(*(adb)->el) * (adb)->nnames); \
2711 		if ((adb)->el == NULL) {                                     \
2712 			result = ISC_R_NOMEMORY;                             \
2713 			goto fail1;                                          \
2714 		}                                                            \
2715 	} while (0)
2716 	ALLOCNAME(adb, names);
2717 	ALLOCNAME(adb, deadnames);
2718 	ALLOCNAME(adb, namelocks);
2719 	ALLOCNAME(adb, name_sd);
2720 	ALLOCNAME(adb, name_refcnt);
2721 #undef ALLOCNAME
2722 
2723 	/*
2724 	 * Initialize the bucket locks for names and elements.
2725 	 * May as well initialize the list heads, too.
2726 	 */
2727 	isc_mutexblock_init(adb->namelocks, adb->nnames);
2728 
2729 	for (i = 0; i < adb->nnames; i++) {
2730 		ISC_LIST_INIT(adb->names[i]);
2731 		ISC_LIST_INIT(adb->deadnames[i]);
2732 		adb->name_sd[i] = false;
2733 		adb->name_refcnt[i] = 0;
2734 		adb->irefcnt++;
2735 	}
2736 	for (i = 0; i < adb->nentries; i++) {
2737 		ISC_LIST_INIT(adb->entries[i]);
2738 		ISC_LIST_INIT(adb->deadentries[i]);
2739 		adb->entry_sd[i] = false;
2740 		adb->entry_refcnt[i] = 0;
2741 		adb->irefcnt++;
2742 	}
2743 	isc_mutexblock_init(adb->entrylocks, adb->nentries);
2744 
2745 	/*
2746 	 * Memory pools
2747 	 */
2748 #define MPINIT(t, p, n)                                       \
2749 	do {                                                  \
2750 		isc_mempool_create(mem, sizeof(t), &(p));     \
2751 		isc_mempool_setfreemax((p), FREE_ITEMS);      \
2752 		isc_mempool_setfillcount((p), FILL_COUNT);    \
2753 		isc_mempool_setname((p), n);                  \
2754 		isc_mempool_associatelock((p), &adb->mplock); \
2755 	} while (0)
2756 
2757 	MPINIT(dns_adbname_t, adb->nmp, "adbname");
2758 	MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
2759 	MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo");
2760 	MPINIT(dns_adbentry_t, adb->emp, "adbentry");
2761 	MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
2762 	MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
2763 	MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
2764 
2765 #undef MPINIT
2766 
2767 	/*
2768 	 * Allocate an internal task.
2769 	 */
2770 	result = isc_task_create(adb->taskmgr, 0, &adb->task);
2771 	if (result != ISC_R_SUCCESS) {
2772 		goto fail2;
2773 	}
2774 
2775 	isc_task_setname(adb->task, "ADB", adb);
2776 
2777 	result = isc_stats_create(adb->mctx, &view->adbstats, dns_adbstats_max);
2778 	if (result != ISC_R_SUCCESS) {
2779 		goto fail2;
2780 	}
2781 
2782 	set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
2783 	set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
2784 
2785 	/*
2786 	 * Normal return.
2787 	 */
2788 	adb->magic = DNS_ADB_MAGIC;
2789 	*newadb = adb;
2790 	return (ISC_R_SUCCESS);
2791 
2792 fail2:
2793 	if (adb->task != NULL) {
2794 		isc_task_detach(&adb->task);
2795 	}
2796 
2797 	/* clean up entrylocks */
2798 	isc_mutexblock_destroy(adb->entrylocks, adb->nentries);
2799 	isc_mutexblock_destroy(adb->namelocks, adb->nnames);
2800 
2801 fail1: /* clean up only allocated memory */
2802 	if (adb->entries != NULL) {
2803 		isc_mem_put(adb->mctx, adb->entries,
2804 			    sizeof(*adb->entries) * adb->nentries);
2805 	}
2806 	if (adb->deadentries != NULL) {
2807 		isc_mem_put(adb->mctx, adb->deadentries,
2808 			    sizeof(*adb->deadentries) * adb->nentries);
2809 	}
2810 	if (adb->entrylocks != NULL) {
2811 		isc_mem_put(adb->mctx, adb->entrylocks,
2812 			    sizeof(*adb->entrylocks) * adb->nentries);
2813 	}
2814 	if (adb->entry_sd != NULL) {
2815 		isc_mem_put(adb->mctx, adb->entry_sd,
2816 			    sizeof(*adb->entry_sd) * adb->nentries);
2817 	}
2818 	if (adb->entry_refcnt != NULL) {
2819 		isc_mem_put(adb->mctx, adb->entry_refcnt,
2820 			    sizeof(*adb->entry_refcnt) * adb->nentries);
2821 	}
2822 	if (adb->names != NULL) {
2823 		isc_mem_put(adb->mctx, adb->names,
2824 			    sizeof(*adb->names) * adb->nnames);
2825 	}
2826 	if (adb->deadnames != NULL) {
2827 		isc_mem_put(adb->mctx, adb->deadnames,
2828 			    sizeof(*adb->deadnames) * adb->nnames);
2829 	}
2830 	if (adb->namelocks != NULL) {
2831 		isc_mem_put(adb->mctx, adb->namelocks,
2832 			    sizeof(*adb->namelocks) * adb->nnames);
2833 	}
2834 	if (adb->name_sd != NULL) {
2835 		isc_mem_put(adb->mctx, adb->name_sd,
2836 			    sizeof(*adb->name_sd) * adb->nnames);
2837 	}
2838 	if (adb->name_refcnt != NULL) {
2839 		isc_mem_put(adb->mctx, adb->name_refcnt,
2840 			    sizeof(*adb->name_refcnt) * adb->nnames);
2841 	}
2842 	if (adb->nmp != NULL) {
2843 		isc_mempool_destroy(&adb->nmp);
2844 	}
2845 	if (adb->nhmp != NULL) {
2846 		isc_mempool_destroy(&adb->nhmp);
2847 	}
2848 	if (adb->limp != NULL) {
2849 		isc_mempool_destroy(&adb->limp);
2850 	}
2851 	if (adb->emp != NULL) {
2852 		isc_mempool_destroy(&adb->emp);
2853 	}
2854 	if (adb->ahmp != NULL) {
2855 		isc_mempool_destroy(&adb->ahmp);
2856 	}
2857 	if (adb->aimp != NULL) {
2858 		isc_mempool_destroy(&adb->aimp);
2859 	}
2860 	if (adb->afmp != NULL) {
2861 		isc_mempool_destroy(&adb->afmp);
2862 	}
2863 
2864 	isc_mutex_destroy(&adb->namescntlock);
2865 	isc_mutex_destroy(&adb->entriescntlock);
2866 	isc_mutex_destroy(&adb->overmemlock);
2867 	isc_mutex_destroy(&adb->reflock);
2868 	isc_mutex_destroy(&adb->mplock);
2869 	isc_mutex_destroy(&adb->lock);
2870 	if (adb->excl != NULL) {
2871 		isc_task_detach(&adb->excl);
2872 	}
2873 	isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
2874 
2875 	return (result);
2876 }
2877 
2878 void
2879 dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) {
2880 	REQUIRE(DNS_ADB_VALID(adb));
2881 	REQUIRE(adbx != NULL && *adbx == NULL);
2882 
2883 	inc_adb_erefcnt(adb);
2884 	*adbx = adb;
2885 }
2886 
2887 void
2888 dns_adb_detach(dns_adb_t **adbx) {
2889 	dns_adb_t *adb;
2890 	bool need_exit_check;
2891 
2892 	REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx));
2893 
2894 	adb = *adbx;
2895 	*adbx = NULL;
2896 
2897 	LOCK(&adb->reflock);
2898 	INSIST(adb->erefcnt > 0);
2899 	adb->erefcnt--;
2900 	need_exit_check = (adb->erefcnt == 0 && adb->irefcnt == 0);
2901 	UNLOCK(&adb->reflock);
2902 
2903 	if (need_exit_check) {
2904 		LOCK(&adb->lock);
2905 		INSIST(adb->shutting_down);
2906 		check_exit(adb);
2907 		UNLOCK(&adb->lock);
2908 	}
2909 }
2910 
2911 void
2912 dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
2913 	isc_task_t *tclone;
2914 	isc_event_t *event;
2915 	bool zeroirefcnt;
2916 
2917 	/*
2918 	 * Send '*eventp' to 'task' when 'adb' has shutdown.
2919 	 */
2920 
2921 	REQUIRE(DNS_ADB_VALID(adb));
2922 	REQUIRE(eventp != NULL);
2923 
2924 	event = *eventp;
2925 	*eventp = NULL;
2926 
2927 	LOCK(&adb->lock);
2928 	LOCK(&adb->reflock);
2929 
2930 	zeroirefcnt = (adb->irefcnt == 0);
2931 
2932 	if (adb->shutting_down && zeroirefcnt &&
2933 	    isc_mempool_getallocated(adb->ahmp) == 0)
2934 	{
2935 		/*
2936 		 * We're already shutdown.  Send the event.
2937 		 */
2938 		event->ev_sender = adb;
2939 		isc_task_send(task, &event);
2940 	} else {
2941 		tclone = NULL;
2942 		isc_task_attach(task, &tclone);
2943 		event->ev_sender = tclone;
2944 		ISC_LIST_APPEND(adb->whenshutdown, event, ev_link);
2945 	}
2946 
2947 	UNLOCK(&adb->reflock);
2948 	UNLOCK(&adb->lock);
2949 }
2950 
2951 static void
2952 shutdown_stage2(isc_task_t *task, isc_event_t *event) {
2953 	dns_adb_t *adb;
2954 
2955 	UNUSED(task);
2956 
2957 	adb = event->ev_arg;
2958 	INSIST(DNS_ADB_VALID(adb));
2959 
2960 	LOCK(&adb->lock);
2961 	INSIST(adb->shutting_down);
2962 	adb->cevent_out = false;
2963 	(void)shutdown_names(adb);
2964 	(void)shutdown_entries(adb);
2965 	if (dec_adb_irefcnt(adb)) {
2966 		check_exit(adb);
2967 	}
2968 	UNLOCK(&adb->lock);
2969 }
2970 
2971 void
2972 dns_adb_shutdown(dns_adb_t *adb) {
2973 	isc_event_t *event;
2974 
2975 	/*
2976 	 * Shutdown 'adb'.
2977 	 */
2978 
2979 	LOCK(&adb->lock);
2980 
2981 	if (!adb->shutting_down) {
2982 		adb->shutting_down = true;
2983 		isc_mem_setwater(adb->mctx, water, adb, 0, 0);
2984 		/*
2985 		 * Isolate shutdown_names and shutdown_entries calls.
2986 		 */
2987 		inc_adb_irefcnt(adb);
2988 		ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
2989 			       DNS_EVENT_ADBCONTROL, shutdown_stage2, adb, adb,
2990 			       NULL, NULL);
2991 		adb->cevent_out = true;
2992 		event = &adb->cevent;
2993 		isc_task_send(adb->task, &event);
2994 	}
2995 
2996 	UNLOCK(&adb->lock);
2997 }
2998 
2999 isc_result_t
3000 dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
3001 		   void *arg, const dns_name_t *name, const dns_name_t *qname,
3002 		   dns_rdatatype_t qtype, unsigned int options,
3003 		   isc_stdtime_t now, dns_name_t *target, in_port_t port,
3004 		   unsigned int depth, isc_counter_t *qc,
3005 		   dns_adbfind_t **findp) {
3006 	dns_adbfind_t *find;
3007 	dns_adbname_t *adbname;
3008 	int bucket;
3009 	bool want_event, start_at_zone, alias, have_address;
3010 	isc_result_t result;
3011 	unsigned int wanted_addresses;
3012 	unsigned int wanted_fetches;
3013 	unsigned int query_pending;
3014 	char namebuf[DNS_NAME_FORMATSIZE];
3015 
3016 	REQUIRE(DNS_ADB_VALID(adb));
3017 	if (task != NULL) {
3018 		REQUIRE(action != NULL);
3019 	}
3020 	REQUIRE(name != NULL);
3021 	REQUIRE(qname != NULL);
3022 	REQUIRE(findp != NULL && *findp == NULL);
3023 	REQUIRE(target == NULL || dns_name_hasbuffer(target));
3024 
3025 	REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
3026 
3027 	result = ISC_R_UNEXPECTED;
3028 	POST(result);
3029 	wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK);
3030 	wanted_fetches = 0;
3031 	query_pending = 0;
3032 	want_event = false;
3033 	start_at_zone = false;
3034 	alias = false;
3035 
3036 	if (now == 0) {
3037 		isc_stdtime_get(&now);
3038 	}
3039 
3040 	/*
3041 	 * XXXMLG  Move this comment somewhere else!
3042 	 *
3043 	 * Look up the name in our internal database.
3044 	 *
3045 	 * Possibilities:  Note that these are not always exclusive.
3046 	 *
3047 	 *      No name found.  In this case, allocate a new name header and
3048 	 *      an initial namehook or two.  If any of these allocations
3049 	 *      fail, clean up and return ISC_R_NOMEMORY.
3050 	 *
3051 	 *      Name found, valid addresses present.  Allocate one addrinfo
3052 	 *      structure for each found and append it to the linked list
3053 	 *      of addresses for this header.
3054 	 *
3055 	 *      Name found, queries pending.  In this case, if a task was
3056 	 *      passed in, allocate a job id, attach it to the name's job
3057 	 *      list and remember to tell the caller that there will be
3058 	 *      more info coming later.
3059 	 */
3060 
3061 	find = new_adbfind(adb);
3062 	if (find == NULL) {
3063 		return (ISC_R_NOMEMORY);
3064 	}
3065 
3066 	find->port = port;
3067 
3068 	/*
3069 	 * Remember what types of addresses we are interested in.
3070 	 */
3071 	find->options = options;
3072 	find->flags |= wanted_addresses;
3073 	if (FIND_WANTEVENT(find)) {
3074 		REQUIRE(task != NULL);
3075 	}
3076 
3077 	if (isc_log_wouldlog(dns_lctx, DEF_LEVEL)) {
3078 		dns_name_format(name, namebuf, sizeof(namebuf));
3079 	} else {
3080 		namebuf[0] = 0;
3081 	}
3082 
3083 	/*
3084 	 * Try to see if we know anything about this name at all.
3085 	 */
3086 	bucket = DNS_ADB_INVALIDBUCKET;
3087 	adbname = find_name_and_lock(adb, name, find->options, &bucket);
3088 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
3089 	if (adb->name_sd[bucket]) {
3090 		DP(DEF_LEVEL, "dns_adb_createfind: returning "
3091 			      "ISC_R_SHUTTINGDOWN");
3092 		RUNTIME_CHECK(!free_adbfind(adb, &find));
3093 		result = ISC_R_SHUTTINGDOWN;
3094 		goto out;
3095 	}
3096 
3097 	/*
3098 	 * Nothing found.  Allocate a new adbname structure for this name.
3099 	 */
3100 	if (adbname == NULL) {
3101 		/*
3102 		 * See if there is any stale name at the end of list, and purge
3103 		 * it if so.
3104 		 */
3105 		check_stale_name(adb, bucket, now);
3106 
3107 		adbname = new_adbname(adb, name);
3108 		if (adbname == NULL) {
3109 			RUNTIME_CHECK(!free_adbfind(adb, &find));
3110 			result = ISC_R_NOMEMORY;
3111 			goto out;
3112 		}
3113 		link_name(adb, bucket, adbname);
3114 		if (FIND_HINTOK(find)) {
3115 			adbname->flags |= NAME_HINT_OK;
3116 		}
3117 		if (FIND_GLUEOK(find)) {
3118 			adbname->flags |= NAME_GLUE_OK;
3119 		}
3120 		if (FIND_STARTATZONE(find)) {
3121 			adbname->flags |= NAME_STARTATZONE;
3122 		}
3123 	} else {
3124 		/* Move this name forward in the LRU list */
3125 		ISC_LIST_UNLINK(adb->names[bucket], adbname, plink);
3126 		ISC_LIST_PREPEND(adb->names[bucket], adbname, plink);
3127 	}
3128 	adbname->last_used = now;
3129 
3130 	/*
3131 	 * Expire old entries, etc.
3132 	 */
3133 	RUNTIME_CHECK(!check_expire_namehooks(adbname, now));
3134 
3135 	/*
3136 	 * Do we know that the name is an alias?
3137 	 */
3138 	if (!EXPIRE_OK(adbname->expire_target, now)) {
3139 		/*
3140 		 * Yes, it is.
3141 		 */
3142 		DP(DEF_LEVEL,
3143 		   "dns_adb_createfind: name %s (%p) is an alias (cached)",
3144 		   namebuf, adbname);
3145 		alias = true;
3146 		goto post_copy;
3147 	}
3148 
3149 	/*
3150 	 * Try to populate the name from the database and/or
3151 	 * start fetches.  First try looking for an A record
3152 	 * in the database.
3153 	 */
3154 	if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) &&
3155 	    WANT_INET(wanted_addresses))
3156 	{
3157 		result = dbfind_name(adbname, now, dns_rdatatype_a);
3158 		if (result == ISC_R_SUCCESS) {
3159 			DP(DEF_LEVEL,
3160 			   "dns_adb_createfind: found A for name %s (%p) in db",
3161 			   namebuf, adbname);
3162 			goto v6;
3163 		}
3164 
3165 		/*
3166 		 * Did we get a CNAME or DNAME?
3167 		 */
3168 		if (result == DNS_R_ALIAS) {
3169 			DP(DEF_LEVEL,
3170 			   "dns_adb_createfind: name %s (%p) is an alias",
3171 			   namebuf, adbname);
3172 			alias = true;
3173 			goto post_copy;
3174 		}
3175 
3176 		/*
3177 		 * If the name doesn't exist at all, don't bother with
3178 		 * v6 queries; they won't work.
3179 		 *
3180 		 * If the name does exist but we didn't get our data, go
3181 		 * ahead and try AAAA.
3182 		 *
3183 		 * If the result is neither of these, try a fetch for A.
3184 		 */
3185 		if (NXDOMAIN_RESULT(result)) {
3186 			goto fetch;
3187 		} else if (NXRRSET_RESULT(result)) {
3188 			goto v6;
3189 		}
3190 
3191 		if (!NAME_FETCH_V4(adbname)) {
3192 			wanted_fetches |= DNS_ADBFIND_INET;
3193 		}
3194 	}
3195 
3196 v6:
3197 	if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) &&
3198 	    WANT_INET6(wanted_addresses))
3199 	{
3200 		result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
3201 		if (result == ISC_R_SUCCESS) {
3202 			DP(DEF_LEVEL,
3203 			   "dns_adb_createfind: found AAAA for name %s (%p)",
3204 			   namebuf, adbname);
3205 			goto fetch;
3206 		}
3207 
3208 		/*
3209 		 * Did we get a CNAME or DNAME?
3210 		 */
3211 		if (result == DNS_R_ALIAS) {
3212 			DP(DEF_LEVEL,
3213 			   "dns_adb_createfind: name %s (%p) is an alias",
3214 			   namebuf, adbname);
3215 			alias = true;
3216 			goto post_copy;
3217 		}
3218 
3219 		/*
3220 		 * Listen to negative cache hints, and don't start
3221 		 * another query.
3222 		 */
3223 		if (NCACHE_RESULT(result) || AUTH_NX(result)) {
3224 			goto fetch;
3225 		}
3226 
3227 		if (!NAME_FETCH_V6(adbname)) {
3228 			wanted_fetches |= DNS_ADBFIND_INET6;
3229 		}
3230 	}
3231 
3232 fetch:
3233 	if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
3234 	    (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
3235 	{
3236 		have_address = true;
3237 	} else {
3238 		have_address = false;
3239 	}
3240 	if (wanted_fetches != 0 && !(FIND_AVOIDFETCHES(find) && have_address) &&
3241 	    !FIND_NOFETCH(find))
3242 	{
3243 		/*
3244 		 * We're missing at least one address family.  Either the
3245 		 * caller hasn't instructed us to avoid fetches, or we don't
3246 		 * know anything about any of the address families that would
3247 		 * be acceptable so we have to launch fetches.
3248 		 */
3249 
3250 		if (FIND_STARTATZONE(find)) {
3251 			start_at_zone = true;
3252 		}
3253 
3254 		/*
3255 		 * Start V4.
3256 		 */
3257 		if (WANT_INET(wanted_fetches) &&
3258 		    fetch_name(adbname, start_at_zone, depth, qc,
3259 			       dns_rdatatype_a) == ISC_R_SUCCESS)
3260 		{
3261 			DP(DEF_LEVEL,
3262 			   "dns_adb_createfind: "
3263 			   "started A fetch for name %s (%p)",
3264 			   namebuf, adbname);
3265 		}
3266 
3267 		/*
3268 		 * Start V6.
3269 		 */
3270 		if (WANT_INET6(wanted_fetches) &&
3271 		    fetch_name(adbname, start_at_zone, depth, qc,
3272 			       dns_rdatatype_aaaa) == ISC_R_SUCCESS)
3273 		{
3274 			DP(DEF_LEVEL,
3275 			   "dns_adb_createfind: "
3276 			   "started AAAA fetch for name %s (%p)",
3277 			   namebuf, adbname);
3278 		}
3279 	}
3280 
3281 	/*
3282 	 * Run through the name and copy out the bits we are
3283 	 * interested in.
3284 	 */
3285 	copy_namehook_lists(adb, find, qname, qtype, adbname, now);
3286 
3287 post_copy:
3288 	if (NAME_FETCH_V4(adbname)) {
3289 		query_pending |= DNS_ADBFIND_INET;
3290 	}
3291 	if (NAME_FETCH_V6(adbname)) {
3292 		query_pending |= DNS_ADBFIND_INET6;
3293 	}
3294 
3295 	/*
3296 	 * Attach to the name's query list if there are queries
3297 	 * already running, and we have been asked to.
3298 	 */
3299 	want_event = true;
3300 	if (!FIND_WANTEVENT(find)) {
3301 		want_event = false;
3302 	}
3303 	if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find)) {
3304 		want_event = false;
3305 	}
3306 	if ((wanted_addresses & query_pending) == 0) {
3307 		want_event = false;
3308 	}
3309 	if (alias) {
3310 		want_event = false;
3311 	}
3312 	if (want_event) {
3313 		find->adbname = adbname;
3314 		find->name_bucket = bucket;
3315 		bool empty = ISC_LIST_EMPTY(adbname->finds);
3316 		ISC_LIST_APPEND(adbname->finds, find, plink);
3317 		find->query_pending = (query_pending & wanted_addresses);
3318 		find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
3319 		find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK);
3320 		DP(DEF_LEVEL,
3321 		   "createfind: attaching find %p to adbname "
3322 		   "%p %d",
3323 		   find, adbname, empty);
3324 	} else {
3325 		/*
3326 		 * Remove the flag so the caller knows there will never
3327 		 * be an event, and set internal flags to fake that
3328 		 * the event was sent and freed, so dns_adb_destroyfind() will
3329 		 * do the right thing.
3330 		 */
3331 		find->query_pending = (query_pending & wanted_addresses);
3332 		find->options &= ~DNS_ADBFIND_WANTEVENT;
3333 		find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
3334 		find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
3335 	}
3336 
3337 	find->partial_result |= (adbname->partial_result & wanted_addresses);
3338 	if (alias) {
3339 		if (target != NULL) {
3340 			dns_name_copynf(&adbname->target, target);
3341 		}
3342 		result = DNS_R_ALIAS;
3343 	} else {
3344 		result = ISC_R_SUCCESS;
3345 	}
3346 
3347 	/*
3348 	 * Copy out error flags from the name structure into the find.
3349 	 */
3350 	find->result_v4 = find_err_map[adbname->fetch_err];
3351 	find->result_v6 = find_err_map[adbname->fetch6_err];
3352 
3353 out:
3354 	if (find != NULL) {
3355 		*findp = find;
3356 
3357 		if (want_event) {
3358 			isc_task_t *taskp;
3359 
3360 			INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
3361 			taskp = NULL;
3362 			isc_task_attach(task, &taskp);
3363 			find->event.ev_sender = taskp;
3364 			find->event.ev_action = action;
3365 			find->event.ev_arg = arg;
3366 		}
3367 	}
3368 
3369 	UNLOCK(&adb->namelocks[bucket]);
3370 
3371 	return (result);
3372 }
3373 
3374 void
3375 dns_adb_destroyfind(dns_adbfind_t **findp) {
3376 	dns_adbfind_t *find;
3377 	dns_adbentry_t *entry;
3378 	dns_adbaddrinfo_t *ai;
3379 	int bucket;
3380 	dns_adb_t *adb;
3381 	bool overmem;
3382 
3383 	REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
3384 	find = *findp;
3385 	*findp = NULL;
3386 
3387 	LOCK(&find->lock);
3388 
3389 	DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
3390 
3391 	adb = find->adb;
3392 	REQUIRE(DNS_ADB_VALID(adb));
3393 
3394 	REQUIRE(FIND_EVENTFREED(find));
3395 
3396 	bucket = find->name_bucket;
3397 	INSIST(bucket == DNS_ADB_INVALIDBUCKET);
3398 
3399 	UNLOCK(&find->lock);
3400 
3401 	/*
3402 	 * The find doesn't exist on any list, and nothing is locked.
3403 	 * Return the find to the memory pool, and decrement the adb's
3404 	 * reference count.
3405 	 */
3406 	overmem = isc_mem_isovermem(adb->mctx);
3407 	ai = ISC_LIST_HEAD(find->list);
3408 	while (ai != NULL) {
3409 		ISC_LIST_UNLINK(find->list, ai, publink);
3410 		entry = ai->entry;
3411 		ai->entry = NULL;
3412 		INSIST(DNS_ADBENTRY_VALID(entry));
3413 		RUNTIME_CHECK(!dec_entry_refcnt(adb, overmem, entry, true));
3414 		free_adbaddrinfo(adb, &ai);
3415 		ai = ISC_LIST_HEAD(find->list);
3416 	}
3417 
3418 	/*
3419 	 * WARNING:  The find is freed with the adb locked.  This is done
3420 	 * to avoid a race condition where we free the find, some other
3421 	 * thread tests to see if it should be destroyed, detects it should
3422 	 * be, destroys it, and then we try to lock it for our check, but the
3423 	 * lock is destroyed.
3424 	 */
3425 	LOCK(&adb->lock);
3426 	if (free_adbfind(adb, &find)) {
3427 		check_exit(adb);
3428 	}
3429 	UNLOCK(&adb->lock);
3430 }
3431 
3432 void
3433 dns_adb_cancelfind(dns_adbfind_t *find) {
3434 	isc_event_t *ev;
3435 	isc_task_t *task;
3436 	dns_adb_t *adb;
3437 	int bucket;
3438 	int unlock_bucket;
3439 
3440 	LOCK(&find->lock);
3441 
3442 	DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
3443 
3444 	adb = find->adb;
3445 	REQUIRE(DNS_ADB_VALID(adb));
3446 
3447 	REQUIRE(!FIND_EVENTFREED(find));
3448 	REQUIRE(FIND_WANTEVENT(find));
3449 
3450 	bucket = find->name_bucket;
3451 	if (bucket == DNS_ADB_INVALIDBUCKET) {
3452 		goto cleanup;
3453 	}
3454 
3455 	/*
3456 	 * We need to get the adbname's lock to unlink the find.
3457 	 */
3458 	unlock_bucket = bucket;
3459 	violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
3460 	bucket = find->name_bucket;
3461 	if (bucket != DNS_ADB_INVALIDBUCKET) {
3462 		ISC_LIST_UNLINK(find->adbname->finds, find, plink);
3463 		find->adbname = NULL;
3464 		find->name_bucket = DNS_ADB_INVALIDBUCKET;
3465 	}
3466 	UNLOCK(&adb->namelocks[unlock_bucket]);
3467 	bucket = DNS_ADB_INVALIDBUCKET;
3468 	POST(bucket);
3469 
3470 cleanup:
3471 
3472 	if (!FIND_EVENTSENT(find)) {
3473 		ev = &find->event;
3474 		task = ev->ev_sender;
3475 		ev->ev_sender = find;
3476 		ev->ev_type = DNS_EVENT_ADBCANCELED;
3477 		ev->ev_destroy = event_free;
3478 		ev->ev_destroy_arg = find;
3479 		find->result_v4 = ISC_R_CANCELED;
3480 		find->result_v6 = ISC_R_CANCELED;
3481 
3482 		DP(DEF_LEVEL, "sending event %p to task %p for find %p", ev,
3483 		   task, find);
3484 
3485 		isc_task_sendanddetach(&task, (isc_event_t **)&ev);
3486 	}
3487 
3488 	UNLOCK(&find->lock);
3489 }
3490 
3491 void
3492 dns_adb_dump(dns_adb_t *adb, FILE *f) {
3493 	unsigned int i;
3494 	isc_stdtime_t now;
3495 
3496 	REQUIRE(DNS_ADB_VALID(adb));
3497 	REQUIRE(f != NULL);
3498 
3499 	/*
3500 	 * Lock the adb itself, lock all the name buckets, then lock all
3501 	 * the entry buckets.  This should put the adb into a state where
3502 	 * nothing can change, so we can iterate through everything and
3503 	 * print at our leisure.
3504 	 */
3505 
3506 	LOCK(&adb->lock);
3507 	isc_stdtime_get(&now);
3508 
3509 	for (i = 0; i < adb->nnames; i++) {
3510 		RUNTIME_CHECK(!cleanup_names(adb, i, now));
3511 	}
3512 	for (i = 0; i < adb->nentries; i++) {
3513 		RUNTIME_CHECK(!cleanup_entries(adb, i, now));
3514 	}
3515 
3516 	dump_adb(adb, f, false, now);
3517 	UNLOCK(&adb->lock);
3518 }
3519 
3520 static void
3521 dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
3522 	if (value == INT_MAX) {
3523 		return;
3524 	}
3525 	fprintf(f, " [%s TTL %d]", legend, (int)(value - now));
3526 }
3527 
3528 static void
3529 dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
3530 	dns_adbname_t *name;
3531 	dns_adbentry_t *entry;
3532 
3533 	fprintf(f, ";\n; Address database dump\n;\n");
3534 	fprintf(f, "; [edns success/4096 timeout/1432 timeout/1232 timeout/"
3535 		   "512 timeout]\n");
3536 	fprintf(f, "; [plain success/timeout]\n;\n");
3537 	if (debug) {
3538 		LOCK(&adb->reflock);
3539 		fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
3540 			adb, adb->erefcnt, adb->irefcnt,
3541 			isc_mempool_getallocated(adb->nhmp));
3542 		UNLOCK(&adb->reflock);
3543 	}
3544 
3545 /*
3546  * In TSAN mode we need to lock the locks individually, as TSAN
3547  * can't handle more than 64 locks locked by one thread.
3548  * In regular mode we want a consistent dump so we need to
3549  * lock everything.
3550  */
3551 #ifndef __SANITIZE_THREAD__
3552 	for (size_t i = 0; i < adb->nnames; i++) {
3553 		LOCK(&adb->namelocks[i]);
3554 	}
3555 	for (size_t i = 0; i < adb->nentries; i++) {
3556 		LOCK(&adb->entrylocks[i]);
3557 	}
3558 #endif /* ifndef __SANITIZE_THREAD__ */
3559 
3560 	/*
3561 	 * Dump the names
3562 	 */
3563 	for (size_t i = 0; i < adb->nnames; i++) {
3564 #ifdef __SANITIZE_THREAD__
3565 		LOCK(&adb->namelocks[i]);
3566 #endif /* ifdef __SANITIZE_THREAD__ */
3567 		name = ISC_LIST_HEAD(adb->names[i]);
3568 		if (name == NULL) {
3569 #ifdef __SANITIZE_THREAD__
3570 			UNLOCK(&adb->namelocks[i]);
3571 #endif /* ifdef __SANITIZE_THREAD__ */
3572 			continue;
3573 		}
3574 		if (debug) {
3575 			fprintf(f, "; bucket %zu\n", i);
3576 		}
3577 		for (; name != NULL; name = ISC_LIST_NEXT(name, plink)) {
3578 			if (debug) {
3579 				fprintf(f, "; name %p (flags %08x)\n", name,
3580 					name->flags);
3581 			}
3582 			fprintf(f, "; ");
3583 			print_dns_name(f, &name->name);
3584 			if (dns_name_countlabels(&name->target) > 0) {
3585 				fprintf(f, " alias ");
3586 				print_dns_name(f, &name->target);
3587 			}
3588 
3589 			dump_ttl(f, "v4", name->expire_v4, now);
3590 			dump_ttl(f, "v6", name->expire_v6, now);
3591 			dump_ttl(f, "target", name->expire_target, now);
3592 
3593 			fprintf(f, " [v4 %s] [v6 %s]",
3594 				errnames[name->fetch_err],
3595 				errnames[name->fetch6_err]);
3596 
3597 			fprintf(f, "\n");
3598 
3599 			print_namehook_list(f, "v4", adb, &name->v4, debug,
3600 					    now);
3601 			print_namehook_list(f, "v6", adb, &name->v6, debug,
3602 					    now);
3603 
3604 			if (debug) {
3605 				print_fetch_list(f, name);
3606 				print_find_list(f, name);
3607 			}
3608 		}
3609 #ifdef __SANITIZE_THREAD__
3610 		UNLOCK(&adb->namelocks[i]);
3611 #endif /* ifdef __SANITIZE_THREAD__ */
3612 	}
3613 
3614 	fprintf(f, ";\n; Unassociated entries\n;\n");
3615 
3616 	for (size_t i = 0; i < adb->nentries; i++) {
3617 #ifdef __SANITIZE_THREAD__
3618 		LOCK(&adb->entrylocks[i]);
3619 #endif /* ifdef __SANITIZE_THREAD__ */
3620 		entry = ISC_LIST_HEAD(adb->entries[i]);
3621 		while (entry != NULL) {
3622 			if (entry->nh == 0) {
3623 				dump_entry(f, adb, entry, debug, now);
3624 			}
3625 			entry = ISC_LIST_NEXT(entry, plink);
3626 		}
3627 #ifdef __SANITIZE_THREAD__
3628 		UNLOCK(&adb->entrylocks[i]);
3629 #endif /* ifdef __SANITIZE_THREAD__ */
3630 	}
3631 
3632 #ifndef __SANITIZE_THREAD__
3633 	/*
3634 	 * Unlock everything
3635 	 */
3636 	for (ssize_t i = adb->nentries - 1; i >= 0; i--) {
3637 		UNLOCK(&adb->entrylocks[i]);
3638 	}
3639 	for (ssize_t i = adb->nnames - 1; i >= 0; i--) {
3640 		UNLOCK(&adb->namelocks[i]);
3641 	}
3642 #endif /* ifndef __SANITIZE_THREAD__ */
3643 }
3644 
3645 static void
3646 dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, bool debug,
3647 	   isc_stdtime_t now) {
3648 	char addrbuf[ISC_NETADDR_FORMATSIZE];
3649 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
3650 	isc_netaddr_t netaddr;
3651 	dns_adblameinfo_t *li;
3652 
3653 	isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
3654 	isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
3655 
3656 	if (debug) {
3657 		fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt);
3658 	}
3659 
3660 	fprintf(f,
3661 		";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] "
3662 		"[plain %u/%u]",
3663 		addrbuf, entry->srtt, entry->flags, entry->edns, entry->to4096,
3664 		entry->to1432, entry->to1232, entry->to512, entry->plain,
3665 		entry->plainto);
3666 	if (entry->udpsize != 0U) {
3667 		fprintf(f, " [udpsize %u]", entry->udpsize);
3668 	}
3669 	if (entry->cookie != NULL) {
3670 		unsigned int i;
3671 		fprintf(f, " [cookie=");
3672 		for (i = 0; i < entry->cookielen; i++) {
3673 			fprintf(f, "%02x", entry->cookie[i]);
3674 		}
3675 		fprintf(f, "]");
3676 	}
3677 	if (entry->expires != 0) {
3678 		fprintf(f, " [ttl %d]", (int)(entry->expires - now));
3679 	}
3680 
3681 	if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
3682 		uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
3683 		fprintf(f, " [atr %0.2f] [quota %" PRIuFAST32 "]", entry->atr,
3684 			quota);
3685 	}
3686 
3687 	fprintf(f, "\n");
3688 	for (li = ISC_LIST_HEAD(entry->lameinfo); li != NULL;
3689 	     li = ISC_LIST_NEXT(li, plink))
3690 	{
3691 		fprintf(f, ";\t\t");
3692 		print_dns_name(f, &li->qname);
3693 		dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf));
3694 		fprintf(f, " %s [lame TTL %d]\n", typebuf,
3695 			(int)(li->lame_timer - now));
3696 	}
3697 }
3698 
3699 void
3700 dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
3701 	char tmp[512];
3702 	const char *tmpp;
3703 	dns_adbaddrinfo_t *ai;
3704 	isc_sockaddr_t *sa;
3705 
3706 	/*
3707 	 * Not used currently, in the API Just In Case we
3708 	 * want to dump out the name and/or entries too.
3709 	 */
3710 
3711 	LOCK(&find->lock);
3712 
3713 	fprintf(f, ";Find %p\n", find);
3714 	fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
3715 		find->query_pending, find->partial_result, find->options,
3716 		find->flags);
3717 	fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n",
3718 		find->name_bucket, find->adbname, find->event.ev_sender);
3719 
3720 	ai = ISC_LIST_HEAD(find->list);
3721 	if (ai != NULL) {
3722 		fprintf(f, "\tAddresses:\n");
3723 	}
3724 	while (ai != NULL) {
3725 		sa = &ai->sockaddr;
3726 		switch (sa->type.sa.sa_family) {
3727 		case AF_INET:
3728 			tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, tmp,
3729 					 sizeof(tmp));
3730 			break;
3731 		case AF_INET6:
3732 			tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
3733 					 tmp, sizeof(tmp));
3734 			break;
3735 		default:
3736 			tmpp = "UnkFamily";
3737 		}
3738 
3739 		if (tmpp == NULL) {
3740 			tmpp = "BadAddress";
3741 		}
3742 
3743 		fprintf(f,
3744 			"\t\tentry %p, flags %08x"
3745 			" srtt %u addr %s\n",
3746 			ai->entry, ai->flags, ai->srtt, tmpp);
3747 
3748 		ai = ISC_LIST_NEXT(ai, publink);
3749 	}
3750 
3751 	UNLOCK(&find->lock);
3752 }
3753 
3754 static void
3755 print_dns_name(FILE *f, const dns_name_t *name) {
3756 	char buf[DNS_NAME_FORMATSIZE];
3757 
3758 	INSIST(f != NULL);
3759 
3760 	dns_name_format(name, buf, sizeof(buf));
3761 	fprintf(f, "%s", buf);
3762 }
3763 
3764 static void
3765 print_namehook_list(FILE *f, const char *legend, dns_adb_t *adb,
3766 		    dns_adbnamehooklist_t *list, bool debug,
3767 		    isc_stdtime_t now) {
3768 	dns_adbnamehook_t *nh;
3769 
3770 	for (nh = ISC_LIST_HEAD(*list); nh != NULL;
3771 	     nh = ISC_LIST_NEXT(nh, plink)) {
3772 		if (debug) {
3773 			fprintf(f, ";\tHook(%s) %p\n", legend, nh);
3774 		}
3775 		dump_entry(f, adb, nh->entry, debug, now);
3776 	}
3777 }
3778 
3779 static inline void
3780 print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
3781 	fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n", type, ft, ft->fetch);
3782 }
3783 
3784 static void
3785 print_fetch_list(FILE *f, dns_adbname_t *n) {
3786 	if (NAME_FETCH_A(n)) {
3787 		print_fetch(f, n->fetch_a, "A");
3788 	}
3789 	if (NAME_FETCH_AAAA(n)) {
3790 		print_fetch(f, n->fetch_aaaa, "AAAA");
3791 	}
3792 }
3793 
3794 static void
3795 print_find_list(FILE *f, dns_adbname_t *name) {
3796 	dns_adbfind_t *find;
3797 
3798 	find = ISC_LIST_HEAD(name->finds);
3799 	while (find != NULL) {
3800 		dns_adb_dumpfind(find, f);
3801 		find = ISC_LIST_NEXT(find, plink);
3802 	}
3803 }
3804 
3805 static isc_result_t
3806 dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
3807 	isc_result_t result;
3808 	dns_rdataset_t rdataset;
3809 	dns_adb_t *adb;
3810 	dns_fixedname_t foundname;
3811 	dns_name_t *fname;
3812 
3813 	INSIST(DNS_ADBNAME_VALID(adbname));
3814 	adb = adbname->adb;
3815 	INSIST(DNS_ADB_VALID(adb));
3816 	INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
3817 
3818 	fname = dns_fixedname_initname(&foundname);
3819 	dns_rdataset_init(&rdataset);
3820 
3821 	if (rdtype == dns_rdatatype_a) {
3822 		adbname->fetch_err = FIND_ERR_UNEXPECTED;
3823 	} else {
3824 		adbname->fetch6_err = FIND_ERR_UNEXPECTED;
3825 	}
3826 
3827 	/*
3828 	 * We need to specify whether to search static-stub zones (if
3829 	 * configured) depending on whether this is a "start at zone" lookup,
3830 	 * i.e., whether it's a "bailiwick" glue.  If it's bailiwick (in which
3831 	 * case NAME_STARTATZONE is set) we need to stop the search at any
3832 	 * matching static-stub zone without looking into the cache to honor
3833 	 * the configuration on which server we should send queries to.
3834 	 */
3835 	result = dns_view_find(adb->view, &adbname->name, rdtype, now,
3836 			       NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
3837 			       NAME_HINTOK(adbname),
3838 			       ((adbname->flags & NAME_STARTATZONE) != 0), NULL,
3839 			       NULL, fname, &rdataset, NULL);
3840 
3841 	/* XXXVIX this switch statement is too sparse to gen a jump table. */
3842 	switch (result) {
3843 	case DNS_R_GLUE:
3844 	case DNS_R_HINT:
3845 	case ISC_R_SUCCESS:
3846 		/*
3847 		 * Found in the database.  Even if we can't copy out
3848 		 * any information, return success, or else a fetch
3849 		 * will be made, which will only make things worse.
3850 		 */
3851 		if (rdtype == dns_rdatatype_a) {
3852 			adbname->fetch_err = FIND_ERR_SUCCESS;
3853 		} else {
3854 			adbname->fetch6_err = FIND_ERR_SUCCESS;
3855 		}
3856 		result = import_rdataset(adbname, &rdataset, now);
3857 		break;
3858 	case DNS_R_NXDOMAIN:
3859 	case DNS_R_NXRRSET:
3860 		/*
3861 		 * We're authoritative and the data doesn't exist.
3862 		 * Make up a negative cache entry so we don't ask again
3863 		 * for a while.
3864 		 *
3865 		 * XXXRTH  What time should we use?  I'm putting in 30 seconds
3866 		 * for now.
3867 		 */
3868 		if (rdtype == dns_rdatatype_a) {
3869 			adbname->expire_v4 = now + 30;
3870 			DP(NCACHE_LEVEL,
3871 			   "adb name %p: Caching auth negative entry for A",
3872 			   adbname);
3873 			if (result == DNS_R_NXDOMAIN) {
3874 				adbname->fetch_err = FIND_ERR_NXDOMAIN;
3875 			} else {
3876 				adbname->fetch_err = FIND_ERR_NXRRSET;
3877 			}
3878 		} else {
3879 			DP(NCACHE_LEVEL,
3880 			   "adb name %p: Caching auth negative entry for AAAA",
3881 			   adbname);
3882 			adbname->expire_v6 = now + 30;
3883 			if (result == DNS_R_NXDOMAIN) {
3884 				adbname->fetch6_err = FIND_ERR_NXDOMAIN;
3885 			} else {
3886 				adbname->fetch6_err = FIND_ERR_NXRRSET;
3887 			}
3888 		}
3889 		break;
3890 	case DNS_R_NCACHENXDOMAIN:
3891 	case DNS_R_NCACHENXRRSET:
3892 		/*
3893 		 * We found a negative cache entry.  Pull the TTL from it
3894 		 * so we won't ask again for a while.
3895 		 */
3896 		rdataset.ttl = ttlclamp(rdataset.ttl);
3897 		if (rdtype == dns_rdatatype_a) {
3898 			adbname->expire_v4 = rdataset.ttl + now;
3899 			if (result == DNS_R_NCACHENXDOMAIN) {
3900 				adbname->fetch_err = FIND_ERR_NXDOMAIN;
3901 			} else {
3902 				adbname->fetch_err = FIND_ERR_NXRRSET;
3903 			}
3904 			DP(NCACHE_LEVEL,
3905 			   "adb name %p: Caching negative entry for A (ttl %u)",
3906 			   adbname, rdataset.ttl);
3907 		} else {
3908 			DP(NCACHE_LEVEL,
3909 			   "adb name %p: Caching negative entry for AAAA (ttl "
3910 			   "%u)",
3911 			   adbname, rdataset.ttl);
3912 			adbname->expire_v6 = rdataset.ttl + now;
3913 			if (result == DNS_R_NCACHENXDOMAIN) {
3914 				adbname->fetch6_err = FIND_ERR_NXDOMAIN;
3915 			} else {
3916 				adbname->fetch6_err = FIND_ERR_NXRRSET;
3917 			}
3918 		}
3919 		break;
3920 	case DNS_R_CNAME:
3921 	case DNS_R_DNAME:
3922 		/*
3923 		 * Clear the hint and glue flags, so this will match
3924 		 * more often.
3925 		 */
3926 		adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
3927 
3928 		rdataset.ttl = ttlclamp(rdataset.ttl);
3929 		clean_target(adb, &adbname->target);
3930 		adbname->expire_target = INT_MAX;
3931 		result = set_target(adb, &adbname->name, fname, &rdataset,
3932 				    &adbname->target);
3933 		if (result == ISC_R_SUCCESS) {
3934 			result = DNS_R_ALIAS;
3935 			DP(NCACHE_LEVEL, "adb name %p: caching alias target",
3936 			   adbname);
3937 			adbname->expire_target = rdataset.ttl + now;
3938 		}
3939 		if (rdtype == dns_rdatatype_a) {
3940 			adbname->fetch_err = FIND_ERR_SUCCESS;
3941 		} else {
3942 			adbname->fetch6_err = FIND_ERR_SUCCESS;
3943 		}
3944 		break;
3945 	}
3946 
3947 	if (dns_rdataset_isassociated(&rdataset)) {
3948 		dns_rdataset_disassociate(&rdataset);
3949 	}
3950 
3951 	return (result);
3952 }
3953 
3954 static void
3955 fetch_callback(isc_task_t *task, isc_event_t *ev) {
3956 	dns_fetchevent_t *dev;
3957 	dns_adbname_t *name;
3958 	dns_adb_t *adb;
3959 	dns_adbfetch_t *fetch;
3960 	int bucket;
3961 	isc_eventtype_t ev_status;
3962 	isc_stdtime_t now;
3963 	isc_result_t result;
3964 	unsigned int address_type;
3965 	bool want_check_exit = false;
3966 
3967 	UNUSED(task);
3968 
3969 	INSIST(ev->ev_type == DNS_EVENT_FETCHDONE);
3970 	dev = (dns_fetchevent_t *)ev;
3971 	name = ev->ev_arg;
3972 	INSIST(DNS_ADBNAME_VALID(name));
3973 	adb = name->adb;
3974 	INSIST(DNS_ADB_VALID(adb));
3975 
3976 	bucket = name->lock_bucket;
3977 	LOCK(&adb->namelocks[bucket]);
3978 
3979 	INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
3980 	address_type = 0;
3981 	if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
3982 		address_type = DNS_ADBFIND_INET;
3983 		fetch = name->fetch_a;
3984 		name->fetch_a = NULL;
3985 	} else if (NAME_FETCH_AAAA(name) &&
3986 		   (name->fetch_aaaa->fetch == dev->fetch)) {
3987 		address_type = DNS_ADBFIND_INET6;
3988 		fetch = name->fetch_aaaa;
3989 		name->fetch_aaaa = NULL;
3990 	} else {
3991 		fetch = NULL;
3992 	}
3993 
3994 	INSIST(address_type != 0 && fetch != NULL);
3995 
3996 	dns_resolver_destroyfetch(&fetch->fetch);
3997 	dev->fetch = NULL;
3998 
3999 	ev_status = DNS_EVENT_ADBNOMOREADDRESSES;
4000 
4001 	/*
4002 	 * Cleanup things we don't care about.
4003 	 */
4004 	if (dev->node != NULL) {
4005 		dns_db_detachnode(dev->db, &dev->node);
4006 	}
4007 	if (dev->db != NULL) {
4008 		dns_db_detach(&dev->db);
4009 	}
4010 
4011 	/*
4012 	 * If this name is marked as dead, clean up, throwing away
4013 	 * potentially good data.
4014 	 */
4015 	if (NAME_DEAD(name)) {
4016 		free_adbfetch(adb, &fetch);
4017 		isc_event_free(&ev);
4018 
4019 		want_check_exit = kill_name(&name, DNS_EVENT_ADBCANCELED);
4020 
4021 		UNLOCK(&adb->namelocks[bucket]);
4022 
4023 		if (want_check_exit) {
4024 			LOCK(&adb->lock);
4025 			check_exit(adb);
4026 			UNLOCK(&adb->lock);
4027 		}
4028 
4029 		return;
4030 	}
4031 
4032 	isc_stdtime_get(&now);
4033 
4034 	/*
4035 	 * If we got a negative cache response, remember it.
4036 	 */
4037 	if (NCACHE_RESULT(dev->result)) {
4038 		dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
4039 		if (address_type == DNS_ADBFIND_INET) {
4040 			DP(NCACHE_LEVEL,
4041 			   "adb fetch name %p: "
4042 			   "caching negative entry for A (ttl %u)",
4043 			   name, dev->rdataset->ttl);
4044 			name->expire_v4 = ISC_MIN(name->expire_v4,
4045 						  dev->rdataset->ttl + now);
4046 			if (dev->result == DNS_R_NCACHENXDOMAIN) {
4047 				name->fetch_err = FIND_ERR_NXDOMAIN;
4048 			} else {
4049 				name->fetch_err = FIND_ERR_NXRRSET;
4050 			}
4051 			inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
4052 		} else {
4053 			DP(NCACHE_LEVEL,
4054 			   "adb fetch name %p: "
4055 			   "caching negative entry for AAAA (ttl %u)",
4056 			   name, dev->rdataset->ttl);
4057 			name->expire_v6 = ISC_MIN(name->expire_v6,
4058 						  dev->rdataset->ttl + now);
4059 			if (dev->result == DNS_R_NCACHENXDOMAIN) {
4060 				name->fetch6_err = FIND_ERR_NXDOMAIN;
4061 			} else {
4062 				name->fetch6_err = FIND_ERR_NXRRSET;
4063 			}
4064 			inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
4065 		}
4066 		goto out;
4067 	}
4068 
4069 	/*
4070 	 * Handle CNAME/DNAME.
4071 	 */
4072 	if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
4073 		dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
4074 		clean_target(adb, &name->target);
4075 		name->expire_target = INT_MAX;
4076 		result = set_target(adb, &name->name,
4077 				    dns_fixedname_name(&dev->foundname),
4078 				    dev->rdataset, &name->target);
4079 		if (result == ISC_R_SUCCESS) {
4080 			DP(NCACHE_LEVEL,
4081 			   "adb fetch name %p: caching alias target", name);
4082 			name->expire_target = dev->rdataset->ttl + now;
4083 		}
4084 		goto check_result;
4085 	}
4086 
4087 	/*
4088 	 * Did we get back junk?  If so, and there are no more fetches
4089 	 * sitting out there, tell all the finds about it.
4090 	 */
4091 	if (dev->result != ISC_R_SUCCESS) {
4092 		char buf[DNS_NAME_FORMATSIZE];
4093 
4094 		dns_name_format(&name->name, buf, sizeof(buf));
4095 		DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf,
4096 		   address_type == DNS_ADBFIND_INET ? "A" : "AAAA",
4097 		   dns_result_totext(dev->result));
4098 		/*
4099 		 * Don't record a failure unless this is the initial
4100 		 * fetch of a chain.
4101 		 */
4102 		if (fetch->depth > 1) {
4103 			goto out;
4104 		}
4105 		/* XXXMLG Don't pound on bad servers. */
4106 		if (address_type == DNS_ADBFIND_INET) {
4107 			name->expire_v4 = ISC_MIN(name->expire_v4, now + 10);
4108 			name->fetch_err = FIND_ERR_FAILURE;
4109 			inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
4110 		} else {
4111 			name->expire_v6 = ISC_MIN(name->expire_v6, now + 10);
4112 			name->fetch6_err = FIND_ERR_FAILURE;
4113 			inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
4114 		}
4115 		goto out;
4116 	}
4117 
4118 	/*
4119 	 * We got something potentially useful.
4120 	 */
4121 	result = import_rdataset(name, &fetch->rdataset, now);
4122 
4123 check_result:
4124 	if (result == ISC_R_SUCCESS) {
4125 		ev_status = DNS_EVENT_ADBMOREADDRESSES;
4126 		if (address_type == DNS_ADBFIND_INET) {
4127 			name->fetch_err = FIND_ERR_SUCCESS;
4128 		} else {
4129 			name->fetch6_err = FIND_ERR_SUCCESS;
4130 		}
4131 	}
4132 
4133 out:
4134 	free_adbfetch(adb, &fetch);
4135 	isc_event_free(&ev);
4136 
4137 	clean_finds_at_name(name, ev_status, address_type);
4138 
4139 	UNLOCK(&adb->namelocks[bucket]);
4140 }
4141 
4142 static isc_result_t
4143 fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
4144 	   isc_counter_t *qc, dns_rdatatype_t type) {
4145 	isc_result_t result;
4146 	dns_adbfetch_t *fetch = NULL;
4147 	dns_adb_t *adb;
4148 	dns_fixedname_t fixed;
4149 	dns_name_t *name;
4150 	dns_rdataset_t rdataset;
4151 	dns_rdataset_t *nameservers;
4152 	unsigned int options;
4153 
4154 	INSIST(DNS_ADBNAME_VALID(adbname));
4155 	adb = adbname->adb;
4156 	INSIST(DNS_ADB_VALID(adb));
4157 
4158 	INSIST((type == dns_rdatatype_a && !NAME_FETCH_V4(adbname)) ||
4159 	       (type == dns_rdatatype_aaaa && !NAME_FETCH_V6(adbname)));
4160 
4161 	adbname->fetch_err = FIND_ERR_NOTFOUND;
4162 
4163 	name = NULL;
4164 	nameservers = NULL;
4165 	dns_rdataset_init(&rdataset);
4166 
4167 	options = DNS_FETCHOPT_NOVALIDATE;
4168 	if (start_at_zone) {
4169 		DP(ENTER_LEVEL, "fetch_name: starting at zone for name %p",
4170 		   adbname);
4171 		name = dns_fixedname_initname(&fixed);
4172 		result = dns_view_findzonecut(adb->view, &adbname->name, name,
4173 					      NULL, 0, 0, true, false,
4174 					      &rdataset, NULL);
4175 		if (result != ISC_R_SUCCESS && result != DNS_R_HINT) {
4176 			goto cleanup;
4177 		}
4178 		nameservers = &rdataset;
4179 		options |= DNS_FETCHOPT_UNSHARED;
4180 	}
4181 
4182 	fetch = new_adbfetch(adb);
4183 	if (fetch == NULL) {
4184 		result = ISC_R_NOMEMORY;
4185 		goto cleanup;
4186 	}
4187 	fetch->depth = depth;
4188 
4189 	/*
4190 	 * We're not minimizing this query, as nothing user-related should
4191 	 * be leaked here.
4192 	 * However, if we'd ever want to change it we'd have to modify
4193 	 * createfetch to find deepest cached name when we're providing
4194 	 * domain and nameservers.
4195 	 */
4196 	result = dns_resolver_createfetch(
4197 		adb->view->resolver, &adbname->name, type, name, nameservers,
4198 		NULL, NULL, 0, options, depth, qc, adb->task, fetch_callback,
4199 		adbname, &fetch->rdataset, NULL, &fetch->fetch);
4200 	if (result != ISC_R_SUCCESS) {
4201 		DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
4202 		   isc_result_totext(result));
4203 		goto cleanup;
4204 	}
4205 
4206 	if (type == dns_rdatatype_a) {
4207 		adbname->fetch_a = fetch;
4208 		inc_stats(adb, dns_resstatscounter_gluefetchv4);
4209 	} else {
4210 		adbname->fetch_aaaa = fetch;
4211 		inc_stats(adb, dns_resstatscounter_gluefetchv6);
4212 	}
4213 	fetch = NULL; /* Keep us from cleaning this up below. */
4214 
4215 cleanup:
4216 	if (fetch != NULL) {
4217 		free_adbfetch(adb, &fetch);
4218 	}
4219 	if (dns_rdataset_isassociated(&rdataset)) {
4220 		dns_rdataset_disassociate(&rdataset);
4221 	}
4222 
4223 	return (result);
4224 }
4225 
4226 /*
4227  * XXXMLG Needs to take a find argument and an address info, no zone or adb,
4228  * since these can be extracted from the find itself.
4229  */
4230 isc_result_t
4231 dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
4232 		 const dns_name_t *qname, dns_rdatatype_t qtype,
4233 		 isc_stdtime_t expire_time) {
4234 	dns_adblameinfo_t *li;
4235 	int bucket;
4236 	isc_result_t result = ISC_R_SUCCESS;
4237 
4238 	REQUIRE(DNS_ADB_VALID(adb));
4239 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4240 	REQUIRE(qname != NULL);
4241 
4242 	bucket = addr->entry->lock_bucket;
4243 	LOCK(&adb->entrylocks[bucket]);
4244 	li = ISC_LIST_HEAD(addr->entry->lameinfo);
4245 	while (li != NULL &&
4246 	       (li->qtype != qtype || !dns_name_equal(qname, &li->qname))) {
4247 		li = ISC_LIST_NEXT(li, plink);
4248 	}
4249 	if (li != NULL) {
4250 		if (expire_time > li->lame_timer) {
4251 			li->lame_timer = expire_time;
4252 		}
4253 		goto unlock;
4254 	}
4255 	li = new_adblameinfo(adb, qname, qtype);
4256 	if (li == NULL) {
4257 		result = ISC_R_NOMEMORY;
4258 		goto unlock;
4259 	}
4260 
4261 	li->lame_timer = expire_time;
4262 
4263 	ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink);
4264 unlock:
4265 	UNLOCK(&adb->entrylocks[bucket]);
4266 
4267 	return (result);
4268 }
4269 
4270 void
4271 dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt,
4272 		   unsigned int factor) {
4273 	int bucket;
4274 	isc_stdtime_t now = 0;
4275 
4276 	REQUIRE(DNS_ADB_VALID(adb));
4277 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4278 	REQUIRE(factor <= 10);
4279 
4280 	bucket = addr->entry->lock_bucket;
4281 	LOCK(&adb->entrylocks[bucket]);
4282 
4283 	if (addr->entry->expires == 0 || factor == DNS_ADB_RTTADJAGE) {
4284 		isc_stdtime_get(&now);
4285 	}
4286 	adjustsrtt(addr, rtt, factor, now);
4287 
4288 	UNLOCK(&adb->entrylocks[bucket]);
4289 }
4290 
4291 void
4292 dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) {
4293 	int bucket;
4294 
4295 	REQUIRE(DNS_ADB_VALID(adb));
4296 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4297 
4298 	bucket = addr->entry->lock_bucket;
4299 	LOCK(&adb->entrylocks[bucket]);
4300 
4301 	adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now);
4302 
4303 	UNLOCK(&adb->entrylocks[bucket]);
4304 }
4305 
4306 static void
4307 adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
4308 	   isc_stdtime_t now) {
4309 	uint64_t new_srtt;
4310 
4311 	if (factor == DNS_ADB_RTTADJAGE) {
4312 		if (addr->entry->lastage != now) {
4313 			new_srtt = addr->entry->srtt;
4314 			new_srtt <<= 9;
4315 			new_srtt -= addr->entry->srtt;
4316 			new_srtt >>= 9;
4317 			addr->entry->lastage = now;
4318 		} else {
4319 			new_srtt = addr->entry->srtt;
4320 		}
4321 	} else {
4322 		new_srtt = ((uint64_t)addr->entry->srtt / 10 * factor) +
4323 			   ((uint64_t)rtt / 10 * (10 - factor));
4324 	}
4325 
4326 	addr->entry->srtt = (unsigned int)new_srtt;
4327 	addr->srtt = (unsigned int)new_srtt;
4328 
4329 	if (addr->entry->expires == 0) {
4330 		addr->entry->expires = now + ADB_ENTRY_WINDOW;
4331 	}
4332 }
4333 
4334 void
4335 dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits,
4336 		    unsigned int mask) {
4337 	int bucket;
4338 	isc_stdtime_t now;
4339 
4340 	REQUIRE(DNS_ADB_VALID(adb));
4341 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4342 
4343 	REQUIRE((bits & ENTRY_IS_DEAD) == 0);
4344 	REQUIRE((mask & ENTRY_IS_DEAD) == 0);
4345 
4346 	bucket = addr->entry->lock_bucket;
4347 	LOCK(&adb->entrylocks[bucket]);
4348 
4349 	addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
4350 	if (addr->entry->expires == 0) {
4351 		isc_stdtime_get(&now);
4352 		addr->entry->expires = now + ADB_ENTRY_WINDOW;
4353 	}
4354 
4355 	/*
4356 	 * Note that we do not update the other bits in addr->flags with
4357 	 * the most recent values from addr->entry->flags.
4358 	 */
4359 	addr->flags = (addr->flags & ~mask) | (bits & mask);
4360 
4361 	UNLOCK(&adb->entrylocks[bucket]);
4362 }
4363 
4364 /*
4365  * The polynomial backoff curve (10000 / ((10 + n) / 10)^(3/2)) <0..99> drops
4366  * fairly aggressively at first, then slows down and tails off at around 2-3%.
4367  *
4368  * These will be used to make quota adjustments.
4369  */
4370 static int quota_adj[] = {
4371 	10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141, 3818, 3536,
4372 	3286,  3065, 2867, 2690, 2530, 2385, 2254, 2134, 2025, 1925, 1832,
4373 	1747,  1668, 1595, 1527, 1464, 1405, 1350, 1298, 1250, 1205, 1162,
4374 	1121,  1083, 1048, 1014, 981,  922,  894,  868,	 843,  820,  797,
4375 	775,   755,  735,  716,	 698,  680,  664,  648,	 632,  618,  603,
4376 	590,   577,  564,  552,	 540,  529,  518,  507,	 497,  487,  477,
4377 	468,   459,  450,  442,	 434,  426,  418,  411,	 404,  397,  390,
4378 	383,   377,  370,  364,	 358,  353,  347,  342,	 336,  331,  326,
4379 	321,   316,  312,  307,	 303,  298,  294,  290,	 286,  282,  278
4380 };
4381 
4382 #define QUOTA_ADJ_SIZE (sizeof(quota_adj) / sizeof(quota_adj[0]))
4383 
4384 /*
4385  * Caller must hold adbentry lock
4386  */
4387 static void
4388 maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) {
4389 	double tr;
4390 
4391 	UNUSED(adb);
4392 
4393 	if (adb->quota == 0 || adb->atr_freq == 0) {
4394 		return;
4395 	}
4396 
4397 	if (timeout) {
4398 		addr->entry->timeouts++;
4399 	}
4400 
4401 	if (addr->entry->completed++ <= adb->atr_freq) {
4402 		return;
4403 	}
4404 
4405 	/*
4406 	 * Calculate an exponential rolling average of the timeout ratio
4407 	 *
4408 	 * XXX: Integer arithmetic might be better than floating point
4409 	 */
4410 	tr = (double)addr->entry->timeouts / addr->entry->completed;
4411 	addr->entry->timeouts = addr->entry->completed = 0;
4412 	INSIST(addr->entry->atr >= 0.0);
4413 	INSIST(addr->entry->atr <= 1.0);
4414 	INSIST(adb->atr_discount >= 0.0);
4415 	INSIST(adb->atr_discount <= 1.0);
4416 	addr->entry->atr *= 1.0 - adb->atr_discount;
4417 	addr->entry->atr += tr * adb->atr_discount;
4418 	addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0);
4419 
4420 	if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) {
4421 		uint_fast32_t new_quota =
4422 			adb->quota * quota_adj[--addr->entry->mode] / 10000;
4423 		atomic_store_release(&addr->entry->quota,
4424 				     ISC_MIN(1, new_quota));
4425 		log_quota(addr->entry,
4426 			  "atr %0.2f, quota increased to %" PRIuFAST32,
4427 			  addr->entry->atr, new_quota);
4428 	} else if (addr->entry->atr > adb->atr_high &&
4429 		   addr->entry->mode < (QUOTA_ADJ_SIZE - 1))
4430 	{
4431 		uint_fast32_t new_quota =
4432 			adb->quota * quota_adj[++addr->entry->mode] / 10000;
4433 		atomic_store_release(&addr->entry->quota,
4434 				     ISC_MIN(1, new_quota));
4435 		log_quota(addr->entry,
4436 			  "atr %0.2f, quota decreased to %" PRIuFAST32,
4437 			  addr->entry->atr, new_quota);
4438 	}
4439 }
4440 
4441 #define EDNSTOS 3U
4442 bool
4443 dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4444 	int bucket;
4445 	bool noedns = false;
4446 
4447 	REQUIRE(DNS_ADB_VALID(adb));
4448 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4449 
4450 	bucket = addr->entry->lock_bucket;
4451 	LOCK(&adb->entrylocks[bucket]);
4452 
4453 	if (addr->entry->edns == 0U &&
4454 	    (addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS))
4455 	{
4456 		if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) {
4457 			noedns = true;
4458 		} else {
4459 			/*
4460 			 * Increment plain so we don't get stuck.
4461 			 */
4462 			addr->entry->plain++;
4463 			if (addr->entry->plain == 0xff) {
4464 				addr->entry->edns >>= 1;
4465 				addr->entry->to4096 >>= 1;
4466 				addr->entry->to1432 >>= 1;
4467 				addr->entry->to1232 >>= 1;
4468 				addr->entry->to512 >>= 1;
4469 				addr->entry->plain >>= 1;
4470 				addr->entry->plainto >>= 1;
4471 			}
4472 		}
4473 	}
4474 	UNLOCK(&adb->entrylocks[bucket]);
4475 	return (noedns);
4476 }
4477 
4478 void
4479 dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4480 	int bucket;
4481 
4482 	REQUIRE(DNS_ADB_VALID(adb));
4483 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4484 
4485 	bucket = addr->entry->lock_bucket;
4486 	LOCK(&adb->entrylocks[bucket]);
4487 
4488 	maybe_adjust_quota(adb, addr, false);
4489 
4490 	addr->entry->plain++;
4491 	if (addr->entry->plain == 0xff) {
4492 		addr->entry->edns >>= 1;
4493 		addr->entry->to4096 >>= 1;
4494 		addr->entry->to1432 >>= 1;
4495 		addr->entry->to1232 >>= 1;
4496 		addr->entry->to512 >>= 1;
4497 		addr->entry->plain >>= 1;
4498 		addr->entry->plainto >>= 1;
4499 	}
4500 	UNLOCK(&adb->entrylocks[bucket]);
4501 }
4502 
4503 void
4504 dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4505 	int bucket;
4506 
4507 	REQUIRE(DNS_ADB_VALID(adb));
4508 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4509 
4510 	bucket = addr->entry->lock_bucket;
4511 	LOCK(&adb->entrylocks[bucket]);
4512 
4513 	maybe_adjust_quota(adb, addr, true);
4514 
4515 	/*
4516 	 * If we have not had a successful query then clear all
4517 	 * edns timeout information.
4518 	 */
4519 	if (addr->entry->edns == 0 && addr->entry->plain == 0) {
4520 		addr->entry->to512 = 0;
4521 		addr->entry->to1232 = 0;
4522 		addr->entry->to1432 = 0;
4523 		addr->entry->to4096 = 0;
4524 	} else {
4525 		addr->entry->to512 >>= 1;
4526 		addr->entry->to1232 >>= 1;
4527 		addr->entry->to1432 >>= 1;
4528 		addr->entry->to4096 >>= 1;
4529 	}
4530 
4531 	addr->entry->plainto++;
4532 	if (addr->entry->plainto == 0xff) {
4533 		addr->entry->edns >>= 1;
4534 		addr->entry->plain >>= 1;
4535 		addr->entry->plainto >>= 1;
4536 	}
4537 	UNLOCK(&adb->entrylocks[bucket]);
4538 }
4539 
4540 void
4541 dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
4542 	int bucket;
4543 
4544 	REQUIRE(DNS_ADB_VALID(adb));
4545 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4546 
4547 	bucket = addr->entry->lock_bucket;
4548 	LOCK(&adb->entrylocks[bucket]);
4549 
4550 	maybe_adjust_quota(adb, addr, true);
4551 
4552 	if (size <= 512U) {
4553 		if (addr->entry->to512 <= EDNSTOS) {
4554 			addr->entry->to512++;
4555 			addr->entry->to1232++;
4556 			addr->entry->to1432++;
4557 			addr->entry->to4096++;
4558 		}
4559 	} else if (size <= 1232U) {
4560 		if (addr->entry->to1232 <= EDNSTOS) {
4561 			addr->entry->to1232++;
4562 			addr->entry->to1432++;
4563 			addr->entry->to4096++;
4564 		}
4565 	} else if (size <= 1432U) {
4566 		if (addr->entry->to1432 <= EDNSTOS) {
4567 			addr->entry->to1432++;
4568 			addr->entry->to4096++;
4569 		}
4570 	} else {
4571 		if (addr->entry->to4096 <= EDNSTOS) {
4572 			addr->entry->to4096++;
4573 		}
4574 	}
4575 
4576 	if (addr->entry->to4096 == 0xff) {
4577 		addr->entry->edns >>= 1;
4578 		addr->entry->to4096 >>= 1;
4579 		addr->entry->to1432 >>= 1;
4580 		addr->entry->to1232 >>= 1;
4581 		addr->entry->to512 >>= 1;
4582 		addr->entry->plain >>= 1;
4583 		addr->entry->plainto >>= 1;
4584 	}
4585 	UNLOCK(&adb->entrylocks[bucket]);
4586 }
4587 
4588 void
4589 dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
4590 	int bucket;
4591 
4592 	REQUIRE(DNS_ADB_VALID(adb));
4593 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4594 
4595 	bucket = addr->entry->lock_bucket;
4596 	LOCK(&adb->entrylocks[bucket]);
4597 	if (size < 512U) {
4598 		size = 512U;
4599 	}
4600 	if (size > addr->entry->udpsize) {
4601 		addr->entry->udpsize = size;
4602 	}
4603 
4604 	maybe_adjust_quota(adb, addr, false);
4605 
4606 	addr->entry->edns++;
4607 	if (addr->entry->edns == 0xff) {
4608 		addr->entry->edns >>= 1;
4609 		addr->entry->to4096 >>= 1;
4610 		addr->entry->to1432 >>= 1;
4611 		addr->entry->to1232 >>= 1;
4612 		addr->entry->to512 >>= 1;
4613 		addr->entry->plain >>= 1;
4614 		addr->entry->plainto >>= 1;
4615 	}
4616 	UNLOCK(&adb->entrylocks[bucket]);
4617 }
4618 
4619 unsigned int
4620 dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4621 	int bucket;
4622 	unsigned int size;
4623 
4624 	REQUIRE(DNS_ADB_VALID(adb));
4625 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4626 
4627 	bucket = addr->entry->lock_bucket;
4628 	LOCK(&adb->entrylocks[bucket]);
4629 	size = addr->entry->udpsize;
4630 	UNLOCK(&adb->entrylocks[bucket]);
4631 
4632 	return (size);
4633 }
4634 
4635 unsigned int
4636 dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups) {
4637 	int bucket;
4638 	unsigned int size;
4639 
4640 	REQUIRE(DNS_ADB_VALID(adb));
4641 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4642 
4643 	bucket = addr->entry->lock_bucket;
4644 	LOCK(&adb->entrylocks[bucket]);
4645 	if (addr->entry->to1232 > EDNSTOS || lookups >= 2) {
4646 		size = 512;
4647 	} else if (addr->entry->to1432 > EDNSTOS || lookups >= 1) {
4648 		size = 1232;
4649 	} else if (addr->entry->to4096 > EDNSTOS) {
4650 		size = 1432;
4651 	} else {
4652 		size = 4096;
4653 	}
4654 	/*
4655 	 * Don't shrink probe size below what we have seen due to multiple
4656 	 * lookups.
4657 	 */
4658 	if (lookups > 0 && size < addr->entry->udpsize &&
4659 	    addr->entry->udpsize < 4096) {
4660 		size = addr->entry->udpsize;
4661 	}
4662 	UNLOCK(&adb->entrylocks[bucket]);
4663 
4664 	return (size);
4665 }
4666 
4667 void
4668 dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
4669 		  const unsigned char *cookie, size_t len) {
4670 	int bucket;
4671 
4672 	REQUIRE(DNS_ADB_VALID(adb));
4673 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4674 
4675 	bucket = addr->entry->lock_bucket;
4676 	LOCK(&adb->entrylocks[bucket]);
4677 
4678 	if (addr->entry->cookie != NULL &&
4679 	    (cookie == NULL || len != addr->entry->cookielen))
4680 	{
4681 		isc_mem_put(adb->mctx, addr->entry->cookie,
4682 			    addr->entry->cookielen);
4683 		addr->entry->cookie = NULL;
4684 		addr->entry->cookielen = 0;
4685 	}
4686 
4687 	if (addr->entry->cookie == NULL && cookie != NULL && len != 0U) {
4688 		addr->entry->cookie = isc_mem_get(adb->mctx, len);
4689 		addr->entry->cookielen = (uint16_t)len;
4690 	}
4691 
4692 	if (addr->entry->cookie != NULL) {
4693 		memmove(addr->entry->cookie, cookie, len);
4694 	}
4695 	UNLOCK(&adb->entrylocks[bucket]);
4696 }
4697 
4698 size_t
4699 dns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
4700 		  unsigned char *cookie, size_t len) {
4701 	int bucket;
4702 
4703 	REQUIRE(DNS_ADB_VALID(adb));
4704 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4705 
4706 	bucket = addr->entry->lock_bucket;
4707 	LOCK(&adb->entrylocks[bucket]);
4708 	if (cookie != NULL && addr->entry->cookie != NULL &&
4709 	    len >= addr->entry->cookielen)
4710 	{
4711 		memmove(cookie, addr->entry->cookie, addr->entry->cookielen);
4712 		len = addr->entry->cookielen;
4713 	} else {
4714 		len = 0;
4715 	}
4716 	UNLOCK(&adb->entrylocks[bucket]);
4717 
4718 	return (len);
4719 }
4720 
4721 isc_result_t
4722 dns_adb_findaddrinfo(dns_adb_t *adb, const isc_sockaddr_t *sa,
4723 		     dns_adbaddrinfo_t **addrp, isc_stdtime_t now) {
4724 	int bucket;
4725 	dns_adbentry_t *entry;
4726 	dns_adbaddrinfo_t *addr;
4727 	isc_result_t result;
4728 	in_port_t port;
4729 
4730 	REQUIRE(DNS_ADB_VALID(adb));
4731 	REQUIRE(addrp != NULL && *addrp == NULL);
4732 
4733 	UNUSED(now);
4734 
4735 	result = ISC_R_SUCCESS;
4736 	bucket = DNS_ADB_INVALIDBUCKET;
4737 	entry = find_entry_and_lock(adb, sa, &bucket, now);
4738 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
4739 	if (adb->entry_sd[bucket]) {
4740 		result = ISC_R_SHUTTINGDOWN;
4741 		goto unlock;
4742 	}
4743 	if (entry == NULL) {
4744 		/*
4745 		 * We don't know anything about this address.
4746 		 */
4747 		entry = new_adbentry(adb);
4748 		if (entry == NULL) {
4749 			result = ISC_R_NOMEMORY;
4750 			goto unlock;
4751 		}
4752 		entry->sockaddr = *sa;
4753 		link_entry(adb, bucket, entry);
4754 		DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry);
4755 	} else {
4756 		DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry);
4757 	}
4758 
4759 	port = isc_sockaddr_getport(sa);
4760 	addr = new_adbaddrinfo(adb, entry, port);
4761 	if (addr == NULL) {
4762 		result = ISC_R_NOMEMORY;
4763 	} else {
4764 		inc_entry_refcnt(adb, entry, false);
4765 		*addrp = addr;
4766 	}
4767 
4768 unlock:
4769 	UNLOCK(&adb->entrylocks[bucket]);
4770 
4771 	return (result);
4772 }
4773 
4774 void
4775 dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
4776 	dns_adbaddrinfo_t *addr;
4777 	dns_adbentry_t *entry;
4778 	int bucket;
4779 	isc_stdtime_t now;
4780 	bool want_check_exit = false;
4781 	bool overmem;
4782 
4783 	REQUIRE(DNS_ADB_VALID(adb));
4784 	REQUIRE(addrp != NULL);
4785 	addr = *addrp;
4786 	*addrp = NULL;
4787 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4788 	entry = addr->entry;
4789 	REQUIRE(DNS_ADBENTRY_VALID(entry));
4790 
4791 	overmem = isc_mem_isovermem(adb->mctx);
4792 
4793 	bucket = addr->entry->lock_bucket;
4794 	LOCK(&adb->entrylocks[bucket]);
4795 
4796 	if (entry->expires == 0) {
4797 		isc_stdtime_get(&now);
4798 		entry->expires = now + ADB_ENTRY_WINDOW;
4799 	}
4800 
4801 	want_check_exit = dec_entry_refcnt(adb, overmem, entry, false);
4802 
4803 	UNLOCK(&adb->entrylocks[bucket]);
4804 
4805 	addr->entry = NULL;
4806 	free_adbaddrinfo(adb, &addr);
4807 
4808 	if (want_check_exit) {
4809 		LOCK(&adb->lock);
4810 		check_exit(adb);
4811 		UNLOCK(&adb->lock);
4812 	}
4813 }
4814 
4815 void
4816 dns_adb_flush(dns_adb_t *adb) {
4817 	unsigned int i;
4818 
4819 	INSIST(DNS_ADB_VALID(adb));
4820 
4821 	LOCK(&adb->lock);
4822 
4823 	/*
4824 	 * Call our cleanup routines.
4825 	 */
4826 	for (i = 0; i < adb->nnames; i++) {
4827 		RUNTIME_CHECK(!cleanup_names(adb, i, INT_MAX));
4828 	}
4829 	for (i = 0; i < adb->nentries; i++) {
4830 		RUNTIME_CHECK(!cleanup_entries(adb, i, INT_MAX));
4831 	}
4832 
4833 #ifdef DUMP_ADB_AFTER_CLEANING
4834 	dump_adb(adb, stdout, true, INT_MAX);
4835 #endif /* ifdef DUMP_ADB_AFTER_CLEANING */
4836 
4837 	UNLOCK(&adb->lock);
4838 }
4839 
4840 void
4841 dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
4842 	dns_adbname_t *adbname;
4843 	dns_adbname_t *nextname;
4844 	unsigned int bucket;
4845 
4846 	REQUIRE(DNS_ADB_VALID(adb));
4847 	REQUIRE(name != NULL);
4848 
4849 	LOCK(&adb->lock);
4850 	bucket = dns_name_hash(name, false) % adb->nnames;
4851 	LOCK(&adb->namelocks[bucket]);
4852 	adbname = ISC_LIST_HEAD(adb->names[bucket]);
4853 	while (adbname != NULL) {
4854 		nextname = ISC_LIST_NEXT(adbname, plink);
4855 		if (!NAME_DEAD(adbname) && dns_name_equal(name, &adbname->name))
4856 		{
4857 			RUNTIME_CHECK(
4858 				!kill_name(&adbname, DNS_EVENT_ADBCANCELED));
4859 		}
4860 		adbname = nextname;
4861 	}
4862 	UNLOCK(&adb->namelocks[bucket]);
4863 	UNLOCK(&adb->lock);
4864 }
4865 
4866 void
4867 dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
4868 	dns_adbname_t *adbname, *nextname;
4869 	unsigned int i;
4870 
4871 	REQUIRE(DNS_ADB_VALID(adb));
4872 	REQUIRE(name != NULL);
4873 
4874 	LOCK(&adb->lock);
4875 	for (i = 0; i < adb->nnames; i++) {
4876 		LOCK(&adb->namelocks[i]);
4877 		adbname = ISC_LIST_HEAD(adb->names[i]);
4878 		while (adbname != NULL) {
4879 			bool ret;
4880 			nextname = ISC_LIST_NEXT(adbname, plink);
4881 			if (!NAME_DEAD(adbname) &&
4882 			    dns_name_issubdomain(&adbname->name, name)) {
4883 				ret = kill_name(&adbname,
4884 						DNS_EVENT_ADBCANCELED);
4885 				RUNTIME_CHECK(!ret);
4886 			}
4887 			adbname = nextname;
4888 		}
4889 		UNLOCK(&adb->namelocks[i]);
4890 	}
4891 	UNLOCK(&adb->lock);
4892 }
4893 
4894 static void
4895 water(void *arg, int mark) {
4896 	/*
4897 	 * We're going to change the way to handle overmem condition: use
4898 	 * isc_mem_isovermem() instead of storing the state via this callback,
4899 	 * since the latter way tends to cause race conditions.
4900 	 * To minimize the change, and in case we re-enable the callback
4901 	 * approach, however, keep this function at the moment.
4902 	 */
4903 
4904 	dns_adb_t *adb = arg;
4905 	bool overmem = (mark == ISC_MEM_HIWATER);
4906 
4907 	REQUIRE(DNS_ADB_VALID(adb));
4908 
4909 	DP(ISC_LOG_DEBUG(1), "adb reached %s water mark",
4910 	   overmem ? "high" : "low");
4911 }
4912 
4913 void
4914 dns_adb_setadbsize(dns_adb_t *adb, size_t size) {
4915 	size_t hiwater, lowater;
4916 
4917 	INSIST(DNS_ADB_VALID(adb));
4918 
4919 	if (size != 0U && size < DNS_ADB_MINADBSIZE) {
4920 		size = DNS_ADB_MINADBSIZE;
4921 	}
4922 
4923 	hiwater = size - (size >> 3); /* Approximately 7/8ths. */
4924 	lowater = size - (size >> 2); /* Approximately 3/4ths. */
4925 
4926 	if (size == 0U || hiwater == 0U || lowater == 0U) {
4927 		isc_mem_setwater(adb->mctx, water, adb, 0, 0);
4928 	} else {
4929 		isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
4930 	}
4931 }
4932 
4933 void
4934 dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, double low,
4935 		 double high, double discount) {
4936 	REQUIRE(DNS_ADB_VALID(adb));
4937 
4938 	adb->quota = quota;
4939 	adb->atr_freq = freq;
4940 	adb->atr_low = low;
4941 	adb->atr_high = high;
4942 	adb->atr_discount = discount;
4943 }
4944 
4945 bool
4946 dns_adbentry_overquota(dns_adbentry_t *entry) {
4947 	REQUIRE(DNS_ADBENTRY_VALID(entry));
4948 
4949 	uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
4950 	uint_fast32_t active = atomic_load_acquire(&entry->active);
4951 
4952 	return (quota != 0 && active >= quota);
4953 }
4954 
4955 void
4956 dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4957 	REQUIRE(DNS_ADB_VALID(adb));
4958 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4959 
4960 	INSIST(atomic_fetch_add_relaxed(&addr->entry->active, 1) != UINT32_MAX);
4961 }
4962 
4963 void
4964 dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4965 	REQUIRE(DNS_ADB_VALID(adb));
4966 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4967 
4968 	INSIST(atomic_fetch_sub_release(&addr->entry->active, 1) != 0);
4969 }
4970