"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/lib/dns/adb.c" (4 Sep 2020, 125480 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "adb.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.3_vs_9.17.4.

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