Compare commits

...

6 Commits

Author SHA1 Message Date
Evan Hunt
ae3fab33fc nonfunctional qpdb-lite checkpoint
begin replacement of the underlying dns_rbt data structures in
dns_rbtdb with dns_qp. this is not complete and won't build.

done:
- add qpmethods functions and change tree, nsec, and nsec3 struct
  members from dns_rbt to dns_qp
- add a dns_qpdata structure to take the place of dns_rbtnode
- remove hashsize implementation since it's irrelevant now

not done yet:
- replace dns_rbt_findnode() and dns_rbt_addnode() with
  dns_qp_lookup() and dns_qp_insert()
- replace dns_rbt_nodefromname() etc with functions to get the name
  from the qpdata
- rewrite the dbiterator functions to use dns_qpiter
- rewrite remaining uses of dns_rbtnodechain to use dns_qpchain
- either rewrite is_leaf() for the QP trie or determine that
  we don't need it anymore
- ...etc?
2023-11-01 10:48:02 -07:00
Evan Hunt
2d8172203c clean up rbtdb.c
minor code cleanups in RBTDB:
- add_changed() can't fail
- consequently, version->commit_ok isn't needed
- nsnode and soanode are never used
2023-11-01 10:48:02 -07:00
Evan Hunt
4fb88632c1 clean up dns_rbt
- create_node() in rbt.c cannot fail.
- the dns_rbt_*name() functions, which are wrappers around
  dns_rbt_[add|find|delete]node(), were never used except in tests.
- dns_rbnodechain_nextflat() and _down() were never used at all.

this change isn't really necessary since RBT is likely to
go away eventually anyway. but keeping the API as simple
as possible while it persists is a good thing, and may
reduce confusion while QPDB is being developed from RBTDB code.
2023-11-01 10:47:29 -07:00
Evan Hunt
b38eafd924 move DNS_RBT_NSEC_* to db.h
these values pertain to whether a node is in the main, nsec, or
nsec3 tree of an RBTDB. they need to be moved to a more generic
location so they can also be used by QPDB.

(this is in db.h rather than db_p.h because rbt.c needs
access to it. technically, that's a layer violation, but
it's a long-existing one, refactoring to get rid of it
would be a huge hassle, and eventually we expect to remove
rbt.c anyway.)
2023-11-01 07:54:57 -07:00
Evan Hunt
cc45c4f6a5 separate generic DB helpers into db_p.h
when the QPDB is implemented, we will need to have both qpdb_p.h and
rbtdb_p.h. to prevent name collisions or code duplication, we here
create a private header file for generic database implementations, for
structures and macros that will be used by both databases.

we also rename some functions and structs to more specifically refer to
the RBT database, to avoid namespace collision with similar things that
will be needed by the QP database later.
2023-11-01 07:54:24 -07:00
Evan Hunt
02a4819279 remove unused functions in dns_master
dns_master_dumpnode() and dns_master_dumpnodetostream() were
never used and can be removed.
2023-11-01 03:14:20 -07:00
22 changed files with 881 additions and 1390 deletions

View File

@@ -214,8 +214,8 @@ libdns_la_SOURCES = \
qp.c \
qp_p.h \
rbt.c \
rbt-cachedb.c \
rbt-zonedb.c \
rbt-cachedb.c \
rbtdb_p.h \
rbtdb.c \
rcode.c \

View File

@@ -592,8 +592,6 @@ dns_cache_dumpstats(dns_cache_t *cache, FILE *fp) {
"cache database nodes");
fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db, dns_dbtree_nsec),
"cache NSEC auxiliary database nodes");
fprintf(fp, "%20" PRIu64 " %s\n", (uint64_t)dns_db_hashsize(cache->db),
"cache database hash buckets");
fprintf(fp, "%20" PRIu64 " %s\n", (uint64_t)isc_mem_inuse(cache->mctx),
"cache tree memory in use");
@@ -653,7 +651,6 @@ dns_cache_renderxml(dns_cache_t *cache, void *writer0) {
dns_db_nodecount(cache->db, dns_dbtree_main), writer));
TRY0(renderstat("CacheNSECNodes",
dns_db_nodecount(cache->db, dns_dbtree_nsec), writer));
TRY0(renderstat("CacheBuckets", dns_db_hashsize(cache->db), writer));
TRY0(renderstat("TreeMemInUse", isc_mem_inuse(cache->mctx), writer));
@@ -723,10 +720,6 @@ dns_cache_renderjson(dns_cache_t *cache, void *cstats0) {
CHECKMEM(obj);
json_object_object_add(cstats, "CacheNSECNodes", obj);
obj = json_object_new_int64(dns_db_hashsize(cache->db));
CHECKMEM(obj);
json_object_object_add(cstats, "CacheBuckets", obj);
obj = json_object_new_int64(isc_mem_inuse(cache->mctx));
CHECKMEM(obj);
json_object_object_add(cstats, "TreeMemInUse", obj);

View File

@@ -61,6 +61,7 @@ struct dns_dbimplementation {
* Built in database implementations are registered here.
*/
#include "db_p.h"
#include "rbtdb_p.h"
unsigned int dns_pps = 0U;
@@ -75,13 +76,14 @@ static void
initialize(void) {
isc_rwlock_init(&implock);
rbtimp.name = "rbt";
rbtimp.create = dns__rbtdb_create;
rbtimp.mctx = NULL;
rbtimp.driverarg = NULL;
ISC_LINK_INIT(&rbtimp, link);
ISC_LIST_INIT(implementations);
rbtimp = (dns_dbimplementation_t){
.name = "rbt",
.create = dns__rbtdb_create,
.link = ISC_LINK_INITIALIZER,
};
ISC_LIST_APPEND(implementations, &rbtimp, link);
}
@@ -601,10 +603,6 @@ dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
isc_result_t
dns_db_createiterator(dns_db_t *db, unsigned int flags,
dns_dbiterator_t **iteratorp) {
/*
* Create an iterator for version 'version' of 'db'.
*/
REQUIRE(DNS_DB_VALID(db));
REQUIRE(iteratorp != NULL && *iteratorp == NULL);

164
lib/dns/db_p.h Normal file
View File

@@ -0,0 +1,164 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
#include <isc/heap.h>
#include <isc/lang.h>
#include <isc/urcu.h>
#include <dns/nsec3.h>
#include <dns/rbt.h>
#include <dns/types.h>
#define RDATATYPE_NCACHEANY DNS_TYPEPAIR_VALUE(0, dns_rdatatype_any)
#ifdef STRONG_RWLOCK_CHECK
#define STRONG_RWLOCK_CHECK(cond) REQUIRE(cond)
#else
#define STRONG_RWLOCK_CHECK(cond)
#endif
#define NODE_INITLOCK(l) isc_rwlock_init((l))
#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l)
#define NODE_LOCK(l, t, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
RWLOCK((l), (t)); \
*tp = t; \
}
#define NODE_UNLOCK(l, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp != isc_rwlocktype_none); \
RWUNLOCK(l, *tp); \
*tp = isc_rwlocktype_none; \
}
#define NODE_RDLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_read, tp);
#define NODE_WRLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_write, tp);
#define NODE_TRYLOCK(l, t, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
isc_result_t _result = isc_rwlock_trylock(l, t); \
if (_result == ISC_R_SUCCESS) { \
*tp = t; \
}; \
_result; \
})
#define NODE_TRYRDLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_read, tp)
#define NODE_TRYWRLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_write, tp)
#define NODE_TRYUPGRADE(l, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_read); \
isc_result_t _result = isc_rwlock_tryupgrade(l); \
if (_result == ISC_R_SUCCESS) { \
*tp = isc_rwlocktype_write; \
}; \
_result; \
})
#define NODE_FORCEUPGRADE(l, tp) \
if (NODE_TRYUPGRADE(l, tp) != ISC_R_SUCCESS) { \
NODE_UNLOCK(l, tp); \
NODE_WRLOCK(l, tp); \
}
#define TREE_INITLOCK(l) isc_rwlock_init(l)
#define TREE_DESTROYLOCK(l) isc_rwlock_destroy(l)
#define TREE_LOCK(l, t, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
RWLOCK(l, t); \
*tp = t; \
}
#define TREE_UNLOCK(l, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp != isc_rwlocktype_none); \
RWUNLOCK(l, *tp); \
*tp = isc_rwlocktype_none; \
}
#define TREE_RDLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_read, tp);
#define TREE_WRLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_write, tp);
#define TREE_TRYLOCK(l, t, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
isc_result_t _result = isc_rwlock_trylock(l, t); \
if (_result == ISC_R_SUCCESS) { \
*tp = t; \
}; \
_result; \
})
#define TREE_TRYRDLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_read, tp)
#define TREE_TRYWRLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_write, tp)
#define TREE_TRYUPGRADE(l, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_read); \
isc_result_t _result = isc_rwlock_tryupgrade(l); \
if (_result == ISC_R_SUCCESS) { \
*tp = isc_rwlocktype_write; \
}; \
_result; \
})
#define TREE_FORCEUPGRADE(l, tp) \
if (TREE_TRYUPGRADE(l, tp) != ISC_R_SUCCESS) { \
TREE_UNLOCK(l, tp); \
TREE_WRLOCK(l, tp); \
}
#define IS_STUB(db) (((db)->common.attributes & DNS_DBATTR_STUB) != 0)
#define IS_CACHE(db) (((db)->common.attributes & DNS_DBATTR_CACHE) != 0)
ISC_LANG_BEGINDECLS
struct dns_glue {
struct dns_glue *next;
dns_fixedname_t fixedname;
dns_rdataset_t rdataset_a;
dns_rdataset_t sigrdataset_a;
dns_rdataset_t rdataset_aaaa;
dns_rdataset_t sigrdataset_aaaa;
isc_mem_t *mctx;
struct rcu_head rcu_head;
};
typedef struct {
dns_glue_t *glue_list;
dns_db_t *db;
dns_dbversion_t *version;
dns_name_t *nodename;
} dns_glue_additionaldata_ctx_t;
typedef struct {
isc_rwlock_t lock;
/* Protected in the refcount routines. */
isc_refcount_t references;
/* Locked by lock. */
bool exiting;
} db_nodelock_t;
/*%
* Load Context
*/
typedef struct {
dns_db_t *db;
isc_stdtime_t now;
} db_load_t;
/*%
* Prune context
*/
typedef struct {
dns_db_t *db;
dns_dbnode_t *node;
} db_prune_t;
ISC_LANG_ENDDECLS

View File

@@ -78,15 +78,15 @@ extern unsigned int dns_pps;
*****/
typedef struct dns_dbmethods {
void (*destroy)(dns_db_t *db);
void (*destroy)(dns_db_t *db);
isc_result_t (*beginload)(dns_db_t *db,
dns_rdatacallbacks_t *callbacks);
isc_result_t (*endload)(dns_db_t *db, dns_rdatacallbacks_t *callbacks);
void (*currentversion)(dns_db_t *db, dns_dbversion_t **versionp);
isc_result_t (*newversion)(dns_db_t *db, dns_dbversion_t **versionp);
void (*attachversion)(dns_db_t *db, dns_dbversion_t *source,
void (*attachversion)(dns_db_t *db, dns_dbversion_t *source,
dns_dbversion_t **targetp);
void (*closeversion)(dns_db_t *db, dns_dbversion_t **versionp,
void (*closeversion)(dns_db_t *db, dns_dbversion_t **versionp,
bool commit DNS__DB_FLARG);
isc_result_t (*findnode)(dns_db_t *db, const dns_name_t *name,
bool create,
@@ -103,7 +103,7 @@ typedef struct dns_dbmethods {
dns_name_t *dcname,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG);
void (*attachnode)(dns_db_t *db, dns_dbnode_t *source,
void (*attachnode)(dns_db_t *db, dns_dbnode_t *source,
dns_dbnode_t **targetp DNS__DB_FLARG);
void (*detachnode)(dns_db_t *db, dns_dbnode_t **targetp DNS__DB_FLARG);
isc_result_t (*createiterator)(dns_db_t *db, unsigned int options,
@@ -131,9 +131,9 @@ typedef struct dns_dbmethods {
dns_dbversion_t *version,
dns_rdatatype_t type,
dns_rdatatype_t covers DNS__DB_FLARG);
bool (*issecure)(dns_db_t *db);
bool (*issecure)(dns_db_t *db);
unsigned int (*nodecount)(dns_db_t *db, dns_dbtree_t);
void (*setloop)(dns_db_t *db, isc_loop_t *);
void (*setloop)(dns_db_t *db, isc_loop_t *);
isc_result_t (*getoriginnode)(dns_db_t *db,
dns_dbnode_t **nodep DNS__DB_FLARG);
isc_result_t (*getnsec3parameters)(dns_db_t *db,
@@ -164,7 +164,7 @@ typedef struct dns_dbmethods {
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG);
isc_result_t (*setcachestats)(dns_db_t *db, isc_stats_t *stats);
size_t (*hashsize)(dns_db_t *db);
size_t (*hashsize)(dns_db_t *db);
isc_result_t (*getsize)(dns_db_t *db, dns_dbversion_t *version,
uint64_t *records, uint64_t *bytes);
isc_result_t (*setservestalettl)(dns_db_t *db, dns_ttl_t ttl);
@@ -228,6 +228,17 @@ struct dns_dbonupdatelistener {
struct rcu_head rcu_head;
};
/*%
* Used in composite databases such as RBTDB to indicate whether a node
* exists in a specal tree for NSEC or NSEC3.
*/
enum {
DNS_DB_NSEC_NORMAL = 0, /* in main tree */
DNS_DB_NSEC_HAS_NSEC = 1, /* also has node in nsec tree */
DNS_DB_NSEC_NSEC = 2, /* in nsec tree */
DNS_DB_NSEC_NSEC3 = 3 /* in nsec3 tree */
};
/*@{*/
/*%
* Options that can be specified for dns_db_find().
@@ -1063,7 +1074,7 @@ isc_result_t
dns_db_createiterator(dns_db_t *db, unsigned int options,
dns_dbiterator_t **iteratorp);
/*%<
* Create an iterator for version 'version' of 'db'.
* Create an iterator for 'db'.
*
* Notes:
*

View File

@@ -336,17 +336,6 @@ dns_master_questiontotext(const dns_name_t *owner_name,
const dns_master_style_t *style,
isc_buffer_t *target);
isc_result_t
dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
dns_dbversion_t *version, dns_dbnode_t *node,
const dns_name_t *name,
const dns_master_style_t *style, FILE *f);
isc_result_t
dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
dns_dbnode_t *node, const dns_name_t *name,
const dns_master_style_t *style, const char *filename);
dns_masterstyle_flags_t
dns_master_styleflags(const dns_master_style_t *style);

View File

@@ -282,11 +282,11 @@ typedef struct dns_qpchain {
* readable identifier into `buf` which has max length `size`.
*/
typedef struct dns_qpmethods {
void (*attach)(void *uctx, void *pval, uint32_t ival);
void (*detach)(void *uctx, void *pval, uint32_t ival);
void (*attach)(void *uctx, void *pval, uint32_t ival);
void (*detach)(void *uctx, void *pval, uint32_t ival);
size_t (*makekey)(dns_qpkey_t key, void *uctx, void *pval,
uint32_t ival);
void (*triename)(void *uctx, char *buf, size_t size);
void (*triename)(void *uctx, char *buf, size_t size);
} dns_qpmethods_t;
/*%

View File

@@ -30,7 +30,7 @@ ISC_LANG_BEGINDECLS
/*@{*/
/*%
* Option values for dns_rbt_findnode() and dns_rbt_findname().
* Option values for dns_rbt_findnode().
* These are used to form a bitmask.
*/
#define DNS_RBTFIND_NOOPTIONS 0x00
@@ -57,12 +57,6 @@ ISC_LANG_BEGINDECLS
* appended to this structure. Allocating a contiguous block of memory for
* multiple dns_rbtnode structures will not work.
*/
enum {
DNS_RBT_NSEC_NORMAL = 0, /* in main tree */
DNS_RBT_NSEC_HAS_NSEC = 1, /* also has node in nsec tree */
DNS_RBT_NSEC_NSEC = 2, /* in nsec tree */
DNS_RBT_NSEC_NSEC3 = 3 /* in nsec3 tree */
};
struct dns_rbtnode {
#if DNS_RBT_USEMAGIC
unsigned int magic;
@@ -150,13 +144,6 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
dns_name_t *name,
void *callback_arg DNS__DB_FLARG);
typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file, unsigned char *data,
void *arg, uint64_t *crc);
typedef isc_result_t (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode, void *base,
size_t offset, void *arg,
uint64_t *crc);
typedef void (*dns_rbtdeleter_t)(void *, void *);
/*****
@@ -282,54 +269,15 @@ dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg,
*
* Returns:
*\li #ISC_R_SUCCESS Success
*\li #ISC_R_NOMEMORY Resource limit: Out of Memory
*/
isc_result_t
dns_rbt_addname(dns_rbt_t *rbt, const dns_name_t *name, void *data);
/*%<
* Add 'name' to the tree of trees, associated with 'data'.
*
* Notes:
*\li 'data' is never required to be non-NULL, but specifying it
* when the name is added is faster than searching for 'name'
* again and then setting the data pointer. The lack of a data pointer
* for a node also has other ramifications regarding whether
* dns_rbt_findname considers a node to exist, or dns_rbt_deletename
* joins nodes.
*
* Requires:
*\li rbt is a valid rbt manager.
*\li dns_name_isabsolute(name) == TRUE
*
* Ensures:
*\li 'name' is not altered in any way.
*
*\li Any external references to nodes in the tree are unaffected by
* node splits that are necessary to insert the new name.
*
*\li If result is #ISC_R_SUCCESS:
* 'name' is findable in the red/black tree of trees in O(log N).
* The data pointer of the node for 'name' is set to 'data'.
*
*\li If result is #ISC_R_EXISTS or #ISC_R_NOSPACE:
* The tree of trees is unaltered.
*
*\li If result is #ISC_R_NOMEMORY:
* No guarantees.
*
* Returns:
*\li #ISC_R_SUCCESS Success
*\li #ISC_R_EXISTS The name already exists with associated data.
*\li #ISC_R_NOSPACE The name had more logical labels than are allowed.
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory
*/
isc_result_t
dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep);
/*%<
* Just like dns_rbt_addname, but returns the address of the node.
* Add 'name' to the tree of trees. On success, return the address of
* the newly added node. If 'name' already existed, return ISC_R_EXISTS
* and the address of the pre-existing node.
*
* Requires:
*\li rbt is a valid rbt structure.
@@ -350,61 +298,16 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep);
* The tree of trees is unaltered.
* *nodep is the existing node for 'name'.
*
*\li If result is ISC_R_NOMEMORY:
* No guarantees.
*
* Returns:
*\li #ISC_R_SUCCESS Success
*\li #ISC_R_EXISTS The name already exists, possibly without data.
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory
*/
#define dns_rbt_findname(rbt, name, options, foundname, data) \
dns__rbt_findname(rbt, name, options, foundname, data DNS__DB_FILELINE)
isc_result_t
dns__rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options,
dns_name_t *foundname, void **data DNS__DB_FLARG);
/*%<
* Get the data pointer associated with 'name'.
*
* Notes:
*\li When #DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is
* returned (also subject to #DNS_RBTFIND_EMPTYDATA), even when there is
* an exact match in the tree.
*
*\li A node that has no data is considered not to exist for this function,
* unless the #DNS_RBTFIND_EMPTYDATA option is set.
*
* Requires:
*\li rbt is a valid rbt manager.
*\li dns_name_isabsolute(name) == TRUE
*\li data != NULL && *data == NULL
*
* Ensures:
*\li 'name' and the tree are not altered in any way.
*
*\li If result is ISC_R_SUCCESS:
* *data is the data associated with 'name'.
*
*\li If result is DNS_R_PARTIALMATCH:
* *data is the data associated with the deepest superdomain
* of 'name' which has data.
*
*\li If result is ISC_R_NOTFOUND:
* Neither the name nor a superdomain was found with data.
*
* Returns:
*\li #ISC_R_SUCCESS Success
*\li #DNS_R_PARTIALMATCH Superdomain found with data
*\li #ISC_R_NOTFOUND No match
*\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
*\li #ISC_R_NOSPACE The name had more logical labels than are allowed.
*/
#define dns_rbt_findnode(rbt, name, foundname, node, chain, options, callback, \
callback_arg) \
dns__rbt_findnode(rbt, name, foundname, node, chain, options, \
callback, callback_arg DNS__DB_FILELINE)
isc_result_t
dns__rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
@@ -510,52 +413,6 @@ dns__rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
*\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
*/
#define dns_rbt_deletename(rbt, name, recurse) \
dns__rbt_deletename(rbt, name, recurse DNS__DB_FILELINE)
isc_result_t
dns__rbt_deletename(dns_rbt_t *rbt, const dns_name_t *name,
bool recurse DNS__DB_FLARG);
/*%<
* Delete 'name' from the tree of trees.
*
* Notes:
*\li When 'name' is removed, if recurse is true then all of its
* subnames are removed too.
*
* Requires:
*\li rbt is a valid rbt manager.
*\li dns_name_isabsolute(name) == TRUE
*
* Ensures:
*\li 'name' is not altered in any way.
*
*\li Does NOT ensure that any external references to nodes in the tree
* are unaffected by node joins.
*
*\li If result is ISC_R_SUCCESS:
* 'name' does not appear in the tree with data; however,
* the node for the name might still exist which can be
* found with dns_rbt_findnode (but not dns_rbt_findname).
*
*\li If result is ISC_R_NOTFOUND:
* 'name' does not appear in the tree with data, because
* it did not appear in the tree before the function was called.
*
*\li If result is something else:
* See result codes for dns_rbt_findnode (if it fails, the
* node is not deleted) or dns_rbt_deletenode (if it fails,
* the node is deleted, but the tree is not optimized when
* it could have been).
*
* Returns:
*\li #ISC_R_SUCCESS Success
*\li #ISC_R_NOTFOUND No match
*\li something_else Any return code from dns_rbt_findnode except
* DNS_R_PARTIALMATCH (which causes ISC_R_NOTFOUND
* to be returned instead), and any code from
* dns_rbt_deletenode.
*/
isc_result_t
dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, bool recurse);
/*%<
@@ -580,13 +437,12 @@ dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, bool recurse);
* the node could can be found with dns_rbt_findnode when
* that function's empty_data_ok parameter is true.
*
*\li If result is ISC_R_NOMEMORY or ISC_R_NOSPACE:
*\li If result is ISC_R_NOSPACE:
* The node was deleted, but the tree structure was not
* optimized.
*
* Returns:
*\li #ISC_R_SUCCESS Success
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes.
*\li #ISC_R_NOSPACE dns_name_concatenate failed when joining nodes.
*/
@@ -670,10 +526,8 @@ dns_rbt_hashsize(dns_rbt_t *rbt);
* \li rbt is a valid rbt manager.
*/
void
dns_rbt_destroy(dns_rbt_t **rbtp);
isc_result_t
dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum);
dns_rbt_destroy(dns_rbt_t **rbtp, unsigned int quantum);
/*%<
* Stop working with a red-black tree of trees.
* If 'quantum' is zero then the entire tree will be destroyed.
@@ -698,7 +552,7 @@ dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum);
void
dns_rbt_printtext(dns_rbt_t *rbt, void (*data_printer)(FILE *, void *),
FILE *f);
FILE *f);
/*%<
* Print an ASCII representation of the internal structure of the red-black
* tree of trees to the passed stream.
@@ -908,7 +762,6 @@ dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
*
* Returns:
*\li #DNS_R_NEWORIGIN The name & origin were successfully set.
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory building chain.
*\li &lt;something_else> Any error result from dns_name_concatenate.
*/
@@ -972,19 +825,6 @@ dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name,
*\li &lt;something_else> Any error result from dns_name_concatenate.
*/
isc_result_t
dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name,
dns_name_t *origin);
/*%<
* Descend down if possible.
*/
isc_result_t
dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name);
/*%<
* Find the next node at the current depth in DNSSEC order.
*/
unsigned int
dns__rbtnode_namelen(dns_rbtnode_t *node);
/*%<

View File

@@ -75,11 +75,11 @@ typedef enum {
} dns_rdatasetadditional_t;
typedef struct dns_rdatasetmethods {
void (*disassociate)(dns_rdataset_t *rdataset DNS__DB_FLARG);
void (*disassociate)(dns_rdataset_t *rdataset DNS__DB_FLARG);
isc_result_t (*first)(dns_rdataset_t *rdataset);
isc_result_t (*next)(dns_rdataset_t *rdataset);
void (*current)(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
void (*clone)(dns_rdataset_t *source,
void (*current)(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
void (*clone)(dns_rdataset_t *source,
dns_rdataset_t *target DNS__DB_FLARG);
unsigned int (*count)(dns_rdataset_t *rdataset);
isc_result_t (*addnoqname)(dns_rdataset_t *rdataset,
@@ -92,9 +92,9 @@ typedef struct dns_rdatasetmethods {
isc_result_t (*getclosest)(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *neg,
dns_rdataset_t *negsig DNS__DB_FLARG);
void (*settrust)(dns_rdataset_t *rdataset, dns_trust_t trust);
void (*expire)(dns_rdataset_t *rdataset DNS__DB_FLARG);
void (*clearprefetch)(dns_rdataset_t *rdataset);
void (*settrust)(dns_rdataset_t *rdataset, dns_trust_t trust);
void (*expire)(dns_rdataset_t *rdataset DNS__DB_FLARG);
void (*clearprefetch)(dns_rdataset_t *rdataset);
void (*setownercase)(dns_rdataset_t *rdataset, const dns_name_t *name);
void (*getownercase)(const dns_rdataset_t *rdataset, dns_name_t *name);
isc_result_t (*addglue)(dns_rdataset_t *rdataset,
@@ -184,12 +184,12 @@ struct dns_rdataset {
* comments in rbtdb.c for details.)
*/
struct {
struct dns_db *db;
dns_dbnode_t *node;
unsigned char *raw;
unsigned char *iter_pos;
unsigned int iter_count;
dns_proof_t *noqname, *closest;
struct dns_db *db;
dns_dbnode_t *node;
unsigned char *raw;
unsigned char *iter_pos;
unsigned int iter_count;
dns_slabheader_proof_t *noqname, *closest;
} slab;
/*

View File

@@ -60,7 +60,7 @@ ISC_LANG_BEGINDECLS
#define DNS_RDATASLAB_OFFLINE 0x01 /* RRSIG is for offline DNSKEY */
struct dns_proof {
struct dns_slabheader_proof {
dns_name_t name;
void *neg;
void *negsig;
@@ -94,8 +94,8 @@ struct dns_slabheader {
atomic_uint_fast32_t last_refresh_fail_ts;
dns_proof_t *noqname;
dns_proof_t *closest;
dns_slabheader_proof_t *noqname;
dns_slabheader_proof_t *closest;
/*%<
* We don't use the LIST macros, because the LIST structure has
* both head and tail pointers, and is doubly linked.
@@ -313,4 +313,10 @@ dns_slabheader_destroy(dns_slabheader_t **headerp);
/*%<
* Free all memory associated with '*headerp'.
*/
void
dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proof);
/*%<
* Free all memory associated with a nonexistence proof.
*/
ISC_LANG_ENDDECLS

View File

@@ -19,10 +19,11 @@
#include <dns/types.h>
#define DNS_TYPEPAIR_TYPE(type) ((dns_rdatatype_t)((type) & 0xFFFF))
#define DNS_TYPEPAIR_TYPE(type) ((dns_rdatatype_t)((type)&0xFFFF))
#define DNS_TYPEPAIR_COVERS(type) ((dns_rdatatype_t)((type) >> 16))
#define DNS_TYPEPAIR_VALUE(base, ext) \
((dns_typepair_t)(((uint32_t)ext) << 16) | (((uint32_t)base) & 0xffff))
#define DNS_SIGTYPE(type) DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, (type))
ISC_LANG_BEGINDECLS

View File

@@ -118,17 +118,17 @@ typedef isc_region_t dns_label_t;
typedef struct dns_name dns_name_t;
typedef struct dns_nametree dns_nametree_t;
typedef ISC_LIST(dns_name_t) dns_namelist_t;
typedef struct dns_ntatable dns_ntatable_t;
typedef struct dns_ntnode dns_ntnode_t;
typedef uint16_t dns_opcode_t;
typedef struct dns_order dns_order_t;
typedef struct dns_peer dns_peer_t;
typedef struct dns_peerlist dns_peerlist_t;
typedef struct dns_proof dns_proof_t;
typedef struct dns_rbt dns_rbt_t;
typedef struct dns_rbtdb dns_rbtdb_t;
typedef struct dns_rbtdb_version dns_rbtdb_version_t;
typedef struct dns_rbtnode dns_rbtnode_t;
typedef struct dns_ntatable dns_ntatable_t;
typedef struct dns_ntnode dns_ntnode_t;
typedef uint16_t dns_opcode_t;
typedef struct dns_order dns_order_t;
typedef struct dns_peer dns_peer_t;
typedef struct dns_peerlist dns_peerlist_t;
typedef struct dns_slabheader_proof dns_slabheader_proof_t;
typedef struct dns_rbt dns_rbt_t;
typedef struct dns_rbtdb dns_rbtdb_t;
typedef struct dns_rbtdb_version dns_rbtdb_version_t;
typedef struct dns_rbtnode dns_rbtnode_t;
typedef ISC_LIST(dns_rbtnode_t) dns_rbtnodelist_t;
typedef uint16_t dns_rcode_t;
typedef struct dns_rdata dns_rdata_t;
@@ -145,6 +145,10 @@ typedef struct dns_requestmgr dns_requestmgr_t;
typedef struct dns_resolver dns_resolver_t;
typedef struct dns_rpsdb dns_rpsdb_t;
typedef struct dns_qpnode dns_qpnode_t;
typedef struct dns_qpdata dns_qpdata_t;
typedef ISC_LIST(dns_qpdata_t) dns_qpdatalist_t;
typedef struct dns_qpdb dns_qpdb_t;
typedef struct dns_qpdb_version dns_qpdb_version_t;
typedef uint8_t dns_secalg_t;
typedef uint8_t dns_secproto_t;
typedef struct dns_signature dns_signature_t;

View File

@@ -1908,93 +1908,6 @@ cleanup:
return (result);
}
/*
* Dump a database node into a master file.
* XXX: this function assumes the text format.
*/
isc_result_t
dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
dns_dbversion_t *version, dns_dbnode_t *node,
const dns_name_t *name,
const dns_master_style_t *style, FILE *f) {
isc_result_t result;
isc_buffer_t buffer;
char *bufmem;
isc_stdtime_t now = isc_stdtime_now();
dns_totext_ctx_t ctx;
dns_rdatasetiter_t *rdsiter = NULL;
unsigned int options = DNS_DB_STALEOK;
if ((style->flags & DNS_STYLEFLAG_EXPIRED) != 0) {
options |= DNS_DB_EXPIREDOK;
}
result = totext_ctx_init(style, NULL, &ctx);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR("could not set master file style");
return (ISC_R_UNEXPECTED);
}
bufmem = isc_mem_get(mctx, initial_buffer_length);
isc_buffer_init(&buffer, bufmem, initial_buffer_length);
result = dns_db_allrdatasets(db, node, version, options, now, &rdsiter);
if (result != ISC_R_SUCCESS) {
goto failure;
}
result = dump_rdatasets_text(mctx, name, rdsiter, &ctx, &buffer, f);
if (result != ISC_R_SUCCESS) {
goto failure;
}
dns_rdatasetiter_destroy(&rdsiter);
result = ISC_R_SUCCESS;
failure:
isc_mem_put(mctx, buffer.base, buffer.length);
return (result);
}
isc_result_t
dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
dns_dbnode_t *node, const dns_name_t *name,
const dns_master_style_t *style, const char *filename) {
FILE *f = NULL;
isc_result_t result;
result = isc_stdio_open(filename, "w", &f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping node to file: %s: open: %s", filename,
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
}
result = dns_master_dumpnodetostream(mctx, db, version, node, name,
style, f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: %s: dump: %s", filename,
isc_result_totext(result));
(void)isc_stdio_close(f);
return (ISC_R_UNEXPECTED);
}
result = isc_stdio_close(f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
"dumping master file: %s: close: %s", filename,
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
}
return (result);
}
dns_masterstyle_flags_t
dns_master_styleflags(const dns_master_style_t *style) {
REQUIRE(style != NULL);

View File

@@ -61,6 +61,7 @@
#include <dns/zone.h>
#include <dns/zonekey.h>
#include "db_p.h"
#include "rbtdb_p.h"
#define CHECK(op) \
@@ -186,9 +187,10 @@ update_header(dns_rbtdb_t *rbtdb, dns_slabheader_t *header, isc_stdtime_t now) {
/* To be checked: can we really assume this? XXXMLG */
INSIST(ISC_LINK_LINKED(header, link));
ISC_LIST_UNLINK(rbtdb->lru[HEADER_NODE(header)->locknum], header, link);
ISC_LIST_UNLINK(rbtdb->lru[RBTDB_HEADERNODE(header)->locknum], header,
link);
header->last_used = now;
ISC_LIST_PREPEND(rbtdb->lru[HEADER_NODE(header)->locknum], header,
ISC_LIST_PREPEND(rbtdb->lru[RBTDB_HEADERNODE(header)->locknum], header,
link);
}
@@ -263,7 +265,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_name_t *zcname = NULL;
dns_typepair_t type;
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
REQUIRE(search != NULL);
REQUIRE(search->zonecut != NULL);
@@ -321,7 +323,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
}
static bool
check_stale_header(dns_rbtnode_t *node, dns_slabheader_t *header,
check_stale_header(dns_qpdata_t *node, dns_slabheader_t *header,
isc_rwlocktype_t *nlocktypep, isc_rwlock_t *lock,
rbtdb_search_t *search, dns_slabheader_t **header_prev) {
if (!ACTIVE(header, search->now)) {
@@ -417,7 +419,7 @@ check_stale_header(dns_rbtnode_t *node, dns_slabheader_t *header,
} else {
dns__rbtdb_mark(header,
DNS_SLABHEADERATTR_ANCIENT);
HEADER_NODE(header)->dirty = 1;
RBTDB_HEADERNODE(header)->dirty = 1;
*header_prev = header;
}
} else {
@@ -429,7 +431,7 @@ check_stale_header(dns_rbtnode_t *node, dns_slabheader_t *header,
}
static isc_result_t
cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
cache_zonecut_callback(dns_qpdata_t *node, dns_name_t *name,
void *arg DNS__DB_FLARG) {
rbtdb_search_t *search = arg;
dns_slabheader_t *header = NULL;
@@ -463,7 +465,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
{
dname_header = header;
header_prev = header;
} else if (header->type == RBTDB_RDATATYPE_SIGDNAME &&
} else if (header->type == DNS_SIGTYPE(dns_rdatatype_dname) &&
EXISTS(header) && !ANCIENT(header))
{
sigdname_header = header;
@@ -498,7 +500,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
}
static isc_result_t
find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
find_deepest_zonecut(rbtdb_search_t *search, dns_qpdata_t *node,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
@@ -545,7 +547,7 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
break;
}
} else if (header->type ==
RBTDB_RDATATYPE_SIGNS)
DNS_SIGTYPE(dns_rdatatype_ns))
{
foundsig = header;
if (found != NULL) {
@@ -572,7 +574,7 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
dns_rbt_namefromnode(node, &name);
dns_name_copy(&name, foundname);
while (i > 0) {
dns_rbtnode_t *level_node =
dns_qpdata_t *level_node =
search->chain.levels[--i];
dns_name_init(&name, NULL);
dns_rbt_namefromnode(level_node, &name);
@@ -652,7 +654,7 @@ find_coveringnsec(rbtdb_search_t *search, const dns_name_t *name,
dns_fixedname_t fprefix, forigin, ftarget, fixed;
dns_name_t *prefix = NULL, *origin = NULL;
dns_name_t *target = NULL, *fname = NULL;
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
dns_rbtnodechain_t chain;
isc_result_t result;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
@@ -762,7 +764,7 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
isc_result_t result;
rbtdb_search_t search;
bool cname_ok = true;
@@ -923,7 +925,7 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
* target type. Remember it.
*/
foundsig = header;
} else if (header->type == RBTDB_RDATATYPE_NCACHEANY ||
} else if (header->type == RDATATYPE_NCACHEANY ||
header->type == negtype)
{
/*
@@ -937,7 +939,9 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
* we might need it later.
*/
nsheader = header;
} else if (header->type == RBTDB_RDATATYPE_SIGNS) {
} else if (header->type ==
DNS_SIGTYPE(dns_rdatatype_ns))
{
/*
* If we need the NS rdataset, we'll also
* need its signature.
@@ -945,10 +949,11 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
nssig = header;
} else if (header->type == dns_rdatatype_nsec) {
nsecheader = header;
} else if (header->type == RBTDB_RDATATYPE_SIGNSEC) {
} else if (header->type ==
DNS_SIGTYPE(dns_rdatatype_nsec))
{
nsecsig = header;
} else if (cname_ok &&
header->type == RBTDB_RDATATYPE_SIGCNAME)
} else if (cname_ok && DNS_SIGTYPE(dns_rdatatype_cname))
{
/*
* If we get a CNAME match, we'll also need
@@ -1173,7 +1178,7 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
dns_name_t *foundname, dns_name_t *dcname,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
isc_rwlock_t *lock = NULL;
isc_result_t result;
rbtdb_search_t search;
@@ -1267,7 +1272,9 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
* we might need it later.
*/
found = header;
} else if (header->type == RBTDB_RDATATYPE_SIGNS) {
} else if (header->type ==
DNS_SIGTYPE(dns_rdatatype_ns))
{
/*
* If we need the NS rdataset, we'll also
* need its signature.
@@ -1338,12 +1345,12 @@ tree_exit:
}
static isc_result_t
cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
cache_findrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *version,
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
dns_qpdata_t *node = (dns_qpdata_t *)dbnode;
dns_slabheader_t *header = NULL, *header_next = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
dns_typepair_t matchtype, sigmatchtype, negtype;
@@ -1362,7 +1369,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
now = isc_stdtime_now();
}
lock = &rbtdb->node_locks[rbtnode->locknum].lock;
lock = &rbtdb->node_locks[node->locknum].lock;
NODE_RDLOCK(lock, &nlocktype);
matchtype = DNS_TYPEPAIR_VALUE(type, covers);
@@ -1373,7 +1380,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
sigmatchtype = 0;
}
for (header = rbtnode->data; header != NULL; header = header_next) {
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
if (!ACTIVE(header, now)) {
if ((header->ttl + STALE_TTL(header, rbtdb) <
@@ -1386,20 +1393,20 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
* We update the node's status only when we
* can get write access.
*
* We don't check if refcurrent(rbtnode) == 0
* We don't check if refcurrent(node) == 0
* and try to free like we do in cache_find(),
* because refcurrent(rbtnode) must be
* because refcurrent(node) must be
* non-zero. This is so because 'node' is an
* argument to the function.
*/
dns__rbtdb_mark(header,
DNS_SLABHEADERATTR_ANCIENT);
HEADER_NODE(header)->dirty = 1;
RBTDB_HEADERNODE(header)->dirty = 1;
}
} else if (EXISTS(header) && !ANCIENT(header)) {
if (header->type == matchtype) {
found = header;
} else if (header->type == RBTDB_RDATATYPE_NCACHEANY ||
} else if (header->type == RDATATYPE_NCACHEANY ||
header->type == negtype)
{
found = header;
@@ -1409,10 +1416,10 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
}
if (found != NULL) {
dns__rbtdb_bindrdataset(rbtdb, rbtnode, found, now, nlocktype,
dns__rbtdb_bindrdataset(rbtdb, node, found, now, nlocktype,
rdataset DNS__DB_FLARG_PASS);
if (!NEGATIVE(found) && foundsig != NULL) {
dns__rbtdb_bindrdataset(rbtdb, rbtnode, foundsig, now,
dns__rbtdb_bindrdataset(rbtdb, node, foundsig, now,
nlocktype,
sigrdataset DNS__DB_FLARG_PASS);
}
@@ -1440,23 +1447,6 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
return (result);
}
static size_t
hashsize(dns_db_t *db) {
dns_rbtdb_t *rbtdb = NULL;
size_t size;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
size = dns_rbt_hashsize(rbtdb->tree);
TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
return (size);
}
static isc_result_t
setcachestats(dns_db_t *db, isc_stats_t *stats) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
@@ -1526,17 +1516,17 @@ getservestalerefresh(dns_db_t *db, uint32_t *interval) {
}
static void
expiredata(dns_db_t *db, dns_dbnode_t *node, void *data) {
expiredata(dns_db_t *db, dns_dbnode_t *dbnode, void *data) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
dns_qpdata_t *node = (dns_qpdata_t *)dbnode;
dns_slabheader_t *header = data;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
dns__cachedb_expireheader(header, &tlocktype,
NODE_WRLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
dns__cacheqp_expireheader(header, &tlocktype,
dns_expire_flush DNS__DB_FLARG_PASS);
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
}
@@ -1562,7 +1552,6 @@ dns_dbmethods_t dns__rbtdb_cachemethods = {
.getoriginnode = dns__rbtdb_getoriginnode,
.getrrsetstats = getrrsetstats,
.setcachestats = setcachestats,
.hashsize = hashsize,
.setservestalettl = setservestalettl,
.getservestalettl = getservestalettl,
.setservestalerefresh = setservestalerefresh,
@@ -1577,14 +1566,14 @@ dns_dbmethods_t dns__rbtdb_cachemethods = {
* Caller must hold the node (write) lock.
*/
void
dns__cachedb_expireheader(dns_slabheader_t *header,
dns__cacheqp_expireheader(dns_slabheader_t *header,
isc_rwlocktype_t *tlocktypep,
dns_expire_t reason DNS__DB_FLARG) {
dns__rbtdb_setttl(header, 0);
dns__rbtdb_mark(header, DNS_SLABHEADERATTR_ANCIENT);
HEADER_NODE(header)->dirty = 1;
RBTDB_HEADERNODE(header)->dirty = 1;
if (isc_refcount_current(&HEADER_NODE(header)->references) == 0) {
if (isc_refcount_current(&RBTDB_HEADERNODE(header)->references) == 0) {
isc_rwlocktype_t nlocktype = isc_rwlocktype_write;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)header->db;
@@ -1593,10 +1582,11 @@ dns__cachedb_expireheader(dns_slabheader_t *header,
* We first need to gain a new reference to the node to meet a
* requirement of dns__rbtdb_decref().
*/
dns__rbtdb_newref(rbtdb, HEADER_NODE(header),
dns__rbtdb_newref(rbtdb, RBTDB_HEADERNODE(header),
nlocktype DNS__DB_FLARG_PASS);
dns__rbtdb_decref(rbtdb, HEADER_NODE(header), 0, &nlocktype,
tlocktypep, true, false DNS__DB_FLARG_PASS);
dns__rbtdb_decref(rbtdb, RBTDB_HEADERNODE(header), 0,
&nlocktype, tlocktypep, true,
false DNS__DB_FLARG_PASS);
if (rbtdb->cachestats == NULL) {
return;
@@ -1648,7 +1638,7 @@ expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
* TTL was reset to 0.
*/
ISC_LIST_UNLINK(rbtdb->lru[locknum], header, link);
dns__cachedb_expireheader(header, tlocktypep,
dns__cacheqp_expireheader(header, tlocktypep,
dns_expire_lru DNS__DB_FLARG_PASS);
purged += header_size;
}
@@ -1670,7 +1660,7 @@ expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
* same NS name).
*/
void
dns__cachedb_overmem(dns_rbtdb_t *rbtdb, dns_slabheader_t *newheader,
dns__cacheqp_overmem(dns_rbtdb_t *rbtdb, dns_slabheader_t *newheader,
unsigned int locknum_start,
isc_rwlocktype_t *tlocktypep DNS__DB_FLARG) {
unsigned int locknum;

View File

@@ -61,6 +61,7 @@
#include <dns/zone.h>
#include <dns/zonekey.h>
#include "db_p.h"
#include "rbtdb_p.h"
#define CHECK(op) \
@@ -101,7 +102,7 @@ findnsec3node(dns_db_t *db, const dns_name_t *name, bool create,
}
static isc_result_t
zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
zone_zonecut_callback(dns_qpdata_t *node, dns_name_t *name,
void *arg DNS__DB_FLARG) {
rbtdb_search_t *search = arg;
dns_slabheader_t *header = NULL, *header_next = NULL;
@@ -109,7 +110,7 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
dns_slabheader_t *ns_header = NULL;
dns_slabheader_t *found = NULL;
isc_result_t result = DNS_R_CONTINUE;
dns_rbtnode_t *onode = NULL;
dns_qpdata_t *onode = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
/*
@@ -121,7 +122,7 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
return (result);
}
onode = search->rbtdb->origin_node;
onode = search->rbtdb->origin;
NODE_RDLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
&nlocktype);
@@ -133,7 +134,7 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
header_next = header->next;
if (header->type == dns_rdatatype_ns ||
header->type == dns_rdatatype_dname ||
header->type == RBTDB_RDATATYPE_SIGDNAME)
header->type == DNS_SIGTYPE(dns_rdatatype_dname))
{
do {
if (header->serial <= search->serial &&
@@ -155,7 +156,7 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name,
if (header->type == dns_rdatatype_dname) {
dname_header = header;
} else if (header->type ==
RBTDB_RDATATYPE_SIGDNAME)
DNS_SIGTYPE(dns_rdatatype_dname))
{
sigdname_header = header;
} else if (node != onode ||
@@ -255,7 +256,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_name_t *zcname = NULL;
dns_typepair_t type;
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
REQUIRE(search != NULL);
REQUIRE(search->zonecut != NULL);
@@ -321,7 +322,7 @@ activeempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain,
dns_name_t *origin = NULL;
dns_name_t prefix;
dns_rbtdb_t *rbtdb = NULL;
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
isc_result_t result;
bool answer = false;
dns_slabheader_t *header = NULL;
@@ -380,7 +381,7 @@ activeemptynode(rbtdb_search_t *search, const dns_name_t *qname,
dns_name_t rname;
dns_name_t tname;
dns_rbtdb_t *rbtdb = NULL;
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
dns_rbtnodechain_t chain;
bool check_next = true;
bool check_prev = true;
@@ -492,10 +493,10 @@ activeemptynode(rbtdb_search_t *search, const dns_name_t *qname,
}
static isc_result_t
find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep,
find_wildcard(rbtdb_search_t *search, dns_qpdata_t **nodep,
const dns_name_t *qname) {
unsigned int i, j;
dns_rbtnode_t *node = NULL, *level_node = NULL, *wnode = NULL;
dns_qpdata_t *node = NULL, *level_node = NULL, *wnode = NULL;
dns_slabheader_t *header = NULL;
isc_result_t result = ISC_R_NOTFOUND;
dns_name_t name;
@@ -696,11 +697,11 @@ matchparams(dns_slabheader_t *header, rbtdb_search_t *search) {
static isc_result_t
previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
dns_name_t *name, dns_name_t *origin,
dns_rbtnode_t **nodep, dns_rbtnodechain_t *nsecchain,
dns_qpdata_t **nodep, dns_rbtnodechain_t *nsecchain,
bool *firstp) {
dns_fixedname_t ftarget;
dns_name_t *target = NULL;
dns_rbtnode_t *nsecnode = NULL;
dns_qpdata_t *nsecnode = NULL;
isc_result_t result;
REQUIRE(nodep != NULL && *nodep == NULL);
@@ -815,7 +816,7 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset, dns_rbt_t *tree,
bool secure DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL, *prevnode = NULL;
dns_qpdata_t *node = NULL, *prevnode = NULL;
dns_slabheader_t *header = NULL, *header_next = NULL;
dns_rbtnodechain_t nsecchain;
bool empty_node;
@@ -830,11 +831,11 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
if (tree == search->rbtdb->nsec3) {
type = dns_rdatatype_nsec3;
sigtype = RBTDB_RDATATYPE_SIGNSEC3;
sigtype = DNS_SIGTYPE(dns_rdatatype_nsec3);
wraps = true;
} else {
type = dns_rdatatype_nsec;
sigtype = RBTDB_RDATATYPE_SIGNSEC;
sigtype = DNS_SIGTYPE(dns_rdatatype_nsec);
wraps = false;
}
@@ -1011,7 +1012,7 @@ zone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
isc_stdtime_t now ISC_ATTR_UNUSED, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
isc_result_t result;
rbtdb_search_t search;
bool cname_ok = true;
@@ -1284,8 +1285,8 @@ found:
if (cnamesig != NULL) {
foundsig = cnamesig;
} else {
sigtype =
RBTDB_RDATATYPE_SIGCNAME;
sigtype = DNS_SIGTYPE(
dns_rdatatype_cname);
}
}
/*
@@ -1315,7 +1316,8 @@ found:
* we might need it later.
*/
nsecheader = header;
} else if (header->type == RBTDB_RDATATYPE_SIGNSEC &&
} else if (header->type ==
DNS_SIGTYPE(dns_rdatatype_nsec) &&
!search.rbtversion->havensec3)
{
/*
@@ -1324,7 +1326,8 @@ found:
*/
nsecsig = header;
} else if (cname_ok &&
header->type == RBTDB_RDATATYPE_SIGCNAME)
header->type ==
DNS_SIGTYPE(dns_rdatatype_cname))
{
/*
* If we get a CNAME match, we'll also need
@@ -1523,7 +1526,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
dns_qpdata_t *node = (dns_qpdata_t *)node;
dns_slabheader_t *header = NULL, *header_next = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
uint32_t serial;
@@ -1544,7 +1547,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
serial = rbtversion->serial;
now = 0;
NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
NODE_RDLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
matchtype = DNS_TYPEPAIR_VALUE(type, covers);
if (covers == 0) {
@@ -1553,7 +1556,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
sigmatchtype = 0;
}
for (header = rbtnode->data; header != NULL; header = header_next) {
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
do {
if (header->serial <= serial && !IGNORE(header)) {
@@ -1588,17 +1591,17 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
}
if (found != NULL) {
dns__rbtdb_bindrdataset(rbtdb, rbtnode, found, now,
dns__rbtdb_bindrdataset(rbtdb, node, found, now,
isc_rwlocktype_read,
rdataset DNS__DB_FLARG_PASS);
if (foundsig != NULL) {
dns__rbtdb_bindrdataset(rbtdb, rbtnode, foundsig, now,
dns__rbtdb_bindrdataset(rbtdb, node, foundsig, now,
isc_rwlocktype_read,
sigrdataset DNS__DB_FLARG_PASS);
}
}
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
if (close_version) {
dns__rbtdb_closeversion(
@@ -1614,10 +1617,10 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
static bool
delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, dns_typepair_t type) {
delegating_type(dns_rbtdb_t *rbtdb, dns_qpdata_t *node, dns_typepair_t type) {
if (type == dns_rdatatype_dname ||
(type == dns_rdatatype_ns &&
(node != rbtdb->origin_node || IS_STUB(rbtdb))))
(node != rbtdb->origin || IS_STUB(rbtdb))))
{
return (true);
}
@@ -1628,10 +1631,10 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, dns_typepair_t type) {
* load a non-NSEC3 node in the main tree and optionally to the auxiliary NSEC
*/
static isc_result_t
loadnode(dns_rbtdb_t *rbtdb, const dns_name_t *name, dns_rbtnode_t **nodep,
loadnode(dns_rbtdb_t *rbtdb, const dns_name_t *name, dns_qpdata_t **nodep,
bool hasnsec) {
isc_result_t noderesult, nsecresult, tmpresult;
dns_rbtnode_t *nsecnode = NULL, *node = NULL;
dns_qpdata_t *nsecnode = NULL, *node = NULL;
noderesult = dns_rbt_addnode(rbtdb->tree, name, &node);
if (!hasnsec) {
@@ -1642,7 +1645,7 @@ loadnode(dns_rbtdb_t *rbtdb, const dns_name_t *name, dns_rbtnode_t **nodep,
* Add a node to the auxiliary NSEC tree for an old node
* just now getting an NSEC record.
*/
if (node->nsec == DNS_RBT_NSEC_HAS_NSEC) {
if (node->nsec == DNS_DB_NSEC_HAS_NSEC) {
goto done;
}
} else if (noderesult != ISC_R_SUCCESS) {
@@ -1659,8 +1662,8 @@ loadnode(dns_rbtdb_t *rbtdb, const dns_name_t *name, dns_rbtnode_t **nodep,
*/
nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
if (nsecresult == ISC_R_SUCCESS) {
nsecnode->nsec = DNS_RBT_NSEC_NSEC;
node->nsec = DNS_RBT_NSEC_HAS_NSEC;
nsecnode->nsec = DNS_DB_NSEC_NSEC;
node->nsec = DNS_DB_NSEC_HAS_NSEC;
goto done;
}
@@ -1670,7 +1673,7 @@ loadnode(dns_rbtdb_t *rbtdb, const dns_name_t *name, dns_rbtnode_t **nodep,
DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
"addnode: NSEC node already exists");
#endif /* if 1 */
node->nsec = DNS_RBT_NSEC_HAS_NSEC;
node->nsec = DNS_DB_NSEC_HAS_NSEC;
goto done;
}
@@ -1706,9 +1709,9 @@ done:
static isc_result_t
loading_addrdataset(void *arg, const dns_name_t *name,
dns_rdataset_t *rdataset DNS__DB_FLARG) {
rbtdb_load_t *loadctx = arg;
dns_rbtdb_t *rbtdb = loadctx->rbtdb;
dns_rbtnode_t *node = NULL;
db_load_t *loadctx = arg;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)loadctx->db;
dns_qpdata_t *node = NULL;
isc_result_t result;
isc_region_t region;
dns_slabheader_t *newheader = NULL;
@@ -1728,7 +1731,7 @@ loading_addrdataset(void *arg, const dns_name_t *name,
if (rdataset->type != dns_rdatatype_nsec3 &&
rdataset->covers != dns_rdatatype_nsec3)
{
dns__zonedb_addwildcards(rbtdb, name, false);
dns__zoneqp_addwildcards(rbtdb, name, false);
}
if (dns_name_iswildcard(name)) {
@@ -1744,7 +1747,7 @@ loading_addrdataset(void *arg, const dns_name_t *name,
if (rdataset->type == dns_rdatatype_nsec3) {
return (DNS_R_INVALIDNSEC3);
}
result = dns__zonedb_wildcardmagic(rbtdb, name, false);
result = dns__zoneqp_wildcardmagic(rbtdb, name, false);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -1755,7 +1758,7 @@ loading_addrdataset(void *arg, const dns_name_t *name,
{
result = dns_rbt_addnode(rbtdb->nsec3, name, &node);
if (result == ISC_R_SUCCESS) {
node->nsec = DNS_RBT_NSEC_NSEC3;
node->nsec = DNS_DB_NSEC_NSEC3;
}
} else if (rdataset->type == dns_rdatatype_nsec) {
result = loadnode(rbtdb, name, &node, true);
@@ -1765,9 +1768,6 @@ loading_addrdataset(void *arg, const dns_name_t *name,
if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
return (result);
}
if (result == ISC_R_SUCCESS) {
node->locknum = node->hashval % rbtdb->node_lock_count;
}
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
&region, sizeof(dns_slabheader_t));
@@ -1814,7 +1814,7 @@ loading_addrdataset(void *arg, const dns_name_t *name,
static isc_result_t
beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
rbtdb_load_t *loadctx = NULL;
db_load_t *loadctx = NULL;
dns_rbtdb_t *rbtdb = NULL;
rbtdb = (dns_rbtdb_t *)db;
@@ -1823,16 +1823,16 @@ beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
loadctx = isc_mem_get(rbtdb->common.mctx, sizeof(*loadctx));
loadctx->rbtdb = rbtdb;
loadctx->db = db;
loadctx->now = 0;
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
REQUIRE((rbtdb->attributes &
(RBTDB_ATTR_LOADED | RBTDB_ATTR_LOADING)) == 0);
rbtdb->attributes |= RBTDB_ATTR_LOADING;
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
callbacks->add = loading_addrdataset;
callbacks->add_private = loadctx;
@@ -1842,16 +1842,16 @@ beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
static isc_result_t
endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
rbtdb_load_t *loadctx = NULL;
db_load_t *loadctx = NULL;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(DNS_CALLBACK_VALID(callbacks));
loadctx = callbacks->add_private;
REQUIRE(loadctx != NULL);
REQUIRE(loadctx->rbtdb == rbtdb);
REQUIRE(loadctx->db == db);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0);
REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0);
@@ -1863,12 +1863,12 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
* If there's a KEY rdataset at the zone origin containing a
* zone key, we consider the zone secure.
*/
if (rbtdb->origin_node != NULL) {
if (rbtdb->origin != NULL) {
dns_dbversion_t *version = rbtdb->current_version;
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
dns__rbtdb_setsecure(db, version, rbtdb->origin_node);
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
dns__rbtdb_setsecure(db, version, rbtdb->origin);
} else {
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
}
callbacks->add = NULL;
@@ -1888,9 +1888,9 @@ issecure(dns_db_t *db) {
REQUIRE(VALID_RBTDB(rbtdb));
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
RWLOCK(&rbtdb->lock, isc_rwlocktype_read);
secure = rbtdb->current_version->secure;
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_read);
return (secure);
}
@@ -1908,7 +1908,7 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
REQUIRE(VALID_RBTDB(rbtdb));
INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
RWLOCK(&rbtdb->lock, isc_rwlocktype_read);
if (rbtversion == NULL) {
rbtversion = rbtdb->current_version;
}
@@ -1933,7 +1933,7 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
}
result = ISC_R_SUCCESS;
}
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_read);
return (result);
}
@@ -1950,7 +1950,7 @@ getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
REQUIRE(VALID_RBTDB(rbtdb));
INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
RWLOCK(&rbtdb->lock, isc_rwlocktype_read);
if (rbtversion == NULL) {
rbtversion = rbtdb->current_version;
}
@@ -1960,7 +1960,7 @@ getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
SET_IF_NOT_NULL(xfrsize, rbtversion->xfrsize);
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_read);
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_read);
return (result);
}
@@ -1978,7 +1978,7 @@ setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
header = dns_slabheader_fromrdataset(rdataset);
NODE_WRLOCK(&rbtdb->node_locks[HEADER_NODE(header)->locknum].lock,
NODE_WRLOCK(&rbtdb->node_locks[RBTDB_HEADERNODE(header)->locknum].lock,
&nlocktype);
oldheader = *header;
@@ -1997,25 +1997,25 @@ setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
INSIST(RESIGN(header));
if (resign == 0) {
isc_heap_delete(
rbtdb->heaps[HEADER_NODE(header)->locknum],
rbtdb->heaps[RBTDB_HEADERNODE(header)->locknum],
header->heap_index);
header->heap_index = 0;
header->heap = NULL;
} else if (rbtdb->sooner(header, &oldheader)) {
isc_heap_increased(
rbtdb->heaps[HEADER_NODE(header)->locknum],
rbtdb->heaps[RBTDB_HEADERNODE(header)->locknum],
header->heap_index);
} else if (rbtdb->sooner(&oldheader, header)) {
isc_heap_decreased(
rbtdb->heaps[HEADER_NODE(header)->locknum],
rbtdb->heaps[RBTDB_HEADERNODE(header)->locknum],
header->heap_index);
}
} else if (resign != 0) {
DNS_SLABHEADER_SETATTR(header, DNS_SLABHEADERATTR_RESIGN);
dns__zonedb_resigninsert(rbtdb, HEADER_NODE(header)->locknum,
header);
dns__zoneqp_resigninsert(
rbtdb, RBTDB_HEADERNODE(header)->locknum, header);
}
NODE_UNLOCK(&rbtdb->node_locks[HEADER_NODE(header)->locknum].lock,
NODE_UNLOCK(&rbtdb->node_locks[RBTDB_HEADERNODE(header)->locknum].lock,
&nlocktype);
return (ISC_R_SUCCESS);
}
@@ -2083,12 +2083,12 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
* Found something; pass back the answer and unlock
* the bucket.
*/
dns__rbtdb_bindrdataset(rbtdb, HEADER_NODE(header), header, 0,
isc_rwlocktype_read,
dns__rbtdb_bindrdataset(rbtdb, RBTDB_HEADERNODE(header), header,
0, isc_rwlocktype_read,
rdataset DNS__DB_FLARG_PASS);
if (foundname != NULL) {
dns_rbt_fullnamefromnode(HEADER_NODE(header),
dns_rbt_fullnamefromnode(RBTDB_HEADERNODE(header),
foundname);
}
@@ -2134,11 +2134,11 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
dns_fixedname_t fixedname_a;
dns_name_t *name_a = NULL;
dns_rdataset_t rdataset_a, sigrdataset_a;
dns_rbtnode_t *node_a = NULL;
dns_qpdata_t *node_a = NULL;
dns_fixedname_t fixedname_aaaa;
dns_name_t *name_aaaa = NULL;
dns_rdataset_t rdataset_aaaa, sigrdataset_aaaa;
dns_rbtnode_t *node_aaaa = NULL;
dns_qpdata_t *node_aaaa = NULL;
dns_glue_t *glue = NULL;
UNUSED(unused);
@@ -2158,12 +2158,12 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
dns_rdataset_init(&rdataset_aaaa);
dns_rdataset_init(&sigrdataset_aaaa);
result = zone_find((dns_db_t *)ctx->rbtdb, name, ctx->rbtversion,
dns_rdatatype_a, DNS_DBFIND_GLUEOK, 0,
(dns_dbnode_t **)&node_a, name_a, &rdataset_a,
result = zone_find(ctx->db, name, ctx->version, dns_rdatatype_a,
DNS_DBFIND_GLUEOK, 0, (dns_dbnode_t **)&node_a,
name_a, &rdataset_a,
&sigrdataset_a DNS__DB_FLARG_PASS);
if (result == DNS_R_GLUE) {
glue = new_gluelist(ctx->rbtdb->common.mctx, name_a);
glue = new_gluelist(ctx->db->mctx, name_a);
dns_rdataset_init(&glue->rdataset_a);
dns_rdataset_init(&glue->sigrdataset_a);
@@ -2177,14 +2177,13 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
}
}
result = zone_find((dns_db_t *)ctx->rbtdb, name, ctx->rbtversion,
dns_rdatatype_aaaa, DNS_DBFIND_GLUEOK, 0,
(dns_dbnode_t **)&node_aaaa, name_aaaa,
&rdataset_aaaa,
result = zone_find(ctx->db, name, ctx->version, dns_rdatatype_aaaa,
DNS_DBFIND_GLUEOK, 0, (dns_dbnode_t **)&node_aaaa,
name_aaaa, &rdataset_aaaa,
&sigrdataset_aaaa DNS__DB_FLARG_PASS);
if (result == DNS_R_GLUE) {
if (glue == NULL) {
glue = new_gluelist(ctx->rbtdb->common.mctx, name_aaaa);
glue = new_gluelist(ctx->db->mctx, name_aaaa);
dns_rdataset_init(&glue->rdataset_a);
dns_rdataset_init(&glue->sigrdataset_a);
@@ -2243,13 +2242,12 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
}
if (node_a != NULL) {
dns__db_detachnode((dns_db_t *)ctx->rbtdb,
dns__db_detachnode(ctx->db,
(dns_dbnode_t *)&node_a DNS__DB_FLARG_PASS);
}
if (node_aaaa != NULL) {
dns__db_detachnode(
(dns_db_t *)ctx->rbtdb,
(dns_dbnode_t *)&node_aaaa DNS__DB_FLARG_PASS);
ctx->db, (dns_dbnode_t *)&node_aaaa DNS__DB_FLARG_PASS);
}
return (result);
@@ -2336,12 +2334,12 @@ addglue_to_message(dns_glue_t *ge, dns_message_t *msg) {
}
static dns_glue_t *
newglue(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *rbtversion,
dns_rbtnode_t *node, dns_rdataset_t *rdataset) {
newglue(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *rbtversion, dns_qpdata_t *node,
dns_rdataset_t *rdataset) {
dns_fixedname_t nodename;
dns_glue_additionaldata_ctx_t ctx = {
.rbtdb = rbtdb,
.rbtversion = rbtversion,
.db = (dns_db_t *)rbtdb,
.version = (dns_dbversion_t *)rbtversion,
.nodename = dns_fixedname_initname(&nodename),
};
@@ -2364,11 +2362,11 @@ addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset,
dns_message_t *msg) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtdb_version_t *rbtversion = version;
dns_rbtnode_t *node = RDATASET_DBNODE(rdataset);
dns_qpdata_t *node = (dns_qpdata_t *)rdataset->slab.node;
dns_slabheader_t *header = dns_slabheader_fromrdataset(rdataset);
REQUIRE(rdataset->type == dns_rdatatype_ns);
REQUIRE(rbtdb == RDATASET_RBTDB(rdataset));
REQUIRE(rbtdb == (dns_rbtdb_t *)rdataset->slab.db);
REQUIRE(rbtdb == rbtversion->rbtdb);
REQUIRE(!IS_CACHE(rbtdb) && !IS_STUB(rbtdb));
@@ -2450,7 +2448,7 @@ dns_dbmethods_t dns__rbtdb_zonemethods = {
};
void
dns__zonedb_resigninsert(dns_rbtdb_t *rbtdb, int idx,
dns__zoneqp_resigninsert(dns_rbtdb_t *rbtdb, int idx,
dns_slabheader_t *newheader) {
INSIST(!IS_CACHE(rbtdb));
INSIST(newheader->heap_index == 0);
@@ -2461,18 +2459,18 @@ dns__zonedb_resigninsert(dns_rbtdb_t *rbtdb, int idx,
}
void
dns__zonedb_resigndelete(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *version,
dns__zoneqp_resigndelete(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *version,
dns_slabheader_t *header DNS__DB_FLARG) {
/*
* Remove the old header from the heap
*/
if (header != NULL && header->heap_index != 0) {
isc_heap_delete(rbtdb->heaps[HEADER_NODE(header)->locknum],
isc_heap_delete(rbtdb->heaps[RBTDB_HEADERNODE(header)->locknum],
header->heap_index);
header->heap_index = 0;
if (version != NULL) {
dns__rbtdb_newref(
rbtdb, HEADER_NODE(header),
rbtdb, RBTDB_HEADERNODE(header),
isc_rwlocktype_write DNS__DB_FLARG_PASS);
ISC_LIST_APPEND(version->resigned_list, header, link);
}
@@ -2480,13 +2478,13 @@ dns__zonedb_resigndelete(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *version,
}
isc_result_t
dns__zonedb_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
dns__zoneqp_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
bool lock) {
isc_result_t result;
dns_name_t foundname;
dns_offsets_t offsets;
unsigned int n;
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
dns_name_init(&foundname, offsets);
@@ -2499,7 +2497,7 @@ dns__zonedb_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
return (result);
}
if (result == ISC_R_SUCCESS) {
node->nsec = DNS_RBT_NSEC_NORMAL;
node->nsec = DNS_DB_NSEC_NORMAL;
}
node->find_callback = 1;
if (lock) {
@@ -2513,7 +2511,7 @@ dns__zonedb_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
}
isc_result_t
dns__zonedb_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name,
dns__zoneqp_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name,
bool lock) {
isc_result_t result;
dns_name_t foundname;
@@ -2525,10 +2523,10 @@ dns__zonedb_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name,
l = dns_name_countlabels(&rbtdb->common.origin);
i = l + 1;
while (i < n) {
dns_rbtnode_t *node = NULL;
dns_qpdata_t *node = NULL;
dns_name_getlabelsequence(name, n - i, i, &foundname);
if (dns_name_iswildcard(&foundname)) {
result = dns__zonedb_wildcardmagic(rbtdb, &foundname,
result = dns__zoneqp_wildcardmagic(rbtdb, &foundname,
lock);
if (result != ISC_R_SUCCESS) {
return (result);
@@ -2539,7 +2537,7 @@ dns__zonedb_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name,
return (result);
}
if (result == ISC_R_SUCCESS) {
node->nsec = DNS_RBT_NSEC_NORMAL;
node->nsec = DNS_DB_NSEC_NORMAL;
}
}
i++;

View File

@@ -36,6 +36,7 @@
#include <isc/result.h>
#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/log.h>
#include <dns/rbt.h>
@@ -177,8 +178,8 @@ dns__rbtnode_getdistance(dns_rbtnode_t *node) {
/*
* Forward declarations.
*/
static isc_result_t
create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep);
static dns_rbtnode_t *
create_node(isc_mem_t *mctx, const dns_name_t *name);
static void
hashtable_new(dns_rbt_t *rbt, uint8_t index, uint8_t bits);
@@ -283,13 +284,8 @@ dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg,
/*
* Deallocate a red/black tree of trees.
*/
void
dns_rbt_destroy(dns_rbt_t **rbtp) {
RUNTIME_CHECK(dns_rbt_destroy2(rbtp, 0) == ISC_R_SUCCESS);
}
isc_result_t
dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) {
dns_rbt_destroy(dns_rbt_t **rbtp, unsigned int quantum) {
dns_rbt_t *rbt;
REQUIRE(rbtp != NULL && VALID_RBT(*rbtp));
@@ -451,18 +447,14 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
dns_name_clone(name, add_name);
if (rbt->root == NULL) {
result = create_node(rbt->mctx, add_name, &new_current);
if (result == ISC_R_SUCCESS) {
rbt->nodecount++;
new_current->is_root = 1;
new_current->uppernode = NULL;
rbt->root = new_current;
*nodep = new_current;
hash_node(rbt, new_current, name);
}
return (result);
new_current = create_node(rbt->mctx, add_name);
rbt->nodecount++;
new_current->is_root = 1;
new_current->uppernode = NULL;
rbt->root = new_current;
*nodep = new_current;
hash_node(rbt, new_current, name);
return (ISC_R_SUCCESS);
}
level_count = 0;
@@ -575,20 +567,16 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
*/
dns_name_split(&current_name, common_labels,
prefix, suffix);
result = create_node(rbt->mctx, suffix,
&new_current);
if (result != ISC_R_SUCCESS) {
break;
}
new_current = create_node(rbt->mctx, suffix);
/*
* Reproduce the tree attributes of the
* current node.
*/
new_current->is_root = current->is_root;
if (current->nsec == DNS_RBT_NSEC_HAS_NSEC) {
new_current->nsec = DNS_RBT_NSEC_NORMAL;
new_current->nsec = current->nsec;
if (current->nsec == DNS_DB_NSEC_HAS_NSEC) {
new_current->nsec = DNS_DB_NSEC_NORMAL;
} else {
new_current->nsec = current->nsec;
}
@@ -666,18 +654,14 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
* Its data pointer is already NULL
* from create_node()), so there's
* nothing more to do to it.
*/
/*
*
* The not-in-common parts of the new
* name will be inserted into the new
* level following this loop (unless
* result != ISC_R_SUCCESS, which
* is tested after the loop ends).
* level following this loop.
*/
dns_name_split(add_name, common_labels,
add_name, NULL);
result = ISC_R_SUCCESS;
break;
}
}
@@ -685,7 +669,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
} while (child != NULL);
if (result == ISC_R_SUCCESS) {
result = create_node(rbt->mctx, add_name, &new_current);
new_current = create_node(rbt->mctx, add_name);
}
if (result == ISC_R_SUCCESS) {
@@ -704,37 +688,6 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
return (result);
}
/*
* Add a name to the tree of trees, associating it with some data.
*/
isc_result_t
dns_rbt_addname(dns_rbt_t *rbt, const dns_name_t *name, void *data) {
isc_result_t result;
dns_rbtnode_t *node;
REQUIRE(VALID_RBT(rbt));
REQUIRE(dns_name_isabsolute(name));
node = NULL;
result = dns_rbt_addnode(rbt, name, &node);
/*
* dns_rbt_addnode will report the node exists even when
* it does not have data associated with it, but the
* dns_rbt_*name functions all behave depending on whether
* there is data associated with a node.
*/
if (result == ISC_R_SUCCESS ||
(result == ISC_R_EXISTS && node->data == NULL))
{
node->data = data;
result = ISC_R_SUCCESS;
}
return (result);
}
/*
* Find the node for "name" in the tree of trees.
*/
@@ -1266,72 +1219,6 @@ dns__rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
return (result);
}
/*
* Get the data pointer associated with 'name'.
*/
isc_result_t
dns__rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options,
dns_name_t *foundname, void **data DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL;
isc_result_t result;
REQUIRE(data != NULL && *data == NULL);
result = dns__rbt_findnode(rbt, name, foundname, &node, NULL, options,
NULL, NULL DNS__DB_FLARG_PASS);
if (node != NULL && WANTEMPTYDATA_OR_DATA(options, node)) {
*data = node->data;
} else {
result = ISC_R_NOTFOUND;
}
return (result);
}
/*
* Delete a name from the tree of trees.
*/
isc_result_t
dns__rbt_deletename(dns_rbt_t *rbt, const dns_name_t *name,
bool recurse DNS__DB_FLARG) {
dns_rbtnode_t *node = NULL;
isc_result_t result;
REQUIRE(VALID_RBT(rbt));
REQUIRE(dns_name_isabsolute(name));
/*
* First, find the node.
*
* When searching, the name might not have an exact match:
* consider a.b.a.com, b.b.a.com and c.b.a.com as the only
* elements of a tree, which would make layer 1 a single
* node tree of "b.a.com" and layer 2 a three node tree of
* a, b, and c. Deleting a.com would find only a partial depth
* match in the first layer. Should it be a requirement that
* that the name to be deleted have data? For now, it is.
*
* ->dirty, ->locknum and ->references are ignored; they are
* solely the province of rbtdb.c.
*/
result = dns__rbt_findnode(rbt, name, NULL, &node, NULL,
DNS_RBTFIND_NOOPTIONS, NULL,
NULL DNS__DB_FLARG_PASS);
if (result == ISC_R_SUCCESS) {
if (node->data != NULL) {
result = dns_rbt_deletenode(rbt, node, recurse);
} else {
result = ISC_R_NOTFOUND;
}
} else if (result == DNS_R_PARTIALMATCH) {
result = ISC_R_NOTFOUND;
}
return (result);
}
/*
* Remove a node from the tree of trees.
*
@@ -1489,9 +1376,9 @@ dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname,
return (printname);
}
static isc_result_t
create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
dns_rbtnode_t *node;
static dns_rbtnode_t *
create_node(isc_mem_t *mctx, const dns_name_t *name) {
dns_rbtnode_t *node = NULL;
isc_region_t region;
unsigned int labels;
size_t nodelen;
@@ -1508,7 +1395,6 @@ create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
nodelen = sizeof(dns_rbtnode_t) + region.length + labels + 1;
node = isc_mem_get(mctx, nodelen);
*node = (dns_rbtnode_t){
.nsec = DNS_RBT_NSEC_NORMAL,
.color = BLACK,
};
@@ -1540,9 +1426,7 @@ create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
#if DNS_RBT_USEMAGIC
node->magic = DNS_RBTNODE_MAGIC;
#endif /* if DNS_RBT_USEMAGIC */
*nodep = node;
return (ISC_R_SUCCESS);
return (node);
}
/*
@@ -2718,119 +2602,6 @@ dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name,
return (result);
}
isc_result_t
dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name,
dns_name_t *origin) {
dns_rbtnode_t *current, *successor;
isc_result_t result = ISC_R_SUCCESS;
bool new_origin = false;
REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);
successor = NULL;
current = chain->end;
if (current->down != NULL) {
/*
* Don't declare an origin change when the new origin is
* "." at the second level tree, because "." is already
* declared as the origin for the top level tree.
*/
if (chain->level_count > 0 || current->offsetlen > 1) {
new_origin = true;
}
ADD_LEVEL(chain, current);
current = current->down;
while (current->left != NULL) {
current = current->left;
}
successor = current;
}
if (successor != NULL) {
chain->end = successor;
/*
* It is not necessary to use dns_rbtnodechain_current
* like the other functions because this function will
* never find a node in the topmost level. This is
* because the root level will never be more than one
* name, and everything in the megatree is a successor
* to that node, down at the second level or below.
*/
if (name != NULL) {
node_name(chain->end, name);
}
if (new_origin) {
if (origin != NULL) {
result = chain_name(chain, origin, false);
}
if (result == ISC_R_SUCCESS) {
result = DNS_R_NEWORIGIN;
}
} else {
result = ISC_R_SUCCESS;
}
} else {
result = ISC_R_NOMORE;
}
return (result);
}
isc_result_t
dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name) {
dns_rbtnode_t *current, *previous, *successor;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);
successor = NULL;
current = chain->end;
if (current->right == NULL) {
while (!current->is_root) {
previous = current;
current = current->parent;
if (current->left == previous) {
successor = current;
break;
}
}
} else {
current = current->right;
while (current->left != NULL) {
current = current->left;
}
successor = current;
}
if (successor != NULL) {
chain->end = successor;
if (name != NULL) {
node_name(chain->end, name);
}
result = ISC_R_SUCCESS;
} else {
result = ISC_R_NOMORE;
}
return (result);
}
isc_result_t
dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name,
dns_name_t *origin) {

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@
#include <isc/urcu.h>
#include <dns/nsec3.h>
#include <dns/rbt.h>
#include <dns/qp.h>
#include <dns/types.h>
/*%
@@ -29,124 +29,7 @@
#define VALID_RBTDB(rbtdb) \
((rbtdb) != NULL && (rbtdb)->common.impmagic == RBTDB_MAGIC)
#define RBTDB_RDATATYPE_SIGNSEC \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec)
#define RBTDB_RDATATYPE_SIGNSEC3 \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3)
#define RBTDB_RDATATYPE_SIGNS \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns)
#define RBTDB_RDATATYPE_SIGCNAME \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname)
#define RBTDB_RDATATYPE_SIGDNAME \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname)
#define RBTDB_RDATATYPE_SIGDS \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds)
#define RBTDB_RDATATYPE_SIGSOA \
DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_soa)
#define RBTDB_RDATATYPE_NCACHEANY DNS_TYPEPAIR_VALUE(0, dns_rdatatype_any)
#define RBTDB_INITLOCK(l) isc_rwlock_init((l))
#define RBTDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
#define RBTDB_LOCK(l, t) RWLOCK((l), (t))
#define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t))
#ifdef DNS_RBTDB_STRONG_RWLOCK_CHECK
#define STRONG_RWLOCK_CHECK(cond) REQUIRE(cond)
#else
#define STRONG_RWLOCK_CHECK(cond)
#endif
#define NODE_INITLOCK(l) isc_rwlock_init((l))
#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l)
#define NODE_LOCK(l, t, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
RWLOCK((l), (t)); \
*tp = t; \
}
#define NODE_UNLOCK(l, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp != isc_rwlocktype_none); \
RWUNLOCK(l, *tp); \
*tp = isc_rwlocktype_none; \
}
#define NODE_RDLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_read, tp);
#define NODE_WRLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_write, tp);
#define NODE_TRYLOCK(l, t, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
isc_result_t _result = isc_rwlock_trylock(l, t); \
if (_result == ISC_R_SUCCESS) { \
*tp = t; \
}; \
_result; \
})
#define NODE_TRYRDLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_read, tp)
#define NODE_TRYWRLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_write, tp)
#define NODE_TRYUPGRADE(l, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_read); \
isc_result_t _result = isc_rwlock_tryupgrade(l); \
if (_result == ISC_R_SUCCESS) { \
*tp = isc_rwlocktype_write; \
}; \
_result; \
})
#define NODE_FORCEUPGRADE(l, tp) \
if (NODE_TRYUPGRADE(l, tp) != ISC_R_SUCCESS) { \
NODE_UNLOCK(l, tp); \
NODE_WRLOCK(l, tp); \
}
#define TREE_INITLOCK(l) isc_rwlock_init(l)
#define TREE_DESTROYLOCK(l) isc_rwlock_destroy(l)
#define TREE_LOCK(l, t, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
RWLOCK(l, t); \
*tp = t; \
}
#define TREE_UNLOCK(l, tp) \
{ \
STRONG_RWLOCK_CHECK(*tp != isc_rwlocktype_none); \
RWUNLOCK(l, *tp); \
*tp = isc_rwlocktype_none; \
}
#define TREE_RDLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_read, tp);
#define TREE_WRLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_write, tp);
#define TREE_TRYLOCK(l, t, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
isc_result_t _result = isc_rwlock_trylock(l, t); \
if (_result == ISC_R_SUCCESS) { \
*tp = t; \
}; \
_result; \
})
#define TREE_TRYRDLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_read, tp)
#define TREE_TRYWRLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_write, tp)
#define TREE_TRYUPGRADE(l, tp) \
({ \
STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_read); \
isc_result_t _result = isc_rwlock_tryupgrade(l); \
if (_result == ISC_R_SUCCESS) { \
*tp = isc_rwlocktype_write; \
}; \
_result; \
})
#define TREE_FORCEUPGRADE(l, tp) \
if (TREE_TRYUPGRADE(l, tp) != ISC_R_SUCCESS) { \
TREE_UNLOCK(l, tp); \
TREE_WRLOCK(l, tp); \
}
#define RDATASET_RBTDB(r) ((dns_rbtdb_t *)(r)->slab.db)
#define RDATASET_DBNODE(r) ((dns_rbtnode_t *)(r)->slab.node)
#define HEADER_NODE(h) ((dns_rbtnode_t *)((h)->node))
#define IS_STUB(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_STUB) != 0)
#define IS_CACHE(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_CACHE) != 0)
#define RBTDB_HEADERNODE(h) ((dns_qpdata_t *)((h)->node))
/*
* Allow clients with a virtual time of up to 5 minutes in the past to see
@@ -165,41 +48,14 @@
ISC_LANG_BEGINDECLS
typedef struct {
isc_rwlock_t lock;
/* Protected in the refcount routines. */
isc_refcount_t references;
/* Locked by lock. */
bool exiting;
} rbtdb_nodelock_t;
typedef struct rbtdb_changed {
dns_rbtnode_t *node;
dns_qpdata_t *node;
bool dirty;
ISC_LINK(struct rbtdb_changed) link;
} rbtdb_changed_t;
typedef ISC_LIST(rbtdb_changed_t) rbtdb_changedlist_t;
struct dns_glue {
struct dns_glue *next;
dns_fixedname_t fixedname;
dns_rdataset_t rdataset_a;
dns_rdataset_t sigrdataset_a;
dns_rdataset_t rdataset_aaaa;
dns_rdataset_t sigrdataset_aaaa;
isc_mem_t *mctx;
struct rcu_head rcu_head;
};
typedef struct {
dns_glue_t *glue_list;
dns_rbtdb_t *rbtdb;
dns_rbtdb_version_t *rbtversion;
dns_name_t *nodename;
} dns_glue_additionaldata_ctx_t;
struct dns_rbtdb_version {
/* Not locked */
uint32_t serial;
@@ -212,7 +68,6 @@ struct dns_rbtdb_version {
isc_refcount_t references;
/* Locked by database lock. */
bool writer;
bool commit_ok;
rbtdb_changedlist_t changed_list;
dns_slabheaderlist_t resigned_list;
ISC_LINK(dns_rbtdb_version_t) link;
@@ -237,6 +92,35 @@ struct dns_rbtdb_version {
typedef ISC_LIST(dns_rbtdb_version_t) rbtdb_versionlist_t;
struct dns_qpdata {
dns_fixedname_t fn;
dns_name_t *name;
isc_mem_t *mctx;
isc_refcount_t references;
void *data;
uint16_t locknum;
/* XXX: most of these bitfields aren't needed anymore */
unsigned int : 0; /* start of bitfields */
uint8_t dirty : 1;
uint8_t wild : 1;
unsigned int is_root : 1; /*%< range is 0..1 */
unsigned int color : 1; /*%< range is 0..1 */
unsigned int find_callback : 1; /*%< range is 0..1 */
bool absolute : 1; /*%< node with absolute DNS name */
unsigned int nsec : 2; /*%< range is 0..3 */
unsigned int namelen : 8; /*%< range is 1..255 */
unsigned int offsetlen : 8; /*%< range is 1..128 */
unsigned int oldnamelen : 8; /*%< range is 1..255 */
unsigned int : 0; /* end of bitfields */
/*%
* Used for LRU cache. This linked list is used to mark nodes which
* have no data any longer, but we cannot unlink at that exact moment
* because we did not or could not obtain a write lock on the tree.
*/
ISC_LINK(dns_qpdata_t) deadlink;
};
struct dns_rbtdb {
/* Unlocked. */
dns_db_t common;
@@ -246,9 +130,9 @@ struct dns_rbtdb {
isc_rwlock_t tree_lock;
/* Locks for individual tree nodes */
unsigned int node_lock_count;
rbtdb_nodelock_t *node_locks;
dns_rbtnode_t *origin_node;
dns_rbtnode_t *nsec3_origin_node;
db_nodelock_t *node_locks;
dns_qpdata_t *origin;
dns_qpdata_t *nsec3_origin;
dns_stats_t *rrsetstats; /* cache DB only */
isc_stats_t *cachestats; /* cache DB only */
isc_stats_t *gluecachestats; /* zone DB only */
@@ -262,8 +146,6 @@ struct dns_rbtdb {
dns_rbtdb_version_t *future_version;
rbtdb_versionlist_t open_versions;
isc_loop_t *loop;
dns_dbnode_t *soanode;
dns_dbnode_t *nsnode;
/*
* The time after a failed lookup, where stale answers from cache
@@ -283,7 +165,7 @@ struct dns_rbtdb {
* Temporary storage for stale cache nodes and dynamically deleted
* nodes that await being cleaned up.
*/
dns_rbtnodelist_t *deadnodes;
dns_qpdatalist_t *deadnodes;
/*
* Heaps. These are used for TTL based expiry in a cache,
@@ -296,9 +178,9 @@ struct dns_rbtdb {
isc_heapcompare_t sooner;
/* Locked by tree_lock. */
dns_rbt_t *tree;
dns_rbt_t *nsec;
dns_rbt_t *nsec3;
dns_qp_t *tree;
dns_qp_t *nsec;
dns_qp_t *nsec3;
/* Unlocked */
unsigned int quantum;
@@ -316,29 +198,13 @@ typedef struct {
bool copy_name;
bool need_cleanup;
bool wild;
dns_rbtnode_t *zonecut;
dns_qpdata_t *zonecut;
dns_slabheader_t *zonecut_header;
dns_slabheader_t *zonecut_sigheader;
dns_fixedname_t zonecut_name;
isc_stdtime_t now;
} rbtdb_search_t;
/*%
* Load Context
*/
typedef struct {
dns_rbtdb_t *rbtdb;
isc_stdtime_t now;
} rbtdb_load_t;
/*%
* Prune context
*/
typedef struct {
dns_db_t *db;
dns_rbtnode_t *node;
} prune_t;
extern dns_dbmethods_t dns__rbtdb_zonemethods;
extern dns_dbmethods_t dns__rbtdb_cachemethods;
@@ -391,7 +257,7 @@ isc_result_t
dns__rbtdb_findnode(dns_db_t *db, const dns_name_t *name, bool create,
dns_dbnode_t **nodep DNS__DB_FLARG);
isc_result_t
dns__rbtdb_findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree,
dns__rbtdb_findnodeintree(dns_rbtdb_t *rbtdb, dns_qp_t *tree,
const dns_name_t *name, bool create,
dns_dbnode_t **nodep DNS__DB_FLARG);
/*%<
@@ -490,7 +356,7 @@ dns__rbtdb_unlocknode(dns_db_t *db, dns_dbnode_t *node, isc_rwlocktype_t type);
* rbt-cachedb.c:
*/
void
dns__rbtdb_bindrdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
dns__rbtdb_bindrdataset(dns_rbtdb_t *rbtdb, dns_qpdata_t *node,
dns_slabheader_t *header, isc_stdtime_t now,
isc_rwlocktype_t locktype,
dns_rdataset_t *rdataset DNS__DB_FLARG);
@@ -502,7 +368,7 @@ void
dns__rbtdb_freeglue(dns_glue_t *glue_list);
void
dns__rbtdb_newref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
dns__rbtdb_newref(dns_rbtdb_t *rbtdb, dns_qpdata_t *node,
isc_rwlocktype_t locktype DNS__DB_FLARG);
/*%<
* Increment the reference counter to a node in an RBT database.
@@ -513,10 +379,9 @@ dns__rbtdb_newref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
*/
bool
dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
uint32_t least_serial, isc_rwlocktype_t *nlocktypep,
isc_rwlocktype_t *tlocktypep, bool tryupgrade,
bool pruning DNS__DB_FLARG);
dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_qpdata_t *node, uint32_t least_serial,
isc_rwlocktype_t *nlocktypep, isc_rwlocktype_t *tlocktypep,
bool tryupgrade, bool pruning DNS__DB_FLARG);
/*%<
* Decrement the reference counter to a node in an RBT database.
* 'nlocktypep' and 'tlocktypep' are pointers to the current status
@@ -527,7 +392,7 @@ dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
*/
isc_result_t
dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_qpdata_t *node,
const dns_name_t *nodename, dns_rbtdb_version_t *rbtversion,
dns_slabheader_t *newheader, unsigned int options, bool loading,
dns_rdataset_t *addedrdataset, isc_stdtime_t now DNS__DB_FLARG);
@@ -564,17 +429,17 @@ dns__rbtdb_setttl(dns_slabheader_t *header, dns_ttl_t newttl);
* Functions specific to zone databases that are also called from rbtdb.c.
*/
void
dns__zonedb_resigninsert(dns_rbtdb_t *rbtdb, int idx,
dns__zoneqp_resigninsert(dns_rbtdb_t *rbtdb, int idx,
dns_slabheader_t *newheader);
void
dns__zonedb_resigndelete(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *version,
dns__zoneqp_resigndelete(dns_rbtdb_t *rbtdb, dns_rbtdb_version_t *version,
dns_slabheader_t *header DNS__DB_FLARG);
/*%<
* Insert/delete a node from the zone database's resigning heap.
*/
isc_result_t
dns__zonedb_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
dns__zoneqp_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
bool lock);
/*%<
* Add the necessary magic for the wildcard name 'name'
@@ -592,7 +457,7 @@ dns__zonedb_wildcardmagic(dns_rbtdb_t *rbtdb, const dns_name_t *name,
* The tree must be write-locked.
*/
isc_result_t
dns__zonedb_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name, bool lock);
dns__zoneqp_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name, bool lock);
/*%<
* If 'name' is or contains a wildcard name, create a node for it in the
* database. The tree must be write-locked.
@@ -602,12 +467,25 @@ dns__zonedb_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name, bool lock);
* Cache-specific functions that are called from rbtdb.c
*/
void
dns__cachedb_expireheader(dns_slabheader_t *header,
dns__cacheqp_expireheader(dns_slabheader_t *header,
isc_rwlocktype_t *tlocktypep,
dns_expire_t reason DNS__DB_FLARG);
void
dns__cachedb_overmem(dns_rbtdb_t *rbtdb, dns_slabheader_t *newheader,
dns__cacheqp_overmem(dns_rbtdb_t *rbtdb, dns_slabheader_t *newheader,
unsigned int locknum_start,
isc_rwlocktype_t *tlocktypep DNS__DB_FLARG);
#ifdef DNS_DB_NODETRACE
#define dns_qpdata_ref(ptr) dns_qpdata__ref(ptr, __func__, __FILE__, __LINE__)
#define dns_qpdata_unref(ptr) \
dns_qpdata__unref(ptr, __func__, __FILE__, __LINE__)
#define dns_qpdata_attach(ptr, ptrp) \
dns_qpdata__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
#define dns_qpdata_detach(ptrp) \
dns_qpdata__detach(ptrp, __func__, __FILE__, __LINE__)
ISC_REFCOUNT_TRACE_DECL(dns_qpdata);
#else
ISC_REFCOUNT_DECL(dns_qpdata);
#endif
ISC_LANG_ENDDECLS

View File

@@ -89,23 +89,6 @@ struct xrdata {
#endif /* if DNS_RDATASET_FIXED */
};
struct dns_glue {
struct dns_glue *next;
dns_fixedname_t fixedname;
dns_rdataset_t rdataset_a;
dns_rdataset_t sigrdataset_a;
dns_rdataset_t rdataset_aaaa;
dns_rdataset_t sigrdataset_aaaa;
struct cds_wfs_node wfs_node;
};
typedef struct {
dns_glue_t *glue_list;
dns_rbtdb_t *rbtdb;
dns_rbtdb_version_t *rbtversion;
dns_name_t *nodename;
} dns_glue_additionaldata_ctx_t;
static void
rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG);
static isc_result_t
@@ -1160,6 +1143,23 @@ dns_slabheader_destroy(dns_slabheader_t **headerp) {
isc_mem_put(mctx, header, size);
}
void
dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proof) {
if (dns_name_dynamic(&(*proof)->name)) {
dns_name_free(&(*proof)->name, mctx);
}
if ((*proof)->neg != NULL) {
isc_mem_put(mctx, (*proof)->neg,
dns_rdataslab_size((*proof)->neg, 0));
}
if ((*proof)->negsig != NULL) {
isc_mem_put(mctx, (*proof)->negsig,
dns_rdataslab_size((*proof)->negsig, 0));
}
isc_mem_put(mctx, *proof, sizeof(**proof));
*proof = NULL;
}
dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods = {
.disassociate = rdataset_disassociate,
.first = rdataset_first,
@@ -1331,7 +1331,7 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *nsecsig DNS__DB_FLARG) {
dns_db_t *db = rdataset->slab.db;
dns_dbnode_t *node = rdataset->slab.node;
const dns_proof_t *noqname = rdataset->slab.noqname;
const dns_slabheader_proof_t *noqname = rdataset->slab.noqname;
/*
* Usually, rdataset->slab.raw refers the data following a
@@ -1387,7 +1387,7 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *nsecsig DNS__DB_FLARG) {
dns_db_t *db = rdataset->slab.db;
dns_dbnode_t *node = rdataset->slab.node;
const dns_proof_t *closest = rdataset->slab.closest;
const dns_slabheader_proof_t *closest = rdataset->slab.closest;
/*
* As mentioned above, rdataset->slab.raw usually refers the data

View File

@@ -311,15 +311,30 @@ new_rbt(isc_mem_t *mem) {
static isc_result_t
add_rbt(void *rbt, size_t count) {
isc_result_t result = dns_rbt_addname(rbt, &item[count].fixed.name,
&item[count]);
isc_result_t result;
dns_rbtnode_t *node = NULL;
result = dns_rbt_addnode(rbt, &item[count].fixed.name, &node);
if (result == ISC_R_SUCCESS ||
(result == ISC_R_EXISTS && node->data == NULL))
{
node->data = &item[count];
result = ISC_R_SUCCESS;
}
return (result);
}
static isc_result_t
get_rbt(void *rbt, size_t count, void **pval) {
isc_result_t result = dns_rbt_findname(rbt, &item[count].fixed.name, 0,
NULL, pval);
isc_result_t result;
dns_rbtnode_t *node = NULL;
result = dns_rbt_findnode(rbt, &item[count].fixed.name, NULL, &node,
NULL, 0, NULL, NULL);
if (result == ISC_R_SUCCESS) {
*pval = node->data;
}
return (result);
}

View File

@@ -150,7 +150,8 @@ test_context_setup(void) {
for (i = 0; i < domain_names_count; i++) {
size_t *n;
dns_fixedname_t fname;
dns_name_t *name;
dns_name_t *name = NULL;
dns_rbtnode_t *node = NULL;
dns_test_namefromstring(domain_names[i], &fname);
@@ -159,13 +160,16 @@ test_context_setup(void) {
n = isc_mem_get(mctx, sizeof(size_t));
assert_non_null(n);
*n = i + 1;
result = dns_rbt_addname(ctx->rbt, name, n);
result = dns_rbt_addnode(ctx->rbt, name, &node);
assert_int_equal(result, ISC_R_SUCCESS);
node->data = n;
node = NULL;
n = isc_mem_get(mctx, sizeof(size_t));
assert_non_null(n);
*n = node_distances[i];
result = dns_rbt_addname(ctx->rbt_distances, name, n);
result = dns_rbt_addnode(ctx->rbt_distances, name, &node);
node->data = n;
assert_int_equal(result, ISC_R_SUCCESS);
}
@@ -174,8 +178,8 @@ test_context_setup(void) {
static void
test_context_teardown(test_context_t *ctx) {
dns_rbt_destroy(&ctx->rbt);
dns_rbt_destroy(&ctx->rbt_distances);
dns_rbt_destroy(&ctx->rbt, 0);
dns_rbt_destroy(&ctx->rbt_distances, 0);
isc_mem_put(mctx, ctx, sizeof(*ctx));
}
@@ -194,15 +198,18 @@ check_test_data(dns_rbt_t *rbt) {
for (i = 0; i < domain_names_count; i++) {
dns_fixedname_t fname;
dns_name_t *name;
size_t *n;
dns_rbtnode_t *node = NULL;
dns_name_t *name = NULL;
size_t *n = NULL;
dns_test_namefromstring(domain_names[i], &fname);
name = dns_fixedname_name(&fname);
n = NULL;
result = dns_rbt_findname(rbt, name, 0, foundname, (void *)&n);
result = dns_rbt_findnode(rbt, name, foundname, &node, NULL, 0,
NULL, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
n = node->data;
assert_int_equal(*n, i + 1);
}
}
@@ -311,7 +318,7 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
* yueojmhyffslpvfmgyfwioxegfhepnqq.
*/
for (i = 0; i < (1 << log_num_nodes); i++) {
size_t *n;
size_t *n = NULL;
char namebuf[34];
n = isc_mem_get(mctx, sizeof(size_t));
@@ -321,7 +328,8 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
while (1) {
int j;
dns_fixedname_t fname;
dns_name_t *name;
dns_rbtnode_t *node = NULL;
dns_name_t *name = NULL;
for (j = 0; j < 32; j++) {
uint32_t v = isc_random_uniform(26);
@@ -333,7 +341,8 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
dns_test_namefromstring(namebuf, &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_addname(mytree, name, n);
result = dns_rbt_addnode(mytree, name, &node);
node->data = n;
if (result == ISC_R_SUCCESS) {
break;
}
@@ -352,7 +361,7 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
tree_ok = dns__rbt_checkproperties(mytree);
assert_true(tree_ok);
dns_rbt_destroy(&mytree);
dns_rbt_destroy(&mytree, 0);
}
/*
@@ -389,7 +398,8 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_ordered) {
size_t *n;
char namebuf[14];
dns_fixedname_t fname;
dns_name_t *name;
dns_name_t *name = NULL;
dns_rbtnode_t *node = NULL;
n = isc_mem_get(mctx, sizeof(size_t));
assert_non_null(n);
@@ -399,8 +409,9 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_ordered) {
dns_test_namefromstring(namebuf, &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_addname(mytree, name, n);
result = dns_rbt_addnode(mytree, name, &node);
assert_int_equal(result, ISC_R_SUCCESS);
node->data = n;
}
/* 1 (root . node) + (1 << log_num_nodes) */
@@ -415,7 +426,7 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_ordered) {
tree_ok = dns__rbt_checkproperties(mytree);
assert_true(tree_ok);
dns_rbt_destroy(&mytree);
dns_rbt_destroy(&mytree, 0);
}
static isc_result_t
@@ -610,6 +621,26 @@ ISC_RUN_TEST_IMPL(rbt_insert) {
* as a red-black tree. This test checks node deletion when upper nodes
* have data.
*/
static isc_result_t
deletename(dns_rbt_t *mytree, const dns_name_t *name) {
isc_result_t result;
dns_rbtnode_t *node = NULL;
result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, 0, NULL,
NULL);
if (result == ISC_R_SUCCESS) {
if (node->data != NULL) {
result = dns_rbt_deletenode(mytree, node, false);
} else {
result = ISC_R_NOTFOUND;
}
} else if (result == DNS_R_PARTIALMATCH) {
result = ISC_R_NOTFOUND;
}
return (result);
}
ISC_RUN_TEST_IMPL(rbt_remove) {
isc_result_t result;
size_t j;
@@ -673,7 +704,7 @@ ISC_RUN_TEST_IMPL(rbt_remove) {
name = dns_fixedname_name(&fname);
result = dns_rbt_deletename(mytree, name, false);
result = deletename(mytree, name);
assert_int_equal(result, ISC_R_SUCCESS);
}
@@ -783,7 +814,7 @@ ISC_RUN_TEST_IMPL(rbt_remove) {
/* We should have reached the end of the tree. */
assert_null(node);
dns_rbt_destroy(&mytree);
dns_rbt_destroy(&mytree, 0);
}
}
@@ -840,22 +871,22 @@ remove_nodes(dns_rbt_t *mytree, char **names, size_t *names_count,
UNUSED(mytree);
for (i = 0; i < num_names; i++) {
uint32_t node;
dns_fixedname_t fname;
dns_name_t *name;
isc_result_t result;
dns_fixedname_t fname;
dns_name_t *name = NULL;
uint32_t num;
node = isc_random_uniform(*names_count);
num = isc_random_uniform(*names_count);
dns_test_namefromstring(names[node], &fname);
dns_test_namefromstring(names[num], &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_deletename(mytree, name, false);
result = deletename(mytree, name);
assert_int_equal(result, ISC_R_SUCCESS);
isc_mem_free(mctx, names[node]);
isc_mem_free(mctx, names[num]);
if (*names_count > 0) {
names[node] = names[*names_count - 1];
names[num] = names[*names_count - 1];
names[*names_count - 1] = NULL;
*names_count -= 1;
}
@@ -901,7 +932,8 @@ check_tree(dns_rbt_t *mytree, char **names, size_t names_count) {
ISC_RUN_TEST_IMPL(rbt_insert_and_remove) {
isc_result_t result;
dns_rbt_t *mytree = NULL;
size_t *n;
size_t *n = NULL;
dns_rbtnode_t *node = NULL;
char *names[1024];
size_t names_count;
int i;
@@ -913,8 +945,9 @@ ISC_RUN_TEST_IMPL(rbt_insert_and_remove) {
n = isc_mem_get(mctx, sizeof(size_t));
assert_non_null(n);
result = dns_rbt_addname(mytree, dns_rootname, n);
result = dns_rbt_addnode(mytree, dns_rootname, &node);
assert_int_equal(result, ISC_R_SUCCESS);
node->data = n;
memset(names, 0, sizeof(names));
names_count = 0;
@@ -954,116 +987,11 @@ ISC_RUN_TEST_IMPL(rbt_insert_and_remove) {
}
}
result = dns_rbt_deletename(mytree, dns_rootname, false);
result = deletename(mytree, dns_rootname);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(dns_rbt_nodecount(mytree), 0);
dns_rbt_destroy(&mytree);
}
/* Test findname return values */
ISC_RUN_TEST_IMPL(rbt_findname) {
isc_result_t result;
test_context_t *ctx = NULL;
dns_fixedname_t fname, found;
dns_name_t *name = NULL, *foundname = NULL;
size_t *n = NULL;
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
ctx = test_context_setup();
/* Try to find a name that exists. */
dns_test_namefromstring("d.e.f.", &fname);
name = dns_fixedname_name(&fname);
foundname = dns_fixedname_initname(&found);
result = dns_rbt_findname(ctx->rbt, name, DNS_RBTFIND_EMPTYDATA,
foundname, (void *)&n);
assert_true(dns_name_equal(foundname, name));
assert_int_equal(result, ISC_R_SUCCESS);
/* Now without EMPTYDATA */
result = dns_rbt_findname(ctx->rbt, name, 0, foundname, (void *)&n);
assert_int_equal(result, ISC_R_NOTFOUND);
/* Now one that partially matches */
dns_test_namefromstring("d.e.f.g.h.i.j.", &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_findname(ctx->rbt, name, DNS_RBTFIND_EMPTYDATA,
foundname, (void *)&n);
assert_int_equal(result, DNS_R_PARTIALMATCH);
/* Now one that doesn't match */
dns_test_namefromstring("1.2.", &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_findname(ctx->rbt, name, DNS_RBTFIND_EMPTYDATA,
foundname, (void *)&n);
assert_int_equal(result, DNS_R_PARTIALMATCH);
assert_true(dns_name_equal(foundname, dns_rootname));
test_context_teardown(ctx);
}
/* Test addname return values */
ISC_RUN_TEST_IMPL(rbt_addname) {
isc_result_t result;
test_context_t *ctx = NULL;
dns_fixedname_t fname;
dns_name_t *name = NULL;
size_t *n;
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
ctx = test_context_setup();
n = isc_mem_get(mctx, sizeof(size_t));
assert_non_null(n);
*n = 1;
dns_test_namefromstring("d.e.f.g.h.i.j.k.", &fname);
name = dns_fixedname_name(&fname);
/* Add a name that doesn't exist */
result = dns_rbt_addname(ctx->rbt, name, n);
assert_int_equal(result, ISC_R_SUCCESS);
/* Now add again, should get ISC_R_EXISTS */
n = isc_mem_get(mctx, sizeof(size_t));
assert_non_null(n);
*n = 2;
result = dns_rbt_addname(ctx->rbt, name, n);
assert_int_equal(result, ISC_R_EXISTS);
isc_mem_put(mctx, n, sizeof(size_t));
test_context_teardown(ctx);
}
/* Test deletename return values */
ISC_RUN_TEST_IMPL(rbt_deletename) {
isc_result_t result;
test_context_t *ctx = NULL;
dns_fixedname_t fname;
dns_name_t *name = NULL;
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
ctx = test_context_setup();
/* Delete a name that doesn't exist */
dns_test_namefromstring("z.x.y.w.", &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_deletename(ctx->rbt, name, false);
assert_int_equal(result, ISC_R_NOTFOUND);
/* Now one that does */
dns_test_namefromstring("d.e.f.", &fname);
name = dns_fixedname_name(&fname);
result = dns_rbt_deletename(ctx->rbt, name, false);
assert_int_equal(result, ISC_R_NOTFOUND);
test_context_teardown(ctx);
dns_rbt_destroy(&mytree, 0);
}
/* Test nodechain */
@@ -1124,7 +1052,7 @@ ISC_RUN_TEST_IMPL(rbt_nodechain) {
test_context_teardown(ctx);
}
/* Test addname return values */
/* Test name lengths */
ISC_RUN_TEST_IMPL(rbtnode_namelen) {
isc_result_t result;
test_context_t *ctx = NULL;
@@ -1270,7 +1198,7 @@ ISC_RUN_TEST_IMPL(benchmark) {
free(names);
free(fnames);
dns_rbt_destroy(&mytree);
dns_rbt_destroy(&mytree, 0);
}
#endif /* defined(DNS_BENCHMARK_TESTS) && !defined(__SANITIZE_THREAD__) */
@@ -1283,9 +1211,6 @@ ISC_TEST_ENTRY(rbt_check_distance_ordered)
ISC_TEST_ENTRY(rbt_insert)
ISC_TEST_ENTRY(rbt_remove)
ISC_TEST_ENTRY(rbt_insert_and_remove)
ISC_TEST_ENTRY(rbt_findname)
ISC_TEST_ENTRY(rbt_addname)
ISC_TEST_ENTRY(rbt_deletename)
ISC_TEST_ENTRY(rbt_nodechain)
ISC_TEST_ENTRY(rbtnode_namelen)
#if defined(DNS_BENCHMARK_TESTS) && !defined(__SANITIZE_THREAD__)

View File

@@ -96,7 +96,7 @@ const char *ownercase_vectors[12][2] = {
static bool
ownercase_test_one(const char *str1, const char *str2) {
isc_result_t result;
rbtdb_nodelock_t node_locks[1];
db_nodelock_t node_locks[1];
dns_rbtdb_t rbtdb = {
.common.methods = &dns__rbtdb_zonemethods,
.common.mctx = mctx,
@@ -163,7 +163,7 @@ ISC_RUN_TEST_IMPL(ownercase) {
ISC_RUN_TEST_IMPL(setownercase) {
isc_result_t result;
rbtdb_nodelock_t node_locks[1];
db_nodelock_t node_locks[1];
dns_rbtdb_t rbtdb = {
.common.methods = &dns__rbtdb_zonemethods,
.common.mctx = mctx,