db.c 14.6 KB
Newer Older
Bob Halley's avatar
Bob Halley committed
1
/*
Bob Halley's avatar
Bob Halley committed
2
 * Copyright (C) 1999, 2000  Internet Software Consortium.
Bob Halley's avatar
Bob Halley committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

18 19 20 21
/***
 *** Imports
 ***/

Bob Halley's avatar
Bob Halley committed
22 23
#include <config.h>

24
#include <isc/buffer.h>
25
#include <isc/string.h>
Bob Halley's avatar
Bob Halley committed
26
#include <isc/util.h>
Bob Halley's avatar
Bob Halley committed
27

28
#include <dns/callbacks.h>
Bob Halley's avatar
Bob Halley committed
29
#include <dns/master.h>
30
#include <dns/rdata.h>
31 32 33 34 35 36 37
#include <dns/rdataset.h>

/***
 *** Private Types
 ***/

typedef struct {
David Lawrence's avatar
David Lawrence committed
38
	const char *		name;	
39
	isc_result_t		(*create)(isc_mem_t *mctx, dns_name_t *name,
40
					  isc_boolean_t cache,
41
					  dns_rdataclass_t rdclass,
42 43 44 45 46 47 48 49 50 51 52 53 54
					  unsigned int argc, char *argv[],
					  dns_db_t **dbp);
} impinfo_t;

/***
 *** Supported DB Implementations Registry
 ***/

/*
 * Supported database implementations must be registered here.
 *
 * It might be nice to generate this automatically some day.
 */
Bob Halley's avatar
Bob Halley committed
55 56

#include "rbtdb.h"
57
#include "rbtdb64.h"
Bob Halley's avatar
Bob Halley committed
58

59
static impinfo_t implementations[] = {
60
	{ "rbt", dns_rbtdb_create },
61
	{ "rbt64", dns_rbtdb64_create },
62 63 64 65 66 67 68
	{ NULL, NULL }
};

/***
 *** Basic DB Methods
 ***/

69
isc_result_t
David Lawrence's avatar
David Lawrence committed
70
dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin,
71
	      isc_boolean_t cache, dns_rdataclass_t rdclass,
Bob Halley's avatar
Bob Halley committed
72 73
	      unsigned int argc, char *argv[], dns_db_t **dbp)
{
74 75 76 77 78 79 80 81
	impinfo_t *impinfo;

	/*
	 * Create a new database using implementation 'db_type'.
	 */

	REQUIRE(dbp != NULL && *dbp == NULL);
	REQUIRE(dns_name_isabsolute(origin));
Bob Halley's avatar
Bob Halley committed
82

83 84
	for (impinfo = implementations; impinfo->name != NULL; impinfo++)
		if (strcasecmp(db_type, impinfo->name) == 0)
85
			return ((impinfo->create)(mctx, origin, cache, rdclass,
86
						  argc, argv, dbp));
Bob Halley's avatar
Bob Halley committed
87

88
	return (ISC_R_NOTFOUND);
Bob Halley's avatar
Bob Halley committed
89 90 91 92 93
}

void
dns_db_attach(dns_db_t *source, dns_db_t **targetp) {

94 95 96 97
	/*
	 * Attach *targetp to source.
	 */

Bob Halley's avatar
Bob Halley committed
98 99 100 101
	REQUIRE(DNS_DB_VALID(source));
	REQUIRE(targetp != NULL);

	(source->methods->attach)(source, targetp);
102 103

	ENSURE(*targetp == source);
Bob Halley's avatar
Bob Halley committed
104 105 106 107 108 109
}

void
dns_db_detach(dns_db_t **dbp) {

	/*
110
	 * Detach *dbp from its database.
Bob Halley's avatar
Bob Halley committed
111 112 113 114 115 116
	 */

	REQUIRE(dbp != NULL);
	REQUIRE(DNS_DB_VALID(*dbp));

	((*dbp)->methods->detach)(dbp);
117 118

	ENSURE(*dbp == NULL);
Bob Halley's avatar
Bob Halley committed
119 120
}

121 122 123 124 125 126 127 128 129
isc_result_t
dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp)
{
	REQUIRE(DNS_DB_VALID(db));

	return (isc_ondestroy_register(&db->ondest, task, eventp));
}


Bob Halley's avatar
Bob Halley committed
130 131
isc_boolean_t
dns_db_iscache(dns_db_t *db) {
132 133 134 135

	/*
	 * Does 'db' have cache semantics?
	 */
Bob Halley's avatar
Bob Halley committed
136 137 138
	
	REQUIRE(DNS_DB_VALID(db));

139 140 141 142
	if ((db->attributes & DNS_DBATTR_CACHE) != 0)
		return (ISC_TRUE);

	return (ISC_FALSE);
Bob Halley's avatar
Bob Halley committed
143 144 145 146
}

isc_boolean_t
dns_db_iszone(dns_db_t *db) {
147 148 149 150

	/*
	 * Does 'db' have zone semantics?
	 */
Bob Halley's avatar
Bob Halley committed
151 152 153
	
	REQUIRE(DNS_DB_VALID(db));

154 155 156 157
	if ((db->attributes & DNS_DBATTR_CACHE) == 0)
		return (ISC_TRUE);

	return (ISC_FALSE);
Bob Halley's avatar
Bob Halley committed
158 159
}

Bob Halley's avatar
Bob Halley committed
160 161 162 163 164 165 166 167 168 169 170 171 172
isc_boolean_t
dns_db_issecure(dns_db_t *db) {

	/*
	 * Is 'db' secure?
	 */
	
	REQUIRE(DNS_DB_VALID(db));
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);

	return ((db->methods->issecure)(db));
}

Bob Halley's avatar
Bob Halley committed
173 174
dns_name_t *
dns_db_origin(dns_db_t *db) {
175 176 177 178
	/*
	 * The origin of the database.
	 */

Bob Halley's avatar
Bob Halley committed
179 180
	REQUIRE(DNS_DB_VALID(db));

181
	return (&db->origin);
Bob Halley's avatar
Bob Halley committed
182 183
}

Bob Halley's avatar
Bob Halley committed
184 185 186 187 188 189 190 191 192 193 194
dns_rdataclass_t
dns_db_class(dns_db_t *db) {
	/*
	 * The class of the database.
	 */

	REQUIRE(DNS_DB_VALID(db));

	return (db->rdclass);
}

195
isc_result_t
Bob Halley's avatar
Bob Halley committed
196 197 198 199 200 201 202 203 204 205 206 207 208
dns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp,
		 dns_dbload_t **dbloadp) {
	/*
	 * Begin loading 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(addp != NULL && *addp == NULL);
	REQUIRE(dbloadp != NULL && *dbloadp == NULL);

	return ((db->methods->beginload)(db, addp, dbloadp));
}

209
isc_result_t
Bob Halley's avatar
Bob Halley committed
210 211 212 213 214 215 216 217 218 219 220
dns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp) {
	/*
	 * Finish loading 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(dbloadp != NULL && *dbloadp != NULL);

	return ((db->methods->endload)(db, dbloadp));
}

221
isc_result_t
Bob Halley's avatar
Bob Halley committed
222
dns_db_load(dns_db_t *db, const char *filename) {
223
	isc_result_t result, eresult;
Bob Halley's avatar
Bob Halley committed
224 225 226 227
	int soacount, nscount;
	dns_rdatacallbacks_t callbacks;
	isc_boolean_t age_ttl = ISC_FALSE;

228 229 230
	/*
	 * Load master file 'filename' into 'db'.
	 */
Bob Halley's avatar
Bob Halley committed
231 232 233

	REQUIRE(DNS_DB_VALID(db));

Bob Halley's avatar
Bob Halley committed
234 235 236 237 238 239
	if ((db->attributes & DNS_DBATTR_CACHE) != 0)
		age_ttl = ISC_TRUE;

	dns_rdatacallbacks_init(&callbacks);

	result = dns_db_beginload(db, &callbacks.add, &callbacks.add_private);
240
	if (result != ISC_R_SUCCESS)
Bob Halley's avatar
Bob Halley committed
241
		return (result);
242 243 244
	result = dns_master_loadfile(filename, &db->origin, &db->origin,
				     db->rdclass, age_ttl, &soacount, &nscount,
				     &callbacks, db->mctx);
Bob Halley's avatar
Bob Halley committed
245 246 247
	eresult = dns_db_endload(db, &callbacks.add_private);
	/*
	 * We always call dns_db_endload(), but we only want to return its
248
	 * result if dns_master_loadfile() succeeded.  If dns_master_loadfile()
Bob Halley's avatar
Bob Halley committed
249 250 251 252 253 254
	 * failed, we want to return the result code it gave us.
	 */
	if (result == ISC_R_SUCCESS)
		result = eresult;

	return (result);
Bob Halley's avatar
Bob Halley committed
255 256
}

257
isc_result_t
Bob Halley's avatar
Bob Halley committed
258
dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) {
259 260 261 262 263 264
	/*
	 * Dump 'db' into master file 'filename'.
	 */

	REQUIRE(DNS_DB_VALID(db));

Bob Halley's avatar
Bob Halley committed
265
	return ((db->methods->dump)(db, version, filename));
266 267
}

268 269 270
/***
 *** Version Methods
 ***/
Bob Halley's avatar
Bob Halley committed
271 272 273 274

void
dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
	
275 276 277 278
	/*
	 * Open the current version for reading.
	 */
	
Bob Halley's avatar
Bob Halley committed
279
	REQUIRE(DNS_DB_VALID(db));
280
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
281
	REQUIRE(versionp != NULL && *versionp == NULL);
Bob Halley's avatar
Bob Halley committed
282 283 284 285

	(db->methods->currentversion)(db, versionp);
}

286
isc_result_t
Bob Halley's avatar
Bob Halley committed
287 288
dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) {
	
289 290 291 292
	/*
	 * Open a new version for reading and writing.
	 */

Bob Halley's avatar
Bob Halley committed
293
	REQUIRE(DNS_DB_VALID(db));
294
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
295
	REQUIRE(versionp != NULL && *versionp == NULL);
Bob Halley's avatar
Bob Halley committed
296 297 298 299

	return ((db->methods->newversion)(db, versionp));
}

Bob Halley's avatar
Bob Halley committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
void
dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source,
		     dns_dbversion_t **targetp)
{
	/*
	 * Attach '*targetp' to 'source'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
	REQUIRE(source != NULL);
	REQUIRE(targetp != NULL && *targetp != NULL);

	(db->methods->attachversion)(db, source, targetp);

	ENSURE(*targetp != NULL);
}	

Bob Halley's avatar
Bob Halley committed
318
void
319 320 321
dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
		    isc_boolean_t commit)
{
Bob Halley's avatar
Bob Halley committed
322
	
323 324 325 326
	/*
	 * Close version '*versionp'.
	 */

Bob Halley's avatar
Bob Halley committed
327
	REQUIRE(DNS_DB_VALID(db));
328
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
329 330 331
	REQUIRE(versionp != NULL && *versionp != NULL);

	(db->methods->closeversion)(db, versionp, commit);
Bob Halley's avatar
Bob Halley committed
332

333
	ENSURE(*versionp == NULL);
Bob Halley's avatar
Bob Halley committed
334 335
}

336 337 338
/***
 *** Node Methods
 ***/
Bob Halley's avatar
Bob Halley committed
339

340
isc_result_t
Bob Halley's avatar
Bob Halley committed
341 342 343
dns_db_findnode(dns_db_t *db, dns_name_t *name,
		isc_boolean_t create, dns_dbnode_t **nodep)
{
344 345 346 347 348

	/*
	 * Find the node with name 'name'.
	 */

Bob Halley's avatar
Bob Halley committed
349
	REQUIRE(DNS_DB_VALID(db));
350 351
	REQUIRE(dns_name_issubdomain(name, &db->origin));
	REQUIRE(nodep != NULL && *nodep == NULL);
Bob Halley's avatar
Bob Halley committed
352 353 354 355

	return ((db->methods->findnode)(db, name, create, nodep));
}

356
isc_result_t
Bob Halley's avatar
Bob Halley committed
357
dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
358
	    dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
Bob Halley's avatar
Bob Halley committed
359
	    dns_dbnode_t **nodep, dns_name_t *foundname,
Bob Halley's avatar
Bob Halley committed
360
	    dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
Bob Halley's avatar
lint  
Bob Halley committed
361
{
Bob Halley's avatar
Bob Halley committed
362

363 364 365 366 367 368 369 370
	/*
	 * Find the best match for 'name' and 'type' in version 'version'
	 * of 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(type != dns_rdatatype_sig);
	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
371
	REQUIRE(dns_name_hasbuffer(foundname));
372
	REQUIRE(rdataset == NULL ||
373 374
		(DNS_RDATASET_VALID(rdataset) &&
		 ! dns_rdataset_isassociated(rdataset)));
Bob Halley's avatar
Bob Halley committed
375 376
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
377
		 ! dns_rdataset_isassociated(sigrdataset)));
378

379
	return ((db->methods->find)(db, name, version, type, options, now,
Bob Halley's avatar
Bob Halley committed
380
				    nodep, foundname, rdataset, sigrdataset));
Bob Halley's avatar
Bob Halley committed
381 382
}

383
isc_result_t
Bob Halley's avatar
Bob Halley committed
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
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)
{
	/*
	 * Find the deepest known zonecut which encloses 'name' in 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
	REQUIRE(dns_name_hasbuffer(foundname));
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
399
		 ! dns_rdataset_isassociated(sigrdataset)));
Bob Halley's avatar
Bob Halley committed
400 401 402 403 404

	return ((db->methods->findzonecut)(db, name, options, now, nodep,
					   foundname, rdataset, sigrdataset));
}

Bob Halley's avatar
Bob Halley committed
405 406 407
void
dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {

408 409 410 411
	/*
	 * Attach *targetp to source.
	 */

Bob Halley's avatar
Bob Halley committed
412
	REQUIRE(DNS_DB_VALID(db));
413 414
	REQUIRE(source != NULL);
	REQUIRE(targetp != NULL && *targetp == NULL);
Bob Halley's avatar
Bob Halley committed
415 416 417 418 419 420 421

	(db->methods->attachnode)(db, source, targetp);
}

void
dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) {

422 423 424 425
	/*
	 * Detach *nodep from its node.
	 */

Bob Halley's avatar
Bob Halley committed
426
	REQUIRE(DNS_DB_VALID(db));
427
	REQUIRE(nodep != NULL && *nodep != NULL);
Bob Halley's avatar
Bob Halley committed
428 429

	(db->methods->detachnode)(db, nodep);
430 431

	ENSURE(*nodep == NULL);
Bob Halley's avatar
Bob Halley committed
432 433
}

434
isc_result_t
Bob Halley's avatar
Bob Halley committed
435 436 437 438 439 440 441 442 443 444 445 446 447
dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {

	/*
	 * Mark as stale all records at 'node' which expire at or before 'now'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
	REQUIRE(node != NULL);

	return ((db->methods->expirenode)(db, node, now));
}

Bob Halley's avatar
Bob Halley committed
448 449 450 451 452 453 454 455 456 457 458 459 460
void
dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
	/*
	 * Print a textual representation of the contents of the node to
	 * 'out'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(node != NULL);

	(db->methods->printnode)(db, node, out);
}

Bob Halley's avatar
Bob Halley committed
461 462 463 464
/***
 *** DB Iterator Creation
 ***/

465
isc_result_t
466
dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
Bob Halley's avatar
Bob Halley committed
467 468 469 470 471 472 473 474 475
		      dns_dbiterator_t **iteratorp)
{
	/*
	 * Create an iterator for version 'version' of 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(iteratorp != NULL && *iteratorp == NULL);

476
	return (db->methods->createiterator(db, relative_names, iteratorp));
Bob Halley's avatar
Bob Halley committed
477 478
}

479 480 481 482
/***
 *** Rdataset Methods
 ***/

483
isc_result_t
Bob Halley's avatar
Bob Halley committed
484
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
Bob Halley's avatar
Bob Halley committed
485
		    dns_rdatatype_t type, dns_rdatatype_t covers,
Bob Halley's avatar
Bob Halley committed
486 487
		    isc_stdtime_t now, dns_rdataset_t *rdataset,
		    dns_rdataset_t *sigrdataset)
Bob Halley's avatar
Bob Halley committed
488
{
489 490 491 492
	/*
	 * Search for an rdataset of type 'type' at 'node' that are in version
	 * 'version' of 'db'.  If found, make 'rdataset' refer to it.
	 */
Bob Halley's avatar
Bob Halley committed
493 494

	REQUIRE(DNS_DB_VALID(db));
495 496
	REQUIRE(node != NULL);
	REQUIRE(DNS_RDATASET_VALID(rdataset));
497
	REQUIRE(! dns_rdataset_isassociated(rdataset));
Bob Halley's avatar
Bob Halley committed
498 499
	REQUIRE(covers == 0 || type == dns_rdatatype_sig);
	REQUIRE(type != dns_rdatatype_any);
Bob Halley's avatar
Bob Halley committed
500 501
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
502
		 ! dns_rdataset_isassociated(sigrdataset)));
Bob Halley's avatar
Bob Halley committed
503

Bob Halley's avatar
Bob Halley committed
504
	return ((db->methods->findrdataset)(db, node, version, type, covers,
Bob Halley's avatar
Bob Halley committed
505
					    now, rdataset, sigrdataset));
Bob Halley's avatar
Bob Halley committed
506 507
}

508
isc_result_t
Bob Halley's avatar
Bob Halley committed
509
dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
510
		    isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
Bob Halley's avatar
Bob Halley committed
511 512 513 514 515 516 517 518 519
{
	/*
	 * Make '*iteratorp' an rdataset iteratator for all rdatasets at
	 * 'node' in version 'version' of 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(iteratorp != NULL && *iteratorp == NULL);

520 521
	return ((db->methods->allrdatasets)(db, node, version, now,
					    iteratorp));
Bob Halley's avatar
Bob Halley committed
522 523
}

524
isc_result_t
Bob Halley's avatar
Bob Halley committed
525
dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
526
		   isc_stdtime_t now, dns_rdataset_t *rdataset,
Bob Halley's avatar
Bob Halley committed
527
		   unsigned int options, dns_rdataset_t *addedrdataset)
Bob Halley's avatar
Bob Halley committed
528
{
529 530 531 532
	/*
	 * Add 'rdataset' to 'node' in version 'version' of 'db'.
	 */

Bob Halley's avatar
Bob Halley committed
533
	REQUIRE(DNS_DB_VALID(db));
534
	REQUIRE(node != NULL);
535
	REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
Bob Halley's avatar
Bob Halley committed
536
		((db->attributes & DNS_DBATTR_CACHE) != 0 &&
Bob Halley's avatar
Bob Halley committed
537
		 version == NULL && (options & DNS_DBADD_MERGE) == 0));
538
	REQUIRE(DNS_RDATASET_VALID(rdataset));
539
	REQUIRE(dns_rdataset_isassociated(rdataset));
540
	REQUIRE(rdataset->rdclass == db->rdclass);
541 542
	REQUIRE(addedrdataset == NULL ||
		(DNS_RDATASET_VALID(addedrdataset) &&
543
		 ! dns_rdataset_isassociated(addedrdataset)));
Bob Halley's avatar
Bob Halley committed
544

545
	return ((db->methods->addrdataset)(db, node, version, now, rdataset,
Bob Halley's avatar
Bob Halley committed
546
					   options, addedrdataset));
Bob Halley's avatar
Bob Halley committed
547 548
}

549
isc_result_t
Bob Halley's avatar
Bob Halley committed
550 551 552 553 554 555 556 557 558 559 560
dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
			dns_dbversion_t *version, dns_rdataset_t *rdataset,
			dns_rdataset_t *newrdataset)
{
	/*
	 * Remove any rdata in 'rdataset' from 'node' in version 'version' of
	 * 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(node != NULL);
Bob Halley's avatar
lint  
Bob Halley committed
561
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL);
Bob Halley's avatar
Bob Halley committed
562
	REQUIRE(DNS_RDATASET_VALID(rdataset));
563
	REQUIRE(dns_rdataset_isassociated(rdataset));
Bob Halley's avatar
Bob Halley committed
564 565 566
	REQUIRE(rdataset->rdclass == db->rdclass);
	REQUIRE(newrdataset == NULL ||
		(DNS_RDATASET_VALID(newrdataset) &&
567
		 ! dns_rdataset_isassociated(newrdataset)));
Bob Halley's avatar
Bob Halley committed
568 569 570

	return ((db->methods->subtractrdataset)(db, node, version, rdataset,
						newrdataset));
Bob Halley's avatar
Bob Halley committed
571 572
}

573
isc_result_t
Bob Halley's avatar
Bob Halley committed
574
dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node,
575 576
		      dns_dbversion_t *version, dns_rdatatype_t type,
		      dns_rdatatype_t covers)
Bob Halley's avatar
Bob Halley committed
577
{
578 579 580 581 582
	/*
	 * Make it so that no rdataset of type 'type' exists at 'node' in
	 * version version 'version' of 'db'.
	 */

Bob Halley's avatar
Bob Halley committed
583
	REQUIRE(DNS_DB_VALID(db));
584
	REQUIRE(node != NULL);
585 586
	REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
		((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL));
Bob Halley's avatar
Bob Halley committed
587

588 589
	return ((db->methods->deleterdataset)(db, node, version,
					      type, covers));
Bob Halley's avatar
Bob Halley committed
590
}
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632

isc_result_t
dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
{
	isc_result_t result;
	dns_dbnode_t *node = NULL;
	dns_rdataset_t rdataset;
	dns_rdata_t rdata;
	isc_buffer_t buffer;

	REQUIRE(dns_db_iszone(db));
		
	result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
	if (result != ISC_R_SUCCESS)
		return (result);

	dns_rdataset_init(&rdataset);
	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
				     (isc_stdtime_t)0, &rdataset, NULL);
 	if (result != ISC_R_SUCCESS)
		goto freenode;
	
	result = dns_rdataset_first(&rdataset);
 	if (result != ISC_R_SUCCESS)
		goto freerdataset;
	dns_rdataset_current(&rdataset, &rdata);

	INSIST(rdata.length > 20);
	isc_buffer_init(&buffer, rdata.data, rdata.length);
	isc_buffer_add(&buffer, rdata.length);
	isc_buffer_forward(&buffer, rdata.length - 20);
	*serialp = isc_buffer_getuint32(&buffer);

	result = ISC_R_SUCCESS;

 freerdataset:
	dns_rdataset_disassociate(&rdataset);
	
 freenode:
	dns_db_detachnode(db, &node);
	return (result);
}