xref: /minix3/external/bsd/bind/dist/lib/dns/rriterator.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: rriterator.c,v 1.4 2014/12/10 04:37:58 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek /*! \file */
22*00b67f09SDavid van Moolenbroek 
23*00b67f09SDavid van Moolenbroek /***
24*00b67f09SDavid van Moolenbroek  *** Imports
25*00b67f09SDavid van Moolenbroek  ***/
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include <config.h>
28*00b67f09SDavid van Moolenbroek 
29*00b67f09SDavid van Moolenbroek #include <isc/string.h>
30*00b67f09SDavid van Moolenbroek #include <isc/util.h>
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <dns/db.h>
33*00b67f09SDavid van Moolenbroek #include <dns/dbiterator.h>
34*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
35*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
36*00b67f09SDavid van Moolenbroek #include <dns/rdatasetiter.h>
37*00b67f09SDavid van Moolenbroek #include <dns/result.h>
38*00b67f09SDavid van Moolenbroek #include <dns/rriterator.h>
39*00b67f09SDavid van Moolenbroek 
40*00b67f09SDavid van Moolenbroek /***
41*00b67f09SDavid van Moolenbroek  *** RRiterator methods
42*00b67f09SDavid van Moolenbroek  ***/
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek isc_result_t
dns_rriterator_init(dns_rriterator_t * it,dns_db_t * db,dns_dbversion_t * ver,isc_stdtime_t now)45*00b67f09SDavid van Moolenbroek dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
46*00b67f09SDavid van Moolenbroek 		    isc_stdtime_t now)
47*00b67f09SDavid van Moolenbroek {
48*00b67f09SDavid van Moolenbroek 	isc_result_t result;
49*00b67f09SDavid van Moolenbroek 	it->magic = RRITERATOR_MAGIC;
50*00b67f09SDavid van Moolenbroek 	it->db = db;
51*00b67f09SDavid van Moolenbroek 	it->dbit = NULL;
52*00b67f09SDavid van Moolenbroek 	it->ver = ver;
53*00b67f09SDavid van Moolenbroek 	it->now = now;
54*00b67f09SDavid van Moolenbroek 	it->node = NULL;
55*00b67f09SDavid van Moolenbroek 	result = dns_db_createiterator(it->db, 0, &it->dbit);
56*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
57*00b67f09SDavid van Moolenbroek 		return (result);
58*00b67f09SDavid van Moolenbroek 	it->rdatasetit = NULL;
59*00b67f09SDavid van Moolenbroek 	dns_rdata_init(&it->rdata);
60*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&it->rdataset);
61*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&it->fixedname);
62*00b67f09SDavid van Moolenbroek 	INSIST(! dns_rdataset_isassociated(&it->rdataset));
63*00b67f09SDavid van Moolenbroek 	it->result = ISC_R_SUCCESS;
64*00b67f09SDavid van Moolenbroek 	return (it->result);
65*00b67f09SDavid van Moolenbroek }
66*00b67f09SDavid van Moolenbroek 
67*00b67f09SDavid van Moolenbroek isc_result_t
dns_rriterator_first(dns_rriterator_t * it)68*00b67f09SDavid van Moolenbroek dns_rriterator_first(dns_rriterator_t *it) {
69*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_RRITERATOR(it));
70*00b67f09SDavid van Moolenbroek 	/* Reset state */
71*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&it->rdataset))
72*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&it->rdataset);
73*00b67f09SDavid van Moolenbroek 	if (it->rdatasetit != NULL)
74*00b67f09SDavid van Moolenbroek 		dns_rdatasetiter_destroy(&it->rdatasetit);
75*00b67f09SDavid van Moolenbroek 	if (it->node != NULL)
76*00b67f09SDavid van Moolenbroek 		dns_db_detachnode(it->db, &it->node);
77*00b67f09SDavid van Moolenbroek 	it->result = dns_dbiterator_first(it->dbit);
78*00b67f09SDavid van Moolenbroek 
79*00b67f09SDavid van Moolenbroek 	/*
80*00b67f09SDavid van Moolenbroek 	 * The top node may be empty when out of zone glue exists.
81*00b67f09SDavid van Moolenbroek 	 * Walk the tree to find the first node with data.
82*00b67f09SDavid van Moolenbroek 	 */
83*00b67f09SDavid van Moolenbroek 	while (it->result == ISC_R_SUCCESS) {
84*00b67f09SDavid van Moolenbroek 		it->result = dns_dbiterator_current(it->dbit, &it->node,
85*00b67f09SDavid van Moolenbroek 					   dns_fixedname_name(&it->fixedname));
86*00b67f09SDavid van Moolenbroek 		if (it->result != ISC_R_SUCCESS)
87*00b67f09SDavid van Moolenbroek 			return (it->result);
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek 		it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
90*00b67f09SDavid van Moolenbroek 						 it->now, &it->rdatasetit);
91*00b67f09SDavid van Moolenbroek 		if (it->result != ISC_R_SUCCESS)
92*00b67f09SDavid van Moolenbroek 			return (it->result);
93*00b67f09SDavid van Moolenbroek 
94*00b67f09SDavid van Moolenbroek 		it->result = dns_rdatasetiter_first(it->rdatasetit);
95*00b67f09SDavid van Moolenbroek 		if (it->result != ISC_R_SUCCESS) {
96*00b67f09SDavid van Moolenbroek 			/*
97*00b67f09SDavid van Moolenbroek 			 * This node is empty. Try next node.
98*00b67f09SDavid van Moolenbroek 			 */
99*00b67f09SDavid van Moolenbroek 			dns_rdatasetiter_destroy(&it->rdatasetit);
100*00b67f09SDavid van Moolenbroek 			dns_db_detachnode(it->db, &it->node);
101*00b67f09SDavid van Moolenbroek 			it->result = dns_dbiterator_next(it->dbit);
102*00b67f09SDavid van Moolenbroek 			continue;
103*00b67f09SDavid van Moolenbroek 		}
104*00b67f09SDavid van Moolenbroek 		dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
105*00b67f09SDavid van Moolenbroek 		it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
106*00b67f09SDavid van Moolenbroek 		it->result = dns_rdataset_first(&it->rdataset);
107*00b67f09SDavid van Moolenbroek 		return (it->result);
108*00b67f09SDavid van Moolenbroek 	}
109*00b67f09SDavid van Moolenbroek 	return (it->result);
110*00b67f09SDavid van Moolenbroek }
111*00b67f09SDavid van Moolenbroek 
112*00b67f09SDavid van Moolenbroek isc_result_t
dns_rriterator_nextrrset(dns_rriterator_t * it)113*00b67f09SDavid van Moolenbroek dns_rriterator_nextrrset(dns_rriterator_t *it) {
114*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_RRITERATOR(it));
115*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&it->rdataset))
116*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&it->rdataset);
117*00b67f09SDavid van Moolenbroek 	it->result = dns_rdatasetiter_next(it->rdatasetit);
118*00b67f09SDavid van Moolenbroek 	/*
119*00b67f09SDavid van Moolenbroek 	 * The while loop body is executed more than once
120*00b67f09SDavid van Moolenbroek 	 * only when an empty dbnode needs to be skipped.
121*00b67f09SDavid van Moolenbroek 	 */
122*00b67f09SDavid van Moolenbroek 	while (it->result == ISC_R_NOMORE) {
123*00b67f09SDavid van Moolenbroek 		dns_rdatasetiter_destroy(&it->rdatasetit);
124*00b67f09SDavid van Moolenbroek 		dns_db_detachnode(it->db, &it->node);
125*00b67f09SDavid van Moolenbroek 		it->result = dns_dbiterator_next(it->dbit);
126*00b67f09SDavid van Moolenbroek 		if (it->result == ISC_R_NOMORE) {
127*00b67f09SDavid van Moolenbroek 			/* We are at the end of the entire database. */
128*00b67f09SDavid van Moolenbroek 			return (it->result);
129*00b67f09SDavid van Moolenbroek 		}
130*00b67f09SDavid van Moolenbroek 		if (it->result != ISC_R_SUCCESS)
131*00b67f09SDavid van Moolenbroek 			return (it->result);
132*00b67f09SDavid van Moolenbroek 		it->result = dns_dbiterator_current(it->dbit, &it->node,
133*00b67f09SDavid van Moolenbroek 					   dns_fixedname_name(&it->fixedname));
134*00b67f09SDavid van Moolenbroek 		if (it->result != ISC_R_SUCCESS)
135*00b67f09SDavid van Moolenbroek 			return (it->result);
136*00b67f09SDavid van Moolenbroek 		it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
137*00b67f09SDavid van Moolenbroek 						 it->now, &it->rdatasetit);
138*00b67f09SDavid van Moolenbroek 		if (it->result != ISC_R_SUCCESS)
139*00b67f09SDavid van Moolenbroek 			return (it->result);
140*00b67f09SDavid van Moolenbroek 		it->result = dns_rdatasetiter_first(it->rdatasetit);
141*00b67f09SDavid van Moolenbroek 	}
142*00b67f09SDavid van Moolenbroek 	if (it->result != ISC_R_SUCCESS)
143*00b67f09SDavid van Moolenbroek 		return (it->result);
144*00b67f09SDavid van Moolenbroek 	dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
145*00b67f09SDavid van Moolenbroek 	it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
146*00b67f09SDavid van Moolenbroek 	it->result = dns_rdataset_first(&it->rdataset);
147*00b67f09SDavid van Moolenbroek 	return (it->result);
148*00b67f09SDavid van Moolenbroek }
149*00b67f09SDavid van Moolenbroek 
150*00b67f09SDavid van Moolenbroek isc_result_t
dns_rriterator_next(dns_rriterator_t * it)151*00b67f09SDavid van Moolenbroek dns_rriterator_next(dns_rriterator_t *it) {
152*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_RRITERATOR(it));
153*00b67f09SDavid van Moolenbroek 	if (it->result != ISC_R_SUCCESS)
154*00b67f09SDavid van Moolenbroek 		return (it->result);
155*00b67f09SDavid van Moolenbroek 
156*00b67f09SDavid van Moolenbroek 	INSIST(it->dbit != NULL);
157*00b67f09SDavid van Moolenbroek 	INSIST(it->node != NULL);
158*00b67f09SDavid van Moolenbroek 	INSIST(it->rdatasetit != NULL);
159*00b67f09SDavid van Moolenbroek 
160*00b67f09SDavid van Moolenbroek 	it->result = dns_rdataset_next(&it->rdataset);
161*00b67f09SDavid van Moolenbroek 	if (it->result == ISC_R_NOMORE)
162*00b67f09SDavid van Moolenbroek 		return (dns_rriterator_nextrrset(it));
163*00b67f09SDavid van Moolenbroek 	return (it->result);
164*00b67f09SDavid van Moolenbroek }
165*00b67f09SDavid van Moolenbroek 
166*00b67f09SDavid van Moolenbroek void
dns_rriterator_pause(dns_rriterator_t * it)167*00b67f09SDavid van Moolenbroek dns_rriterator_pause(dns_rriterator_t *it) {
168*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_RRITERATOR(it));
169*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
170*00b67f09SDavid van Moolenbroek }
171*00b67f09SDavid van Moolenbroek 
172*00b67f09SDavid van Moolenbroek void
dns_rriterator_destroy(dns_rriterator_t * it)173*00b67f09SDavid van Moolenbroek dns_rriterator_destroy(dns_rriterator_t *it) {
174*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_RRITERATOR(it));
175*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&it->rdataset))
176*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&it->rdataset);
177*00b67f09SDavid van Moolenbroek 	if (it->rdatasetit != NULL)
178*00b67f09SDavid van Moolenbroek 		dns_rdatasetiter_destroy(&it->rdatasetit);
179*00b67f09SDavid van Moolenbroek 	if (it->node != NULL)
180*00b67f09SDavid van Moolenbroek 		dns_db_detachnode(it->db, &it->node);
181*00b67f09SDavid van Moolenbroek 	dns_dbiterator_destroy(&it->dbit);
182*00b67f09SDavid van Moolenbroek }
183*00b67f09SDavid van Moolenbroek 
184*00b67f09SDavid van Moolenbroek void
dns_rriterator_current(dns_rriterator_t * it,dns_name_t ** name,isc_uint32_t * ttl,dns_rdataset_t ** rdataset,dns_rdata_t ** rdata)185*00b67f09SDavid van Moolenbroek dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
186*00b67f09SDavid van Moolenbroek 		       isc_uint32_t *ttl, dns_rdataset_t **rdataset,
187*00b67f09SDavid van Moolenbroek 		       dns_rdata_t **rdata)
188*00b67f09SDavid van Moolenbroek {
189*00b67f09SDavid van Moolenbroek 	REQUIRE(name != NULL && *name == NULL);
190*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_RRITERATOR(it));
191*00b67f09SDavid van Moolenbroek 	REQUIRE(it->result == ISC_R_SUCCESS);
192*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset == NULL || *rdataset == NULL);
193*00b67f09SDavid van Moolenbroek 	REQUIRE(rdata == NULL || *rdata == NULL);
194*00b67f09SDavid van Moolenbroek 
195*00b67f09SDavid van Moolenbroek 	*name = dns_fixedname_name(&it->fixedname);
196*00b67f09SDavid van Moolenbroek 	*ttl = it->rdataset.ttl;
197*00b67f09SDavid van Moolenbroek 
198*00b67f09SDavid van Moolenbroek 	dns_rdata_reset(&it->rdata);
199*00b67f09SDavid van Moolenbroek 	dns_rdataset_current(&it->rdataset, &it->rdata);
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 	if (rdataset != NULL)
202*00b67f09SDavid van Moolenbroek 		*rdataset = &it->rdataset;
203*00b67f09SDavid van Moolenbroek 
204*00b67f09SDavid van Moolenbroek 	if (rdata != NULL)
205*00b67f09SDavid van Moolenbroek 		*rdata = &it->rdata;
206*00b67f09SDavid van Moolenbroek }
207