adb.c revision 1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Copyright (C) 1999-2001 Internet Software Consortium.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Permission to use, copy, modify, and distribute this software for any
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * purpose with or without fee is hereby granted, provided that the above
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * copyright notice and this permission notice appear in all copies.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff/* $Id: adb.c,v 1.195 2001/11/30 01:59:03 gson Exp $ */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Implementation notes
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * --------------------
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * In finds, if task == NULL, no events will be generated, and no events
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * have been sent. If task != NULL but taskaction == NULL, an event has been
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * posted but not yet freed. If neither are NULL, no event was posted.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * After we have cleaned all buckets, dump the database contents.
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff#include <isc/string.h> /* Required for HP/UX (and others?) */
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
439c0011e642fb1d26011116144af698125262dbMichael Graff#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBZONEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * The number of buckets needs to be a prime (for good hashing).
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * XXXRTH How many buckets do we need?
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define NBUCKETS 1009 /* how many buckets for names/addrs */
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * For type 3 negative cache entries, we will remember that the address is
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * broken for this long. XXXMLG This is also used for actual addresses, too.
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * The intent is to keep us from constantly asking about A/A6/AAAA records
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * if the zone has extremely low TTLs.
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff#define ADB_CACHE_MAXIMUM 86400 /* seconds (86400 = 24 hours) */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * Wake up every CLEAN_SECONDS and clean CLEAN_BUCKETS buckets, so that all
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * buckets are cleaned in CLEAN_PERIOD seconds.
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define CLEAN_BUCKETS ((NBUCKETS * CLEAN_SECONDS) / CLEAN_PERIOD)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define FREE_ITEMS 64 /* free count for memory pools */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define FILL_COUNT 16 /* fill count for memory pools */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define DNS_ADB_INVALIDBUCKET (-1) /* invalid bucket address */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#define DNS_ADB_MINADBSIZE (1024*1024) /* 1 Megabyte */
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Grafftypedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Grafftypedef struct dns_adbnamehook dns_adbnamehook_t;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Grafftypedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Grafftypedef struct dns_adbzoneinfo dns_adbzoneinfo_t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Grafftypedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley unsigned int magic;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mutex_t reflock; /* Covers irefcnt, erefcnt */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley unsigned int irefcnt;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int erefcnt;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Bucketized locks and lists for names.
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * XXXRTH Have a per-bucket structure that contains all of these?
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * Bucketized locks for entries.
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff * XXXRTH Have a per-bucket structure that contains all of these?
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley isc_boolean_t entry_sd[NBUCKETS]; /* shutting down */
59c049874bbef182857c57bd9cca292898921c69Bob Halley * XXXMLG Document these structures.
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned int magic;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int flags;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley unsigned int chains;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int magic;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff unsigned int magic;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley unsigned int flags;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * dns_adbnamehook_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * This is a small widget that dangles off a dns_adbname_t. It contains a
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * pointer to the address information about this host, and a link to the next
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * namehook that will contain the next address this host has.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int magic;
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * dns_adbzoneinfo_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * This is a small widget that holds zone-specific information about an
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * address. Currently limited to lameness, but could just as easily be
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * extended to other types of information about zones.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int magic;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * An address entry. It holds quite a bit of information about addresses,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * including edns state (in "flags"), rtt, and of course the address of
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff unsigned int magic;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned int refcnt;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int flags;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int srtt;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * A nonzero 'expires' field indicates that the entry should
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * persist until that time. This allows entries found
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * using dns_adb_findaddrinfo() to persist for a limited time
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff * even though they are not necessarily associated with a
439c0011e642fb1d26011116144af698125262dbMichael Graff * Internal functions (and prototypes).
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graffstatic inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbname(dns_adb_t *, dns_adbname_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *, dns_name_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbzoneinfo(dns_adb_t *, dns_adbzoneinfo_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbentry_t *new_adbentry(dns_adb_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline dns_adbfind_t *new_adbfind(dns_adb_t *);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffstatic inline void free_adbfind(dns_adb_t *, dns_adbfind_t **);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffstatic inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *,
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbfetch_t *new_adbfetch(dns_adb_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbfetch6_t *new_adbfetch6(dns_adb_t *, dns_adbname_t *,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graffstatic inline void free_adbfetch6(dns_adb_t *, dns_adbfetch6_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *,
439c0011e642fb1d26011116144af698125262dbMichael Graff unsigned int, int *);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic void print_dns_name(FILE *, dns_name_t *);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic void print_namehook_list(FILE *, const char *legend,
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic void print_find_list(FILE *, dns_adbname_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic void print_fetch_list(FILE *, dns_adbname_t *);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffstatic inline void dec_adb_irefcnt(dns_adb_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void inc_adb_erefcnt(dns_adb_t *);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic inline void dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleystatic inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic void clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic void clean_target(dns_adb_t *, dns_name_t *);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley unsigned int);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void check_expire_namehooks(dns_adbname_t *, isc_stdtime_t,
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic void cancel_fetches_at_name(dns_adbname_t *);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffstatic isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic isc_result_t fetch_name_v4(dns_adbname_t *, isc_boolean_t);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic isc_result_t fetch_name_aaaa(dns_adbname_t *);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic isc_result_t fetch_name_a6(dns_adbname_t *, isc_boolean_t);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic void timer_cleanup(isc_task_t *, isc_event_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic inline void link_name(dns_adb_t *, int, dns_adbname_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void unlink_name(dns_adb_t *, dns_adbname_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic inline void link_entry(dns_adb_t *, int, dns_adbentry_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic inline void unlink_entry(dns_adb_t *, dns_adbentry_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic void kill_name(dns_adbname_t **, isc_eventtype_t);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic void fetch_callback_a6(isc_task_t *, isc_event_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff * MUST NOT overlap DNS_ADBFIND_* flags!
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_STARTATROOT DNS_ADBFIND_STARTATROOT
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * To the name, address classes are all that really exist. If it has a
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * V6 address it doesn't care if it came from an A6 chain or an AAAA query.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff#define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4))
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff#define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6))
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff#define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Fetches are broken out into A, AAAA, and A6 types. In some cases,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * however, it makes more sense to test for a particular class of fetches,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * like V4 or V6 above.
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_A6(n) (!ISC_LIST_EMPTY((n)->fetches_a6))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n) || NAME_FETCH_A6(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Was this fetch started using the hints database?
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Was this the initial fetch for the A6 record? If so, we might want to
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * start AAAA queries if it fails.
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley#define FETCH_FIRSTA6(f) (((f)->flags & FETCH_FIRST_A6) != 0)
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * Find options and tests to see if there are addresses on the list.
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_STARTATROOT(fn) (((fn)->options & DNS_ADBFIND_STARTATROOT) \
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
78854e02c127f31ab90f56da0531542004b45377Michael Graff#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
78854e02c127f31ab90f56da0531542004b45377Michael Graff#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * These are currently used on simple unsigned ints, so they are
78854e02c127f31ab90f56da0531542004b45377Michael Graff * not really associated with any particular type.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0)
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley#define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0)
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * Find out if the flags on a name (nf) indicate if it is a hint or
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * glue, and compare this to the appropriate bits set in o, to see if
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * this is ok.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define STARTATROOT_MATCHES(nf, o) (((nf)->flags & NAME_STARTATROOT) == \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * Error state rankings.
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graffstatic const char *errnames[] = {
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff "unexpected",
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NEWERR(old, new) (ISC_MIN((old), (new)))
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graffstatic isc_result_t find_err_map[FIND_ERR_MAX] = {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael GraffDP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * Requires the adbname bucket be locked and that no entry buckets be locked.
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * This code handles A and AAAA rdatasets only.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyimport_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff dns_adbentry_t *foundentry; /* NO CLEAN UP! */
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * Lie a little here. This is more or less so code that cares
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * can find out if any new information was added or not.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbentry_t *foundentry; /* NO CLEAN UP! */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff DP(ENTER_LEVEL, "ENTER: import_a6() name %p", name);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff name->partial_result |= DNS_ADBFIND_INET6; /* clear for AAAA */
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_sockaddr_fromin6(&sockaddr, &a6ctx->in6addr, 0);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) in import_v6",
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff name->expire_v6 = ISC_MIN(name->expire_v6, a6ctx->expiration);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Requires the name's bucket be locked.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffkill_name(dns_adbname_t **n, isc_eventtype_t ev) {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * If we're dead already, just check to see if we should go
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff * away now or not.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Clean up the name's various lists. These two are destructive
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * in that they will always empty the list.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * If fetches are running, cancel them. If none are running, we can
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * just kill the name here.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Requires the name's bucket be locked and no entry buckets be locked.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffcheck_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now,
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Check to see if we need to remove the v4 addresses
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Check to see if we need to remove the v6 addresses
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Check to see if we need to remove the alias target.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (expire || EXPIRE_OK(name->expire_target, now)) {
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff * Requires the name's bucket be locked.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic inline void
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Grafflink_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff ISC_LIST_PREPEND(adb->names[bucket], name, plink);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Requires the name's bucket be locked.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic inline void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleyunlink_name(dns_adb_t *adb, dns_adbname_t *name) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley ISC_LIST_UNLINK(adb->names[bucket], name, plink);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Requires the entry's bucket be locked.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic inline void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleylink_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Requires the entry's bucket be locked.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyunlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic inline void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleyviolate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * The ADB _MUST_ be locked before calling. Also, exit conditions must be
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * checked after calling this function.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * This bucket has no names. We must decrement the
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * irefcnt ourselves, since it will not be
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * automatically triggered by a name being unlinked.
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Run through the list. For each name, clean up finds
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * found there, and cancel any fetches running. When
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * all the fetches are canceled, the name will destroy
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * The ADB _MUST_ be locked before calling. Also, exit conditions must be
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * checked after calling this function.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff for (bucket = 0; bucket < NBUCKETS; bucket++) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * This bucket has no entries. We must decrement the
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * irefcnt ourselves, since it will not be
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * automatically triggered by an entry being unlinked.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Run through the list. Cleanup any entries not
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * associated with names, and which are not in use.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Name bucket must be locked
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Assumes the name bucket is locked.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleyclean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Clean up the entry if needed.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Free the namehook
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyclean_target(dns_adb_t *adb, dns_name_t *target) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyset_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Copy the CNAME's target into the target name.
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff result = dns_rdata_tostruct(&rdata, &cname, NULL);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff result = dns_name_dup(&cname.cname, adb->mctx, target);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff INSIST(rdataset->type == dns_rdatatype_dname);
78854e02c127f31ab90f56da0531542004b45377Michael Graff namereln = dns_name_fullcompare(name, fname, &order,
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Get the target name of the DNAME.
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = dns_rdata_tostruct(&rdata, &dname, NULL);
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Construct the new target name.
78854e02c127f31ab90f56da0531542004b45377Michael Graff result = dns_name_split(name, nlabels, nbits, prefix, NULL);
875e88e734b310976b178dc26a74d86fbebc935cBob Halley result = dns_name_concatenate(prefix, &dname.dname, new_target,
875e88e734b310976b178dc26a74d86fbebc935cBob Halley result = dns_name_dup(new_target, adb->mctx, target);
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Assumes nothing is locked, since this is called by the client.
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Assumes the name bucket is locked.
78854e02c127f31ab90f56da0531542004b45377Michael Graffclean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
78854e02c127f31ab90f56da0531542004b45377Michael Graff unsigned int addrs)
78854e02c127f31ab90f56da0531542004b45377Michael Graff "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if ((notify) != 0) {
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Unlink the find from the name, letting the caller
59c049874bbef182857c57bd9cca292898921c69Bob Halley * call dns_adb_destroyfind() on it to clean it up
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff find->result_v4 = find_err_map[name->fetch_err];
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff find->result_v6 = find_err_map[name->fetch6_err];
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff "sending event %p to task %p for find %p",
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_task_sendanddetach(&task, (isc_event_t **)&ev);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff DP(DEF_LEVEL, "cfan: skipping find %p", find);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic inline void
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff * The caller must be holding the adb lock.
439c0011e642fb1d26011116144af698125262dbMichael Graff * We're now shutdown. Send any whenshutdown events.
439c0011e642fb1d26011116144af698125262dbMichael Graff ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
439c0011e642fb1d26011116144af698125262dbMichael Graff * If there aren't any external references either, we're
439c0011e642fb1d26011116144af698125262dbMichael Graff * done. Send the control event to initiate shutdown.
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(!adb->cevent_sent); /* Sanity check. */
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Graffinc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffdec_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff (adb->entry_sd[bucket] || entry->expires == 0)) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffnew_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Grafffree_adbname(dns_adb_t *adb, dns_adbname_t **name) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffnew_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Grafffree_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
439c0011e642fb1d26011116144af698125262dbMichael Graffnew_adbzoneinfo(dns_adb_t *adb, dns_name_t *zone) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (dns_name_dup(zone, adb->mctx, &zi->zone) != ISC_R_SUCCESS) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbzoneinfo(dns_adb_t *adb, dns_adbzoneinfo_t **zoneinfo) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(zoneinfo != NULL && DNS_ADBZONEINFO_VALID(*zoneinfo));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Public members.
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff * private members
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff "isc_mutex_init failed in new_adbfind()");
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleystatic inline void
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleyfree_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Caller must be holding the name lock.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleya6find(void *arg, dns_name_t *a6name, dns_rdatatype_t type, isc_stdtime_t now,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley result = dns_view_simplefind(adb->view, a6name, type, now,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Caller must be holding the name lock.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleya6missing(dns_a6context_t *a6ctx, dns_name_t *a6name) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley result = dns_resolver_createfetch(adb->view->resolver, a6name,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleynew_adbfetch6(dns_adb_t *adb, dns_adbname_t *name, dns_a6context_t *a6ctx) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline void
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Grafffree_adbfetch6(dns_adb_t *adb, dns_adbfetch6_t **fetch) {
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(fetch != NULL && DNS_ADBFETCH6_VALID(*fetch));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff * Copy bits from the entry into the newly allocated addrinfo. The entry
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff * must be locked, and the reference count must be bumped up by one
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff * if this function returns a valid pointer.
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffnew_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff * Search for the name. NOTE: The bucket is kept locked on both
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * success and failure, so it must always be unlocked by the caller!
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * On the first call to this function, *bucketp must be set to
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * DNS_ADB_INVALIDBUCKET.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffind_name_and_lock(dns_adb_t *adb, dns_name_t *name,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Search for the address. NOTE: The bucket is kept locked on both
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * success and failure, so it must always be unlocked by the caller.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * On the first call to this function, *bucketp must be set to
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * DNS_ADB_INVALIDBUCKET. This will cause a lock to occur. On
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * later calls (within the same "lock path") it can be left alone, so
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * if this function is called multiple times locking is only done if
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * the bucket changes.
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Grafffind_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff bucket = isc_sockaddr_hash(addr, ISC_TRUE) % NBUCKETS;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (isc_sockaddr_equal(addr, &entry->sockaddr))
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * Entry bucket MUST be locked!
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffentry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Has the entry expired?
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Order tests from least to most expensive.
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graffcopy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff && entry_is_bad_for_zone(adb, entry, zone, now)) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff addrinfo = new_adbaddrinfo(adb, entry, find->port);
439c0011e642fb1d26011116144af698125262dbMichael Graff * Found a valid entry. Add it to the find's list.
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff ISC_LIST_APPEND(find->list, addrinfo, publink);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff if (entry_is_bad_for_zone(adb, entry, zone, now))
59c049874bbef182857c57bd9cca292898921c69Bob Halley addrinfo = new_adbaddrinfo(adb, entry, find->port);
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Found a valid entry. Add it to the find's list.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff ISC_LIST_APPEND(find->list, addrinfo, publink);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graffshutdown_task(isc_task_t *task, isc_event_t *ev) {
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * Kill the timer, and then the ADB itself. Note that this implies
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * that this task was the one scheduled to get timer events. If
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * this is not true (and it is unfortunate there is no way to INSIST()
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * this) badness will occur.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Name bucket must be locked; adb may be locked; no other locks held.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleycheck_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * The name is empty. Delete it.
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * Our caller, or one of its callers, will be calling check_exit() at
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * some point, so we don't need to do it here.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Entry bucket must be locked; adb may be locked; no other locks held.
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graffcheck_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now)
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (entry->expires == 0 || (! expire && entry->expires > now))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * The entry is not in use. Delete it.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * ADB must be locked, and no other locks held.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffcleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * ADB must be locked, and no other locks held.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graffcleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Grafftimer_cleanup(isc_task_t *task, isc_event_t *ev) {
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff unsigned int i;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff for (i = 0; i < CLEAN_BUCKETS; i++) {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff * Call our cleanup routines.
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff cleanup_names(adb, adb->next_cleanbucket, now);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff cleanup_entries(adb, adb->next_cleanbucket, now);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff * Set the next bucket to be cleaned.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Reset the timer.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * XXXDCL isc_timer_reset might return ISC_R_UNEXPECTED or
fbcf7bc351f2d42d338cb1fa29e59babd9bee94eMichael Graff * ISC_R_NOMEMORY, but it isn't clear what could be done here
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff * if either one of those things happened.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff (void)isc_timer_reset(adb->timer, isc_timertype_once, NULL,
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * The timer is already dead, from the task's shutdown callback.
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Public functions.
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffdns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * Initialize things here that cannot fail, and especially things
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff * that must be NULL for the error return to work properly.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff * Initialize the bucket locks for names and elements.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff * May as well initialize the list heads, too.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff result = isc_mutexblock_init(adb->namelocks, NBUCKETS);
e485d16462b0a66b835107fae04fe9d562e77af0Bob Halley for (i = 0; i < NBUCKETS; i++) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff for (i = 0; i < NBUCKETS; i++) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = isc_mutexblock_init(adb->entrylocks, NBUCKETS);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Memory pools
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff#define MPINIT(t, p, n) do { \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff result = isc_mempool_create(mem, sizeof(t), &(p)); \
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_associatelock((p), &adb->mplock); \
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbzoneinfo_t, adb->zimp, "adbzoneinfo");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbfetch6_t, adb->af6mp, "adbfetch6");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Allocate a timer and a task for our periodic cleanup.
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = isc_task_create(adb->taskmgr, 0, &adb->task);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * XXXMLG When this is changed to be a config file option,
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_interval_set(&adb->tick_interval, CLEAN_SECONDS, 0);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff result = isc_timer_create(adb->timermgr, isc_timertype_once,
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff "%u buckets every %u seconds, %u buckets in system, %u cl.interval",
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff CLEAN_BUCKETS, CLEAN_SECONDS, NBUCKETS, CLEAN_PERIOD);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff * Normal return.
59c049874bbef182857c57bd9cca292898921c69Bob Halley /* clean up entrylocks */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
59c049874bbef182857c57bd9cca292898921c69Bob Halleydns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) {
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graffdns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Send '*eventp' to 'task' when 'adb' has shutdown.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * We're already shutdown. Send the event.
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff ISC_LIST_APPEND(adb->whenshutdown, event, ev_link);
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff * Shutdown 'adb'.
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff isc_mem_setwater(adb->mctx, water, adb, 0, 0);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffdns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff void *arg, dns_name_t *name, dns_name_t *zone,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff unsigned int options, isc_stdtime_t now, dns_name_t *target,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_boolean_t want_event, start_at_root, alias, have_address;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff REQUIRE(target == NULL || dns_name_hasbuffer(target));
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK);
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff * XXXMLG Move this comment somewhere else!
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Look up the name in our internal database.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Possibilities: Note that these are not always exclusive.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * No name found. In this case, allocate a new name header and
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * an initial namehook or two. If any of these allocations
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * fail, clean up and return ISC_R_NOMEMORY.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Name found, valid addresses present. Allocate one addrinfo
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * structure for each found and append it to the linked list
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * of addresses for this header.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Name found, queries pending. In this case, if a task was
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * passed in, allocate a job id, attach it to the name's job
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * list and remember to tell the caller that there will be
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff * more info coming later.
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Remember what types of addresses we are interested in.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Try to see if we know anything about this name at all.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley adbname = find_name_and_lock(adb, name, find->options, &bucket);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "dns_adb_createfind: returning ISC_R_SHUTTINGDOWN");
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Nothing found. Allocate a new adbname structure for this name.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Expire old entries, etc.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley check_expire_namehooks(adbname, now, adb->overmem);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Do we know that the name is an alias?
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Yes, it is.
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley "dns_adb_createfind: name %p is an alias (cached)",
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * Try to populate the name from the database and/or
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * start fetches. First try looking for an A record
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * in the database.
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley if (!NAME_HAS_V4(adbname) && !NAME_FETCH_V4(adbname)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = dbfind_name(adbname, now, dns_rdatatype_a);
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley "dns_adb_createfind: found A for name %p in db",
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Did we get a CNAME or DNAME?
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley "dns_adb_createfind: name %p is an alias",
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * If the name doesn't exist at all, don't bother with
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley * v6 queries; they won't work.
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * If the name does exist but we didn't get our data, go
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * ahead and try a6.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * If the result is neither of these, try a fetch for A.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (!NAME_HAS_V6(adbname) && !NAME_FETCH_V6(adbname)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff "dns_adb_createfind: found A6 for name %p",
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * Did we get a CNAME or DNAME?
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff "dns_adb_createfind: name %p is an alias",
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * If the name doesn't exist at all, jump to the fetch
b5492be2c7c3792a1b6c03995fe378703fc814cbMichael Graff * code. Otherwise, we'll try AAAA.
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
5a675fa40aa755b21ab2906e90b1b80e2105291fMichael Graff "dns_adb_createfind: found AAAA for name %p",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Did we get a CNAME or DNAME? This should have hit
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * during the A6 query, but we'll reproduce it here Just
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "dns_adb_createfind: name %p is an alias",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Listen to negative cache hints, and don't start
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * another query.
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ! (FIND_AVOIDFETCHES(find) && have_address)) {
439c0011e642fb1d26011116144af698125262dbMichael Graff * We're missing at least one address family. Either the
439c0011e642fb1d26011116144af698125262dbMichael Graff * caller hasn't instructed us to avoid fetches, or we don't
439c0011e642fb1d26011116144af698125262dbMichael Graff * know anything about any of the address families that would
3c5148c4d98af51d6dcb449c6dbd45fe8c645f61Michael Graff * be acceptable so we have to launch fetches.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fetch_name_v4(adbname, start_at_root) == ISC_R_SUCCESS) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff "dns_adb_createfind: started A fetch for name %p",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fetch_name_a6(adbname, start_at_root) == ISC_R_SUCCESS) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff "dns_adb_createfind: started A6 fetch for name %p",
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Run through the name and copy out the bits we are
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * interested in.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley copy_namehook_lists(adb, find, zone, adbname, now);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Attach to the name's query list if there are queries
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * already running, and we have been asked to.
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find))
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->query_pending = (query_pending & wanted_addresses);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK);
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p",
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Remove the flag so the caller knows there will never
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * be an event, and set internal flags to fake that
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff * the event was sent and freed, so dns_adb_destroyfind() will
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff * do the right thing.
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff find->query_pending = (query_pending & wanted_addresses);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->partial_result |= (adbname->partial_result & wanted_addresses);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = dns_name_copy(&adbname->target, target, NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Copy out error flags from the name structure into the find.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->result_v4 = find_err_map[adbname->fetch_err];
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->result_v6 = find_err_map[adbname->fetch6_err];
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff * The find doesn't exist on any list, and nothing is locked.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Return the find to the memory pool, and decrement the adb's
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * reference count.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * WARNING: The find is freed with the adb locked. This is done
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * to avoid a race condition where we free the find, some other
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * thread tests to see if it should be destroyed, detects it should
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * be, destroys it, and then we try to lock it for our check, but the
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * lock is destroyed.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * We need to get the adbname's lock to unlink the find.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff ISC_LIST_UNLINK(find->adbname->finds, find, plink);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff DP(DEF_LEVEL, "sending event %p to task %p for find %p",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_task_sendanddetach(&task, (isc_event_t **)&ev);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Lock the adb itself, lock all the name buckets, then lock all
08d131595373326ec4a3af793b536df8c33115ecMichael Graff * the entry buckets. This should put the adb into a state where
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * nothing can change, so we can iterate through everything and
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * print at our leisure.
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffdump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff fprintf(f, " [%s TTL %d]", legend, value - now);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffdump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug) {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff fprintf(f, ";\n; Address database dump\n;\n");
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff for (i = 0; i < NBUCKETS; i++)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff for (i = 0; i < NBUCKETS; i++)
a44bd6a6edccd4c8e3884a13fcff037e7e2dd868Michael Graff * Dump the names
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff for (i = 0; i < NBUCKETS; i++) {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (dns_name_countlabels(&name->target) > 0) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dump_ttl(f, "target", name->expire_target, now);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff print_namehook_list(f, "v4", &name->v4, debug);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff print_namehook_list(f, "v6", &name->v6, debug);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * Unlock everything
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff for (i = 0; i < NBUCKETS; i++)
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff for (i = 0; i < NBUCKETS; i++)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffdump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, ";\t%s [srtt %u]", addrbuf, entry->srtt);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffdns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff * Not used currently, in the API Just In Case we
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff * want to dump out the name and/or entries too.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff find->name_bucket, find->adbname, find->event.ev_sender);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff " srtt %u addr %s\n",
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graffprint_namehook_list(FILE *f, const char *legend, dns_adbnamehooklist_t *list,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffprint_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, "\t\tFetch(%s): %p -> { nh %p, entry %p, fetch %p }\n",
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff type, ft, ft->namehook, ft->entry, ft->fetch);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, "\t\tFetch(A6): %p -> { nh %p, entry %p, fetch %p }\n",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffprint_find_list(FILE *f, dns_adbname_t *name) {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffdbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype)
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff result = dns_view_find(adb->view, &adbname->name, rdtype, now,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * Found in the database. Even if we can't copy out
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * any information, return success, or else a fetch
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * will be made, which will only make things worse.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff result = import_rdataset(adbname, &rdataset, now);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * We're authoritative and the data doesn't exist.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * Make up a negative cache entry so we don't ask again
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * for a while.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * XXXRTH What time should we use? I'm putting in 30 seconds
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff "adb name %p: Caching auth negative entry for A",
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff "adb name %p: Caching auth negative entry for AAAA",
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * We found a negative cache entry. Pull the TTL from it
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * so we won't ask again for a while.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff "adb name %p: Caching negative entry for A (ttl %u)",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff "adb name %p: Caching negative entry for AAAA (ttl %u)",
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * Clear the hint and glue flags, so this will match
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * more often.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff result = set_target(adb, &adbname->name, fname, &rdataset,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "adb name %p: caching alias target",
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halleydbfind_a6(dns_adbname_t *adbname, isc_stdtime_t now) {
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff result = dns_view_find(adb->view, &adbname->name, dns_rdatatype_a6,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Start A6 chain follower. There is no need to poke people
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * who might be waiting, since this is call requires there
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * We're authoritative and the data doesn't exist.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Make up a negative cache entry so we don't ask again
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * for a while.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * XXXRTH What time should we use? I'm putting in 30 seconds
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "adb name %p: Caching auth negative entry for A6",
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * We found a negative cache entry. Pull the TTL from it
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * so we won't ask again for a while.
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff "adb name %p: Caching negative entry for A6 (ttl %u)",
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff result = set_target(adb, &adbname->name, fname, &rdataset,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff "adb name %p: caching alias target",
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyfetch_callback(isc_task_t *task, isc_event_t *ev) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * Cleanup things we don't care about.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * If this name is marked as dead, clean up, throwing away
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * potentially good data.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * If we're shutting down and this bucket is empty, we need
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * to call check_exit() to see if we're done.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff * If we got a negative cache response, remember it.
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "caching negative entry for A (ttl %u)",
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff "caching negative entry for AAAA (ttl %u)",
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley "adb fetch name %p: caching alias target",
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->expire_target = dev->rdataset->ttl + now;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Did we get back junk? If so, and there are no more fetches
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * sitting out there, tell all the finds about it.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /* XXXMLG Don't pound on bad servers. */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name->expire_v4 = ISC_MIN(name->expire_v4, now + 300);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name->expire_v6 = ISC_MIN(name->expire_v6, now + 300);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * We got something potentially useful.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff result = import_rdataset(name, &fetch->rdataset, now);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley clean_finds_at_name(name, ev_status, address_type);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleyfetch_callback_a6(isc_task_t *task, isc_event_t *ev) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff ISC_LIST_UNLINK(name->fetches_a6, fetch, plink);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff DP(ENTER_LEVEL, "ENTER: fetch_callback_a6() name %p", name);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Cleanup things we don't care about.
59c049874bbef182857c57bd9cca292898921c69Bob Halley * If this name is marked as dead, clean up, throwing away
59c049874bbef182857c57bd9cca292898921c69Bob Halley * potentially good data.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * If we're shutting down and this bucket is empty, we need
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * to call check_exit() to see if we're done.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * If the A6 query didn't succeed, and this is the first query
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * in the A6 chain, try AAAA records instead. For later failures,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * don't do this.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * If we got a negative cache response, remember it.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley "caching negative entry for A6 (ttl %u)",
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff "adb A6 fetch name %p: caching alias target",
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Make this name 'pokeable', since
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * we've learned that this name is an
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff if (FETCH_FIRSTA6(fetch) && !NAME_HAS_V6(name)) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley "name %p: A6 query failed, starting AAAA", name);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Since this is the very first fetch, and it
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * failed, we know there are no more running.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff result = dbfind_name(name, now, dns_rdatatype_aaaa);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "name %p: callback_a6: Found AAAA for",
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley * Listen to negative cache hints, and don't start
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley * another query.
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley name->fetch6_err = NEWERR(name->fetch6_err, FIND_ERR_NXDOMAIN);
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley name->fetch6_err = NEWERR(name->fetch6_err, FIND_ERR_NXRRSET);
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley * Try to start fetches for AAAA.
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley "name %p: callback_a6: Started AAAA fetch",
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * We got something potentially useful. Run the A6 chain
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * follower on this A6 rdataset.
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff (void)dns_a6_foreach(&fetch->a6ctx, dev->rdataset, now);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff clean_finds_at_name(name, DNS_EVENT_ADBMOREADDRESSES,
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff clean_finds_at_name(name, DNS_EVENT_ADBNOMOREADDRESSES,
14b98cb34eda66c87ce41a207704a2c232280eafMichael Grafffetch_name_v4(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff unsigned int options;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley DP(50, "fetch_name_v4: starting at DNS root for name %p",
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = dns_view_simplefind(adb->view, name, dns_rdatatype_ns,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff fetch = NULL; /* Keep us from cleaning this up below. */
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff/* XXXMLG Why doesn't this look a lot like fetch_name_a and fetch_name_a6? */
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff fetch = NULL; /* Keep us from cleaning this up below. */
528829aa8ad69238e674cd81078bc14d4199691bMichael Grafffetch_name_a6(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff unsigned int options;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley DP(50, "fetch_name_a6: starting at DNS root for name %p",
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff result = dns_view_simplefind(adb->view, name, dns_rdatatype_ns,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff ISC_LIST_APPEND(adbname->fetches_a6, fetch, plink);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff fetch = NULL; /* Keep us from cleaning this up below. */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * XXXMLG Needs to take a find argument and an address info, no zone or adb,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * since these can be extracted from the find itself.
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffdns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone,
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff ISC_LIST_PREPEND(addr->entry->zoneinfo, zi, plink);
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graffdns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
ca924f706b53b895a662de8345d88437b23b8f01Michael Graffdns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff * Note that we do not update the other bits in addr->flags with
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff * the most recent values from addr->entry->flags.
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff addr->flags = (addr->flags & ~mask) | (bits & mask);
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graffdns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
42fe494186d386ddda15eb9403038c3558bbd5bfMichael Graff entry = find_entry_and_lock(adb, sa, &bucket);
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff * We don't know anything about this address.
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff DP(50, "findaddrinfo: found entry %p", entry);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley unsigned int i;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley for (i = 0; i < NBUCKETS; i++) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Call our cleanup routines.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
if (overmem) {