sdb.c revision c0d2891f6e08fcf5379dfb9a1bf8fbbb63f1952a
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sdb.c,v 1.46 2004/07/22 03:58:07 marka Exp $ */
#include <config.h>
#include <string.h>
#include <dns/callbacks.h>
#include <dns/dbiterator.h>
#include <dns/fixedname.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/rdatatype.h>
#include "rdatalist_p.h"
struct dns_sdbimplementation {
const dns_sdbmethods_t *methods;
void *driverdata;
unsigned int flags;
};
struct dns_sdb {
/* Unlocked */
char *zone;
void *dbdata;
/* Locked */
unsigned int references;
};
struct dns_sdblookup {
/* Unlocked */
unsigned int magic;
/* Locked */
unsigned int references;
};
typedef struct dns_sdblookup dns_sdbnode_t;
struct dns_sdballnodes {
};
typedef dns_sdballnodes_t sdb_dbiterator_t;
typedef struct sdb_rdatasetiter {
/*
* Note that "impmagic" is not the first four bytes of the struct, so
* ISC_MAGIC_VALID cannot be used.
*/
/* These values are taken from RFC 1537 */
/* This is a reasonable value */
#define MAYBE_LOCK(sdb) \
do { \
if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
} while (0)
#define MAYBE_UNLOCK(sdb) \
do { \
if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
} while (0)
static int dummy;
dns_name_t *name);
dns_name_t *name);
dns_name_t *name);
static dns_dbiteratormethods_t dbiterator_methods = {
};
static dns_rdatasetitermethods_t rdatasetiter_methods = {
};
/*
* Functions used by implementors of simple databases
*/
{
DNS_SDBFLAG_THREADSAFE)) == 0);
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
"isc_mutex_init() failed: %s",
goto cleanup_mctx;
}
if (result != ISC_R_SUCCESS)
goto cleanup_mutex;
return (ISC_R_SUCCESS);
return (result);
}
void
}
static inline unsigned int
initial_size(unsigned int len) {
unsigned int size;
return (size);
return (64 * 1024);
}
{
break;
}
return (ISC_R_NOMEMORY);
} else
return (DNS_R_BADTTL);
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS)
goto failure;
®ion);
return (result);
}
const char *data)
{
unsigned int datalen;
unsigned char *p = NULL;
unsigned int size = 0; /* Init to suppress compiler warning */
isc_buffer_t b;
if (result != ISC_R_SUCCESS)
return (result);
else
if (result != ISC_R_SUCCESS)
goto failure;
for (;;) {
isc_buffer_add(&b, datalen);
if (result != ISC_R_SUCCESS)
goto failure;
if (p == NULL) {
goto failure;
}
origin, 0,
if (result != ISC_R_NOSPACE)
break;
p = NULL;
size *= 2;
} while (result == ISC_R_NOSPACE);
if (result != ISC_R_SUCCESS)
goto failure;
if (p != NULL)
return (result);
}
static isc_result_t
isc_buffer_t b;
else
if (result != ISC_R_SUCCESS)
return (result);
/* All names are relative to the root */
}
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_NOMEMORY);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
}
return (ISC_R_SUCCESS);
}
{
if (result != ISC_R_SUCCESS)
return (result);
}
{
if (result != ISC_R_SUCCESS)
return (result);
}
{
int n;
if (n >= (int)sizeof(str) || n < 0)
return (ISC_R_NOSPACE);
}
/*
* DB routines
*/
static void
sdb->references++;
}
static void
}
}
static void
sdb->references--;
if (sdb->references == 0)
if (need_destroy)
}
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
}
static void
return;
}
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
}
static void
{
return;
}
static void
}
static isc_result_t
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
"isc_mutex_init() failed: %s",
return (ISC_R_UNEXPECTED);
}
return (ISC_R_SUCCESS);
}
static void
isc_buffer_t *b;
}
}
isc_buffer_free(&b);
}
}
}
static isc_result_t
{
isc_buffer_t b;
unsigned int labels;
if (result != ISC_R_SUCCESS)
return (result);
} else {
if (result != ISC_R_SUCCESS)
return (result);
}
isc_buffer_putuint8(&b, 0);
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS &&
!(result == ISC_R_NOTFOUND &&
{
return (result);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
}
return (ISC_R_SUCCESS);
}
static isc_result_t
{
unsigned int i;
return (DNS_R_NXDOMAIN);
}
/*
* Unless this is an explicit lookup at the origin, don't
* look at the origin.
*/
continue;
/*
* Look up the next label.
*/
if (result != ISC_R_SUCCESS) {
continue;
}
/*
* Look for a DNAME at the current label, unless this is
* the qname.
*/
if (i < nlabels) {
if (result == ISC_R_SUCCESS) {
break;
}
}
/*
* Look for an NS at the current label, unless this is the
* origin or glue is ok.
*/
if (result == ISC_R_SUCCESS) {
{
if (sigrdataset != NULL)
(sigrdataset);
} else
break;
}
}
/*
* If the current name is not the qname, add another label
* and try again.
*/
if (i < nlabels) {
continue;
}
/*
* If we're looking for ANY, we're done.
*/
if (type == dns_rdatatype_any) {
break;
}
/*
* Look for the qtype.
*/
if (result == ISC_R_SUCCESS)
break;
/*
* Look for a CNAME
*/
if (type != dns_rdatatype_cname) {
if (result == ISC_R_SUCCESS) {
break;
}
}
break;
}
if (xresult != ISC_R_SUCCESS) {
return (DNS_R_BADDB);
}
}
return (result);
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
}
static void
node->references++;
}
static void
node->references--;
if (node->references == 0)
if (need_destroy)
}
static isc_result_t
INSIST(0);
return (ISC_R_UNEXPECTED);
}
static void
return;
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
return (ISC_R_SUCCESS);
}
static isc_result_t
{
if (type == dns_rdatatype_rrsig)
return (ISC_R_NOTIMPLEMENTED);
break;
}
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
}
static isc_result_t
{
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
}
static isc_boolean_t
return (ISC_FALSE);
}
static unsigned int
return (0);
}
static isc_boolean_t
return (ISC_TRUE);
}
static void
}
static void
}
static dns_dbmethods_t sdb_methods = {
dump,
find,
};
static isc_result_t
{
isc_buffer_t b;
if (type != dns_dbtype_zone)
return (ISC_R_NOTIMPLEMENTED);
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
"isc_mutex_init() failed: %s",
goto cleanup_mctx;
}
if (result != ISC_R_SUCCESS)
goto cleanup_lock;
if (result != ISC_R_SUCCESS)
goto cleanup_origin;
isc_buffer_putuint8(&b, 0);
goto cleanup_origin;
}
if (result != ISC_R_SUCCESS)
goto cleanup_zonestr;
}
return (ISC_R_SUCCESS);
return (result);
}
/*
* Rdataset Methods
*/
static void
}
static void
}
static dns_rdatasetmethods_t methods = {
};
static void
{
/*
* The sdb rdataset is an rdatalist with some additions.
* - private1 & private2 are used by the rdatalist.
* - private3 & private 4 are unused.
* - private5 is the node.
*/
/* This should never fail. */
}
/*
* Database Iterator Methods
*/
static void
}
}
static isc_result_t
return (ISC_R_NOMORE);
else
return (ISC_R_SUCCESS);
}
static isc_result_t
return (ISC_R_NOMORE);
else
return (ISC_R_SUCCESS);
}
static isc_result_t
return (ISC_R_SUCCESS);
return (ISC_R_NOTFOUND);
}
static isc_result_t
return (ISC_R_NOMORE);
else
return (ISC_R_SUCCESS);
}
static isc_result_t
return (ISC_R_NOMORE);
else
return (ISC_R_SUCCESS);
}
static isc_result_t
{
return (ISC_R_SUCCESS);
}
static isc_result_t
return (ISC_R_SUCCESS);
}
static isc_result_t
}
/*
* Rdataset Iterator Methods
*/
static void
sizeof(sdb_rdatasetiter_t));
}
static isc_result_t
return (ISC_R_NOMORE);
return (ISC_R_SUCCESS);
}
static isc_result_t
return (ISC_R_NOMORE);
else
return (ISC_R_SUCCESS);
}
static void
rdataset);
}