adb.c revision dec90b6caef758fe2890ee50db148cff6acffb90
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Copyright (C) 1999 Internet Software Consortium.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Permission to use, copy, modify, and distribute this software for any
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * purpose with or without fee is hereby granted, provided that the above
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * copyright notice and this permission notice appear in all copies.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Implementation notes
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * --------------------
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * In handles, if task == NULL, no events will be generated, and no events
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * have been sent. If task != NULL but taskaction == NULL, an event has been
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * posted but not yet freed. If neigher are NULL, no event was posted.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#include "../isc/util.h"
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBNAMEHOOK_MAGIC 0x61644e48 /* adNH. */
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBZONEINFO_MAGIC 0x6164625a /* adbZ. */
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC)
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Lengths of lists needs to be powers of two.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBNAMELIST_LENGTH 32 /* how many buckets for names */
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADBENTRYLIST_LENGTH 32 /* how many buckets for addresses */
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define FREE_ITEMS 16 /* free count for memory pools */
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define FILL_COUNT 8 /* fill count for memory pools */
1ccbfca64ae86ace521053773001cb995352f96fBob Halley#define DNS_ADB_INVALIDBUCKET (-1) /* invalid bucket address */
1ccbfca64ae86ace521053773001cb995352f96fBob Halleytypedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
1ccbfca64ae86ace521053773001cb995352f96fBob Halleytypedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int magic;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int irefcnt;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int erefcnt;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Bucketized locks and lists for names.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int name_refcnt[DNS_ADBNAMELIST_LENGTH];
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Bucketized locks for entries.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley dns_adbentrylist_t entries[DNS_ADBENTRYLIST_LENGTH];
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int magic;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * dns_adbnamehook_t
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * This is a small widget that dangles off a dns_adbname_t. It contains a
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * pointer to the address information about this host, and a link to the next
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * namehook that will contain the next address this host has.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int magic;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * dns_adbzoneinfo_t
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * This is a small widget that holds zone-specific information about an
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * address. Currently limited to lameness, but could just as easily be
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * extended to other types of information about zones.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int magic;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * An address entry. It holds quite a bit of information about addresses,
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * including edns state, rtt, and of course the address of the host.
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int magic;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int refcnt;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int flags;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley unsigned int srtt;
1ccbfca64ae86ace521053773001cb995352f96fBob Halley * Internal functions (and prototypes).
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline void free_adbname(dns_adb_t *, dns_adbname_t **);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *, dns_name_t *);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline void free_adbzoneinfo(dns_adb_t *, dns_adbzoneinfo_t **);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline dns_adbentry_t *new_adbentry(dns_adb_t *);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
1ccbfca64ae86ace521053773001cb995352f96fBob Halleystatic inline dns_adbhandle_t *new_adbhandle(dns_adb_t *);
dns_adbentry_t *);
isc_sockaddr_t *, int *);
int bucket;
int addr_bucket;
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_adbhandle_t *
dns_adbhandle_t *h;
if (h == NULL)
return (NULL);
h->magic = 0;
return (NULL);
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 next;
goto out;
next:
out:
return (ISC_R_NOMEMORY);
goto fail0a;
goto fail0b;
goto fail0c;
goto fail0d;
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); \
return (ISC_R_SUCCESS);
return (result);
if (!done)
} while (!done);
int bucket;
if (now == 0) {
return (result);
goto out;
goto fail;
goto fail;
goto out;
goto fail;
goto again;
fail:
out:
if (attach_to_task) {
return (result);
int name_bucket;
return (ISC_R_NOTFOUND);
if (decr_adbrefcnt)
return (DNS_R_SUCCESS);
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;
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;
(void)adb;
case AF_INET:
case AF_INET6:
isc_buffer_t b;
static isc_result_t
int addr_bucket;
return (ISC_R_NOTIMPLEMENTED);
goto fail;
goto fail;
fail:
if (return_success)
return (ISC_R_SUCCESS);
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)