adb.c revision 784d78b831830bf7b53507e742254f9c49295752
94d102893aeb8ecea49dcda64e742835ffe0c102Bob Halley * Copyright (C) 1999-2001 Internet Software Consortium.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * Permission to use, copy, modify, and distribute this software for any
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * purpose with or without fee is hereby granted, provided that the above
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * copyright notice and this permission notice appear in all copies.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley/* $Id: adb.c,v 1.175 2001/04/30 18:27:10 gson Exp $ */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Implementation notes
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * --------------------
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * In finds, if task == NULL, no events will be generated, and no events
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * have been sent. If task != NULL but taskaction == NULL, an event has been
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * posted but not yet freed. If neither are NULL, no event was posted.
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley * After we have cleaned all buckets, dump the database contents.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley#include <isc/string.h> /* Required for HP/UX (and others?) */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley#define DNS_ADBNAMEHOOK_MAGIC 0x61644e48 /* adNH. */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBZONEINFO_MAGIC 0x6164625a /* adbZ. */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBFETCH6_MAGIC 0x61644636 /* adF6. */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * The number of buckets needs to be a prime (for good hashing).
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * XXXRTH How many buckets do we need?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NBUCKETS 1009 /* how many buckets for names/addrs */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * For type 3 negative cache entries, we will remember that the address is
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * broken for this long. XXXMLG This is also used for actual addresses, too.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * The intent is to keep us from constantly asking about A/A6/AAAA records
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * if the zone has extremely low TTLs.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define ADB_CACHE_MAXIMUM 86400 /* seconds (86400 = 24 hours) */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Wake up every CLEAN_SECONDS and clean CLEAN_BUCKETS buckets, so that all
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * buckets are cleaned in CLEAN_PERIOD seconds.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define CLEAN_BUCKETS ((NBUCKETS * CLEAN_SECONDS) / CLEAN_PERIOD)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FREE_ITEMS 64 /* free count for memory pools */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FILL_COUNT 16 /* fill count for memory pools */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define DNS_ADB_INVALIDBUCKET (-1) /* invalid bucket address */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleytypedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleytypedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleytypedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int magic;
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley unsigned int irefcnt;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley unsigned int erefcnt;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * Bucketized locks and lists for names.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * XXXRTH Have a per-bucket structure that contains all of these?
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * Bucketized locks for entries.
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley * XXXRTH Have a per-bucket structure that contains all of these?
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley isc_boolean_t entry_sd[NBUCKETS]; /* shutting down */
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley * XXXMLG Document these structures.
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley unsigned int magic;
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley unsigned int flags;
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley unsigned int chains;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int fetch_err;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int fetch6_err;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int magic;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int magic;
3740b569ae76295b941d57a724a43beb75b533baBob Halley unsigned int flags;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * dns_adbnamehook_t
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * This is a small widget that dangles off a dns_adbname_t. It contains a
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * pointer to the address information about this host, and a link to the next
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * namehook that will contain the next address this host has.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int magic;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * dns_adbzoneinfo_t
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * This is a small widget that holds zone-specific information about an
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * address. Currently limited to lameness, but could just as easily be
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * extended to other types of information about zones.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int magic;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * An address entry. It holds quite a bit of information about addresses,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * including edns state (in "flags"), rtt, and of course the address of
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int magic;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int refcnt;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int flags;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int srtt;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley * A nonzero 'expires' field indicates that the entry should
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * persist until that time. This allows entries found
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * using dns_adb_findaddrinfo() to persist for a limited time
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley * even though they are not necessarily associated with a
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Internal functions (and prototypes).
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void free_adbname(dns_adb_t *, dns_adbname_t **);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halleystatic inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleystatic inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *, dns_name_t *);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleystatic inline void free_adbzoneinfo(dns_adb_t *, dns_adbzoneinfo_t **);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbentry_t *new_adbentry(dns_adb_t *);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleystatic inline dns_adbfind_t *new_adbfind(dns_adb_t *);
3740b569ae76295b941d57a724a43beb75b533baBob Halleystatic inline void free_adbfind(dns_adb_t *, dns_adbfind_t **);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleystatic inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbfetch_t *new_adbfetch(dns_adb_t *);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbfetch6_t *new_adbfetch6(dns_adb_t *, dns_adbname_t *,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline void free_adbfetch6(dns_adb_t *, dns_adbfetch6_t **);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *,
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley unsigned int, int *);
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleystatic inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void print_namehook_list(FILE *, const char *legend,
f0bbac2c0f1afa74b88cab902daf11202ebe7cbdBob Halleystatic void print_find_list(FILE *, dns_adbname_t *);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void print_fetch_list(FILE *, dns_adbname_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic inline void inc_adb_erefcnt(dns_adb_t *, isc_boolean_t);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic inline void dec_adb_erefcnt(dns_adb_t *, isc_boolean_t);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic inline void dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void clean_target(dns_adb_t *, dns_name_t *);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halley unsigned int);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void cancel_fetches_at_name(dns_adbname_t *);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic isc_result_t fetch_name_v4(dns_adbname_t *, isc_boolean_t);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic isc_result_t fetch_name_aaaa(dns_adbname_t *);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic isc_result_t fetch_name_a6(dns_adbname_t *, isc_boolean_t);
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halleystatic void timer_cleanup(isc_task_t *, isc_event_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic inline void link_name(dns_adb_t *, int, dns_adbname_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic inline void unlink_name(dns_adb_t *, dns_adbname_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic inline void link_entry(dns_adb_t *, int, dns_adbentry_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic inline void unlink_entry(dns_adb_t *, dns_adbentry_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic void kill_name(dns_adbname_t **, isc_eventtype_t);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic void fetch_callback_a6(isc_task_t *, isc_event_t *);
1366b7833c86343de278480b9abd71754e418bfaBob Halleystatic isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t);
1366b7833c86343de278480b9abd71754e418bfaBob Halley * MUST NOT overlap DNS_ADBFIND_* flags!
1366b7833c86343de278480b9abd71754e418bfaBob Halley#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
1366b7833c86343de278480b9abd71754e418bfaBob Halley#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halley#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halley#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
bcfcece57e9411ee4bd352b45a8b1ac1dbcf01f4Bob Halley#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * To the name, address classes are all that really exist. If it has a
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * V6 address it doesn't care if it came from an A6 chain or an AAAA query.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley#define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Fetches are broken out into A, AAAA, and A6 types. In some cases,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * however, it makes more sense to test for a particular class of fetches,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * like V4 or V6 above.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NAME_FETCH_A6(n) (!ISC_LIST_EMPTY((n)->fetches_a6))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n) || NAME_FETCH_A6(n))
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley#define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Was this fetch started using the hints database?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Was this the initial fetch for the A6 record? If so, we might want to
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * start AAAA queries if it fails.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FETCH_FIRSTA6(f) (((f)->flags & FETCH_FIRST_A6) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Find options and tests to see if there are addresses on the list.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FIND_STARTATROOT(fn) (((fn)->options & DNS_ADBFIND_STARTATROOT) \
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * These are currently used on simple unsigned ints, so they are
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * not really associated with any particular type.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Find out if the flags on a name (nf) indicate if it is a hint or
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * glue, and compare this to the appropriate bits set in o, to see if
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * this is ok.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Error state rankings.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic const char *errnames[] = {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley "unexpected",
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic isc_result_t find_err_map[FIND_ERR_MAX] = {
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * Requires the adbname bucket be locked and that no entry buckets be locked.
b5b97de45a561784bd88fb8fa7e1464a28ad9a44Bob Halley * This code handles A and AAAA rdatasets only.
b5b97de45a561784bd88fb8fa7e1464a28ad9a44Bob Halleyimport_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley * Lie a little here. This is more or less so code that cares
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * can find out if any new information was added or not.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley DP(ENTER_LEVEL, "ENTER: import_a6() name %p", name);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->partial_result |= DNS_ADBFIND_INET6; /* clear for AAAA */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley isc_sockaddr_fromin6(&sockaddr, &a6ctx->in6addr, 0);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) in import_v6",
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->expire_v6 = ISC_MIN(name->expire_v6, a6ctx->expiration);
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley * Requires the name's bucket be locked.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleykill_name(dns_adbname_t **n, isc_eventtype_t ev) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * If we're dead already, just check to see if we should go
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * away now or not.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Clean up the name's various lists. These two are destructive
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * in that they will always empty the list.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * If fetches are running, cancel them. If none are running, we can
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * just kill the name here.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Requires the name's bucket be locked and no entry buckets be locked.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleycheck_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley * Check to see if we need to remove the v4 addresses
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Check to see if we need to remove the v6 addresses
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Check to see if we need to remove the alias target.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Requires the name's bucket be locked.
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleylink_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ISC_LIST_PREPEND(adb->names[bucket], name, plink);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Requires the name's bucket be locked.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyunlink_name(dns_adb_t *adb, dns_adbname_t *name) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ISC_LIST_UNLINK(adb->names[bucket], name, plink);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Requires the entry's bucket be locked.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
577179503f2eb7695ec668d8eeb41889a150e28fBob Halleylink_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Requires the entry's bucket be locked.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleyunlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyviolate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * The ADB _MUST_ be locked before calling. Also, exit conditions must be
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * checked after calling this function.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley for (bucket = 0 ; bucket < NBUCKETS ; bucket++) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * This bucket has no names. We must decrement the
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * irefcnt ourselves, since it will not be
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * automatically triggered by a name being unlinked.
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley * Run through the list. For each name, clean up finds
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * found there, and cancel any fetches running. When
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * all the fetches are canceled, the name will destroy
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * The ADB _MUST_ be locked before calling. Also, exit conditions must be
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * checked after calling this function.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley for (bucket = 0 ; bucket < NBUCKETS ; bucket++) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * This bucket has no entries. We must decrement the
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * irefcnt ourselves, since it will not be
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * automatically triggered by an entry being unlinked.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Run through the list. Cleanup any entries not
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * associated with names, and which are not in use.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Name bucket must be locked
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Assumes the name bucket is locked.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyclean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Clean up the entry if needed.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Free the namehook
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyclean_target(dns_adb_t *adb, dns_name_t *target) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyset_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Copy the CNAME's target into the target name.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley result = dns_rdata_tostruct(&rdata, &cname, NULL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = dns_name_dup(&cname.cname, adb->mctx, target);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley namereln = dns_name_fullcompare(name, fname, &order,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Get the target name of the DNAME.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = dns_rdata_tostruct(&rdata, &dname, NULL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Construct the new target name.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = dns_name_split(name, nlabels, nbits, prefix, NULL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = dns_name_concatenate(prefix, &dname.dname, new_target,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = dns_name_dup(new_target, adb->mctx, target);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Assumes nothing is locked, since this is called by the client.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Assumes the name bucket is locked.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyclean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int addrs)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if ((notify) != 0) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Unlink the find from the name, letting the caller
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * call dns_adb_destroyfind() on it to clean it up
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley find->result_v6 = find_err_map[name->fetch6_err];
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley "Sending event %p to task %p for find %p",
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley isc_task_sendanddetach(&task, (isc_event_t **)&ev);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * The caller must be holding the adb lock.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * We're now shutdown. Send any whenshutdown events.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * If there aren't any external references either, we're
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * done. Send the control event to initiate shutdown.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleyinc_adb_erefcnt(dns_adb_t *adb, isc_boolean_t lock) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleydec_adb_erefcnt(dns_adb_t *adb, isc_boolean_t lock) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyinc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleydec_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley (adb->entry_sd[bucket] || entry->expires == 0)) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbname_t *
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleynew_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyfree_adbname(dns_adb_t *adb, dns_adbname_t **name) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleynew_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyfree_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
b5b97de45a561784bd88fb8fa7e1464a28ad9a44Bob Halleynew_adbzoneinfo(dns_adb_t *adb, dns_name_t *zone) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (dns_name_dup(zone, adb->mctx, &zi->zone) != ISC_R_SUCCESS) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyfree_adbzoneinfo(dns_adb_t *adb, dns_adbzoneinfo_t **zoneinfo) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(zoneinfo != NULL && DNS_ADBZONEINFO_VALID(*zoneinfo));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbentry_t *
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline void
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyfree_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbfind_t *
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Public members.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * private members
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley "isc_mutex_init failed in new_adbfind()");
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ISC_EVENT_INIT(&h->event, sizeof (isc_event_t), 0, 0, 0, NULL, NULL,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic inline dns_adbfetch_t *
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline void
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyfree_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley * Caller must be holding the name lock.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleya6find(void *arg, dns_name_t *a6name, dns_rdatatype_t type, isc_stdtime_t now,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley return (dns_view_simplefind(adb->view, a6name, type, now,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Caller must be holding the name lock.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleya6missing(dns_a6context_t *a6ctx, dns_name_t *a6name) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley result = dns_resolver_createfetch(adb->view->resolver, a6name,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleynew_adbfetch6(dns_adb_t *adb, dns_adbname_t *name, dns_a6context_t *a6ctx) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline void
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyfree_adbfetch6(dns_adb_t *adb, dns_adbfetch6_t **fetch) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(fetch != NULL && DNS_ADBFETCH6_VALID(*fetch));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline void
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyfree_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Copy bits from the entry into the newly allocated addrinfo. The entry
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * must be locked, and the reference count must be bumped up by one
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * if this function returns a valid pointer.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleynew_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline void
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyfree_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Search for the name. NOTE: The bucket is kept locked on both
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * success and failure, so it must always be unlocked by the caller!
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * On the first call to this function, *bucketp must be set to
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * DNS_ADB_INVALIDBUCKET.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleystatic inline dns_adbname_t *
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyfind_name_and_lock(dns_adb_t *adb, dns_name_t *name,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
return (adbname);
return (NULL);
static inline dns_adbentry_t *
int bucket;
return (entry);
return (NULL);
static isc_boolean_t
return (ISC_FALSE);
return (is_bad);
int bucket;
goto nextv4;
goto out;
goto nextv6;
goto out;
out:
for (i = 0 ; i < CLEAN_BUCKETS ; i++) {
#ifdef DUMP_ADB_AFTER_CLEANING
return (ISC_R_NOMEMORY);
goto fail0b;
goto fail0c;
goto fail0d;
goto fail1;
for (i = 0 ; i < NBUCKETS ; i++) {
for (i = 0 ; i < NBUCKETS ; i++) {
goto fail2;
#define MPINIT(t, p, n) do { \
goto fail3; \
isc_mempool_setname((p), n); \
goto fail3;
goto fail3;
return (ISC_R_SUCCESS);
return (result);
int bucket;
unsigned int wanted_addresses;
unsigned int wanted_fetches;
unsigned int query_pending;
wanted_fetches = 0;
query_pending = 0;
if (now == 0)
return (ISC_R_NOMEMORY);
goto out;
goto out;
adbname);
goto post_copy;
adbname);
goto v6;
adbname);
goto post_copy;
goto fetch;
goto v6;
v6:
adbname);
goto fetch;
adbname);
goto post_copy;
goto fetch;
adbname);
goto fetch;
adbname);
goto post_copy;
goto fetch;
if (wanted_fetches != 0 &&
adbname);
adbname);
if (alias)
if (want_event) {
if (alias) {
goto out;
out:
if (want_event) {
return (result);
int bucket;
int bucket;
int unlock_bucket;
goto cleanup;
if (debug)
for (i = 0 ; i < NBUCKETS ; i++)
for (i = 0 ; i < NBUCKETS ; i++)
for (i = 0 ; i < NBUCKETS ; i++) {
if (debug)
if (debug)
if (debug)
if (debug)
for (i = 0; i < NBUCKETS; i++)
for (i = 0; i < NBUCKETS; i++)
if (debug)
const char *tmpp;
case AF_INET:
case AF_INET6:
if (debug)
if (NAME_FETCH_A(n))
if (NAME_FETCH_AAAA(n))
static isc_result_t
switch (result) {
case DNS_R_GLUE:
case DNS_R_HINT:
case ISC_R_SUCCESS:
case DNS_R_NXDOMAIN:
case DNS_R_NXRRSET:
adbname);
adbname);
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
case DNS_R_CNAME:
case DNS_R_DNAME:
adbname);
return (result);
static isc_result_t
switch (result) {
case DNS_R_GLUE:
case DNS_R_HINT:
case ISC_R_SUCCESS:
case DNS_R_NXDOMAIN:
case DNS_R_NXRRSET:
adbname);
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
case DNS_R_CNAME:
case DNS_R_DNAME:
adbname);
return (result);
int bucket;
unsigned int address_type;
address_type = 0;
if (want_check_exit) {
goto out;
name);
goto check_result;
goto out;
out:
int bucket;
if (want_check_exit) {
name);
goto out;
name);
goto out;
goto out;
name);
goto out;
goto out;
out:
static isc_result_t
if (start_at_root) {
adbname);
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
static isc_result_t
goto cleanup;
goto cleanup;
return (result);
static isc_result_t
if (start_at_root) {
adbname);
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
int bucket;
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
int bucket;
unsigned int new_srtt;
int bucket;
int bucket;
goto unlock;
goto unlock;
return (result);
int bucket;
if (want_check_exit) {
for (i = 0 ; i < NBUCKETS ; i++) {
#ifdef DUMP_ADB_AFTER_CLEANING