mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Support for AXFR and minor cleanup.
This commit is contained in:
parent
32de824866
commit
60b90a37f4
@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: sdb.h,v 1.5 2000/08/22 22:06:46 bwelling Exp $ */
|
||||
/* $Id: sdb.h,v 1.6 2000/08/23 18:28:03 bwelling Exp $ */
|
||||
|
||||
#ifndef DNS_SDB_H
|
||||
#define DNS_SDB_H 1
|
||||
@ -47,10 +47,13 @@ typedef struct dns_sdb dns_sdb_t;
|
||||
|
||||
/*
|
||||
* A simple database lookup in progress. This is an opaque type.
|
||||
* It's also the database node returned by dns_db_* functions.
|
||||
*/
|
||||
typedef struct dns_sdblookup dns_sdblookup_t;
|
||||
typedef struct dns_sdblookup dns_sdbnode_t;
|
||||
|
||||
/*
|
||||
* A simple database traversal in progress. This is an opaque type.
|
||||
*/
|
||||
typedef struct dns_sdballnodes dns_sdballnodes_t;
|
||||
|
||||
typedef isc_result_t
|
||||
(*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata,
|
||||
@ -59,6 +62,10 @@ typedef isc_result_t
|
||||
typedef isc_result_t
|
||||
(*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *);
|
||||
|
||||
typedef isc_result_t
|
||||
(*dns_sdballnodesfunc_t)(const char *zone, void *dbdata,
|
||||
dns_sdballnodes_t *allnodes);
|
||||
|
||||
typedef isc_result_t
|
||||
(*dns_sdbcreatefunc_t)(const char *zone, int argc, char **argv,
|
||||
void *driverdata, void **dbdata);
|
||||
@ -66,9 +73,11 @@ typedef isc_result_t
|
||||
typedef void
|
||||
(*dns_sdbdestroyfunc_t)(const char *zone, void *driverdata, void **dbdata);
|
||||
|
||||
|
||||
typedef struct dns_sdbmethods {
|
||||
dns_sdblookupfunc_t lookup;
|
||||
dns_sdbauthorityfunc_t authority;
|
||||
dns_sdballnodesfunc_t allnodes;
|
||||
dns_sdbcreatefunc_t create;
|
||||
dns_sdbdestroyfunc_t destroy;
|
||||
} dns_sdbmethods_t;
|
||||
@ -105,6 +114,12 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
|
||||
* these records. The 'authority' function may be NULL if invoking
|
||||
* the 'lookup' function on the zone apex will return SOA and NS records.
|
||||
*
|
||||
* The allnodes function, if non-NULL, fills in an opaque structure to be
|
||||
* used by a database iterator. This allows the zone to be transferred.
|
||||
* This may use a considerable amount of memory for large zones, and the
|
||||
* zone transfer may not be RFC 1035 compliant if the zone is frequently
|
||||
* changed.
|
||||
*
|
||||
* The create function will be called when a database is created, and
|
||||
* allows the implementation to create database specific data.
|
||||
*
|
||||
@ -134,8 +149,16 @@ isc_result_t
|
||||
dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
|
||||
const char *data);
|
||||
/*
|
||||
* Return a single resource record as a partial result for 'lookup' to
|
||||
* the name server.
|
||||
* Add a single resource record to the lookup structure to be later
|
||||
* parsed into a query response.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name,
|
||||
const char *type, dns_ttl_t ttl, const char *data);
|
||||
/*
|
||||
* Add a single resource record to the allnodes structure to be later
|
||||
* parsed into a zone transfer response.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
|
276
lib/dns/sdb.c
276
lib/dns/sdb.c
@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: sdb.c,v 1.5 2000/08/22 22:06:44 bwelling Exp $ */
|
||||
/* $Id: sdb.c,v 1.6 2000/08/23 18:28:02 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/db.h>
|
||||
#include <dns/dbiterator.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
@ -67,11 +68,24 @@ struct dns_sdblookup {
|
||||
dns_sdb_t *sdb;
|
||||
ISC_LIST(dns_rdatalist_t) lists;
|
||||
ISC_LIST(isc_buffer_t) buffers;
|
||||
dns_name_t *name;
|
||||
ISC_LINK(dns_sdblookup_t) link;
|
||||
isc_mutex_t lock;
|
||||
/* Locked */
|
||||
unsigned int references;
|
||||
};
|
||||
|
||||
typedef struct dns_sdblookup dns_sdbnode_t;
|
||||
|
||||
struct dns_sdballnodes {
|
||||
dns_dbiterator_t common;
|
||||
ISC_LIST(dns_sdbnode_t) nodelist;
|
||||
dns_sdbnode_t *current;
|
||||
dns_sdbnode_t *origin;
|
||||
};
|
||||
|
||||
typedef dns_sdballnodes_t sdb_dbiterator_t;
|
||||
|
||||
typedef struct sdb_rdatasetiter {
|
||||
dns_rdatasetiter_t common;
|
||||
dns_rdatalist_t *current;
|
||||
@ -109,6 +123,10 @@ static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset);
|
||||
|
||||
static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep);
|
||||
|
||||
static void destroynode(dns_sdbnode_t *node);
|
||||
|
||||
static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
|
||||
|
||||
|
||||
@ -116,12 +134,37 @@ static void list_tordataset(dns_rdatalist_t *rdatalist,
|
||||
dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_rdataset_t *rdataset);
|
||||
|
||||
static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
|
||||
static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
|
||||
static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
|
||||
static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
|
||||
dns_name_t *name);
|
||||
static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
|
||||
static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
|
||||
static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
|
||||
dns_dbnode_t **nodep,
|
||||
dns_name_t *name);
|
||||
static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
|
||||
static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
|
||||
dns_name_t *name);
|
||||
|
||||
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
|
||||
static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
|
||||
static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
|
||||
static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
|
||||
dns_rdataset_t *rdataset);
|
||||
static dns_dbiteratormethods_t dbiterator_methods = {
|
||||
dbiterator_destroy,
|
||||
dbiterator_first,
|
||||
dbiterator_last,
|
||||
dbiterator_seek,
|
||||
dbiterator_prev,
|
||||
dbiterator_next,
|
||||
dbiterator_current,
|
||||
dbiterator_pause,
|
||||
dbiterator_origin
|
||||
};
|
||||
|
||||
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
|
||||
static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
|
||||
static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
|
||||
static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
|
||||
dns_rdataset_t *rdataset);
|
||||
|
||||
static dns_rdatasetitermethods_t rdatasetiter_methods = {
|
||||
rdatasetiter_destroy,
|
||||
@ -303,6 +346,66 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name,
|
||||
const char *type, dns_ttl_t ttl, const char *data)
|
||||
{
|
||||
dns_name_t *newname, *origin;
|
||||
dns_fixedname_t fnewname;
|
||||
dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db;
|
||||
sdbimp_t *imp = sdb->implementation;
|
||||
dns_sdbnode_t *sdbnode;
|
||||
isc_mem_t *mctx = sdb->common.mctx;
|
||||
isc_buffer_t b;
|
||||
isc_result_t result;
|
||||
|
||||
dns_fixedname_init(&fnewname);
|
||||
newname = dns_fixedname_name(&fnewname);
|
||||
|
||||
if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
|
||||
origin = &sdb->common.origin;
|
||||
else
|
||||
origin = dns_rootname;
|
||||
isc_buffer_init(&b, name, strlen(name));
|
||||
isc_buffer_add(&b, strlen(name));
|
||||
|
||||
result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
if (allnodes->common.relative_names) {
|
||||
/* All names are relative to the root */
|
||||
unsigned int nlabels = dns_name_countlabels(newname);
|
||||
dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
|
||||
}
|
||||
|
||||
sdbnode = ISC_LIST_HEAD(allnodes->nodelist);
|
||||
if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) {
|
||||
sdbnode = NULL;
|
||||
result = createnode(sdb, &sdbnode);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t));
|
||||
if (sdbnode->name == NULL) {
|
||||
destroynode(sdbnode);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
dns_name_init(sdbnode->name, NULL);
|
||||
result = dns_name_dup(newname, mctx, sdbnode->name);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t));
|
||||
destroynode(sdbnode);
|
||||
return (result);
|
||||
}
|
||||
ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link);
|
||||
if (allnodes->origin == NULL &&
|
||||
dns_name_equal(newname, &sdb->common.origin))
|
||||
allnodes->origin = sdbnode;
|
||||
}
|
||||
return (dns_sdb_putrr(sdbnode, type, ttl, data));
|
||||
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname,
|
||||
isc_uint32_t serial)
|
||||
@ -459,6 +562,8 @@ createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) {
|
||||
attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb);
|
||||
ISC_LIST_INIT(node->lists);
|
||||
ISC_LIST_INIT(node->buffers);
|
||||
ISC_LINK_INIT(node, link);
|
||||
node->name = NULL;
|
||||
result = isc_mutex_init(&node->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(sdb->common.mctx, sdb, sizeof(dns_sdb_t));
|
||||
@ -481,18 +586,20 @@ destroynode(dns_sdbnode_t *node) {
|
||||
dns_rdata_t *rdata;
|
||||
isc_buffer_t *b;
|
||||
dns_sdb_t *sdb;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
sdb = node->sdb;
|
||||
mctx = sdb->common.mctx;
|
||||
|
||||
while (!ISC_LIST_EMPTY(node->lists)) {
|
||||
list = ISC_LIST_HEAD(node->lists);
|
||||
while (!ISC_LIST_EMPTY(list->rdata)) {
|
||||
rdata = ISC_LIST_HEAD(list->rdata);
|
||||
ISC_LIST_UNLINK(list->rdata, rdata, link);
|
||||
isc_mem_put(node->sdb->common.mctx, rdata,
|
||||
sizeof(dns_rdata_t));
|
||||
isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
|
||||
}
|
||||
ISC_LIST_UNLINK(node->lists, list, link);
|
||||
isc_mem_put(node->sdb->common.mctx, list,
|
||||
sizeof(dns_rdatalist_t));
|
||||
isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
|
||||
}
|
||||
|
||||
while (!ISC_LIST_EMPTY(node->buffers)) {
|
||||
@ -501,10 +608,13 @@ destroynode(dns_sdbnode_t *node) {
|
||||
isc_buffer_free(&b);
|
||||
}
|
||||
|
||||
if (node->name != NULL) {
|
||||
dns_name_free(node->name, mctx);
|
||||
isc_mem_put(mctx, node->name, sizeof(dns_name_t));
|
||||
}
|
||||
isc_mutex_destroy(&node->lock);
|
||||
sdb = node->sdb;
|
||||
node->magic = 0;
|
||||
isc_mem_put(node->sdb->common.mctx, node, sizeof(dns_sdbnode_t));
|
||||
isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
|
||||
detach((dns_db_t **)&sdb);
|
||||
}
|
||||
|
||||
@ -798,10 +908,43 @@ static isc_result_t
|
||||
createiterator(dns_db_t *db, isc_boolean_t relative_names,
|
||||
dns_dbiterator_t **iteratorp)
|
||||
{
|
||||
UNUSED(db);
|
||||
UNUSED(relative_names);
|
||||
UNUSED(iteratorp);
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
dns_sdb_t *sdb = (dns_sdb_t *)db;
|
||||
sdb_dbiterator_t *sdbiter;
|
||||
sdbimp_t *imp = sdb->implementation;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_SDB(sdb));
|
||||
|
||||
if (imp->methods->allnodes == NULL)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
|
||||
sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t));
|
||||
if (sdbiter == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
sdbiter->common.methods = &dbiterator_methods;
|
||||
sdbiter->common.db = NULL;
|
||||
dns_db_attach(db, &sdbiter->common.db);
|
||||
sdbiter->common.relative_names = relative_names;
|
||||
sdbiter->common.magic = DNS_DBITERATOR_MAGIC;
|
||||
ISC_LIST_INIT(sdbiter->nodelist);
|
||||
sdbiter->current = NULL;
|
||||
sdbiter->origin = NULL;
|
||||
|
||||
result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dbiterator_destroy((dns_dbiterator_t **)&sdbiter);
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (sdbiter->origin != NULL) {
|
||||
ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link);
|
||||
ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link);
|
||||
}
|
||||
|
||||
*iteratorp = (dns_dbiterator_t *)sdbiter;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@ -1087,6 +1230,107 @@ list_tordataset(dns_rdatalist_t *rdatalist,
|
||||
dns_db_attachnode(db, node, &rdataset->private5);
|
||||
}
|
||||
|
||||
/*
|
||||
* Database Iterator Methods
|
||||
*/
|
||||
static void
|
||||
dbiterator_destroy(dns_dbiterator_t **iteratorp) {
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp);
|
||||
dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db;
|
||||
|
||||
while (!ISC_LIST_EMPTY(sdbiter->nodelist)) {
|
||||
dns_sdbnode_t *node;
|
||||
node = ISC_LIST_HEAD(sdbiter->nodelist);
|
||||
ISC_LIST_UNLINK(sdbiter->nodelist, node, link);
|
||||
destroynode(node);
|
||||
}
|
||||
|
||||
dns_db_detach(&sdbiter->common.db);
|
||||
isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t));
|
||||
|
||||
*iteratorp = NULL;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_first(dns_dbiterator_t *iterator) {
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
|
||||
|
||||
sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
|
||||
if (sdbiter->current == NULL)
|
||||
return (ISC_R_NOMORE);
|
||||
else
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_last(dns_dbiterator_t *iterator) {
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
|
||||
|
||||
sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist);
|
||||
if (sdbiter->current == NULL)
|
||||
return (ISC_R_NOMORE);
|
||||
else
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
|
||||
|
||||
sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
|
||||
while (sdbiter->current != NULL)
|
||||
if (dns_name_equal(sdbiter->current->name, name))
|
||||
return (ISC_R_SUCCESS);
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_prev(dns_dbiterator_t *iterator) {
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
|
||||
|
||||
sdbiter->current = ISC_LIST_PREV(sdbiter->current, link);
|
||||
if (sdbiter->current == NULL)
|
||||
return (ISC_R_NOMORE);
|
||||
else
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_next(dns_dbiterator_t *iterator) {
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
|
||||
|
||||
sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
|
||||
if (sdbiter->current == NULL)
|
||||
return (ISC_R_NOMORE);
|
||||
else
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
|
||||
dns_name_t *name)
|
||||
{
|
||||
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
|
||||
|
||||
attachnode(iterator->db, sdbiter->current, nodep);
|
||||
if (name != NULL)
|
||||
return (dns_name_concatenate(sdbiter->current->name, NULL,
|
||||
name, NULL));
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dbiterator_pause(dns_dbiterator_t *iterator) {
|
||||
UNUSED(iterator);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
|
||||
UNUSED(iterator);
|
||||
return (dns_name_concatenate(dns_rootname, NULL, name, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Rdataset Iterator Methods
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user