rbtdb.c revision 6cac2e0f7a1ab207a64127bef11bb93404523c15
5cd4555ad444fd391002ae32450572054369fd42Rob Austein * Copyright (C) 1999, 2000 Internet Software Consortium.
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * Permission to use, copy, modify, and distribute this software for any
c1a883f2e04d94e99c433b1f6cfd0c0338f4ed85Mark Andrews * purpose with or without fee is hereby granted, provided that the above
c651f15b30f1dae5cc2f00878fb5da5b3a35a468Mark Andrews * copyright notice and this permission notice appear in all copies.
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * Principal Author: Bob Halley
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein#define RBTDB_RDATATYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF))
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein#define RBTDB_RDATATYPE_EXT(type) ((dns_rdatatype_t)((type) >> 16))
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein#define RBTDB_RDATATYPE_VALUE(b, e) (((e) << 16) | (b))
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_nxt)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_ns)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_cname)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeintypedef struct rdatasetheader {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Locked by the owning node's lock.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * We don't use the LIST macros, because the LIST structure has
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * both head and tail pointers, and is doubly linked.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein#undef IGNORE /* WIN32 winbase.h defines this. */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein (((header)->attributes & RDATASET_ATTR_NONEXISTENT) == 0)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein (((header)->attributes & RDATASET_ATTR_NONEXISTENT) != 0)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein (((header)->attributes & RDATASET_ATTR_IGNORE) != 0)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein#define DEFAULT_NODE_LOCK_COUNT 7 /* Should be prime. */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeintypedef struct {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeintypedef struct rbtdb_changed {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeintypedef ISC_LIST(rbtdb_changed_t) rbtdb_changedlist_t;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeintypedef struct rbtdb_version {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /* Not locked */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /* Locked by database lock. */
94bd918b63001277f1b28ae4581645f8a835688fBob Halleytypedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t;
94bd918b63001277f1b28ae4581645f8a835688fBob Halleytypedef struct {
94bd918b63001277f1b28ae4581645f8a835688fBob Halley /* Unlocked. */
94bd918b63001277f1b28ae4581645f8a835688fBob Halley /* Locked by lock. */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /* Locked by tree_lock. */
94bd918b63001277f1b28ae4581645f8a835688fBob Halley * Search Context
94bd918b63001277f1b28ae4581645f8a835688fBob Halleytypedef struct {
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews unsigned int options;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Load Context
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeintypedef struct {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic void rdataset_disassociate(dns_rdataset_t *rdataset);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrewsstatic isc_result_t rdataset_first(dns_rdataset_t *rdataset);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t rdataset_next(dns_rdataset_t *rdataset);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic unsigned int rdataset_count(dns_rdataset_t *rdataset);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic void rdatasetiter_current(dns_rdatasetiter_t *iterator,
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic dns_rdatasetitermethods_t rdatasetiter_methods = {
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic void dbiterator_destroy(dns_dbiterator_t **iteratorp);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
94bd918b63001277f1b28ae4581645f8a835688fBob Halleystatic dns_dbiteratormethods_t dbiterator_methods = {
typedef struct rbtdb_dbiterator {
isc_region_t r;
sizeof (rbtdb_version_t));
if (set_exiting)
if (want_free)
if (maybe_free)
static inline rbtdb_version_t *
return (NULL);
return (version);
static isc_result_t
ISC_TRUE);
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
static rbtdb_changed_t *
return (changed);
unsigned int size;
sizeof *rdataset);
if (make_dirty)
if (!still_dirty)
if (least_serial == 0) {
if (commit) {
&cleanup_list);
&cleanup_list);
&cleanup_list);
link);
sizeof *cleanup_version);
if (rollback)
sizeof *changed);
static isc_result_t
unsigned int locknum;
if (!create) {
return (result);
return (result);
return (DNS_R_SUCCESS);
static isc_result_t
return (DNS_R_CONTINUE);
RDATASET_ATTR_NONEXISTENT) != 0)
NULL) ==
return (result);
unsigned char *raw;
unsigned int count;
if (count == 0) {
count--;
static inline isc_result_t
return (result);
return (DNS_R_DNAME);
return (DNS_R_DELEGATION);
static inline isc_boolean_t
unsigned char *raw;
return (ISC_FALSE);
return (ISC_FALSE);
while (count > 0) {
count--;
return (valid);
static inline isc_result_t
if (wild) {
&name,
NULL);
if (active) {
} while (!done);
return (result);
static inline isc_result_t
return (result);
RDATASET_ATTR_NONEXISTENT) != 0)
if (!empty_node) {
node);
rdataset);
NULL);
return (result);
static isc_result_t
now = 0;
rdataset);
goto tree_exit;
goto tree_exit;
goto found;
goto tree_exit;
goto tree_exit;
goto tree_exit;
RDATASET_ATTR_NONEXISTENT) != 0)
if (maybe_zonecut &&
cname_ok)) {
cname_ok) {
sigtype =
} else if (cname_ok &&
if (empty_node) {
goto partial_match;
rdataset);
goto tree_exit;
goto node_exit;
0, rdataset);
0, sigrdataset);
goto node_exit;
rdataset);
goto tree_exit;
if (!at_zonecut)
if (close_version)
return (result);
static isc_result_t
(void)db;
(void)name;
(void)options;
(void)now;
(void)nodep;
(void)foundname;
(void)rdataset;
(void)sigrdataset;
return (DNS_R_NOTIMPLEMENTED);
static isc_result_t
(void)name;
header);
return (result);
static inline isc_result_t
header);
RDATASET_ATTR_NONEXISTENT) == 0) {
&name);
result =
&name,
NULL);
goto node_exit;
rdataset);
} while (!done);
return (result);
static isc_result_t
if (now == 0)
rdataset);
goto tree_exit;
goto tree_exit;
goto tree_exit;
header);
cname_ok &&
sigtype =
} else if (cname_ok &&
if (empty_node) {
goto find_ns;
rdataset);
goto node_exit;
goto find_ns;
rdataset);
return (result);
static isc_result_t
if (now == 0)
goto tree_exit;
goto tree_exit;
header);
goto find_ns;
return (result);
if (maybe_free)
static isc_result_t
if (now == 0)
return (DNS_R_SUCCESS);
if (!first)
static isc_result_t
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
static isc_result_t
now = 0;
if (covers == 0)
sigmatchtype = 0;
RDATASET_ATTR_NONEXISTENT) != 0)
if (close_version)
return (DNS_R_NOTFOUND);
return (DNS_R_SUCCESS);
static isc_result_t
if (now == 0)
if (covers == 0)
sigmatchtype = 0;
return (DNS_R_NOTFOUND);
return (result);
static isc_result_t
return (DNS_R_NOMEMORY);
now = 0;
if (now == 0)
return (DNS_R_SUCCESS);
static isc_result_t
unsigned char *merged;
return (DNS_R_NOMEMORY);
nxtype = 0;
if (rdtype == 0) {
goto find_header;
return (DNS_R_UNCHANGED);
goto find_header;
return (DNS_R_UNCHANGED);
return (DNS_R_UNCHANGED);
if (merge) {
(unsigned char *)header,
(unsigned char *)newheader,
(unsigned int)(sizeof *newheader),
&merged);
return (result);
if (loading) {
if (newheader_nx) {
return (DNS_R_UNCHANGED);
return (DNS_R_SUCCESS);
static inline isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
if (now == 0)
now = 0;
®ion,
sizeof (rdatasetheader_t));
return (result);
now = 0;
if (delegating)
return (result);
static isc_result_t
unsigned char *subresult;
®ion,
sizeof (rdatasetheader_t));
return (result);
return (DNS_R_NOMEMORY);
(unsigned char *)header,
(unsigned char *)newheader,
(unsigned int)(sizeof *newheader),
&subresult);
sizeof *newheader);
goto unlock;
goto unlock;
return (result);
static isc_result_t
return (DNS_R_NOTIMPLEMENTED);
return (DNS_R_NOTIMPLEMENTED);
return (DNS_R_NOMEMORY);
return (result);
static isc_result_t
return (result);
return (result);
®ion,
sizeof (rdatasetheader_t));
return (result);
return (result);
static isc_result_t
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
static isc_result_t
return (DNS_R_SUCCESS);
static isc_result_t
filename));
static isc_boolean_t
return (secure);
dump,
dump,
#ifdef DNS_RBTDB_VERSION64
(void)argc;
(void)argv;
return (DNS_R_NOMEMORY);
if (cache) {
return (DNS_R_UNEXPECTED);
return (DNS_R_UNEXPECTED);
sizeof (rbtdb_nodelock_t));
sizeof (rbtdb_nodelock_t));
return (DNS_R_UNEXPECTED);
return (DNS_R_NOMEMORY);
return (result);
return (result);
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
static isc_result_t
unsigned int count;
if (count == 0) {
return (DNS_R_NOMORE);
count--;
return (DNS_R_SUCCESS);
static isc_result_t
unsigned int count;
unsigned int length;
unsigned char *raw;
if (count == 0)
return (DNS_R_NOMORE);
count--;
return (DNS_R_SUCCESS);
isc_region_t r;
unsigned int count;
return (count);
sizeof *rbtiterator);
static isc_result_t
now = 0;
RDATASET_ATTR_NONEXISTENT) != 0 ||
return (DNS_R_NOMORE);
return (DNS_R_SUCCESS);
static isc_result_t
return (DNS_R_NOMORE);
now = 0;
RDATASET_ATTR_NONEXISTENT) != 0 ||
return (DNS_R_NOMORE);
return (DNS_R_SUCCESS);
rdataset);
static isc_result_t
origin);
return (result);
static isc_result_t
origin);
return (result);
static isc_result_t
return (result);
static isc_result_t
return (result);
static isc_result_t
return (result);
static inline isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
return (result);
return (result);
static isc_result_t
return (DNS_R_SUCCESS);
static isc_result_t