Compare commits

...

4 Commits

Author SHA1 Message Date
Matthijs Mekking
32547b81f5 WIP: add delegation db to the cache 2023-02-02 17:00:22 +01:00
Matthijs Mekking
955cdf3db5 Introduce new db type for storing delegations
Introduce a new database type dns_dbtype_delegation, that is going to
be used for storing and looking up delegation records (NS).

This database will be used for the resolver to follow delegations. NS
RRsets will be stored into both the cache db and delegation db. The
child side of the NS RRset will be stored in the cache database, while
the parent side will be stored in the delegation cache.
2023-02-02 09:42:08 +01:00
Matthijs Mekking
0c79ed1b7d Add new rdatatype attribute 'delegation'
Introduce a new rdatatype attribute DNS_RDATATYPEATTR_DELEGATION that
can be used to determine if the RRset of that type can be found in the
delegation cache.

Currently this is only RRtype=NS.
2023-02-02 09:38:22 +01:00
Matthijs Mekking
70694bf1d2 Remove unused nsnode and soanode from rbtdb 2023-01-26 11:52:29 +01:00
8 changed files with 130 additions and 21 deletions

View File

@@ -77,6 +77,7 @@ struct dns_cache {
/* Locked by 'lock'. */
dns_rdataclass_t rdclass;
dns_db_t *db;
dns_db_t *nsdb;
size_t size;
dns_ttl_t serve_stale_ttl;
dns_ttl_t serve_stale_refresh;
@@ -89,7 +90,7 @@ struct dns_cache {
***/
static isc_result_t
cache_create_db(dns_cache_t *cache, dns_db_t **db) {
cache_create_db(dns_cache_t *cache, dns_dbtype_t dbtype, dns_db_t **db) {
isc_result_t result;
char *argv[1] = { 0 };
@@ -99,8 +100,8 @@ cache_create_db(dns_cache_t *cache, dns_db_t **db) {
* dns_db_create() via argv[0].
*/
argv[0] = (char *)cache->hmctx;
result = dns_db_create(cache->mctx, "rbt", dns_rootname,
dns_dbtype_cache, cache->rdclass, 1, argv, db);
result = dns_db_create(cache->mctx, "rbt", dns_rootname, dbtype,
cache->rdclass, 1, argv, db);
if (result == ISC_R_SUCCESS) {
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
}
@@ -155,12 +156,19 @@ dns_cache_create(isc_loopmgr_t *loopmgr, dns_rdataclass_t rdclass,
/*
* Create the database
*/
result = cache_create_db(cache, &cache->db);
result = cache_create_db(cache, dns_dbtype_cache, &cache->db);
if (result != ISC_R_SUCCESS) {
goto cleanup_stats;
}
result = cache_create_db(cache, dns_dbtype_delegation, &cache->nsdb);
if (result != ISC_R_SUCCESS) {
goto cleanup_db;
}
dns_db_setloop(cache->db, isc_loop_main(loopmgr));
dns_db_setloop(cache->nsdb, isc_loop_main(loopmgr));
cache->magic = CACHE_MAGIC;
/*
@@ -169,12 +177,19 @@ dns_cache_create(isc_loopmgr_t *loopmgr, dns_rdataclass_t rdclass,
*/
result = dns_db_setcachestats(cache->db, cache->stats);
if (result != ISC_R_SUCCESS) {
goto cleanup_db;
goto cleanup_nsdb;
}
result = dns_db_setcachestats(cache->nsdb, cache->stats);
if (result != ISC_R_SUCCESS) {
goto cleanup_nsdb;
}
*cachep = cache;
return (ISC_R_SUCCESS);
cleanup_nsdb:
dns_db_detach(&cache->nsdb);
cleanup_db:
dns_db_detach(&cache->db);
cleanup_stats:
@@ -194,6 +209,7 @@ cache_free(dns_cache_t *cache) {
isc_refcount_destroy(&cache->references);
isc_mem_clearwater(cache->mctx);
dns_db_detach(&cache->nsdb);
dns_db_detach(&cache->db);
isc_mem_free(cache->mctx, cache->name);
isc_stats_detach(&cache->stats);
@@ -240,6 +256,17 @@ dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp) {
UNLOCK(&cache->lock);
}
void
dns_cache_attachnsdb(dns_cache_t *cache, dns_db_t **dbp) {
REQUIRE(VALID_CACHE(cache));
REQUIRE(dbp != NULL && *dbp == NULL);
REQUIRE(cache->db != NULL);
LOCK(&cache->lock);
dns_db_attach(cache->nsdb, dbp);
UNLOCK(&cache->lock);
}
const char *
dns_cache_getname(dns_cache_t *cache) {
REQUIRE(VALID_CACHE(cache));
@@ -259,6 +286,7 @@ water(void *arg, int mark) {
dns_db_overmem(cache->db, overmem);
cache->overmem = overmem;
isc_mem_waterack(cache->mctx, mark);
/* WMM: Probably some nsdb overmem updates required */
}
UNLOCK(&cache->lock);
}
@@ -353,6 +381,7 @@ dns_cache_setservestalerefresh(dns_cache_t *cache, dns_ttl_t interval) {
UNLOCK(&cache->lock);
(void)dns_db_setservestalerefresh(cache->db, interval);
(void)dns_db_setservestalerefresh(cache->nsdb, interval);
}
dns_ttl_t
@@ -369,20 +398,32 @@ dns_cache_getservestalerefresh(dns_cache_t *cache) {
isc_result_t
dns_cache_flush(dns_cache_t *cache) {
dns_db_t *db = NULL, *olddb;
dns_db_t *nsdb = NULL, *oldnsdb;
isc_result_t result;
result = cache_create_db(cache, &db);
result = cache_create_db(cache, dns_dbtype_cache, &db);
if (result != ISC_R_SUCCESS) {
return (result);
}
result = cache_create_db(cache, dns_dbtype_delegation, &nsdb);
if (result != ISC_R_SUCCESS) {
dns_db_detach(&db);
return (result);
}
LOCK(&cache->lock);
olddb = cache->db;
cache->db = db;
dns_db_setcachestats(cache->db, cache->stats);
oldnsdb = cache->nsdb;
cache->nsdb = nsdb;
dns_db_setcachestats(cache->nsdb, cache->stats);
UNLOCK(&cache->lock);
dns_db_detach(&olddb);
dns_db_detach(&oldnsdb);
return (ISC_R_SUCCESS);
}
@@ -501,6 +542,42 @@ dns_cache_flushname(dns_cache_t *cache, const dns_name_t *name) {
return (dns_cache_flushnode(cache, name, false));
}
static isc_result_t
dbns_flushnode(dns_cache_t *cache, const dns_name_t *name, bool tree) {
isc_result_t result;
dns_dbnode_t *node = NULL;
dns_db_t *db = NULL;
LOCK(&cache->lock);
if (cache->nsdb != NULL) {
dns_db_attach(cache->nsdb, &db);
}
UNLOCK(&cache->lock);
if (db == NULL) {
return (ISC_R_SUCCESS);
}
if (tree) {
result = cleartree(cache->nsdb, name);
} else {
result = dns_db_findnode(cache->nsdb, name, false, &node);
if (result == ISC_R_NOTFOUND) {
result = ISC_R_SUCCESS;
goto cleanup_db;
}
if (result != ISC_R_SUCCESS) {
goto cleanup_db;
}
result = clearnode(cache->nsdb, node);
dns_db_detachnode(cache->nsdb, &node);
}
cleanup_db:
dns_db_detach(&db);
return (result);
}
isc_result_t
dns_cache_flushnode(dns_cache_t *cache, const dns_name_t *name, bool tree) {
isc_result_t result;
@@ -517,7 +594,7 @@ dns_cache_flushnode(dns_cache_t *cache, const dns_name_t *name, bool tree) {
}
UNLOCK(&cache->lock);
if (db == NULL) {
return (ISC_R_SUCCESS);
return (dbns_flushnode(cache, name, tree));
}
if (tree) {
@@ -537,7 +614,11 @@ dns_cache_flushnode(dns_cache_t *cache, const dns_name_t *name, bool tree) {
cleanup_db:
dns_db_detach(&db);
return (result);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (dbns_flushnode(cache, name, tree));
}
isc_stats_t *
@@ -643,6 +724,7 @@ dns_cache_dumpstats(dns_cache_t *cache, FILE *fp) {
"cache NSEC auxiliary database nodes");
fprintf(fp, "%20" PRIu64 " %s\n", (uint64_t)dns_db_hashsize(cache->db),
"cache database hash buckets");
/* WMM: Probably some nsdb stats adaptations needed */
fprintf(fp, "%20" PRIu64 " %s\n", (uint64_t)isc_mem_inuse(cache->mctx),
"cache tree memory in use");
@@ -703,6 +785,7 @@ dns_cache_renderxml(dns_cache_t *cache, void *writer0) {
TRY0(renderstat("CacheNSECNodes",
dns_db_nodecount(cache->db, dns_dbtree_nsec), writer));
TRY0(renderstat("CacheBuckets", dns_db_hashsize(cache->db), writer));
/* WMM: Probably some nsdb stats adaptations needed here */
TRY0(renderstat("TreeMemInUse", isc_mem_inuse(cache->mctx), writer));
@@ -775,6 +858,7 @@ dns_cache_renderjson(dns_cache_t *cache, void *cstats0) {
obj = json_object_new_int64(dns_db_hashsize(cache->db));
CHECKMEM(obj);
json_object_object_add(cstats, "CacheBuckets", obj);
/* WMM: Probably some nsdb stats adaptations needed here */
obj = json_object_new_int64(isc_mem_inuse(cache->mctx));
CHECKMEM(obj);

View File

@@ -116,6 +116,8 @@ dns_cache_detach(dns_cache_t **cachep);
void
dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp);
void
dns_cache_attachnsdb(dns_cache_t *cache, dns_db_t **dbp);
/*%<
* Attach *dbp to the cache's database.
*

View File

@@ -219,8 +219,9 @@ struct dns_db {
ISC_LIST(dns_dbonupdatelistener_t) update_listeners;
};
#define DNS_DBATTR_CACHE 0x01
#define DNS_DBATTR_STUB 0x02
#define DNS_DBATTR_CACHE 0x01
#define DNS_DBATTR_STUB 0x02
#define DNS_DBATTR_DELEGATION 0x04
struct dns_dbonupdatelistener {
dns_dbupdate_callback_t onupdate;

View File

@@ -684,6 +684,17 @@ dns_rdatatype_atparent(dns_rdatatype_t type);
*
*/
bool
dns_rdatatype_isdelegation(dns_rdatatype_t type);
/*%<
* Return true iff rdata of type 'type' should appear at both the parent and
* child side of a zone cut.
*
* Requires:
* \li 'type' is a valid rdata type.
*
*/
bool
dns_rdatatype_atcname(dns_rdatatype_t type);
/*%<
@@ -745,6 +756,8 @@ dns_rdatatype_attributes(dns_rdatatype_t rdtype);
#define DNS_RDATATYPEATTR_ATCNAME 0x00000400U
/*% Follow additional */
#define DNS_RDATATYPEATTR_FOLLOWADDITIONAL 0x00000800U
/*% Is present at parent and child apex */
#define DNS_RDATATYPEATTR_DELEGATION 0x00001000U
dns_rdatatype_t
dns_rdata_covers(dns_rdata_t *rdata);

View File

@@ -181,7 +181,8 @@ typedef enum { dns_one_answer, dns_many_answers } dns_transfer_format_t;
typedef enum {
dns_dbtype_zone = 0,
dns_dbtype_cache = 1,
dns_dbtype_stub = 3
dns_dbtype_stub = 3,
dns_dbtype_delegation = 4
} dns_dbtype_t;
typedef enum {

View File

@@ -507,8 +507,6 @@ struct dns_rbtdb {
rbtdb_version_t *future_version;
rbtdb_versionlist_t open_versions;
isc_loop_t *loop;
dns_dbnode_t *soanode;
dns_dbnode_t *nsnode;
/*
* Maximum length of time to keep using a stale answer past its
@@ -763,6 +761,8 @@ typedef struct rbtdb_dbiterator {
#define IS_STUB(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_STUB) != 0)
#define IS_CACHE(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_CACHE) != 0)
#define IS_DELEGCACHE(rbtdb) \
(((rbtdb)->common.attributes & DNS_DBATTR_DELEGATION) != 0)
static void
free_rbtdb(dns_rbtdb_t *rbtdb, bool log);
@@ -1206,13 +1206,6 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
/* XXX check for open versions here */
if (rbtdb->soanode != NULL) {
dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->soanode);
}
if (rbtdb->nsnode != NULL) {
dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->nsnode);
}
/*
* The current version's glue table needs to be freed early
* so the nodes are dereferenced before we check the active
@@ -8238,6 +8231,10 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
} else if (type == dns_dbtype_stub) {
rbtdb->common.methods = &zone_methods;
rbtdb->common.attributes |= DNS_DBATTR_STUB;
} else if (type == dns_dbtype_delegation) {
rbtdb->common.methods = &cache_methods;
rbtdb->common.attributes |= DNS_DBATTR_CACHE;
rbtdb->common.attributes |= DNS_DBATTR_DELEGATION;
} else {
rbtdb->common.methods = &zone_methods;
}

View File

@@ -2245,6 +2245,16 @@ dns_rdatatype_atparent(dns_rdatatype_t type) {
return (false);
}
bool
dns_rdatatype_isdelegation(dns_rdatatype_t type) {
if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DELEGATION) !=
0)
{
return (true);
}
return (false);
}
bool
dns_rdatatype_followadditional(dns_rdatatype_t type) {
if ((dns_rdatatype_attributes(type) &

View File

@@ -14,7 +14,8 @@
#ifndef RDATA_GENERIC_NS_2_C
#define RDATA_GENERIC_NS_2_C
#define RRTYPE_NS_ATTRIBUTES (DNS_RDATATYPEATTR_ZONECUTAUTH)
#define RRTYPE_NS_ATTRIBUTES \
(DNS_RDATATYPEATTR_ZONECUTAUTH | DNS_RDATATYPEATTR_DELEGATION)
static isc_result_t
fromtext_ns(ARGS_FROMTEXT) {