adb.c revision c8b60c24abf816a48691ed8a06281c5a4e35e482
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * Copyright (C) 1999 Internet Software Consortium.
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * Permission to use, copy, modify, and distribute this software for any
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * purpose with or without fee is hereby granted, provided that the above
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * copyright notice and this permission notice appear in all copies.
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * Implementation notes
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * --------------------
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * In finds, if task == NULL, no events will be generated, and no events
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * have been sent. If task != NULL but taskaction == NULL, an event has been
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * posted but not yet freed. If neigher are NULL, no event was posted.
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBNAME_MAGIC 0x6164624e /* adbN. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBNAMEHOOK_MAGIC 0x61644e48 /* adNH. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBZONEINFO_MAGIC 0x6164625a /* adbZ. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBENTRY_MAGIC 0x61646245 /* adbE. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBFETCH_MAGIC 0x61644634 /* adF4. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBFETCH6_MAGIC 0x61644636 /* adF6. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * Lengths of lists needs to be small primes.
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBNAMELIST_LENGTH 31 /* how many buckets for names */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADBENTRYLIST_LENGTH 31 /* how many buckets for addresses */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews/* clean this many seconds initially */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define CLEAN_SECONDS (300 / DNS_ADBNAMELIST_LENGTH)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define FREE_ITEMS 16 /* free count for memory pools */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define FILL_COUNT 8 /* fill count for memory pools */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#define DNS_ADB_INVALIDBUCKET (-1) /* invalid bucket address */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrewstypedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrewstypedef struct dns_adbnamehook dns_adbnamehook_t;
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrewstypedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrewstypedef struct dns_adbzoneinfo dns_adbzoneinfo_t;
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrewstypedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews unsigned int magic;
int next_namebucket;
int next_entrybucket;
unsigned int irefcnt;
unsigned int erefcnt;
struct dns_adbname {
unsigned int magic;
unsigned int partial_result;
unsigned int query_pending;
unsigned int flags;
int lock_bucket;
unsigned int chains;
struct dns_adbfetch {
unsigned int magic;
struct dns_adbfetch6 {
unsigned int magic;
struct dns_adbnamehook {
unsigned int magic;
struct dns_adbzoneinfo {
unsigned int magic;
struct dns_adbentry {
unsigned int magic;
int lock_bucket;
unsigned int refcnt;
unsigned int flags;
unsigned int srtt;
dns_adbentry_t *);
dns_adbentry_t *);
dns_a6context_t *);
isc_sockaddr_t *, int *);
#define QUERYPENDING(x, y) (((x) & (y)) != 0)
#define WANTEDADDR(x, y) (((x) & (y)) != 0)
&& NO_FETCHES_AAAA(n) \
&& NO_FETCHES_A6(n))
static isc_result_t
int addr_bucket;
unsigned int findoptions;
goto fail;
goto fail;
fail:
if (new_addresses_added)
return (ISC_R_SUCCESS);
return (result);
int addr_bucket;
goto fail;
goto fail;
fail:
if (address_added)
name = *n;
*n = NULL;
int bucket;
int bucket;
int addr_bucket;
unsigned int addrs)
goto next;
next:
if (lock)
if (lock)
if (lock)
if (lock)
if (lock)
if (lock)
if (lock)
if (lock)
int bucket;
if (lock)
if (lock)
int bucket;
if (lock)
if (lock)
if (!destroy_entry)
static inline dns_adbname_t *
return (NULL);
return (NULL);
return (name);
dns_adbname_t *n;
n = *name;
n->magic = 0;
static inline dns_adbnamehook_t *
return (NULL);
return (nh);
static inline dns_adbzoneinfo_t *
return (NULL);
return (NULL);
return (zi);
static inline dns_adbentry_t *
dns_adbentry_t *e;
isc_uint32_t r;
if (e == NULL)
return (NULL);
e->refcnt = 0;
e->flags = 0;
e->goodness = 0;
dns_adbentry_t *e;
e = *entry;
e->magic = 0;
static inline dns_adbfind_t *
dns_adbfind_t *h;
if (h == NULL)
return (NULL);
h->magic = 0;
h->query_pending = 0;
h->partial_result = 0;
h->options = 0;
h->flags = 0;
return (NULL);
static inline dns_adbfetch_t *
dns_adbfetch_t *f;
if (f == NULL)
return (NULL);
f->magic = 0;
goto err;
goto err;
err:
return (NULL);
dns_adbfetch_t *f;
f = *fetch;
f->magic = 0;
static isc_result_t
goto cleanup;
goto cleanup;
static inline dns_adbfetch6_t *
dns_adbfetch6_t *f;
if (f == NULL)
return (NULL);
f->magic = 0;
goto err;
goto err;
err:
return (NULL);
dns_adbfetch6_t *f;
f = *fetch;
f->magic = 0;
static inline dns_adbaddrinfo_t *
return (NULL);
return (ai);
static inline dns_adbname_t *
int bucket;
return (adbname);
return (NULL);
static inline dns_adbentry_t *
int bucket;
return (entry);
return (NULL);
static isc_boolean_t
return (ISC_FALSE);
return (is_bad);
int bucket;
goto nextv4;
goto out;
goto nextv6;
goto out;
out:
goto reset;
return (ISC_R_NOMEMORY);
goto fail0a;
goto fail0b;
goto fail0c;
goto fail1;
for (i = 0 ; i < DNS_ADBNAMELIST_LENGTH ; i++) {
for (i = 0 ; i < DNS_ADBENTRYLIST_LENGTH ; i++)
goto fail2;
#define MPINIT(t, p, l, n) do { \
goto fail3; \
isc_mempool_setname((p), n); \
goto fail3;
goto fail3;
return (ISC_R_SUCCESS);
return (result);
int bucket;
unsigned int wanted_addresses;
if (now == 0) {
return (result);
return (ISC_R_NOMEMORY);
goto out;
goto out;
adbname);
goto v6;
adbname);
goto v6;
v6:
goto copy;
adbname);
goto copy;
copy:
& wanted_addresses);
out:
if (attach_to_task) {
return (result);
int name_bucket;
return (ISC_R_NOTFOUND);
if (decr_adbrefcnt)
return (DNS_R_SUCCESS);
if (now == 0) {
return (result);
goto out;
goto out;
goto out;
goto out;
return (ISC_R_SUCCESS);
out:
if (free_name)
if (free_entry)
if (free_namehook)
return (result);
int bucket;
int bucket;
goto cleanup;
const char *tmpp;
for (i = 0 ; i < DNS_ADBNAMELIST_LENGTH ; i++)
for (i = 0 ; i < DNS_ADBENTRYLIST_LENGTH ; i++)
for (i = 0 ; i < DNS_ADBNAMELIST_LENGTH ; i++) {
for (i = 0 ; i < DNS_ADBENTRYLIST_LENGTH ; i++) {
case AF_INET:
case AF_INET6:
for (i = 0 ; i < DNS_ADBENTRYLIST_LENGTH ; i++)
for (i = 0 ; i < DNS_ADBNAMELIST_LENGTH ; i++)
const char *tmpp;
case AF_INET:
case AF_INET6:
isc_buffer_t b;
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
switch (result) {
case DNS_R_GLUE:
case DNS_R_HINT:
case DNS_R_SUCCESS:
return (result);
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
switch (result) {
case DNS_R_GLUE:
case DNS_R_HINT:
case DNS_R_SUCCESS:
return (result);
int bucket;
(void)task;
if (decr_adbrefcnt)
goto out;
out:
int bucket;
(void)task;
if (decr_adbrefcnt)
goto out;
out:
int bucket;
(void)task;
if (decr_adbrefcnt)
goto out;
out:
static isc_result_t
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
static isc_result_t
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
static isc_result_t
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
int bucket;
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
int goodness_adjustment)
int bucket;
if (goodness_adjustment == 0)
if (goodness_adjustment > 0) {
int bucket;
unsigned int new_srtt;
if (factor == 0)