bd911976d51f102751848568ccf56592fd5f6d77Tinderbox User * Copyright (C) 1999-2017 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * 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
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * posted but not yet freed. If neither are NULL, no event was posted.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#include <isc/string.h> /* Required for HP/UX (and others?) */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael 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)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrews#define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * For type 3 negative cache entries, we will remember that the address is
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff * broken for this long. XXXMLG This is also used for actual addresses, too.
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews * The intent is to keep us from constantly asking about A/AAAA records
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff * if the zone has extremely low TTLs.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * The period in seconds after which an ADB name entry is regarded as stale
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * and forced to be cleaned up.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * TODO: This should probably be configurable at run-time.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FREE_ITEMS 64 /*%< free count for memory pools */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FILL_COUNT 16 /*%< fill count for memory pools */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */
f3350b671881f175d03e16fa5d0f685a1691bcabMark Andrews#define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Grafftypedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Grafftypedef struct dns_adbnamehook dns_adbnamehook_t;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Grafftypedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewstypedef struct dns_adblameinfo dns_adblameinfo_t;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafftypedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% dns adb structure */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mutex_t overmemlock; /*%< Covers overmem */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *limp; /*%< dns_adblameinfo_t */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *emp; /*%< dns_adbentry_t */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *ahmp; /*%< dns_adbfind_t */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *afmp; /*%< dns_adbfetch_t */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Bucketized locks and lists for names.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * XXXRTH Have a per-bucket structure that contains all of these?
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Bucketized locks and lists for entries.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * XXXRTH Have a per-bucket structure that contains all of these?
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * XXXMLG Document these structures.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% dns_adbname structure */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* for LRU-based management */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% The adbfetch structure */
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.
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrews * This is a small widget that holds qname-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 * An address entry. It holds quite a bit of information about addresses,
57ecc983c0b37ce7dbccf28f44c6bffdfd6491f7Andreas Gustafsson * including edns state (in "flags"), rtt, and of course the address of
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews * Allow for encapsulated IPv4/IPv6 UDP packet over ethernet.
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews * Ethernet 1500 - IP(20) - IP6(40) - UDP(8) = 1432.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * A nonzero 'expires' field indicates that the entry should
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * persist until that time. This allows entries found
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * using dns_adb_findaddrinfo() to persist for a limited time
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * even though they are not necessarily associated with a
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Internal functions (and prototypes).
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael 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 *,
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewsstatic inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *,
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewsstatic inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbentry_t *new_adbentry(dns_adb_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline dns_adbfind_t *new_adbfind(dns_adb_t *);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic inline isc_boolean_t free_adbfind(dns_adb_t *, dns_adbfind_t **);
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graffstatic inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline dns_adbfetch_t *new_adbfetch(dns_adb_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int, int *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *,
dd95acdbce0e2a2775391709cdfca0a9eda7e8f7Mark Andrewsstatic void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug, isc_stdtime_t);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic void print_dns_name(FILE *, dns_name_t *);
5fca48054b5e791a2fa0c5015bc3b6fef4fcdce1Andreas Gustafssonstatic void print_namehook_list(FILE *, const char *legend,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic void print_find_list(FILE *, dns_adbname_t *);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graffstatic void print_fetch_list(FILE *, dns_adbname_t *);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic inline isc_boolean_t dec_adb_irefcnt(dns_adb_t *);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic inline void inc_adb_irefcnt(dns_adb_t *);
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafssonstatic inline void inc_adb_erefcnt(dns_adb_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, isc_boolean_t,
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffstatic inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void clean_target(dns_adb_t *, dns_name_t *);
05e448935cb2d6ab08c24257f6536362d3496512Evan Huntstatic void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffstatic isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleystatic void cancel_fetches_at_name(dns_adbname_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrewsstatic isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic isc_boolean_t shutdown_names(dns_adb_t *);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic isc_boolean_t shutdown_entries(dns_adb_t *);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic inline void link_name(dns_adb_t *, int, dns_adbname_t *);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic inline isc_boolean_t unlink_name(dns_adb_t *, dns_adbname_t *);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void link_entry(dns_adb_t *, int, dns_adbentry_t *);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic inline isc_boolean_t unlink_entry(dns_adb_t *, dns_adbentry_t *);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉static isc_boolean_t kill_name(dns_adbname_t **, isc_eventtype_t);
dd95acdbce0e2a2775391709cdfca0a9eda7e8f7Mark Andrewsstatic void water(void *, int);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntstatic void dump_entry(FILE *, dns_adb_t *, dns_adbentry_t *,
0fe07891819138ad6e1de45f279cff940d170542Mark Andrewsstatic void adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt,
b04839cfe21f131a8e7c7cae2a89e6ca8b678b5aMark Andrewsstatic void shutdown_task(isc_task_t *task, isc_event_t *ev);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntstatic void log_quota(dns_adbentry_t *entry, const char *fmt, ...)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff * MUST NOT overlap DNS_ADBFIND_* flags!
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 * Private flag(s) for entries.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 * MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0.
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * To the name, address classes are all that really exist. If it has a
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews * V6 address it doesn't care if it came from a AAAA query.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4))
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6))
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews * Fetches are broken out into A and AAAA 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.
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews * are now equal to FETCH_V4 and FETCH_V6, respectively.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Find options and tests to see if there are addresses on the list.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) \
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * These are currently used on simple unsigned ints, so they are
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * not really associated with any particular type.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff * Find out if the flags on a name (nf) indicate if it is a hint or
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff * glue, and compare this to the appropriate bits set in o, to see if
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff * this is ok.
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
53cf67186506f9557aaf2149898dd76715803db2Mark Andrews#define STARTATZONE_MATCHES(nf, o) (((nf)->flags & NAME_STARTATZONE) == \
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff * Error state rankings.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define NEWERR(old, new) (ISC_MIN((old), (new)))
306a93530536f05edfb477cac1c2667d90129a8fMichael Graffstatic isc_result_t find_err_map[FIND_ERR_MAX] = {
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas GustafssonDP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews * Increment resolver-related statistics counters.
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrewsstatic inline void
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉inc_stats(dns_adb_t *adb, isc_statscounter_t counter) {
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 isc_stats_increment(adb->view->resstats, counter);
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt * Set adb-related statistics counters.
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Huntstatic inline void
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Huntset_adbstat(dns_adb_t *adb, isc_uint64_t val, isc_statscounter_t counter) {
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Huntstatic inline void
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Huntdec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
3b27d9a31819437dc1855904ca104d3b542767e1Mark Andrews isc_stats_decrement(adb->view->adbstats, counter);
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Huntstatic inline void
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Huntinc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt isc_stats_increment(adb->view->adbstats, counter);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Hashing is most efficient if the number of buckets is prime.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * The sequence below is the closest previous primes to 2^n and
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * 1.5 * 2^n, for values of n from 10 to 28. (The tables will
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * no longer grow beyond 2^28 entries.)
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrewsstatic const unsigned nbuckets[] = { 1021, 1531, 2039, 3067, 4093, 6143,
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews 268535431, 0 };
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrewsgrow_entries(isc_task_t *task, isc_event_t *ev) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i])
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Are we shutting down?
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Grab all the resources we need.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews if (newentries == NULL || newdeadentries == NULL ||
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newentrylocks == NULL || newentry_sd == NULL ||
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Initialise the new resources.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews result = isc_mutexblock_init(newentrylocks, n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews for (i = 0; i < n; i++) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Move entries to new arrays.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews while (e != NULL) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n;
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews while (e != NULL) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_LIST_UNLINK(adb->deadentries[i], e, plink);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n;
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_LIST_APPEND(newdeadentries[bucket], e, plink);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Cleanup old resources.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Install new resources.
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Only on success do we set adb->growentries_sent to ISC_FALSE.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * This will prevent us being continuously being called on error.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews sizeof(*newentries) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews sizeof(*newentry_sd) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DP(ISC_LOG_INFO, "adb: grow_entries finished");
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i])
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Are we shutting down?
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Grab all the resources we need.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews if (newnames == NULL || newdeadnames == NULL ||
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Initialise the new resources.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews for (i = 0; i < n; i++) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Move names to new arrays.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n;
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_LIST_APPEND(newnames[bucket], name, plink);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_LIST_UNLINK(adb->deadnames[i], name, plink);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n;
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_LIST_APPEND(newdeadnames[bucket], name, plink);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Cleanup old resources.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Install new resources.
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * Only on success do we set adb->grownames_sent to ISC_FALSE.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews * This will prevent us being continuously being called on error.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * Requires the adbname bucket be locked and that no entry buckets be locked.
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff * This code handles A and AAAA rdatasets only.
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graffimport_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_adbentry_t *foundentry; /* NO CLEAN UP! */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket,
26b49e84597ab3ebaa9ae1eb0fe01befa46a8107Mark Andrews else if (rdataset->trust == dns_trust_ultimate)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Lie a little here. This is more or less so code that cares
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * can find out if any new information was added or not.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Requires the name's bucket be locked.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉kill_name(dns_adbname_t **n, isc_eventtype_t ev) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If we're dead already, just check to see if we should go
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * away now or not.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (NAME_DEAD(name) && !NAME_FETCH(name)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Clean up the name's various lists. These two are destructive
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * in that they will always empty the list.
05e448935cb2d6ab08c24257f6536362d3496512Evan Hunt clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 result4 = clean_namehooks(adb, &name->v4);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 result6 = clean_namehooks(adb, &name->v6);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If fetches are running, cancel them. If none are running, we can
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * just kill the name here.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->names[bucket], name, plink);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_APPEND(adb->deadnames[bucket], name, plink);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Requires the name's bucket be locked and no entry buckets be locked.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffcheck_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Check to see if we need to remove the v4 addresses
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "expiring v4 for name %p", name);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 result4 = clean_namehooks(adb, &name->v4);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->partial_result &= ~DNS_ADBFIND_INET;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Check to see if we need to remove the v6 addresses
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "expiring v6 for name %p", name);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 result6 = clean_namehooks(adb, &name->v6);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->partial_result &= ~DNS_ADBFIND_INET6;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Check to see if we need to remove the alias target.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (EXPIRE_OK(name->expire_target, now)) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Requires the name's bucket be locked.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencelink_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_PREPEND(adb->names[bucket], name, plink);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Requires the name's bucket be locked.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceunlink_name(dns_adb_t *adb, dns_adbname_t *name) {
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->names[bucket], name, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->lock_bucket = DNS_ADB_INVALIDBUCKET;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Requires the entry's bucket be locked.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencelink_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 for (i = 0; i < 2; i++) {
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 if (e->refcnt == 0) {
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->entries[bucket], e, plink);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Requires the entry's bucket be locked.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceunlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceviolate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff * The ADB _MUST_ be locked before calling. Also, exit conditions must be
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff * checked after calling this function.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews for (bucket = 0; bucket < adb->nnames; bucket++) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * This bucket has no names. We must decrement the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * irefcnt ourselves, since it will not be
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * automatically triggered by a name being unlinked.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Run through the list. For each name, clean up finds
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * found there, and cancel any fetches running. When
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * all the fetches are canceled, the name will destroy
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * The ADB _MUST_ be locked before calling. Also, exit conditions must be
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * checked after calling this function.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews for (bucket = 0; bucket < adb->nentries; bucket++) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater entry = ISC_LIST_HEAD(adb->entries[bucket]);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * This bucket has no entries. We must decrement the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * irefcnt ourselves, since it will not be
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * automatically triggered by an entry being unlinked.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Run through the list. Cleanup any entries not
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * associated with names, and which are not in use.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Name bucket must be locked
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_resolver_cancelfetch(name->fetch_a->fetch);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * Assumes the name bucket is locked.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Clean up the entry if needed.
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 result = dec_entry_refcnt(adb, overmem, entry,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Free the namehook
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_UNLINK(*namehooks, namehook, plink);
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,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_rdataset_t *rdataset, dns_name_t *target)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(dns_name_countlabels(target) == 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (rdataset->type == dns_rdatatype_cname) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Copy the CNAME's target into the target name.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_rdata_tostruct(&rdata, &cname, NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_name_dup(&cname.cname, adb->mctx, target);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(rdataset->type == dns_rdatatype_dname);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater namereln = dns_name_fullcompare(name, fname, &order, &nlabels);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(namereln == dns_namereln_subdomain);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Get the target name of the DNAME.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_rdata_tostruct(&rdata, &dname, NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Construct the new target name.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_name_split(name, nlabels, prefix, NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_name_concatenate(prefix, &dname.dname, new_target,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_name_dup(new_target, adb->mctx, target);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff * Assumes nothing is locked, since this is called by the client.
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * Assumes the name bucket is locked.
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffclean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
05e448935cb2d6ab08c24257f6536362d3496512Evan Hunt unsigned int addrs)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "cfan: processing find %p", find);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Unlink the find from the name, letting the caller
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * call dns_adb_destroyfind() on it to clean it up
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_UNLINK(name->finds, find, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->name_bucket = DNS_ADB_INVALIDBUCKET;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->result_v4 = find_err_map[name->fetch_err];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->result_v6 = find_err_map[name->fetch6_err];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "sending event %p to task %p for find %p",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_task_sendanddetach(&task, (isc_event_t **)&ev);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "cfan: skipping find %p", find);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic inline void
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * The caller must be holding the adb lock.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If there aren't any external references either, we're
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * done. Send the control event to initiate shutdown.
b04839cfe21f131a8e7c7cae2a89e6ca8b678b5aMark Andrews ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (adb->irefcnt == 0 && adb->erefcnt == 0)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic inline void
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceinc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉dec_entry_refcnt(dns_adb_t *adb, isc_boolean_t overmem, dns_adbentry_t *entry,
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenew_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->lock_bucket = DNS_ADB_INVALIDBUCKET;
c965b1869024ab38518fade703cc1dae2d71a59eMark Andrews if (!adb->grownames_sent && adb->excl != NULL &&
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefree_adbname(dns_adb_t *adb, dns_adbname_t **name) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenew_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefree_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewsnew_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) {
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewsfree_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
4b36b9c1fff56d836feeaa1dc7eb1d4676d9c8bbMark Andrews if (!adb->growentries_sent && adb->excl != NULL &&
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefree_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews isc_mem_put(adb->mctx, e->cookie, e->cookielen);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Public members.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * private members
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefree_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (dns_rdataset_isassociated(&f->rdataset))
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefree_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Copy bits from the entry into the newly allocated addrinfo. The entry
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * must be locked, and the reference count must be bumped up by one
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * if this function returns a valid pointer.
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graffnew_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_sockaddr_setport(&ai->sockaddr, port);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefree_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael 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!
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * On the first call to this function, *bucketp must be set to
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * DNS_ADB_INVALIDBUCKET.
1a0e33bc2044e1902493111db14cbf793083ac47Michael Grafffind_name_and_lock(dns_adb_t *adb, dns_name_t *name,
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = dns_name_fullhash(name, ISC_FALSE) % adb->nnames;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname = ISC_LIST_HEAD(adb->names[bucket]);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Search for the address. NOTE: The bucket is kept locked on both
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * success and failure, so it must always be unlocked by the caller.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * On the first call to this function, *bucketp must be set to
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * DNS_ADB_INVALIDBUCKET. This will cause a lock to occur. On
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * later calls (within the same "lock path") it can be left alone, so
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * if this function is called multiple times locking is only done if
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * the bucket changes.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp,
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = isc_sockaddr_hash(addr, ISC_TRUE) % adb->nentries;
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 /* Search the list, while cleaning up expired entries. */
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 for (entry = ISC_LIST_HEAD(adb->entries[bucket]);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 entry_next = ISC_LIST_NEXT(entry, plink);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 (void)check_expire_entry(adb, &entry, now);
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews (entry->expires == 0 || entry->expires > now) &&
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 isc_sockaddr_equal(addr, &entry->sockaddr)) {
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * Entry bucket MUST be locked!
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewsentry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Has the entry expired?
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_UNLINK(entry->lameinfo, li, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Order tests from least to most expensive.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We do not break out of the main loop here as
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * we use the loop for house keeping.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (li != NULL && !is_bad && li->qtype == qtype &&
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntlog_quota(dns_adbentry_t *entry, const char *fmt, ...) {
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewscopy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_rdatatype_t qtype, dns_adbname_t *name,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater && entry_is_lame(adb, entry, qname, qtype, now)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater addrinfo = new_adbaddrinfo(adb, entry, find->port);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Found a valid entry. Add it to the find's list.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_APPEND(find->list, addrinfo, publink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater namehook = ISC_LIST_NEXT(namehook, plink);
698a4dcc8ae5c2a62a254ab2aff7b16d52598cc0Mark Andrews && entry_is_lame(adb, entry, qname, qtype, now)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater addrinfo = new_adbaddrinfo(adb, entry, find->port);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->partial_result |= DNS_ADBFIND_INET6;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Found a valid entry. Add it to the find's list.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_APPEND(find->list, addrinfo, publink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater namehook = ISC_LIST_NEXT(namehook, plink);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceshutdown_task(isc_task_t *task, isc_event_t *ev) {
0dba2713dec4cf3f97f21b957e403a36ee989b3cMark Andrews * Wait for lock around check_exit() call to be released.
ff303bcf27507c2bab1fab7f05e203fdccae7e19Andreas Gustafsson * Name bucket must be locked; adb may be locked; no other locks held.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencecheck_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (NAME_HAS_V4(name) || NAME_HAS_V6(name))
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * The name is empty. Delete it.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 result = kill_name(&name, DNS_EVENT_ADBEXPIRED);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Our caller, or one of its callers, will be calling check_exit() at
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * some point, so we don't need to do it here.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * Examine the tail entry of the LRU list to see if it expires or is stale
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * (unused for some period); if so, the name entry will be freed. If the ADB
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * is in the overmem condition, the tail and the next to tail entries
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * will be unconditionally removed (unless they have an outstanding fetch).
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * We don't care about a race on 'overmem' at the risk of causing some
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * collateral damage or a small delay in starting cleanup, so we don't bother
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * to lock ADB (if it's not locked).
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * Name bucket must be locked; adb may be locked; no other locks held.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffcheck_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We limit the number of scanned entries to 10 (arbitrary choice)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * in order to avoid examining too many entries when there are many
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * tail entries that have fetches (this should be rare, but could
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater victim = ISC_LIST_TAIL(adb->names[bucket]);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater victim != NULL && victims < max_victims && scans < 10;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater next_victim = ISC_LIST_PREV(victim, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (overmem || victim->last_used + ADB_STALE_MARGIN <= now)) {
ff303bcf27507c2bab1fab7f05e203fdccae7e19Andreas Gustafsson * Entry bucket must be locked; adb may be locked; no other locks held.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleycheck_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (entry->expires == 0 || entry->expires > now)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * The entry is not in use. Delete it.
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * ADB must be locked, and no other locks held.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencecleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = check_expire_namehooks(name, now);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * ADB must be locked, and no other locks held.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencecleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater entry = ISC_LIST_HEAD(adb->entries[bucket]);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = check_expire_entry(adb, &entry, now);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Public functions.
fbcf7bc351f2d42d338cb1fa29e59babd9bee94eMichael Graffdns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_taskmgr_t *taskmgr, dns_adb_t **newadb)
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews unsigned int i;
5c024f787777143031c2c49f9811c39c84bfa259Tatuya JINMEI 神明達哉 REQUIRE(timermgr != NULL); /* this is actually unused */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(newadb != NULL && *newadb == NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adb = isc_mem_get(mem, sizeof(dns_adb_t));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Initialize things here that cannot fail, and especially things
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * that must be NULL for the error return to work properly.
b04839cfe21f131a8e7c7cae2a89e6ca8b678b5aMark Andrews ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent),
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_EVENT_INIT(&adb->growentries, sizeof(adb->growentries), 0, NULL,
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews ISC_EVENT_INIT(&adb->grownames, sizeof(adb->grownames), 0, NULL,
c965b1869024ab38518fade703cc1dae2d71a59eMark Andrews result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl);
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt DP(DEF_LEVEL, "adb: task-exclusive mode unavailable, "
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt "intializing table sizes to %u\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = isc_mutex_init(&adb->overmemlock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Initialize the bucket locks for names and elements.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * May as well initialize the list heads, too.
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews result = isc_mutexblock_init(adb->namelocks, adb->nnames);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews result = isc_mutexblock_init(adb->entrylocks, adb->nentries);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Memory pools
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = isc_mempool_create(mem, sizeof(t), &(p)); \
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_setfreemax((p), FREE_ITEMS); \
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_setfillcount((p), FILL_COUNT); \
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_associatelock((p), &adb->mplock); \
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adbname_t, adb->nmp, "adbname");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adbentry_t, adb->emp, "adbentry");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
5c024f787777143031c2c49f9811c39c84bfa259Tatuya JINMEI 神明達哉 * Allocate an internal task.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = isc_task_create(adb->taskmgr, 0, &adb->task);
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt result = isc_stats_create(adb->mctx, &view->adbstats, dns_adbstats_max);
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
dd2a0a6d2dec1c23787351e51b434a838dec5603Evan Hunt set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Normal return.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* clean up entrylocks */
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
9b8057fce9ee7cdc39ad35f6e16d4ff5e623a941Mark Andrewsdns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater need_exit_check = ISC_TF(adb->erefcnt == 0 && adb->irefcnt == 0);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Send '*eventp' to 'task' when 'adb' has shutdown.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_getallocated(adb->ahmp) == 0) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We're already shutdown. Send the event.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_APPEND(adb->whenshutdown, event, ev_link);
b04839cfe21f131a8e7c7cae2a89e6ca8b678b5aMark Andrewsshutdown_stage2(isc_task_t *task, isc_event_t *event) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Shutdown 'adb'.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_setwater(adb->mctx, water, adb, 0, 0);
b04839cfe21f131a8e7c7cae2a89e6ca8b678b5aMark Andrews * Isolate shutdown_names and shutdown_entries calls.
b04839cfe21f131a8e7c7cae2a89e6ca8b678b5aMark Andrews ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffdns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void *arg, dns_name_t *name, dns_name_t *qname,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_rdatatype_t qtype, unsigned int options,
3230429e175dcaafe9c59967124d44c02ca0ccadEvan Hunt return (dns_adb_createfind2(adb, task, action, arg, name,
3230429e175dcaafe9c59967124d44c02ca0ccadEvan Huntdns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
05e448935cb2d6ab08c24257f6536362d3496512Evan Hunt in_port_t port, unsigned int depth, isc_counter_t *qc,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t want_event, start_at_zone, alias, have_address;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(target == NULL || dns_name_hasbuffer(target));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * XXXMLG Move this comment somewhere else!
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Look up the name in our internal database.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Possibilities: Note that these are not always exclusive.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * No name found. In this case, allocate a new name header and
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * an initial namehook or two. If any of these allocations
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * fail, clean up and return ISC_R_NOMEMORY.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Name found, valid addresses present. Allocate one addrinfo
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * structure for each found and append it to the linked list
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * of addresses for this header.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Name found, queries pending. In this case, if a task was
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * passed in, allocate a job id, attach it to the name's job
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * list and remember to tell the caller that there will be
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * more info coming later.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Remember what types of addresses we are interested in.
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews dns_name_format(name, namebuf, sizeof(namebuf));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Try to see if we know anything about this name at all.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname = find_name_and_lock(adb, name, find->options, &bucket);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "dns_adb_createfind: returning ISC_R_SHUTTINGDOWN");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Nothing found. Allocate a new adbname structure for this name.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * See if there is any stale name at the end of list, and purge
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* Move this name forward in the LRU list */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_UNLINK(adb->names[bucket], adbname, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_PREPEND(adb->names[bucket], adbname, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Expire old entries, etc.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(check_expire_namehooks(adbname, now) == ISC_FALSE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Do we know that the name is an alias?
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (!EXPIRE_OK(adbname->expire_target, now)) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "dns_adb_createfind: name %s (%p) is an alias (cached)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Try to populate the name from the database and/or
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * start fetches. First try looking for an A record
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * in the database.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dbfind_name(adbname, now, dns_rdatatype_a);
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "dns_adb_createfind: found A for name %s (%p) in db",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Did we get a CNAME or DNAME?
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "dns_adb_createfind: name %s (%p) is an alias",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If the name doesn't exist at all, don't bother with
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * v6 queries; they won't work.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If the name does exist but we didn't get our data, go
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * ahead and try AAAA.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If the result is neither of these, try a fetch for A.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "dns_adb_createfind: found AAAA for name %s (%p)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Did we get a CNAME or DNAME?
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "dns_adb_createfind: name %s (%p) is an alias",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Listen to negative cache hints, and don't start
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * another query.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (NCACHE_RESULT(result) || AUTH_NX(result))
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ! (FIND_AVOIDFETCHES(find) && have_address)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We're missing at least one address family. Either the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * caller hasn't instructed us to avoid fetches, or we don't
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * know anything about any of the address families that would
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * be acceptable so we have to launch fetches.
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "started A fetch for name %s (%p)",
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "started AAAA fetch for name %s (%p)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Run through the name and copy out the bits we are
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * interested in.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater copy_namehook_lists(adb, find, qname, qtype, adbname, now);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Attach to the name's query list if there are queries
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * already running, and we have been asked to.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find))
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if ((wanted_addresses & query_pending) == 0)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_APPEND(adbname->finds, find, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->query_pending = (query_pending & wanted_addresses);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Remove the flag so the caller knows there will never
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * be an event, and set internal flags to fake that
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * the event was sent and freed, so dns_adb_destroyfind() will
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * do the right thing.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->query_pending = (query_pending & wanted_addresses);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->partial_result |= (adbname->partial_result & wanted_addresses);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_name_copy(&adbname->target, target, NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Copy out error flags from the name structure into the find.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->result_v4 = find_err_map[adbname->fetch_err];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->result_v6 = find_err_map[adbname->fetch6_err];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * The find doesn't exist on any list, and nothing is locked.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Return the find to the memory pool, and decrement the adb's
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * reference count.
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 RUNTIME_CHECK(dec_entry_refcnt(adb, overmem, entry, ISC_TRUE) ==
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * WARNING: The find is freed with the adb locked. This is done
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * to avoid a race condition where we free the find, some other
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * thread tests to see if it should be destroyed, detects it should
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * be, destroys it, and then we try to lock it for our check, but the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * lock is destroyed.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We need to get the adbname's lock to unlink the find.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_UNLINK(find->adbname->finds, find, plink);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->name_bucket = DNS_ADB_INVALIDBUCKET;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "sending event %p to task %p for find %p",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_task_sendanddetach(&task, (isc_event_t **)&ev);
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews unsigned int i;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Lock the adb itself, lock all the name buckets, then lock all
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * the entry buckets. This should put the adb into a state where
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * nothing can change, so we can iterate through everything and
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * print at our leisure.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(cleanup_names(adb, i, now) == ISC_FALSE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(cleanup_entries(adb, i, now) == ISC_FALSE);
5fca48054b5e791a2fa0c5015bc3b6fef4fcdce1Andreas Gustafssondump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, " [%s TTL %d]", legend, value - now);
dd95acdbce0e2a2775391709cdfca0a9eda7e8f7Mark Andrewsdump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews unsigned int i;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, ";\n; Address database dump\n;\n");
7c19754baccc946eb655f49b6981fe6c0d478dfaMark Andrews fprintf(f, "; [edns success/4096 timeout/1432 timeout/1232 timeout/"
7c19754baccc946eb655f49b6981fe6c0d478dfaMark Andrews "512 timeout]\n");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Dump the names
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (dns_name_countlabels(&name->target) > 0) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dump_ttl(f, "target", name->expire_target, now);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, ";\n; Unassociated entries\n;\n");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Unlock everything
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntdump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt);
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews fprintf(f, ";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] "
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews "[plain %u/%u]", addrbuf, entry->srtt, entry->flags,
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews entry->edns, entry->to4096, entry->to1432, entry->to1232,
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews unsigned int i;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, " [ttl %d]", entry->expires - now);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, " %s [lame TTL %d]\n", typebuf,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Not used currently, in the API Just In Case we
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * want to dump out the name and/or entries too.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->query_pending, find->partial_result,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater find->name_bucket, find->adbname, find->event.ev_sender);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater " srtt %u addr %s\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(f, ";\tHook(%s) %p\n", legend, nh);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graffstatic inline void
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrenceprint_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
5d0984f4fd3133c869b0736adb5291e6fca34a0cTatuya JINMEI 神明達哉 fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n",
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceprint_find_list(FILE *f, dns_adbname_t *name) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname->fetch6_err = FIND_ERR_UNEXPECTED;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * We need to specify whether to search static-stub zones (if
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * configured) depending on whether this is a "start at zone" lookup,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * i.e., whether it's a "bailiwick" glue. If it's bailiwick (in which
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * case NAME_STARTATZONE is set) we need to stop the search at any
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * matching static-stub zone without looking into the cache to honor
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * the configuration on which server we should send queries to.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 result = dns_view_find2(adb->view, &adbname->name, rdtype, now,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 (adbname->flags & NAME_STARTATZONE) != 0 ?
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* XXXVIX this switch statement is too sparse to gen a jump table. */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Found in the database. Even if we can't copy out
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * any information, return success, or else a fetch
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * will be made, which will only make things worse.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = import_rdataset(adbname, &rdataset, now);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We're authoritative and the data doesn't exist.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Make up a negative cache entry so we don't ask again
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * for a while.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * XXXRTH What time should we use? I'm putting in 30 seconds
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb name %p: Caching auth negative entry for A",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb name %p: Caching auth negative entry for AAAA",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We found a negative cache entry. Pull the TTL from it
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * so we won't ask again for a while.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb name %p: Caching negative entry for A (ttl %u)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb name %p: Caching negative entry for AAAA (ttl %u)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Clear the hint and glue flags, so this will match
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = set_target(adb, &adbname->name, fname, &rdataset,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb name %p: caching alias target",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname->expire_target = rdataset.ttl + now;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencefetch_callback(isc_task_t *task, isc_event_t *ev) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t want_check_exit = ISC_FALSE;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(ev->ev_type == DNS_EVENT_FETCHDONE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater && (name->fetch_aaaa->fetch == dev->fetch)) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Cleanup things we don't care about.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If this name is marked as dead, clean up, throwing away
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * potentially good data.
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 want_check_exit = kill_name(&name, DNS_EVENT_ADBCANCELED);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If we got a negative cache response, remember it.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "caching negative entry for A (ttl %u)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->expire_v4 = ISC_MIN(name->expire_v4,
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "caching negative entry for AAAA (ttl %u)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->expire_v6 = ISC_MIN(name->expire_v6,
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb fetch name %p: caching alias target",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater name->expire_target = dev->rdataset->ttl + now;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Did we get back junk? If so, and there are no more fetches
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * sitting out there, tell all the finds about it.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_name_format(&name->name, buf, sizeof(buf));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater buf, address_type == DNS_ADBFIND_INET ? "A" : "AAAA",
3230429e175dcaafe9c59967124d44c02ca0ccadEvan Hunt * Don't record a failure unless this is the initial
3230429e175dcaafe9c59967124d44c02ca0ccadEvan Hunt * fetch of a chain.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* XXXMLG Don't pound on bad servers. */
be7fba80190c33b0e50f086509b42bb319bb95b4Evan Hunt name->expire_v4 = ISC_MIN(name->expire_v4, now + 10);
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
be7fba80190c33b0e50f086509b42bb319bb95b4Evan Hunt name->expire_v6 = ISC_MIN(name->expire_v6, now + 10);
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We got something potentially useful.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = import_rdataset(name, &fetch->rdataset, now);
05e448935cb2d6ab08c24257f6536362d3496512Evan Hunt clean_finds_at_name(name, ev_status, address_type);
3230429e175dcaafe9c59967124d44c02ca0ccadEvan Huntfetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone,
05e448935cb2d6ab08c24257f6536362d3496512Evan Hunt unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST((type == dns_rdatatype_a && !NAME_FETCH_V4(adbname)) ||
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (type == dns_rdatatype_aaaa && !NAME_FETCH_V6(adbname)));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "fetch_name: starting at zone for name %p",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = dns_view_findzonecut2(adb->view, &adbname->name, name,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
3230429e175dcaafe9c59967124d44c02ca0ccadEvan Hunt result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews inc_stats(adb, dns_resstatscounter_gluefetchv4);
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews inc_stats(adb, dns_resstatscounter_gluefetchv6);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fetch = NULL; /* Keep us from cleaning this up below. */
f58cfa95f77ae2c26847b41c731dc17366e273b2Andreas Gustafsson * XXXMLG Needs to take a find argument and an address info, no zone or adb,
f58cfa95f77ae2c26847b41c731dc17366e273b2Andreas Gustafsson * since these can be extracted from the find itself.
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrewsdns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_rdatatype_t qtype, isc_stdtime_t expire_time)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater li = ISC_LIST_HEAD(addr->entry->lameinfo);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (li->qtype != qtype || !dns_name_equal(qname, &li->qname)))
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink);
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graffdns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
0fe07891819138ad6e1de45f279cff940d170542Mark Andrews if (addr->entry->expires == 0 || factor == DNS_ADB_RTTADJAGE)
0fe07891819138ad6e1de45f279cff940d170542Mark Andrewsdns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) {
9d9626fb776663b1e5c62263f9a12b1b4e52106aTinderbox Useradjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
57d5f5abe1c2f7e08bf7851581f4bcc60e883282Mark Andrews new_srtt = ((isc_uint64_t)addr->entry->srtt / 10 * factor)
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graffdns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Note that we do not update the other bits in addr->flags with
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * the most recent values from addr->entry->flags.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater addr->flags = (addr->flags & ~mask) | (bits & mask);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt * (10000 / ((10 + n) / 10)^(3/2)) for n in 0..99.
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt * These will be used to make quota adjustments.
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 3818, 3536, 3286, 3065, 2867, 2690, 2530, 2385, 2254,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 2134, 2025, 1925, 1832, 1747, 1668, 1595, 1527, 1464,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 1405, 1350, 1298, 1250, 1205, 1162, 1121, 1083, 1048,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 1014, 981, 922, 894, 868, 843, 820, 797, 775, 755,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 735, 716, 698, 680, 664, 648, 632, 618, 603, 590, 577,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 564, 552, 540, 529, 518, 507, 497, 487, 477, 468, 459,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 450, 442, 434, 426, 418, 411, 404, 397, 390, 383, 377,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt 370, 364, 358, 353, 347, 342, 336, 331, 326, 321, 316,
c76e8412f4ff4f5945157410312df2a8950f942dMark Andrews#define QUOTA_ADJ_SIZE (sizeof(quota_adj)/sizeof(quota_adj[0]))
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt * Caller must hold adbentry lock
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntmaybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt * Calculate an exponential rolling average of the timeout ratio
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt * XXX: Integer arithmetic might be better than floating point
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt tr = (double) addr->entry->timeouts / addr->entry->completed;
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt addr->entry->timeouts = addr->entry->completed = 0;
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) {
c76e8412f4ff4f5945157410312df2a8950f942dMark Andrews log_quota(addr->entry, "atr %0.2f, quota increased to %u",
c76e8412f4ff4f5945157410312df2a8950f942dMark Andrews log_quota(addr->entry, "atr %0.2f, quota decreased to %u",
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt /* Ensure we don't drop to zero */
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews (addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS)) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews * Increment plain so we don't get stuck.
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews * If we have not had a successful query then clear all
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews * edns timeout information.
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrews if (addr->entry->edns == 0 && addr->entry->plain == 0) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591Mark Andrewsdns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
c5734964e6400f9e6d8c3f057fcccab596929deaMark Andrewsdns_adb_probesize2(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups) {
c5734964e6400f9e6d8c3f057fcccab596929deaMark Andrews if (addr->entry->to1232 > EDNSTOS || lookups >= 2)
c5734964e6400f9e6d8c3f057fcccab596929deaMark Andrews else if (addr->entry->to1432 > EDNSTOS || lookups >= 1)
c5734964e6400f9e6d8c3f057fcccab596929deaMark Andrews * Don't shrink probe size below what we have seen due to multiple
c5734964e6400f9e6d8c3f057fcccab596929deaMark Andrews size < addr->entry->udpsize && addr->entry->udpsize < 4096)
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrewsdns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews (cookie == NULL || len != addr->entry->cookielen)) {
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews if (addr->entry->cookie == NULL && cookie != NULL && len != 0U) {
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews addr->entry->cookie = isc_mem_get(adb->mctx, len);
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrewsdns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews if (cookie != NULL && addr->entry->cookie != NULL &&
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews memmove(cookie, addr->entry->cookie, addr->entry->cookielen);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater dns_adbaddrinfo_t **addrp, isc_stdtime_t now)
c82bb6a709abe89c051485b49403ef5bad1b756cTatuya JINMEI 神明達哉 entry = find_entry_and_lock(adb, sa, &bucket, now);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * We don't know anything about this address.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t want_check_exit = ISC_FALSE;
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int i;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Call our cleanup routines.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == ISC_FALSE);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == ISC_FALSE);
1e4bfff1855795853648f507422b96fc8fecbff1Mark Andrewsdns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
82f77687abd21349fa7c7f51e71fdc0c7367d2e2Mark Andrews bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater adbname = ISC_LIST_HEAD(adb->names[bucket]);
9fa5a723e188ddb5e6165af4957ba789e17cfdf5Evan Huntdns_adb_flushnames(dns_adb_t *adb, dns_name_t *name) {
9fa5a723e188ddb5e6165af4957ba789e17cfdf5Evan Hunt unsigned int i;
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 * We're going to change the way to handle overmem condition: use
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 * isc_mem_isovermem() instead of storing the state via this callback,
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 * since the latter way tends to cause race conditions.
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 * To minimize the change, and in case we re-enable the callback
27fe1966c948ba0c1c9d0d831ea3d8bf32d052acTatuya JINMEI 神明達哉 * approach, however, keep this function at the moment.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "adb reached %s water mark", overmem ? "high" : "low");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater hiwater = size - (size >> 3); /* Approximately 7/8ths. */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater lowater = size - (size >> 2); /* Approximately 3/4ths. */
f3350b671881f175d03e16fa5d0f685a1691bcabMark Andrews if (size == 0U || hiwater == 0U || lowater == 0U)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_setwater(adb->mctx, water, adb, 0, 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntdns_adb_setquota(dns_adb_t *adb, isc_uint32_t quota, isc_uint32_t freq,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt block = ISC_TF(entry->quota != 0 && entry->active >= entry->quota);
1479200aa05414b2acf33607dbd1682c16f58c51Evan Huntdns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {