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