ecdb.c revision 5e93bad21b6d68fce862ff8aace3bb29b658f4f6
/*
* Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC")
*
* 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.
*/
#include "config.h"
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/rdataslab.h>
/*%
* The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides
* temporary storage for ongoing name resolution with the common DB interfaces.
* It actually doesn't cache anything. The implementation expects any stored
* data is released within a short period, and does not care about the
* scalability in terms of the number of nodes.
*/
typedef struct dns_ecdb {
/* Unlocked */
/* Locked */
unsigned int references;
} dns_ecdb_t;
typedef struct dns_ecdbnode {
/* Unlocked */
unsigned int magic;
/* Locked */
unsigned int references;
typedef struct rdatasetheader {
unsigned int attributes;
/* Copied from rbtdb.c */
#define RDATASET_ATTR_NXDOMAIN 0x0010
#define RDATASET_ATTR_NEGATIVE 0x0100
static dns_rdatasetmethods_t rdataset_methods = {
NULL, /* addnoqname */
NULL, /* getnoqname */
NULL, /* addclosest */
NULL, /* getclosest */
NULL, /* getadditional */
NULL, /* setadditional */
NULL, /* putadditional */
rdataset_settrust, /* settrust */
NULL, /* expire */
NULL, /* clearprefetch */
NULL, /* setownercase */
NULL /* getownercase */
};
typedef struct ecdb_rdatasetiter {
static dns_rdatasetitermethods_t rdatasetiter_methods = {
};
}
void
}
/*%
* DB routines
*/
static void
ecdb->references++;
}
static void
}
static void
ecdb->references--;
if (need_destroy)
destroy_ecdb(&ecdb);
}
static void
node->references++;
}
static void
unsigned int headersize;
dns_rdataslab_size((unsigned char *)header,
sizeof(*header));
}
if (need_destroydb)
destroy_ecdb(&ecdb);
}
static void
node->references--;
if (node->references == 0)
if (need_destroy)
}
static isc_result_t
{
return (ISC_R_NOTFOUND);
}
static isc_result_t
{
return (ISC_R_NOTFOUND);
}
static isc_result_t
{
/* an 'ephemeral' node is never reused. */
return (ISC_R_NOTFOUND);
}
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
"isc_mutex_init() failed: %s",
return (ISC_R_UNEXPECTED);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
static void
{
unsigned char *raw;
/*
* Caller must be holding the node lock.
*/
/*
* Reset iterator state.
*/
rdataset->privateuint4 = 0;
node->references++;
}
static isc_result_t
{
isc_region_t r;
/*
* Sanity check: this implementation does not allow overriding an
* existing rdataset of the same type.
*/
}
&r, sizeof(rdatasetheader_t));
if (result != ISC_R_SUCCESS)
goto unlock;
header->attributes = 0;
if (addedrdataset == NULL)
goto unlock;
return (result);
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
{
return (ISC_R_NOTIMPLEMENTED);
}
static isc_result_t
{
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
static dns_dbmethods_t ecdb_methods = {
NULL, /* beginload */
NULL, /* endload */
NULL, /* serialize */
NULL, /* dump */
NULL, /* currentversion */
NULL, /* newversion */
NULL, /* attachversion */
NULL, /* closeversion */
find,
NULL, /* expirenode */
NULL, /* printnode */
createiterator, /* createiterator */
NULL, /* findrdataset */
NULL, /* subtractrdataset */
NULL, /* issecure */
NULL, /* nodecount */
NULL, /* ispersistent */
NULL, /* overmem */
NULL, /* settask */
NULL, /* getoriginnode */
NULL, /* transfernode */
NULL, /* getnsec3parameters */
NULL, /* findnsec3node */
NULL, /* setsigningtime */
NULL, /* getsigningtime */
NULL, /* resigned */
NULL, /* isdnssec */
NULL, /* getrrsetstats */
NULL, /* rpz_attach */
NULL, /* rpz_ready */
NULL, /* findnodeext */
NULL, /* findext */
NULL, /* setcachestats */
NULL /* hashsize */
};
static isc_result_t
{
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (result != ISC_R_SUCCESS) {
"isc_mutex_init() failed: %s",
return (ISC_R_UNEXPECTED);
}
return (ISC_R_SUCCESS);
}
/*%
* Rdataset Methods
*/
static void
}
static isc_result_t
unsigned int count;
if (count == 0) {
return (ISC_R_NOMORE);
}
#else
raw += 2;
#endif
/*
* The privateuint4 field is the number of rdata beyond the cursor
* position, so we decrement the total count by one before storing
* it.
*/
count--;
return (ISC_R_SUCCESS);
}
static isc_result_t
unsigned int count;
unsigned int length;
unsigned char *raw;
if (count == 0)
return (ISC_R_NOMORE);
count--;
#else
#endif
return (ISC_R_SUCCESS);
}
static void
isc_region_t r;
unsigned int length;
unsigned int flags = 0;
raw += 4;
#else
raw += 2;
#endif
if (*raw & DNS_RDATASLAB_OFFLINE)
length--;
raw++;
}
}
static void
/*
* Reset iterator state.
*/
target->privateuint4 = 0;
}
static unsigned int
unsigned int count;
return (count);
}
static void
header--;
}
/*
* Rdataset Iterator Methods
*/
static void
union {
} u;
u.rdatasetiterator = *iteratorp;
sizeof(ecdb_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
}