1*00b67f09SDavid van Moolenbroek /* $NetBSD: sdb.c,v 1.9 2015/07/08 17:28:59 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek
26*00b67f09SDavid van Moolenbroek #include <string.h>
27*00b67f09SDavid van Moolenbroek
28*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
29*00b67f09SDavid van Moolenbroek #include <isc/lex.h>
30*00b67f09SDavid van Moolenbroek #include <isc/log.h>
31*00b67f09SDavid van Moolenbroek #include <isc/magic.h>
32*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
33*00b67f09SDavid van Moolenbroek #include <isc/once.h>
34*00b67f09SDavid van Moolenbroek #include <isc/print.h>
35*00b67f09SDavid van Moolenbroek #include <isc/region.h>
36*00b67f09SDavid van Moolenbroek #include <isc/util.h>
37*00b67f09SDavid van Moolenbroek
38*00b67f09SDavid van Moolenbroek #include <dns/callbacks.h>
39*00b67f09SDavid van Moolenbroek #include <dns/db.h>
40*00b67f09SDavid van Moolenbroek #include <dns/dbiterator.h>
41*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
42*00b67f09SDavid van Moolenbroek #include <dns/log.h>
43*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
44*00b67f09SDavid van Moolenbroek #include <dns/rdatalist.h>
45*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
46*00b67f09SDavid van Moolenbroek #include <dns/rdatasetiter.h>
47*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
48*00b67f09SDavid van Moolenbroek #include <dns/result.h>
49*00b67f09SDavid van Moolenbroek #include <dns/sdb.h>
50*00b67f09SDavid van Moolenbroek #include <dns/types.h>
51*00b67f09SDavid van Moolenbroek
52*00b67f09SDavid van Moolenbroek #include "rdatalist_p.h"
53*00b67f09SDavid van Moolenbroek
54*00b67f09SDavid van Moolenbroek struct dns_sdbimplementation {
55*00b67f09SDavid van Moolenbroek const dns_sdbmethods_t *methods;
56*00b67f09SDavid van Moolenbroek void *driverdata;
57*00b67f09SDavid van Moolenbroek unsigned int flags;
58*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
59*00b67f09SDavid van Moolenbroek isc_mutex_t driverlock;
60*00b67f09SDavid van Moolenbroek dns_dbimplementation_t *dbimp;
61*00b67f09SDavid van Moolenbroek };
62*00b67f09SDavid van Moolenbroek
63*00b67f09SDavid van Moolenbroek struct dns_sdb {
64*00b67f09SDavid van Moolenbroek /* Unlocked */
65*00b67f09SDavid van Moolenbroek dns_db_t common;
66*00b67f09SDavid van Moolenbroek char *zone;
67*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *implementation;
68*00b67f09SDavid van Moolenbroek void *dbdata;
69*00b67f09SDavid van Moolenbroek isc_mutex_t lock;
70*00b67f09SDavid van Moolenbroek /* Locked */
71*00b67f09SDavid van Moolenbroek unsigned int references;
72*00b67f09SDavid van Moolenbroek };
73*00b67f09SDavid van Moolenbroek
74*00b67f09SDavid van Moolenbroek struct dns_sdblookup {
75*00b67f09SDavid van Moolenbroek /* Unlocked */
76*00b67f09SDavid van Moolenbroek unsigned int magic;
77*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb;
78*00b67f09SDavid van Moolenbroek ISC_LIST(dns_rdatalist_t) lists;
79*00b67f09SDavid van Moolenbroek ISC_LIST(isc_buffer_t) buffers;
80*00b67f09SDavid van Moolenbroek dns_name_t *name;
81*00b67f09SDavid van Moolenbroek ISC_LINK(dns_sdblookup_t) link;
82*00b67f09SDavid van Moolenbroek isc_mutex_t lock;
83*00b67f09SDavid van Moolenbroek dns_rdatacallbacks_t callbacks;
84*00b67f09SDavid van Moolenbroek /* Locked */
85*00b67f09SDavid van Moolenbroek unsigned int references;
86*00b67f09SDavid van Moolenbroek };
87*00b67f09SDavid van Moolenbroek
88*00b67f09SDavid van Moolenbroek typedef struct dns_sdblookup dns_sdbnode_t;
89*00b67f09SDavid van Moolenbroek
90*00b67f09SDavid van Moolenbroek struct dns_sdballnodes {
91*00b67f09SDavid van Moolenbroek dns_dbiterator_t common;
92*00b67f09SDavid van Moolenbroek ISC_LIST(dns_sdbnode_t) nodelist;
93*00b67f09SDavid van Moolenbroek dns_sdbnode_t *current;
94*00b67f09SDavid van Moolenbroek dns_sdbnode_t *origin;
95*00b67f09SDavid van Moolenbroek };
96*00b67f09SDavid van Moolenbroek
97*00b67f09SDavid van Moolenbroek typedef dns_sdballnodes_t sdb_dbiterator_t;
98*00b67f09SDavid van Moolenbroek
99*00b67f09SDavid van Moolenbroek typedef struct sdb_rdatasetiter {
100*00b67f09SDavid van Moolenbroek dns_rdatasetiter_t common;
101*00b67f09SDavid van Moolenbroek dns_rdatalist_t *current;
102*00b67f09SDavid van Moolenbroek } sdb_rdatasetiter_t;
103*00b67f09SDavid van Moolenbroek
104*00b67f09SDavid van Moolenbroek #define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-')
105*00b67f09SDavid van Moolenbroek
106*00b67f09SDavid van Moolenbroek /*%
107*00b67f09SDavid van Moolenbroek * Note that "impmagic" is not the first four bytes of the struct, so
108*00b67f09SDavid van Moolenbroek * ISC_MAGIC_VALID cannot be used.
109*00b67f09SDavid van Moolenbroek */
110*00b67f09SDavid van Moolenbroek #define VALID_SDB(sdb) ((sdb) != NULL && \
111*00b67f09SDavid van Moolenbroek (sdb)->common.impmagic == SDB_MAGIC)
112*00b67f09SDavid van Moolenbroek
113*00b67f09SDavid van Moolenbroek #define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L')
114*00b67f09SDavid van Moolenbroek #define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC)
115*00b67f09SDavid van Moolenbroek #define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn)
116*00b67f09SDavid van Moolenbroek
117*00b67f09SDavid van Moolenbroek /* These values are taken from RFC1537 */
118*00b67f09SDavid van Moolenbroek #define SDB_DEFAULT_REFRESH (60 * 60 * 8)
119*00b67f09SDavid van Moolenbroek #define SDB_DEFAULT_RETRY (60 * 60 * 2)
120*00b67f09SDavid van Moolenbroek #define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
121*00b67f09SDavid van Moolenbroek #define SDB_DEFAULT_MINIMUM (60 * 60 * 24)
122*00b67f09SDavid van Moolenbroek
123*00b67f09SDavid van Moolenbroek /* This is a reasonable value */
124*00b67f09SDavid van Moolenbroek #define SDB_DEFAULT_TTL (60 * 60 * 24)
125*00b67f09SDavid van Moolenbroek
126*00b67f09SDavid van Moolenbroek #ifdef __COVERITY__
127*00b67f09SDavid van Moolenbroek #define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock)
128*00b67f09SDavid van Moolenbroek #define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock)
129*00b67f09SDavid van Moolenbroek #else
130*00b67f09SDavid van Moolenbroek #define MAYBE_LOCK(sdb) \
131*00b67f09SDavid van Moolenbroek do { \
132*00b67f09SDavid van Moolenbroek unsigned int flags = sdb->implementation->flags; \
133*00b67f09SDavid van Moolenbroek if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
134*00b67f09SDavid van Moolenbroek LOCK(&sdb->implementation->driverlock); \
135*00b67f09SDavid van Moolenbroek } while (/*CONSTCOND*/0)
136*00b67f09SDavid van Moolenbroek
137*00b67f09SDavid van Moolenbroek #define MAYBE_UNLOCK(sdb) \
138*00b67f09SDavid van Moolenbroek do { \
139*00b67f09SDavid van Moolenbroek unsigned int flags = sdb->implementation->flags; \
140*00b67f09SDavid van Moolenbroek if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
141*00b67f09SDavid van Moolenbroek UNLOCK(&sdb->implementation->driverlock); \
142*00b67f09SDavid van Moolenbroek } while (/*CONSTCOND*/0)
143*00b67f09SDavid van Moolenbroek #endif
144*00b67f09SDavid van Moolenbroek
145*00b67f09SDavid van Moolenbroek static int dummy;
146*00b67f09SDavid van Moolenbroek
147*00b67f09SDavid van Moolenbroek static isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin,
148*00b67f09SDavid van Moolenbroek dns_dbtype_t type, dns_rdataclass_t rdclass,
149*00b67f09SDavid van Moolenbroek unsigned int argc, char *argv[],
150*00b67f09SDavid van Moolenbroek void *driverarg, dns_db_t **dbp);
151*00b67f09SDavid van Moolenbroek
152*00b67f09SDavid van Moolenbroek static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node,
153*00b67f09SDavid van Moolenbroek dns_dbversion_t *version,
154*00b67f09SDavid van Moolenbroek dns_rdatatype_t type, dns_rdatatype_t covers,
155*00b67f09SDavid van Moolenbroek isc_stdtime_t now, dns_rdataset_t *rdataset,
156*00b67f09SDavid van Moolenbroek dns_rdataset_t *sigrdataset);
157*00b67f09SDavid van Moolenbroek
158*00b67f09SDavid van Moolenbroek static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep);
159*00b67f09SDavid van Moolenbroek
160*00b67f09SDavid van Moolenbroek static void destroynode(dns_sdbnode_t *node);
161*00b67f09SDavid van Moolenbroek
162*00b67f09SDavid van Moolenbroek static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
163*00b67f09SDavid van Moolenbroek
164*00b67f09SDavid van Moolenbroek
165*00b67f09SDavid van Moolenbroek static void list_tordataset(dns_rdatalist_t *rdatalist,
166*00b67f09SDavid van Moolenbroek dns_db_t *db, dns_dbnode_t *node,
167*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset);
168*00b67f09SDavid van Moolenbroek
169*00b67f09SDavid van Moolenbroek static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
170*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
171*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
172*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
173*00b67f09SDavid van Moolenbroek dns_name_t *name);
174*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
175*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
176*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
177*00b67f09SDavid van Moolenbroek dns_dbnode_t **nodep,
178*00b67f09SDavid van Moolenbroek dns_name_t *name);
179*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
180*00b67f09SDavid van Moolenbroek static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
181*00b67f09SDavid van Moolenbroek dns_name_t *name);
182*00b67f09SDavid van Moolenbroek
183*00b67f09SDavid van Moolenbroek static dns_dbiteratormethods_t dbiterator_methods = {
184*00b67f09SDavid van Moolenbroek dbiterator_destroy,
185*00b67f09SDavid van Moolenbroek dbiterator_first,
186*00b67f09SDavid van Moolenbroek dbiterator_last,
187*00b67f09SDavid van Moolenbroek dbiterator_seek,
188*00b67f09SDavid van Moolenbroek dbiterator_prev,
189*00b67f09SDavid van Moolenbroek dbiterator_next,
190*00b67f09SDavid van Moolenbroek dbiterator_current,
191*00b67f09SDavid van Moolenbroek dbiterator_pause,
192*00b67f09SDavid van Moolenbroek dbiterator_origin
193*00b67f09SDavid van Moolenbroek };
194*00b67f09SDavid van Moolenbroek
195*00b67f09SDavid van Moolenbroek static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
196*00b67f09SDavid van Moolenbroek static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
197*00b67f09SDavid van Moolenbroek static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
198*00b67f09SDavid van Moolenbroek static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
199*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset);
200*00b67f09SDavid van Moolenbroek
201*00b67f09SDavid van Moolenbroek static dns_rdatasetitermethods_t rdatasetiter_methods = {
202*00b67f09SDavid van Moolenbroek rdatasetiter_destroy,
203*00b67f09SDavid van Moolenbroek rdatasetiter_first,
204*00b67f09SDavid van Moolenbroek rdatasetiter_next,
205*00b67f09SDavid van Moolenbroek rdatasetiter_current
206*00b67f09SDavid van Moolenbroek };
207*00b67f09SDavid van Moolenbroek
208*00b67f09SDavid van Moolenbroek /*
209*00b67f09SDavid van Moolenbroek * Functions used by implementors of simple databases
210*00b67f09SDavid van Moolenbroek */
211*00b67f09SDavid van Moolenbroek isc_result_t
dns_sdb_register(const char * drivername,const dns_sdbmethods_t * methods,void * driverdata,unsigned int flags,isc_mem_t * mctx,dns_sdbimplementation_t ** sdbimp)212*00b67f09SDavid van Moolenbroek dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
213*00b67f09SDavid van Moolenbroek void *driverdata, unsigned int flags, isc_mem_t *mctx,
214*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t **sdbimp)
215*00b67f09SDavid van Moolenbroek {
216*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp;
217*00b67f09SDavid van Moolenbroek isc_result_t result;
218*00b67f09SDavid van Moolenbroek
219*00b67f09SDavid van Moolenbroek REQUIRE(drivername != NULL);
220*00b67f09SDavid van Moolenbroek REQUIRE(methods != NULL);
221*00b67f09SDavid van Moolenbroek REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL);
222*00b67f09SDavid van Moolenbroek REQUIRE(mctx != NULL);
223*00b67f09SDavid van Moolenbroek REQUIRE(sdbimp != NULL && *sdbimp == NULL);
224*00b67f09SDavid van Moolenbroek REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER |
225*00b67f09SDavid van Moolenbroek DNS_SDBFLAG_RELATIVERDATA |
226*00b67f09SDavid van Moolenbroek DNS_SDBFLAG_THREADSAFE|
227*00b67f09SDavid van Moolenbroek DNS_SDBFLAG_DNS64)) == 0);
228*00b67f09SDavid van Moolenbroek
229*00b67f09SDavid van Moolenbroek imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t));
230*00b67f09SDavid van Moolenbroek if (imp == NULL)
231*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
232*00b67f09SDavid van Moolenbroek imp->methods = methods;
233*00b67f09SDavid van Moolenbroek imp->driverdata = driverdata;
234*00b67f09SDavid van Moolenbroek imp->flags = flags;
235*00b67f09SDavid van Moolenbroek imp->mctx = NULL;
236*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &imp->mctx);
237*00b67f09SDavid van Moolenbroek result = isc_mutex_init(&imp->driverlock);
238*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
239*00b67f09SDavid van Moolenbroek goto cleanup_mctx;
240*00b67f09SDavid van Moolenbroek
241*00b67f09SDavid van Moolenbroek imp->dbimp = NULL;
242*00b67f09SDavid van Moolenbroek result = dns_db_register(drivername, dns_sdb_create, imp, mctx,
243*00b67f09SDavid van Moolenbroek &imp->dbimp);
244*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
245*00b67f09SDavid van Moolenbroek goto cleanup_mutex;
246*00b67f09SDavid van Moolenbroek *sdbimp = imp;
247*00b67f09SDavid van Moolenbroek
248*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
249*00b67f09SDavid van Moolenbroek
250*00b67f09SDavid van Moolenbroek cleanup_mutex:
251*00b67f09SDavid van Moolenbroek DESTROYLOCK(&imp->driverlock);
252*00b67f09SDavid van Moolenbroek cleanup_mctx:
253*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t));
254*00b67f09SDavid van Moolenbroek return (result);
255*00b67f09SDavid van Moolenbroek }
256*00b67f09SDavid van Moolenbroek
257*00b67f09SDavid van Moolenbroek void
dns_sdb_unregister(dns_sdbimplementation_t ** sdbimp)258*00b67f09SDavid van Moolenbroek dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) {
259*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp;
260*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
261*00b67f09SDavid van Moolenbroek
262*00b67f09SDavid van Moolenbroek REQUIRE(sdbimp != NULL && *sdbimp != NULL);
263*00b67f09SDavid van Moolenbroek
264*00b67f09SDavid van Moolenbroek imp = *sdbimp;
265*00b67f09SDavid van Moolenbroek dns_db_unregister(&imp->dbimp);
266*00b67f09SDavid van Moolenbroek DESTROYLOCK(&imp->driverlock);
267*00b67f09SDavid van Moolenbroek
268*00b67f09SDavid van Moolenbroek mctx = imp->mctx;
269*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t));
270*00b67f09SDavid van Moolenbroek isc_mem_detach(&mctx);
271*00b67f09SDavid van Moolenbroek
272*00b67f09SDavid van Moolenbroek *sdbimp = NULL;
273*00b67f09SDavid van Moolenbroek }
274*00b67f09SDavid van Moolenbroek
275*00b67f09SDavid van Moolenbroek static inline unsigned int
initial_size(unsigned int len)276*00b67f09SDavid van Moolenbroek initial_size(unsigned int len) {
277*00b67f09SDavid van Moolenbroek unsigned int size;
278*00b67f09SDavid van Moolenbroek
279*00b67f09SDavid van Moolenbroek for (size = 1024; size < (64 * 1024); size *= 2)
280*00b67f09SDavid van Moolenbroek if (len < size)
281*00b67f09SDavid van Moolenbroek return (size);
282*00b67f09SDavid van Moolenbroek return (65535);
283*00b67f09SDavid van Moolenbroek }
284*00b67f09SDavid van Moolenbroek
285*00b67f09SDavid van Moolenbroek isc_result_t
dns_sdb_putrdata(dns_sdblookup_t * lookup,dns_rdatatype_t typeval,dns_ttl_t ttl,const unsigned char * rdatap,unsigned int rdlen)286*00b67f09SDavid van Moolenbroek dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval,
287*00b67f09SDavid van Moolenbroek dns_ttl_t ttl, const unsigned char *rdatap,
288*00b67f09SDavid van Moolenbroek unsigned int rdlen)
289*00b67f09SDavid van Moolenbroek {
290*00b67f09SDavid van Moolenbroek dns_rdatalist_t *rdatalist;
291*00b67f09SDavid van Moolenbroek dns_rdata_t *rdata;
292*00b67f09SDavid van Moolenbroek isc_buffer_t *rdatabuf = NULL;
293*00b67f09SDavid van Moolenbroek isc_result_t result;
294*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
295*00b67f09SDavid van Moolenbroek isc_region_t region;
296*00b67f09SDavid van Moolenbroek
297*00b67f09SDavid van Moolenbroek mctx = lookup->sdb->common.mctx;
298*00b67f09SDavid van Moolenbroek
299*00b67f09SDavid van Moolenbroek rdatalist = ISC_LIST_HEAD(lookup->lists);
300*00b67f09SDavid van Moolenbroek while (rdatalist != NULL) {
301*00b67f09SDavid van Moolenbroek if (rdatalist->type == typeval)
302*00b67f09SDavid van Moolenbroek break;
303*00b67f09SDavid van Moolenbroek rdatalist = ISC_LIST_NEXT(rdatalist, link);
304*00b67f09SDavid van Moolenbroek }
305*00b67f09SDavid van Moolenbroek
306*00b67f09SDavid van Moolenbroek if (rdatalist == NULL) {
307*00b67f09SDavid van Moolenbroek rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
308*00b67f09SDavid van Moolenbroek if (rdatalist == NULL)
309*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
310*00b67f09SDavid van Moolenbroek rdatalist->rdclass = lookup->sdb->common.rdclass;
311*00b67f09SDavid van Moolenbroek rdatalist->type = typeval;
312*00b67f09SDavid van Moolenbroek rdatalist->covers = 0;
313*00b67f09SDavid van Moolenbroek rdatalist->ttl = ttl;
314*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(rdatalist->rdata);
315*00b67f09SDavid van Moolenbroek ISC_LINK_INIT(rdatalist, link);
316*00b67f09SDavid van Moolenbroek ISC_LIST_APPEND(lookup->lists, rdatalist, link);
317*00b67f09SDavid van Moolenbroek } else
318*00b67f09SDavid van Moolenbroek if (rdatalist->ttl != ttl)
319*00b67f09SDavid van Moolenbroek return (DNS_R_BADTTL);
320*00b67f09SDavid van Moolenbroek
321*00b67f09SDavid van Moolenbroek rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
322*00b67f09SDavid van Moolenbroek if (rdata == NULL)
323*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
324*00b67f09SDavid van Moolenbroek
325*00b67f09SDavid van Moolenbroek result = isc_buffer_allocate(mctx, &rdatabuf, rdlen);
326*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
327*00b67f09SDavid van Moolenbroek goto failure;
328*00b67f09SDavid van Moolenbroek DE_CONST(rdatap, region.base);
329*00b67f09SDavid van Moolenbroek region.length = rdlen;
330*00b67f09SDavid van Moolenbroek isc_buffer_copyregion(rdatabuf, ®ion);
331*00b67f09SDavid van Moolenbroek isc_buffer_usedregion(rdatabuf, ®ion);
332*00b67f09SDavid van Moolenbroek dns_rdata_init(rdata);
333*00b67f09SDavid van Moolenbroek dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type,
334*00b67f09SDavid van Moolenbroek ®ion);
335*00b67f09SDavid van Moolenbroek ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
336*00b67f09SDavid van Moolenbroek ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
337*00b67f09SDavid van Moolenbroek rdata = NULL;
338*00b67f09SDavid van Moolenbroek
339*00b67f09SDavid van Moolenbroek failure:
340*00b67f09SDavid van Moolenbroek if (rdata != NULL)
341*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
342*00b67f09SDavid van Moolenbroek return (result);
343*00b67f09SDavid van Moolenbroek }
344*00b67f09SDavid van Moolenbroek
345*00b67f09SDavid van Moolenbroek isc_result_t
dns_sdb_putrr(dns_sdblookup_t * lookup,const char * type,dns_ttl_t ttl,const char * data)346*00b67f09SDavid van Moolenbroek dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
347*00b67f09SDavid van Moolenbroek const char *data)
348*00b67f09SDavid van Moolenbroek {
349*00b67f09SDavid van Moolenbroek unsigned int datalen;
350*00b67f09SDavid van Moolenbroek dns_rdatatype_t typeval;
351*00b67f09SDavid van Moolenbroek isc_textregion_t r;
352*00b67f09SDavid van Moolenbroek isc_lex_t *lex = NULL;
353*00b67f09SDavid van Moolenbroek isc_result_t result;
354*00b67f09SDavid van Moolenbroek unsigned char *p = NULL;
355*00b67f09SDavid van Moolenbroek unsigned int size = 0; /* Init to suppress compiler warning */
356*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
357*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp;
358*00b67f09SDavid van Moolenbroek dns_name_t *origin;
359*00b67f09SDavid van Moolenbroek isc_buffer_t b;
360*00b67f09SDavid van Moolenbroek isc_buffer_t rb;
361*00b67f09SDavid van Moolenbroek
362*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDBLOOKUP(lookup));
363*00b67f09SDavid van Moolenbroek REQUIRE(type != NULL);
364*00b67f09SDavid van Moolenbroek REQUIRE(data != NULL);
365*00b67f09SDavid van Moolenbroek
366*00b67f09SDavid van Moolenbroek mctx = lookup->sdb->common.mctx;
367*00b67f09SDavid van Moolenbroek
368*00b67f09SDavid van Moolenbroek DE_CONST(type, r.base);
369*00b67f09SDavid van Moolenbroek r.length = strlen(type);
370*00b67f09SDavid van Moolenbroek result = dns_rdatatype_fromtext(&typeval, &r);
371*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
372*00b67f09SDavid van Moolenbroek return (result);
373*00b67f09SDavid van Moolenbroek
374*00b67f09SDavid van Moolenbroek imp = lookup->sdb->implementation;
375*00b67f09SDavid van Moolenbroek if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
376*00b67f09SDavid van Moolenbroek origin = &lookup->sdb->common.origin;
377*00b67f09SDavid van Moolenbroek else
378*00b67f09SDavid van Moolenbroek origin = dns_rootname;
379*00b67f09SDavid van Moolenbroek
380*00b67f09SDavid van Moolenbroek result = isc_lex_create(mctx, 64, &lex);
381*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
382*00b67f09SDavid van Moolenbroek goto failure;
383*00b67f09SDavid van Moolenbroek
384*00b67f09SDavid van Moolenbroek datalen = strlen(data);
385*00b67f09SDavid van Moolenbroek size = initial_size(datalen);
386*00b67f09SDavid van Moolenbroek do {
387*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, data, datalen);
388*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, datalen);
389*00b67f09SDavid van Moolenbroek result = isc_lex_openbuffer(lex, &b);
390*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
391*00b67f09SDavid van Moolenbroek goto failure;
392*00b67f09SDavid van Moolenbroek
393*00b67f09SDavid van Moolenbroek if (size >= 65535)
394*00b67f09SDavid van Moolenbroek size = 65535;
395*00b67f09SDavid van Moolenbroek p = isc_mem_get(mctx, size);
396*00b67f09SDavid van Moolenbroek if (p == NULL) {
397*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
398*00b67f09SDavid van Moolenbroek goto failure;
399*00b67f09SDavid van Moolenbroek }
400*00b67f09SDavid van Moolenbroek isc_buffer_init(&rb, p, size);
401*00b67f09SDavid van Moolenbroek result = dns_rdata_fromtext(NULL,
402*00b67f09SDavid van Moolenbroek lookup->sdb->common.rdclass,
403*00b67f09SDavid van Moolenbroek typeval, lex,
404*00b67f09SDavid van Moolenbroek origin, 0,
405*00b67f09SDavid van Moolenbroek mctx, &rb,
406*00b67f09SDavid van Moolenbroek &lookup->callbacks);
407*00b67f09SDavid van Moolenbroek if (result != ISC_R_NOSPACE)
408*00b67f09SDavid van Moolenbroek break;
409*00b67f09SDavid van Moolenbroek
410*00b67f09SDavid van Moolenbroek /*
411*00b67f09SDavid van Moolenbroek * Is the RR too big?
412*00b67f09SDavid van Moolenbroek */
413*00b67f09SDavid van Moolenbroek if (size >= 65535)
414*00b67f09SDavid van Moolenbroek break;
415*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, p, size);
416*00b67f09SDavid van Moolenbroek p = NULL;
417*00b67f09SDavid van Moolenbroek size *= 2;
418*00b67f09SDavid van Moolenbroek } while (result == ISC_R_NOSPACE);
419*00b67f09SDavid van Moolenbroek
420*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
421*00b67f09SDavid van Moolenbroek goto failure;
422*00b67f09SDavid van Moolenbroek
423*00b67f09SDavid van Moolenbroek result = dns_sdb_putrdata(lookup, typeval, ttl,
424*00b67f09SDavid van Moolenbroek isc_buffer_base(&rb),
425*00b67f09SDavid van Moolenbroek isc_buffer_usedlength(&rb));
426*00b67f09SDavid van Moolenbroek failure:
427*00b67f09SDavid van Moolenbroek if (p != NULL)
428*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, p, size);
429*00b67f09SDavid van Moolenbroek if (lex != NULL)
430*00b67f09SDavid van Moolenbroek isc_lex_destroy(&lex);
431*00b67f09SDavid van Moolenbroek
432*00b67f09SDavid van Moolenbroek return (result);
433*00b67f09SDavid van Moolenbroek }
434*00b67f09SDavid van Moolenbroek
435*00b67f09SDavid van Moolenbroek static isc_result_t
getnode(dns_sdballnodes_t * allnodes,const char * name,dns_sdbnode_t ** nodep)436*00b67f09SDavid van Moolenbroek getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) {
437*00b67f09SDavid van Moolenbroek dns_name_t *newname, *origin;
438*00b67f09SDavid van Moolenbroek dns_fixedname_t fnewname;
439*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db;
440*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp = sdb->implementation;
441*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode;
442*00b67f09SDavid van Moolenbroek isc_mem_t *mctx = sdb->common.mctx;
443*00b67f09SDavid van Moolenbroek isc_buffer_t b;
444*00b67f09SDavid van Moolenbroek isc_result_t result;
445*00b67f09SDavid van Moolenbroek
446*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fnewname);
447*00b67f09SDavid van Moolenbroek newname = dns_fixedname_name(&fnewname);
448*00b67f09SDavid van Moolenbroek
449*00b67f09SDavid van Moolenbroek if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
450*00b67f09SDavid van Moolenbroek origin = &sdb->common.origin;
451*00b67f09SDavid van Moolenbroek else
452*00b67f09SDavid van Moolenbroek origin = dns_rootname;
453*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, name, strlen(name));
454*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(name));
455*00b67f09SDavid van Moolenbroek
456*00b67f09SDavid van Moolenbroek result = dns_name_fromtext(newname, &b, origin, 0, NULL);
457*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
458*00b67f09SDavid van Moolenbroek return (result);
459*00b67f09SDavid van Moolenbroek
460*00b67f09SDavid van Moolenbroek if (allnodes->common.relative_names) {
461*00b67f09SDavid van Moolenbroek /* All names are relative to the root */
462*00b67f09SDavid van Moolenbroek unsigned int nlabels = dns_name_countlabels(newname);
463*00b67f09SDavid van Moolenbroek dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
464*00b67f09SDavid van Moolenbroek }
465*00b67f09SDavid van Moolenbroek
466*00b67f09SDavid van Moolenbroek sdbnode = ISC_LIST_HEAD(allnodes->nodelist);
467*00b67f09SDavid van Moolenbroek if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) {
468*00b67f09SDavid van Moolenbroek sdbnode = NULL;
469*00b67f09SDavid van Moolenbroek result = createnode(sdb, &sdbnode);
470*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
471*00b67f09SDavid van Moolenbroek return (result);
472*00b67f09SDavid van Moolenbroek sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t));
473*00b67f09SDavid van Moolenbroek if (sdbnode->name == NULL) {
474*00b67f09SDavid van Moolenbroek destroynode(sdbnode);
475*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
476*00b67f09SDavid van Moolenbroek }
477*00b67f09SDavid van Moolenbroek dns_name_init(sdbnode->name, NULL);
478*00b67f09SDavid van Moolenbroek result = dns_name_dup(newname, mctx, sdbnode->name);
479*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
480*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t));
481*00b67f09SDavid van Moolenbroek destroynode(sdbnode);
482*00b67f09SDavid van Moolenbroek return (result);
483*00b67f09SDavid van Moolenbroek }
484*00b67f09SDavid van Moolenbroek ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link);
485*00b67f09SDavid van Moolenbroek if (allnodes->origin == NULL &&
486*00b67f09SDavid van Moolenbroek dns_name_equal(newname, &sdb->common.origin))
487*00b67f09SDavid van Moolenbroek allnodes->origin = sdbnode;
488*00b67f09SDavid van Moolenbroek }
489*00b67f09SDavid van Moolenbroek *nodep = sdbnode;
490*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
491*00b67f09SDavid van Moolenbroek }
492*00b67f09SDavid van Moolenbroek
493*00b67f09SDavid van Moolenbroek isc_result_t
dns_sdb_putnamedrr(dns_sdballnodes_t * allnodes,const char * name,const char * type,dns_ttl_t ttl,const char * data)494*00b67f09SDavid van Moolenbroek dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name,
495*00b67f09SDavid van Moolenbroek const char *type, dns_ttl_t ttl, const char *data)
496*00b67f09SDavid van Moolenbroek {
497*00b67f09SDavid van Moolenbroek isc_result_t result;
498*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode = NULL;
499*00b67f09SDavid van Moolenbroek result = getnode(allnodes, name, &sdbnode);
500*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
501*00b67f09SDavid van Moolenbroek return (result);
502*00b67f09SDavid van Moolenbroek return (dns_sdb_putrr(sdbnode, type, ttl, data));
503*00b67f09SDavid van Moolenbroek }
504*00b67f09SDavid van Moolenbroek
505*00b67f09SDavid van Moolenbroek isc_result_t
dns_sdb_putnamedrdata(dns_sdballnodes_t * allnodes,const char * name,dns_rdatatype_t type,dns_ttl_t ttl,const void * rdata,unsigned int rdlen)506*00b67f09SDavid van Moolenbroek dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name,
507*00b67f09SDavid van Moolenbroek dns_rdatatype_t type, dns_ttl_t ttl,
508*00b67f09SDavid van Moolenbroek const void *rdata, unsigned int rdlen)
509*00b67f09SDavid van Moolenbroek {
510*00b67f09SDavid van Moolenbroek isc_result_t result;
511*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode = NULL;
512*00b67f09SDavid van Moolenbroek result = getnode(allnodes, name, &sdbnode);
513*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
514*00b67f09SDavid van Moolenbroek return (result);
515*00b67f09SDavid van Moolenbroek return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen));
516*00b67f09SDavid van Moolenbroek }
517*00b67f09SDavid van Moolenbroek
518*00b67f09SDavid van Moolenbroek isc_result_t
dns_sdb_putsoa(dns_sdblookup_t * lookup,const char * mname,const char * rname,isc_uint32_t serial)519*00b67f09SDavid van Moolenbroek dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname,
520*00b67f09SDavid van Moolenbroek isc_uint32_t serial)
521*00b67f09SDavid van Moolenbroek {
522*00b67f09SDavid van Moolenbroek char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
523*00b67f09SDavid van Moolenbroek int n;
524*00b67f09SDavid van Moolenbroek
525*00b67f09SDavid van Moolenbroek REQUIRE(mname != NULL);
526*00b67f09SDavid van Moolenbroek REQUIRE(rname != NULL);
527*00b67f09SDavid van Moolenbroek
528*00b67f09SDavid van Moolenbroek n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u",
529*00b67f09SDavid van Moolenbroek mname, rname, serial,
530*00b67f09SDavid van Moolenbroek SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY,
531*00b67f09SDavid van Moolenbroek SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM);
532*00b67f09SDavid van Moolenbroek if (n >= (int)sizeof(str) || n < 0)
533*00b67f09SDavid van Moolenbroek return (ISC_R_NOSPACE);
534*00b67f09SDavid van Moolenbroek return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str));
535*00b67f09SDavid van Moolenbroek }
536*00b67f09SDavid van Moolenbroek
537*00b67f09SDavid van Moolenbroek /*
538*00b67f09SDavid van Moolenbroek * DB routines
539*00b67f09SDavid van Moolenbroek */
540*00b67f09SDavid van Moolenbroek
541*00b67f09SDavid van Moolenbroek static void
attach(dns_db_t * source,dns_db_t ** targetp)542*00b67f09SDavid van Moolenbroek attach(dns_db_t *source, dns_db_t **targetp) {
543*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *) source;
544*00b67f09SDavid van Moolenbroek
545*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
546*00b67f09SDavid van Moolenbroek
547*00b67f09SDavid van Moolenbroek LOCK(&sdb->lock);
548*00b67f09SDavid van Moolenbroek REQUIRE(sdb->references > 0);
549*00b67f09SDavid van Moolenbroek sdb->references++;
550*00b67f09SDavid van Moolenbroek UNLOCK(&sdb->lock);
551*00b67f09SDavid van Moolenbroek
552*00b67f09SDavid van Moolenbroek *targetp = source;
553*00b67f09SDavid van Moolenbroek }
554*00b67f09SDavid van Moolenbroek
555*00b67f09SDavid van Moolenbroek static void
destroy(dns_sdb_t * sdb)556*00b67f09SDavid van Moolenbroek destroy(dns_sdb_t *sdb) {
557*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
558*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp = sdb->implementation;
559*00b67f09SDavid van Moolenbroek
560*00b67f09SDavid van Moolenbroek mctx = sdb->common.mctx;
561*00b67f09SDavid van Moolenbroek
562*00b67f09SDavid van Moolenbroek if (imp->methods->destroy != NULL) {
563*00b67f09SDavid van Moolenbroek MAYBE_LOCK(sdb);
564*00b67f09SDavid van Moolenbroek imp->methods->destroy(sdb->zone, imp->driverdata,
565*00b67f09SDavid van Moolenbroek &sdb->dbdata);
566*00b67f09SDavid van Moolenbroek MAYBE_UNLOCK(sdb);
567*00b67f09SDavid van Moolenbroek }
568*00b67f09SDavid van Moolenbroek
569*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, sdb->zone);
570*00b67f09SDavid van Moolenbroek DESTROYLOCK(&sdb->lock);
571*00b67f09SDavid van Moolenbroek
572*00b67f09SDavid van Moolenbroek sdb->common.magic = 0;
573*00b67f09SDavid van Moolenbroek sdb->common.impmagic = 0;
574*00b67f09SDavid van Moolenbroek
575*00b67f09SDavid van Moolenbroek dns_name_free(&sdb->common.origin, mctx);
576*00b67f09SDavid van Moolenbroek
577*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
578*00b67f09SDavid van Moolenbroek isc_mem_detach(&mctx);
579*00b67f09SDavid van Moolenbroek }
580*00b67f09SDavid van Moolenbroek
581*00b67f09SDavid van Moolenbroek static void
detach(dns_db_t ** dbp)582*00b67f09SDavid van Moolenbroek detach(dns_db_t **dbp) {
583*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)(*dbp);
584*00b67f09SDavid van Moolenbroek isc_boolean_t need_destroy = ISC_FALSE;
585*00b67f09SDavid van Moolenbroek
586*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
587*00b67f09SDavid van Moolenbroek LOCK(&sdb->lock);
588*00b67f09SDavid van Moolenbroek REQUIRE(sdb->references > 0);
589*00b67f09SDavid van Moolenbroek sdb->references--;
590*00b67f09SDavid van Moolenbroek if (sdb->references == 0)
591*00b67f09SDavid van Moolenbroek need_destroy = ISC_TRUE;
592*00b67f09SDavid van Moolenbroek UNLOCK(&sdb->lock);
593*00b67f09SDavid van Moolenbroek
594*00b67f09SDavid van Moolenbroek if (need_destroy)
595*00b67f09SDavid van Moolenbroek destroy(sdb);
596*00b67f09SDavid van Moolenbroek
597*00b67f09SDavid van Moolenbroek *dbp = NULL;
598*00b67f09SDavid van Moolenbroek }
599*00b67f09SDavid van Moolenbroek
600*00b67f09SDavid van Moolenbroek static isc_result_t
beginload(dns_db_t * db,dns_rdatacallbacks_t * callbacks)601*00b67f09SDavid van Moolenbroek beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
602*00b67f09SDavid van Moolenbroek UNUSED(db);
603*00b67f09SDavid van Moolenbroek UNUSED(callbacks);
604*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
605*00b67f09SDavid van Moolenbroek }
606*00b67f09SDavid van Moolenbroek
607*00b67f09SDavid van Moolenbroek static isc_result_t
endload(dns_db_t * db,dns_rdatacallbacks_t * callbacks)608*00b67f09SDavid van Moolenbroek endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
609*00b67f09SDavid van Moolenbroek UNUSED(db);
610*00b67f09SDavid van Moolenbroek UNUSED(callbacks);
611*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
612*00b67f09SDavid van Moolenbroek }
613*00b67f09SDavid van Moolenbroek
614*00b67f09SDavid van Moolenbroek static isc_result_t
dump(dns_db_t * db,dns_dbversion_t * version,const char * filename,dns_masterformat_t masterformat)615*00b67f09SDavid van Moolenbroek dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
616*00b67f09SDavid van Moolenbroek dns_masterformat_t masterformat) {
617*00b67f09SDavid van Moolenbroek UNUSED(db);
618*00b67f09SDavid van Moolenbroek UNUSED(version);
619*00b67f09SDavid van Moolenbroek UNUSED(filename);
620*00b67f09SDavid van Moolenbroek UNUSED(masterformat);
621*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
622*00b67f09SDavid van Moolenbroek }
623*00b67f09SDavid van Moolenbroek
624*00b67f09SDavid van Moolenbroek static void
currentversion(dns_db_t * db,dns_dbversion_t ** versionp)625*00b67f09SDavid van Moolenbroek currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
626*00b67f09SDavid van Moolenbroek REQUIRE(versionp != NULL && *versionp == NULL);
627*00b67f09SDavid van Moolenbroek
628*00b67f09SDavid van Moolenbroek UNUSED(db);
629*00b67f09SDavid van Moolenbroek
630*00b67f09SDavid van Moolenbroek *versionp = (void *) &dummy;
631*00b67f09SDavid van Moolenbroek return;
632*00b67f09SDavid van Moolenbroek }
633*00b67f09SDavid van Moolenbroek
634*00b67f09SDavid van Moolenbroek static isc_result_t
newversion(dns_db_t * db,dns_dbversion_t ** versionp)635*00b67f09SDavid van Moolenbroek newversion(dns_db_t *db, dns_dbversion_t **versionp) {
636*00b67f09SDavid van Moolenbroek UNUSED(db);
637*00b67f09SDavid van Moolenbroek UNUSED(versionp);
638*00b67f09SDavid van Moolenbroek
639*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
640*00b67f09SDavid van Moolenbroek }
641*00b67f09SDavid van Moolenbroek
642*00b67f09SDavid van Moolenbroek static void
attachversion(dns_db_t * db,dns_dbversion_t * source,dns_dbversion_t ** targetp)643*00b67f09SDavid van Moolenbroek attachversion(dns_db_t *db, dns_dbversion_t *source,
644*00b67f09SDavid van Moolenbroek dns_dbversion_t **targetp)
645*00b67f09SDavid van Moolenbroek {
646*00b67f09SDavid van Moolenbroek REQUIRE(source != NULL && source == (void *) &dummy);
647*00b67f09SDavid van Moolenbroek REQUIRE(targetp != NULL && *targetp == NULL);
648*00b67f09SDavid van Moolenbroek
649*00b67f09SDavid van Moolenbroek UNUSED(db);
650*00b67f09SDavid van Moolenbroek *targetp = source;
651*00b67f09SDavid van Moolenbroek return;
652*00b67f09SDavid van Moolenbroek }
653*00b67f09SDavid van Moolenbroek
654*00b67f09SDavid van Moolenbroek static void
closeversion(dns_db_t * db,dns_dbversion_t ** versionp,isc_boolean_t commit)655*00b67f09SDavid van Moolenbroek closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
656*00b67f09SDavid van Moolenbroek REQUIRE(versionp != NULL && *versionp == (void *) &dummy);
657*00b67f09SDavid van Moolenbroek REQUIRE(commit == ISC_FALSE);
658*00b67f09SDavid van Moolenbroek
659*00b67f09SDavid van Moolenbroek UNUSED(db);
660*00b67f09SDavid van Moolenbroek UNUSED(commit);
661*00b67f09SDavid van Moolenbroek
662*00b67f09SDavid van Moolenbroek *versionp = NULL;
663*00b67f09SDavid van Moolenbroek }
664*00b67f09SDavid van Moolenbroek
665*00b67f09SDavid van Moolenbroek static isc_result_t
createnode(dns_sdb_t * sdb,dns_sdbnode_t ** nodep)666*00b67f09SDavid van Moolenbroek createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) {
667*00b67f09SDavid van Moolenbroek dns_sdbnode_t *node;
668*00b67f09SDavid van Moolenbroek isc_result_t result;
669*00b67f09SDavid van Moolenbroek
670*00b67f09SDavid van Moolenbroek node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t));
671*00b67f09SDavid van Moolenbroek if (node == NULL)
672*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
673*00b67f09SDavid van Moolenbroek
674*00b67f09SDavid van Moolenbroek node->sdb = NULL;
675*00b67f09SDavid van Moolenbroek attach((dns_db_t *)sdb, (dns_db_t **)(void *)&node->sdb);
676*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(node->lists);
677*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(node->buffers);
678*00b67f09SDavid van Moolenbroek ISC_LINK_INIT(node, link);
679*00b67f09SDavid van Moolenbroek node->name = NULL;
680*00b67f09SDavid van Moolenbroek result = isc_mutex_init(&node->lock);
681*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
682*00b67f09SDavid van Moolenbroek isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t));
683*00b67f09SDavid van Moolenbroek return (result);
684*00b67f09SDavid van Moolenbroek }
685*00b67f09SDavid van Moolenbroek dns_rdatacallbacks_init(&node->callbacks);
686*00b67f09SDavid van Moolenbroek node->references = 1;
687*00b67f09SDavid van Moolenbroek node->magic = SDBLOOKUP_MAGIC;
688*00b67f09SDavid van Moolenbroek
689*00b67f09SDavid van Moolenbroek *nodep = node;
690*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
691*00b67f09SDavid van Moolenbroek }
692*00b67f09SDavid van Moolenbroek
693*00b67f09SDavid van Moolenbroek static void
destroynode(dns_sdbnode_t * node)694*00b67f09SDavid van Moolenbroek destroynode(dns_sdbnode_t *node) {
695*00b67f09SDavid van Moolenbroek dns_rdatalist_t *list;
696*00b67f09SDavid van Moolenbroek dns_rdata_t *rdata;
697*00b67f09SDavid van Moolenbroek isc_buffer_t *b;
698*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb;
699*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
700*00b67f09SDavid van Moolenbroek
701*00b67f09SDavid van Moolenbroek sdb = node->sdb;
702*00b67f09SDavid van Moolenbroek mctx = sdb->common.mctx;
703*00b67f09SDavid van Moolenbroek
704*00b67f09SDavid van Moolenbroek while (!ISC_LIST_EMPTY(node->lists)) {
705*00b67f09SDavid van Moolenbroek list = ISC_LIST_HEAD(node->lists);
706*00b67f09SDavid van Moolenbroek while (!ISC_LIST_EMPTY(list->rdata)) {
707*00b67f09SDavid van Moolenbroek rdata = ISC_LIST_HEAD(list->rdata);
708*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(list->rdata, rdata, link);
709*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
710*00b67f09SDavid van Moolenbroek }
711*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(node->lists, list, link);
712*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
713*00b67f09SDavid van Moolenbroek }
714*00b67f09SDavid van Moolenbroek
715*00b67f09SDavid van Moolenbroek while (!ISC_LIST_EMPTY(node->buffers)) {
716*00b67f09SDavid van Moolenbroek b = ISC_LIST_HEAD(node->buffers);
717*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(node->buffers, b, link);
718*00b67f09SDavid van Moolenbroek isc_buffer_free(&b);
719*00b67f09SDavid van Moolenbroek }
720*00b67f09SDavid van Moolenbroek
721*00b67f09SDavid van Moolenbroek if (node->name != NULL) {
722*00b67f09SDavid van Moolenbroek dns_name_free(node->name, mctx);
723*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, node->name, sizeof(dns_name_t));
724*00b67f09SDavid van Moolenbroek }
725*00b67f09SDavid van Moolenbroek DESTROYLOCK(&node->lock);
726*00b67f09SDavid van Moolenbroek node->magic = 0;
727*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
728*00b67f09SDavid van Moolenbroek detach((dns_db_t **) (void *)&sdb);
729*00b67f09SDavid van Moolenbroek }
730*00b67f09SDavid van Moolenbroek
731*00b67f09SDavid van Moolenbroek static isc_result_t
findnodeext(dns_db_t * db,dns_name_t * name,isc_boolean_t create,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo,dns_dbnode_t ** nodep)732*00b67f09SDavid van Moolenbroek findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
733*00b67f09SDavid van Moolenbroek dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
734*00b67f09SDavid van Moolenbroek dns_dbnode_t **nodep)
735*00b67f09SDavid van Moolenbroek {
736*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)db;
737*00b67f09SDavid van Moolenbroek dns_sdbnode_t *node = NULL;
738*00b67f09SDavid van Moolenbroek isc_result_t result;
739*00b67f09SDavid van Moolenbroek isc_buffer_t b;
740*00b67f09SDavid van Moolenbroek char namestr[DNS_NAME_MAXTEXT + 1];
741*00b67f09SDavid van Moolenbroek isc_boolean_t isorigin;
742*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp;
743*00b67f09SDavid van Moolenbroek dns_name_t relname;
744*00b67f09SDavid van Moolenbroek unsigned int labels;
745*00b67f09SDavid van Moolenbroek
746*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
747*00b67f09SDavid van Moolenbroek REQUIRE(create == ISC_FALSE);
748*00b67f09SDavid van Moolenbroek REQUIRE(nodep != NULL && *nodep == NULL);
749*00b67f09SDavid van Moolenbroek
750*00b67f09SDavid van Moolenbroek UNUSED(name);
751*00b67f09SDavid van Moolenbroek UNUSED(create);
752*00b67f09SDavid van Moolenbroek
753*00b67f09SDavid van Moolenbroek imp = sdb->implementation;
754*00b67f09SDavid van Moolenbroek
755*00b67f09SDavid van Moolenbroek isorigin = dns_name_equal(name, &sdb->common.origin);
756*00b67f09SDavid van Moolenbroek
757*00b67f09SDavid van Moolenbroek if (imp->methods->lookup2 != NULL) {
758*00b67f09SDavid van Moolenbroek if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
759*00b67f09SDavid van Moolenbroek labels = dns_name_countlabels(name) -
760*00b67f09SDavid van Moolenbroek dns_name_countlabels(&db->origin);
761*00b67f09SDavid van Moolenbroek dns_name_init(&relname, NULL);
762*00b67f09SDavid van Moolenbroek dns_name_getlabelsequence(name, 0, labels, &relname);
763*00b67f09SDavid van Moolenbroek name = &relname;
764*00b67f09SDavid van Moolenbroek }
765*00b67f09SDavid van Moolenbroek } else {
766*00b67f09SDavid van Moolenbroek isc_buffer_init(&b, namestr, sizeof(namestr));
767*00b67f09SDavid van Moolenbroek if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
768*00b67f09SDavid van Moolenbroek
769*00b67f09SDavid van Moolenbroek labels = dns_name_countlabels(name) -
770*00b67f09SDavid van Moolenbroek dns_name_countlabels(&db->origin);
771*00b67f09SDavid van Moolenbroek dns_name_init(&relname, NULL);
772*00b67f09SDavid van Moolenbroek dns_name_getlabelsequence(name, 0, labels, &relname);
773*00b67f09SDavid van Moolenbroek result = dns_name_totext(&relname, ISC_TRUE, &b);
774*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
775*00b67f09SDavid van Moolenbroek return (result);
776*00b67f09SDavid van Moolenbroek } else {
777*00b67f09SDavid van Moolenbroek result = dns_name_totext(name, ISC_TRUE, &b);
778*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
779*00b67f09SDavid van Moolenbroek return (result);
780*00b67f09SDavid van Moolenbroek }
781*00b67f09SDavid van Moolenbroek isc_buffer_putuint8(&b, 0);
782*00b67f09SDavid van Moolenbroek }
783*00b67f09SDavid van Moolenbroek
784*00b67f09SDavid van Moolenbroek result = createnode(sdb, &node);
785*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
786*00b67f09SDavid van Moolenbroek return (result);
787*00b67f09SDavid van Moolenbroek
788*00b67f09SDavid van Moolenbroek MAYBE_LOCK(sdb);
789*00b67f09SDavid van Moolenbroek if (imp->methods->lookup2 != NULL)
790*00b67f09SDavid van Moolenbroek result = imp->methods->lookup2(&sdb->common.origin, name,
791*00b67f09SDavid van Moolenbroek sdb->dbdata, node, methods,
792*00b67f09SDavid van Moolenbroek clientinfo);
793*00b67f09SDavid van Moolenbroek else
794*00b67f09SDavid van Moolenbroek result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata,
795*00b67f09SDavid van Moolenbroek node, methods, clientinfo);
796*00b67f09SDavid van Moolenbroek MAYBE_UNLOCK(sdb);
797*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS &&
798*00b67f09SDavid van Moolenbroek !(result == ISC_R_NOTFOUND &&
799*00b67f09SDavid van Moolenbroek isorigin && imp->methods->authority != NULL))
800*00b67f09SDavid van Moolenbroek {
801*00b67f09SDavid van Moolenbroek destroynode(node);
802*00b67f09SDavid van Moolenbroek return (result);
803*00b67f09SDavid van Moolenbroek }
804*00b67f09SDavid van Moolenbroek
805*00b67f09SDavid van Moolenbroek if (isorigin && imp->methods->authority != NULL) {
806*00b67f09SDavid van Moolenbroek MAYBE_LOCK(sdb);
807*00b67f09SDavid van Moolenbroek result = imp->methods->authority(sdb->zone, sdb->dbdata, node);
808*00b67f09SDavid van Moolenbroek MAYBE_UNLOCK(sdb);
809*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
810*00b67f09SDavid van Moolenbroek destroynode(node);
811*00b67f09SDavid van Moolenbroek return (result);
812*00b67f09SDavid van Moolenbroek }
813*00b67f09SDavid van Moolenbroek }
814*00b67f09SDavid van Moolenbroek
815*00b67f09SDavid van Moolenbroek *nodep = node;
816*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
817*00b67f09SDavid van Moolenbroek }
818*00b67f09SDavid van Moolenbroek
819*00b67f09SDavid van Moolenbroek static isc_result_t
findext(dns_db_t * db,dns_name_t * name,dns_dbversion_t * version,dns_rdatatype_t type,unsigned int options,isc_stdtime_t now,dns_dbnode_t ** nodep,dns_name_t * foundname,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)820*00b67f09SDavid van Moolenbroek findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
821*00b67f09SDavid van Moolenbroek dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
822*00b67f09SDavid van Moolenbroek dns_dbnode_t **nodep, dns_name_t *foundname,
823*00b67f09SDavid van Moolenbroek dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
824*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
825*00b67f09SDavid van Moolenbroek {
826*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)db;
827*00b67f09SDavid van Moolenbroek dns_dbnode_t *node = NULL;
828*00b67f09SDavid van Moolenbroek dns_fixedname_t fname;
829*00b67f09SDavid van Moolenbroek dns_rdataset_t xrdataset;
830*00b67f09SDavid van Moolenbroek dns_name_t *xname;
831*00b67f09SDavid van Moolenbroek unsigned int nlabels, olabels;
832*00b67f09SDavid van Moolenbroek isc_result_t result;
833*00b67f09SDavid van Moolenbroek unsigned int i;
834*00b67f09SDavid van Moolenbroek unsigned int flags;
835*00b67f09SDavid van Moolenbroek
836*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
837*00b67f09SDavid van Moolenbroek REQUIRE(nodep == NULL || *nodep == NULL);
838*00b67f09SDavid van Moolenbroek REQUIRE(version == NULL || version == (void *) &dummy);
839*00b67f09SDavid van Moolenbroek
840*00b67f09SDavid van Moolenbroek UNUSED(options);
841*00b67f09SDavid van Moolenbroek
842*00b67f09SDavid van Moolenbroek if (!dns_name_issubdomain(name, &db->origin))
843*00b67f09SDavid van Moolenbroek return (DNS_R_NXDOMAIN);
844*00b67f09SDavid van Moolenbroek
845*00b67f09SDavid van Moolenbroek olabels = dns_name_countlabels(&db->origin);
846*00b67f09SDavid van Moolenbroek nlabels = dns_name_countlabels(name);
847*00b67f09SDavid van Moolenbroek
848*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fname);
849*00b67f09SDavid van Moolenbroek xname = dns_fixedname_name(&fname);
850*00b67f09SDavid van Moolenbroek
851*00b67f09SDavid van Moolenbroek if (rdataset == NULL) {
852*00b67f09SDavid van Moolenbroek dns_rdataset_init(&xrdataset);
853*00b67f09SDavid van Moolenbroek rdataset = &xrdataset;
854*00b67f09SDavid van Moolenbroek }
855*00b67f09SDavid van Moolenbroek
856*00b67f09SDavid van Moolenbroek result = DNS_R_NXDOMAIN;
857*00b67f09SDavid van Moolenbroek flags = sdb->implementation->flags;
858*00b67f09SDavid van Moolenbroek i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels;
859*00b67f09SDavid van Moolenbroek for (; i <= nlabels; i++) {
860*00b67f09SDavid van Moolenbroek /*
861*00b67f09SDavid van Moolenbroek * Look up the next label.
862*00b67f09SDavid van Moolenbroek */
863*00b67f09SDavid van Moolenbroek dns_name_getlabelsequence(name, nlabels - i, i, xname);
864*00b67f09SDavid van Moolenbroek result = findnodeext(db, xname, ISC_FALSE, methods,
865*00b67f09SDavid van Moolenbroek clientinfo, &node);
866*00b67f09SDavid van Moolenbroek if (result == ISC_R_NOTFOUND) {
867*00b67f09SDavid van Moolenbroek /*
868*00b67f09SDavid van Moolenbroek * No data at zone apex?
869*00b67f09SDavid van Moolenbroek */
870*00b67f09SDavid van Moolenbroek if (i == olabels)
871*00b67f09SDavid van Moolenbroek return (DNS_R_BADDB);
872*00b67f09SDavid van Moolenbroek result = DNS_R_NXDOMAIN;
873*00b67f09SDavid van Moolenbroek continue;
874*00b67f09SDavid van Moolenbroek }
875*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
876*00b67f09SDavid van Moolenbroek return (result);
877*00b67f09SDavid van Moolenbroek
878*00b67f09SDavid van Moolenbroek /*
879*00b67f09SDavid van Moolenbroek * DNS64 zone's don't have DNAME or NS records.
880*00b67f09SDavid van Moolenbroek */
881*00b67f09SDavid van Moolenbroek if ((flags & DNS_SDBFLAG_DNS64) != 0)
882*00b67f09SDavid van Moolenbroek goto skip;
883*00b67f09SDavid van Moolenbroek
884*00b67f09SDavid van Moolenbroek /*
885*00b67f09SDavid van Moolenbroek * DNS64 zone's don't have DNAME or NS records.
886*00b67f09SDavid van Moolenbroek */
887*00b67f09SDavid van Moolenbroek if ((flags & DNS_SDBFLAG_DNS64) != 0)
888*00b67f09SDavid van Moolenbroek goto skip;
889*00b67f09SDavid van Moolenbroek
890*00b67f09SDavid van Moolenbroek /*
891*00b67f09SDavid van Moolenbroek * Look for a DNAME at the current label, unless this is
892*00b67f09SDavid van Moolenbroek * the qname.
893*00b67f09SDavid van Moolenbroek */
894*00b67f09SDavid van Moolenbroek if (i < nlabels) {
895*00b67f09SDavid van Moolenbroek result = findrdataset(db, node, version,
896*00b67f09SDavid van Moolenbroek dns_rdatatype_dname,
897*00b67f09SDavid van Moolenbroek 0, now, rdataset, sigrdataset);
898*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
899*00b67f09SDavid van Moolenbroek result = DNS_R_DNAME;
900*00b67f09SDavid van Moolenbroek break;
901*00b67f09SDavid van Moolenbroek }
902*00b67f09SDavid van Moolenbroek }
903*00b67f09SDavid van Moolenbroek
904*00b67f09SDavid van Moolenbroek /*
905*00b67f09SDavid van Moolenbroek * Look for an NS at the current label, unless this is the
906*00b67f09SDavid van Moolenbroek * origin or glue is ok.
907*00b67f09SDavid van Moolenbroek */
908*00b67f09SDavid van Moolenbroek if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
909*00b67f09SDavid van Moolenbroek result = findrdataset(db, node, version,
910*00b67f09SDavid van Moolenbroek dns_rdatatype_ns,
911*00b67f09SDavid van Moolenbroek 0, now, rdataset, sigrdataset);
912*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
913*00b67f09SDavid van Moolenbroek if (i == nlabels && type == dns_rdatatype_any)
914*00b67f09SDavid van Moolenbroek {
915*00b67f09SDavid van Moolenbroek result = DNS_R_ZONECUT;
916*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
917*00b67f09SDavid van Moolenbroek if (sigrdataset != NULL &&
918*00b67f09SDavid van Moolenbroek dns_rdataset_isassociated
919*00b67f09SDavid van Moolenbroek (sigrdataset)) {
920*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate
921*00b67f09SDavid van Moolenbroek (sigrdataset);
922*00b67f09SDavid van Moolenbroek }
923*00b67f09SDavid van Moolenbroek } else
924*00b67f09SDavid van Moolenbroek result = DNS_R_DELEGATION;
925*00b67f09SDavid van Moolenbroek break;
926*00b67f09SDavid van Moolenbroek }
927*00b67f09SDavid van Moolenbroek }
928*00b67f09SDavid van Moolenbroek
929*00b67f09SDavid van Moolenbroek /*
930*00b67f09SDavid van Moolenbroek * If the current name is not the qname, add another label
931*00b67f09SDavid van Moolenbroek * and try again.
932*00b67f09SDavid van Moolenbroek */
933*00b67f09SDavid van Moolenbroek if (i < nlabels) {
934*00b67f09SDavid van Moolenbroek destroynode(node);
935*00b67f09SDavid van Moolenbroek node = NULL;
936*00b67f09SDavid van Moolenbroek continue;
937*00b67f09SDavid van Moolenbroek }
938*00b67f09SDavid van Moolenbroek
939*00b67f09SDavid van Moolenbroek skip:
940*00b67f09SDavid van Moolenbroek /*
941*00b67f09SDavid van Moolenbroek * If we're looking for ANY, we're done.
942*00b67f09SDavid van Moolenbroek */
943*00b67f09SDavid van Moolenbroek if (type == dns_rdatatype_any) {
944*00b67f09SDavid van Moolenbroek result = ISC_R_SUCCESS;
945*00b67f09SDavid van Moolenbroek break;
946*00b67f09SDavid van Moolenbroek }
947*00b67f09SDavid van Moolenbroek
948*00b67f09SDavid van Moolenbroek /*
949*00b67f09SDavid van Moolenbroek * Look for the qtype.
950*00b67f09SDavid van Moolenbroek */
951*00b67f09SDavid van Moolenbroek result = findrdataset(db, node, version, type,
952*00b67f09SDavid van Moolenbroek 0, now, rdataset, sigrdataset);
953*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
954*00b67f09SDavid van Moolenbroek break;
955*00b67f09SDavid van Moolenbroek
956*00b67f09SDavid van Moolenbroek /*
957*00b67f09SDavid van Moolenbroek * Look for a CNAME
958*00b67f09SDavid van Moolenbroek */
959*00b67f09SDavid van Moolenbroek if (type != dns_rdatatype_cname) {
960*00b67f09SDavid van Moolenbroek result = findrdataset(db, node, version,
961*00b67f09SDavid van Moolenbroek dns_rdatatype_cname,
962*00b67f09SDavid van Moolenbroek 0, now, rdataset, sigrdataset);
963*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
964*00b67f09SDavid van Moolenbroek result = DNS_R_CNAME;
965*00b67f09SDavid van Moolenbroek break;
966*00b67f09SDavid van Moolenbroek }
967*00b67f09SDavid van Moolenbroek }
968*00b67f09SDavid van Moolenbroek
969*00b67f09SDavid van Moolenbroek result = DNS_R_NXRRSET;
970*00b67f09SDavid van Moolenbroek break;
971*00b67f09SDavid van Moolenbroek }
972*00b67f09SDavid van Moolenbroek
973*00b67f09SDavid van Moolenbroek if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
974*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
975*00b67f09SDavid van Moolenbroek
976*00b67f09SDavid van Moolenbroek if (foundname != NULL) {
977*00b67f09SDavid van Moolenbroek isc_result_t xresult;
978*00b67f09SDavid van Moolenbroek
979*00b67f09SDavid van Moolenbroek xresult = dns_name_copy(xname, foundname, NULL);
980*00b67f09SDavid van Moolenbroek if (xresult != ISC_R_SUCCESS) {
981*00b67f09SDavid van Moolenbroek if (node != NULL)
982*00b67f09SDavid van Moolenbroek destroynode(node);
983*00b67f09SDavid van Moolenbroek if (dns_rdataset_isassociated(rdataset))
984*00b67f09SDavid van Moolenbroek dns_rdataset_disassociate(rdataset);
985*00b67f09SDavid van Moolenbroek return (DNS_R_BADDB);
986*00b67f09SDavid van Moolenbroek }
987*00b67f09SDavid van Moolenbroek }
988*00b67f09SDavid van Moolenbroek
989*00b67f09SDavid van Moolenbroek if (nodep != NULL)
990*00b67f09SDavid van Moolenbroek *nodep = node;
991*00b67f09SDavid van Moolenbroek else if (node != NULL)
992*00b67f09SDavid van Moolenbroek detachnode(db, &node);
993*00b67f09SDavid van Moolenbroek
994*00b67f09SDavid van Moolenbroek return (result);
995*00b67f09SDavid van Moolenbroek }
996*00b67f09SDavid van Moolenbroek
997*00b67f09SDavid van Moolenbroek static isc_result_t
findzonecut(dns_db_t * db,dns_name_t * name,unsigned int options,isc_stdtime_t now,dns_dbnode_t ** nodep,dns_name_t * foundname,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)998*00b67f09SDavid van Moolenbroek findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
999*00b67f09SDavid van Moolenbroek isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
1000*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1001*00b67f09SDavid van Moolenbroek {
1002*00b67f09SDavid van Moolenbroek UNUSED(db);
1003*00b67f09SDavid van Moolenbroek UNUSED(name);
1004*00b67f09SDavid van Moolenbroek UNUSED(options);
1005*00b67f09SDavid van Moolenbroek UNUSED(now);
1006*00b67f09SDavid van Moolenbroek UNUSED(nodep);
1007*00b67f09SDavid van Moolenbroek UNUSED(foundname);
1008*00b67f09SDavid van Moolenbroek UNUSED(rdataset);
1009*00b67f09SDavid van Moolenbroek UNUSED(sigrdataset);
1010*00b67f09SDavid van Moolenbroek
1011*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1012*00b67f09SDavid van Moolenbroek }
1013*00b67f09SDavid van Moolenbroek
1014*00b67f09SDavid van Moolenbroek static void
attachnode(dns_db_t * db,dns_dbnode_t * source,dns_dbnode_t ** targetp)1015*00b67f09SDavid van Moolenbroek attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
1016*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)db;
1017*00b67f09SDavid van Moolenbroek dns_sdbnode_t *node = (dns_sdbnode_t *)source;
1018*00b67f09SDavid van Moolenbroek
1019*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
1020*00b67f09SDavid van Moolenbroek
1021*00b67f09SDavid van Moolenbroek UNUSED(sdb);
1022*00b67f09SDavid van Moolenbroek
1023*00b67f09SDavid van Moolenbroek LOCK(&node->lock);
1024*00b67f09SDavid van Moolenbroek INSIST(node->references > 0);
1025*00b67f09SDavid van Moolenbroek node->references++;
1026*00b67f09SDavid van Moolenbroek INSIST(node->references != 0); /* Catch overflow. */
1027*00b67f09SDavid van Moolenbroek UNLOCK(&node->lock);
1028*00b67f09SDavid van Moolenbroek
1029*00b67f09SDavid van Moolenbroek *targetp = source;
1030*00b67f09SDavid van Moolenbroek }
1031*00b67f09SDavid van Moolenbroek
1032*00b67f09SDavid van Moolenbroek static void
detachnode(dns_db_t * db,dns_dbnode_t ** targetp)1033*00b67f09SDavid van Moolenbroek detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
1034*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)db;
1035*00b67f09SDavid van Moolenbroek dns_sdbnode_t *node;
1036*00b67f09SDavid van Moolenbroek isc_boolean_t need_destroy = ISC_FALSE;
1037*00b67f09SDavid van Moolenbroek
1038*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
1039*00b67f09SDavid van Moolenbroek REQUIRE(targetp != NULL && *targetp != NULL);
1040*00b67f09SDavid van Moolenbroek
1041*00b67f09SDavid van Moolenbroek UNUSED(sdb);
1042*00b67f09SDavid van Moolenbroek
1043*00b67f09SDavid van Moolenbroek node = (dns_sdbnode_t *)(*targetp);
1044*00b67f09SDavid van Moolenbroek
1045*00b67f09SDavid van Moolenbroek LOCK(&node->lock);
1046*00b67f09SDavid van Moolenbroek INSIST(node->references > 0);
1047*00b67f09SDavid van Moolenbroek node->references--;
1048*00b67f09SDavid van Moolenbroek if (node->references == 0)
1049*00b67f09SDavid van Moolenbroek need_destroy = ISC_TRUE;
1050*00b67f09SDavid van Moolenbroek UNLOCK(&node->lock);
1051*00b67f09SDavid van Moolenbroek
1052*00b67f09SDavid van Moolenbroek if (need_destroy)
1053*00b67f09SDavid van Moolenbroek destroynode(node);
1054*00b67f09SDavid van Moolenbroek
1055*00b67f09SDavid van Moolenbroek *targetp = NULL;
1056*00b67f09SDavid van Moolenbroek }
1057*00b67f09SDavid van Moolenbroek
1058*00b67f09SDavid van Moolenbroek static isc_result_t
expirenode(dns_db_t * db,dns_dbnode_t * node,isc_stdtime_t now)1059*00b67f09SDavid van Moolenbroek expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
1060*00b67f09SDavid van Moolenbroek UNUSED(db);
1061*00b67f09SDavid van Moolenbroek UNUSED(node);
1062*00b67f09SDavid van Moolenbroek UNUSED(now);
1063*00b67f09SDavid van Moolenbroek INSIST(0);
1064*00b67f09SDavid van Moolenbroek return (ISC_R_UNEXPECTED);
1065*00b67f09SDavid van Moolenbroek }
1066*00b67f09SDavid van Moolenbroek
1067*00b67f09SDavid van Moolenbroek static void
printnode(dns_db_t * db,dns_dbnode_t * node,FILE * out)1068*00b67f09SDavid van Moolenbroek printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
1069*00b67f09SDavid van Moolenbroek UNUSED(db);
1070*00b67f09SDavid van Moolenbroek UNUSED(node);
1071*00b67f09SDavid van Moolenbroek UNUSED(out);
1072*00b67f09SDavid van Moolenbroek return;
1073*00b67f09SDavid van Moolenbroek }
1074*00b67f09SDavid van Moolenbroek
1075*00b67f09SDavid van Moolenbroek static isc_result_t
createiterator(dns_db_t * db,unsigned int options,dns_dbiterator_t ** iteratorp)1076*00b67f09SDavid van Moolenbroek createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
1077*00b67f09SDavid van Moolenbroek {
1078*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)db;
1079*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter;
1080*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp = sdb->implementation;
1081*00b67f09SDavid van Moolenbroek isc_result_t result;
1082*00b67f09SDavid van Moolenbroek
1083*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDB(sdb));
1084*00b67f09SDavid van Moolenbroek
1085*00b67f09SDavid van Moolenbroek if (imp->methods->allnodes == NULL)
1086*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1087*00b67f09SDavid van Moolenbroek
1088*00b67f09SDavid van Moolenbroek if ((options & DNS_DB_NSEC3ONLY) != 0 ||
1089*00b67f09SDavid van Moolenbroek (options & DNS_DB_NONSEC3) != 0)
1090*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1091*00b67f09SDavid van Moolenbroek
1092*00b67f09SDavid van Moolenbroek sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t));
1093*00b67f09SDavid van Moolenbroek if (sdbiter == NULL)
1094*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1095*00b67f09SDavid van Moolenbroek
1096*00b67f09SDavid van Moolenbroek sdbiter->common.methods = &dbiterator_methods;
1097*00b67f09SDavid van Moolenbroek sdbiter->common.db = NULL;
1098*00b67f09SDavid van Moolenbroek dns_db_attach(db, &sdbiter->common.db);
1099*00b67f09SDavid van Moolenbroek sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
1100*00b67f09SDavid van Moolenbroek sdbiter->common.magic = DNS_DBITERATOR_MAGIC;
1101*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(sdbiter->nodelist);
1102*00b67f09SDavid van Moolenbroek sdbiter->current = NULL;
1103*00b67f09SDavid van Moolenbroek sdbiter->origin = NULL;
1104*00b67f09SDavid van Moolenbroek
1105*00b67f09SDavid van Moolenbroek MAYBE_LOCK(sdb);
1106*00b67f09SDavid van Moolenbroek result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter);
1107*00b67f09SDavid van Moolenbroek MAYBE_UNLOCK(sdb);
1108*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
1109*00b67f09SDavid van Moolenbroek dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter);
1110*00b67f09SDavid van Moolenbroek return (result);
1111*00b67f09SDavid van Moolenbroek }
1112*00b67f09SDavid van Moolenbroek
1113*00b67f09SDavid van Moolenbroek if (sdbiter->origin != NULL) {
1114*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link);
1115*00b67f09SDavid van Moolenbroek ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link);
1116*00b67f09SDavid van Moolenbroek }
1117*00b67f09SDavid van Moolenbroek
1118*00b67f09SDavid van Moolenbroek *iteratorp = (dns_dbiterator_t *)sdbiter;
1119*00b67f09SDavid van Moolenbroek
1120*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1121*00b67f09SDavid van Moolenbroek }
1122*00b67f09SDavid van Moolenbroek
1123*00b67f09SDavid van Moolenbroek static isc_result_t
findrdataset(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdatatype_t type,dns_rdatatype_t covers,isc_stdtime_t now,dns_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)1124*00b67f09SDavid van Moolenbroek findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1125*00b67f09SDavid van Moolenbroek dns_rdatatype_t type, dns_rdatatype_t covers,
1126*00b67f09SDavid van Moolenbroek isc_stdtime_t now, dns_rdataset_t *rdataset,
1127*00b67f09SDavid van Moolenbroek dns_rdataset_t *sigrdataset)
1128*00b67f09SDavid van Moolenbroek {
1129*00b67f09SDavid van Moolenbroek dns_rdatalist_t *list;
1130*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node;
1131*00b67f09SDavid van Moolenbroek
1132*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SDBNODE(node));
1133*00b67f09SDavid van Moolenbroek
1134*00b67f09SDavid van Moolenbroek UNUSED(db);
1135*00b67f09SDavid van Moolenbroek UNUSED(version);
1136*00b67f09SDavid van Moolenbroek UNUSED(covers);
1137*00b67f09SDavid van Moolenbroek UNUSED(now);
1138*00b67f09SDavid van Moolenbroek UNUSED(sigrdataset);
1139*00b67f09SDavid van Moolenbroek
1140*00b67f09SDavid van Moolenbroek if (type == dns_rdatatype_rrsig)
1141*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1142*00b67f09SDavid van Moolenbroek
1143*00b67f09SDavid van Moolenbroek list = ISC_LIST_HEAD(sdbnode->lists);
1144*00b67f09SDavid van Moolenbroek while (list != NULL) {
1145*00b67f09SDavid van Moolenbroek if (list->type == type)
1146*00b67f09SDavid van Moolenbroek break;
1147*00b67f09SDavid van Moolenbroek list = ISC_LIST_NEXT(list, link);
1148*00b67f09SDavid van Moolenbroek }
1149*00b67f09SDavid van Moolenbroek if (list == NULL)
1150*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1151*00b67f09SDavid van Moolenbroek
1152*00b67f09SDavid van Moolenbroek list_tordataset(list, db, node, rdataset);
1153*00b67f09SDavid van Moolenbroek
1154*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1155*00b67f09SDavid van Moolenbroek }
1156*00b67f09SDavid van Moolenbroek
1157*00b67f09SDavid van Moolenbroek static isc_result_t
allrdatasets(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,isc_stdtime_t now,dns_rdatasetiter_t ** iteratorp)1158*00b67f09SDavid van Moolenbroek allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1159*00b67f09SDavid van Moolenbroek isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
1160*00b67f09SDavid van Moolenbroek {
1161*00b67f09SDavid van Moolenbroek sdb_rdatasetiter_t *iterator;
1162*00b67f09SDavid van Moolenbroek
1163*00b67f09SDavid van Moolenbroek REQUIRE(version == NULL || version == &dummy);
1164*00b67f09SDavid van Moolenbroek
1165*00b67f09SDavid van Moolenbroek UNUSED(version);
1166*00b67f09SDavid van Moolenbroek UNUSED(now);
1167*00b67f09SDavid van Moolenbroek
1168*00b67f09SDavid van Moolenbroek iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t));
1169*00b67f09SDavid van Moolenbroek if (iterator == NULL)
1170*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1171*00b67f09SDavid van Moolenbroek
1172*00b67f09SDavid van Moolenbroek iterator->common.magic = DNS_RDATASETITER_MAGIC;
1173*00b67f09SDavid van Moolenbroek iterator->common.methods = &rdatasetiter_methods;
1174*00b67f09SDavid van Moolenbroek iterator->common.db = db;
1175*00b67f09SDavid van Moolenbroek iterator->common.node = NULL;
1176*00b67f09SDavid van Moolenbroek attachnode(db, node, &iterator->common.node);
1177*00b67f09SDavid van Moolenbroek iterator->common.version = version;
1178*00b67f09SDavid van Moolenbroek iterator->common.now = now;
1179*00b67f09SDavid van Moolenbroek
1180*00b67f09SDavid van Moolenbroek *iteratorp = (dns_rdatasetiter_t *)iterator;
1181*00b67f09SDavid van Moolenbroek
1182*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1183*00b67f09SDavid van Moolenbroek }
1184*00b67f09SDavid van Moolenbroek
1185*00b67f09SDavid van Moolenbroek static isc_result_t
addrdataset(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,isc_stdtime_t now,dns_rdataset_t * rdataset,unsigned int options,dns_rdataset_t * addedrdataset)1186*00b67f09SDavid van Moolenbroek addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1187*00b67f09SDavid van Moolenbroek isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
1188*00b67f09SDavid van Moolenbroek dns_rdataset_t *addedrdataset)
1189*00b67f09SDavid van Moolenbroek {
1190*00b67f09SDavid van Moolenbroek UNUSED(db);
1191*00b67f09SDavid van Moolenbroek UNUSED(node);
1192*00b67f09SDavid van Moolenbroek UNUSED(version);
1193*00b67f09SDavid van Moolenbroek UNUSED(now);
1194*00b67f09SDavid van Moolenbroek UNUSED(rdataset);
1195*00b67f09SDavid van Moolenbroek UNUSED(options);
1196*00b67f09SDavid van Moolenbroek UNUSED(addedrdataset);
1197*00b67f09SDavid van Moolenbroek
1198*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1199*00b67f09SDavid van Moolenbroek }
1200*00b67f09SDavid van Moolenbroek
1201*00b67f09SDavid van Moolenbroek static isc_result_t
subtractrdataset(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdataset_t * rdataset,unsigned int options,dns_rdataset_t * newrdataset)1202*00b67f09SDavid van Moolenbroek subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1203*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset, unsigned int options,
1204*00b67f09SDavid van Moolenbroek dns_rdataset_t *newrdataset)
1205*00b67f09SDavid van Moolenbroek {
1206*00b67f09SDavid van Moolenbroek UNUSED(db);
1207*00b67f09SDavid van Moolenbroek UNUSED(node);
1208*00b67f09SDavid van Moolenbroek UNUSED(version);
1209*00b67f09SDavid van Moolenbroek UNUSED(rdataset);
1210*00b67f09SDavid van Moolenbroek UNUSED(options);
1211*00b67f09SDavid van Moolenbroek UNUSED(newrdataset);
1212*00b67f09SDavid van Moolenbroek
1213*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1214*00b67f09SDavid van Moolenbroek }
1215*00b67f09SDavid van Moolenbroek
1216*00b67f09SDavid van Moolenbroek static isc_result_t
deleterdataset(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdatatype_t type,dns_rdatatype_t covers)1217*00b67f09SDavid van Moolenbroek deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1218*00b67f09SDavid van Moolenbroek dns_rdatatype_t type, dns_rdatatype_t covers)
1219*00b67f09SDavid van Moolenbroek {
1220*00b67f09SDavid van Moolenbroek UNUSED(db);
1221*00b67f09SDavid van Moolenbroek UNUSED(node);
1222*00b67f09SDavid van Moolenbroek UNUSED(version);
1223*00b67f09SDavid van Moolenbroek UNUSED(type);
1224*00b67f09SDavid van Moolenbroek UNUSED(covers);
1225*00b67f09SDavid van Moolenbroek
1226*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1227*00b67f09SDavid van Moolenbroek }
1228*00b67f09SDavid van Moolenbroek
1229*00b67f09SDavid van Moolenbroek static isc_boolean_t
issecure(dns_db_t * db)1230*00b67f09SDavid van Moolenbroek issecure(dns_db_t *db) {
1231*00b67f09SDavid van Moolenbroek UNUSED(db);
1232*00b67f09SDavid van Moolenbroek
1233*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
1234*00b67f09SDavid van Moolenbroek }
1235*00b67f09SDavid van Moolenbroek
1236*00b67f09SDavid van Moolenbroek static unsigned int
nodecount(dns_db_t * db)1237*00b67f09SDavid van Moolenbroek nodecount(dns_db_t *db) {
1238*00b67f09SDavid van Moolenbroek UNUSED(db);
1239*00b67f09SDavid van Moolenbroek
1240*00b67f09SDavid van Moolenbroek return (0);
1241*00b67f09SDavid van Moolenbroek }
1242*00b67f09SDavid van Moolenbroek
1243*00b67f09SDavid van Moolenbroek static isc_boolean_t
ispersistent(dns_db_t * db)1244*00b67f09SDavid van Moolenbroek ispersistent(dns_db_t *db) {
1245*00b67f09SDavid van Moolenbroek UNUSED(db);
1246*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
1247*00b67f09SDavid van Moolenbroek }
1248*00b67f09SDavid van Moolenbroek
1249*00b67f09SDavid van Moolenbroek static void
overmem(dns_db_t * db,isc_boolean_t overmem)1250*00b67f09SDavid van Moolenbroek overmem(dns_db_t *db, isc_boolean_t overmem) {
1251*00b67f09SDavid van Moolenbroek UNUSED(db);
1252*00b67f09SDavid van Moolenbroek UNUSED(overmem);
1253*00b67f09SDavid van Moolenbroek }
1254*00b67f09SDavid van Moolenbroek
1255*00b67f09SDavid van Moolenbroek static void
settask(dns_db_t * db,isc_task_t * task)1256*00b67f09SDavid van Moolenbroek settask(dns_db_t *db, isc_task_t *task) {
1257*00b67f09SDavid van Moolenbroek UNUSED(db);
1258*00b67f09SDavid van Moolenbroek UNUSED(task);
1259*00b67f09SDavid van Moolenbroek }
1260*00b67f09SDavid van Moolenbroek
1261*00b67f09SDavid van Moolenbroek
1262*00b67f09SDavid van Moolenbroek static dns_dbmethods_t sdb_methods = {
1263*00b67f09SDavid van Moolenbroek attach,
1264*00b67f09SDavid van Moolenbroek detach,
1265*00b67f09SDavid van Moolenbroek beginload,
1266*00b67f09SDavid van Moolenbroek endload,
1267*00b67f09SDavid van Moolenbroek NULL,
1268*00b67f09SDavid van Moolenbroek dump,
1269*00b67f09SDavid van Moolenbroek currentversion,
1270*00b67f09SDavid van Moolenbroek newversion,
1271*00b67f09SDavid van Moolenbroek attachversion,
1272*00b67f09SDavid van Moolenbroek closeversion,
1273*00b67f09SDavid van Moolenbroek NULL,
1274*00b67f09SDavid van Moolenbroek NULL,
1275*00b67f09SDavid van Moolenbroek findzonecut,
1276*00b67f09SDavid van Moolenbroek attachnode,
1277*00b67f09SDavid van Moolenbroek detachnode,
1278*00b67f09SDavid van Moolenbroek expirenode,
1279*00b67f09SDavid van Moolenbroek printnode,
1280*00b67f09SDavid van Moolenbroek createiterator,
1281*00b67f09SDavid van Moolenbroek findrdataset,
1282*00b67f09SDavid van Moolenbroek allrdatasets,
1283*00b67f09SDavid van Moolenbroek addrdataset,
1284*00b67f09SDavid van Moolenbroek subtractrdataset,
1285*00b67f09SDavid van Moolenbroek deleterdataset,
1286*00b67f09SDavid van Moolenbroek issecure,
1287*00b67f09SDavid van Moolenbroek nodecount,
1288*00b67f09SDavid van Moolenbroek ispersistent,
1289*00b67f09SDavid van Moolenbroek overmem,
1290*00b67f09SDavid van Moolenbroek settask,
1291*00b67f09SDavid van Moolenbroek NULL, /* getoriginnode */
1292*00b67f09SDavid van Moolenbroek NULL, /* transfernode */
1293*00b67f09SDavid van Moolenbroek NULL, /* getnsec3parameters */
1294*00b67f09SDavid van Moolenbroek NULL, /* findnsec3node */
1295*00b67f09SDavid van Moolenbroek NULL, /* setsigningtime */
1296*00b67f09SDavid van Moolenbroek NULL, /* getsigningtime */
1297*00b67f09SDavid van Moolenbroek NULL, /* resigned */
1298*00b67f09SDavid van Moolenbroek NULL, /* isdnssec */
1299*00b67f09SDavid van Moolenbroek NULL, /* getrrsetstats */
1300*00b67f09SDavid van Moolenbroek NULL, /* rpz_attach */
1301*00b67f09SDavid van Moolenbroek NULL, /* rpz_ready */
1302*00b67f09SDavid van Moolenbroek findnodeext,
1303*00b67f09SDavid van Moolenbroek findext,
1304*00b67f09SDavid van Moolenbroek NULL, /* setcachestats */
1305*00b67f09SDavid van Moolenbroek NULL /* hashsize */
1306*00b67f09SDavid van Moolenbroek };
1307*00b67f09SDavid van Moolenbroek
1308*00b67f09SDavid van Moolenbroek static isc_result_t
dns_sdb_create(isc_mem_t * mctx,dns_name_t * origin,dns_dbtype_t type,dns_rdataclass_t rdclass,unsigned int argc,char * argv[],void * driverarg,dns_db_t ** dbp)1309*00b67f09SDavid van Moolenbroek dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
1310*00b67f09SDavid van Moolenbroek dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
1311*00b67f09SDavid van Moolenbroek void *driverarg, dns_db_t **dbp)
1312*00b67f09SDavid van Moolenbroek {
1313*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb;
1314*00b67f09SDavid van Moolenbroek isc_result_t result;
1315*00b67f09SDavid van Moolenbroek char zonestr[DNS_NAME_MAXTEXT + 1];
1316*00b67f09SDavid van Moolenbroek isc_buffer_t b;
1317*00b67f09SDavid van Moolenbroek dns_sdbimplementation_t *imp;
1318*00b67f09SDavid van Moolenbroek
1319*00b67f09SDavid van Moolenbroek REQUIRE(driverarg != NULL);
1320*00b67f09SDavid van Moolenbroek
1321*00b67f09SDavid van Moolenbroek imp = driverarg;
1322*00b67f09SDavid van Moolenbroek
1323*00b67f09SDavid van Moolenbroek if (type != dns_dbtype_zone)
1324*00b67f09SDavid van Moolenbroek return (ISC_R_NOTIMPLEMENTED);
1325*00b67f09SDavid van Moolenbroek
1326*00b67f09SDavid van Moolenbroek sdb = isc_mem_get(mctx, sizeof(dns_sdb_t));
1327*00b67f09SDavid van Moolenbroek if (sdb == NULL)
1328*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
1329*00b67f09SDavid van Moolenbroek memset(sdb, 0, sizeof(dns_sdb_t));
1330*00b67f09SDavid van Moolenbroek
1331*00b67f09SDavid van Moolenbroek dns_name_init(&sdb->common.origin, NULL);
1332*00b67f09SDavid van Moolenbroek sdb->common.attributes = 0;
1333*00b67f09SDavid van Moolenbroek sdb->common.methods = &sdb_methods;
1334*00b67f09SDavid van Moolenbroek sdb->common.rdclass = rdclass;
1335*00b67f09SDavid van Moolenbroek sdb->common.mctx = NULL;
1336*00b67f09SDavid van Moolenbroek sdb->implementation = imp;
1337*00b67f09SDavid van Moolenbroek
1338*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &sdb->common.mctx);
1339*00b67f09SDavid van Moolenbroek
1340*00b67f09SDavid van Moolenbroek result = isc_mutex_init(&sdb->lock);
1341*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1342*00b67f09SDavid van Moolenbroek goto cleanup_mctx;
1343*00b67f09SDavid van Moolenbroek
1344*00b67f09SDavid van Moolenbroek result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin);
1345*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1346*00b67f09SDavid van Moolenbroek goto cleanup_lock;
1347*00b67f09SDavid van Moolenbroek
1348*00b67f09SDavid van Moolenbroek isc_buffer_init(&b, zonestr, sizeof(zonestr));
1349*00b67f09SDavid van Moolenbroek result = dns_name_totext(origin, ISC_TRUE, &b);
1350*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1351*00b67f09SDavid van Moolenbroek goto cleanup_origin;
1352*00b67f09SDavid van Moolenbroek isc_buffer_putuint8(&b, 0);
1353*00b67f09SDavid van Moolenbroek
1354*00b67f09SDavid van Moolenbroek sdb->zone = isc_mem_strdup(mctx, zonestr);
1355*00b67f09SDavid van Moolenbroek if (sdb->zone == NULL) {
1356*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
1357*00b67f09SDavid van Moolenbroek goto cleanup_origin;
1358*00b67f09SDavid van Moolenbroek }
1359*00b67f09SDavid van Moolenbroek
1360*00b67f09SDavid van Moolenbroek sdb->dbdata = NULL;
1361*00b67f09SDavid van Moolenbroek if (imp->methods->create != NULL) {
1362*00b67f09SDavid van Moolenbroek MAYBE_LOCK(sdb);
1363*00b67f09SDavid van Moolenbroek result = imp->methods->create(sdb->zone, argc, argv,
1364*00b67f09SDavid van Moolenbroek imp->driverdata, &sdb->dbdata);
1365*00b67f09SDavid van Moolenbroek MAYBE_UNLOCK(sdb);
1366*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1367*00b67f09SDavid van Moolenbroek goto cleanup_zonestr;
1368*00b67f09SDavid van Moolenbroek }
1369*00b67f09SDavid van Moolenbroek
1370*00b67f09SDavid van Moolenbroek sdb->references = 1;
1371*00b67f09SDavid van Moolenbroek
1372*00b67f09SDavid van Moolenbroek sdb->common.magic = DNS_DB_MAGIC;
1373*00b67f09SDavid van Moolenbroek sdb->common.impmagic = SDB_MAGIC;
1374*00b67f09SDavid van Moolenbroek
1375*00b67f09SDavid van Moolenbroek *dbp = (dns_db_t *)sdb;
1376*00b67f09SDavid van Moolenbroek
1377*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1378*00b67f09SDavid van Moolenbroek
1379*00b67f09SDavid van Moolenbroek cleanup_zonestr:
1380*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, sdb->zone);
1381*00b67f09SDavid van Moolenbroek cleanup_origin:
1382*00b67f09SDavid van Moolenbroek dns_name_free(&sdb->common.origin, mctx);
1383*00b67f09SDavid van Moolenbroek cleanup_lock:
1384*00b67f09SDavid van Moolenbroek (void)isc_mutex_destroy(&sdb->lock);
1385*00b67f09SDavid van Moolenbroek cleanup_mctx:
1386*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
1387*00b67f09SDavid van Moolenbroek isc_mem_detach(&mctx);
1388*00b67f09SDavid van Moolenbroek
1389*00b67f09SDavid van Moolenbroek return (result);
1390*00b67f09SDavid van Moolenbroek }
1391*00b67f09SDavid van Moolenbroek
1392*00b67f09SDavid van Moolenbroek
1393*00b67f09SDavid van Moolenbroek /*
1394*00b67f09SDavid van Moolenbroek * Rdataset Methods
1395*00b67f09SDavid van Moolenbroek */
1396*00b67f09SDavid van Moolenbroek
1397*00b67f09SDavid van Moolenbroek static void
disassociate(dns_rdataset_t * rdataset)1398*00b67f09SDavid van Moolenbroek disassociate(dns_rdataset_t *rdataset) {
1399*00b67f09SDavid van Moolenbroek dns_dbnode_t *node = rdataset->private5;
1400*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node;
1401*00b67f09SDavid van Moolenbroek dns_db_t *db = (dns_db_t *) sdbnode->sdb;
1402*00b67f09SDavid van Moolenbroek
1403*00b67f09SDavid van Moolenbroek detachnode(db, &node);
1404*00b67f09SDavid van Moolenbroek isc__rdatalist_disassociate(rdataset);
1405*00b67f09SDavid van Moolenbroek }
1406*00b67f09SDavid van Moolenbroek
1407*00b67f09SDavid van Moolenbroek static void
rdataset_clone(dns_rdataset_t * source,dns_rdataset_t * target)1408*00b67f09SDavid van Moolenbroek rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
1409*00b67f09SDavid van Moolenbroek dns_dbnode_t *node = source->private5;
1410*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node;
1411*00b67f09SDavid van Moolenbroek dns_db_t *db = (dns_db_t *) sdbnode->sdb;
1412*00b67f09SDavid van Moolenbroek dns_dbnode_t *tempdb = NULL;
1413*00b67f09SDavid van Moolenbroek
1414*00b67f09SDavid van Moolenbroek isc__rdatalist_clone(source, target);
1415*00b67f09SDavid van Moolenbroek attachnode(db, node, &tempdb);
1416*00b67f09SDavid van Moolenbroek source->private5 = tempdb;
1417*00b67f09SDavid van Moolenbroek }
1418*00b67f09SDavid van Moolenbroek
1419*00b67f09SDavid van Moolenbroek static dns_rdatasetmethods_t methods = {
1420*00b67f09SDavid van Moolenbroek disassociate,
1421*00b67f09SDavid van Moolenbroek isc__rdatalist_first,
1422*00b67f09SDavid van Moolenbroek isc__rdatalist_next,
1423*00b67f09SDavid van Moolenbroek isc__rdatalist_current,
1424*00b67f09SDavid van Moolenbroek rdataset_clone,
1425*00b67f09SDavid van Moolenbroek isc__rdatalist_count,
1426*00b67f09SDavid van Moolenbroek isc__rdatalist_addnoqname,
1427*00b67f09SDavid van Moolenbroek isc__rdatalist_getnoqname,
1428*00b67f09SDavid van Moolenbroek NULL,
1429*00b67f09SDavid van Moolenbroek NULL,
1430*00b67f09SDavid van Moolenbroek NULL,
1431*00b67f09SDavid van Moolenbroek NULL,
1432*00b67f09SDavid van Moolenbroek NULL,
1433*00b67f09SDavid van Moolenbroek NULL,
1434*00b67f09SDavid van Moolenbroek NULL,
1435*00b67f09SDavid van Moolenbroek NULL
1436*00b67f09SDavid van Moolenbroek };
1437*00b67f09SDavid van Moolenbroek
1438*00b67f09SDavid van Moolenbroek static void
list_tordataset(dns_rdatalist_t * rdatalist,dns_db_t * db,dns_dbnode_t * node,dns_rdataset_t * rdataset)1439*00b67f09SDavid van Moolenbroek list_tordataset(dns_rdatalist_t *rdatalist,
1440*00b67f09SDavid van Moolenbroek dns_db_t *db, dns_dbnode_t *node,
1441*00b67f09SDavid van Moolenbroek dns_rdataset_t *rdataset)
1442*00b67f09SDavid van Moolenbroek {
1443*00b67f09SDavid van Moolenbroek /*
1444*00b67f09SDavid van Moolenbroek * The sdb rdataset is an rdatalist with some additions.
1445*00b67f09SDavid van Moolenbroek * - private1 & private2 are used by the rdatalist.
1446*00b67f09SDavid van Moolenbroek * - private3 & private 4 are unused.
1447*00b67f09SDavid van Moolenbroek * - private5 is the node.
1448*00b67f09SDavid van Moolenbroek */
1449*00b67f09SDavid van Moolenbroek
1450*00b67f09SDavid van Moolenbroek /* This should never fail. */
1451*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
1452*00b67f09SDavid van Moolenbroek ISC_R_SUCCESS);
1453*00b67f09SDavid van Moolenbroek
1454*00b67f09SDavid van Moolenbroek rdataset->methods = &methods;
1455*00b67f09SDavid van Moolenbroek dns_db_attachnode(db, node, &rdataset->private5);
1456*00b67f09SDavid van Moolenbroek }
1457*00b67f09SDavid van Moolenbroek
1458*00b67f09SDavid van Moolenbroek /*
1459*00b67f09SDavid van Moolenbroek * Database Iterator Methods
1460*00b67f09SDavid van Moolenbroek */
1461*00b67f09SDavid van Moolenbroek static void
dbiterator_destroy(dns_dbiterator_t ** iteratorp)1462*00b67f09SDavid van Moolenbroek dbiterator_destroy(dns_dbiterator_t **iteratorp) {
1463*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp);
1464*00b67f09SDavid van Moolenbroek dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db;
1465*00b67f09SDavid van Moolenbroek
1466*00b67f09SDavid van Moolenbroek while (!ISC_LIST_EMPTY(sdbiter->nodelist)) {
1467*00b67f09SDavid van Moolenbroek dns_sdbnode_t *node;
1468*00b67f09SDavid van Moolenbroek node = ISC_LIST_HEAD(sdbiter->nodelist);
1469*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(sdbiter->nodelist, node, link);
1470*00b67f09SDavid van Moolenbroek destroynode(node);
1471*00b67f09SDavid van Moolenbroek }
1472*00b67f09SDavid van Moolenbroek
1473*00b67f09SDavid van Moolenbroek dns_db_detach(&sdbiter->common.db);
1474*00b67f09SDavid van Moolenbroek isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t));
1475*00b67f09SDavid van Moolenbroek
1476*00b67f09SDavid van Moolenbroek *iteratorp = NULL;
1477*00b67f09SDavid van Moolenbroek }
1478*00b67f09SDavid van Moolenbroek
1479*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_first(dns_dbiterator_t * iterator)1480*00b67f09SDavid van Moolenbroek dbiterator_first(dns_dbiterator_t *iterator) {
1481*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
1482*00b67f09SDavid van Moolenbroek
1483*00b67f09SDavid van Moolenbroek sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
1484*00b67f09SDavid van Moolenbroek if (sdbiter->current == NULL)
1485*00b67f09SDavid van Moolenbroek return (ISC_R_NOMORE);
1486*00b67f09SDavid van Moolenbroek else
1487*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1488*00b67f09SDavid van Moolenbroek }
1489*00b67f09SDavid van Moolenbroek
1490*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_last(dns_dbiterator_t * iterator)1491*00b67f09SDavid van Moolenbroek dbiterator_last(dns_dbiterator_t *iterator) {
1492*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
1493*00b67f09SDavid van Moolenbroek
1494*00b67f09SDavid van Moolenbroek sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist);
1495*00b67f09SDavid van Moolenbroek if (sdbiter->current == NULL)
1496*00b67f09SDavid van Moolenbroek return (ISC_R_NOMORE);
1497*00b67f09SDavid van Moolenbroek else
1498*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1499*00b67f09SDavid van Moolenbroek }
1500*00b67f09SDavid van Moolenbroek
1501*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_seek(dns_dbiterator_t * iterator,dns_name_t * name)1502*00b67f09SDavid van Moolenbroek dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
1503*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
1504*00b67f09SDavid van Moolenbroek
1505*00b67f09SDavid van Moolenbroek sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
1506*00b67f09SDavid van Moolenbroek while (sdbiter->current != NULL) {
1507*00b67f09SDavid van Moolenbroek if (dns_name_equal(sdbiter->current->name, name))
1508*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1509*00b67f09SDavid van Moolenbroek sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
1510*00b67f09SDavid van Moolenbroek }
1511*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1512*00b67f09SDavid van Moolenbroek }
1513*00b67f09SDavid van Moolenbroek
1514*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_prev(dns_dbiterator_t * iterator)1515*00b67f09SDavid van Moolenbroek dbiterator_prev(dns_dbiterator_t *iterator) {
1516*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
1517*00b67f09SDavid van Moolenbroek
1518*00b67f09SDavid van Moolenbroek sdbiter->current = ISC_LIST_PREV(sdbiter->current, link);
1519*00b67f09SDavid van Moolenbroek if (sdbiter->current == NULL)
1520*00b67f09SDavid van Moolenbroek return (ISC_R_NOMORE);
1521*00b67f09SDavid van Moolenbroek else
1522*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1523*00b67f09SDavid van Moolenbroek }
1524*00b67f09SDavid van Moolenbroek
1525*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_next(dns_dbiterator_t * iterator)1526*00b67f09SDavid van Moolenbroek dbiterator_next(dns_dbiterator_t *iterator) {
1527*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
1528*00b67f09SDavid van Moolenbroek
1529*00b67f09SDavid van Moolenbroek sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
1530*00b67f09SDavid van Moolenbroek if (sdbiter->current == NULL)
1531*00b67f09SDavid van Moolenbroek return (ISC_R_NOMORE);
1532*00b67f09SDavid van Moolenbroek else
1533*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1534*00b67f09SDavid van Moolenbroek }
1535*00b67f09SDavid van Moolenbroek
1536*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_current(dns_dbiterator_t * iterator,dns_dbnode_t ** nodep,dns_name_t * name)1537*00b67f09SDavid van Moolenbroek dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
1538*00b67f09SDavid van Moolenbroek dns_name_t *name)
1539*00b67f09SDavid van Moolenbroek {
1540*00b67f09SDavid van Moolenbroek sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
1541*00b67f09SDavid van Moolenbroek
1542*00b67f09SDavid van Moolenbroek attachnode(iterator->db, sdbiter->current, nodep);
1543*00b67f09SDavid van Moolenbroek if (name != NULL)
1544*00b67f09SDavid van Moolenbroek return (dns_name_copy(sdbiter->current->name, name, NULL));
1545*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1546*00b67f09SDavid van Moolenbroek }
1547*00b67f09SDavid van Moolenbroek
1548*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_pause(dns_dbiterator_t * iterator)1549*00b67f09SDavid van Moolenbroek dbiterator_pause(dns_dbiterator_t *iterator) {
1550*00b67f09SDavid van Moolenbroek UNUSED(iterator);
1551*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1552*00b67f09SDavid van Moolenbroek }
1553*00b67f09SDavid van Moolenbroek
1554*00b67f09SDavid van Moolenbroek static isc_result_t
dbiterator_origin(dns_dbiterator_t * iterator,dns_name_t * name)1555*00b67f09SDavid van Moolenbroek dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
1556*00b67f09SDavid van Moolenbroek UNUSED(iterator);
1557*00b67f09SDavid van Moolenbroek return (dns_name_copy(dns_rootname, name, NULL));
1558*00b67f09SDavid van Moolenbroek }
1559*00b67f09SDavid van Moolenbroek
1560*00b67f09SDavid van Moolenbroek /*
1561*00b67f09SDavid van Moolenbroek * Rdataset Iterator Methods
1562*00b67f09SDavid van Moolenbroek */
1563*00b67f09SDavid van Moolenbroek
1564*00b67f09SDavid van Moolenbroek static void
rdatasetiter_destroy(dns_rdatasetiter_t ** iteratorp)1565*00b67f09SDavid van Moolenbroek rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
1566*00b67f09SDavid van Moolenbroek sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp);
1567*00b67f09SDavid van Moolenbroek detachnode(sdbiterator->common.db, &sdbiterator->common.node);
1568*00b67f09SDavid van Moolenbroek isc_mem_put(sdbiterator->common.db->mctx, sdbiterator,
1569*00b67f09SDavid van Moolenbroek sizeof(sdb_rdatasetiter_t));
1570*00b67f09SDavid van Moolenbroek *iteratorp = NULL;
1571*00b67f09SDavid van Moolenbroek }
1572*00b67f09SDavid van Moolenbroek
1573*00b67f09SDavid van Moolenbroek static isc_result_t
rdatasetiter_first(dns_rdatasetiter_t * iterator)1574*00b67f09SDavid van Moolenbroek rdatasetiter_first(dns_rdatasetiter_t *iterator) {
1575*00b67f09SDavid van Moolenbroek sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
1576*00b67f09SDavid van Moolenbroek dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node;
1577*00b67f09SDavid van Moolenbroek
1578*00b67f09SDavid van Moolenbroek if (ISC_LIST_EMPTY(sdbnode->lists))
1579*00b67f09SDavid van Moolenbroek return (ISC_R_NOMORE);
1580*00b67f09SDavid van Moolenbroek sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists);
1581*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1582*00b67f09SDavid van Moolenbroek }
1583*00b67f09SDavid van Moolenbroek
1584*00b67f09SDavid van Moolenbroek static isc_result_t
rdatasetiter_next(dns_rdatasetiter_t * iterator)1585*00b67f09SDavid van Moolenbroek rdatasetiter_next(dns_rdatasetiter_t *iterator) {
1586*00b67f09SDavid van Moolenbroek sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
1587*00b67f09SDavid van Moolenbroek
1588*00b67f09SDavid van Moolenbroek sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link);
1589*00b67f09SDavid van Moolenbroek if (sdbiterator->current == NULL)
1590*00b67f09SDavid van Moolenbroek return (ISC_R_NOMORE);
1591*00b67f09SDavid van Moolenbroek else
1592*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1593*00b67f09SDavid van Moolenbroek }
1594*00b67f09SDavid van Moolenbroek
1595*00b67f09SDavid van Moolenbroek static void
rdatasetiter_current(dns_rdatasetiter_t * iterator,dns_rdataset_t * rdataset)1596*00b67f09SDavid van Moolenbroek rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
1597*00b67f09SDavid van Moolenbroek sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
1598*00b67f09SDavid van Moolenbroek
1599*00b67f09SDavid van Moolenbroek list_tordataset(sdbiterator->current, iterator->db, iterator->node,
1600*00b67f09SDavid van Moolenbroek rdataset);
1601*00b67f09SDavid van Moolenbroek }
1602