1/*
2 * Copyright (C) 2004, 2005, 2007, 2009, 2011  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: t_db.c,v 1.39.346.2 2011/03/12 04:59:14 tbox Exp $ */
19
20#include <config.h>
21
22#include <ctype.h>
23#include <stdlib.h>
24
25#include <isc/entropy.h>
26#include <isc/hash.h>
27#include <isc/mem.h>
28#include <isc/string.h>
29#include <isc/util.h>
30
31#include <dns/db.h>
32#include <dns/fixedname.h>
33#include <dns/rdata.h>
34#include <dns/rdataclass.h>
35#include <dns/rdatatype.h>
36#include <dns/rdatalist.h>
37#include <dns/rdataset.h>
38#include <dns/result.h>
39
40#include <tests/t_api.h>
41
42static isc_result_t
43t_create(const char *db_type, const char *origin, const char *class,
44	 const char *model, isc_mem_t *mctx, dns_db_t **db)
45{
46	int			len;
47	isc_result_t		dns_result;
48	dns_dbtype_t		dbtype;
49	isc_textregion_t	region;
50	isc_buffer_t		origin_buffer;
51	dns_fixedname_t		dns_origin;
52	dns_rdataclass_t	rdataclass;
53
54
55	dbtype = dns_dbtype_zone;
56	if (strcasecmp(model, "cache") == 0)
57		dbtype = dns_dbtype_cache;
58
59	dns_fixedname_init(&dns_origin);
60	len = strlen(origin);
61	isc_buffer_init(&origin_buffer, origin, len);
62	isc_buffer_add(&origin_buffer, len);
63	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
64				       &origin_buffer, NULL, 0, NULL);
65	if (dns_result != ISC_R_SUCCESS) {
66		t_info("dns_name_fromtext failed %s\n",
67		       dns_result_totext(dns_result));
68		return(dns_result);
69	}
70
71	DE_CONST(class, region.base);
72	region.length = strlen(class);
73	dns_result = dns_rdataclass_fromtext(&rdataclass, &region);
74	if (dns_result != ISC_R_SUCCESS) {
75		t_info("dns_rdataclass_fromtext failed %s\n",
76		       dns_result_totext(dns_result));
77		return(dns_result);
78	}
79
80	dns_result = dns_db_create(mctx, db_type,
81				   dns_fixedname_name(&dns_origin),
82				   dbtype, rdataclass, 0, NULL, db);
83	if (dns_result != ISC_R_SUCCESS)
84		t_info("dns_db_create failed %s\n",
85		       dns_result_totext(dns_result));
86
87	return(dns_result);
88
89}
90
91static int
92t_dns_db_load(char **av) {
93	char			*filename;
94	char			*db_type;
95	char			*origin;
96	char			*model;
97	char			*class;
98	char			*expected_load_result;
99	char			*findname;
100	char			*find_type;
101	char			*expected_find_result;
102
103	int			result;
104	int			len;
105	dns_db_t		*db;
106	isc_result_t		dns_result;
107	isc_result_t		isc_result;
108	isc_mem_t		*mctx;
109	isc_entropy_t		*ectx;
110	dns_dbnode_t		*nodep;
111	isc_textregion_t	textregion;
112	isc_buffer_t		findname_buffer;
113	dns_fixedname_t		dns_findname;
114	dns_fixedname_t		dns_foundname;
115	dns_rdataset_t		rdataset;
116	dns_rdatatype_t		rdatatype;
117	dns_dbversion_t		*versionp;
118	isc_result_t		exp_load_result;
119	isc_result_t		exp_find_result;
120
121	db = NULL;
122	mctx = NULL;
123	ectx = NULL;
124	filename = T_ARG(0);
125	db_type = T_ARG(1);
126	origin = T_ARG(2);
127	model = T_ARG(3);
128	class = T_ARG(4);
129	expected_load_result = T_ARG(5);
130	findname = T_ARG(6);
131	find_type = T_ARG(7);
132	expected_find_result = T_ARG(8);
133
134	t_info("testing using file %s and name %s\n", filename, findname);
135
136	exp_load_result = t_dns_result_fromtext(expected_load_result);
137	exp_find_result = t_dns_result_fromtext(expected_find_result);
138
139	isc_result = isc_mem_create(0, 0, &mctx);
140	if (isc_result != ISC_R_SUCCESS) {
141		t_info("isc_mem_create failed %s\n",
142				isc_result_totext(isc_result));
143		return(T_UNRESOLVED);
144	}
145
146	isc_result = isc_entropy_create(mctx, &ectx);
147	if (isc_result != ISC_R_SUCCESS) {
148		t_info("isc_entropy_create failed %s\n",
149				isc_result_totext(isc_result));
150		isc_mem_destroy(&mctx);
151		return(T_UNRESOLVED);
152	}
153
154	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
155	if (isc_result != ISC_R_SUCCESS) {
156		t_info("isc_hash_create failed %s\n",
157				isc_result_totext(isc_result));
158		isc_entropy_detach(&ectx);
159		isc_mem_destroy(&mctx);
160		return(T_UNRESOLVED);
161	}
162
163	dns_result = t_create(db_type, origin, class, model, mctx, &db);
164	if (dns_result != ISC_R_SUCCESS) {
165		isc_hash_destroy();
166		isc_entropy_detach(&ectx);
167		isc_mem_destroy(&mctx);
168		return(T_UNRESOLVED);
169	}
170
171	dns_result = dns_db_load(db, filename);
172	if (dns_result != exp_load_result) {
173		t_info("dns_db_load returned %s, expected %s\n",
174				dns_result_totext(dns_result),
175				dns_result_totext(exp_load_result));
176		dns_db_detach(&db);
177		isc_hash_destroy();
178		isc_entropy_detach(&ectx);
179		isc_mem_destroy(&mctx);
180		return(T_FAIL);
181	}
182	if (dns_result != ISC_R_SUCCESS) {
183		result = T_PASS;
184		goto cleanup_db;
185	}
186
187	dns_fixedname_init(&dns_findname);
188	len = strlen(findname);
189	isc_buffer_init(&findname_buffer, findname, len);
190	isc_buffer_add(&findname_buffer, len);
191	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
192				&findname_buffer, NULL, 0, NULL);
193	if (dns_result != ISC_R_SUCCESS) {
194		t_info("dns_name_fromtext failed %s\n",
195			dns_result_totext(dns_result));
196		dns_db_detach(&db);
197		isc_hash_destroy();
198		isc_entropy_detach(&ectx);
199		isc_mem_destroy(&mctx);
200		return(T_UNRESOLVED);
201	}
202
203	textregion.base = find_type;
204	textregion.length = strlen(find_type);
205	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
206	if (dns_result != ISC_R_SUCCESS) {
207		t_info("dns_rdatatype_fromtext %s failed %s\n",
208				find_type,
209				dns_result_totext(dns_result));
210		dns_db_detach(&db);
211		isc_hash_destroy();
212		isc_entropy_detach(&ectx);
213		isc_mem_destroy(&mctx);
214		return(T_UNRESOLVED);
215	}
216
217	versionp = NULL;
218	dns_fixedname_init(&dns_foundname);
219	dns_rdataset_init(&rdataset);
220	if (dns_db_iszone(db))
221		dns_db_currentversion(db, &versionp);
222	nodep = NULL;
223
224	dns_result = dns_db_find(db,
225			dns_fixedname_name(&dns_findname),
226			versionp,
227			rdatatype,
228			DNS_DBFIND_GLUEOK,
229			0,
230			&nodep,
231			dns_fixedname_name(&dns_foundname),
232			&rdataset, NULL);
233
234	if (dns_result != exp_find_result) {
235		t_info("dns_db_find returned %s, expected %s\n",
236				dns_result_totext(dns_result),
237				dns_result_totext(exp_find_result));
238		result = T_FAIL;
239	} else {
240		result = T_PASS;
241	}
242
243	if (dns_result != ISC_R_NOTFOUND) {
244		dns_db_detachnode(db, &nodep);
245		if (dns_rdataset_isassociated(&rdataset))
246			dns_rdataset_disassociate(&rdataset);
247	}
248
249	if (dns_db_iszone(db))
250		dns_db_closeversion(db, &versionp, ISC_FALSE);
251 cleanup_db:
252	dns_db_detach(&db);
253	isc_hash_destroy();
254	isc_entropy_detach(&ectx);
255	isc_mem_destroy(&mctx);
256	return(result);
257}
258
259static const char *a1 =
260	"A call to dns_db_load(db, filename) loads the contents of "
261	"the database in filename into db.";
262
263static void
264t1(void) {
265	int	result;
266
267	t_assert("dns_db_load", 1, T_REQUIRED, "%s", a1);
268	result = t_eval("dns_db_load_data", t_dns_db_load, 9);
269	t_result(result);
270}
271
272
273static const char *a2 =
274	"When the database db has cache semantics, a call to "
275	"dns_db_iscache(db) returns ISC_TRUE.";
276
277static int
278t_dns_db_zc_x(char *filename, char *db_type, char *origin, char *class,
279	      dns_dbtype_t dbtype, isc_boolean_t(*cf)(dns_db_t *),
280	      isc_boolean_t exp_result)
281{
282	int			result;
283	int			len;
284	dns_db_t		*db;
285	isc_result_t		dns_result;
286	isc_result_t		isc_result;
287	isc_mem_t		*mctx;
288	isc_entropy_t		*ectx;
289	dns_rdataclass_t	rdataclass;
290	isc_textregion_t	textregion;
291	isc_buffer_t		origin_buffer;
292	dns_fixedname_t		dns_origin;
293
294	db = NULL;
295	mctx = NULL;
296	ectx = NULL;
297
298	t_info("testing using file %s\n", filename);
299
300	dns_fixedname_init(&dns_origin);
301	len = strlen(origin);
302	isc_buffer_init(&origin_buffer, origin, len);
303	isc_buffer_add(&origin_buffer, len);
304	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
305				       &origin_buffer, NULL, 0, NULL);
306	if (dns_result != ISC_R_SUCCESS) {
307		t_info("dns_name_fromtext failed %s\n",
308		       dns_result_totext(dns_result));
309		return(T_UNRESOLVED);
310	}
311
312	textregion.base = class;
313	textregion.length = strlen(class);
314	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
315	if (dns_result != ISC_R_SUCCESS) {
316		t_info("dns_rdataclass_fromtext failed %s\n",
317		       dns_result_totext(dns_result));
318		return(T_UNRESOLVED);
319	}
320
321	isc_result = isc_mem_create(0, 0, &mctx);
322	if (isc_result != ISC_R_SUCCESS) {
323		t_info("isc_mem_create failed %s\n",
324		       isc_result_totext(isc_result));
325		return(T_UNRESOLVED);
326	}
327
328	isc_result = isc_entropy_create(mctx, &ectx);
329	if (isc_result != ISC_R_SUCCESS) {
330		t_info("isc_entropy_create failed %s\n",
331				isc_result_totext(isc_result));
332		isc_mem_destroy(&mctx);
333		return(T_UNRESOLVED);
334	}
335
336	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
337	if (isc_result != ISC_R_SUCCESS) {
338		t_info("isc_hash_create failed %s\n",
339				isc_result_totext(isc_result));
340		isc_entropy_detach(&ectx);
341		isc_mem_destroy(&mctx);
342		return(T_UNRESOLVED);
343	}
344
345	dns_result = dns_db_create(mctx, db_type,
346				   dns_fixedname_name(&dns_origin),
347				   dbtype, rdataclass, 0, NULL, &db);
348	if (dns_result != ISC_R_SUCCESS) {
349		t_info("dns_db_create failed %s\n",
350		       dns_result_totext(dns_result));
351		isc_hash_destroy();
352		isc_entropy_detach(&ectx);
353		isc_mem_destroy(&mctx);
354		return(T_UNRESOLVED);
355	}
356
357	dns_result = dns_db_load(db, filename);
358	if (dns_result == ISC_R_SUCCESS) {
359		if ((*cf)(db) == exp_result)
360			result = T_PASS;
361		else
362			result = T_FAIL;
363	} else {
364		t_info("dns_db_load failed %s\n",
365		       dns_result_totext(dns_result));
366		result = T_FAIL;
367	}
368
369	dns_db_detach(&db);
370	isc_hash_destroy();
371	isc_entropy_detach(&ectx);
372	isc_mem_destroy(&mctx);
373	return(result);
374}
375
376static int
377test_dns_db_zc_x(const char *filename, dns_dbtype_t dbtype,
378		 isc_boolean_t(*cf)(dns_db_t *), isc_boolean_t exp_result)
379{
380
381	FILE		*fp;
382	char		*p;
383	int		line;
384	int		cnt;
385	int		result;
386	int		nfails;
387	int		nprobs;
388	char		*tokens[T_MAXTOKS];
389
390	nfails = 0;
391	nprobs = 0;
392
393	fp = fopen(filename, "r");
394	if (fp != NULL) {
395		line = 0;
396		while ((p = t_fgetbs(fp)) != NULL) {
397
398			++line;
399
400			/*
401			 * Skip comment lines.
402			 */
403			if ((isspace((unsigned char)*p)) || (*p == '#')) {
404				(void)free(p);
405				continue;
406			}
407
408			cnt = t_bustline(p, tokens);
409			if (cnt == 4) {
410				result = t_dns_db_zc_x(tokens[0], /* file */
411						       tokens[1], /* type */
412						       tokens[2], /* origin */
413						       tokens[3], /* class */
414						       dbtype,     /* cache */
415						       cf,     /* check func */
416						       exp_result);/* expect */
417				if (result != T_PASS) {
418					if (result == T_FAIL)
419						++nfails;
420					else
421						++nprobs;
422				}
423			} else {
424				t_info("bad format in %s at line %d\n",
425				       filename, line);
426				++nprobs;
427			}
428
429			(void)free(p);
430		}
431		(void)fclose(fp);
432	} else {
433		t_info("Missing datafile %s\n", filename);
434		++nprobs;
435	}
436
437	result = T_UNRESOLVED;
438
439	if (nfails == 0 && nprobs == 0)
440		result = T_PASS;
441	else if (nfails)
442		result = T_FAIL;
443
444	return(result);
445}
446
447static void
448t2(void) {
449	int	result;
450
451	t_assert("dns_db_iscache", 2, T_REQUIRED, "%s", a2);
452	result = test_dns_db_zc_x("dns_db_iscache_1_data",
453				  dns_dbtype_cache, dns_db_iscache, ISC_TRUE);
454	t_result(result);
455}
456
457
458static const char *a3 =
459	"When the database db has zone semantics, a call to "
460	"dns_db_iscache(db) returns ISC_FALSE.";
461
462
463static void
464t3(void) {
465	int	result;
466
467	t_assert("dns_db_iscache", 3, T_REQUIRED, "%s", a3);
468	result = test_dns_db_zc_x("dns_db_iscache_2_data",
469				  dns_dbtype_zone, dns_db_iscache, ISC_FALSE);
470	t_result(result);
471}
472
473
474static const char *a4 =
475	"When the database db has zone semantics, a call to "
476	"dns_db_iszone(db) returns ISC_TRUE.";
477
478
479static void
480t4(void) {
481	int	result;
482
483	t_assert("dns_db_iszone", 4, T_REQUIRED, "%s", a4);
484	result = test_dns_db_zc_x("dns_db_iszone_1_data",
485				  dns_dbtype_zone, dns_db_iszone, ISC_TRUE);
486	t_result(result);
487}
488
489
490static const char *a5 =
491	"When the database db has cache semantics, a call to "
492	"dns_db_iszone(db) returns ISC_FALSE.";
493
494static void
495t5(void) {
496	int	result;
497
498	t_assert("dns_db_iszone", 5, T_REQUIRED, "%s", a5);
499	result = test_dns_db_zc_x("dns_db_iszone_2_data",
500				  dns_dbtype_cache, dns_db_iszone, ISC_FALSE);
501	t_result(result);
502}
503
504static int
505t_dns_db_origin(char **av) {
506
507	char			*filename;
508	char			*origin;
509
510	int			result;
511	int			len;
512	int			order;
513	isc_result_t		dns_result;
514	isc_result_t		isc_result;
515	isc_mem_t		*mctx;
516	isc_entropy_t		*ectx;
517	dns_db_t		*db;
518	dns_fixedname_t		dns_origin;
519	dns_fixedname_t		dns_dborigin;
520	isc_buffer_t		origin_buffer;
521
522	db = NULL;
523	mctx = NULL;
524	ectx = NULL;
525
526	filename = T_ARG(0);
527	origin = T_ARG(1);
528
529	t_info("testing with database %s and origin %s\n",
530			filename, origin);
531
532	isc_result = isc_mem_create(0, 0, &mctx);
533	if (isc_result != ISC_R_SUCCESS) {
534		t_info("isc_mem_create failed %s\n",
535			isc_result_totext(isc_result));
536		return(T_UNRESOLVED);
537	}
538
539	isc_result = isc_entropy_create(mctx, &ectx);
540	if (isc_result != ISC_R_SUCCESS) {
541		t_info("isc_entropy_create failed %s\n",
542				isc_result_totext(isc_result));
543		isc_mem_destroy(&mctx);
544		return(T_UNRESOLVED);
545	}
546
547	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
548	if (isc_result != ISC_R_SUCCESS) {
549		t_info("isc_hash_create failed %s\n",
550				isc_result_totext(isc_result));
551		isc_entropy_detach(&ectx);
552		isc_mem_destroy(&mctx);
553		return(T_UNRESOLVED);
554	}
555
556	dns_result = t_create("rbt", origin, "in", "isc_true", mctx, &db);
557	if (dns_result != ISC_R_SUCCESS) {
558		t_info("t_create failed %s\n",
559			dns_result_totext(dns_result));
560		isc_hash_destroy();
561		isc_entropy_detach(&ectx);
562		isc_mem_destroy(&mctx);
563		return(T_UNRESOLVED);
564	}
565	dns_fixedname_init(&dns_origin);
566	dns_fixedname_init(&dns_dborigin);
567
568	len = strlen(origin);
569	isc_buffer_init(&origin_buffer, origin, len);
570	isc_buffer_add(&origin_buffer, len);
571
572	dns_result = dns_db_load(db, filename);
573	if (dns_result != ISC_R_SUCCESS) {
574		t_info("dns_db_load failed %s\n",
575				dns_result_totext(dns_result));
576		dns_db_detach(&db);
577		isc_hash_destroy();
578		isc_entropy_detach(&ectx);
579		isc_mem_destroy(&mctx);
580		return(T_UNRESOLVED);
581	}
582
583	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
584				&origin_buffer, NULL, 0, NULL);
585	if (dns_result != ISC_R_SUCCESS) {
586		t_info("dns_name_fromtext failed %s\n",
587				dns_result_totext(dns_result));
588		dns_db_detach(&db);
589		isc_hash_destroy();
590		isc_entropy_detach(&ectx);
591		isc_mem_destroy(&mctx);
592		return(T_UNRESOLVED);
593	}
594	order = dns_name_compare(dns_fixedname_name(&dns_origin),
595				 dns_db_origin(db));
596	if (order == 0) {
597		result = T_PASS;
598	} else {
599		t_info("dns_name_compare returned %d\n", order);
600		result = T_FAIL;
601	}
602
603	dns_db_detach(&db);
604	isc_hash_destroy();
605	isc_entropy_detach(&ectx);
606	isc_mem_destroy(&mctx);
607	return(result);
608
609}
610
611static const char *a6 =
612	"A call to dns_db_origin(db) returns the origin of the database.";
613
614static void
615t6(void) {
616	int	result;
617
618	t_assert("dns_db_origin", 6, T_REQUIRED, "%s", a6);
619	result = t_eval("dns_db_origin_data", t_dns_db_origin, 2);
620	t_result(result);
621}
622
623
624static const char *a7 =
625	"A call to dns_db_class(db) returns the class of the database.";
626
627
628#define	CLASSBUFLEN	256
629
630static int
631t_dns_db_class(char **av) {
632
633	char			*filename;
634	char			*class;
635
636	int			result;
637	isc_result_t		dns_result;
638	isc_result_t		isc_result;
639	isc_mem_t		*mctx;
640	isc_entropy_t		*ectx;
641	dns_db_t		*db;
642	dns_rdataclass_t	rdataclass;
643	dns_rdataclass_t	db_rdataclass;
644	isc_textregion_t	textregion;
645
646	filename = T_ARG(0);
647	class = T_ARG(1);
648	db = NULL;
649	mctx = NULL;
650	ectx = NULL;
651
652	t_info("testing with database %s and class %s\n",
653			filename, class);
654
655	textregion.base = class;
656	textregion.length = strlen(class);
657	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
658	if (dns_result != ISC_R_SUCCESS) {
659		t_info("dns_rdataclass_fromtext failed %s\n",
660				dns_result_totext(dns_result));
661		return(T_UNRESOLVED);
662	}
663
664	isc_result = isc_mem_create(0, 0, &mctx);
665	if (isc_result != ISC_R_SUCCESS) {
666		t_info("isc_mem_create failed %s\n",
667			isc_result_totext(isc_result));
668		return(T_UNRESOLVED);
669	}
670
671	isc_result = isc_entropy_create(mctx, &ectx);
672	if (isc_result != ISC_R_SUCCESS) {
673		t_info("isc_entropy_create failed %s\n",
674				isc_result_totext(isc_result));
675		isc_mem_destroy(&mctx);
676		return(T_UNRESOLVED);
677	}
678
679	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
680	if (isc_result != ISC_R_SUCCESS) {
681		t_info("isc_hash_create failed %s\n",
682				isc_result_totext(isc_result));
683		isc_entropy_detach(&ectx);
684		isc_mem_destroy(&mctx);
685		return(T_UNRESOLVED);
686	}
687
688	dns_result = t_create("rbt", ".", class, "isc_true", mctx, &db);
689	if (dns_result != ISC_R_SUCCESS) {
690		t_info("t_create failed %s\n",
691			dns_result_totext(dns_result));
692		isc_hash_destroy();
693		isc_entropy_detach(&ectx);
694		isc_mem_destroy(&mctx);
695		return(T_UNRESOLVED);
696	}
697
698	dns_result = dns_db_load(db, filename);
699	if (dns_result != ISC_R_SUCCESS) {
700		t_info("dns_db_load failed %s\n",
701				dns_result_totext(dns_result));
702		dns_db_detach(&db);
703		isc_hash_destroy();
704		isc_entropy_detach(&ectx);
705		isc_mem_destroy(&mctx);
706		return(T_UNRESOLVED);
707	}
708
709	db_rdataclass = dns_db_class(db);
710	if (db_rdataclass == rdataclass)
711		result = T_PASS;
712	else {
713		char classbuf[DNS_RDATACLASS_FORMATSIZE];
714		dns_rdataclass_format(db_rdataclass,
715				      classbuf, sizeof(classbuf));
716		t_info("dns_db_class returned %s, expected %s\n",
717		       classbuf, class);
718		result = T_FAIL;
719	}
720
721	dns_db_detach(&db);
722	isc_hash_destroy();
723	isc_entropy_detach(&ectx);
724	isc_mem_destroy(&mctx);
725	return(result);
726
727}
728static void
729t7(void) {
730	int	result;
731
732	t_assert("dns_db_class", 7, T_REQUIRED, "%s", a7);
733	result = t_eval("dns_db_class_data", t_dns_db_class, 2);
734	t_result(result);
735}
736
737
738static const char *a8 =
739	"A call to dns_db_currentversion() opens the current "
740	"version for reading.";
741
742static int
743t_dns_db_currentversion(char **av) {
744	char			*filename;
745	char			*db_type;
746	char			*origin;
747	char			*class;
748	char			*model;
749	char			*findname;
750	char			*findtype;
751
752	int			result;
753	int			len;
754	dns_db_t		*db;
755	isc_result_t		dns_result;
756	isc_result_t		isc_result;
757	isc_mem_t		*mctx;
758	isc_entropy_t		*ectx;
759	dns_dbnode_t		*nodep;
760	isc_textregion_t	textregion;
761	isc_buffer_t		findname_buffer;
762	dns_fixedname_t		dns_findname;
763	dns_fixedname_t		dns_foundname;
764	dns_rdataset_t		rdataset;
765	dns_rdatatype_t		rdatatype;
766	dns_dbversion_t		*cversionp;
767	dns_dbversion_t		*nversionp;
768
769	filename = T_ARG(0);
770	db_type = T_ARG(1);
771	origin = T_ARG(2);
772	class = T_ARG(3);
773	model = T_ARG(4);
774	findname = T_ARG(5);
775	findtype = T_ARG(6);
776	db = NULL;
777	mctx = NULL;
778	ectx = NULL;
779
780	t_info("testing using file %s and name %s\n", filename, findname);
781
782	isc_result = isc_mem_create(0, 0, &mctx);
783	if (isc_result != ISC_R_SUCCESS) {
784		t_info("isc_mem_create failed %s\n",
785				isc_result_totext(isc_result));
786		return(T_UNRESOLVED);
787	}
788
789	isc_result = isc_entropy_create(mctx, &ectx);
790	if (isc_result != ISC_R_SUCCESS) {
791		t_info("isc_entropy_create failed %s\n",
792				isc_result_totext(isc_result));
793		isc_mem_destroy(&mctx);
794		return(T_UNRESOLVED);
795	}
796
797	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
798	if (isc_result != ISC_R_SUCCESS) {
799		t_info("isc_hash_create failed %s\n",
800				isc_result_totext(isc_result));
801		isc_entropy_detach(&ectx);
802		isc_mem_destroy(&mctx);
803		return(T_UNRESOLVED);
804	}
805
806	dns_result = t_create(db_type, origin, class, model, mctx, &db);
807	if (dns_result != ISC_R_SUCCESS) {
808		isc_hash_destroy();
809		isc_entropy_detach(&ectx);
810		isc_mem_destroy(&mctx);
811		return(T_UNRESOLVED);
812	}
813
814	dns_result = dns_db_load(db, filename);
815	if (dns_result != ISC_R_SUCCESS) {
816		t_info("dns_db_load returned %s\n",
817				dns_result_totext(dns_result));
818		dns_db_detach(&db);
819		isc_hash_destroy();
820		isc_entropy_detach(&ectx);
821		isc_mem_destroy(&mctx);
822		return(T_UNRESOLVED);
823	}
824
825	dns_fixedname_init(&dns_findname);
826	len = strlen(findname);
827	isc_buffer_init(&findname_buffer, findname, len);
828	isc_buffer_add(&findname_buffer, len);
829	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
830				&findname_buffer, NULL, 0, NULL);
831	if (dns_result != ISC_R_SUCCESS) {
832		t_info("dns_name_fromtext failed %s\n",
833			dns_result_totext(dns_result));
834		dns_db_detach(&db);
835		isc_hash_destroy();
836		isc_entropy_detach(&ectx);
837		isc_mem_destroy(&mctx);
838		return(T_UNRESOLVED);
839	}
840
841	textregion.base = findtype;
842	textregion.length = strlen(findtype);
843	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
844	if (dns_result != ISC_R_SUCCESS) {
845		t_info("dns_rdatatype_fromtext %s failed %s\n",
846				findtype,
847				dns_result_totext(dns_result));
848		dns_db_detach(&db);
849		isc_hash_destroy();
850		isc_entropy_detach(&ectx);
851		isc_mem_destroy(&mctx);
852		return(T_UNRESOLVED);
853	}
854
855	/*
856	 * find a name we know is there
857	 */
858
859	cversionp = NULL;
860	dns_fixedname_init(&dns_foundname);
861	dns_rdataset_init(&rdataset);
862	dns_db_currentversion(db, &cversionp);
863	nodep = NULL;
864
865	dns_result = dns_db_find(db,
866			dns_fixedname_name(&dns_findname),
867			cversionp,
868			rdatatype,
869			0,
870			0,
871			&nodep,
872			dns_fixedname_name(&dns_foundname),
873			&rdataset, NULL);
874
875	if (dns_result != ISC_R_SUCCESS) {
876		t_info("unable to find %s using current version\n", findname);
877		dns_db_closeversion(db, &cversionp, ISC_FALSE);
878		dns_db_detach(&db);
879		isc_hash_destroy();
880		isc_entropy_detach(&ectx);
881		isc_mem_destroy(&mctx);
882		return(T_UNRESOLVED);
883	}
884
885	/*
886	 * create a new version
887	 * delete the found rdataset in the new version
888	 * attempt to find the rdataset again and expect the find to fail
889	 * close/commit the new version
890	 * attempt to find the rdataset in the current version and
891	 * expect the find to succeed
892	 */
893
894	nversionp = NULL;
895	dns_result = dns_db_newversion(db, &nversionp);
896	if (dns_result != ISC_R_SUCCESS) {
897		t_info("dns_db_newversion failed %s\n",
898				dns_result_totext(dns_result));
899		dns_db_detachnode(db, &nodep);
900		dns_rdataset_disassociate(&rdataset);
901		dns_db_closeversion(db, &cversionp, ISC_FALSE);
902		dns_db_detach(&db);
903		isc_hash_destroy();
904		isc_entropy_detach(&ectx);
905		isc_mem_destroy(&mctx);
906		return(T_UNRESOLVED);
907	}
908
909	/*
910	 * Delete the found rdataset in the new version.
911	 */
912	dns_result = dns_db_deleterdataset(db, nodep, nversionp, rdatatype, 0);
913	if (dns_result != ISC_R_SUCCESS) {
914		t_info("dns_db_deleterdataset failed %s\n",
915				dns_result_totext(dns_result));
916		dns_rdataset_disassociate(&rdataset);
917		dns_db_detachnode(db, &nodep);
918		dns_db_closeversion(db, &nversionp, ISC_FALSE);
919		dns_db_closeversion(db, &cversionp, ISC_FALSE);
920		dns_db_detach(&db);
921		isc_hash_destroy();
922		isc_entropy_detach(&ectx);
923		isc_mem_destroy(&mctx);
924		return(T_UNRESOLVED);
925	}
926
927	/*
928	 * Don't need these now.
929	 */
930	dns_rdataset_disassociate(&rdataset);
931	dns_db_detachnode(db, &nodep);
932	nodep = NULL;
933
934	/*
935	 * Find the deleted rdataset and expect it to fail.
936	 */
937	dns_result = dns_db_find(db,
938			dns_fixedname_name(&dns_findname),
939			nversionp,
940			rdatatype,
941			0,
942			0,
943			&nodep,
944			dns_fixedname_name(&dns_foundname),
945			&rdataset, NULL);
946
947	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
948		t_info("unexpectedly found %s using current version\n",
949		       findname);
950		dns_db_closeversion(db, &cversionp, ISC_FALSE);
951		dns_db_closeversion(db, &nversionp, ISC_FALSE);
952		dns_db_detach(&db);
953		isc_hash_destroy();
954		isc_entropy_detach(&ectx);
955		isc_mem_destroy(&mctx);
956		return(T_FAIL);
957	}
958
959	/*
960	 * Close/commit the new version.
961	 */
962	dns_db_closeversion(db, &nversionp, ISC_TRUE);
963
964	/*
965	 * Find the deleted rdata in the current version.
966	 */
967	dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname),
968				 cversionp, rdatatype, DNS_DBFIND_GLUEOK,
969				 0, &nodep, dns_fixedname_name(&dns_foundname),
970				 &rdataset, NULL);
971
972	/*
973	 * And expect it to succeed.
974	 */
975	if (dns_result == ISC_R_SUCCESS) {
976		result = T_PASS;
977	} else {
978		t_info("cound not find %s using current version\n", findname);
979		dns_db_closeversion(db, &cversionp, ISC_FALSE);
980		dns_db_detach(&db);
981		isc_hash_destroy();
982		isc_entropy_detach(&ectx);
983		isc_mem_destroy(&mctx);
984		result = T_FAIL;
985	}
986
987	dns_db_detachnode(db, &nodep);
988	dns_rdataset_disassociate(&rdataset);
989
990	dns_db_closeversion(db, &cversionp, ISC_FALSE);
991	dns_db_detach(&db);
992	isc_hash_destroy();
993	isc_entropy_detach(&ectx);
994	isc_mem_destroy(&mctx);
995
996	return(result);
997}
998
999static void
1000t8(void) {
1001	int	result;
1002
1003	t_assert("dns_db_currentversion", 8, T_REQUIRED, "%s", a8);
1004	result = t_eval("dns_db_currentversion_data",
1005			t_dns_db_currentversion, 7);
1006	t_result(result);
1007}
1008
1009static const char *a9 =
1010	"A call to dns_db_newversion() opens a new version for "
1011	"reading and writing.";
1012
1013static int
1014t_dns_db_newversion(char **av) {
1015
1016	char			*filename;
1017	char			*db_type;
1018	char			*origin;
1019	char			*class;
1020	char			*model;
1021	char			*newname;
1022	char			*newtype;
1023
1024	int			result;
1025	int			len;
1026	int			rval;
1027	dns_db_t		*db;
1028	isc_result_t		dns_result;
1029	isc_result_t		isc_result;
1030	isc_mem_t		*mctx;
1031	isc_entropy_t		*ectx;
1032	dns_dbnode_t		*nodep;
1033	dns_dbnode_t		*found_nodep;
1034	isc_textregion_t	textregion;
1035	isc_buffer_t		newname_buffer;
1036	dns_fixedname_t		dns_newname;
1037	dns_fixedname_t		dns_foundname;
1038	dns_rdata_t		added_rdata = DNS_RDATA_INIT;
1039	const char *		added_rdata_data;
1040	dns_rdataset_t		added_rdataset;
1041	dns_rdata_t		found_rdata = DNS_RDATA_INIT;
1042	dns_rdataset_t		found_rdataset;
1043	dns_rdatatype_t		rdatatype;
1044	dns_rdataclass_t	rdataclass;
1045	dns_dbversion_t		*nversionp;
1046	dns_rdatalist_t		rdatalist;
1047
1048	filename = T_ARG(0);
1049	db_type = T_ARG(1);
1050	origin = T_ARG(2);
1051	class = T_ARG(3);
1052	model = T_ARG(4);
1053	newname = T_ARG(5);
1054	newtype = T_ARG(6);
1055	db = NULL;
1056	mctx = NULL;
1057	ectx = NULL;
1058
1059	/*
1060	 * Open a new version, add some data, commit it,
1061	 * close it, open a new version, and check that changes
1062	 * are present.
1063	 */
1064
1065	t_info("testing using file %s and name %s\n", filename, newname);
1066
1067	isc_result = isc_mem_create(0, 0, &mctx);
1068	if (isc_result != ISC_R_SUCCESS) {
1069		t_info("isc_mem_create failed %s\n",
1070				isc_result_totext(isc_result));
1071		return(T_UNRESOLVED);
1072	}
1073
1074	isc_result = isc_entropy_create(mctx, &ectx);
1075	if (isc_result != ISC_R_SUCCESS) {
1076		t_info("isc_entropy_create failed %s\n",
1077				isc_result_totext(isc_result));
1078		isc_mem_destroy(&mctx);
1079		return(T_UNRESOLVED);
1080	}
1081
1082	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
1083	if (isc_result != ISC_R_SUCCESS) {
1084		t_info("isc_hash_create failed %s\n",
1085				isc_result_totext(isc_result));
1086		isc_entropy_detach(&ectx);
1087		isc_mem_destroy(&mctx);
1088		return(T_UNRESOLVED);
1089	}
1090
1091	dns_result = t_create(db_type, origin, class, model, mctx, &db);
1092	if (dns_result != ISC_R_SUCCESS) {
1093		isc_hash_destroy();
1094		isc_entropy_detach(&ectx);
1095		isc_mem_destroy(&mctx);
1096		return(T_UNRESOLVED);
1097	}
1098
1099	dns_result = dns_db_load(db, filename);
1100	if (dns_result != ISC_R_SUCCESS) {
1101		t_info("dns_db_load returned %s\n",
1102				dns_result_totext(dns_result));
1103		dns_db_detach(&db);
1104		isc_hash_destroy();
1105		isc_entropy_detach(&ectx);
1106		isc_mem_destroy(&mctx);
1107		return(T_UNRESOLVED);
1108	}
1109
1110	/*
1111	 * Add a new name.
1112	 */
1113
1114	dns_fixedname_init(&dns_newname);
1115	len = strlen(newname);
1116	isc_buffer_init(&newname_buffer, newname, len);
1117	isc_buffer_add(&newname_buffer, len);
1118	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
1119				&newname_buffer, NULL, 0, NULL);
1120	if (dns_result != ISC_R_SUCCESS) {
1121		t_info("dns_name_fromtext failed %s\n",
1122			dns_result_totext(dns_result));
1123		dns_db_detach(&db);
1124		isc_hash_destroy();
1125		isc_entropy_detach(&ectx);
1126		isc_mem_destroy(&mctx);
1127		return(T_UNRESOLVED);
1128	}
1129
1130	nodep = NULL;
1131	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname),
1132				ISC_TRUE, &nodep);
1133	if (dns_result != ISC_R_SUCCESS) {
1134		t_info("dns_db_findnode failed %s\n",
1135				dns_result_totext(dns_result));
1136		dns_db_detach(&db);
1137		isc_hash_destroy();
1138		isc_entropy_detach(&ectx);
1139		isc_mem_destroy(&mctx);
1140		return(T_UNRESOLVED);
1141	}
1142
1143	/*
1144	 * Open a new version and associate some rdata with the new name.
1145	 */
1146
1147	textregion.base = newtype;
1148	textregion.length = strlen(newtype);
1149	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
1150
1151	if (dns_result != ISC_R_SUCCESS) {
1152		t_info("dns_rdatatype_fromtext %s failed %s\n",
1153				newtype,
1154				dns_result_totext(dns_result));
1155		dns_db_detachnode(db, &nodep);
1156		dns_db_detach(&db);
1157		isc_hash_destroy();
1158		isc_entropy_detach(&ectx);
1159		isc_mem_destroy(&mctx);
1160		return(T_UNRESOLVED);
1161	}
1162
1163	textregion.base = class;
1164	textregion.length = strlen(class);
1165	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
1166	if (dns_result != ISC_R_SUCCESS) {
1167		t_info("dns_rdataclass_fromtext failed %s\n",
1168				dns_result_totext(dns_result));
1169		dns_db_detachnode(db, &nodep);
1170		dns_db_detach(&db);
1171		isc_hash_destroy();
1172		isc_entropy_detach(&ectx);
1173		isc_mem_destroy(&mctx);
1174		return(T_UNRESOLVED);
1175	}
1176
1177	dns_rdata_init(&added_rdata);
1178	added_rdata_data = "\x10\x00\x00\x01";
1179	DE_CONST(added_rdata_data, added_rdata.data);
1180	added_rdata.length = 4;
1181	added_rdata.rdclass = rdataclass;
1182	added_rdata.type = rdatatype;
1183
1184	dns_rdataset_init(&added_rdataset);
1185	rdatalist.type = rdatatype;
1186	rdatalist.covers = 0;
1187	rdatalist.rdclass = rdataclass;
1188	rdatalist.ttl = 0;
1189	ISC_LIST_INIT(rdatalist.rdata);
1190	ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link);
1191
1192	dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset);
1193	if (dns_result != ISC_R_SUCCESS) {
1194		t_info("dns_rdatalist_tordataset failed %s\n",
1195				dns_result_totext(dns_result));
1196		dns_db_detachnode(db, &nodep);
1197		dns_db_detach(&db);
1198		isc_hash_destroy();
1199		isc_entropy_detach(&ectx);
1200		isc_mem_destroy(&mctx);
1201		return(T_UNRESOLVED);
1202	}
1203
1204	nversionp = NULL;
1205	dns_result = dns_db_newversion(db, &nversionp);
1206	if (dns_result != ISC_R_SUCCESS) {
1207		t_info("dns_db_newversion failed %s\n",
1208				dns_result_totext(dns_result));
1209		dns_db_detachnode(db, &nodep);
1210		dns_db_detach(&db);
1211		isc_hash_destroy();
1212		isc_entropy_detach(&ectx);
1213		isc_mem_destroy(&mctx);
1214		return(T_UNRESOLVED);
1215	}
1216
1217	dns_result = dns_db_addrdataset(db, nodep, nversionp, 0,
1218				&added_rdataset, 0, NULL);
1219	if (dns_result != ISC_R_SUCCESS) {
1220		t_info("dns_db_addrdataset failed %s\n",
1221				dns_result_totext(dns_result));
1222		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1223		dns_db_detachnode(db, &nodep);
1224		dns_db_detach(&db);
1225		isc_hash_destroy();
1226		isc_entropy_detach(&ectx);
1227		isc_mem_destroy(&mctx);
1228		return(T_UNRESOLVED);
1229	}
1230
1231	/*
1232	 * Close and commit the version.
1233	 */
1234	dns_db_closeversion(db, &nversionp, ISC_TRUE);
1235	dns_db_detachnode(db, &nodep);
1236	if (dns_rdataset_isassociated(&added_rdataset))
1237		dns_rdataset_disassociate(&added_rdataset);
1238	nodep = NULL;
1239
1240	/*
1241	 * Open a new version and find the data we added.
1242	 */
1243	dns_fixedname_init(&dns_foundname);
1244	dns_rdataset_init(&found_rdataset);
1245	nversionp = NULL;
1246	found_nodep = NULL;
1247	dns_db_newversion(db, &nversionp);
1248
1249	/*
1250	 * Find the recently added name and rdata.
1251	 */
1252	dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname),
1253				 nversionp, rdatatype, 0, 0, &found_nodep,
1254				 dns_fixedname_name(&dns_foundname),
1255				 &found_rdataset, NULL);
1256
1257	if (dns_result != ISC_R_SUCCESS) {
1258		/* XXXWPK - NXRRSET ???  reference counts ??? */
1259		t_info("dns_db_find failed %s\n",
1260		       dns_result_totext(dns_result));
1261		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1262		dns_db_detachnode(db, &found_nodep);
1263		if (dns_rdataset_isassociated(&found_rdataset))
1264			dns_rdataset_disassociate(&found_rdataset);
1265		dns_db_detach(&db);
1266		isc_hash_destroy();
1267		isc_entropy_detach(&ectx);
1268		isc_mem_destroy(&mctx);
1269		return(T_FAIL);
1270	}
1271
1272	dns_result = dns_rdataset_first(&found_rdataset);
1273	if (dns_result != ISC_R_SUCCESS) {
1274		t_info("dns_rdataset_first failed %s\n",
1275				dns_result_totext(dns_result));
1276		dns_db_detachnode(db, &nodep);
1277		if (dns_rdataset_isassociated(&found_rdataset))
1278			dns_rdataset_disassociate(&found_rdataset);
1279		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1280		dns_db_detach(&db);
1281		isc_hash_destroy();
1282		isc_entropy_detach(&ectx);
1283		isc_mem_destroy(&mctx);
1284		return(T_FAIL);
1285	}
1286
1287	/*
1288	 * Now make sure its what we expect.
1289	 */
1290	dns_rdata_init(&found_rdata);
1291	dns_rdataset_current(&found_rdataset, &found_rdata);
1292	rval = dns_rdata_compare(&added_rdata, &found_rdata);
1293	if (rval == 0) {
1294		result = T_PASS;
1295	} else {
1296		t_info("dns_rdata_compare returned %d\n", rval);
1297		result = T_FAIL;
1298	}
1299
1300	/*
1301	 * Don't need these now.
1302	 */
1303	dns_db_closeversion(db, &nversionp, ISC_FALSE);
1304	if (dns_rdataset_isassociated(&found_rdataset))
1305		dns_rdataset_disassociate(&found_rdataset);
1306	dns_db_detachnode(db, &found_nodep);
1307	dns_db_detach(&db);
1308	isc_hash_destroy();
1309	isc_entropy_detach(&ectx);
1310	isc_mem_destroy(&mctx);
1311
1312	return(result);
1313}
1314
1315static void
1316t9(void) {
1317	int	result;
1318
1319	t_assert("dns_db_newversion", 9, T_REQUIRED, "%s", a9);
1320	result = t_eval("dns_db_newversion_data", t_dns_db_newversion, 7);
1321	t_result(result);
1322}
1323
1324static const char *a10 =
1325	"When versionp points to a read-write version and commit is "
1326	"ISC_TRUE, a call to dns_db_closeversion(db, versionp, commit) "
1327	"causes all changes made in the version to take effect, "
1328	"and returns ISC_R_SUCCESS.";
1329
1330static int
1331t_dns_db_closeversion_1(char **av) {
1332	char			*filename;
1333	char			*db_type;
1334	char			*origin;
1335	char			*class;
1336	char			*model;
1337	char			*new_name;
1338	char			*new_type;
1339	char			*existing_name;
1340	char			*existing_type;
1341
1342	int			result;
1343	int			len;
1344	int			rval;
1345	int			nfails;
1346	dns_db_t		*db;
1347	isc_result_t		dns_result;
1348	isc_result_t		isc_result;
1349	isc_mem_t		*mctx;
1350	isc_entropy_t		*ectx;
1351	dns_dbnode_t		*nodep;
1352	isc_textregion_t	textregion;
1353	isc_buffer_t		name_buffer;
1354	dns_fixedname_t		dns_newname;
1355	dns_fixedname_t		dns_foundname;
1356	dns_fixedname_t		dns_existingname;
1357	dns_rdata_t		added_rdata = DNS_RDATA_INIT;
1358	const char *		added_rdata_data;
1359	dns_rdataset_t		added_rdataset;
1360	dns_rdata_t		found_rdata = DNS_RDATA_INIT;
1361	dns_rdataset_t		found_rdataset;
1362	dns_rdatatype_t		new_rdatatype;
1363	dns_rdatatype_t		existing_rdatatype;
1364	dns_rdataclass_t	rdataclass;
1365	dns_dbversion_t		*nversionp;
1366	dns_dbversion_t		*cversionp;
1367	dns_rdatalist_t		rdatalist;
1368
1369	filename = T_ARG(0);
1370	db_type = T_ARG(1);
1371	origin = T_ARG(2);
1372	class = T_ARG(3);
1373	model = T_ARG(4);
1374	new_name = T_ARG(5);
1375	new_type = T_ARG(6);
1376	existing_name = T_ARG(7);
1377	existing_type = T_ARG(8);
1378
1379	nfails = 0;
1380	db = NULL;
1381	mctx = NULL;
1382	ectx = NULL;
1383
1384	/*
1385	 * Open a new version, add some data,
1386	 * remove some data, close with commit, open the current
1387	 * version and check that changes are present.
1388	 */
1389
1390	t_info("testing using file %s and name %s\n", filename, new_name);
1391
1392	isc_result = isc_mem_create(0, 0, &mctx);
1393	if (isc_result != ISC_R_SUCCESS) {
1394		t_info("isc_mem_create failed %s\n",
1395				isc_result_totext(isc_result));
1396		return(T_UNRESOLVED);
1397	}
1398
1399	isc_result = isc_entropy_create(mctx, &ectx);
1400	if (isc_result != ISC_R_SUCCESS) {
1401		t_info("isc_entropy_create failed %s\n",
1402				isc_result_totext(isc_result));
1403		isc_mem_destroy(&mctx);
1404		return(T_UNRESOLVED);
1405	}
1406
1407	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
1408	if (isc_result != ISC_R_SUCCESS) {
1409		t_info("isc_hash_create failed %s\n",
1410				isc_result_totext(isc_result));
1411		isc_entropy_detach(&ectx);
1412		isc_mem_destroy(&mctx);
1413		return(T_UNRESOLVED);
1414	}
1415
1416	dns_result = t_create(db_type, origin, class, model, mctx, &db);
1417	if (dns_result != ISC_R_SUCCESS) {
1418		isc_hash_destroy();
1419		isc_entropy_detach(&ectx);
1420		isc_mem_destroy(&mctx);
1421		return(T_UNRESOLVED);
1422	}
1423
1424	dns_result = dns_db_load(db, filename);
1425	if (dns_result != ISC_R_SUCCESS) {
1426		t_info("dns_db_load returned %s\n",
1427				dns_result_totext(dns_result));
1428		dns_db_detach(&db);
1429		isc_hash_destroy();
1430		isc_entropy_detach(&ectx);
1431		isc_mem_destroy(&mctx);
1432		return(T_UNRESOLVED);
1433	}
1434
1435	/*
1436	 * Remove all rdata for an existing name.
1437	 */
1438
1439	dns_fixedname_init(&dns_existingname);
1440	len = strlen(existing_name);
1441	isc_buffer_init(&name_buffer, existing_name, len);
1442	isc_buffer_add(&name_buffer, len);
1443	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
1444			&name_buffer, NULL, 0, NULL);
1445	if (dns_result != ISC_R_SUCCESS) {
1446		t_info("dns_name_fromtext failed %s\n",
1447			dns_result_totext(dns_result));
1448		dns_db_detach(&db);
1449		isc_hash_destroy();
1450		isc_entropy_detach(&ectx);
1451		isc_mem_destroy(&mctx);
1452		return(T_UNRESOLVED);
1453	}
1454
1455	textregion.base = existing_type;
1456	textregion.length = strlen(existing_type);
1457	dns_result = dns_rdatatype_fromtext(&existing_rdatatype, &textregion);
1458	if (dns_result != ISC_R_SUCCESS) {
1459		t_info("dns_rdatatype_fromtext %s failed %s\n",
1460				existing_type,
1461				dns_result_totext(dns_result));
1462		dns_db_detachnode(db, &nodep);
1463		dns_db_detach(&db);
1464		isc_hash_destroy();
1465		isc_entropy_detach(&ectx);
1466		isc_mem_destroy(&mctx);
1467		return(T_UNRESOLVED);
1468	}
1469
1470	nodep = NULL;
1471	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname),
1472				ISC_FALSE, &nodep);
1473	if (dns_result != ISC_R_SUCCESS) {
1474		t_info("dns_db_findnode %s\n",
1475				dns_result_totext(dns_result));
1476		dns_db_detach(&db);
1477		isc_hash_destroy();
1478		isc_entropy_detach(&ectx);
1479		isc_mem_destroy(&mctx);
1480		return(T_UNRESOLVED);
1481	}
1482
1483	/* open a new version */
1484	nversionp = NULL;
1485	dns_result = dns_db_newversion(db, &nversionp);
1486	if (dns_result != ISC_R_SUCCESS) {
1487		t_info("dns_db_newversion failed %s\n",
1488				dns_result_totext(dns_result));
1489		dns_db_detachnode(db, &nodep);
1490		dns_db_detach(&db);
1491		isc_hash_destroy();
1492		isc_entropy_detach(&ectx);
1493		isc_mem_destroy(&mctx);
1494		return(T_UNRESOLVED);
1495	}
1496
1497	dns_result = dns_db_deleterdataset(db, nodep, nversionp,
1498					   existing_rdatatype, 0);
1499	if (dns_result != ISC_R_SUCCESS) {
1500		t_info("dns_db_deleterdataset failed %s\n",
1501				dns_result_totext(dns_result));
1502		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1503		dns_db_detachnode(db, &nodep);
1504		dns_db_detach(&db);
1505		isc_hash_destroy();
1506		isc_entropy_detach(&ectx);
1507		isc_mem_destroy(&mctx);
1508		return(T_UNRESOLVED);
1509	}
1510
1511	/*
1512	 * add a new name and associate some rdata with it
1513	 */
1514
1515	dns_db_detachnode(db, &nodep);
1516	nodep = NULL;
1517
1518	dns_fixedname_init(&dns_newname);
1519	len = strlen(new_name);
1520	isc_buffer_init(&name_buffer, new_name, len);
1521	isc_buffer_add(&name_buffer, len);
1522	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
1523				&name_buffer, NULL, 0, NULL);
1524	if (dns_result != ISC_R_SUCCESS) {
1525		t_info("dns_name_fromtext failed %s\n",
1526			dns_result_totext(dns_result));
1527		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1528		dns_db_detach(&db);
1529		isc_hash_destroy();
1530		isc_entropy_detach(&ectx);
1531		isc_mem_destroy(&mctx);
1532		return(T_UNRESOLVED);
1533	}
1534
1535	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname),
1536				ISC_TRUE, &nodep);
1537	if (dns_result != ISC_R_SUCCESS) {
1538		t_info("dns_db_findnode failed %s\n",
1539				dns_result_totext(dns_result));
1540		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1541		dns_db_detach(&db);
1542		isc_hash_destroy();
1543		isc_entropy_detach(&ectx);
1544		isc_mem_destroy(&mctx);
1545		return(T_UNRESOLVED);
1546	}
1547
1548	/*
1549	 * associate some rdata with the new name
1550	 */
1551
1552	textregion.base = new_type;
1553	textregion.length = strlen(new_type);
1554	dns_result = dns_rdatatype_fromtext(&new_rdatatype, &textregion);
1555	if (dns_result != ISC_R_SUCCESS) {
1556		t_info("dns_rdatatype_fromtext %s failed %s\n",
1557				new_type,
1558				dns_result_totext(dns_result));
1559		dns_db_detachnode(db, &nodep);
1560		dns_db_detach(&db);
1561		isc_hash_destroy();
1562		isc_entropy_detach(&ectx);
1563		isc_mem_destroy(&mctx);
1564		return(T_UNRESOLVED);
1565	}
1566
1567	textregion.base = class;
1568	textregion.length = strlen(class);
1569	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
1570	if (dns_result != ISC_R_SUCCESS) {
1571		t_info("dns_rdataclass_fromtext failed %s\n",
1572				dns_result_totext(dns_result));
1573		dns_db_detachnode(db, &nodep);
1574		dns_db_detach(&db);
1575		isc_hash_destroy();
1576		isc_entropy_detach(&ectx);
1577		isc_mem_destroy(&mctx);
1578		return(T_UNRESOLVED);
1579	}
1580
1581	dns_rdata_init(&added_rdata);
1582	added_rdata_data = "\x10\x00\x00\x01";
1583	DE_CONST(added_rdata_data, added_rdata.data);
1584	added_rdata.length = 4;
1585	added_rdata.rdclass = rdataclass;
1586	added_rdata.type = new_rdatatype;
1587
1588	dns_rdataset_init(&added_rdataset);
1589	rdatalist.type = new_rdatatype;
1590	rdatalist.covers = 0;
1591	rdatalist.rdclass = rdataclass;
1592	rdatalist.ttl = 0;
1593	ISC_LIST_INIT(rdatalist.rdata);
1594	ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link);
1595
1596	dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset);
1597	if (dns_result != ISC_R_SUCCESS) {
1598		t_info("dns_rdatalist_tordataset failed %s\n",
1599				dns_result_totext(dns_result));
1600		dns_db_detachnode(db, &nodep);
1601		dns_db_detach(&db);
1602		isc_hash_destroy();
1603		isc_entropy_detach(&ectx);
1604		isc_mem_destroy(&mctx);
1605		return(T_UNRESOLVED);
1606	}
1607
1608	dns_result = dns_db_addrdataset(db, nodep, nversionp, 0,
1609				&added_rdataset, 0, NULL);
1610	if (dns_result != ISC_R_SUCCESS) {
1611		t_info("dns_db_addrdataset failed %s\n",
1612				dns_result_totext(dns_result));
1613		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1614		dns_db_detachnode(db, &nodep);
1615		dns_db_detach(&db);
1616		isc_hash_destroy();
1617		isc_entropy_detach(&ectx);
1618		isc_mem_destroy(&mctx);
1619		return(T_UNRESOLVED);
1620	}
1621
1622	/* close and commit the version */
1623	dns_db_closeversion(db, &nversionp, ISC_TRUE);
1624	dns_db_detachnode(db, &nodep);
1625	nodep = NULL;
1626
1627	/* open the current version and check changes */
1628	dns_fixedname_init(&dns_foundname);
1629	dns_rdataset_init(&found_rdataset);
1630	cversionp = NULL;
1631	dns_db_currentversion(db, &cversionp);
1632
1633	/* find the recently added name and rdata */
1634	dns_result = dns_db_find(db,
1635			dns_fixedname_name(&dns_newname),
1636			cversionp,
1637			new_rdatatype,
1638			0,
1639			0,
1640			&nodep,
1641			dns_fixedname_name(&dns_foundname),
1642			&found_rdataset, NULL);
1643
1644	if (dns_result != ISC_R_SUCCESS) {
1645		/* XXXWPK NXRRSET ??? reference counting ??? */
1646		t_info("dns_db_find failed %s\n",
1647				dns_result_totext(dns_result));
1648		dns_db_closeversion(db, &cversionp, ISC_FALSE);
1649		dns_db_detachnode(db, &nodep);
1650		if (dns_rdataset_isassociated(&found_rdataset))
1651			dns_rdataset_disassociate(&found_rdataset);
1652		dns_db_detach(&db);
1653		isc_hash_destroy();
1654		isc_entropy_detach(&ectx);
1655		isc_mem_destroy(&mctx);
1656		return(T_FAIL);
1657	}
1658
1659	dns_result = dns_rdataset_first(&found_rdataset);
1660	if (dns_result != ISC_R_SUCCESS) {
1661		t_info("dns_rdataset_first failed %s\n",
1662				dns_result_totext(dns_result));
1663		dns_db_detachnode(db, &nodep);
1664		if (dns_rdataset_isassociated(&found_rdataset))
1665			dns_rdataset_disassociate(&found_rdataset);
1666		dns_db_closeversion(db, &cversionp, ISC_FALSE);
1667		dns_db_detach(&db);
1668		isc_hash_destroy();
1669		isc_entropy_detach(&ectx);
1670		isc_mem_destroy(&mctx);
1671		return(T_FAIL);
1672	}
1673
1674	/*
1675	 * Now make sure its what we expect.
1676	 */
1677	dns_rdata_init(&found_rdata);
1678	dns_rdataset_current(&found_rdataset, &found_rdata);
1679	rval = dns_rdata_compare(&added_rdata, &found_rdata);
1680	if (rval != 0) {
1681		t_info("dns_rdata_compare returned %d\n", rval);
1682		++nfails;
1683	}
1684
1685	/*
1686	 * Now check the rdata deletion.
1687	 */
1688
1689	if (dns_rdataset_isassociated(&found_rdataset))
1690		dns_rdataset_disassociate(&found_rdataset);
1691	dns_rdataset_init(&found_rdataset);
1692	dns_db_detachnode(db, &nodep);
1693	nodep = NULL;
1694	dns_fixedname_init(&dns_foundname);
1695
1696	dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname),
1697				 cversionp, existing_rdatatype,
1698				 0, 0, &nodep,
1699				 dns_fixedname_name(&dns_foundname),
1700				 &found_rdataset, NULL);
1701
1702
1703	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
1704		dns_rdataset_disassociate(&found_rdataset);
1705		dns_db_detachnode(db, &nodep);
1706		t_info("dns_db_find %s returned %s\n", existing_name,
1707		       dns_result_totext(dns_result));
1708		++nfails;
1709	}
1710
1711	dns_db_closeversion(db, &cversionp, ISC_FALSE);
1712	dns_db_detach(&db);
1713	isc_hash_destroy();
1714	isc_entropy_detach(&ectx);
1715	isc_mem_destroy(&mctx);
1716
1717	if (nfails == 0)
1718		result = T_PASS;
1719	else
1720		result = T_FAIL;
1721
1722	return(result);
1723}
1724
1725static void
1726t10(void) {
1727	int	result;
1728
1729	t_assert("dns_db_closeversion", 10, T_REQUIRED, "%s", a10);
1730	result = t_eval("dns_db_closeversion_1_data",
1731			t_dns_db_closeversion_1, 9);
1732	t_result(result);
1733}
1734
1735static const char *a11 =
1736	"When versionp points to a read-write version and commit is "
1737	"ISC_FALSE, a call to dns_db_closeversion(db, versionp, commit) "
1738	"causes all changes made in the version to to be rolled back, "
1739	"and returns ISC_R_SUCCESS.";
1740
1741static int
1742t_dns_db_closeversion_2(char **av) {
1743	char			*filename;
1744	char			*db_type;
1745	char			*origin;
1746	char			*class;
1747	char			*model;
1748	char			*new_name;
1749	char			*new_type;
1750	char			*existing_name;
1751	char			*existing_type;
1752
1753	int			result;
1754	int			len;
1755	int			rval;
1756	int			nfails;
1757	dns_db_t		*db;
1758	isc_result_t		dns_result;
1759	isc_result_t		isc_result;
1760	isc_mem_t		*mctx;
1761	isc_entropy_t		*ectx;
1762	dns_dbnode_t		*nodep;
1763	isc_textregion_t	textregion;
1764	isc_buffer_t		name_buffer;
1765	dns_fixedname_t		dns_newname;
1766	dns_fixedname_t		dns_foundname;
1767	dns_fixedname_t		dns_existingname;
1768	dns_rdata_t		added_rdata = DNS_RDATA_INIT;
1769	const char *		added_rdata_data;
1770	dns_rdataset_t		added_rdataset;
1771	dns_rdata_t		found_rdata = DNS_RDATA_INIT;
1772	dns_rdataset_t		found_rdataset;
1773	dns_rdatatype_t		new_rdatatype;
1774	dns_rdatatype_t		existing_rdatatype;
1775	dns_rdataclass_t	rdataclass;
1776	dns_dbversion_t		*nversionp;
1777	dns_dbversion_t		*cversionp;
1778	dns_rdatalist_t		rdatalist;
1779
1780	filename = T_ARG(0);
1781	db_type = T_ARG(1);
1782	origin = T_ARG(2);
1783	class = T_ARG(3);
1784	model = T_ARG(4);
1785	new_name = T_ARG(5);
1786	new_type = T_ARG(6);
1787	existing_name = T_ARG(7);
1788	existing_type = T_ARG(8);
1789
1790	nfails = 0;
1791	db = NULL;
1792	mctx = NULL;
1793	ectx = NULL;
1794
1795	/*
1796	 * Open a new version, add some data,
1797	 * remove some data, close with commit, open the current
1798	 * version and check that changes are present.
1799	 */
1800
1801	t_info("testing using file %s and name %s\n", filename, new_name);
1802
1803	isc_result = isc_mem_create(0, 0, &mctx);
1804	if (isc_result != ISC_R_SUCCESS) {
1805		t_info("isc_mem_create failed %s\n",
1806				isc_result_totext(isc_result));
1807		return(T_UNRESOLVED);
1808	}
1809
1810	isc_result = isc_entropy_create(mctx, &ectx);
1811	if (isc_result != ISC_R_SUCCESS) {
1812		t_info("isc_entropy_create failed %s\n",
1813				isc_result_totext(isc_result));
1814		isc_mem_destroy(&mctx);
1815		return(T_UNRESOLVED);
1816	}
1817
1818	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
1819	if (isc_result != ISC_R_SUCCESS) {
1820		t_info("isc_hash_create failed %s\n",
1821				isc_result_totext(isc_result));
1822		isc_entropy_detach(&ectx);
1823		isc_mem_destroy(&mctx);
1824		return(T_UNRESOLVED);
1825	}
1826
1827	dns_result = t_create(db_type, origin, class, model, mctx, &db);
1828	if (dns_result != ISC_R_SUCCESS) {
1829		isc_hash_destroy();
1830		isc_entropy_detach(&ectx);
1831		isc_mem_destroy(&mctx);
1832		return(T_UNRESOLVED);
1833	}
1834
1835	dns_result = dns_db_load(db, filename);
1836	if (dns_result != ISC_R_SUCCESS) {
1837		t_info("dns_db_load returned %s\n",
1838				dns_result_totext(dns_result));
1839		dns_db_detach(&db);
1840		isc_hash_destroy();
1841		isc_entropy_detach(&ectx);
1842		isc_mem_destroy(&mctx);
1843		return(T_UNRESOLVED);
1844	}
1845
1846	/*
1847	 * Remove all rdata for an existing name.
1848	 */
1849
1850	dns_fixedname_init(&dns_existingname);
1851	len = strlen(existing_name);
1852	isc_buffer_init(&name_buffer, existing_name, len);
1853	isc_buffer_add(&name_buffer, len);
1854	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
1855			&name_buffer, NULL, 0, NULL);
1856	if (dns_result != ISC_R_SUCCESS) {
1857		t_info("dns_name_fromtext failed %s\n",
1858			dns_result_totext(dns_result));
1859		dns_db_detach(&db);
1860		isc_hash_destroy();
1861		isc_entropy_detach(&ectx);
1862		isc_mem_destroy(&mctx);
1863		return(T_UNRESOLVED);
1864	}
1865
1866	textregion.base = existing_type;
1867	textregion.length = strlen(existing_type);
1868	dns_result = dns_rdatatype_fromtext(&existing_rdatatype, &textregion);
1869	if (dns_result != ISC_R_SUCCESS) {
1870		t_info("dns_rdatatype_fromtext %s failed %s\n",
1871				existing_type,
1872				dns_result_totext(dns_result));
1873		dns_db_detachnode(db, &nodep);
1874		dns_db_detach(&db);
1875		isc_hash_destroy();
1876		isc_entropy_detach(&ectx);
1877		isc_mem_destroy(&mctx);
1878		return(T_UNRESOLVED);
1879	}
1880
1881	nodep = NULL;
1882	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname),
1883				ISC_FALSE, &nodep);
1884	if (dns_result != ISC_R_SUCCESS) {
1885		t_info("dns_db_findnode %s\n",
1886				dns_result_totext(dns_result));
1887		dns_db_detach(&db);
1888		isc_hash_destroy();
1889		isc_entropy_detach(&ectx);
1890		isc_mem_destroy(&mctx);
1891		return(T_UNRESOLVED);
1892	}
1893
1894	/*
1895	 * Open a new version.
1896	 */
1897	nversionp = NULL;
1898	dns_result = dns_db_newversion(db, &nversionp);
1899	if (dns_result != ISC_R_SUCCESS) {
1900		t_info("dns_db_newversion failed %s\n",
1901				dns_result_totext(dns_result));
1902		dns_db_detachnode(db, &nodep);
1903		dns_db_detach(&db);
1904		isc_hash_destroy();
1905		isc_entropy_detach(&ectx);
1906		isc_mem_destroy(&mctx);
1907		return(T_UNRESOLVED);
1908	}
1909
1910	dns_result = dns_db_deleterdataset(db, nodep, nversionp,
1911					   existing_rdatatype, 0);
1912	if (dns_result != ISC_R_SUCCESS) {
1913		t_info("dns_db_deleterdataset failed %s\n",
1914				dns_result_totext(dns_result));
1915		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1916		dns_db_detachnode(db, &nodep);
1917		dns_db_detach(&db);
1918		isc_hash_destroy();
1919		isc_entropy_detach(&ectx);
1920		isc_mem_destroy(&mctx);
1921		return(T_UNRESOLVED);
1922	}
1923
1924	/*
1925	 * add a new name and associate some rdata with it
1926	 */
1927
1928	dns_db_detachnode(db, &nodep);
1929	nodep = NULL;
1930
1931	dns_fixedname_init(&dns_newname);
1932	len = strlen(new_name);
1933	isc_buffer_init(&name_buffer, new_name, len);
1934	isc_buffer_add(&name_buffer, len);
1935	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
1936				       &name_buffer, NULL, 0, NULL);
1937	if (dns_result != ISC_R_SUCCESS) {
1938		t_info("dns_name_fromtext failed %s\n",
1939		       dns_result_totext(dns_result));
1940		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1941		dns_db_detach(&db);
1942		isc_hash_destroy();
1943		isc_entropy_detach(&ectx);
1944		isc_mem_destroy(&mctx);
1945		return(T_UNRESOLVED);
1946	}
1947
1948	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname),
1949				     ISC_TRUE, &nodep);
1950	if (dns_result != ISC_R_SUCCESS) {
1951		t_info("dns_db_findnode failed %s\n",
1952		       dns_result_totext(dns_result));
1953		dns_db_closeversion(db, &nversionp, ISC_FALSE);
1954		dns_db_detach(&db);
1955		isc_hash_destroy();
1956		isc_entropy_detach(&ectx);
1957		isc_mem_destroy(&mctx);
1958		return(T_UNRESOLVED);
1959	}
1960
1961	textregion.base = new_type;
1962	textregion.length = strlen(new_type);
1963	dns_result = dns_rdatatype_fromtext(&new_rdatatype, &textregion);
1964	if (dns_result != ISC_R_SUCCESS) {
1965		t_info("dns_rdatatype_fromtext %s failed %s\n",
1966		       new_type, dns_result_totext(dns_result));
1967		dns_db_detachnode(db, &nodep);
1968		dns_db_detach(&db);
1969		isc_hash_destroy();
1970		isc_entropy_detach(&ectx);
1971		isc_mem_destroy(&mctx);
1972		return(T_UNRESOLVED);
1973	}
1974
1975	textregion.base = class;
1976	textregion.length = strlen(class);
1977	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
1978	if (dns_result != ISC_R_SUCCESS) {
1979		t_info("dns_rdataclass_fromtext failed %s\n",
1980		       dns_result_totext(dns_result));
1981		dns_db_detachnode(db, &nodep);
1982		dns_db_detach(&db);
1983		isc_hash_destroy();
1984		isc_entropy_detach(&ectx);
1985		isc_mem_destroy(&mctx);
1986		return(T_UNRESOLVED);
1987	}
1988
1989	dns_rdata_init(&added_rdata);
1990	added_rdata_data = "\x10\x00\x00\x01";
1991	DE_CONST(added_rdata_data, added_rdata.data);
1992	added_rdata.length = 4;
1993	added_rdata.rdclass = rdataclass;
1994	added_rdata.type = new_rdatatype;
1995
1996	dns_rdataset_init(&added_rdataset);
1997	rdatalist.type = new_rdatatype;
1998	rdatalist.covers = 0;
1999	rdatalist.rdclass = rdataclass;
2000	rdatalist.ttl = 0;
2001	ISC_LIST_INIT(rdatalist.rdata);
2002	ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link);
2003
2004	dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset);
2005	if (dns_result != ISC_R_SUCCESS) {
2006		t_info("dns_rdatalist_tordataset failed %s\n",
2007		       dns_result_totext(dns_result));
2008		dns_db_detachnode(db, &nodep);
2009		dns_db_detach(&db);
2010		isc_hash_destroy();
2011		isc_entropy_detach(&ectx);
2012		isc_mem_destroy(&mctx);
2013		return(T_UNRESOLVED);
2014	}
2015
2016	dns_result = dns_db_addrdataset(db, nodep, nversionp, 0,
2017				&added_rdataset, 0, NULL);
2018	if (dns_result != ISC_R_SUCCESS) {
2019		t_info("dns_db_addrdataset failed %s\n",
2020		       dns_result_totext(dns_result));
2021		dns_db_closeversion(db, &nversionp, ISC_FALSE);
2022		dns_db_detachnode(db, &nodep);
2023		dns_db_detach(&db);
2024		isc_hash_destroy();
2025		isc_entropy_detach(&ectx);
2026		isc_mem_destroy(&mctx);
2027		return(T_UNRESOLVED);
2028	}
2029
2030	/*
2031	 * Check that our changes took.
2032	 */
2033	dns_db_detachnode(db, &nodep);
2034	nodep = NULL;
2035	dns_fixedname_init(&dns_foundname);
2036	dns_rdataset_init(&found_rdataset);
2037
2038	/*
2039	 * Find the recently added name and rdata.
2040	 */
2041	dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname),
2042				 nversionp, new_rdatatype, 0, 0, &nodep,
2043				 dns_fixedname_name(&dns_foundname),
2044				 &found_rdataset, NULL);
2045
2046	if ((dns_result == ISC_R_NOTFOUND) ||
2047	    (dns_result == DNS_R_NXDOMAIN) ||
2048	    (dns_result == DNS_R_NXRRSET)) {
2049
2050		t_info("dns_db_find failed %s\n",
2051		       dns_result_totext(dns_result));
2052		dns_db_closeversion(db, &nversionp, ISC_FALSE);
2053		dns_db_detachnode(db, &nodep);
2054		if (dns_rdataset_isassociated(&found_rdataset))
2055			dns_rdataset_disassociate(&found_rdataset);
2056		dns_db_detach(&db);
2057		isc_hash_destroy();
2058		isc_entropy_detach(&ectx);
2059		isc_mem_destroy(&mctx);
2060		return(T_FAIL);
2061	}
2062
2063	dns_result = dns_rdataset_first(&found_rdataset);
2064	if (dns_result != ISC_R_SUCCESS) {
2065		t_info("dns_rdataset_first failed %s\n",
2066				dns_result_totext(dns_result));
2067		dns_db_detachnode(db, &nodep);
2068		if (dns_rdataset_isassociated(&found_rdataset))
2069			dns_rdataset_disassociate(&found_rdataset);
2070		dns_db_closeversion(db, &nversionp, ISC_FALSE);
2071		dns_db_detach(&db);
2072		isc_hash_destroy();
2073		isc_entropy_detach(&ectx);
2074		isc_mem_destroy(&mctx);
2075		return(T_FAIL);
2076	}
2077
2078	/*
2079	 * Now make sure its what we expect.
2080	 */
2081	dns_rdata_init(&found_rdata);
2082	dns_rdataset_current(&found_rdataset, &found_rdata);
2083	rval = dns_rdata_compare(&added_rdata, &found_rdata);
2084	if (rval != 0) {
2085		t_info("dns_rdata_compare returned %d\n", rval);
2086		++nfails;
2087	}
2088
2089	/*
2090	 * Now check the rdata deletion.
2091	 */
2092	if (dns_rdataset_isassociated(&found_rdataset))
2093		dns_rdataset_disassociate(&found_rdataset);
2094	dns_rdataset_init(&found_rdataset);
2095	dns_db_detachnode(db, &nodep);
2096	nodep = NULL;
2097	dns_fixedname_init(&dns_foundname);
2098
2099	dns_result = dns_db_find(db,
2100			dns_fixedname_name(&dns_existingname),
2101			nversionp,
2102			existing_rdatatype,
2103			0,
2104			0,
2105			&nodep,
2106			dns_fixedname_name(&dns_foundname),
2107			&found_rdataset, NULL);
2108
2109
2110	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2111		t_info("dns_db_find %s returned %s\n", existing_name,
2112		       dns_result_totext(dns_result));
2113		if (dns_rdataset_isassociated(&found_rdataset))
2114			dns_rdataset_disassociate(&found_rdataset);
2115		dns_db_detachnode(db, &nodep);
2116		++nfails;
2117	}
2118
2119
2120	/*
2121	 * Close the version without a commit.
2122	 */
2123	dns_db_closeversion(db, &nversionp, ISC_FALSE);
2124
2125	/*
2126	 * Open the current version and check changes.
2127	 */
2128	dns_fixedname_init(&dns_foundname);
2129	dns_rdataset_init(&found_rdataset);
2130	cversionp = NULL;
2131	dns_db_currentversion(db, &cversionp);
2132
2133	/*
2134	 * Find the recently added name and rdata.
2135	 */
2136	dns_result = dns_db_find(db,
2137			dns_fixedname_name(&dns_newname),
2138			cversionp,
2139			new_rdatatype,
2140			0,
2141			0,
2142			&nodep,
2143			dns_fixedname_name(&dns_foundname),
2144			&found_rdataset, NULL);
2145
2146	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2147		t_info("dns_db_find %s returned %s\n", new_name,
2148				dns_result_totext(dns_result));
2149		dns_rdataset_disassociate(&found_rdataset);
2150		dns_db_detachnode(db, &nodep);
2151		dns_db_closeversion(db, &cversionp, ISC_FALSE);
2152		dns_db_detach(&db);
2153		isc_hash_destroy();
2154		isc_entropy_detach(&ectx);
2155		isc_mem_destroy(&mctx);
2156		return(T_FAIL);
2157	}
2158
2159	/*
2160	 * Now check the rdata deletion.
2161	 */
2162	nodep = NULL;
2163	dns_rdataset_init(&found_rdataset);
2164	dns_fixedname_init(&dns_foundname);
2165
2166	dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname),
2167				 cversionp, existing_rdatatype, 0, 0,
2168				 &nodep, dns_fixedname_name(&dns_foundname),
2169				 &found_rdataset, NULL);
2170
2171
2172	if ((dns_result == ISC_R_NOTFOUND) ||
2173	    (dns_result == DNS_R_NXDOMAIN) ||
2174	    (dns_result == DNS_R_NXRRSET)) {
2175
2176		t_info("dns_db_find %s returned %s\n", existing_name,
2177		       dns_result_totext(dns_result));
2178		dns_rdataset_disassociate(&found_rdataset);
2179		dns_db_detachnode(db, &nodep);
2180		++nfails;
2181	}
2182
2183	dns_db_detachnode(db, &nodep);
2184	dns_rdataset_disassociate(&found_rdataset);
2185	dns_db_closeversion(db, &cversionp, ISC_FALSE);
2186	dns_db_detach(&db);
2187	isc_hash_destroy();
2188	isc_entropy_detach(&ectx);
2189	isc_mem_destroy(&mctx);
2190
2191	if (nfails == 0)
2192		result = T_PASS;
2193	else
2194		result = T_FAIL;
2195
2196	return(result);
2197}
2198
2199static void
2200t11(void) {
2201	int	result;
2202
2203	t_assert("dns_db_closeversion", 11, T_REQUIRED, "%s", a11);
2204	result = t_eval("dns_db_closeversion_2_data",
2205			t_dns_db_closeversion_2, 9);
2206	t_result(result);
2207}
2208
2209static const char *a12 =
2210	"A call to dns_db_expirenode() marks as stale all records at node  "
2211	"which expire at or before 'now'. If 'now' is zero, then the current  "
2212	"time will be used.";
2213
2214static int
2215t_dns_db_expirenode(char **av) {
2216	char			*filename;
2217	char			*db_type;
2218	char			*origin;
2219	char			*class;
2220	char			*existing_name;
2221	char			*node_xtime;
2222	char			*find_xtime;
2223	char			*exp_find_result;
2224
2225	int			result;
2226	int			len;
2227	dns_db_t		*db;
2228	isc_result_t		dns_result;
2229	isc_result_t		exp_result;
2230	isc_result_t		isc_result;
2231	isc_mem_t		*mctx;
2232	isc_entropy_t		*ectx;
2233	dns_dbnode_t		*nodep;
2234	isc_buffer_t		name_buffer;
2235	dns_fixedname_t		dns_foundname;
2236	dns_fixedname_t		dns_existingname;
2237	isc_stdtime_t		node_expire_time;
2238	isc_stdtime_t		find_expire_time;
2239	isc_stdtime_t		now;
2240	dns_rdataset_t		rdataset;
2241
2242	filename = T_ARG(0);
2243	db_type = T_ARG(1);
2244	origin = T_ARG(2);
2245	class = T_ARG(3);
2246	existing_name = T_ARG(4);
2247	node_xtime = T_ARG(5);
2248	find_xtime = T_ARG(6);
2249	exp_find_result = T_ARG(7);
2250	mctx = NULL;
2251	ectx = NULL;
2252
2253	/*
2254	 * Find a node, mark it as stale, do a dns_db_find on the name and
2255	 * expect it to fail.
2256	 */
2257
2258	t_info("testing using file %s and name %s\n", filename, existing_name);
2259
2260	node_expire_time = (isc_stdtime_t) strtol(node_xtime, NULL, 10);
2261	find_expire_time = (isc_stdtime_t) strtol(find_xtime, NULL, 10);
2262	exp_result = t_dns_result_fromtext(exp_find_result);
2263
2264	isc_stdtime_get(&now);
2265
2266	dns_fixedname_init(&dns_existingname);
2267	len = strlen(existing_name);
2268	isc_buffer_init(&name_buffer, existing_name, len);
2269	isc_buffer_add(&name_buffer, len);
2270	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
2271				       &name_buffer, NULL, 0, NULL);
2272	if (dns_result != ISC_R_SUCCESS) {
2273		t_info("dns_name_fromtext failed %s\n",
2274		       dns_result_totext(dns_result));
2275		return(T_UNRESOLVED);
2276	}
2277
2278	isc_result = isc_mem_create(0, 0, &mctx);
2279	if (isc_result != ISC_R_SUCCESS) {
2280		t_info("isc_mem_create failed %s\n",
2281		       isc_result_totext(isc_result));
2282		return(T_UNRESOLVED);
2283	}
2284
2285	isc_result = isc_entropy_create(mctx, &ectx);
2286	if (isc_result != ISC_R_SUCCESS) {
2287		t_info("isc_entropy_create failed %s\n",
2288				isc_result_totext(isc_result));
2289		isc_mem_destroy(&mctx);
2290		return(T_UNRESOLVED);
2291	}
2292
2293	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2294	if (isc_result != ISC_R_SUCCESS) {
2295		t_info("isc_hash_create failed %s\n",
2296				isc_result_totext(isc_result));
2297		isc_entropy_detach(&ectx);
2298		isc_mem_destroy(&mctx);
2299		return(T_UNRESOLVED);
2300	}
2301
2302	db = NULL;
2303	dns_result = t_create(db_type, origin, class, "cache", mctx, &db);
2304	if (dns_result != ISC_R_SUCCESS) {
2305		isc_hash_destroy();
2306		isc_entropy_detach(&ectx);
2307		isc_mem_destroy(&mctx);
2308		return(T_UNRESOLVED);
2309	}
2310
2311	dns_result = dns_db_load(db, filename);
2312	if (dns_result != ISC_R_SUCCESS) {
2313		t_info("dns_db_load returned %s\n",
2314		       dns_result_totext(dns_result));
2315		dns_db_detach(&db);
2316		isc_hash_destroy();
2317		isc_entropy_detach(&ectx);
2318		isc_mem_destroy(&mctx);
2319		return(T_UNRESOLVED);
2320	}
2321
2322	nodep = NULL;
2323
2324	/*
2325	 * Check that the node is there.
2326	 */
2327	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname),
2328				     ISC_FALSE, &nodep);
2329	if (dns_result != ISC_R_SUCCESS) {
2330		t_info("unable to find %s\n", existing_name);
2331		dns_db_detach(&db);
2332		isc_hash_destroy();
2333		isc_entropy_detach(&ectx);
2334		isc_mem_destroy(&mctx);
2335		return(T_UNRESOLVED);
2336	}
2337
2338	/*
2339	 * Expire it.
2340	 */
2341	if (node_expire_time != 0)
2342		node_expire_time += now;
2343
2344	dns_result = dns_db_expirenode(db, nodep, node_expire_time);
2345	if (dns_result != ISC_R_SUCCESS) {
2346		t_info("dns_db_expirenode failed %s\n",
2347		       dns_result_totext(dns_result));
2348		dns_db_detachnode(db, &nodep);
2349		dns_db_detach(&db);
2350		isc_hash_destroy();
2351		isc_entropy_detach(&ectx);
2352		isc_mem_destroy(&mctx);
2353		return(T_FAIL);
2354	}
2355
2356	dns_fixedname_init(&dns_foundname);
2357	dns_rdataset_init(&rdataset);
2358	dns_db_detachnode(db, &nodep);
2359	nodep = NULL;
2360
2361	if (find_expire_time != 0)
2362		find_expire_time += now;
2363
2364	dns_result = dns_db_find(db,
2365				 dns_fixedname_name(&dns_existingname),
2366				 NULL,
2367				 dns_rdatatype_any,
2368				 0,
2369				 find_expire_time,
2370				 &nodep,
2371				 dns_fixedname_name(&dns_foundname),
2372				 &rdataset, NULL);
2373
2374	if (dns_result == exp_result) {
2375		result = T_PASS;
2376	} else {
2377		t_info("dns_db_find %s returned %s\n", existing_name,
2378		       dns_result_totext(dns_result));
2379		result = T_FAIL;
2380	}
2381
2382	if ((dns_result != ISC_R_NOTFOUND) &&
2383	    (dns_result != DNS_R_NXDOMAIN) &&
2384	    (dns_result != DNS_R_NXRRSET)) {
2385
2386		/*
2387		 * Don't need to disassociate the rdataset because
2388		 * we're searching with dns_rdatatype_any.
2389		 */
2390		dns_db_detachnode(db, &nodep);
2391	}
2392
2393
2394	dns_db_detach(&db);
2395	isc_hash_destroy();
2396	isc_entropy_detach(&ectx);
2397	isc_mem_destroy(&mctx);
2398
2399	return(result);
2400}
2401
2402static void
2403t12(void) {
2404	int	result;
2405
2406	t_assert("dns_db_expirenode", 12, T_REQUIRED, "%s", a12);
2407	result = t_eval("dns_db_expirenode_data", t_dns_db_expirenode, 8);
2408	t_result(result);
2409}
2410
2411static const char *a13 =
2412	"If the node name exists, then a call to "
2413	"dns_db_findnode(db, name, ISC_FALSE, nodep) initializes nodep "
2414	"to point to the node and returns ISC_R_SUCCESS, otherwise "
2415	"it returns ISC_R_NOTFOUND.";
2416
2417static int
2418t_dns_db_findnode_1(char **av) {
2419	char		*filename;
2420	char		*db_type;
2421	char		*origin;
2422	char		*class;
2423	char		*model;
2424	char		*find_name;
2425	char		*find_type;
2426	char		*expected_result;
2427
2428	int			result;
2429	int			len;
2430	dns_db_t		*db;
2431	isc_result_t		dns_result;
2432	isc_result_t		isc_result;
2433	isc_mem_t		*mctx;
2434	isc_entropy_t		*ectx;
2435	dns_dbnode_t		*nodep;
2436	isc_buffer_t		name_buffer;
2437	dns_rdataset_t		rdataset;
2438	dns_rdatatype_t		rdatatype;
2439	isc_textregion_t	textregion;
2440	dns_fixedname_t		dns_name;
2441	dns_dbversion_t		*cversionp;
2442	isc_result_t		exp_result;
2443
2444	filename = T_ARG(0);
2445	db_type = T_ARG(1);
2446	origin = T_ARG(2);
2447	class = T_ARG(3);
2448	model = T_ARG(4);
2449	find_name = T_ARG(5);
2450	find_type = T_ARG(6);
2451	expected_result = T_ARG(7);
2452
2453	db = NULL;
2454	mctx = NULL;
2455	ectx = NULL;
2456
2457	t_info("testing using file %s and name %s\n", filename, find_name);
2458
2459	exp_result = t_dns_result_fromtext(expected_result);
2460
2461	textregion.base = find_type;
2462	textregion.length = strlen(find_type);
2463	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
2464	if (dns_result != ISC_R_SUCCESS) {
2465		t_info("dns_rdatatype_fromtext %s failed %s\n",
2466				find_type,
2467				dns_result_totext(dns_result));
2468		return(T_UNRESOLVED);
2469	}
2470
2471	isc_result = isc_mem_create(0, 0, &mctx);
2472	if (isc_result != ISC_R_SUCCESS) {
2473		t_info("isc_mem_create failed %s\n",
2474				isc_result_totext(isc_result));
2475		return(T_UNRESOLVED);
2476	}
2477
2478	isc_result = isc_entropy_create(mctx, &ectx);
2479	if (isc_result != ISC_R_SUCCESS) {
2480		t_info("isc_entropy_create failed %s\n",
2481				isc_result_totext(isc_result));
2482		isc_mem_destroy(&mctx);
2483		return(T_UNRESOLVED);
2484	}
2485
2486	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2487	if (isc_result != ISC_R_SUCCESS) {
2488		t_info("isc_hash_create failed %s\n",
2489				isc_result_totext(isc_result));
2490		isc_mem_destroy(&mctx);
2491		return(T_UNRESOLVED);
2492	}
2493
2494	dns_result = t_create(db_type, origin, class, model, mctx, &db);
2495	if (dns_result != ISC_R_SUCCESS) {
2496		isc_mem_destroy(&mctx);
2497		return(T_UNRESOLVED);
2498	}
2499
2500	dns_result = dns_db_load(db, filename);
2501	if (dns_result != ISC_R_SUCCESS) {
2502		t_info("dns_db_load returned %s\n",
2503				dns_result_totext(dns_result));
2504		dns_db_detach(&db);
2505		isc_mem_destroy(&mctx);
2506		return(T_UNRESOLVED);
2507	}
2508
2509	nodep = NULL;
2510	dns_fixedname_init(&dns_name);
2511
2512	len = strlen(find_name);
2513	isc_buffer_init(&name_buffer, find_name, len);
2514	isc_buffer_add(&name_buffer, len);
2515	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name),
2516				&name_buffer, NULL, 0, NULL);
2517	if (dns_result != ISC_R_SUCCESS) {
2518		t_info("dns_name_fromtext failed %s\n",
2519			       dns_result_totext(dns_result));
2520		dns_db_detach(&db);
2521		isc_mem_destroy(&mctx);
2522		return(T_UNRESOLVED);
2523	}
2524
2525	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2526				ISC_FALSE, &nodep);
2527	if (dns_result != exp_result) {
2528		t_info("dns_db_findnode failed %s\n",
2529				dns_result_totext(dns_result));
2530		if (dns_result == ISC_R_SUCCESS)
2531			dns_db_detachnode(db, &nodep);
2532		dns_db_detach(&db);
2533		isc_mem_destroy(&mctx);
2534		return(T_FAIL);
2535	}
2536
2537	/*
2538	 * if we're expecting the find to succeed and it did,
2539	 * check that the node has been initialized
2540	 * by checking for the specified type of rdata
2541	 * and expecting the search to succeed
2542	 */
2543
2544	if (dns_result == ISC_R_SUCCESS) {
2545		cversionp = NULL;
2546		dns_db_currentversion(db, &cversionp);
2547		dns_rdataset_init(&rdataset);
2548
2549		dns_result = dns_db_findrdataset(db, nodep, cversionp,
2550						 rdatatype, 0,
2551						 0, &rdataset, NULL);
2552		if (dns_result == ISC_R_SUCCESS) {
2553			dns_rdataset_disassociate(&rdataset);
2554			result = T_PASS;
2555		} else {
2556			t_info("dns_db_findrdataset failed %s\n",
2557					dns_result_totext(dns_result));
2558			result = T_FAIL;
2559		}
2560		dns_db_closeversion(db, &cversionp, ISC_FALSE);
2561		dns_db_detachnode(db, &nodep);
2562	} else {
2563		result = T_PASS;
2564	}
2565
2566	dns_db_detach(&db);
2567	isc_hash_destroy();
2568	isc_entropy_detach(&ectx);
2569	isc_mem_destroy(&mctx);
2570
2571	return(result);
2572}
2573
2574static void
2575t13(void) {
2576	int	result;
2577
2578	t_assert("dns_db_findnode", 13, T_REQUIRED, "%s", a13);
2579	result = t_eval("dns_db_findnode_1_data", t_dns_db_findnode_1, 8);
2580	t_result(result);
2581}
2582
2583static const char *a14 =
2584	"If the node name does not exist and create is ISC_TRUE, "
2585	"then a call to dns_db_findnode(db, name, create, nodep) "
2586	"creates the node, initializes nodep to point to the node, "
2587	"and returns ISC_R_SUCCESS.";
2588
2589static int
2590t_dns_db_findnode_2(char **av) {
2591	char			*filename;
2592	char			*db_type;
2593	char			*origin;
2594	char			*class;
2595	char			*model;
2596	char			*newname;
2597
2598	int			nfails;
2599	int			result;
2600	int			len;
2601	dns_db_t		*db;
2602	isc_result_t		dns_result;
2603	isc_result_t		isc_result;
2604	isc_mem_t		*mctx;
2605	isc_entropy_t		*ectx;
2606	dns_dbnode_t		*nodep;
2607	dns_dbnode_t		*newnodep;
2608	isc_buffer_t		name_buffer;
2609	dns_rdataset_t		rdataset;
2610	dns_fixedname_t		dns_name;
2611	dns_fixedname_t		dns_foundname;
2612	dns_dbversion_t		*cversionp;
2613
2614	filename = T_ARG(0);
2615	db_type = T_ARG(1);
2616	origin = T_ARG(2);
2617	class = T_ARG(3);
2618	model = T_ARG(4);
2619	newname = T_ARG(5);
2620
2621	db = NULL;
2622	mctx = NULL;
2623	ectx = NULL;
2624	nfails = 0;
2625
2626	t_info("testing using file %s and name %s\n", filename, newname);
2627
2628	isc_result = isc_mem_create(0, 0, &mctx);
2629	if (isc_result != ISC_R_SUCCESS) {
2630		t_info("isc_mem_create failed %s\n",
2631				isc_result_totext(isc_result));
2632		return(T_UNRESOLVED);
2633	}
2634
2635	isc_result = isc_entropy_create(mctx, &ectx);
2636	if (isc_result != ISC_R_SUCCESS) {
2637		t_info("isc_entropy_create failed %s\n",
2638				isc_result_totext(isc_result));
2639		return(T_UNRESOLVED);
2640	}
2641
2642	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2643	if (isc_result != ISC_R_SUCCESS) {
2644		t_info("isc_hash_create failed %s\n",
2645				isc_result_totext(isc_result));
2646		return(T_UNRESOLVED);
2647	}
2648
2649	dns_result = t_create(db_type, origin, class, model, mctx, &db);
2650	if (dns_result != ISC_R_SUCCESS) {
2651		isc_hash_destroy();
2652		isc_entropy_detach(&ectx);
2653		isc_mem_destroy(&mctx);
2654		return(T_UNRESOLVED);
2655	}
2656
2657	dns_result = dns_db_load(db, filename);
2658	if (dns_result != ISC_R_SUCCESS) {
2659		t_info("dns_db_load returned %s\n",
2660				dns_result_totext(dns_result));
2661		dns_db_detach(&db);
2662		isc_hash_destroy();
2663		isc_entropy_detach(&ectx);
2664		isc_mem_destroy(&mctx);
2665		return(T_UNRESOLVED);
2666	}
2667
2668	nodep = NULL;
2669	dns_fixedname_init(&dns_name);
2670
2671	/*
2672	 * Make sure the name isn't there
2673	 */
2674	len = strlen(newname);
2675	isc_buffer_init(&name_buffer, newname, len);
2676	isc_buffer_add(&name_buffer, len);
2677	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name),
2678				       &name_buffer, NULL, 0, NULL);
2679	if (dns_result != ISC_R_SUCCESS) {
2680		t_info("dns_name_fromtext returned %s\n",
2681				dns_result_totext(dns_result));
2682		dns_db_detach(&db);
2683		isc_hash_destroy();
2684		isc_entropy_detach(&ectx);
2685		isc_mem_destroy(&mctx);
2686		return(T_UNRESOLVED);
2687	}
2688
2689	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2690				     ISC_FALSE, &nodep);
2691	if ((dns_result != ISC_R_NOTFOUND) &&
2692	    (dns_result != DNS_R_NXDOMAIN) &&
2693	    (dns_result != DNS_R_NXRRSET)) {
2694		t_info("dns_db_findnode %s\n",
2695		       dns_result_totext(dns_result));
2696		dns_db_detachnode(db, &nodep);
2697		dns_db_detach(&db);
2698		isc_hash_destroy();
2699		isc_entropy_detach(&ectx);
2700		isc_mem_destroy(&mctx);
2701		return(T_UNRESOLVED);
2702	}
2703
2704	/*
2705	 * Add it.
2706	 */
2707	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2708				ISC_TRUE, &nodep);
2709	if (dns_result != ISC_R_SUCCESS) {
2710		t_info("dns_db_findnode %s\n",
2711				dns_result_totext(dns_result));
2712		dns_db_detach(&db);
2713		isc_hash_destroy();
2714		isc_entropy_detach(&ectx);
2715		isc_mem_destroy(&mctx);
2716		return(T_FAIL);
2717	}
2718
2719	/*
2720	 * Check it.
2721	 */
2722	newnodep = NULL;
2723	dns_rdataset_init(&rdataset);
2724	dns_fixedname_init(&dns_foundname);
2725	cversionp = NULL;
2726	dns_db_currentversion(db, &cversionp);
2727
2728	/*
2729	 * First try dns_db_find DNS_R_NXDOMAIN.
2730	 */
2731	dns_result = dns_db_find(db,
2732			dns_fixedname_name(&dns_name),
2733			cversionp,
2734			dns_rdatatype_any,
2735			0,
2736			0,
2737			&newnodep,
2738			dns_fixedname_name(&dns_foundname),
2739			&rdataset, NULL);
2740	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2741		dns_db_detachnode(db, &newnodep);
2742	}
2743
2744	if (dns_result != DNS_R_NXDOMAIN) {
2745		t_info("dns_db_find %s\n",
2746				dns_result_totext(dns_result));
2747		++nfails;
2748	}
2749
2750	/*
2751	 * Then try dns_db_findnode ISC_R_SUCCESS.
2752	 */
2753	dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2754				     ISC_FALSE, &newnodep);
2755	t_info("dns_db_findnode %s\n", dns_result_totext(dns_result));
2756	if (dns_result == ISC_R_SUCCESS) {
2757		dns_db_detachnode(db, &newnodep);
2758	} else {
2759		t_info("dns_db_findnode %s failed %s\n", newname,
2760				dns_result_totext(dns_result));
2761		++nfails;
2762	}
2763
2764
2765	dns_db_detachnode(db, &nodep);
2766	dns_db_closeversion(db, &cversionp, ISC_FALSE);
2767	dns_db_detach(&db);
2768	isc_hash_destroy();
2769	isc_entropy_detach(&ectx);
2770	isc_mem_destroy(&mctx);
2771
2772	if (nfails == 0)
2773		result = T_PASS;
2774	else
2775		result = T_FAIL;
2776
2777	return(result);
2778}
2779
2780static void
2781t14(void) {
2782	int	result;
2783
2784	t_assert("dns_db_findnode", 14, T_REQUIRED, "%s", a14);
2785	result = t_eval("dns_db_findnode_2_data", t_dns_db_findnode_2, 6);
2786	t_result(result);
2787}
2788
2789static int
2790t_dns_db_find_x(char **av) {
2791	char			*dbfile;
2792	char			*dbtype;
2793	char			*dborigin;
2794	char			*dbclass;
2795	char			*dbmodel;
2796	char			*findname;
2797	char			*findtype;
2798	char			*findopts;
2799	char			*findtime;
2800	char			*expected_result;
2801
2802	int			result;
2803	int			len;
2804	int			opts;
2805	dns_db_t		*db;
2806	isc_result_t		dns_result;
2807	isc_result_t		isc_result;
2808	isc_stdtime_t		ftime;
2809	isc_stdtime_t		now;
2810	isc_result_t		exp_result;
2811	isc_mem_t		*mctx;
2812	isc_entropy_t		*ectx;
2813	dns_dbnode_t		*nodep;
2814	isc_textregion_t	textregion;
2815	isc_buffer_t		findname_buffer;
2816	dns_fixedname_t		dns_findname;
2817	dns_fixedname_t		dns_foundname;
2818	dns_rdataset_t		rdataset;
2819	dns_rdatatype_t		rdatatype;
2820	dns_dbversion_t		*cversionp;
2821
2822	dbfile = T_ARG(0);
2823	dbtype = T_ARG(1);
2824	dborigin = T_ARG(2);
2825	dbclass = T_ARG(3);
2826	dbmodel = T_ARG(4);
2827	findname = T_ARG(5);
2828	findtype = T_ARG(6);
2829	findopts = T_ARG(7);
2830	findtime = T_ARG(8);
2831	expected_result = T_ARG(9);
2832	db = NULL;
2833	mctx = NULL;
2834	ectx = NULL;
2835	opts = 0;
2836
2837	t_info("testing using %s, name %s, type %s\n", dbfile, findname,
2838	       findtype);
2839
2840	isc_result = isc_mem_create(0, 0, &mctx);
2841	if (isc_result != ISC_R_SUCCESS) {
2842		t_info("isc_mem_create failed %s\n",
2843				isc_result_totext(isc_result));
2844		return(T_UNRESOLVED);
2845	}
2846
2847	isc_result = isc_entropy_create(mctx, &ectx);
2848	if (isc_result != ISC_R_SUCCESS) {
2849		t_info("isc_entropy_create failed %s\n",
2850				isc_result_totext(isc_result));
2851		isc_mem_destroy(&mctx);
2852		return(T_UNRESOLVED);
2853	}
2854
2855	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2856	if (isc_result != ISC_R_SUCCESS) {
2857		t_info("isc_hash_create failed %s\n",
2858				isc_result_totext(isc_result));
2859		isc_entropy_detach(&ectx);
2860		isc_mem_destroy(&mctx);
2861		return(T_UNRESOLVED);
2862	}
2863
2864	dns_result = t_create(dbtype, dborigin, dbclass, dbmodel, mctx, &db);
2865	if (dns_result != ISC_R_SUCCESS) {
2866		isc_hash_destroy();
2867		isc_entropy_detach(&ectx);
2868		isc_mem_destroy(&mctx);
2869		return(T_UNRESOLVED);
2870	}
2871
2872	dns_result = dns_db_load(db, dbfile);
2873	if (dns_result != ISC_R_SUCCESS) {
2874		t_info("dns_db_load returned %s\n",
2875				dns_result_totext(dns_result));
2876		dns_db_detach(&db);
2877		isc_hash_destroy();
2878		isc_entropy_detach(&ectx);
2879		isc_mem_destroy(&mctx);
2880		return(T_UNRESOLVED);
2881	}
2882
2883	exp_result = t_dns_result_fromtext(expected_result);
2884
2885	dns_fixedname_init(&dns_findname);
2886	len = strlen(findname);
2887	isc_buffer_init(&findname_buffer, findname, len);
2888	isc_buffer_add(&findname_buffer, len);
2889	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
2890				&findname_buffer, NULL, 0, NULL);
2891	if (dns_result != ISC_R_SUCCESS) {
2892		t_info("dns_name_fromtext failed %s\n",
2893			dns_result_totext(dns_result));
2894		dns_db_detach(&db);
2895		isc_hash_destroy();
2896		isc_entropy_detach(&ectx);
2897		isc_mem_destroy(&mctx);
2898		return(T_UNRESOLVED);
2899	}
2900
2901	textregion.base = findtype;
2902	textregion.length = strlen(findtype);
2903	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
2904	if (dns_result != ISC_R_SUCCESS) {
2905		t_info("dns_rdatatype_fromtext %s failed %s\n",
2906				findtype,
2907				dns_result_totext(dns_result));
2908		dns_db_detach(&db);
2909		isc_hash_destroy();
2910		isc_entropy_detach(&ectx);
2911		isc_mem_destroy(&mctx);
2912		return(T_UNRESOLVED);
2913	}
2914
2915	if (strstr(findopts, "DNS_DBFIND_GLUEOK"))
2916		opts |= DNS_DBFIND_GLUEOK;
2917	if (strstr(findopts, "DNS_DBFIND_VALIDATEGLUE"))
2918		opts |= DNS_DBFIND_VALIDATEGLUE;
2919
2920	isc_stdtime_get(&now);
2921
2922	ftime = strtol(findtime, NULL, 10);
2923	if (ftime != 0)
2924		ftime += now;
2925
2926	cversionp = NULL;
2927	dns_fixedname_init(&dns_foundname);
2928	dns_rdataset_init(&rdataset);
2929	if (dns_db_iszone(db))
2930		dns_db_currentversion(db, &cversionp);
2931	nodep = NULL;
2932
2933	dns_result = dns_db_find(db,
2934			dns_fixedname_name(&dns_findname),
2935			cversionp,
2936			rdatatype,
2937			opts,
2938			ftime,
2939			&nodep,
2940			dns_fixedname_name(&dns_foundname),
2941			&rdataset, NULL);
2942
2943	if (dns_result != exp_result) {
2944		t_info("dns_db_find %s %s unexpectedly returned %s, "
2945		       "expected %s\n",
2946		       findname, findtype, dns_result_totext(dns_result),
2947		       dns_result_totext(exp_result));
2948		result = T_FAIL;
2949	} else {
2950		result = T_PASS;
2951	}
2952
2953	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2954
2955		if ((dns_result != DNS_R_NXRRSET) &&
2956		    (dns_result != DNS_R_ZONECUT))
2957			if (dns_rdataset_isassociated(&rdataset))
2958				dns_rdataset_disassociate(&rdataset);
2959		dns_db_detachnode(db, &nodep);
2960	}
2961
2962	if (dns_db_iszone(db))
2963		dns_db_closeversion(db, &cversionp, ISC_FALSE);
2964	dns_db_detach(&db);
2965	isc_hash_destroy();
2966	isc_entropy_detach(&ectx);
2967	isc_mem_destroy(&mctx);
2968
2969	return(result);
2970}
2971
2972static const char *a15 =
2973	"A call to dns_db_find(db, name, version, type, options, now, ...)  "
2974	"finds the best match for 'name' and 'type' in version 'version' "
2975	"of 'db'.";
2976
2977static void
2978t15(void) {
2979	int	result;
2980
2981	t_assert("dns_db_find", 15, T_REQUIRED, "%s", a15);
2982	result = t_eval("dns_db_find_1_data", t_dns_db_find_x, 10);
2983	t_result(result);
2984}
2985
2986
2987static const char *a16 =
2988	"When the desired node and type were found, but are glue, "
2989	"and the DNS_DBFIND_GLUEOK option is set, a call to "
2990	"dns_db_find(db, name, version, type, options, now, ...)  "
2991	"returns DNS_R_GLUE.";
2992
2993static void
2994t16(void) {
2995	int	result;
2996
2997	t_assert("dns_db_find", 16, T_REQUIRED, "%s", a16);
2998	result = t_eval("dns_db_find_2_data", t_dns_db_find_x, 10);
2999	t_result(result);
3000}
3001
3002static const char *a17 =
3003	"A call to dns_db_find() returns DNS_R_DELEGATION when the data "
3004	"requested is beneath a zone cut.";
3005
3006static void
3007t17(void) {
3008	int	result;
3009
3010	t_assert("dns_db_find", 17, T_REQUIRED, "%s", a17);
3011	result = t_eval("dns_db_find_3_data", t_dns_db_find_x, 10);
3012	t_result(result);
3013}
3014
3015static const char *a18 =
3016	"A call to dns_db_find() returns DNS_R_DELEGATION when type is "
3017	"dns_rdatatype_any and the desired node is a zone cut.";
3018
3019static void
3020t18(void) {
3021	int	result;
3022
3023	t_assert("dns_db_find", 18, T_REQUIRED, "%s", a18);
3024	result = t_eval("dns_db_find_4_data", t_dns_db_find_x, 10);
3025	t_result(result);
3026}
3027
3028static const char *a19 =
3029	"A call to dns_db_find() returns DNS_R_DNAME when the data "
3030	"requested is beneath a DNAME.";
3031
3032static void
3033t19(void) {
3034	int	result;
3035
3036	t_assert("dns_db_find", 19, T_REQUIRED, "%s", a19);
3037	result = t_eval("dns_db_find_5_data", t_dns_db_find_x, 10);
3038	t_result(result);
3039}
3040
3041static const char *a20 =
3042	"A call to dns_db_find() returns DNS_R_CNAME when the requested "
3043	"rdataset was not found but there is a CNAME at the desired name.";
3044
3045static void
3046t20(void) {
3047	int	result;
3048
3049	t_assert("dns_db_find", 20, T_REQUIRED, "%s", a20);
3050	result = t_eval("dns_db_find_6_data", t_dns_db_find_x, 10);
3051	t_result(result);
3052}
3053
3054static const char *a21 =
3055	"A call to dns_db_find() returns DNS_R_NXDOMAIN when name "
3056	"does not exist.";
3057
3058static void
3059t21(void) {
3060	int	result;
3061
3062	t_assert("dns_db_find", 21, T_REQUIRED, "%s", a21);
3063	result = t_eval("dns_db_find_7_data", t_dns_db_find_x, 10);
3064	t_result(result);
3065}
3066
3067static const char *a22 =
3068	"A call to dns_db_find() returns DNS_R_NXRRSET when "
3069	"the desired name exists, but the desired type does not.";
3070
3071static void
3072t22(void) {
3073	int	result;
3074
3075	t_assert("dns_db_find", 22, T_REQUIRED, "%s", a22);
3076	result = t_eval("dns_db_find_8_data", t_dns_db_find_x, 10);
3077	t_result(result);
3078}
3079
3080static const char *a23 =
3081	"When db is a cache database, a call to dns_db_find() "
3082	"returns ISC_R_NOTFOUND when the desired name does not exist, "
3083	"and no delegation could be found.";
3084
3085static void
3086t23(void) {
3087	int	result;
3088
3089	t_assert("dns_db_find", 23, T_REQUIRED, "%s", a23);
3090	result = t_eval("dns_db_find_9_data", t_dns_db_find_x, 10);
3091	t_result(result);
3092}
3093
3094static const char *a24 =
3095	"When db is a cache database, an rdataset will be found only "
3096	"if at least one rdataset at the found node expires after 'now'.";
3097
3098static void
3099t24(void) {
3100	int	result;
3101
3102	t_assert("dns_db_find", 24, T_REQUIRED, "%s", a24);
3103	result = t_eval("dns_db_find_10_data", t_dns_db_find_x, 10);
3104	t_result(result);
3105}
3106
3107static const char *a25 =
3108	"A call to dns_db_load(db, filename) returns DNS_R_NOTZONETOP "
3109	"when the zone data contains a SOA not at the zone apex.";
3110
3111static void
3112t25(void) {
3113	int	result;
3114
3115	t_assert("dns_db_load", 25, T_REQUIRED, "%s", a25);
3116	result = t_eval("dns_db_load_soa_not_top", t_dns_db_load, 9);
3117	t_result(result);
3118}
3119
3120testspec_t	T_testlist[] = {
3121	{	t1,		"dns_db_load"		},
3122	{	t2,		"dns_db_iscache"	},
3123	{	t3,		"dns_db_iscache"	},
3124	{	t4,		"dns_db_iszone"		},
3125	{	t5,		"dns_db_iszone"		},
3126	{	t6,		"dns_db_origin"		},
3127	{	t7,		"dns_db_class"		},
3128	{	t8,		"dns_db_currentversion"	},
3129	{	t9,		"dns_db_newversion"	},
3130	{	t10,		"dns_db_closeversion"	},
3131	{	t11,		"dns_db_closeversion"	},
3132	{	t12,		"dns_db_expirenode"	},
3133	{	t13,		"dns_db_findnode"	},
3134	{	t14,		"dns_db_findnode"	},
3135	{	t15,		"dns_db_find"		},
3136	{	t16,		"dns_db_find"		},
3137	{	t17,		"dns_db_find"		},
3138	{	t18,		"dns_db_find"		},
3139	{	t19,		"dns_db_find"		},
3140	{	t20,		"dns_db_find"		},
3141	{	t21,		"dns_db_find"		},
3142	{	t22,		"dns_db_find"		},
3143	{	t23,		"dns_db_find"		},
3144	{	t24,		"dns_db_find"		},
3145	{	t25,		"dns_db_load"		},
3146	{	NULL,		NULL			}
3147};
3148