xref: /minix3/external/bsd/bind/dist/lib/dns/db.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: db.c,v 1.7 2014/12/10 04:37:58 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007-2009, 2011-2013  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-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 /***
25*00b67f09SDavid van Moolenbroek  *** Imports
26*00b67f09SDavid van Moolenbroek  ***/
27*00b67f09SDavid van Moolenbroek 
28*00b67f09SDavid van Moolenbroek #include <config.h>
29*00b67f09SDavid van Moolenbroek 
30*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
31*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
32*00b67f09SDavid van Moolenbroek #include <isc/once.h>
33*00b67f09SDavid van Moolenbroek #include <isc/rwlock.h>
34*00b67f09SDavid van Moolenbroek #include <isc/string.h>
35*00b67f09SDavid van Moolenbroek #include <isc/util.h>
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek #include <dns/callbacks.h>
38*00b67f09SDavid van Moolenbroek #include <dns/clientinfo.h>
39*00b67f09SDavid van Moolenbroek #include <dns/db.h>
40*00b67f09SDavid van Moolenbroek #include <dns/dbiterator.h>
41*00b67f09SDavid van Moolenbroek #include <dns/log.h>
42*00b67f09SDavid van Moolenbroek #include <dns/master.h>
43*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
44*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
45*00b67f09SDavid van Moolenbroek #include <dns/rdatasetiter.h>
46*00b67f09SDavid van Moolenbroek #include <dns/result.h>
47*00b67f09SDavid van Moolenbroek 
48*00b67f09SDavid van Moolenbroek /***
49*00b67f09SDavid van Moolenbroek  *** Private Types
50*00b67f09SDavid van Moolenbroek  ***/
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek struct dns_dbimplementation {
53*00b67f09SDavid van Moolenbroek 	const char *				name;
54*00b67f09SDavid van Moolenbroek 	dns_dbcreatefunc_t			create;
55*00b67f09SDavid van Moolenbroek 	isc_mem_t *				mctx;
56*00b67f09SDavid van Moolenbroek 	void *					driverarg;
57*00b67f09SDavid van Moolenbroek 	ISC_LINK(dns_dbimplementation_t)	link;
58*00b67f09SDavid van Moolenbroek };
59*00b67f09SDavid van Moolenbroek 
60*00b67f09SDavid van Moolenbroek /***
61*00b67f09SDavid van Moolenbroek  *** Supported DB Implementations Registry
62*00b67f09SDavid van Moolenbroek  ***/
63*00b67f09SDavid van Moolenbroek 
64*00b67f09SDavid van Moolenbroek /*
65*00b67f09SDavid van Moolenbroek  * Built in database implementations are registered here.
66*00b67f09SDavid van Moolenbroek  */
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek #include "rbtdb.h"
69*00b67f09SDavid van Moolenbroek #include "rbtdb64.h"
70*00b67f09SDavid van Moolenbroek 
71*00b67f09SDavid van Moolenbroek static ISC_LIST(dns_dbimplementation_t) implementations;
72*00b67f09SDavid van Moolenbroek static isc_rwlock_t implock;
73*00b67f09SDavid van Moolenbroek static isc_once_t once = ISC_ONCE_INIT;
74*00b67f09SDavid van Moolenbroek 
75*00b67f09SDavid van Moolenbroek static dns_dbimplementation_t rbtimp;
76*00b67f09SDavid van Moolenbroek static dns_dbimplementation_t rbt64imp;
77*00b67f09SDavid van Moolenbroek 
78*00b67f09SDavid van Moolenbroek static void
initialize(void)79*00b67f09SDavid van Moolenbroek initialize(void) {
80*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_rwlock_init(&implock, 0, 0) == ISC_R_SUCCESS);
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek 	rbtimp.name = "rbt";
83*00b67f09SDavid van Moolenbroek 	rbtimp.create = dns_rbtdb_create;
84*00b67f09SDavid van Moolenbroek 	rbtimp.mctx = NULL;
85*00b67f09SDavid van Moolenbroek 	rbtimp.driverarg = NULL;
86*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(&rbtimp, link);
87*00b67f09SDavid van Moolenbroek 
88*00b67f09SDavid van Moolenbroek 	rbt64imp.name = "rbt64";
89*00b67f09SDavid van Moolenbroek 	rbt64imp.create = dns_rbtdb64_create;
90*00b67f09SDavid van Moolenbroek 	rbt64imp.mctx = NULL;
91*00b67f09SDavid van Moolenbroek 	rbt64imp.driverarg = NULL;
92*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(&rbt64imp, link);
93*00b67f09SDavid van Moolenbroek 
94*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(implementations);
95*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(implementations, &rbtimp, link);
96*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(implementations, &rbt64imp, link);
97*00b67f09SDavid van Moolenbroek }
98*00b67f09SDavid van Moolenbroek 
99*00b67f09SDavid van Moolenbroek static inline dns_dbimplementation_t *
impfind(const char * name)100*00b67f09SDavid van Moolenbroek impfind(const char *name) {
101*00b67f09SDavid van Moolenbroek 	dns_dbimplementation_t *imp;
102*00b67f09SDavid van Moolenbroek 
103*00b67f09SDavid van Moolenbroek 	for (imp = ISC_LIST_HEAD(implementations);
104*00b67f09SDavid van Moolenbroek 	     imp != NULL;
105*00b67f09SDavid van Moolenbroek 	     imp = ISC_LIST_NEXT(imp, link))
106*00b67f09SDavid van Moolenbroek 		if (strcasecmp(name, imp->name) == 0)
107*00b67f09SDavid van Moolenbroek 			return (imp);
108*00b67f09SDavid van Moolenbroek 	return (NULL);
109*00b67f09SDavid van Moolenbroek }
110*00b67f09SDavid van Moolenbroek 
111*00b67f09SDavid van Moolenbroek 
112*00b67f09SDavid van Moolenbroek /***
113*00b67f09SDavid van Moolenbroek  *** Basic DB Methods
114*00b67f09SDavid van Moolenbroek  ***/
115*00b67f09SDavid van Moolenbroek 
116*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_create(isc_mem_t * mctx,const char * db_type,dns_name_t * origin,dns_dbtype_t type,dns_rdataclass_t rdclass,unsigned int argc,char * argv[],dns_db_t ** dbp)117*00b67f09SDavid van Moolenbroek dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin,
118*00b67f09SDavid van Moolenbroek 	      dns_dbtype_t type, dns_rdataclass_t rdclass,
119*00b67f09SDavid van Moolenbroek 	      unsigned int argc, char *argv[], dns_db_t **dbp)
120*00b67f09SDavid van Moolenbroek {
121*00b67f09SDavid van Moolenbroek 	dns_dbimplementation_t *impinfo;
122*00b67f09SDavid van Moolenbroek 
123*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 	/*
126*00b67f09SDavid van Moolenbroek 	 * Create a new database using implementation 'db_type'.
127*00b67f09SDavid van Moolenbroek 	 */
128*00b67f09SDavid van Moolenbroek 
129*00b67f09SDavid van Moolenbroek 	REQUIRE(dbp != NULL && *dbp == NULL);
130*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_name_isabsolute(origin));
131*00b67f09SDavid van Moolenbroek 
132*00b67f09SDavid van Moolenbroek 	RWLOCK(&implock, isc_rwlocktype_read);
133*00b67f09SDavid van Moolenbroek 	impinfo = impfind(db_type);
134*00b67f09SDavid van Moolenbroek 	if (impinfo != NULL) {
135*00b67f09SDavid van Moolenbroek 		isc_result_t result;
136*00b67f09SDavid van Moolenbroek 		result = ((impinfo->create)(mctx, origin, type,
137*00b67f09SDavid van Moolenbroek 					    rdclass, argc, argv,
138*00b67f09SDavid van Moolenbroek 					    impinfo->driverarg, dbp));
139*00b67f09SDavid van Moolenbroek 		RWUNLOCK(&implock, isc_rwlocktype_read);
140*00b67f09SDavid van Moolenbroek 		return (result);
141*00b67f09SDavid van Moolenbroek 	}
142*00b67f09SDavid van Moolenbroek 
143*00b67f09SDavid van Moolenbroek 	RWUNLOCK(&implock, isc_rwlocktype_read);
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
146*00b67f09SDavid van Moolenbroek 		      DNS_LOGMODULE_DB, ISC_LOG_ERROR,
147*00b67f09SDavid van Moolenbroek 		      "unsupported database type '%s'", db_type);
148*00b67f09SDavid van Moolenbroek 
149*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTFOUND);
150*00b67f09SDavid van Moolenbroek }
151*00b67f09SDavid van Moolenbroek 
152*00b67f09SDavid van Moolenbroek void
dns_db_attach(dns_db_t * source,dns_db_t ** targetp)153*00b67f09SDavid van Moolenbroek dns_db_attach(dns_db_t *source, dns_db_t **targetp) {
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek 	/*
156*00b67f09SDavid van Moolenbroek 	 * Attach *targetp to source.
157*00b67f09SDavid van Moolenbroek 	 */
158*00b67f09SDavid van Moolenbroek 
159*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(source));
160*00b67f09SDavid van Moolenbroek 	REQUIRE(targetp != NULL && *targetp == NULL);
161*00b67f09SDavid van Moolenbroek 
162*00b67f09SDavid van Moolenbroek 	(source->methods->attach)(source, targetp);
163*00b67f09SDavid van Moolenbroek 
164*00b67f09SDavid van Moolenbroek 	ENSURE(*targetp == source);
165*00b67f09SDavid van Moolenbroek }
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek void
dns_db_detach(dns_db_t ** dbp)168*00b67f09SDavid van Moolenbroek dns_db_detach(dns_db_t **dbp) {
169*00b67f09SDavid van Moolenbroek 
170*00b67f09SDavid van Moolenbroek 	/*
171*00b67f09SDavid van Moolenbroek 	 * Detach *dbp from its database.
172*00b67f09SDavid van Moolenbroek 	 */
173*00b67f09SDavid van Moolenbroek 
174*00b67f09SDavid van Moolenbroek 	REQUIRE(dbp != NULL);
175*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(*dbp));
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek 	((*dbp)->methods->detach)(dbp);
178*00b67f09SDavid van Moolenbroek 
179*00b67f09SDavid van Moolenbroek 	ENSURE(*dbp == NULL);
180*00b67f09SDavid van Moolenbroek }
181*00b67f09SDavid van Moolenbroek 
182*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_ondestroy(dns_db_t * db,isc_task_t * task,isc_event_t ** eventp)183*00b67f09SDavid van Moolenbroek dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp)
184*00b67f09SDavid van Moolenbroek {
185*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
186*00b67f09SDavid van Moolenbroek 
187*00b67f09SDavid van Moolenbroek 	return (isc_ondestroy_register(&db->ondest, task, eventp));
188*00b67f09SDavid van Moolenbroek }
189*00b67f09SDavid van Moolenbroek 
190*00b67f09SDavid van Moolenbroek 
191*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_db_iscache(dns_db_t * db)192*00b67f09SDavid van Moolenbroek dns_db_iscache(dns_db_t *db) {
193*00b67f09SDavid van Moolenbroek 
194*00b67f09SDavid van Moolenbroek 	/*
195*00b67f09SDavid van Moolenbroek 	 * Does 'db' have cache semantics?
196*00b67f09SDavid van Moolenbroek 	 */
197*00b67f09SDavid van Moolenbroek 
198*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
199*00b67f09SDavid van Moolenbroek 
200*00b67f09SDavid van Moolenbroek 	if ((db->attributes & DNS_DBATTR_CACHE) != 0)
201*00b67f09SDavid van Moolenbroek 		return (ISC_TRUE);
202*00b67f09SDavid van Moolenbroek 
203*00b67f09SDavid van Moolenbroek 	return (ISC_FALSE);
204*00b67f09SDavid van Moolenbroek }
205*00b67f09SDavid van Moolenbroek 
206*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_db_iszone(dns_db_t * db)207*00b67f09SDavid van Moolenbroek dns_db_iszone(dns_db_t *db) {
208*00b67f09SDavid van Moolenbroek 
209*00b67f09SDavid van Moolenbroek 	/*
210*00b67f09SDavid van Moolenbroek 	 * Does 'db' have zone semantics?
211*00b67f09SDavid van Moolenbroek 	 */
212*00b67f09SDavid van Moolenbroek 
213*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
214*00b67f09SDavid van Moolenbroek 
215*00b67f09SDavid van Moolenbroek 	if ((db->attributes & (DNS_DBATTR_CACHE|DNS_DBATTR_STUB)) == 0)
216*00b67f09SDavid van Moolenbroek 		return (ISC_TRUE);
217*00b67f09SDavid van Moolenbroek 
218*00b67f09SDavid van Moolenbroek 	return (ISC_FALSE);
219*00b67f09SDavid van Moolenbroek }
220*00b67f09SDavid van Moolenbroek 
221*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_db_isstub(dns_db_t * db)222*00b67f09SDavid van Moolenbroek dns_db_isstub(dns_db_t *db) {
223*00b67f09SDavid van Moolenbroek 
224*00b67f09SDavid van Moolenbroek 	/*
225*00b67f09SDavid van Moolenbroek 	 * Does 'db' have stub semantics?
226*00b67f09SDavid van Moolenbroek 	 */
227*00b67f09SDavid van Moolenbroek 
228*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
229*00b67f09SDavid van Moolenbroek 
230*00b67f09SDavid van Moolenbroek 	if ((db->attributes & DNS_DBATTR_STUB) != 0)
231*00b67f09SDavid van Moolenbroek 		return (ISC_TRUE);
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek 	return (ISC_FALSE);
234*00b67f09SDavid van Moolenbroek }
235*00b67f09SDavid van Moolenbroek 
236*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_db_isdnssec(dns_db_t * db)237*00b67f09SDavid van Moolenbroek dns_db_isdnssec(dns_db_t *db) {
238*00b67f09SDavid van Moolenbroek 
239*00b67f09SDavid van Moolenbroek 	/*
240*00b67f09SDavid van Moolenbroek 	 * Is 'db' secure or partially secure?
241*00b67f09SDavid van Moolenbroek 	 */
242*00b67f09SDavid van Moolenbroek 
243*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
244*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
245*00b67f09SDavid van Moolenbroek 
246*00b67f09SDavid van Moolenbroek 	if (db->methods->isdnssec != NULL)
247*00b67f09SDavid van Moolenbroek 		return ((db->methods->isdnssec)(db));
248*00b67f09SDavid van Moolenbroek 	return ((db->methods->issecure)(db));
249*00b67f09SDavid van Moolenbroek }
250*00b67f09SDavid van Moolenbroek 
251*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_db_issecure(dns_db_t * db)252*00b67f09SDavid van Moolenbroek dns_db_issecure(dns_db_t *db) {
253*00b67f09SDavid van Moolenbroek 
254*00b67f09SDavid van Moolenbroek 	/*
255*00b67f09SDavid van Moolenbroek 	 * Is 'db' secure?
256*00b67f09SDavid van Moolenbroek 	 */
257*00b67f09SDavid van Moolenbroek 
258*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
259*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
260*00b67f09SDavid van Moolenbroek 
261*00b67f09SDavid van Moolenbroek 	return ((db->methods->issecure)(db));
262*00b67f09SDavid van Moolenbroek }
263*00b67f09SDavid van Moolenbroek 
264*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_db_ispersistent(dns_db_t * db)265*00b67f09SDavid van Moolenbroek dns_db_ispersistent(dns_db_t *db) {
266*00b67f09SDavid van Moolenbroek 
267*00b67f09SDavid van Moolenbroek 	/*
268*00b67f09SDavid van Moolenbroek 	 * Is 'db' persistent?
269*00b67f09SDavid van Moolenbroek 	 */
270*00b67f09SDavid van Moolenbroek 
271*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	return ((db->methods->ispersistent)(db));
274*00b67f09SDavid van Moolenbroek }
275*00b67f09SDavid van Moolenbroek 
276*00b67f09SDavid van Moolenbroek dns_name_t *
dns_db_origin(dns_db_t * db)277*00b67f09SDavid van Moolenbroek dns_db_origin(dns_db_t *db) {
278*00b67f09SDavid van Moolenbroek 	/*
279*00b67f09SDavid van Moolenbroek 	 * The origin of the database.
280*00b67f09SDavid van Moolenbroek 	 */
281*00b67f09SDavid van Moolenbroek 
282*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
283*00b67f09SDavid van Moolenbroek 
284*00b67f09SDavid van Moolenbroek 	return (&db->origin);
285*00b67f09SDavid van Moolenbroek }
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek dns_rdataclass_t
dns_db_class(dns_db_t * db)288*00b67f09SDavid van Moolenbroek dns_db_class(dns_db_t *db) {
289*00b67f09SDavid van Moolenbroek 	/*
290*00b67f09SDavid van Moolenbroek 	 * The class of the database.
291*00b67f09SDavid van Moolenbroek 	 */
292*00b67f09SDavid van Moolenbroek 
293*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
294*00b67f09SDavid van Moolenbroek 
295*00b67f09SDavid van Moolenbroek 	return (db->rdclass);
296*00b67f09SDavid van Moolenbroek }
297*00b67f09SDavid van Moolenbroek 
298*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_beginload(dns_db_t * db,dns_rdatacallbacks_t * callbacks)299*00b67f09SDavid van Moolenbroek dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
300*00b67f09SDavid van Moolenbroek 	/*
301*00b67f09SDavid van Moolenbroek 	 * Begin loading 'db'.
302*00b67f09SDavid van Moolenbroek 	 */
303*00b67f09SDavid van Moolenbroek 
304*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
305*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_CALLBACK_VALID(callbacks));
306*00b67f09SDavid van Moolenbroek 
307*00b67f09SDavid van Moolenbroek 	return ((db->methods->beginload)(db, callbacks));
308*00b67f09SDavid van Moolenbroek }
309*00b67f09SDavid van Moolenbroek 
310*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_endload(dns_db_t * db,dns_rdatacallbacks_t * callbacks)311*00b67f09SDavid van Moolenbroek dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
312*00b67f09SDavid van Moolenbroek 	/*
313*00b67f09SDavid van Moolenbroek 	 * Finish loading 'db'.
314*00b67f09SDavid van Moolenbroek 	 */
315*00b67f09SDavid van Moolenbroek 
316*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
317*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_CALLBACK_VALID(callbacks));
318*00b67f09SDavid van Moolenbroek 	REQUIRE(callbacks->add_private != NULL);
319*00b67f09SDavid van Moolenbroek 
320*00b67f09SDavid van Moolenbroek 	return ((db->methods->endload)(db, callbacks));
321*00b67f09SDavid van Moolenbroek }
322*00b67f09SDavid van Moolenbroek 
323*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_load(dns_db_t * db,const char * filename)324*00b67f09SDavid van Moolenbroek dns_db_load(dns_db_t *db, const char *filename) {
325*00b67f09SDavid van Moolenbroek 	return (dns_db_load3(db, filename, dns_masterformat_text, 0));
326*00b67f09SDavid van Moolenbroek }
327*00b67f09SDavid van Moolenbroek 
328*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_load2(dns_db_t * db,const char * filename,dns_masterformat_t format)329*00b67f09SDavid van Moolenbroek dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) {
330*00b67f09SDavid van Moolenbroek 	return (dns_db_load3(db, filename, format, 0));
331*00b67f09SDavid van Moolenbroek }
332*00b67f09SDavid van Moolenbroek 
333*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_load3(dns_db_t * db,const char * filename,dns_masterformat_t format,unsigned int options)334*00b67f09SDavid van Moolenbroek dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format,
335*00b67f09SDavid van Moolenbroek 	     unsigned int options) {
336*00b67f09SDavid van Moolenbroek 	isc_result_t result, eresult;
337*00b67f09SDavid van Moolenbroek 	dns_rdatacallbacks_t callbacks;
338*00b67f09SDavid van Moolenbroek 
339*00b67f09SDavid van Moolenbroek 	/*
340*00b67f09SDavid van Moolenbroek 	 * Load master file 'filename' into 'db'.
341*00b67f09SDavid van Moolenbroek 	 */
342*00b67f09SDavid van Moolenbroek 
343*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
344*00b67f09SDavid van Moolenbroek 
345*00b67f09SDavid van Moolenbroek 	if ((db->attributes & DNS_DBATTR_CACHE) != 0)
346*00b67f09SDavid van Moolenbroek 		options |= DNS_MASTER_AGETTL;
347*00b67f09SDavid van Moolenbroek 
348*00b67f09SDavid van Moolenbroek 	dns_rdatacallbacks_init(&callbacks);
349*00b67f09SDavid van Moolenbroek 	result = dns_db_beginload(db, &callbacks);
350*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
351*00b67f09SDavid van Moolenbroek 		return (result);
352*00b67f09SDavid van Moolenbroek 	result = dns_master_loadfile2(filename, &db->origin, &db->origin,
353*00b67f09SDavid van Moolenbroek 				      db->rdclass, options,
354*00b67f09SDavid van Moolenbroek 				      &callbacks, db->mctx, format);
355*00b67f09SDavid van Moolenbroek 	eresult = dns_db_endload(db, &callbacks);
356*00b67f09SDavid van Moolenbroek 	/*
357*00b67f09SDavid van Moolenbroek 	 * We always call dns_db_endload(), but we only want to return its
358*00b67f09SDavid van Moolenbroek 	 * result if dns_master_loadfile() succeeded.  If dns_master_loadfile()
359*00b67f09SDavid van Moolenbroek 	 * failed, we want to return the result code it gave us.
360*00b67f09SDavid van Moolenbroek 	 */
361*00b67f09SDavid van Moolenbroek 	if (eresult != ISC_R_SUCCESS &&
362*00b67f09SDavid van Moolenbroek 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
363*00b67f09SDavid van Moolenbroek 		result = eresult;
364*00b67f09SDavid van Moolenbroek 
365*00b67f09SDavid van Moolenbroek 	return (result);
366*00b67f09SDavid van Moolenbroek }
367*00b67f09SDavid van Moolenbroek 
368*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_serialize(dns_db_t * db,dns_dbversion_t * version,FILE * file)369*00b67f09SDavid van Moolenbroek dns_db_serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file) {
370*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
371*00b67f09SDavid van Moolenbroek 	if (db->methods->serialize == NULL)
372*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
373*00b67f09SDavid van Moolenbroek 	return ((db->methods->serialize)(db, version, file));
374*00b67f09SDavid van Moolenbroek }
375*00b67f09SDavid van Moolenbroek 
376*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_dump(dns_db_t * db,dns_dbversion_t * version,const char * filename)377*00b67f09SDavid van Moolenbroek dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) {
378*00b67f09SDavid van Moolenbroek 	return ((db->methods->dump)(db, version, filename,
379*00b67f09SDavid van Moolenbroek 				    dns_masterformat_text));
380*00b67f09SDavid van Moolenbroek }
381*00b67f09SDavid van Moolenbroek 
382*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_dump2(dns_db_t * db,dns_dbversion_t * version,const char * filename,dns_masterformat_t masterformat)383*00b67f09SDavid van Moolenbroek dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename,
384*00b67f09SDavid van Moolenbroek 	     dns_masterformat_t masterformat) {
385*00b67f09SDavid van Moolenbroek 	/*
386*00b67f09SDavid van Moolenbroek 	 * Dump 'db' into master file 'filename' in the 'masterformat' format.
387*00b67f09SDavid van Moolenbroek 	 * XXXJT: is it okay to modify the interface to the existing "dump"
388*00b67f09SDavid van Moolenbroek 	 * method?
389*00b67f09SDavid van Moolenbroek 	 */
390*00b67f09SDavid van Moolenbroek 
391*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
392*00b67f09SDavid van Moolenbroek 
393*00b67f09SDavid van Moolenbroek 	return ((db->methods->dump)(db, version, filename, masterformat));
394*00b67f09SDavid van Moolenbroek }
395*00b67f09SDavid van Moolenbroek 
396*00b67f09SDavid van Moolenbroek /***
397*00b67f09SDavid van Moolenbroek  *** Version Methods
398*00b67f09SDavid van Moolenbroek  ***/
399*00b67f09SDavid van Moolenbroek 
400*00b67f09SDavid van Moolenbroek void
dns_db_currentversion(dns_db_t * db,dns_dbversion_t ** versionp)401*00b67f09SDavid van Moolenbroek dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
402*00b67f09SDavid van Moolenbroek 
403*00b67f09SDavid van Moolenbroek 	/*
404*00b67f09SDavid van Moolenbroek 	 * Open the current version for reading.
405*00b67f09SDavid van Moolenbroek 	 */
406*00b67f09SDavid van Moolenbroek 
407*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
408*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
409*00b67f09SDavid van Moolenbroek 	REQUIRE(versionp != NULL && *versionp == NULL);
410*00b67f09SDavid van Moolenbroek 
411*00b67f09SDavid van Moolenbroek 	(db->methods->currentversion)(db, versionp);
412*00b67f09SDavid van Moolenbroek }
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_newversion(dns_db_t * db,dns_dbversion_t ** versionp)415*00b67f09SDavid van Moolenbroek dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) {
416*00b67f09SDavid van Moolenbroek 
417*00b67f09SDavid van Moolenbroek 	/*
418*00b67f09SDavid van Moolenbroek 	 * Open a new version for reading and writing.
419*00b67f09SDavid van Moolenbroek 	 */
420*00b67f09SDavid van Moolenbroek 
421*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
422*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
423*00b67f09SDavid van Moolenbroek 	REQUIRE(versionp != NULL && *versionp == NULL);
424*00b67f09SDavid van Moolenbroek 
425*00b67f09SDavid van Moolenbroek 	return ((db->methods->newversion)(db, versionp));
426*00b67f09SDavid van Moolenbroek }
427*00b67f09SDavid van Moolenbroek 
428*00b67f09SDavid van Moolenbroek void
dns_db_attachversion(dns_db_t * db,dns_dbversion_t * source,dns_dbversion_t ** targetp)429*00b67f09SDavid van Moolenbroek dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source,
430*00b67f09SDavid van Moolenbroek 		     dns_dbversion_t **targetp)
431*00b67f09SDavid van Moolenbroek {
432*00b67f09SDavid van Moolenbroek 	/*
433*00b67f09SDavid van Moolenbroek 	 * Attach '*targetp' to 'source'.
434*00b67f09SDavid van Moolenbroek 	 */
435*00b67f09SDavid van Moolenbroek 
436*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
437*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
438*00b67f09SDavid van Moolenbroek 	REQUIRE(source != NULL);
439*00b67f09SDavid van Moolenbroek 	REQUIRE(targetp != NULL && *targetp == NULL);
440*00b67f09SDavid van Moolenbroek 
441*00b67f09SDavid van Moolenbroek 	(db->methods->attachversion)(db, source, targetp);
442*00b67f09SDavid van Moolenbroek 
443*00b67f09SDavid van Moolenbroek 	ENSURE(*targetp != NULL);
444*00b67f09SDavid van Moolenbroek }
445*00b67f09SDavid van Moolenbroek 
446*00b67f09SDavid van Moolenbroek void
dns_db_closeversion(dns_db_t * db,dns_dbversion_t ** versionp,isc_boolean_t commit)447*00b67f09SDavid van Moolenbroek dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
448*00b67f09SDavid van Moolenbroek 		    isc_boolean_t commit)
449*00b67f09SDavid van Moolenbroek {
450*00b67f09SDavid van Moolenbroek 
451*00b67f09SDavid van Moolenbroek 	/*
452*00b67f09SDavid van Moolenbroek 	 * Close version '*versionp'.
453*00b67f09SDavid van Moolenbroek 	 */
454*00b67f09SDavid van Moolenbroek 
455*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
456*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
457*00b67f09SDavid van Moolenbroek 	REQUIRE(versionp != NULL && *versionp != NULL);
458*00b67f09SDavid van Moolenbroek 
459*00b67f09SDavid van Moolenbroek 	(db->methods->closeversion)(db, versionp, commit);
460*00b67f09SDavid van Moolenbroek 
461*00b67f09SDavid van Moolenbroek 	ENSURE(*versionp == NULL);
462*00b67f09SDavid van Moolenbroek }
463*00b67f09SDavid van Moolenbroek 
464*00b67f09SDavid van Moolenbroek /***
465*00b67f09SDavid van Moolenbroek  *** Node Methods
466*00b67f09SDavid van Moolenbroek  ***/
467*00b67f09SDavid van Moolenbroek 
468*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_findnode(dns_db_t * db,dns_name_t * name,isc_boolean_t create,dns_dbnode_t ** nodep)469*00b67f09SDavid van Moolenbroek dns_db_findnode(dns_db_t *db, dns_name_t *name,
470*00b67f09SDavid van Moolenbroek 		isc_boolean_t create, dns_dbnode_t **nodep)
471*00b67f09SDavid van Moolenbroek {
472*00b67f09SDavid van Moolenbroek 
473*00b67f09SDavid van Moolenbroek 	/*
474*00b67f09SDavid van Moolenbroek 	 * Find the node with name 'name'.
475*00b67f09SDavid van Moolenbroek 	 */
476*00b67f09SDavid van Moolenbroek 
477*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
478*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep != NULL && *nodep == NULL);
479*00b67f09SDavid van Moolenbroek 
480*00b67f09SDavid van Moolenbroek 	if (db->methods->findnode != NULL)
481*00b67f09SDavid van Moolenbroek 		return ((db->methods->findnode)(db, name, create, nodep));
482*00b67f09SDavid van Moolenbroek 	else
483*00b67f09SDavid van Moolenbroek 		return ((db->methods->findnodeext)(db, name, create,
484*00b67f09SDavid van Moolenbroek 						   NULL, NULL, nodep));
485*00b67f09SDavid van Moolenbroek }
486*00b67f09SDavid van Moolenbroek 
487*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_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)488*00b67f09SDavid van Moolenbroek dns_db_findnodeext(dns_db_t *db, dns_name_t *name,
489*00b67f09SDavid van Moolenbroek 		   isc_boolean_t create, dns_clientinfomethods_t *methods,
490*00b67f09SDavid van Moolenbroek 		   dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
491*00b67f09SDavid van Moolenbroek {
492*00b67f09SDavid van Moolenbroek 	/*
493*00b67f09SDavid van Moolenbroek 	 * Find the node with name 'name', passing 'arg' to the database
494*00b67f09SDavid van Moolenbroek 	 * implementation.
495*00b67f09SDavid van Moolenbroek 	 */
496*00b67f09SDavid van Moolenbroek 
497*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
498*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep != NULL && *nodep == NULL);
499*00b67f09SDavid van Moolenbroek 
500*00b67f09SDavid van Moolenbroek 	if (db->methods->findnodeext != NULL)
501*00b67f09SDavid van Moolenbroek 		return ((db->methods->findnodeext)(db, name, create,
502*00b67f09SDavid van Moolenbroek 						   methods, clientinfo, nodep));
503*00b67f09SDavid van Moolenbroek 	else
504*00b67f09SDavid van Moolenbroek 		return ((db->methods->findnode)(db, name, create, nodep));
505*00b67f09SDavid van Moolenbroek }
506*00b67f09SDavid van Moolenbroek 
507*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_findnsec3node(dns_db_t * db,dns_name_t * name,isc_boolean_t create,dns_dbnode_t ** nodep)508*00b67f09SDavid van Moolenbroek dns_db_findnsec3node(dns_db_t *db, dns_name_t *name,
509*00b67f09SDavid van Moolenbroek 		     isc_boolean_t create, dns_dbnode_t **nodep)
510*00b67f09SDavid van Moolenbroek {
511*00b67f09SDavid van Moolenbroek 
512*00b67f09SDavid van Moolenbroek 	/*
513*00b67f09SDavid van Moolenbroek 	 * Find the node with name 'name'.
514*00b67f09SDavid van Moolenbroek 	 */
515*00b67f09SDavid van Moolenbroek 
516*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
517*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep != NULL && *nodep == NULL);
518*00b67f09SDavid van Moolenbroek 
519*00b67f09SDavid van Moolenbroek 	return ((db->methods->findnsec3node)(db, name, create, nodep));
520*00b67f09SDavid van Moolenbroek }
521*00b67f09SDavid van Moolenbroek 
522*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_find(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_rdataset_t * rdataset,dns_rdataset_t * sigrdataset)523*00b67f09SDavid van Moolenbroek dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
524*00b67f09SDavid van Moolenbroek 	    dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
525*00b67f09SDavid van Moolenbroek 	    dns_dbnode_t **nodep, dns_name_t *foundname,
526*00b67f09SDavid van Moolenbroek 	    dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
527*00b67f09SDavid van Moolenbroek {
528*00b67f09SDavid van Moolenbroek 	/*
529*00b67f09SDavid van Moolenbroek 	 * Find the best match for 'name' and 'type' in version 'version'
530*00b67f09SDavid van Moolenbroek 	 * of 'db'.
531*00b67f09SDavid van Moolenbroek 	 */
532*00b67f09SDavid van Moolenbroek 
533*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
534*00b67f09SDavid van Moolenbroek 	REQUIRE(type != dns_rdatatype_rrsig);
535*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
536*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_name_hasbuffer(foundname));
537*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset == NULL ||
538*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(rdataset) &&
539*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(rdataset)));
540*00b67f09SDavid van Moolenbroek 	REQUIRE(sigrdataset == NULL ||
541*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(sigrdataset) &&
542*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(sigrdataset)));
543*00b67f09SDavid van Moolenbroek 
544*00b67f09SDavid van Moolenbroek 	if (db->methods->find != NULL)
545*00b67f09SDavid van Moolenbroek 		return ((db->methods->find)(db, name, version, type,
546*00b67f09SDavid van Moolenbroek 					    options, now, nodep, foundname,
547*00b67f09SDavid van Moolenbroek 					    rdataset, sigrdataset));
548*00b67f09SDavid van Moolenbroek 	else
549*00b67f09SDavid van Moolenbroek 		return ((db->methods->findext)(db, name, version, type,
550*00b67f09SDavid van Moolenbroek 					       options, now, nodep, foundname,
551*00b67f09SDavid van Moolenbroek 					       NULL, NULL,
552*00b67f09SDavid van Moolenbroek 					       rdataset, sigrdataset));
553*00b67f09SDavid van Moolenbroek }
554*00b67f09SDavid van Moolenbroek 
555*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_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)556*00b67f09SDavid van Moolenbroek dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
557*00b67f09SDavid van Moolenbroek 	       dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
558*00b67f09SDavid van Moolenbroek 	       dns_dbnode_t **nodep, dns_name_t *foundname,
559*00b67f09SDavid van Moolenbroek 	       dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
560*00b67f09SDavid van Moolenbroek 	       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
561*00b67f09SDavid van Moolenbroek {
562*00b67f09SDavid van Moolenbroek 
563*00b67f09SDavid van Moolenbroek 	/*
564*00b67f09SDavid van Moolenbroek 	 * Find the best match for 'name' and 'type' in version 'version'
565*00b67f09SDavid van Moolenbroek 	 * of 'db', passing in 'arg'.
566*00b67f09SDavid van Moolenbroek 	 */
567*00b67f09SDavid van Moolenbroek 
568*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
569*00b67f09SDavid van Moolenbroek 	REQUIRE(type != dns_rdatatype_rrsig);
570*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
571*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_name_hasbuffer(foundname));
572*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset == NULL ||
573*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(rdataset) &&
574*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(rdataset)));
575*00b67f09SDavid van Moolenbroek 	REQUIRE(sigrdataset == NULL ||
576*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(sigrdataset) &&
577*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(sigrdataset)));
578*00b67f09SDavid van Moolenbroek 
579*00b67f09SDavid van Moolenbroek 	if (db->methods->findext != NULL)
580*00b67f09SDavid van Moolenbroek 		return ((db->methods->findext)(db, name, version, type,
581*00b67f09SDavid van Moolenbroek 					       options, now, nodep, foundname,
582*00b67f09SDavid van Moolenbroek 					       methods, clientinfo,
583*00b67f09SDavid van Moolenbroek 					       rdataset, sigrdataset));
584*00b67f09SDavid van Moolenbroek 	else
585*00b67f09SDavid van Moolenbroek 		return ((db->methods->find)(db, name, version, type,
586*00b67f09SDavid van Moolenbroek 					    options, now, nodep, foundname,
587*00b67f09SDavid van Moolenbroek 					    rdataset, sigrdataset));
588*00b67f09SDavid van Moolenbroek }
589*00b67f09SDavid van Moolenbroek 
590*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_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)591*00b67f09SDavid van Moolenbroek dns_db_findzonecut(dns_db_t *db, dns_name_t *name,
592*00b67f09SDavid van Moolenbroek 		   unsigned int options, isc_stdtime_t now,
593*00b67f09SDavid van Moolenbroek 		   dns_dbnode_t **nodep, dns_name_t *foundname,
594*00b67f09SDavid van Moolenbroek 		   dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
595*00b67f09SDavid van Moolenbroek {
596*00b67f09SDavid van Moolenbroek 	/*
597*00b67f09SDavid van Moolenbroek 	 * Find the deepest known zonecut which encloses 'name' in 'db'.
598*00b67f09SDavid van Moolenbroek 	 */
599*00b67f09SDavid van Moolenbroek 
600*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
601*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
602*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
603*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_name_hasbuffer(foundname));
604*00b67f09SDavid van Moolenbroek 	REQUIRE(sigrdataset == NULL ||
605*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(sigrdataset) &&
606*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(sigrdataset)));
607*00b67f09SDavid van Moolenbroek 
608*00b67f09SDavid van Moolenbroek 	return ((db->methods->findzonecut)(db, name, options, now, nodep,
609*00b67f09SDavid van Moolenbroek 					   foundname, rdataset, sigrdataset));
610*00b67f09SDavid van Moolenbroek }
611*00b67f09SDavid van Moolenbroek 
612*00b67f09SDavid van Moolenbroek void
dns_db_attachnode(dns_db_t * db,dns_dbnode_t * source,dns_dbnode_t ** targetp)613*00b67f09SDavid van Moolenbroek dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
614*00b67f09SDavid van Moolenbroek 
615*00b67f09SDavid van Moolenbroek 	/*
616*00b67f09SDavid van Moolenbroek 	 * Attach *targetp to source.
617*00b67f09SDavid van Moolenbroek 	 */
618*00b67f09SDavid van Moolenbroek 
619*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
620*00b67f09SDavid van Moolenbroek 	REQUIRE(source != NULL);
621*00b67f09SDavid van Moolenbroek 	REQUIRE(targetp != NULL && *targetp == NULL);
622*00b67f09SDavid van Moolenbroek 
623*00b67f09SDavid van Moolenbroek 	(db->methods->attachnode)(db, source, targetp);
624*00b67f09SDavid van Moolenbroek }
625*00b67f09SDavid van Moolenbroek 
626*00b67f09SDavid van Moolenbroek void
dns_db_detachnode(dns_db_t * db,dns_dbnode_t ** nodep)627*00b67f09SDavid van Moolenbroek dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
628*00b67f09SDavid van Moolenbroek 
629*00b67f09SDavid van Moolenbroek 	/*
630*00b67f09SDavid van Moolenbroek 	 * Detach *nodep from its node.
631*00b67f09SDavid van Moolenbroek 	 */
632*00b67f09SDavid van Moolenbroek 
633*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
634*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep != NULL && *nodep != NULL);
635*00b67f09SDavid van Moolenbroek 
636*00b67f09SDavid van Moolenbroek 	(db->methods->detachnode)(db, nodep);
637*00b67f09SDavid van Moolenbroek 
638*00b67f09SDavid van Moolenbroek 	ENSURE(*nodep == NULL);
639*00b67f09SDavid van Moolenbroek }
640*00b67f09SDavid van Moolenbroek 
641*00b67f09SDavid van Moolenbroek void
dns_db_transfernode(dns_db_t * db,dns_dbnode_t ** sourcep,dns_dbnode_t ** targetp)642*00b67f09SDavid van Moolenbroek dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
643*00b67f09SDavid van Moolenbroek 		    dns_dbnode_t **targetp)
644*00b67f09SDavid van Moolenbroek {
645*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
646*00b67f09SDavid van Moolenbroek 	REQUIRE(targetp != NULL && *targetp == NULL);
647*00b67f09SDavid van Moolenbroek 	/*
648*00b67f09SDavid van Moolenbroek 	 * This doesn't check the implementation magic.  If we find that
649*00b67f09SDavid van Moolenbroek 	 * we need such checks in future then this will be done in the
650*00b67f09SDavid van Moolenbroek 	 * method.
651*00b67f09SDavid van Moolenbroek 	 */
652*00b67f09SDavid van Moolenbroek 	REQUIRE(sourcep != NULL && *sourcep != NULL);
653*00b67f09SDavid van Moolenbroek 
654*00b67f09SDavid van Moolenbroek 	UNUSED(db);
655*00b67f09SDavid van Moolenbroek 
656*00b67f09SDavid van Moolenbroek 	if (db->methods->transfernode == NULL) {
657*00b67f09SDavid van Moolenbroek 		*targetp = *sourcep;
658*00b67f09SDavid van Moolenbroek 		*sourcep = NULL;
659*00b67f09SDavid van Moolenbroek 	} else
660*00b67f09SDavid van Moolenbroek 		(db->methods->transfernode)(db, sourcep, targetp);
661*00b67f09SDavid van Moolenbroek 
662*00b67f09SDavid van Moolenbroek 	ENSURE(*sourcep == NULL);
663*00b67f09SDavid van Moolenbroek }
664*00b67f09SDavid van Moolenbroek 
665*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_expirenode(dns_db_t * db,dns_dbnode_t * node,isc_stdtime_t now)666*00b67f09SDavid van Moolenbroek dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
667*00b67f09SDavid van Moolenbroek 
668*00b67f09SDavid van Moolenbroek 	/*
669*00b67f09SDavid van Moolenbroek 	 * Mark as stale all records at 'node' which expire at or before 'now'.
670*00b67f09SDavid van Moolenbroek 	 */
671*00b67f09SDavid van Moolenbroek 
672*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
673*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
674*00b67f09SDavid van Moolenbroek 	REQUIRE(node != NULL);
675*00b67f09SDavid van Moolenbroek 
676*00b67f09SDavid van Moolenbroek 	return ((db->methods->expirenode)(db, node, now));
677*00b67f09SDavid van Moolenbroek }
678*00b67f09SDavid van Moolenbroek 
679*00b67f09SDavid van Moolenbroek void
dns_db_printnode(dns_db_t * db,dns_dbnode_t * node,FILE * out)680*00b67f09SDavid van Moolenbroek dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
681*00b67f09SDavid van Moolenbroek 	/*
682*00b67f09SDavid van Moolenbroek 	 * Print a textual representation of the contents of the node to
683*00b67f09SDavid van Moolenbroek 	 * 'out'.
684*00b67f09SDavid van Moolenbroek 	 */
685*00b67f09SDavid van Moolenbroek 
686*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
687*00b67f09SDavid van Moolenbroek 	REQUIRE(node != NULL);
688*00b67f09SDavid van Moolenbroek 
689*00b67f09SDavid van Moolenbroek 	(db->methods->printnode)(db, node, out);
690*00b67f09SDavid van Moolenbroek }
691*00b67f09SDavid van Moolenbroek 
692*00b67f09SDavid van Moolenbroek /***
693*00b67f09SDavid van Moolenbroek  *** DB Iterator Creation
694*00b67f09SDavid van Moolenbroek  ***/
695*00b67f09SDavid van Moolenbroek 
696*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_createiterator(dns_db_t * db,unsigned int flags,dns_dbiterator_t ** iteratorp)697*00b67f09SDavid van Moolenbroek dns_db_createiterator(dns_db_t *db, unsigned int flags,
698*00b67f09SDavid van Moolenbroek 		      dns_dbiterator_t **iteratorp)
699*00b67f09SDavid van Moolenbroek {
700*00b67f09SDavid van Moolenbroek 	/*
701*00b67f09SDavid van Moolenbroek 	 * Create an iterator for version 'version' of 'db'.
702*00b67f09SDavid van Moolenbroek 	 */
703*00b67f09SDavid van Moolenbroek 
704*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
705*00b67f09SDavid van Moolenbroek 	REQUIRE(iteratorp != NULL && *iteratorp == NULL);
706*00b67f09SDavid van Moolenbroek 
707*00b67f09SDavid van Moolenbroek 	return (db->methods->createiterator(db, flags, iteratorp));
708*00b67f09SDavid van Moolenbroek }
709*00b67f09SDavid van Moolenbroek 
710*00b67f09SDavid van Moolenbroek /***
711*00b67f09SDavid van Moolenbroek  *** Rdataset Methods
712*00b67f09SDavid van Moolenbroek  ***/
713*00b67f09SDavid van Moolenbroek 
714*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_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)715*00b67f09SDavid van Moolenbroek dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
716*00b67f09SDavid van Moolenbroek 		    dns_rdatatype_t type, dns_rdatatype_t covers,
717*00b67f09SDavid van Moolenbroek 		    isc_stdtime_t now, dns_rdataset_t *rdataset,
718*00b67f09SDavid van Moolenbroek 		    dns_rdataset_t *sigrdataset)
719*00b67f09SDavid van Moolenbroek {
720*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
721*00b67f09SDavid van Moolenbroek 	REQUIRE(node != NULL);
722*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_RDATASET_VALID(rdataset));
723*00b67f09SDavid van Moolenbroek 	REQUIRE(! dns_rdataset_isassociated(rdataset));
724*00b67f09SDavid van Moolenbroek 	REQUIRE(covers == 0 || type == dns_rdatatype_rrsig);
725*00b67f09SDavid van Moolenbroek 	REQUIRE(type != dns_rdatatype_any);
726*00b67f09SDavid van Moolenbroek 	REQUIRE(sigrdataset == NULL ||
727*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(sigrdataset) &&
728*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(sigrdataset)));
729*00b67f09SDavid van Moolenbroek 
730*00b67f09SDavid van Moolenbroek 	return ((db->methods->findrdataset)(db, node, version, type,
731*00b67f09SDavid van Moolenbroek 					    covers, now, rdataset,
732*00b67f09SDavid van Moolenbroek 					    sigrdataset));
733*00b67f09SDavid van Moolenbroek }
734*00b67f09SDavid van Moolenbroek 
735*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_allrdatasets(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,isc_stdtime_t now,dns_rdatasetiter_t ** iteratorp)736*00b67f09SDavid van Moolenbroek dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
737*00b67f09SDavid van Moolenbroek 		    isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
738*00b67f09SDavid van Moolenbroek {
739*00b67f09SDavid van Moolenbroek 	/*
740*00b67f09SDavid van Moolenbroek 	 * Make '*iteratorp' an rdataset iteratator for all rdatasets at
741*00b67f09SDavid van Moolenbroek 	 * 'node' in version 'version' of 'db'.
742*00b67f09SDavid van Moolenbroek 	 */
743*00b67f09SDavid van Moolenbroek 
744*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
745*00b67f09SDavid van Moolenbroek 	REQUIRE(iteratorp != NULL && *iteratorp == NULL);
746*00b67f09SDavid van Moolenbroek 
747*00b67f09SDavid van Moolenbroek 	return ((db->methods->allrdatasets)(db, node, version, now,
748*00b67f09SDavid van Moolenbroek 					    iteratorp));
749*00b67f09SDavid van Moolenbroek }
750*00b67f09SDavid van Moolenbroek 
751*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_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)752*00b67f09SDavid van Moolenbroek dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
753*00b67f09SDavid van Moolenbroek 		   isc_stdtime_t now, dns_rdataset_t *rdataset,
754*00b67f09SDavid van Moolenbroek 		   unsigned int options, dns_rdataset_t *addedrdataset)
755*00b67f09SDavid van Moolenbroek {
756*00b67f09SDavid van Moolenbroek 	/*
757*00b67f09SDavid van Moolenbroek 	 * Add 'rdataset' to 'node' in version 'version' of 'db'.
758*00b67f09SDavid van Moolenbroek 	 */
759*00b67f09SDavid van Moolenbroek 
760*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
761*00b67f09SDavid van Moolenbroek 	REQUIRE(node != NULL);
762*00b67f09SDavid van Moolenbroek 	REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
763*00b67f09SDavid van Moolenbroek 		((db->attributes & DNS_DBATTR_CACHE) != 0 &&
764*00b67f09SDavid van Moolenbroek 		 version == NULL && (options & DNS_DBADD_MERGE) == 0));
765*00b67f09SDavid van Moolenbroek 	REQUIRE((options & DNS_DBADD_EXACT) == 0 ||
766*00b67f09SDavid van Moolenbroek 		(options & DNS_DBADD_MERGE) != 0);
767*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_RDATASET_VALID(rdataset));
768*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_rdataset_isassociated(rdataset));
769*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset->rdclass == db->rdclass);
770*00b67f09SDavid van Moolenbroek 	REQUIRE(addedrdataset == NULL ||
771*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(addedrdataset) &&
772*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(addedrdataset)));
773*00b67f09SDavid van Moolenbroek 
774*00b67f09SDavid van Moolenbroek 	return ((db->methods->addrdataset)(db, node, version, now, rdataset,
775*00b67f09SDavid van Moolenbroek 					   options, addedrdataset));
776*00b67f09SDavid van Moolenbroek }
777*00b67f09SDavid van Moolenbroek 
778*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_subtractrdataset(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdataset_t * rdataset,unsigned int options,dns_rdataset_t * newrdataset)779*00b67f09SDavid van Moolenbroek dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
780*00b67f09SDavid van Moolenbroek 			dns_dbversion_t *version, dns_rdataset_t *rdataset,
781*00b67f09SDavid van Moolenbroek 			unsigned int options, dns_rdataset_t *newrdataset)
782*00b67f09SDavid van Moolenbroek {
783*00b67f09SDavid van Moolenbroek 	/*
784*00b67f09SDavid van Moolenbroek 	 * Remove any rdata in 'rdataset' from 'node' in version 'version' of
785*00b67f09SDavid van Moolenbroek 	 * 'db'.
786*00b67f09SDavid van Moolenbroek 	 */
787*00b67f09SDavid van Moolenbroek 
788*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
789*00b67f09SDavid van Moolenbroek 	REQUIRE(node != NULL);
790*00b67f09SDavid van Moolenbroek 	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL);
791*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_RDATASET_VALID(rdataset));
792*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_rdataset_isassociated(rdataset));
793*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset->rdclass == db->rdclass);
794*00b67f09SDavid van Moolenbroek 	REQUIRE(newrdataset == NULL ||
795*00b67f09SDavid van Moolenbroek 		(DNS_RDATASET_VALID(newrdataset) &&
796*00b67f09SDavid van Moolenbroek 		 ! dns_rdataset_isassociated(newrdataset)));
797*00b67f09SDavid van Moolenbroek 
798*00b67f09SDavid van Moolenbroek 	return ((db->methods->subtractrdataset)(db, node, version, rdataset,
799*00b67f09SDavid van Moolenbroek 						options, newrdataset));
800*00b67f09SDavid van Moolenbroek }
801*00b67f09SDavid van Moolenbroek 
802*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_deleterdataset(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdatatype_t type,dns_rdatatype_t covers)803*00b67f09SDavid van Moolenbroek dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node,
804*00b67f09SDavid van Moolenbroek 		      dns_dbversion_t *version, dns_rdatatype_t type,
805*00b67f09SDavid van Moolenbroek 		      dns_rdatatype_t covers)
806*00b67f09SDavid van Moolenbroek {
807*00b67f09SDavid van Moolenbroek 	/*
808*00b67f09SDavid van Moolenbroek 	 * Make it so that no rdataset of type 'type' exists at 'node' in
809*00b67f09SDavid van Moolenbroek 	 * version version 'version' of 'db'.
810*00b67f09SDavid van Moolenbroek 	 */
811*00b67f09SDavid van Moolenbroek 
812*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
813*00b67f09SDavid van Moolenbroek 	REQUIRE(node != NULL);
814*00b67f09SDavid van Moolenbroek 	REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
815*00b67f09SDavid van Moolenbroek 		((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL));
816*00b67f09SDavid van Moolenbroek 
817*00b67f09SDavid van Moolenbroek 	return ((db->methods->deleterdataset)(db, node, version,
818*00b67f09SDavid van Moolenbroek 					      type, covers));
819*00b67f09SDavid van Moolenbroek }
820*00b67f09SDavid van Moolenbroek 
821*00b67f09SDavid van Moolenbroek void
dns_db_overmem(dns_db_t * db,isc_boolean_t overmem)822*00b67f09SDavid van Moolenbroek dns_db_overmem(dns_db_t *db, isc_boolean_t overmem) {
823*00b67f09SDavid van Moolenbroek 
824*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
825*00b67f09SDavid van Moolenbroek 
826*00b67f09SDavid van Moolenbroek 	(db->methods->overmem)(db, overmem);
827*00b67f09SDavid van Moolenbroek }
828*00b67f09SDavid van Moolenbroek 
829*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_getsoaserial(dns_db_t * db,dns_dbversion_t * ver,isc_uint32_t * serialp)830*00b67f09SDavid van Moolenbroek dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
831*00b67f09SDavid van Moolenbroek {
832*00b67f09SDavid van Moolenbroek 	isc_result_t result;
833*00b67f09SDavid van Moolenbroek 	dns_dbnode_t *node = NULL;
834*00b67f09SDavid van Moolenbroek 	dns_rdataset_t rdataset;
835*00b67f09SDavid van Moolenbroek 	dns_rdata_t rdata = DNS_RDATA_INIT;
836*00b67f09SDavid van Moolenbroek 	isc_buffer_t buffer;
837*00b67f09SDavid van Moolenbroek 
838*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_db_iszone(db) || dns_db_isstub(db));
839*00b67f09SDavid van Moolenbroek 
840*00b67f09SDavid van Moolenbroek 	result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
841*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
842*00b67f09SDavid van Moolenbroek 		return (result);
843*00b67f09SDavid van Moolenbroek 
844*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&rdataset);
845*00b67f09SDavid van Moolenbroek 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
846*00b67f09SDavid van Moolenbroek 				     (isc_stdtime_t)0, &rdataset, NULL);
847*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
848*00b67f09SDavid van Moolenbroek 		goto freenode;
849*00b67f09SDavid van Moolenbroek 
850*00b67f09SDavid van Moolenbroek 	result = dns_rdataset_first(&rdataset);
851*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
852*00b67f09SDavid van Moolenbroek 		goto freerdataset;
853*00b67f09SDavid van Moolenbroek 	dns_rdataset_current(&rdataset, &rdata);
854*00b67f09SDavid van Moolenbroek 	result = dns_rdataset_next(&rdataset);
855*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_NOMORE);
856*00b67f09SDavid van Moolenbroek 
857*00b67f09SDavid van Moolenbroek 	INSIST(rdata.length > 20);
858*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&buffer, rdata.data, rdata.length);
859*00b67f09SDavid van Moolenbroek 	isc_buffer_add(&buffer, rdata.length);
860*00b67f09SDavid van Moolenbroek 	isc_buffer_forward(&buffer, rdata.length - 20);
861*00b67f09SDavid van Moolenbroek 	*serialp = isc_buffer_getuint32(&buffer);
862*00b67f09SDavid van Moolenbroek 
863*00b67f09SDavid van Moolenbroek 	result = ISC_R_SUCCESS;
864*00b67f09SDavid van Moolenbroek 
865*00b67f09SDavid van Moolenbroek  freerdataset:
866*00b67f09SDavid van Moolenbroek 	dns_rdataset_disassociate(&rdataset);
867*00b67f09SDavid van Moolenbroek 
868*00b67f09SDavid van Moolenbroek  freenode:
869*00b67f09SDavid van Moolenbroek 	dns_db_detachnode(db, &node);
870*00b67f09SDavid van Moolenbroek 	return (result);
871*00b67f09SDavid van Moolenbroek }
872*00b67f09SDavid van Moolenbroek 
873*00b67f09SDavid van Moolenbroek unsigned int
dns_db_nodecount(dns_db_t * db)874*00b67f09SDavid van Moolenbroek dns_db_nodecount(dns_db_t *db) {
875*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
876*00b67f09SDavid van Moolenbroek 
877*00b67f09SDavid van Moolenbroek 	return ((db->methods->nodecount)(db));
878*00b67f09SDavid van Moolenbroek }
879*00b67f09SDavid van Moolenbroek 
880*00b67f09SDavid van Moolenbroek unsigned int
dns_db_hashsize(dns_db_t * db)881*00b67f09SDavid van Moolenbroek dns_db_hashsize(dns_db_t *db) {
882*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
883*00b67f09SDavid van Moolenbroek 
884*00b67f09SDavid van Moolenbroek 	if (db->methods->hashsize == NULL)
885*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
886*00b67f09SDavid van Moolenbroek 
887*00b67f09SDavid van Moolenbroek 	return ((db->methods->hashsize)(db));
888*00b67f09SDavid van Moolenbroek }
889*00b67f09SDavid van Moolenbroek 
890*00b67f09SDavid van Moolenbroek void
dns_db_settask(dns_db_t * db,isc_task_t * task)891*00b67f09SDavid van Moolenbroek dns_db_settask(dns_db_t *db, isc_task_t *task) {
892*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
893*00b67f09SDavid van Moolenbroek 
894*00b67f09SDavid van Moolenbroek 	(db->methods->settask)(db, task);
895*00b67f09SDavid van Moolenbroek }
896*00b67f09SDavid van Moolenbroek 
897*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_register(const char * name,dns_dbcreatefunc_t create,void * driverarg,isc_mem_t * mctx,dns_dbimplementation_t ** dbimp)898*00b67f09SDavid van Moolenbroek dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg,
899*00b67f09SDavid van Moolenbroek 		isc_mem_t *mctx, dns_dbimplementation_t **dbimp)
900*00b67f09SDavid van Moolenbroek {
901*00b67f09SDavid van Moolenbroek 	dns_dbimplementation_t *imp;
902*00b67f09SDavid van Moolenbroek 
903*00b67f09SDavid van Moolenbroek 	REQUIRE(name != NULL);
904*00b67f09SDavid van Moolenbroek 	REQUIRE(dbimp != NULL && *dbimp == NULL);
905*00b67f09SDavid van Moolenbroek 
906*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
907*00b67f09SDavid van Moolenbroek 
908*00b67f09SDavid van Moolenbroek 	RWLOCK(&implock, isc_rwlocktype_write);
909*00b67f09SDavid van Moolenbroek 	imp = impfind(name);
910*00b67f09SDavid van Moolenbroek 	if (imp != NULL) {
911*00b67f09SDavid van Moolenbroek 		RWUNLOCK(&implock, isc_rwlocktype_write);
912*00b67f09SDavid van Moolenbroek 		return (ISC_R_EXISTS);
913*00b67f09SDavid van Moolenbroek 	}
914*00b67f09SDavid van Moolenbroek 
915*00b67f09SDavid van Moolenbroek 	imp = isc_mem_get(mctx, sizeof(dns_dbimplementation_t));
916*00b67f09SDavid van Moolenbroek 	if (imp == NULL) {
917*00b67f09SDavid van Moolenbroek 		RWUNLOCK(&implock, isc_rwlocktype_write);
918*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
919*00b67f09SDavid van Moolenbroek 	}
920*00b67f09SDavid van Moolenbroek 	imp->name = name;
921*00b67f09SDavid van Moolenbroek 	imp->create = create;
922*00b67f09SDavid van Moolenbroek 	imp->mctx = NULL;
923*00b67f09SDavid van Moolenbroek 	imp->driverarg = driverarg;
924*00b67f09SDavid van Moolenbroek 	isc_mem_attach(mctx, &imp->mctx);
925*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(imp, link);
926*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(implementations, imp, link);
927*00b67f09SDavid van Moolenbroek 	RWUNLOCK(&implock, isc_rwlocktype_write);
928*00b67f09SDavid van Moolenbroek 
929*00b67f09SDavid van Moolenbroek 	*dbimp = imp;
930*00b67f09SDavid van Moolenbroek 
931*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
932*00b67f09SDavid van Moolenbroek }
933*00b67f09SDavid van Moolenbroek 
934*00b67f09SDavid van Moolenbroek void
dns_db_unregister(dns_dbimplementation_t ** dbimp)935*00b67f09SDavid van Moolenbroek dns_db_unregister(dns_dbimplementation_t **dbimp) {
936*00b67f09SDavid van Moolenbroek 	dns_dbimplementation_t *imp;
937*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx;
938*00b67f09SDavid van Moolenbroek 
939*00b67f09SDavid van Moolenbroek 	REQUIRE(dbimp != NULL && *dbimp != NULL);
940*00b67f09SDavid van Moolenbroek 
941*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
942*00b67f09SDavid van Moolenbroek 
943*00b67f09SDavid van Moolenbroek 	imp = *dbimp;
944*00b67f09SDavid van Moolenbroek 	*dbimp = NULL;
945*00b67f09SDavid van Moolenbroek 	RWLOCK(&implock, isc_rwlocktype_write);
946*00b67f09SDavid van Moolenbroek 	ISC_LIST_UNLINK(implementations, imp, link);
947*00b67f09SDavid van Moolenbroek 	mctx = imp->mctx;
948*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t));
949*00b67f09SDavid van Moolenbroek 	isc_mem_detach(&mctx);
950*00b67f09SDavid van Moolenbroek 	RWUNLOCK(&implock, isc_rwlocktype_write);
951*00b67f09SDavid van Moolenbroek 	ENSURE(*dbimp == NULL);
952*00b67f09SDavid van Moolenbroek }
953*00b67f09SDavid van Moolenbroek 
954*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_getoriginnode(dns_db_t * db,dns_dbnode_t ** nodep)955*00b67f09SDavid van Moolenbroek dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
956*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
957*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_db_iszone(db) == ISC_TRUE);
958*00b67f09SDavid van Moolenbroek 	REQUIRE(nodep != NULL && *nodep == NULL);
959*00b67f09SDavid van Moolenbroek 
960*00b67f09SDavid van Moolenbroek 	if (db->methods->getoriginnode != NULL)
961*00b67f09SDavid van Moolenbroek 		return ((db->methods->getoriginnode)(db, nodep));
962*00b67f09SDavid van Moolenbroek 
963*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTFOUND);
964*00b67f09SDavid van Moolenbroek }
965*00b67f09SDavid van Moolenbroek 
966*00b67f09SDavid van Moolenbroek dns_stats_t *
dns_db_getrrsetstats(dns_db_t * db)967*00b67f09SDavid van Moolenbroek dns_db_getrrsetstats(dns_db_t *db) {
968*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
969*00b67f09SDavid van Moolenbroek 
970*00b67f09SDavid van Moolenbroek 	if (db->methods->getrrsetstats != NULL)
971*00b67f09SDavid van Moolenbroek 		return ((db->methods->getrrsetstats)(db));
972*00b67f09SDavid van Moolenbroek 
973*00b67f09SDavid van Moolenbroek 	return (NULL);
974*00b67f09SDavid van Moolenbroek }
975*00b67f09SDavid van Moolenbroek 
976*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_setcachestats(dns_db_t * db,isc_stats_t * stats)977*00b67f09SDavid van Moolenbroek dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats) {
978*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
979*00b67f09SDavid van Moolenbroek 
980*00b67f09SDavid van Moolenbroek 	if (db->methods->setcachestats != NULL)
981*00b67f09SDavid van Moolenbroek 		return ((db->methods->setcachestats)(db, stats));
982*00b67f09SDavid van Moolenbroek 
983*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTIMPLEMENTED);
984*00b67f09SDavid van Moolenbroek }
985*00b67f09SDavid van Moolenbroek 
986*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_getnsec3parameters(dns_db_t * db,dns_dbversion_t * version,dns_hash_t * hash,isc_uint8_t * flags,isc_uint16_t * iterations,unsigned char * salt,size_t * salt_length)987*00b67f09SDavid van Moolenbroek dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
988*00b67f09SDavid van Moolenbroek 			  dns_hash_t *hash, isc_uint8_t *flags,
989*00b67f09SDavid van Moolenbroek 			  isc_uint16_t *iterations,
990*00b67f09SDavid van Moolenbroek 			  unsigned char *salt, size_t *salt_length)
991*00b67f09SDavid van Moolenbroek {
992*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_DB_VALID(db));
993*00b67f09SDavid van Moolenbroek 	REQUIRE(dns_db_iszone(db) == ISC_TRUE);
994*00b67f09SDavid van Moolenbroek 
995*00b67f09SDavid van Moolenbroek 	if (db->methods->getnsec3parameters != NULL)
996*00b67f09SDavid van Moolenbroek 		return ((db->methods->getnsec3parameters)(db, version, hash,
997*00b67f09SDavid van Moolenbroek 							  flags, iterations,
998*00b67f09SDavid van Moolenbroek 							  salt, salt_length));
999*00b67f09SDavid van Moolenbroek 
1000*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTFOUND);
1001*00b67f09SDavid van Moolenbroek }
1002*00b67f09SDavid van Moolenbroek 
1003*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_setsigningtime(dns_db_t * db,dns_rdataset_t * rdataset,isc_stdtime_t resign)1004*00b67f09SDavid van Moolenbroek dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
1005*00b67f09SDavid van Moolenbroek 		      isc_stdtime_t resign)
1006*00b67f09SDavid van Moolenbroek {
1007*00b67f09SDavid van Moolenbroek 	if (db->methods->setsigningtime != NULL)
1008*00b67f09SDavid van Moolenbroek 		return ((db->methods->setsigningtime)(db, rdataset, resign));
1009*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTIMPLEMENTED);
1010*00b67f09SDavid van Moolenbroek }
1011*00b67f09SDavid van Moolenbroek 
1012*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_getsigningtime(dns_db_t * db,dns_rdataset_t * rdataset,dns_name_t * name)1013*00b67f09SDavid van Moolenbroek dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name)
1014*00b67f09SDavid van Moolenbroek {
1015*00b67f09SDavid van Moolenbroek 	if (db->methods->getsigningtime != NULL)
1016*00b67f09SDavid van Moolenbroek 		return ((db->methods->getsigningtime)(db, rdataset, name));
1017*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTFOUND);
1018*00b67f09SDavid van Moolenbroek }
1019*00b67f09SDavid van Moolenbroek 
1020*00b67f09SDavid van Moolenbroek void
dns_db_resigned(dns_db_t * db,dns_rdataset_t * rdataset,dns_dbversion_t * version)1021*00b67f09SDavid van Moolenbroek dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
1022*00b67f09SDavid van Moolenbroek 		dns_dbversion_t *version)
1023*00b67f09SDavid van Moolenbroek {
1024*00b67f09SDavid van Moolenbroek 	if (db->methods->resigned != NULL)
1025*00b67f09SDavid van Moolenbroek 		(db->methods->resigned)(db, rdataset, version);
1026*00b67f09SDavid van Moolenbroek }
1027*00b67f09SDavid van Moolenbroek 
1028*00b67f09SDavid van Moolenbroek /*
1029*00b67f09SDavid van Moolenbroek  * Attach a database to policy zone databases.
1030*00b67f09SDavid van Moolenbroek  * This should only happen when the caller has already ensured that
1031*00b67f09SDavid van Moolenbroek  * it is dealing with a database that understands response policy zones.
1032*00b67f09SDavid van Moolenbroek  */
1033*00b67f09SDavid van Moolenbroek void
dns_db_rpz_attach(dns_db_t * db,dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num)1034*00b67f09SDavid van Moolenbroek dns_db_rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) {
1035*00b67f09SDavid van Moolenbroek 	REQUIRE(db->methods->rpz_attach != NULL);
1036*00b67f09SDavid van Moolenbroek 	(db->methods->rpz_attach)(db, rpzs, rpz_num);
1037*00b67f09SDavid van Moolenbroek }
1038*00b67f09SDavid van Moolenbroek 
1039*00b67f09SDavid van Moolenbroek /*
1040*00b67f09SDavid van Moolenbroek  * Finish loading a response policy zone.
1041*00b67f09SDavid van Moolenbroek  */
1042*00b67f09SDavid van Moolenbroek isc_result_t
dns_db_rpz_ready(dns_db_t * db)1043*00b67f09SDavid van Moolenbroek dns_db_rpz_ready(dns_db_t *db) {
1044*00b67f09SDavid van Moolenbroek 	if (db->methods->rpz_ready == NULL)
1045*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
1046*00b67f09SDavid van Moolenbroek 	return ((db->methods->rpz_ready)(db));
1047*00b67f09SDavid van Moolenbroek }
1048