xref: /netbsd-src/external/mpl/bind/dist/lib/dns/adb.c (revision d90047b5d07facf36e6c01dcc0bded8997ce9cc2)
1 /*	$NetBSD: adb.c,v 1.5 2020/05/24 19:46:22 christos 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 http://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, bucket;
762 
763 	adb = ev->ev_arg;
764 	INSIST(DNS_ADB_VALID(adb));
765 
766 	isc_event_free(&ev);
767 
768 	result = isc_task_beginexclusive(task);
769 	if (result != ISC_R_SUCCESS) {
770 		goto check_exit;
771 	}
772 
773 	i = 0;
774 	while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i]) {
775 		i++;
776 	}
777 	if (nbuckets[i] != 0) {
778 		n = nbuckets[i];
779 	} else {
780 		goto done;
781 	}
782 
783 	DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n);
784 
785 	/*
786 	 * Are we shutting down?
787 	 */
788 	for (i = 0; i < adb->nnames; i++) {
789 		if (adb->name_sd[i]) {
790 			goto cleanup;
791 
792 			/*
793 			 * Grab all the resources we need.
794 			 */
795 		}
796 	}
797 
798 	/*
799 	 * Grab all the resources we need.
800 	 */
801 	newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n);
802 	newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n);
803 	newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
804 	newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
805 	newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
806 	if (newnames == NULL || newdeadnames == NULL || newnamelocks == NULL ||
807 	    newname_sd == NULL || newname_refcnt == NULL)
808 	{
809 		goto cleanup;
810 	}
811 
812 	/*
813 	 * Initialise the new resources.
814 	 */
815 	isc_mutexblock_init(newnamelocks, n);
816 
817 	for (i = 0; i < n; i++) {
818 		ISC_LIST_INIT(newnames[i]);
819 		ISC_LIST_INIT(newdeadnames[i]);
820 		newname_sd[i] = false;
821 		newname_refcnt[i] = 0;
822 		adb->irefcnt++;
823 	}
824 
825 	/*
826 	 * Move names to new arrays.
827 	 */
828 	for (i = 0; i < adb->nnames; i++) {
829 		name = ISC_LIST_HEAD(adb->names[i]);
830 		while (name != NULL) {
831 			ISC_LIST_UNLINK(adb->names[i], name, plink);
832 			bucket = dns_name_fullhash(&name->name, true) % n;
833 			name->lock_bucket = bucket;
834 			ISC_LIST_APPEND(newnames[bucket], name, plink);
835 			INSIST(adb->name_refcnt[i] > 0);
836 			adb->name_refcnt[i]--;
837 			newname_refcnt[bucket]++;
838 			name = ISC_LIST_HEAD(adb->names[i]);
839 		}
840 		name = ISC_LIST_HEAD(adb->deadnames[i]);
841 		while (name != NULL) {
842 			ISC_LIST_UNLINK(adb->deadnames[i], name, plink);
843 			bucket = dns_name_fullhash(&name->name, true) % n;
844 			name->lock_bucket = bucket;
845 			ISC_LIST_APPEND(newdeadnames[bucket], name, plink);
846 			INSIST(adb->name_refcnt[i] > 0);
847 			adb->name_refcnt[i]--;
848 			newname_refcnt[bucket]++;
849 			name = ISC_LIST_HEAD(adb->deadnames[i]);
850 		}
851 		INSIST(adb->name_refcnt[i] == 0);
852 		adb->irefcnt--;
853 	}
854 
855 	/*
856 	 * Cleanup old resources.
857 	 */
858 	isc_mutexblock_destroy(adb->namelocks, adb->nnames);
859 	isc_mem_put(adb->mctx, adb->names, sizeof(*adb->names) * adb->nnames);
860 	isc_mem_put(adb->mctx, adb->deadnames,
861 		    sizeof(*adb->deadnames) * adb->nnames);
862 	isc_mem_put(adb->mctx, adb->namelocks,
863 		    sizeof(*adb->namelocks) * adb->nnames);
864 	isc_mem_put(adb->mctx, adb->name_sd,
865 		    sizeof(*adb->name_sd) * adb->nnames);
866 	isc_mem_put(adb->mctx, adb->name_refcnt,
867 		    sizeof(*adb->name_refcnt) * adb->nnames);
868 
869 	/*
870 	 * Install new resources.
871 	 */
872 	adb->names = newnames;
873 	adb->deadnames = newdeadnames;
874 	adb->namelocks = newnamelocks;
875 	adb->name_sd = newname_sd;
876 	adb->name_refcnt = newname_refcnt;
877 	adb->nnames = n;
878 
879 	set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
880 
881 	/*
882 	 * Only on success do we set adb->grownames_sent to false.
883 	 * This will prevent us being continuously being called on error.
884 	 */
885 	adb->grownames_sent = false;
886 	goto done;
887 
888 cleanup:
889 	if (newnames != NULL) {
890 		isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n);
891 	}
892 	if (newdeadnames != NULL) {
893 		isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n);
894 	}
895 	if (newnamelocks != NULL) {
896 		isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n);
897 	}
898 	if (newname_sd != NULL) {
899 		isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n);
900 	}
901 	if (newname_refcnt != NULL) {
902 		isc_mem_put(adb->mctx, newname_refcnt,
903 			    sizeof(*newname_refcnt) * n);
904 	}
905 done:
906 	isc_task_endexclusive(task);
907 
908 check_exit:
909 	LOCK(&adb->lock);
910 	if (dec_adb_irefcnt(adb)) {
911 		check_exit(adb);
912 	}
913 	UNLOCK(&adb->lock);
914 	DP(ISC_LOG_INFO, "adb: grow_names finished");
915 }
916 
917 /*
918  * Requires the adbname bucket be locked and that no entry buckets be locked.
919  *
920  * This code handles A and AAAA rdatasets only.
921  */
922 static isc_result_t
923 import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
924 		isc_stdtime_t now) {
925 	isc_result_t result;
926 	dns_adb_t *adb;
927 	dns_adbnamehook_t *nh;
928 	dns_adbnamehook_t *anh;
929 	dns_rdata_t rdata = DNS_RDATA_INIT;
930 	struct in_addr ina;
931 	struct in6_addr in6a;
932 	isc_sockaddr_t sockaddr;
933 	dns_adbentry_t *foundentry; /* NO CLEAN UP! */
934 	int addr_bucket;
935 	bool new_addresses_added;
936 	dns_rdatatype_t rdtype;
937 	unsigned int findoptions;
938 	dns_adbnamehooklist_t *hookhead;
939 
940 	INSIST(DNS_ADBNAME_VALID(adbname));
941 	adb = adbname->adb;
942 	INSIST(DNS_ADB_VALID(adb));
943 
944 	rdtype = rdataset->type;
945 	INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
946 	if (rdtype == dns_rdatatype_a) {
947 		findoptions = DNS_ADBFIND_INET;
948 	} else {
949 		findoptions = DNS_ADBFIND_INET6;
950 	}
951 
952 	addr_bucket = DNS_ADB_INVALIDBUCKET;
953 	new_addresses_added = false;
954 
955 	nh = NULL;
956 	result = dns_rdataset_first(rdataset);
957 	while (result == ISC_R_SUCCESS) {
958 		dns_rdata_reset(&rdata);
959 		dns_rdataset_current(rdataset, &rdata);
960 		if (rdtype == dns_rdatatype_a) {
961 			INSIST(rdata.length == 4);
962 			memmove(&ina.s_addr, rdata.data, 4);
963 			isc_sockaddr_fromin(&sockaddr, &ina, 0);
964 			hookhead = &adbname->v4;
965 		} else {
966 			INSIST(rdata.length == 16);
967 			memmove(in6a.s6_addr, rdata.data, 16);
968 			isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
969 			hookhead = &adbname->v6;
970 		}
971 
972 		INSIST(nh == NULL);
973 		nh = new_adbnamehook(adb, NULL);
974 		if (nh == NULL) {
975 			adbname->partial_result |= findoptions;
976 			result = ISC_R_NOMEMORY;
977 			goto fail;
978 		}
979 
980 		foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket,
981 						 now);
982 		if (foundentry == NULL) {
983 			dns_adbentry_t *entry;
984 
985 			entry = new_adbentry(adb);
986 			if (entry == NULL) {
987 				adbname->partial_result |= findoptions;
988 				result = ISC_R_NOMEMORY;
989 				goto fail;
990 			}
991 
992 			entry->sockaddr = sockaddr;
993 			entry->refcnt = 1;
994 			entry->nh = 1;
995 
996 			nh->entry = entry;
997 
998 			link_entry(adb, addr_bucket, entry);
999 		} else {
1000 			for (anh = ISC_LIST_HEAD(*hookhead); anh != NULL;
1001 			     anh = ISC_LIST_NEXT(anh, plink))
1002 			{
1003 				if (anh->entry == foundentry) {
1004 					break;
1005 				}
1006 			}
1007 			if (anh == NULL) {
1008 				foundentry->refcnt++;
1009 				foundentry->nh++;
1010 				nh->entry = foundentry;
1011 			} else {
1012 				free_adbnamehook(adb, &nh);
1013 			}
1014 		}
1015 
1016 		new_addresses_added = true;
1017 		if (nh != NULL) {
1018 			ISC_LIST_APPEND(*hookhead, nh, plink);
1019 		}
1020 		nh = NULL;
1021 		result = dns_rdataset_next(rdataset);
1022 	}
1023 
1024 fail:
1025 	if (nh != NULL) {
1026 		free_adbnamehook(adb, &nh);
1027 	}
1028 
1029 	if (addr_bucket != DNS_ADB_INVALIDBUCKET) {
1030 		UNLOCK(&adb->entrylocks[addr_bucket]);
1031 	}
1032 
1033 	if (rdataset->trust == dns_trust_glue ||
1034 	    rdataset->trust == dns_trust_additional)
1035 	{
1036 		rdataset->ttl = ADB_CACHE_MINIMUM;
1037 	} else if (rdataset->trust == dns_trust_ultimate) {
1038 		rdataset->ttl = 0;
1039 	} else {
1040 		rdataset->ttl = ttlclamp(rdataset->ttl);
1041 	}
1042 
1043 	if (rdtype == dns_rdatatype_a) {
1044 		DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
1045 		   adbname->expire_v4, now + rdataset->ttl);
1046 		adbname->expire_v4 = ISC_MIN(
1047 			adbname->expire_v4,
1048 			ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
1049 	} else {
1050 		DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
1051 		   adbname->expire_v6, now + rdataset->ttl);
1052 		adbname->expire_v6 = ISC_MIN(
1053 			adbname->expire_v6,
1054 			ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
1055 	}
1056 
1057 	if (new_addresses_added) {
1058 		/*
1059 		 * Lie a little here.  This is more or less so code that cares
1060 		 * can find out if any new information was added or not.
1061 		 */
1062 		return (ISC_R_SUCCESS);
1063 	}
1064 
1065 	return (result);
1066 }
1067 
1068 /*
1069  * Requires the name's bucket be locked.
1070  */
1071 static bool
1072 kill_name(dns_adbname_t **n, isc_eventtype_t ev) {
1073 	dns_adbname_t *name;
1074 	bool result = false;
1075 	bool result4, result6;
1076 	int bucket;
1077 	dns_adb_t *adb;
1078 
1079 	INSIST(n != NULL);
1080 	name = *n;
1081 	*n = NULL;
1082 	INSIST(DNS_ADBNAME_VALID(name));
1083 	adb = name->adb;
1084 	INSIST(DNS_ADB_VALID(adb));
1085 
1086 	DP(DEF_LEVEL, "killing name %p", name);
1087 
1088 	/*
1089 	 * If we're dead already, just check to see if we should go
1090 	 * away now or not.
1091 	 */
1092 	if (NAME_DEAD(name) && !NAME_FETCH(name)) {
1093 		result = unlink_name(adb, name);
1094 		free_adbname(adb, &name);
1095 		if (result) {
1096 			result = dec_adb_irefcnt(adb);
1097 		}
1098 		return (result);
1099 	}
1100 
1101 	/*
1102 	 * Clean up the name's various lists.  These two are destructive
1103 	 * in that they will always empty the list.
1104 	 */
1105 	clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
1106 	result4 = clean_namehooks(adb, &name->v4);
1107 	result6 = clean_namehooks(adb, &name->v6);
1108 	clean_target(adb, &name->target);
1109 	result = (result4 || result6);
1110 
1111 	/*
1112 	 * If fetches are running, cancel them.  If none are running, we can
1113 	 * just kill the name here.
1114 	 */
1115 	if (!NAME_FETCH(name)) {
1116 		INSIST(result == false);
1117 		result = unlink_name(adb, name);
1118 		free_adbname(adb, &name);
1119 		if (result) {
1120 			result = dec_adb_irefcnt(adb);
1121 		}
1122 	} else {
1123 		cancel_fetches_at_name(name);
1124 		if (!NAME_DEAD(name)) {
1125 			bucket = name->lock_bucket;
1126 			ISC_LIST_UNLINK(adb->names[bucket], name, plink);
1127 			ISC_LIST_APPEND(adb->deadnames[bucket], name, plink);
1128 			name->flags |= NAME_IS_DEAD;
1129 		}
1130 	}
1131 	return (result);
1132 }
1133 
1134 /*
1135  * Requires the name's bucket be locked and no entry buckets be locked.
1136  */
1137 static bool
1138 check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
1139 	dns_adb_t *adb;
1140 	bool result4 = false;
1141 	bool result6 = false;
1142 
1143 	INSIST(DNS_ADBNAME_VALID(name));
1144 	adb = name->adb;
1145 	INSIST(DNS_ADB_VALID(adb));
1146 
1147 	/*
1148 	 * Check to see if we need to remove the v4 addresses
1149 	 */
1150 	if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) {
1151 		if (NAME_HAS_V4(name)) {
1152 			DP(DEF_LEVEL, "expiring v4 for name %p", name);
1153 			result4 = clean_namehooks(adb, &name->v4);
1154 			name->partial_result &= ~DNS_ADBFIND_INET;
1155 		}
1156 		name->expire_v4 = INT_MAX;
1157 		name->fetch_err = FIND_ERR_UNEXPECTED;
1158 	}
1159 
1160 	/*
1161 	 * Check to see if we need to remove the v6 addresses
1162 	 */
1163 	if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) {
1164 		if (NAME_HAS_V6(name)) {
1165 			DP(DEF_LEVEL, "expiring v6 for name %p", name);
1166 			result6 = clean_namehooks(adb, &name->v6);
1167 			name->partial_result &= ~DNS_ADBFIND_INET6;
1168 		}
1169 		name->expire_v6 = INT_MAX;
1170 		name->fetch6_err = FIND_ERR_UNEXPECTED;
1171 	}
1172 
1173 	/*
1174 	 * Check to see if we need to remove the alias target.
1175 	 */
1176 	if (EXPIRE_OK(name->expire_target, now)) {
1177 		clean_target(adb, &name->target);
1178 		name->expire_target = INT_MAX;
1179 	}
1180 	return (result4 || result6);
1181 }
1182 
1183 /*
1184  * Requires the name's bucket be locked.
1185  */
1186 static inline void
1187 link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
1188 	INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
1189 
1190 	ISC_LIST_PREPEND(adb->names[bucket], name, plink);
1191 	name->lock_bucket = bucket;
1192 	adb->name_refcnt[bucket]++;
1193 }
1194 
1195 /*
1196  * Requires the name's bucket be locked.
1197  */
1198 static inline bool
1199 unlink_name(dns_adb_t *adb, dns_adbname_t *name) {
1200 	int bucket;
1201 	bool result = false;
1202 
1203 	bucket = name->lock_bucket;
1204 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
1205 
1206 	if (NAME_DEAD(name)) {
1207 		ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink);
1208 	} else {
1209 		ISC_LIST_UNLINK(adb->names[bucket], name, plink);
1210 	}
1211 	name->lock_bucket = DNS_ADB_INVALIDBUCKET;
1212 	INSIST(adb->name_refcnt[bucket] > 0);
1213 	adb->name_refcnt[bucket]--;
1214 	if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0) {
1215 		result = true;
1216 	}
1217 	return (result);
1218 }
1219 
1220 /*
1221  * Requires the entry's bucket be locked.
1222  */
1223 static inline void
1224 link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
1225 	int i;
1226 	dns_adbentry_t *e;
1227 
1228 	if (isc_mem_isovermem(adb->mctx)) {
1229 		for (i = 0; i < 2; i++) {
1230 			e = ISC_LIST_TAIL(adb->entries[bucket]);
1231 			if (e == NULL) {
1232 				break;
1233 			}
1234 			if (e->refcnt == 0) {
1235 				unlink_entry(adb, e);
1236 				free_adbentry(adb, &e);
1237 				continue;
1238 			}
1239 			INSIST((e->flags & ENTRY_IS_DEAD) == 0);
1240 			e->flags |= ENTRY_IS_DEAD;
1241 			ISC_LIST_UNLINK(adb->entries[bucket], e, plink);
1242 			ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink);
1243 		}
1244 	}
1245 
1246 	ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
1247 	entry->lock_bucket = bucket;
1248 	adb->entry_refcnt[bucket]++;
1249 }
1250 
1251 /*
1252  * Requires the entry's bucket be locked.
1253  */
1254 static inline bool
1255 unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
1256 	int bucket;
1257 	bool result = false;
1258 
1259 	bucket = entry->lock_bucket;
1260 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
1261 
1262 	if ((entry->flags & ENTRY_IS_DEAD) != 0) {
1263 		ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink);
1264 	} else {
1265 		ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
1266 	}
1267 	entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
1268 	INSIST(adb->entry_refcnt[bucket] > 0);
1269 	adb->entry_refcnt[bucket]--;
1270 	if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0) {
1271 		result = true;
1272 	}
1273 	return (result);
1274 }
1275 
1276 static inline void
1277 violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
1278 	if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
1279 		UNLOCK(have);
1280 		LOCK(want);
1281 		LOCK(have);
1282 	}
1283 }
1284 
1285 /*
1286  * The ADB _MUST_ be locked before calling.  Also, exit conditions must be
1287  * checked after calling this function.
1288  */
1289 static bool
1290 shutdown_names(dns_adb_t *adb) {
1291 	unsigned int bucket;
1292 	bool result = false;
1293 	dns_adbname_t *name;
1294 	dns_adbname_t *next_name;
1295 
1296 	for (bucket = 0; bucket < adb->nnames; bucket++) {
1297 		LOCK(&adb->namelocks[bucket]);
1298 		adb->name_sd[bucket] = true;
1299 
1300 		name = ISC_LIST_HEAD(adb->names[bucket]);
1301 		if (name == NULL) {
1302 			/*
1303 			 * This bucket has no names.  We must decrement the
1304 			 * irefcnt ourselves, since it will not be
1305 			 * automatically triggered by a name being unlinked.
1306 			 */
1307 			INSIST(result == false);
1308 			result = dec_adb_irefcnt(adb);
1309 		} else {
1310 			/*
1311 			 * Run through the list.  For each name, clean up finds
1312 			 * found there, and cancel any fetches running.  When
1313 			 * all the fetches are canceled, the name will destroy
1314 			 * itself.
1315 			 */
1316 			while (name != NULL) {
1317 				next_name = ISC_LIST_NEXT(name, plink);
1318 				INSIST(result == false);
1319 				result = kill_name(&name,
1320 						   DNS_EVENT_ADBSHUTDOWN);
1321 				name = next_name;
1322 			}
1323 		}
1324 
1325 		UNLOCK(&adb->namelocks[bucket]);
1326 	}
1327 	return (result);
1328 }
1329 
1330 /*
1331  * The ADB _MUST_ be locked before calling.  Also, exit conditions must be
1332  * checked after calling this function.
1333  */
1334 static bool
1335 shutdown_entries(dns_adb_t *adb) {
1336 	unsigned int bucket;
1337 	bool result = false;
1338 	dns_adbentry_t *entry;
1339 	dns_adbentry_t *next_entry;
1340 
1341 	for (bucket = 0; bucket < adb->nentries; bucket++) {
1342 		LOCK(&adb->entrylocks[bucket]);
1343 		adb->entry_sd[bucket] = true;
1344 
1345 		entry = ISC_LIST_HEAD(adb->entries[bucket]);
1346 		if (adb->entry_refcnt[bucket] == 0) {
1347 			/*
1348 			 * This bucket has no entries.  We must decrement the
1349 			 * irefcnt ourselves, since it will not be
1350 			 * automatically triggered by an entry being unlinked.
1351 			 */
1352 			result = dec_adb_irefcnt(adb);
1353 		} else {
1354 			/*
1355 			 * Run through the list.  Cleanup any entries not
1356 			 * associated with names, and which are not in use.
1357 			 */
1358 			while (entry != NULL) {
1359 				next_entry = ISC_LIST_NEXT(entry, plink);
1360 				if (entry->refcnt == 0 && entry->expires != 0) {
1361 					result = unlink_entry(adb, entry);
1362 					free_adbentry(adb, &entry);
1363 					if (result) {
1364 						result = dec_adb_irefcnt(adb);
1365 					}
1366 				}
1367 				entry = next_entry;
1368 			}
1369 		}
1370 
1371 		UNLOCK(&adb->entrylocks[bucket]);
1372 	}
1373 	return (result);
1374 }
1375 
1376 /*
1377  * Name bucket must be locked
1378  */
1379 static void
1380 cancel_fetches_at_name(dns_adbname_t *name) {
1381 	if (NAME_FETCH_A(name)) {
1382 		dns_resolver_cancelfetch(name->fetch_a->fetch);
1383 	}
1384 
1385 	if (NAME_FETCH_AAAA(name)) {
1386 		dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
1387 	}
1388 }
1389 
1390 /*
1391  * Assumes the name bucket is locked.
1392  */
1393 static bool
1394 clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
1395 	dns_adbentry_t *entry;
1396 	dns_adbnamehook_t *namehook;
1397 	int addr_bucket;
1398 	bool result = false;
1399 	bool overmem = isc_mem_isovermem(adb->mctx);
1400 
1401 	addr_bucket = DNS_ADB_INVALIDBUCKET;
1402 	namehook = ISC_LIST_HEAD(*namehooks);
1403 	while (namehook != NULL) {
1404 		INSIST(DNS_ADBNAMEHOOK_VALID(namehook));
1405 
1406 		/*
1407 		 * Clean up the entry if needed.
1408 		 */
1409 		entry = namehook->entry;
1410 		if (entry != NULL) {
1411 			INSIST(DNS_ADBENTRY_VALID(entry));
1412 
1413 			if (addr_bucket != entry->lock_bucket) {
1414 				if (addr_bucket != DNS_ADB_INVALIDBUCKET) {
1415 					UNLOCK(&adb->entrylocks[addr_bucket]);
1416 				}
1417 				addr_bucket = entry->lock_bucket;
1418 				INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET);
1419 				LOCK(&adb->entrylocks[addr_bucket]);
1420 			}
1421 
1422 			entry->nh--;
1423 			result = dec_entry_refcnt(adb, overmem, entry, false);
1424 		}
1425 
1426 		/*
1427 		 * Free the namehook
1428 		 */
1429 		namehook->entry = NULL;
1430 		ISC_LIST_UNLINK(*namehooks, namehook, plink);
1431 		free_adbnamehook(adb, &namehook);
1432 
1433 		namehook = ISC_LIST_HEAD(*namehooks);
1434 	}
1435 
1436 	if (addr_bucket != DNS_ADB_INVALIDBUCKET) {
1437 		UNLOCK(&adb->entrylocks[addr_bucket]);
1438 	}
1439 	return (result);
1440 }
1441 
1442 static void
1443 clean_target(dns_adb_t *adb, dns_name_t *target) {
1444 	if (dns_name_countlabels(target) > 0) {
1445 		dns_name_free(target, adb->mctx);
1446 		dns_name_init(target, NULL);
1447 	}
1448 }
1449 
1450 static isc_result_t
1451 set_target(dns_adb_t *adb, const dns_name_t *name, const dns_name_t *fname,
1452 	   dns_rdataset_t *rdataset, dns_name_t *target) {
1453 	isc_result_t result;
1454 	dns_namereln_t namereln;
1455 	unsigned int nlabels;
1456 	int order;
1457 	dns_rdata_t rdata = DNS_RDATA_INIT;
1458 	dns_fixedname_t fixed1, fixed2;
1459 	dns_name_t *prefix, *new_target;
1460 
1461 	REQUIRE(dns_name_countlabels(target) == 0);
1462 
1463 	if (rdataset->type == dns_rdatatype_cname) {
1464 		dns_rdata_cname_t cname;
1465 
1466 		/*
1467 		 * Copy the CNAME's target into the target name.
1468 		 */
1469 		result = dns_rdataset_first(rdataset);
1470 		if (result != ISC_R_SUCCESS) {
1471 			return (result);
1472 		}
1473 		dns_rdataset_current(rdataset, &rdata);
1474 		result = dns_rdata_tostruct(&rdata, &cname, NULL);
1475 		if (result != ISC_R_SUCCESS) {
1476 			return (result);
1477 		}
1478 		dns_name_dup(&cname.cname, adb->mctx, target);
1479 		dns_rdata_freestruct(&cname);
1480 	} else {
1481 		dns_rdata_dname_t dname;
1482 
1483 		INSIST(rdataset->type == dns_rdatatype_dname);
1484 		namereln = dns_name_fullcompare(name, fname, &order, &nlabels);
1485 		INSIST(namereln == dns_namereln_subdomain);
1486 		/*
1487 		 * Get the target name of the DNAME.
1488 		 */
1489 		result = dns_rdataset_first(rdataset);
1490 		if (result != ISC_R_SUCCESS) {
1491 			return (result);
1492 		}
1493 		dns_rdataset_current(rdataset, &rdata);
1494 		result = dns_rdata_tostruct(&rdata, &dname, NULL);
1495 		if (result != ISC_R_SUCCESS) {
1496 			return (result);
1497 		}
1498 		/*
1499 		 * Construct the new target name.
1500 		 */
1501 		prefix = dns_fixedname_initname(&fixed1);
1502 		new_target = dns_fixedname_initname(&fixed2);
1503 		dns_name_split(name, nlabels, prefix, NULL);
1504 		result = dns_name_concatenate(prefix, &dname.dname, new_target,
1505 					      NULL);
1506 		dns_rdata_freestruct(&dname);
1507 		if (result != ISC_R_SUCCESS) {
1508 			return (result);
1509 		}
1510 		dns_name_dup(new_target, adb->mctx, target);
1511 	}
1512 
1513 	return (ISC_R_SUCCESS);
1514 }
1515 
1516 /*
1517  * Assumes nothing is locked, since this is called by the client.
1518  */
1519 static void
1520 event_free(isc_event_t *event) {
1521 	dns_adbfind_t *find;
1522 
1523 	INSIST(event != NULL);
1524 	find = event->ev_destroy_arg;
1525 	INSIST(DNS_ADBFIND_VALID(find));
1526 
1527 	LOCK(&find->lock);
1528 	find->flags |= FIND_EVENT_FREED;
1529 	event->ev_destroy_arg = NULL;
1530 	UNLOCK(&find->lock);
1531 }
1532 
1533 /*
1534  * Assumes the name bucket is locked.
1535  */
1536 static void
1537 clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
1538 		    unsigned int addrs) {
1539 	isc_event_t *ev;
1540 	isc_task_t *task;
1541 	dns_adbfind_t *find;
1542 	dns_adbfind_t *next_find;
1543 	bool process;
1544 	unsigned int wanted, notify;
1545 
1546 	DP(ENTER_LEVEL,
1547 	   "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x", name,
1548 	   evtype, addrs);
1549 
1550 	find = ISC_LIST_HEAD(name->finds);
1551 	while (find != NULL) {
1552 		LOCK(&find->lock);
1553 		next_find = ISC_LIST_NEXT(find, plink);
1554 
1555 		process = false;
1556 		wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
1557 		notify = wanted & addrs;
1558 
1559 		switch (evtype) {
1560 		case DNS_EVENT_ADBMOREADDRESSES:
1561 			DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
1562 			if ((notify) != 0) {
1563 				find->flags &= ~addrs;
1564 				process = true;
1565 			}
1566 			break;
1567 		case DNS_EVENT_ADBNOMOREADDRESSES:
1568 			DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
1569 			find->flags &= ~addrs;
1570 			wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
1571 			if (wanted == 0) {
1572 				process = true;
1573 			}
1574 			break;
1575 		default:
1576 			find->flags &= ~addrs;
1577 			process = true;
1578 		}
1579 
1580 		if (process) {
1581 			DP(DEF_LEVEL, "cfan: processing find %p", find);
1582 			/*
1583 			 * Unlink the find from the name, letting the caller
1584 			 * call dns_adb_destroyfind() on it to clean it up
1585 			 * later.
1586 			 */
1587 			ISC_LIST_UNLINK(name->finds, find, plink);
1588 			find->adbname = NULL;
1589 			find->name_bucket = DNS_ADB_INVALIDBUCKET;
1590 
1591 			INSIST(!FIND_EVENTSENT(find));
1592 
1593 			ev = &find->event;
1594 			task = ev->ev_sender;
1595 			ev->ev_sender = find;
1596 			find->result_v4 = find_err_map[name->fetch_err];
1597 			find->result_v6 = find_err_map[name->fetch6_err];
1598 			ev->ev_type = evtype;
1599 			ev->ev_destroy = event_free;
1600 			ev->ev_destroy_arg = find;
1601 
1602 			DP(DEF_LEVEL, "sending event %p to task %p for find %p",
1603 			   ev, task, find);
1604 
1605 			isc_task_sendanddetach(&task, (isc_event_t **)&ev);
1606 			find->flags |= FIND_EVENT_SENT;
1607 		} else {
1608 			DP(DEF_LEVEL, "cfan: skipping find %p", find);
1609 		}
1610 
1611 		UNLOCK(&find->lock);
1612 		find = next_find;
1613 	}
1614 	DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
1615 }
1616 
1617 static inline void
1618 check_exit(dns_adb_t *adb) {
1619 	isc_event_t *event;
1620 	/*
1621 	 * The caller must be holding the adb lock.
1622 	 */
1623 	if (adb->shutting_down) {
1624 		/*
1625 		 * If there aren't any external references either, we're
1626 		 * done.  Send the control event to initiate shutdown.
1627 		 */
1628 		INSIST(!adb->cevent_out); /* Sanity check. */
1629 		ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
1630 			       DNS_EVENT_ADBCONTROL, shutdown_task, adb, adb,
1631 			       NULL, NULL);
1632 		event = &adb->cevent;
1633 		isc_task_send(adb->task, &event);
1634 		adb->cevent_out = true;
1635 	}
1636 }
1637 
1638 static inline bool
1639 dec_adb_irefcnt(dns_adb_t *adb) {
1640 	isc_event_t *event;
1641 	isc_task_t *etask;
1642 	bool result = false;
1643 
1644 	LOCK(&adb->reflock);
1645 
1646 	INSIST(adb->irefcnt > 0);
1647 	adb->irefcnt--;
1648 
1649 	if (adb->irefcnt == 0) {
1650 		event = ISC_LIST_HEAD(adb->whenshutdown);
1651 		while (event != NULL) {
1652 			ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
1653 			etask = event->ev_sender;
1654 			event->ev_sender = adb;
1655 			isc_task_sendanddetach(&etask, &event);
1656 			event = ISC_LIST_HEAD(adb->whenshutdown);
1657 		}
1658 	}
1659 
1660 	if (adb->irefcnt == 0 && adb->erefcnt == 0) {
1661 		result = true;
1662 	}
1663 	UNLOCK(&adb->reflock);
1664 	return (result);
1665 }
1666 
1667 static inline void
1668 inc_adb_irefcnt(dns_adb_t *adb) {
1669 	LOCK(&adb->reflock);
1670 	adb->irefcnt++;
1671 	UNLOCK(&adb->reflock);
1672 }
1673 
1674 static inline void
1675 inc_adb_erefcnt(dns_adb_t *adb) {
1676 	LOCK(&adb->reflock);
1677 	adb->erefcnt++;
1678 	UNLOCK(&adb->reflock);
1679 }
1680 
1681 static inline void
1682 inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, bool lock) {
1683 	int bucket;
1684 
1685 	bucket = entry->lock_bucket;
1686 
1687 	if (lock) {
1688 		LOCK(&adb->entrylocks[bucket]);
1689 	}
1690 
1691 	entry->refcnt++;
1692 
1693 	if (lock) {
1694 		UNLOCK(&adb->entrylocks[bucket]);
1695 	}
1696 }
1697 
1698 static inline bool
1699 dec_entry_refcnt(dns_adb_t *adb, bool overmem, dns_adbentry_t *entry,
1700 		 bool lock) {
1701 	int bucket;
1702 	bool destroy_entry;
1703 	bool result = false;
1704 
1705 	bucket = entry->lock_bucket;
1706 
1707 	if (lock) {
1708 		LOCK(&adb->entrylocks[bucket]);
1709 	}
1710 
1711 	INSIST(entry->refcnt > 0);
1712 	entry->refcnt--;
1713 
1714 	destroy_entry = false;
1715 	if (entry->refcnt == 0 &&
1716 	    (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
1717 	     (entry->flags & ENTRY_IS_DEAD) != 0))
1718 	{
1719 		destroy_entry = true;
1720 		result = unlink_entry(adb, entry);
1721 	}
1722 
1723 	if (lock) {
1724 		UNLOCK(&adb->entrylocks[bucket]);
1725 	}
1726 
1727 	if (!destroy_entry) {
1728 		return (result);
1729 	}
1730 
1731 	entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
1732 
1733 	free_adbentry(adb, &entry);
1734 	if (result) {
1735 		result = dec_adb_irefcnt(adb);
1736 	}
1737 
1738 	return (result);
1739 }
1740 
1741 static inline dns_adbname_t *
1742 new_adbname(dns_adb_t *adb, const dns_name_t *dnsname) {
1743 	dns_adbname_t *name;
1744 
1745 	name = isc_mempool_get(adb->nmp);
1746 	if (name == NULL) {
1747 		return (NULL);
1748 	}
1749 
1750 	dns_name_init(&name->name, NULL);
1751 	dns_name_dup(dnsname, adb->mctx, &name->name);
1752 	dns_name_init(&name->target, NULL);
1753 	name->magic = DNS_ADBNAME_MAGIC;
1754 	name->adb = adb;
1755 	name->partial_result = 0;
1756 	name->flags = 0;
1757 	name->expire_v4 = INT_MAX;
1758 	name->expire_v6 = INT_MAX;
1759 	name->expire_target = INT_MAX;
1760 	name->chains = 0;
1761 	name->lock_bucket = DNS_ADB_INVALIDBUCKET;
1762 	ISC_LIST_INIT(name->v4);
1763 	ISC_LIST_INIT(name->v6);
1764 	name->fetch_a = NULL;
1765 	name->fetch_aaaa = NULL;
1766 	name->fetch_err = FIND_ERR_UNEXPECTED;
1767 	name->fetch6_err = FIND_ERR_UNEXPECTED;
1768 	ISC_LIST_INIT(name->finds);
1769 	ISC_LINK_INIT(name, plink);
1770 
1771 	LOCK(&adb->namescntlock);
1772 	adb->namescnt++;
1773 	inc_adbstats(adb, dns_adbstats_namescnt);
1774 	if (!adb->grownames_sent && adb->excl != NULL &&
1775 	    adb->namescnt > (adb->nnames * 8))
1776 	{
1777 		isc_event_t *event = &adb->grownames;
1778 		inc_adb_irefcnt(adb);
1779 		isc_task_send(adb->excl, &event);
1780 		adb->grownames_sent = true;
1781 	}
1782 	UNLOCK(&adb->namescntlock);
1783 
1784 	return (name);
1785 }
1786 
1787 static inline void
1788 free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
1789 	dns_adbname_t *n;
1790 
1791 	INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
1792 	n = *name;
1793 	*name = NULL;
1794 
1795 	INSIST(!NAME_HAS_V4(n));
1796 	INSIST(!NAME_HAS_V6(n));
1797 	INSIST(!NAME_FETCH(n));
1798 	INSIST(ISC_LIST_EMPTY(n->finds));
1799 	INSIST(!ISC_LINK_LINKED(n, plink));
1800 	INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
1801 	INSIST(n->adb == adb);
1802 
1803 	n->magic = 0;
1804 	dns_name_free(&n->name, adb->mctx);
1805 
1806 	isc_mempool_put(adb->nmp, n);
1807 	LOCK(&adb->namescntlock);
1808 	adb->namescnt--;
1809 	dec_adbstats(adb, dns_adbstats_namescnt);
1810 	UNLOCK(&adb->namescntlock);
1811 }
1812 
1813 static inline dns_adbnamehook_t *
1814 new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
1815 	dns_adbnamehook_t *nh;
1816 
1817 	nh = isc_mempool_get(adb->nhmp);
1818 	if (nh == NULL) {
1819 		return (NULL);
1820 	}
1821 
1822 	nh->magic = DNS_ADBNAMEHOOK_MAGIC;
1823 	nh->entry = entry;
1824 	ISC_LINK_INIT(nh, plink);
1825 
1826 	return (nh);
1827 }
1828 
1829 static inline void
1830 free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
1831 	dns_adbnamehook_t *nh;
1832 
1833 	INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
1834 	nh = *namehook;
1835 	*namehook = NULL;
1836 
1837 	INSIST(nh->entry == NULL);
1838 	INSIST(!ISC_LINK_LINKED(nh, plink));
1839 
1840 	nh->magic = 0;
1841 	isc_mempool_put(adb->nhmp, nh);
1842 }
1843 
1844 static inline dns_adblameinfo_t *
1845 new_adblameinfo(dns_adb_t *adb, const dns_name_t *qname,
1846 		dns_rdatatype_t qtype) {
1847 	dns_adblameinfo_t *li;
1848 
1849 	li = isc_mempool_get(adb->limp);
1850 	if (li == NULL) {
1851 		return (NULL);
1852 	}
1853 
1854 	dns_name_init(&li->qname, NULL);
1855 	dns_name_dup(qname, adb->mctx, &li->qname);
1856 	li->magic = DNS_ADBLAMEINFO_MAGIC;
1857 	li->lame_timer = 0;
1858 	li->qtype = qtype;
1859 	ISC_LINK_INIT(li, plink);
1860 
1861 	return (li);
1862 }
1863 
1864 static inline void
1865 free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
1866 	dns_adblameinfo_t *li;
1867 
1868 	INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
1869 	li = *lameinfo;
1870 	*lameinfo = NULL;
1871 
1872 	INSIST(!ISC_LINK_LINKED(li, plink));
1873 
1874 	dns_name_free(&li->qname, adb->mctx);
1875 
1876 	li->magic = 0;
1877 
1878 	isc_mempool_put(adb->limp, li);
1879 }
1880 
1881 static inline dns_adbentry_t *
1882 new_adbentry(dns_adb_t *adb) {
1883 	dns_adbentry_t *e;
1884 
1885 	e = isc_mempool_get(adb->emp);
1886 	if (e == NULL) {
1887 		return (NULL);
1888 	}
1889 
1890 	e->magic = DNS_ADBENTRY_MAGIC;
1891 	e->lock_bucket = DNS_ADB_INVALIDBUCKET;
1892 	e->refcnt = 0;
1893 	e->nh = 0;
1894 	e->flags = 0;
1895 	e->udpsize = 0;
1896 	e->edns = 0;
1897 	e->completed = 0;
1898 	e->timeouts = 0;
1899 	e->plain = 0;
1900 	e->plainto = 0;
1901 	e->to4096 = 0;
1902 	e->to1432 = 0;
1903 	e->to1232 = 0;
1904 	e->to512 = 0;
1905 	e->cookie = NULL;
1906 	e->cookielen = 0;
1907 	e->srtt = (isc_random_uniform(0x1f)) + 1;
1908 	e->lastage = 0;
1909 	e->expires = 0;
1910 	atomic_init(&e->active, 0);
1911 	e->mode = 0;
1912 	atomic_init(&e->quota, adb->quota);
1913 	e->atr = 0.0;
1914 	ISC_LIST_INIT(e->lameinfo);
1915 	ISC_LINK_INIT(e, plink);
1916 	LOCK(&adb->entriescntlock);
1917 	adb->entriescnt++;
1918 	inc_adbstats(adb, dns_adbstats_entriescnt);
1919 	if (!adb->growentries_sent && adb->excl != NULL &&
1920 	    adb->entriescnt > (adb->nentries * 8))
1921 	{
1922 		isc_event_t *event = &adb->growentries;
1923 		inc_adb_irefcnt(adb);
1924 		isc_task_send(adb->excl, &event);
1925 		adb->growentries_sent = true;
1926 	}
1927 	UNLOCK(&adb->entriescntlock);
1928 
1929 	return (e);
1930 }
1931 
1932 static inline void
1933 free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
1934 	dns_adbentry_t *e;
1935 	dns_adblameinfo_t *li;
1936 
1937 	INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
1938 	e = *entry;
1939 	*entry = NULL;
1940 
1941 	INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);
1942 	INSIST(e->refcnt == 0);
1943 	INSIST(!ISC_LINK_LINKED(e, plink));
1944 
1945 	e->magic = 0;
1946 
1947 	if (e->cookie != NULL) {
1948 		isc_mem_put(adb->mctx, e->cookie, e->cookielen);
1949 	}
1950 
1951 	li = ISC_LIST_HEAD(e->lameinfo);
1952 	while (li != NULL) {
1953 		ISC_LIST_UNLINK(e->lameinfo, li, plink);
1954 		free_adblameinfo(adb, &li);
1955 		li = ISC_LIST_HEAD(e->lameinfo);
1956 	}
1957 
1958 	isc_mempool_put(adb->emp, e);
1959 	LOCK(&adb->entriescntlock);
1960 	adb->entriescnt--;
1961 	dec_adbstats(adb, dns_adbstats_entriescnt);
1962 	UNLOCK(&adb->entriescntlock);
1963 }
1964 
1965 static inline dns_adbfind_t *
1966 new_adbfind(dns_adb_t *adb) {
1967 	dns_adbfind_t *h;
1968 
1969 	h = isc_mempool_get(adb->ahmp);
1970 	if (h == NULL) {
1971 		return (NULL);
1972 	}
1973 
1974 	/*
1975 	 * Public members.
1976 	 */
1977 	h->magic = 0;
1978 	h->adb = adb;
1979 	h->partial_result = 0;
1980 	h->options = 0;
1981 	h->flags = 0;
1982 	h->result_v4 = ISC_R_UNEXPECTED;
1983 	h->result_v6 = ISC_R_UNEXPECTED;
1984 	ISC_LINK_INIT(h, publink);
1985 	ISC_LINK_INIT(h, plink);
1986 	ISC_LIST_INIT(h->list);
1987 	h->adbname = NULL;
1988 	h->name_bucket = DNS_ADB_INVALIDBUCKET;
1989 
1990 	/*
1991 	 * private members
1992 	 */
1993 	isc_mutex_init(&h->lock);
1994 
1995 	ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
1996 		       NULL, NULL, h);
1997 
1998 	inc_adb_irefcnt(adb);
1999 	h->magic = DNS_ADBFIND_MAGIC;
2000 	return (h);
2001 }
2002 
2003 static inline dns_adbfetch_t *
2004 new_adbfetch(dns_adb_t *adb) {
2005 	dns_adbfetch_t *f;
2006 
2007 	f = isc_mempool_get(adb->afmp);
2008 	if (f == NULL) {
2009 		return (NULL);
2010 	}
2011 
2012 	f->magic = 0;
2013 	f->fetch = NULL;
2014 
2015 	dns_rdataset_init(&f->rdataset);
2016 
2017 	f->magic = DNS_ADBFETCH_MAGIC;
2018 
2019 	return (f);
2020 }
2021 
2022 static inline void
2023 free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
2024 	dns_adbfetch_t *f;
2025 
2026 	INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
2027 	f = *fetch;
2028 	*fetch = NULL;
2029 
2030 	f->magic = 0;
2031 
2032 	if (dns_rdataset_isassociated(&f->rdataset)) {
2033 		dns_rdataset_disassociate(&f->rdataset);
2034 	}
2035 
2036 	isc_mempool_put(adb->afmp, f);
2037 }
2038 
2039 static inline bool
2040 free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
2041 	dns_adbfind_t *find;
2042 
2043 	INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
2044 	find = *findp;
2045 	*findp = NULL;
2046 
2047 	INSIST(!FIND_HAS_ADDRS(find));
2048 	INSIST(!ISC_LINK_LINKED(find, publink));
2049 	INSIST(!ISC_LINK_LINKED(find, plink));
2050 	INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
2051 	INSIST(find->adbname == NULL);
2052 
2053 	find->magic = 0;
2054 
2055 	isc_mutex_destroy(&find->lock);
2056 	isc_mempool_put(adb->ahmp, find);
2057 	return (dec_adb_irefcnt(adb));
2058 }
2059 
2060 /*
2061  * Copy bits from the entry into the newly allocated addrinfo.  The entry
2062  * must be locked, and the reference count must be bumped up by one
2063  * if this function returns a valid pointer.
2064  */
2065 static inline dns_adbaddrinfo_t *
2066 new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
2067 	dns_adbaddrinfo_t *ai;
2068 
2069 	ai = isc_mempool_get(adb->aimp);
2070 	if (ai == NULL) {
2071 		return (NULL);
2072 	}
2073 
2074 	ai->magic = DNS_ADBADDRINFO_MAGIC;
2075 	ai->sockaddr = entry->sockaddr;
2076 	isc_sockaddr_setport(&ai->sockaddr, port);
2077 	ai->srtt = entry->srtt;
2078 	ai->flags = entry->flags;
2079 	ai->entry = entry;
2080 	ai->dscp = -1;
2081 	ISC_LINK_INIT(ai, publink);
2082 
2083 	return (ai);
2084 }
2085 
2086 static inline void
2087 free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
2088 	dns_adbaddrinfo_t *ai;
2089 
2090 	INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
2091 	ai = *ainfo;
2092 	*ainfo = NULL;
2093 
2094 	INSIST(ai->entry == NULL);
2095 	INSIST(!ISC_LINK_LINKED(ai, publink));
2096 
2097 	ai->magic = 0;
2098 
2099 	isc_mempool_put(adb->aimp, ai);
2100 }
2101 
2102 /*
2103  * Search for the name.  NOTE:  The bucket is kept locked on both
2104  * success and failure, so it must always be unlocked by the caller!
2105  *
2106  * On the first call to this function, *bucketp must be set to
2107  * DNS_ADB_INVALIDBUCKET.
2108  */
2109 static inline dns_adbname_t *
2110 find_name_and_lock(dns_adb_t *adb, const dns_name_t *name, unsigned int options,
2111 		   int *bucketp) {
2112 	dns_adbname_t *adbname;
2113 	int bucket;
2114 
2115 	bucket = dns_name_fullhash(name, false) % adb->nnames;
2116 
2117 	if (*bucketp == DNS_ADB_INVALIDBUCKET) {
2118 		LOCK(&adb->namelocks[bucket]);
2119 		*bucketp = bucket;
2120 	} else if (*bucketp != bucket) {
2121 		UNLOCK(&adb->namelocks[*bucketp]);
2122 		LOCK(&adb->namelocks[bucket]);
2123 		*bucketp = bucket;
2124 	}
2125 
2126 	adbname = ISC_LIST_HEAD(adb->names[bucket]);
2127 	while (adbname != NULL) {
2128 		if (!NAME_DEAD(adbname)) {
2129 			if (dns_name_equal(name, &adbname->name) &&
2130 			    GLUEHINT_OK(adbname, options) &&
2131 			    STARTATZONE_MATCHES(adbname, options))
2132 			{
2133 				return (adbname);
2134 			}
2135 		}
2136 		adbname = ISC_LIST_NEXT(adbname, plink);
2137 	}
2138 
2139 	return (NULL);
2140 }
2141 
2142 /*
2143  * Search for the address.  NOTE:  The bucket is kept locked on both
2144  * success and failure, so it must always be unlocked by the caller.
2145  *
2146  * On the first call to this function, *bucketp must be set to
2147  * DNS_ADB_INVALIDBUCKET.  This will cause a lock to occur.  On
2148  * later calls (within the same "lock path") it can be left alone, so
2149  * if this function is called multiple times locking is only done if
2150  * the bucket changes.
2151  */
2152 static inline dns_adbentry_t *
2153 find_entry_and_lock(dns_adb_t *adb, const isc_sockaddr_t *addr, int *bucketp,
2154 		    isc_stdtime_t now) {
2155 	dns_adbentry_t *entry, *entry_next;
2156 	int bucket;
2157 
2158 	bucket = isc_sockaddr_hash(addr, true) % adb->nentries;
2159 
2160 	if (*bucketp == DNS_ADB_INVALIDBUCKET) {
2161 		LOCK(&adb->entrylocks[bucket]);
2162 		*bucketp = bucket;
2163 	} else if (*bucketp != bucket) {
2164 		UNLOCK(&adb->entrylocks[*bucketp]);
2165 		LOCK(&adb->entrylocks[bucket]);
2166 		*bucketp = bucket;
2167 	}
2168 
2169 	/* Search the list, while cleaning up expired entries. */
2170 	for (entry = ISC_LIST_HEAD(adb->entries[bucket]); entry != NULL;
2171 	     entry = entry_next)
2172 	{
2173 		entry_next = ISC_LIST_NEXT(entry, plink);
2174 		(void)check_expire_entry(adb, &entry, now);
2175 		if (entry != NULL &&
2176 		    (entry->expires == 0 || entry->expires > now) &&
2177 		    isc_sockaddr_equal(addr, &entry->sockaddr))
2178 		{
2179 			ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
2180 			ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
2181 			return (entry);
2182 		}
2183 	}
2184 
2185 	return (NULL);
2186 }
2187 
2188 /*
2189  * Entry bucket MUST be locked!
2190  */
2191 static bool
2192 entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, const dns_name_t *qname,
2193 	      dns_rdatatype_t qtype, isc_stdtime_t now) {
2194 	dns_adblameinfo_t *li, *next_li;
2195 	bool is_bad;
2196 
2197 	is_bad = false;
2198 
2199 	li = ISC_LIST_HEAD(entry->lameinfo);
2200 	if (li == NULL) {
2201 		return (false);
2202 	}
2203 	while (li != NULL) {
2204 		next_li = ISC_LIST_NEXT(li, plink);
2205 
2206 		/*
2207 		 * Has the entry expired?
2208 		 */
2209 		if (li->lame_timer < now) {
2210 			ISC_LIST_UNLINK(entry->lameinfo, li, plink);
2211 			free_adblameinfo(adb, &li);
2212 		}
2213 
2214 		/*
2215 		 * Order tests from least to most expensive.
2216 		 *
2217 		 * We do not break out of the main loop here as
2218 		 * we use the loop for house keeping.
2219 		 */
2220 		if (li != NULL && !is_bad && li->qtype == qtype &&
2221 		    dns_name_equal(qname, &li->qname))
2222 		{
2223 			is_bad = true;
2224 		}
2225 
2226 		li = next_li;
2227 	}
2228 
2229 	return (is_bad);
2230 }
2231 
2232 static void
2233 log_quota(dns_adbentry_t *entry, const char *fmt, ...) {
2234 	va_list ap;
2235 	char msgbuf[2048];
2236 	char addrbuf[ISC_NETADDR_FORMATSIZE];
2237 	isc_netaddr_t netaddr;
2238 
2239 	va_start(ap, fmt);
2240 	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
2241 	va_end(ap);
2242 
2243 	isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
2244 	isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
2245 
2246 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
2247 		      ISC_LOG_INFO,
2248 		      "adb: quota %s (%" PRIuFAST32 "/%" PRIuFAST32 "): %s",
2249 		      addrbuf, atomic_load_relaxed(&entry->active),
2250 		      atomic_load_relaxed(&entry->quota), msgbuf);
2251 }
2252 
2253 static void
2254 copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find,
2255 		    const dns_name_t *qname, dns_rdatatype_t qtype,
2256 		    dns_adbname_t *name, isc_stdtime_t now) {
2257 	dns_adbnamehook_t *namehook;
2258 	dns_adbaddrinfo_t *addrinfo;
2259 	dns_adbentry_t *entry;
2260 	int bucket;
2261 
2262 	bucket = DNS_ADB_INVALIDBUCKET;
2263 
2264 	if ((find->options & DNS_ADBFIND_INET) != 0) {
2265 		namehook = ISC_LIST_HEAD(name->v4);
2266 		while (namehook != NULL) {
2267 			entry = namehook->entry;
2268 			bucket = entry->lock_bucket;
2269 			INSIST(bucket != DNS_ADB_INVALIDBUCKET);
2270 			LOCK(&adb->entrylocks[bucket]);
2271 
2272 			if (dns_adbentry_overquota(entry)) {
2273 				find->options |= (DNS_ADBFIND_LAMEPRUNED |
2274 						  DNS_ADBFIND_OVERQUOTA);
2275 				goto nextv4;
2276 			}
2277 
2278 			if (!FIND_RETURNLAME(find) &&
2279 			    entry_is_lame(adb, entry, qname, qtype, now)) {
2280 				find->options |= DNS_ADBFIND_LAMEPRUNED;
2281 				goto nextv4;
2282 			}
2283 			addrinfo = new_adbaddrinfo(adb, entry, find->port);
2284 			if (addrinfo == NULL) {
2285 				find->partial_result |= DNS_ADBFIND_INET;
2286 				goto out;
2287 			}
2288 			/*
2289 			 * Found a valid entry.  Add it to the find's list.
2290 			 */
2291 			inc_entry_refcnt(adb, entry, false);
2292 			ISC_LIST_APPEND(find->list, addrinfo, publink);
2293 			addrinfo = NULL;
2294 		nextv4:
2295 			UNLOCK(&adb->entrylocks[bucket]);
2296 			bucket = DNS_ADB_INVALIDBUCKET;
2297 			namehook = ISC_LIST_NEXT(namehook, plink);
2298 		}
2299 	}
2300 
2301 	if ((find->options & DNS_ADBFIND_INET6) != 0) {
2302 		namehook = ISC_LIST_HEAD(name->v6);
2303 		while (namehook != NULL) {
2304 			entry = namehook->entry;
2305 			bucket = entry->lock_bucket;
2306 			INSIST(bucket != DNS_ADB_INVALIDBUCKET);
2307 			LOCK(&adb->entrylocks[bucket]);
2308 
2309 			if (dns_adbentry_overquota(entry)) {
2310 				find->options |= (DNS_ADBFIND_LAMEPRUNED |
2311 						  DNS_ADBFIND_OVERQUOTA);
2312 				goto nextv6;
2313 			}
2314 
2315 			if (!FIND_RETURNLAME(find) &&
2316 			    entry_is_lame(adb, entry, qname, qtype, now)) {
2317 				find->options |= DNS_ADBFIND_LAMEPRUNED;
2318 				goto nextv6;
2319 			}
2320 			addrinfo = new_adbaddrinfo(adb, entry, find->port);
2321 			if (addrinfo == NULL) {
2322 				find->partial_result |= DNS_ADBFIND_INET6;
2323 				goto out;
2324 			}
2325 			/*
2326 			 * Found a valid entry.  Add it to the find's list.
2327 			 */
2328 			inc_entry_refcnt(adb, entry, false);
2329 			ISC_LIST_APPEND(find->list, addrinfo, publink);
2330 			addrinfo = NULL;
2331 		nextv6:
2332 			UNLOCK(&adb->entrylocks[bucket]);
2333 			bucket = DNS_ADB_INVALIDBUCKET;
2334 			namehook = ISC_LIST_NEXT(namehook, plink);
2335 		}
2336 	}
2337 
2338 out:
2339 	if (bucket != DNS_ADB_INVALIDBUCKET) {
2340 		UNLOCK(&adb->entrylocks[bucket]);
2341 	}
2342 }
2343 
2344 static void
2345 shutdown_task(isc_task_t *task, isc_event_t *ev) {
2346 	dns_adb_t *adb;
2347 
2348 	UNUSED(task);
2349 
2350 	adb = ev->ev_arg;
2351 	INSIST(DNS_ADB_VALID(adb));
2352 
2353 	isc_event_free(&ev);
2354 	/*
2355 	 * Wait for lock around check_exit() call to be released.
2356 	 */
2357 	LOCK(&adb->lock);
2358 	UNLOCK(&adb->lock);
2359 	destroy(adb);
2360 }
2361 
2362 /*
2363  * Name bucket must be locked; adb may be locked; no other locks held.
2364  */
2365 static bool
2366 check_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
2367 	dns_adbname_t *name;
2368 	bool result = false;
2369 
2370 	INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
2371 	name = *namep;
2372 
2373 	if (NAME_HAS_V4(name) || NAME_HAS_V6(name)) {
2374 		return (result);
2375 	}
2376 	if (NAME_FETCH(name)) {
2377 		return (result);
2378 	}
2379 	if (!EXPIRE_OK(name->expire_v4, now)) {
2380 		return (result);
2381 	}
2382 	if (!EXPIRE_OK(name->expire_v6, now)) {
2383 		return (result);
2384 	}
2385 	if (!EXPIRE_OK(name->expire_target, now)) {
2386 		return (result);
2387 	}
2388 
2389 	/*
2390 	 * The name is empty.  Delete it.
2391 	 */
2392 	*namep = NULL;
2393 	result = kill_name(&name, DNS_EVENT_ADBEXPIRED);
2394 
2395 	/*
2396 	 * Our caller, or one of its callers, will be calling check_exit() at
2397 	 * some point, so we don't need to do it here.
2398 	 */
2399 	return (result);
2400 }
2401 
2402 /*%
2403  * Examine the tail entry of the LRU list to see if it expires or is stale
2404  * (unused for some period); if so, the name entry will be freed.  If the ADB
2405  * is in the overmem condition, the tail and the next to tail entries
2406  * will be unconditionally removed (unless they have an outstanding fetch).
2407  * We don't care about a race on 'overmem' at the risk of causing some
2408  * collateral damage or a small delay in starting cleanup, so we don't bother
2409  * to lock ADB (if it's not locked).
2410  *
2411  * Name bucket must be locked; adb may be locked; no other locks held.
2412  */
2413 static void
2414 check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2415 	int victims, max_victims;
2416 	dns_adbname_t *victim, *next_victim;
2417 	bool overmem = isc_mem_isovermem(adb->mctx);
2418 	int scans = 0;
2419 
2420 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
2421 
2422 	max_victims = overmem ? 2 : 1;
2423 
2424 	/*
2425 	 * We limit the number of scanned entries to 10 (arbitrary choice)
2426 	 * in order to avoid examining too many entries when there are many
2427 	 * tail entries that have fetches (this should be rare, but could
2428 	 * happen).
2429 	 */
2430 	victim = ISC_LIST_TAIL(adb->names[bucket]);
2431 	for (victims = 0; victim != NULL && victims < max_victims && scans < 10;
2432 	     victim = next_victim)
2433 	{
2434 		INSIST(!NAME_DEAD(victim));
2435 		scans++;
2436 		next_victim = ISC_LIST_PREV(victim, plink);
2437 		(void)check_expire_name(&victim, now);
2438 		if (victim == NULL) {
2439 			victims++;
2440 			goto next;
2441 		}
2442 
2443 		if (!NAME_FETCH(victim) &&
2444 		    (overmem || victim->last_used + ADB_STALE_MARGIN <= now))
2445 		{
2446 			RUNTIME_CHECK(
2447 				kill_name(&victim, DNS_EVENT_ADBCANCELED) ==
2448 				false);
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 == false);
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 == false);
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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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) == false);
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) == false);
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) == false);
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 			      false);
3415 		free_adbaddrinfo(adb, &ai);
3416 		ai = ISC_LIST_HEAD(find->list);
3417 	}
3418 
3419 	/*
3420 	 * WARNING:  The find is freed with the adb locked.  This is done
3421 	 * to avoid a race condition where we free the find, some other
3422 	 * thread tests to see if it should be destroyed, detects it should
3423 	 * be, destroys it, and then we try to lock it for our check, but the
3424 	 * lock is destroyed.
3425 	 */
3426 	LOCK(&adb->lock);
3427 	if (free_adbfind(adb, &find)) {
3428 		check_exit(adb);
3429 	}
3430 	UNLOCK(&adb->lock);
3431 }
3432 
3433 void
3434 dns_adb_cancelfind(dns_adbfind_t *find) {
3435 	isc_event_t *ev;
3436 	isc_task_t *task;
3437 	dns_adb_t *adb;
3438 	int bucket;
3439 	int unlock_bucket;
3440 
3441 	LOCK(&find->lock);
3442 
3443 	DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
3444 
3445 	adb = find->adb;
3446 	REQUIRE(DNS_ADB_VALID(adb));
3447 
3448 	REQUIRE(!FIND_EVENTFREED(find));
3449 	REQUIRE(FIND_WANTEVENT(find));
3450 
3451 	bucket = find->name_bucket;
3452 	if (bucket == DNS_ADB_INVALIDBUCKET) {
3453 		goto cleanup;
3454 	}
3455 
3456 	/*
3457 	 * We need to get the adbname's lock to unlink the find.
3458 	 */
3459 	unlock_bucket = bucket;
3460 	violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
3461 	bucket = find->name_bucket;
3462 	if (bucket != DNS_ADB_INVALIDBUCKET) {
3463 		ISC_LIST_UNLINK(find->adbname->finds, find, plink);
3464 		find->adbname = NULL;
3465 		find->name_bucket = DNS_ADB_INVALIDBUCKET;
3466 	}
3467 	UNLOCK(&adb->namelocks[unlock_bucket]);
3468 	bucket = DNS_ADB_INVALIDBUCKET;
3469 	POST(bucket);
3470 
3471 cleanup:
3472 
3473 	if (!FIND_EVENTSENT(find)) {
3474 		ev = &find->event;
3475 		task = ev->ev_sender;
3476 		ev->ev_sender = find;
3477 		ev->ev_type = DNS_EVENT_ADBCANCELED;
3478 		ev->ev_destroy = event_free;
3479 		ev->ev_destroy_arg = find;
3480 		find->result_v4 = ISC_R_CANCELED;
3481 		find->result_v6 = ISC_R_CANCELED;
3482 
3483 		DP(DEF_LEVEL, "sending event %p to task %p for find %p", ev,
3484 		   task, find);
3485 
3486 		isc_task_sendanddetach(&task, (isc_event_t **)&ev);
3487 	}
3488 
3489 	UNLOCK(&find->lock);
3490 }
3491 
3492 void
3493 dns_adb_dump(dns_adb_t *adb, FILE *f) {
3494 	unsigned int i;
3495 	isc_stdtime_t now;
3496 
3497 	REQUIRE(DNS_ADB_VALID(adb));
3498 	REQUIRE(f != NULL);
3499 
3500 	/*
3501 	 * Lock the adb itself, lock all the name buckets, then lock all
3502 	 * the entry buckets.  This should put the adb into a state where
3503 	 * nothing can change, so we can iterate through everything and
3504 	 * print at our leisure.
3505 	 */
3506 
3507 	LOCK(&adb->lock);
3508 	isc_stdtime_get(&now);
3509 
3510 	for (i = 0; i < adb->nnames; i++) {
3511 		RUNTIME_CHECK(cleanup_names(adb, i, now) == false);
3512 	}
3513 	for (i = 0; i < adb->nentries; i++) {
3514 		RUNTIME_CHECK(cleanup_entries(adb, i, now) == false);
3515 	}
3516 
3517 	dump_adb(adb, f, false, now);
3518 	UNLOCK(&adb->lock);
3519 }
3520 
3521 static void
3522 dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
3523 	if (value == INT_MAX) {
3524 		return;
3525 	}
3526 	fprintf(f, " [%s TTL %d]", legend, (int)(value - now));
3527 }
3528 
3529 static void
3530 dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
3531 	dns_adbname_t *name;
3532 	dns_adbentry_t *entry;
3533 
3534 	fprintf(f, ";\n; Address database dump\n;\n");
3535 	fprintf(f, "; [edns success/4096 timeout/1432 timeout/1232 timeout/"
3536 		   "512 timeout]\n");
3537 	fprintf(f, "; [plain success/timeout]\n;\n");
3538 	if (debug) {
3539 		LOCK(&adb->reflock);
3540 		fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
3541 			adb, adb->erefcnt, adb->irefcnt,
3542 			isc_mempool_getallocated(adb->nhmp));
3543 		UNLOCK(&adb->reflock);
3544 	}
3545 
3546 /*
3547  * In TSAN mode we need to lock the locks individually, as TSAN
3548  * can't handle more than 64 locks locked by one thread.
3549  * In regular mode we want a consistent dump so we need to
3550  * lock everything.
3551  */
3552 #ifndef __SANITIZE_THREAD__
3553 	for (size_t i = 0; i < adb->nnames; i++) {
3554 		LOCK(&adb->namelocks[i]);
3555 	}
3556 	for (size_t i = 0; i < adb->nentries; i++) {
3557 		LOCK(&adb->entrylocks[i]);
3558 	}
3559 #endif /* ifndef __SANITIZE_THREAD__ */
3560 
3561 	/*
3562 	 * Dump the names
3563 	 */
3564 	for (size_t i = 0; i < adb->nnames; i++) {
3565 #ifdef __SANITIZE_THREAD__
3566 		LOCK(&adb->namelocks[i]);
3567 #endif /* ifdef __SANITIZE_THREAD__ */
3568 		name = ISC_LIST_HEAD(adb->names[i]);
3569 		if (name == NULL) {
3570 #ifdef __SANITIZE_THREAD__
3571 			UNLOCK(&adb->namelocks[i]);
3572 #endif /* ifdef __SANITIZE_THREAD__ */
3573 			continue;
3574 		}
3575 		if (debug) {
3576 			fprintf(f, "; bucket %zu\n", i);
3577 		}
3578 		for (; name != NULL; name = ISC_LIST_NEXT(name, plink)) {
3579 			if (debug) {
3580 				fprintf(f, "; name %p (flags %08x)\n", name,
3581 					name->flags);
3582 			}
3583 			fprintf(f, "; ");
3584 			print_dns_name(f, &name->name);
3585 			if (dns_name_countlabels(&name->target) > 0) {
3586 				fprintf(f, " alias ");
3587 				print_dns_name(f, &name->target);
3588 			}
3589 
3590 			dump_ttl(f, "v4", name->expire_v4, now);
3591 			dump_ttl(f, "v6", name->expire_v6, now);
3592 			dump_ttl(f, "target", name->expire_target, now);
3593 
3594 			fprintf(f, " [v4 %s] [v6 %s]",
3595 				errnames[name->fetch_err],
3596 				errnames[name->fetch6_err]);
3597 
3598 			fprintf(f, "\n");
3599 
3600 			print_namehook_list(f, "v4", adb, &name->v4, debug,
3601 					    now);
3602 			print_namehook_list(f, "v6", adb, &name->v6, debug,
3603 					    now);
3604 
3605 			if (debug) {
3606 				print_fetch_list(f, name);
3607 				print_find_list(f, name);
3608 			}
3609 		}
3610 #ifdef __SANITIZE_THREAD__
3611 		UNLOCK(&adb->namelocks[i]);
3612 #endif /* ifdef __SANITIZE_THREAD__ */
3613 	}
3614 
3615 	fprintf(f, ";\n; Unassociated entries\n;\n");
3616 
3617 	for (size_t i = 0; i < adb->nentries; i++) {
3618 #ifdef __SANITIZE_THREAD__
3619 		LOCK(&adb->entrylocks[i]);
3620 #endif /* ifdef __SANITIZE_THREAD__ */
3621 		entry = ISC_LIST_HEAD(adb->entries[i]);
3622 		while (entry != NULL) {
3623 			if (entry->nh == 0) {
3624 				dump_entry(f, adb, entry, debug, now);
3625 			}
3626 			entry = ISC_LIST_NEXT(entry, plink);
3627 		}
3628 #ifdef __SANITIZE_THREAD__
3629 		UNLOCK(&adb->entrylocks[i]);
3630 #endif /* ifdef __SANITIZE_THREAD__ */
3631 	}
3632 
3633 #ifndef __SANITIZE_THREAD__
3634 	/*
3635 	 * Unlock everything
3636 	 */
3637 	for (ssize_t i = adb->nentries - 1; i >= 0; i--) {
3638 		UNLOCK(&adb->entrylocks[i]);
3639 	}
3640 	for (ssize_t i = adb->nnames - 1; i >= 0; i--) {
3641 		UNLOCK(&adb->namelocks[i]);
3642 	}
3643 #endif /* ifndef __SANITIZE_THREAD__ */
3644 }
3645 
3646 static void
3647 dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, bool debug,
3648 	   isc_stdtime_t now) {
3649 	char addrbuf[ISC_NETADDR_FORMATSIZE];
3650 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
3651 	isc_netaddr_t netaddr;
3652 	dns_adblameinfo_t *li;
3653 
3654 	isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
3655 	isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
3656 
3657 	if (debug) {
3658 		fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt);
3659 	}
3660 
3661 	fprintf(f,
3662 		";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] "
3663 		"[plain %u/%u]",
3664 		addrbuf, entry->srtt, entry->flags, entry->edns, entry->to4096,
3665 		entry->to1432, entry->to1232, entry->to512, entry->plain,
3666 		entry->plainto);
3667 	if (entry->udpsize != 0U) {
3668 		fprintf(f, " [udpsize %u]", entry->udpsize);
3669 	}
3670 	if (entry->cookie != NULL) {
3671 		unsigned int i;
3672 		fprintf(f, " [cookie=");
3673 		for (i = 0; i < entry->cookielen; i++) {
3674 			fprintf(f, "%02x", entry->cookie[i]);
3675 		}
3676 		fprintf(f, "]");
3677 	}
3678 	if (entry->expires != 0) {
3679 		fprintf(f, " [ttl %d]", (int)(entry->expires - now));
3680 	}
3681 
3682 	if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
3683 		uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
3684 		fprintf(f, " [atr %0.2f] [quota %" PRIuFAST32 "]", entry->atr,
3685 			quota);
3686 	}
3687 
3688 	fprintf(f, "\n");
3689 	for (li = ISC_LIST_HEAD(entry->lameinfo); li != NULL;
3690 	     li = ISC_LIST_NEXT(li, plink))
3691 	{
3692 		fprintf(f, ";\t\t");
3693 		print_dns_name(f, &li->qname);
3694 		dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf));
3695 		fprintf(f, " %s [lame TTL %d]\n", typebuf,
3696 			(int)(li->lame_timer - now));
3697 	}
3698 }
3699 
3700 void
3701 dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
3702 	char tmp[512];
3703 	const char *tmpp;
3704 	dns_adbaddrinfo_t *ai;
3705 	isc_sockaddr_t *sa;
3706 
3707 	/*
3708 	 * Not used currently, in the API Just In Case we
3709 	 * want to dump out the name and/or entries too.
3710 	 */
3711 
3712 	LOCK(&find->lock);
3713 
3714 	fprintf(f, ";Find %p\n", find);
3715 	fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
3716 		find->query_pending, find->partial_result, find->options,
3717 		find->flags);
3718 	fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n",
3719 		find->name_bucket, find->adbname, find->event.ev_sender);
3720 
3721 	ai = ISC_LIST_HEAD(find->list);
3722 	if (ai != NULL) {
3723 		fprintf(f, "\tAddresses:\n");
3724 	}
3725 	while (ai != NULL) {
3726 		sa = &ai->sockaddr;
3727 		switch (sa->type.sa.sa_family) {
3728 		case AF_INET:
3729 			tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, tmp,
3730 					 sizeof(tmp));
3731 			break;
3732 		case AF_INET6:
3733 			tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
3734 					 tmp, sizeof(tmp));
3735 			break;
3736 		default:
3737 			tmpp = "UnkFamily";
3738 		}
3739 
3740 		if (tmpp == NULL) {
3741 			tmpp = "BadAddress";
3742 		}
3743 
3744 		fprintf(f,
3745 			"\t\tentry %p, flags %08x"
3746 			" srtt %u addr %s\n",
3747 			ai->entry, ai->flags, ai->srtt, tmpp);
3748 
3749 		ai = ISC_LIST_NEXT(ai, publink);
3750 	}
3751 
3752 	UNLOCK(&find->lock);
3753 }
3754 
3755 static void
3756 print_dns_name(FILE *f, const dns_name_t *name) {
3757 	char buf[DNS_NAME_FORMATSIZE];
3758 
3759 	INSIST(f != NULL);
3760 
3761 	dns_name_format(name, buf, sizeof(buf));
3762 	fprintf(f, "%s", buf);
3763 }
3764 
3765 static void
3766 print_namehook_list(FILE *f, const char *legend, dns_adb_t *adb,
3767 		    dns_adbnamehooklist_t *list, bool debug,
3768 		    isc_stdtime_t now) {
3769 	dns_adbnamehook_t *nh;
3770 
3771 	for (nh = ISC_LIST_HEAD(*list); nh != NULL;
3772 	     nh = ISC_LIST_NEXT(nh, plink)) {
3773 		if (debug) {
3774 			fprintf(f, ";\tHook(%s) %p\n", legend, nh);
3775 		}
3776 		dump_entry(f, adb, nh->entry, debug, now);
3777 	}
3778 }
3779 
3780 static inline void
3781 print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
3782 	fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n", type, ft, ft->fetch);
3783 }
3784 
3785 static void
3786 print_fetch_list(FILE *f, dns_adbname_t *n) {
3787 	if (NAME_FETCH_A(n)) {
3788 		print_fetch(f, n->fetch_a, "A");
3789 	}
3790 	if (NAME_FETCH_AAAA(n)) {
3791 		print_fetch(f, n->fetch_aaaa, "AAAA");
3792 	}
3793 }
3794 
3795 static void
3796 print_find_list(FILE *f, dns_adbname_t *name) {
3797 	dns_adbfind_t *find;
3798 
3799 	find = ISC_LIST_HEAD(name->finds);
3800 	while (find != NULL) {
3801 		dns_adb_dumpfind(find, f);
3802 		find = ISC_LIST_NEXT(find, plink);
3803 	}
3804 }
3805 
3806 static isc_result_t
3807 dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
3808 	isc_result_t result;
3809 	dns_rdataset_t rdataset;
3810 	dns_adb_t *adb;
3811 	dns_fixedname_t foundname;
3812 	dns_name_t *fname;
3813 
3814 	INSIST(DNS_ADBNAME_VALID(adbname));
3815 	adb = adbname->adb;
3816 	INSIST(DNS_ADB_VALID(adb));
3817 	INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
3818 
3819 	fname = dns_fixedname_initname(&foundname);
3820 	dns_rdataset_init(&rdataset);
3821 
3822 	if (rdtype == dns_rdatatype_a) {
3823 		adbname->fetch_err = FIND_ERR_UNEXPECTED;
3824 	} else {
3825 		adbname->fetch6_err = FIND_ERR_UNEXPECTED;
3826 	}
3827 
3828 	/*
3829 	 * We need to specify whether to search static-stub zones (if
3830 	 * configured) depending on whether this is a "start at zone" lookup,
3831 	 * i.e., whether it's a "bailiwick" glue.  If it's bailiwick (in which
3832 	 * case NAME_STARTATZONE is set) we need to stop the search at any
3833 	 * matching static-stub zone without looking into the cache to honor
3834 	 * the configuration on which server we should send queries to.
3835 	 */
3836 	result = dns_view_find(adb->view, &adbname->name, rdtype, now,
3837 			       NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
3838 			       NAME_HINTOK(adbname),
3839 			       ((adbname->flags & NAME_STARTATZONE) != 0), NULL,
3840 			       NULL, fname, &rdataset, NULL);
3841 
3842 	/* XXXVIX this switch statement is too sparse to gen a jump table. */
3843 	switch (result) {
3844 	case DNS_R_GLUE:
3845 	case DNS_R_HINT:
3846 	case ISC_R_SUCCESS:
3847 		/*
3848 		 * Found in the database.  Even if we can't copy out
3849 		 * any information, return success, or else a fetch
3850 		 * will be made, which will only make things worse.
3851 		 */
3852 		if (rdtype == dns_rdatatype_a) {
3853 			adbname->fetch_err = FIND_ERR_SUCCESS;
3854 		} else {
3855 			adbname->fetch6_err = FIND_ERR_SUCCESS;
3856 		}
3857 		result = import_rdataset(adbname, &rdataset, now);
3858 		break;
3859 	case DNS_R_NXDOMAIN:
3860 	case DNS_R_NXRRSET:
3861 		/*
3862 		 * We're authoritative and the data doesn't exist.
3863 		 * Make up a negative cache entry so we don't ask again
3864 		 * for a while.
3865 		 *
3866 		 * XXXRTH  What time should we use?  I'm putting in 30 seconds
3867 		 * for now.
3868 		 */
3869 		if (rdtype == dns_rdatatype_a) {
3870 			adbname->expire_v4 = now + 30;
3871 			DP(NCACHE_LEVEL,
3872 			   "adb name %p: Caching auth negative entry for A",
3873 			   adbname);
3874 			if (result == DNS_R_NXDOMAIN) {
3875 				adbname->fetch_err = FIND_ERR_NXDOMAIN;
3876 			} else {
3877 				adbname->fetch_err = FIND_ERR_NXRRSET;
3878 			}
3879 		} else {
3880 			DP(NCACHE_LEVEL,
3881 			   "adb name %p: Caching auth negative entry for AAAA",
3882 			   adbname);
3883 			adbname->expire_v6 = now + 30;
3884 			if (result == DNS_R_NXDOMAIN) {
3885 				adbname->fetch6_err = FIND_ERR_NXDOMAIN;
3886 			} else {
3887 				adbname->fetch6_err = FIND_ERR_NXRRSET;
3888 			}
3889 		}
3890 		break;
3891 	case DNS_R_NCACHENXDOMAIN:
3892 	case DNS_R_NCACHENXRRSET:
3893 		/*
3894 		 * We found a negative cache entry.  Pull the TTL from it
3895 		 * so we won't ask again for a while.
3896 		 */
3897 		rdataset.ttl = ttlclamp(rdataset.ttl);
3898 		if (rdtype == dns_rdatatype_a) {
3899 			adbname->expire_v4 = rdataset.ttl + now;
3900 			if (result == DNS_R_NCACHENXDOMAIN) {
3901 				adbname->fetch_err = FIND_ERR_NXDOMAIN;
3902 			} else {
3903 				adbname->fetch_err = FIND_ERR_NXRRSET;
3904 			}
3905 			DP(NCACHE_LEVEL,
3906 			   "adb name %p: Caching negative entry for A (ttl %u)",
3907 			   adbname, rdataset.ttl);
3908 		} else {
3909 			DP(NCACHE_LEVEL,
3910 			   "adb name %p: Caching negative entry for AAAA (ttl "
3911 			   "%u)",
3912 			   adbname, rdataset.ttl);
3913 			adbname->expire_v6 = rdataset.ttl + now;
3914 			if (result == DNS_R_NCACHENXDOMAIN) {
3915 				adbname->fetch6_err = FIND_ERR_NXDOMAIN;
3916 			} else {
3917 				adbname->fetch6_err = FIND_ERR_NXRRSET;
3918 			}
3919 		}
3920 		break;
3921 	case DNS_R_CNAME:
3922 	case DNS_R_DNAME:
3923 		/*
3924 		 * Clear the hint and glue flags, so this will match
3925 		 * more often.
3926 		 */
3927 		adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
3928 
3929 		rdataset.ttl = ttlclamp(rdataset.ttl);
3930 		clean_target(adb, &adbname->target);
3931 		adbname->expire_target = INT_MAX;
3932 		result = set_target(adb, &adbname->name, fname, &rdataset,
3933 				    &adbname->target);
3934 		if (result == ISC_R_SUCCESS) {
3935 			result = DNS_R_ALIAS;
3936 			DP(NCACHE_LEVEL, "adb name %p: caching alias target",
3937 			   adbname);
3938 			adbname->expire_target = rdataset.ttl + now;
3939 		}
3940 		if (rdtype == dns_rdatatype_a) {
3941 			adbname->fetch_err = FIND_ERR_SUCCESS;
3942 		} else {
3943 			adbname->fetch6_err = FIND_ERR_SUCCESS;
3944 		}
3945 		break;
3946 	}
3947 
3948 	if (dns_rdataset_isassociated(&rdataset)) {
3949 		dns_rdataset_disassociate(&rdataset);
3950 	}
3951 
3952 	return (result);
3953 }
3954 
3955 static void
3956 fetch_callback(isc_task_t *task, isc_event_t *ev) {
3957 	dns_fetchevent_t *dev;
3958 	dns_adbname_t *name;
3959 	dns_adb_t *adb;
3960 	dns_adbfetch_t *fetch;
3961 	int bucket;
3962 	isc_eventtype_t ev_status;
3963 	isc_stdtime_t now;
3964 	isc_result_t result;
3965 	unsigned int address_type;
3966 	bool want_check_exit = false;
3967 
3968 	UNUSED(task);
3969 
3970 	INSIST(ev->ev_type == DNS_EVENT_FETCHDONE);
3971 	dev = (dns_fetchevent_t *)ev;
3972 	name = ev->ev_arg;
3973 	INSIST(DNS_ADBNAME_VALID(name));
3974 	adb = name->adb;
3975 	INSIST(DNS_ADB_VALID(adb));
3976 
3977 	bucket = name->lock_bucket;
3978 	LOCK(&adb->namelocks[bucket]);
3979 
3980 	INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
3981 	address_type = 0;
3982 	if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
3983 		address_type = DNS_ADBFIND_INET;
3984 		fetch = name->fetch_a;
3985 		name->fetch_a = NULL;
3986 	} else if (NAME_FETCH_AAAA(name) &&
3987 		   (name->fetch_aaaa->fetch == dev->fetch)) {
3988 		address_type = DNS_ADBFIND_INET6;
3989 		fetch = name->fetch_aaaa;
3990 		name->fetch_aaaa = NULL;
3991 	} else {
3992 		fetch = NULL;
3993 	}
3994 
3995 	INSIST(address_type != 0 && fetch != NULL);
3996 
3997 	dns_resolver_destroyfetch(&fetch->fetch);
3998 	dev->fetch = NULL;
3999 
4000 	ev_status = DNS_EVENT_ADBNOMOREADDRESSES;
4001 
4002 	/*
4003 	 * Cleanup things we don't care about.
4004 	 */
4005 	if (dev->node != NULL) {
4006 		dns_db_detachnode(dev->db, &dev->node);
4007 	}
4008 	if (dev->db != NULL) {
4009 		dns_db_detach(&dev->db);
4010 	}
4011 
4012 	/*
4013 	 * If this name is marked as dead, clean up, throwing away
4014 	 * potentially good data.
4015 	 */
4016 	if (NAME_DEAD(name)) {
4017 		free_adbfetch(adb, &fetch);
4018 		isc_event_free(&ev);
4019 
4020 		want_check_exit = kill_name(&name, DNS_EVENT_ADBCANCELED);
4021 
4022 		UNLOCK(&adb->namelocks[bucket]);
4023 
4024 		if (want_check_exit) {
4025 			LOCK(&adb->lock);
4026 			check_exit(adb);
4027 			UNLOCK(&adb->lock);
4028 		}
4029 
4030 		return;
4031 	}
4032 
4033 	isc_stdtime_get(&now);
4034 
4035 	/*
4036 	 * If we got a negative cache response, remember it.
4037 	 */
4038 	if (NCACHE_RESULT(dev->result)) {
4039 		dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
4040 		if (address_type == DNS_ADBFIND_INET) {
4041 			DP(NCACHE_LEVEL,
4042 			   "adb fetch name %p: "
4043 			   "caching negative entry for A (ttl %u)",
4044 			   name, dev->rdataset->ttl);
4045 			name->expire_v4 = ISC_MIN(name->expire_v4,
4046 						  dev->rdataset->ttl + now);
4047 			if (dev->result == DNS_R_NCACHENXDOMAIN) {
4048 				name->fetch_err = FIND_ERR_NXDOMAIN;
4049 			} else {
4050 				name->fetch_err = FIND_ERR_NXRRSET;
4051 			}
4052 			inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
4053 		} else {
4054 			DP(NCACHE_LEVEL,
4055 			   "adb fetch name %p: "
4056 			   "caching negative entry for AAAA (ttl %u)",
4057 			   name, dev->rdataset->ttl);
4058 			name->expire_v6 = ISC_MIN(name->expire_v6,
4059 						  dev->rdataset->ttl + now);
4060 			if (dev->result == DNS_R_NCACHENXDOMAIN) {
4061 				name->fetch6_err = FIND_ERR_NXDOMAIN;
4062 			} else {
4063 				name->fetch6_err = FIND_ERR_NXRRSET;
4064 			}
4065 			inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
4066 		}
4067 		goto out;
4068 	}
4069 
4070 	/*
4071 	 * Handle CNAME/DNAME.
4072 	 */
4073 	if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
4074 		dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
4075 		clean_target(adb, &name->target);
4076 		name->expire_target = INT_MAX;
4077 		result = set_target(adb, &name->name,
4078 				    dns_fixedname_name(&dev->foundname),
4079 				    dev->rdataset, &name->target);
4080 		if (result == ISC_R_SUCCESS) {
4081 			DP(NCACHE_LEVEL,
4082 			   "adb fetch name %p: caching alias target", name);
4083 			name->expire_target = dev->rdataset->ttl + now;
4084 		}
4085 		goto check_result;
4086 	}
4087 
4088 	/*
4089 	 * Did we get back junk?  If so, and there are no more fetches
4090 	 * sitting out there, tell all the finds about it.
4091 	 */
4092 	if (dev->result != ISC_R_SUCCESS) {
4093 		char buf[DNS_NAME_FORMATSIZE];
4094 
4095 		dns_name_format(&name->name, buf, sizeof(buf));
4096 		DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf,
4097 		   address_type == DNS_ADBFIND_INET ? "A" : "AAAA",
4098 		   dns_result_totext(dev->result));
4099 		/*
4100 		 * Don't record a failure unless this is the initial
4101 		 * fetch of a chain.
4102 		 */
4103 		if (fetch->depth > 1) {
4104 			goto out;
4105 		}
4106 		/* XXXMLG Don't pound on bad servers. */
4107 		if (address_type == DNS_ADBFIND_INET) {
4108 			name->expire_v4 = ISC_MIN(name->expire_v4, now + 10);
4109 			name->fetch_err = FIND_ERR_FAILURE;
4110 			inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
4111 		} else {
4112 			name->expire_v6 = ISC_MIN(name->expire_v6, now + 10);
4113 			name->fetch6_err = FIND_ERR_FAILURE;
4114 			inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
4115 		}
4116 		goto out;
4117 	}
4118 
4119 	/*
4120 	 * We got something potentially useful.
4121 	 */
4122 	result = import_rdataset(name, &fetch->rdataset, now);
4123 
4124 check_result:
4125 	if (result == ISC_R_SUCCESS) {
4126 		ev_status = DNS_EVENT_ADBMOREADDRESSES;
4127 		if (address_type == DNS_ADBFIND_INET) {
4128 			name->fetch_err = FIND_ERR_SUCCESS;
4129 		} else {
4130 			name->fetch6_err = FIND_ERR_SUCCESS;
4131 		}
4132 	}
4133 
4134 out:
4135 	free_adbfetch(adb, &fetch);
4136 	isc_event_free(&ev);
4137 
4138 	clean_finds_at_name(name, ev_status, address_type);
4139 
4140 	UNLOCK(&adb->namelocks[bucket]);
4141 }
4142 
4143 static isc_result_t
4144 fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
4145 	   isc_counter_t *qc, dns_rdatatype_t type) {
4146 	isc_result_t result;
4147 	dns_adbfetch_t *fetch = NULL;
4148 	dns_adb_t *adb;
4149 	dns_fixedname_t fixed;
4150 	dns_name_t *name;
4151 	dns_rdataset_t rdataset;
4152 	dns_rdataset_t *nameservers;
4153 	unsigned int options;
4154 
4155 	INSIST(DNS_ADBNAME_VALID(adbname));
4156 	adb = adbname->adb;
4157 	INSIST(DNS_ADB_VALID(adb));
4158 
4159 	INSIST((type == dns_rdatatype_a && !NAME_FETCH_V4(adbname)) ||
4160 	       (type == dns_rdatatype_aaaa && !NAME_FETCH_V6(adbname)));
4161 
4162 	adbname->fetch_err = FIND_ERR_NOTFOUND;
4163 
4164 	name = NULL;
4165 	nameservers = NULL;
4166 	dns_rdataset_init(&rdataset);
4167 
4168 	options = DNS_FETCHOPT_NOVALIDATE;
4169 	if (start_at_zone) {
4170 		DP(ENTER_LEVEL, "fetch_name: starting at zone for name %p",
4171 		   adbname);
4172 		name = dns_fixedname_initname(&fixed);
4173 		result = dns_view_findzonecut(adb->view, &adbname->name, name,
4174 					      NULL, 0, 0, true, false,
4175 					      &rdataset, NULL);
4176 		if (result != ISC_R_SUCCESS && result != DNS_R_HINT) {
4177 			goto cleanup;
4178 		}
4179 		nameservers = &rdataset;
4180 		options |= DNS_FETCHOPT_UNSHARED;
4181 	}
4182 
4183 	fetch = new_adbfetch(adb);
4184 	if (fetch == NULL) {
4185 		result = ISC_R_NOMEMORY;
4186 		goto cleanup;
4187 	}
4188 	fetch->depth = depth;
4189 
4190 	/*
4191 	 * We're not minimizing this query, as nothing user-related should
4192 	 * be leaked here.
4193 	 * However, if we'd ever want to change it we'd have to modify
4194 	 * createfetch to find deepest cached name when we're providing
4195 	 * domain and nameservers.
4196 	 */
4197 	result = dns_resolver_createfetch(
4198 		adb->view->resolver, &adbname->name, type, name, nameservers,
4199 		NULL, NULL, 0, options, depth, qc, adb->task, fetch_callback,
4200 		adbname, &fetch->rdataset, NULL, &fetch->fetch);
4201 	if (result != ISC_R_SUCCESS) {
4202 		DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
4203 		   isc_result_totext(result));
4204 		goto cleanup;
4205 	}
4206 
4207 	if (type == dns_rdatatype_a) {
4208 		adbname->fetch_a = fetch;
4209 		inc_stats(adb, dns_resstatscounter_gluefetchv4);
4210 	} else {
4211 		adbname->fetch_aaaa = fetch;
4212 		inc_stats(adb, dns_resstatscounter_gluefetchv6);
4213 	}
4214 	fetch = NULL; /* Keep us from cleaning this up below. */
4215 
4216 cleanup:
4217 	if (fetch != NULL) {
4218 		free_adbfetch(adb, &fetch);
4219 	}
4220 	if (dns_rdataset_isassociated(&rdataset)) {
4221 		dns_rdataset_disassociate(&rdataset);
4222 	}
4223 
4224 	return (result);
4225 }
4226 
4227 /*
4228  * XXXMLG Needs to take a find argument and an address info, no zone or adb,
4229  * since these can be extracted from the find itself.
4230  */
4231 isc_result_t
4232 dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
4233 		 const dns_name_t *qname, dns_rdatatype_t qtype,
4234 		 isc_stdtime_t expire_time) {
4235 	dns_adblameinfo_t *li;
4236 	int bucket;
4237 	isc_result_t result = ISC_R_SUCCESS;
4238 
4239 	REQUIRE(DNS_ADB_VALID(adb));
4240 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4241 	REQUIRE(qname != NULL);
4242 
4243 	bucket = addr->entry->lock_bucket;
4244 	LOCK(&adb->entrylocks[bucket]);
4245 	li = ISC_LIST_HEAD(addr->entry->lameinfo);
4246 	while (li != NULL &&
4247 	       (li->qtype != qtype || !dns_name_equal(qname, &li->qname))) {
4248 		li = ISC_LIST_NEXT(li, plink);
4249 	}
4250 	if (li != NULL) {
4251 		if (expire_time > li->lame_timer) {
4252 			li->lame_timer = expire_time;
4253 		}
4254 		goto unlock;
4255 	}
4256 	li = new_adblameinfo(adb, qname, qtype);
4257 	if (li == NULL) {
4258 		result = ISC_R_NOMEMORY;
4259 		goto unlock;
4260 	}
4261 
4262 	li->lame_timer = expire_time;
4263 
4264 	ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink);
4265 unlock:
4266 	UNLOCK(&adb->entrylocks[bucket]);
4267 
4268 	return (result);
4269 }
4270 
4271 void
4272 dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt,
4273 		   unsigned int factor) {
4274 	int bucket;
4275 	isc_stdtime_t now = 0;
4276 
4277 	REQUIRE(DNS_ADB_VALID(adb));
4278 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4279 	REQUIRE(factor <= 10);
4280 
4281 	bucket = addr->entry->lock_bucket;
4282 	LOCK(&adb->entrylocks[bucket]);
4283 
4284 	if (addr->entry->expires == 0 || factor == DNS_ADB_RTTADJAGE) {
4285 		isc_stdtime_get(&now);
4286 	}
4287 	adjustsrtt(addr, rtt, factor, now);
4288 
4289 	UNLOCK(&adb->entrylocks[bucket]);
4290 }
4291 
4292 void
4293 dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) {
4294 	int bucket;
4295 
4296 	REQUIRE(DNS_ADB_VALID(adb));
4297 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4298 
4299 	bucket = addr->entry->lock_bucket;
4300 	LOCK(&adb->entrylocks[bucket]);
4301 
4302 	adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now);
4303 
4304 	UNLOCK(&adb->entrylocks[bucket]);
4305 }
4306 
4307 static void
4308 adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
4309 	   isc_stdtime_t now) {
4310 	uint64_t new_srtt;
4311 
4312 	if (factor == DNS_ADB_RTTADJAGE) {
4313 		if (addr->entry->lastage != now) {
4314 			new_srtt = addr->entry->srtt;
4315 			new_srtt <<= 9;
4316 			new_srtt -= addr->entry->srtt;
4317 			new_srtt >>= 9;
4318 			addr->entry->lastage = now;
4319 		} else {
4320 			new_srtt = addr->entry->srtt;
4321 		}
4322 	} else {
4323 		new_srtt = ((uint64_t)addr->entry->srtt / 10 * factor) +
4324 			   ((uint64_t)rtt / 10 * (10 - factor));
4325 	}
4326 
4327 	addr->entry->srtt = (unsigned int)new_srtt;
4328 	addr->srtt = (unsigned int)new_srtt;
4329 
4330 	if (addr->entry->expires == 0) {
4331 		addr->entry->expires = now + ADB_ENTRY_WINDOW;
4332 	}
4333 }
4334 
4335 void
4336 dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits,
4337 		    unsigned int mask) {
4338 	int bucket;
4339 	isc_stdtime_t now;
4340 
4341 	REQUIRE(DNS_ADB_VALID(adb));
4342 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4343 
4344 	REQUIRE((bits & ENTRY_IS_DEAD) == 0);
4345 	REQUIRE((mask & ENTRY_IS_DEAD) == 0);
4346 
4347 	bucket = addr->entry->lock_bucket;
4348 	LOCK(&adb->entrylocks[bucket]);
4349 
4350 	addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
4351 	if (addr->entry->expires == 0) {
4352 		isc_stdtime_get(&now);
4353 		addr->entry->expires = now + ADB_ENTRY_WINDOW;
4354 	}
4355 
4356 	/*
4357 	 * Note that we do not update the other bits in addr->flags with
4358 	 * the most recent values from addr->entry->flags.
4359 	 */
4360 	addr->flags = (addr->flags & ~mask) | (bits & mask);
4361 
4362 	UNLOCK(&adb->entrylocks[bucket]);
4363 }
4364 
4365 /*
4366  * The polynomial backoff curve (10000 / ((10 + n) / 10)^(3/2)) <0..99> drops
4367  * fairly aggressively at first, then slows down and tails off at around 2-3%.
4368  *
4369  * These will be used to make quota adjustments.
4370  */
4371 static int quota_adj[] = {
4372 	10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141, 3818, 3536,
4373 	3286,  3065, 2867, 2690, 2530, 2385, 2254, 2134, 2025, 1925, 1832,
4374 	1747,  1668, 1595, 1527, 1464, 1405, 1350, 1298, 1250, 1205, 1162,
4375 	1121,  1083, 1048, 1014, 981,  922,  894,  868,	 843,  820,  797,
4376 	775,   755,  735,  716,	 698,  680,  664,  648,	 632,  618,  603,
4377 	590,   577,  564,  552,	 540,  529,  518,  507,	 497,  487,  477,
4378 	468,   459,  450,  442,	 434,  426,  418,  411,	 404,  397,  390,
4379 	383,   377,  370,  364,	 358,  353,  347,  342,	 336,  331,  326,
4380 	321,   316,  312,  307,	 303,  298,  294,  290,	 286,  282,  278
4381 };
4382 
4383 #define QUOTA_ADJ_SIZE (sizeof(quota_adj) / sizeof(quota_adj[0]))
4384 
4385 /*
4386  * Caller must hold adbentry lock
4387  */
4388 static void
4389 maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) {
4390 	double tr;
4391 
4392 	UNUSED(adb);
4393 
4394 	if (adb->quota == 0 || adb->atr_freq == 0) {
4395 		return;
4396 	}
4397 
4398 	if (timeout) {
4399 		addr->entry->timeouts++;
4400 	}
4401 
4402 	if (addr->entry->completed++ <= adb->atr_freq) {
4403 		return;
4404 	}
4405 
4406 	/*
4407 	 * Calculate an exponential rolling average of the timeout ratio
4408 	 *
4409 	 * XXX: Integer arithmetic might be better than floating point
4410 	 */
4411 	tr = (double)addr->entry->timeouts / addr->entry->completed;
4412 	addr->entry->timeouts = addr->entry->completed = 0;
4413 	INSIST(addr->entry->atr >= 0.0);
4414 	INSIST(addr->entry->atr <= 1.0);
4415 	INSIST(adb->atr_discount >= 0.0);
4416 	INSIST(adb->atr_discount <= 1.0);
4417 	addr->entry->atr *= 1.0 - adb->atr_discount;
4418 	addr->entry->atr += tr * adb->atr_discount;
4419 	addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0);
4420 
4421 	if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) {
4422 		uint_fast32_t new_quota =
4423 			adb->quota * quota_adj[--addr->entry->mode] / 10000;
4424 		atomic_store_release(&addr->entry->quota,
4425 				     ISC_MIN(1, new_quota));
4426 		log_quota(addr->entry,
4427 			  "atr %0.2f, quota increased to %" PRIuFAST32,
4428 			  addr->entry->atr, new_quota);
4429 	} else if (addr->entry->atr > adb->atr_high &&
4430 		   addr->entry->mode < (QUOTA_ADJ_SIZE - 1))
4431 	{
4432 		uint_fast32_t new_quota =
4433 			adb->quota * quota_adj[++addr->entry->mode] / 10000;
4434 		atomic_store_release(&addr->entry->quota,
4435 				     ISC_MIN(1, new_quota));
4436 		log_quota(addr->entry,
4437 			  "atr %0.2f, quota decreased to %" PRIuFAST32,
4438 			  addr->entry->atr, new_quota);
4439 	}
4440 }
4441 
4442 #define EDNSTOS 3U
4443 bool
4444 dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4445 	int bucket;
4446 	bool noedns = false;
4447 
4448 	REQUIRE(DNS_ADB_VALID(adb));
4449 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4450 
4451 	bucket = addr->entry->lock_bucket;
4452 	LOCK(&adb->entrylocks[bucket]);
4453 
4454 	if (addr->entry->edns == 0U &&
4455 	    (addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS))
4456 	{
4457 		if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) {
4458 			noedns = true;
4459 		} else {
4460 			/*
4461 			 * Increment plain so we don't get stuck.
4462 			 */
4463 			addr->entry->plain++;
4464 			if (addr->entry->plain == 0xff) {
4465 				addr->entry->edns >>= 1;
4466 				addr->entry->to4096 >>= 1;
4467 				addr->entry->to1432 >>= 1;
4468 				addr->entry->to1232 >>= 1;
4469 				addr->entry->to512 >>= 1;
4470 				addr->entry->plain >>= 1;
4471 				addr->entry->plainto >>= 1;
4472 			}
4473 		}
4474 	}
4475 	UNLOCK(&adb->entrylocks[bucket]);
4476 	return (noedns);
4477 }
4478 
4479 void
4480 dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4481 	int bucket;
4482 
4483 	REQUIRE(DNS_ADB_VALID(adb));
4484 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4485 
4486 	bucket = addr->entry->lock_bucket;
4487 	LOCK(&adb->entrylocks[bucket]);
4488 
4489 	maybe_adjust_quota(adb, addr, false);
4490 
4491 	addr->entry->plain++;
4492 	if (addr->entry->plain == 0xff) {
4493 		addr->entry->edns >>= 1;
4494 		addr->entry->to4096 >>= 1;
4495 		addr->entry->to1432 >>= 1;
4496 		addr->entry->to1232 >>= 1;
4497 		addr->entry->to512 >>= 1;
4498 		addr->entry->plain >>= 1;
4499 		addr->entry->plainto >>= 1;
4500 	}
4501 	UNLOCK(&adb->entrylocks[bucket]);
4502 }
4503 
4504 void
4505 dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4506 	int bucket;
4507 
4508 	REQUIRE(DNS_ADB_VALID(adb));
4509 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4510 
4511 	bucket = addr->entry->lock_bucket;
4512 	LOCK(&adb->entrylocks[bucket]);
4513 
4514 	maybe_adjust_quota(adb, addr, true);
4515 
4516 	/*
4517 	 * If we have not had a successful query then clear all
4518 	 * edns timeout information.
4519 	 */
4520 	if (addr->entry->edns == 0 && addr->entry->plain == 0) {
4521 		addr->entry->to512 = 0;
4522 		addr->entry->to1232 = 0;
4523 		addr->entry->to1432 = 0;
4524 		addr->entry->to4096 = 0;
4525 	} else {
4526 		addr->entry->to512 >>= 1;
4527 		addr->entry->to1232 >>= 1;
4528 		addr->entry->to1432 >>= 1;
4529 		addr->entry->to4096 >>= 1;
4530 	}
4531 
4532 	addr->entry->plainto++;
4533 	if (addr->entry->plainto == 0xff) {
4534 		addr->entry->edns >>= 1;
4535 		addr->entry->plain >>= 1;
4536 		addr->entry->plainto >>= 1;
4537 	}
4538 	UNLOCK(&adb->entrylocks[bucket]);
4539 }
4540 
4541 void
4542 dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
4543 	int bucket;
4544 
4545 	REQUIRE(DNS_ADB_VALID(adb));
4546 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4547 
4548 	bucket = addr->entry->lock_bucket;
4549 	LOCK(&adb->entrylocks[bucket]);
4550 
4551 	maybe_adjust_quota(adb, addr, true);
4552 
4553 	if (size <= 512U) {
4554 		if (addr->entry->to512 <= EDNSTOS) {
4555 			addr->entry->to512++;
4556 			addr->entry->to1232++;
4557 			addr->entry->to1432++;
4558 			addr->entry->to4096++;
4559 		}
4560 	} else if (size <= 1232U) {
4561 		if (addr->entry->to1232 <= EDNSTOS) {
4562 			addr->entry->to1232++;
4563 			addr->entry->to1432++;
4564 			addr->entry->to4096++;
4565 		}
4566 	} else if (size <= 1432U) {
4567 		if (addr->entry->to1432 <= EDNSTOS) {
4568 			addr->entry->to1432++;
4569 			addr->entry->to4096++;
4570 		}
4571 	} else {
4572 		if (addr->entry->to4096 <= EDNSTOS) {
4573 			addr->entry->to4096++;
4574 		}
4575 	}
4576 
4577 	if (addr->entry->to4096 == 0xff) {
4578 		addr->entry->edns >>= 1;
4579 		addr->entry->to4096 >>= 1;
4580 		addr->entry->to1432 >>= 1;
4581 		addr->entry->to1232 >>= 1;
4582 		addr->entry->to512 >>= 1;
4583 		addr->entry->plain >>= 1;
4584 		addr->entry->plainto >>= 1;
4585 	}
4586 	UNLOCK(&adb->entrylocks[bucket]);
4587 }
4588 
4589 void
4590 dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
4591 	int bucket;
4592 
4593 	REQUIRE(DNS_ADB_VALID(adb));
4594 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4595 
4596 	bucket = addr->entry->lock_bucket;
4597 	LOCK(&adb->entrylocks[bucket]);
4598 	if (size < 512U) {
4599 		size = 512U;
4600 	}
4601 	if (size > addr->entry->udpsize) {
4602 		addr->entry->udpsize = size;
4603 	}
4604 
4605 	maybe_adjust_quota(adb, addr, false);
4606 
4607 	addr->entry->edns++;
4608 	if (addr->entry->edns == 0xff) {
4609 		addr->entry->edns >>= 1;
4610 		addr->entry->to4096 >>= 1;
4611 		addr->entry->to1432 >>= 1;
4612 		addr->entry->to1232 >>= 1;
4613 		addr->entry->to512 >>= 1;
4614 		addr->entry->plain >>= 1;
4615 		addr->entry->plainto >>= 1;
4616 	}
4617 	UNLOCK(&adb->entrylocks[bucket]);
4618 }
4619 
4620 unsigned int
4621 dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4622 	int bucket;
4623 	unsigned int size;
4624 
4625 	REQUIRE(DNS_ADB_VALID(adb));
4626 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4627 
4628 	bucket = addr->entry->lock_bucket;
4629 	LOCK(&adb->entrylocks[bucket]);
4630 	size = addr->entry->udpsize;
4631 	UNLOCK(&adb->entrylocks[bucket]);
4632 
4633 	return (size);
4634 }
4635 
4636 unsigned int
4637 dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups) {
4638 	int bucket;
4639 	unsigned int size;
4640 
4641 	REQUIRE(DNS_ADB_VALID(adb));
4642 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4643 
4644 	bucket = addr->entry->lock_bucket;
4645 	LOCK(&adb->entrylocks[bucket]);
4646 	if (addr->entry->to1232 > EDNSTOS || lookups >= 2) {
4647 		size = 512;
4648 	} else if (addr->entry->to1432 > EDNSTOS || lookups >= 1) {
4649 		size = 1232;
4650 	} else if (addr->entry->to4096 > EDNSTOS) {
4651 		size = 1432;
4652 	} else {
4653 		size = 4096;
4654 	}
4655 	/*
4656 	 * Don't shrink probe size below what we have seen due to multiple
4657 	 * lookups.
4658 	 */
4659 	if (lookups > 0 && size < addr->entry->udpsize &&
4660 	    addr->entry->udpsize < 4096) {
4661 		size = addr->entry->udpsize;
4662 	}
4663 	UNLOCK(&adb->entrylocks[bucket]);
4664 
4665 	return (size);
4666 }
4667 
4668 void
4669 dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
4670 		  const unsigned char *cookie, size_t len) {
4671 	int bucket;
4672 
4673 	REQUIRE(DNS_ADB_VALID(adb));
4674 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4675 
4676 	bucket = addr->entry->lock_bucket;
4677 	LOCK(&adb->entrylocks[bucket]);
4678 
4679 	if (addr->entry->cookie != NULL &&
4680 	    (cookie == NULL || len != addr->entry->cookielen))
4681 	{
4682 		isc_mem_put(adb->mctx, addr->entry->cookie,
4683 			    addr->entry->cookielen);
4684 		addr->entry->cookie = NULL;
4685 		addr->entry->cookielen = 0;
4686 	}
4687 
4688 	if (addr->entry->cookie == NULL && cookie != NULL && len != 0U) {
4689 		addr->entry->cookie = isc_mem_get(adb->mctx, len);
4690 		addr->entry->cookielen = (uint16_t)len;
4691 	}
4692 
4693 	if (addr->entry->cookie != NULL) {
4694 		memmove(addr->entry->cookie, cookie, len);
4695 	}
4696 	UNLOCK(&adb->entrylocks[bucket]);
4697 }
4698 
4699 size_t
4700 dns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
4701 		  unsigned char *cookie, size_t len) {
4702 	int bucket;
4703 
4704 	REQUIRE(DNS_ADB_VALID(adb));
4705 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4706 
4707 	bucket = addr->entry->lock_bucket;
4708 	LOCK(&adb->entrylocks[bucket]);
4709 	if (cookie != NULL && addr->entry->cookie != NULL &&
4710 	    len >= addr->entry->cookielen)
4711 	{
4712 		memmove(cookie, addr->entry->cookie, addr->entry->cookielen);
4713 		len = addr->entry->cookielen;
4714 	} else {
4715 		len = 0;
4716 	}
4717 	UNLOCK(&adb->entrylocks[bucket]);
4718 
4719 	return (len);
4720 }
4721 
4722 isc_result_t
4723 dns_adb_findaddrinfo(dns_adb_t *adb, const isc_sockaddr_t *sa,
4724 		     dns_adbaddrinfo_t **addrp, isc_stdtime_t now) {
4725 	int bucket;
4726 	dns_adbentry_t *entry;
4727 	dns_adbaddrinfo_t *addr;
4728 	isc_result_t result;
4729 	in_port_t port;
4730 
4731 	REQUIRE(DNS_ADB_VALID(adb));
4732 	REQUIRE(addrp != NULL && *addrp == NULL);
4733 
4734 	UNUSED(now);
4735 
4736 	result = ISC_R_SUCCESS;
4737 	bucket = DNS_ADB_INVALIDBUCKET;
4738 	entry = find_entry_and_lock(adb, sa, &bucket, now);
4739 	INSIST(bucket != DNS_ADB_INVALIDBUCKET);
4740 	if (adb->entry_sd[bucket]) {
4741 		result = ISC_R_SHUTTINGDOWN;
4742 		goto unlock;
4743 	}
4744 	if (entry == NULL) {
4745 		/*
4746 		 * We don't know anything about this address.
4747 		 */
4748 		entry = new_adbentry(adb);
4749 		if (entry == NULL) {
4750 			result = ISC_R_NOMEMORY;
4751 			goto unlock;
4752 		}
4753 		entry->sockaddr = *sa;
4754 		link_entry(adb, bucket, entry);
4755 		DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry);
4756 	} else {
4757 		DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry);
4758 	}
4759 
4760 	port = isc_sockaddr_getport(sa);
4761 	addr = new_adbaddrinfo(adb, entry, port);
4762 	if (addr == NULL) {
4763 		result = ISC_R_NOMEMORY;
4764 	} else {
4765 		inc_entry_refcnt(adb, entry, false);
4766 		*addrp = addr;
4767 	}
4768 
4769 unlock:
4770 	UNLOCK(&adb->entrylocks[bucket]);
4771 
4772 	return (result);
4773 }
4774 
4775 void
4776 dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
4777 	dns_adbaddrinfo_t *addr;
4778 	dns_adbentry_t *entry;
4779 	int bucket;
4780 	isc_stdtime_t now;
4781 	bool want_check_exit = false;
4782 	bool overmem;
4783 
4784 	REQUIRE(DNS_ADB_VALID(adb));
4785 	REQUIRE(addrp != NULL);
4786 	addr = *addrp;
4787 	*addrp = NULL;
4788 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4789 	entry = addr->entry;
4790 	REQUIRE(DNS_ADBENTRY_VALID(entry));
4791 
4792 	overmem = isc_mem_isovermem(adb->mctx);
4793 
4794 	bucket = addr->entry->lock_bucket;
4795 	LOCK(&adb->entrylocks[bucket]);
4796 
4797 	if (entry->expires == 0) {
4798 		isc_stdtime_get(&now);
4799 		entry->expires = now + ADB_ENTRY_WINDOW;
4800 	}
4801 
4802 	want_check_exit = dec_entry_refcnt(adb, overmem, entry, false);
4803 
4804 	UNLOCK(&adb->entrylocks[bucket]);
4805 
4806 	addr->entry = NULL;
4807 	free_adbaddrinfo(adb, &addr);
4808 
4809 	if (want_check_exit) {
4810 		LOCK(&adb->lock);
4811 		check_exit(adb);
4812 		UNLOCK(&adb->lock);
4813 	}
4814 }
4815 
4816 void
4817 dns_adb_flush(dns_adb_t *adb) {
4818 	unsigned int i;
4819 
4820 	INSIST(DNS_ADB_VALID(adb));
4821 
4822 	LOCK(&adb->lock);
4823 
4824 	/*
4825 	 * Call our cleanup routines.
4826 	 */
4827 	for (i = 0; i < adb->nnames; i++) {
4828 		RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == false);
4829 	}
4830 	for (i = 0; i < adb->nentries; i++) {
4831 		RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == false);
4832 	}
4833 
4834 #ifdef DUMP_ADB_AFTER_CLEANING
4835 	dump_adb(adb, stdout, true, INT_MAX);
4836 #endif /* ifdef DUMP_ADB_AFTER_CLEANING */
4837 
4838 	UNLOCK(&adb->lock);
4839 }
4840 
4841 void
4842 dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
4843 	dns_adbname_t *adbname;
4844 	dns_adbname_t *nextname;
4845 	int bucket;
4846 
4847 	REQUIRE(DNS_ADB_VALID(adb));
4848 	REQUIRE(name != NULL);
4849 
4850 	LOCK(&adb->lock);
4851 	bucket = dns_name_hash(name, false) % adb->nnames;
4852 	LOCK(&adb->namelocks[bucket]);
4853 	adbname = ISC_LIST_HEAD(adb->names[bucket]);
4854 	while (adbname != NULL) {
4855 		nextname = ISC_LIST_NEXT(adbname, plink);
4856 		if (!NAME_DEAD(adbname) && dns_name_equal(name, &adbname->name))
4857 		{
4858 			RUNTIME_CHECK(
4859 				kill_name(&adbname, DNS_EVENT_ADBCANCELED) ==
4860 				false);
4861 		}
4862 		adbname = nextname;
4863 	}
4864 	UNLOCK(&adb->namelocks[bucket]);
4865 	UNLOCK(&adb->lock);
4866 }
4867 
4868 void
4869 dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
4870 	dns_adbname_t *adbname, *nextname;
4871 	unsigned int i;
4872 
4873 	REQUIRE(DNS_ADB_VALID(adb));
4874 	REQUIRE(name != NULL);
4875 
4876 	LOCK(&adb->lock);
4877 	for (i = 0; i < adb->nnames; i++) {
4878 		LOCK(&adb->namelocks[i]);
4879 		adbname = ISC_LIST_HEAD(adb->names[i]);
4880 		while (adbname != NULL) {
4881 			bool ret;
4882 			nextname = ISC_LIST_NEXT(adbname, plink);
4883 			if (!NAME_DEAD(adbname) &&
4884 			    dns_name_issubdomain(&adbname->name, name)) {
4885 				ret = kill_name(&adbname,
4886 						DNS_EVENT_ADBCANCELED);
4887 				RUNTIME_CHECK(ret == false);
4888 			}
4889 			adbname = nextname;
4890 		}
4891 		UNLOCK(&adb->namelocks[i]);
4892 	}
4893 	UNLOCK(&adb->lock);
4894 }
4895 
4896 static void
4897 water(void *arg, int mark) {
4898 	/*
4899 	 * We're going to change the way to handle overmem condition: use
4900 	 * isc_mem_isovermem() instead of storing the state via this callback,
4901 	 * since the latter way tends to cause race conditions.
4902 	 * To minimize the change, and in case we re-enable the callback
4903 	 * approach, however, keep this function at the moment.
4904 	 */
4905 
4906 	dns_adb_t *adb = arg;
4907 	bool overmem = (mark == ISC_MEM_HIWATER);
4908 
4909 	REQUIRE(DNS_ADB_VALID(adb));
4910 
4911 	DP(ISC_LOG_DEBUG(1), "adb reached %s water mark",
4912 	   overmem ? "high" : "low");
4913 }
4914 
4915 void
4916 dns_adb_setadbsize(dns_adb_t *adb, size_t size) {
4917 	size_t hiwater, lowater;
4918 
4919 	INSIST(DNS_ADB_VALID(adb));
4920 
4921 	if (size != 0U && size < DNS_ADB_MINADBSIZE) {
4922 		size = DNS_ADB_MINADBSIZE;
4923 	}
4924 
4925 	hiwater = size - (size >> 3); /* Approximately 7/8ths. */
4926 	lowater = size - (size >> 2); /* Approximately 3/4ths. */
4927 
4928 	if (size == 0U || hiwater == 0U || lowater == 0U) {
4929 		isc_mem_setwater(adb->mctx, water, adb, 0, 0);
4930 	} else {
4931 		isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
4932 	}
4933 }
4934 
4935 void
4936 dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, double low,
4937 		 double high, double discount) {
4938 	REQUIRE(DNS_ADB_VALID(adb));
4939 
4940 	adb->quota = quota;
4941 	adb->atr_freq = freq;
4942 	adb->atr_low = low;
4943 	adb->atr_high = high;
4944 	adb->atr_discount = discount;
4945 }
4946 
4947 bool
4948 dns_adbentry_overquota(dns_adbentry_t *entry) {
4949 	REQUIRE(DNS_ADBENTRY_VALID(entry));
4950 
4951 	uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
4952 	uint_fast32_t active = atomic_load_acquire(&entry->active);
4953 
4954 	return (quota != 0 && active >= quota);
4955 }
4956 
4957 void
4958 dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4959 	REQUIRE(DNS_ADB_VALID(adb));
4960 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4961 
4962 	INSIST(atomic_fetch_add_relaxed(&addr->entry->active, 1) != UINT32_MAX);
4963 }
4964 
4965 void
4966 dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
4967 	REQUIRE(DNS_ADB_VALID(adb));
4968 	REQUIRE(DNS_ADBADDRINFO_VALID(addr));
4969 
4970 	INSIST(atomic_fetch_sub_release(&addr->entry->active, 1) != 0);
4971 }
4972