xref: /minix3/external/bsd/bind/dist/lib/dns/rdatalist.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: rdatalist.c,v 1.6 2015/07/08 17:28:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007, 2008, 2010-2012, 2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <stddef.h>
27*00b67f09SDavid van Moolenbroek 
28*00b67f09SDavid van Moolenbroek #include <isc/util.h>
29*00b67f09SDavid van Moolenbroek 
30*00b67f09SDavid van Moolenbroek #include <dns/name.h>
31*00b67f09SDavid van Moolenbroek #include <dns/nsec3.h>
32*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
33*00b67f09SDavid van Moolenbroek #include <dns/rdatalist.h>
34*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #include "rdatalist_p.h"
37*00b67f09SDavid van Moolenbroek 
38*00b67f09SDavid van Moolenbroek static dns_rdatasetmethods_t methods = {
39*00b67f09SDavid van Moolenbroek 	isc__rdatalist_disassociate,
40*00b67f09SDavid van Moolenbroek 	isc__rdatalist_first,
41*00b67f09SDavid van Moolenbroek 	isc__rdatalist_next,
42*00b67f09SDavid van Moolenbroek 	isc__rdatalist_current,
43*00b67f09SDavid van Moolenbroek 	isc__rdatalist_clone,
44*00b67f09SDavid van Moolenbroek 	isc__rdatalist_count,
45*00b67f09SDavid van Moolenbroek 	isc__rdatalist_addnoqname,
46*00b67f09SDavid van Moolenbroek 	isc__rdatalist_getnoqname,
47*00b67f09SDavid van Moolenbroek 	isc__rdatalist_addclosest,
48*00b67f09SDavid van Moolenbroek 	isc__rdatalist_getclosest,
49*00b67f09SDavid van Moolenbroek 	NULL,
50*00b67f09SDavid van Moolenbroek 	NULL,
51*00b67f09SDavid van Moolenbroek 	NULL,
52*00b67f09SDavid van Moolenbroek 	NULL,
53*00b67f09SDavid van Moolenbroek 	NULL,
54*00b67f09SDavid van Moolenbroek 	NULL
55*00b67f09SDavid van Moolenbroek };
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek void
dns_rdatalist_init(dns_rdatalist_t * rdatalist)58*00b67f09SDavid van Moolenbroek dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
59*00b67f09SDavid van Moolenbroek 
60*00b67f09SDavid van Moolenbroek 	REQUIRE(rdatalist != NULL);
61*00b67f09SDavid van Moolenbroek 
62*00b67f09SDavid van Moolenbroek 	/*
63*00b67f09SDavid van Moolenbroek 	 * Initialize rdatalist.
64*00b67f09SDavid van Moolenbroek 	 */
65*00b67f09SDavid van Moolenbroek 
66*00b67f09SDavid van Moolenbroek 	rdatalist->rdclass = 0;
67*00b67f09SDavid van Moolenbroek 	rdatalist->type = 0;
68*00b67f09SDavid van Moolenbroek 	rdatalist->covers = 0;
69*00b67f09SDavid van Moolenbroek 	rdatalist->ttl = 0;
70*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(rdatalist->rdata);
71*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(rdatalist, link);
72*00b67f09SDavid van Moolenbroek }
73*00b67f09SDavid van Moolenbroek 
74*00b67f09SDavid van Moolenbroek isc_result_t
dns_rdatalist_tordataset(dns_rdatalist_t * rdatalist,dns_rdataset_t * rdataset)75*00b67f09SDavid van Moolenbroek dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
76*00b67f09SDavid van Moolenbroek 			 dns_rdataset_t *rdataset)
77*00b67f09SDavid van Moolenbroek {
78*00b67f09SDavid van Moolenbroek 	/*
79*00b67f09SDavid van Moolenbroek 	 * Make 'rdataset' refer to the rdata in 'rdatalist'.
80*00b67f09SDavid van Moolenbroek 	 */
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek 	REQUIRE(rdatalist != NULL);
83*00b67f09SDavid van Moolenbroek 	REQUIRE(DNS_RDATASET_VALID(rdataset));
84*00b67f09SDavid van Moolenbroek 	REQUIRE(! dns_rdataset_isassociated(rdataset));
85*00b67f09SDavid van Moolenbroek 
86*00b67f09SDavid van Moolenbroek 	rdataset->methods = &methods;
87*00b67f09SDavid van Moolenbroek 	rdataset->rdclass = rdatalist->rdclass;
88*00b67f09SDavid van Moolenbroek 	rdataset->type = rdatalist->type;
89*00b67f09SDavid van Moolenbroek 	rdataset->covers = rdatalist->covers;
90*00b67f09SDavid van Moolenbroek 	rdataset->ttl = rdatalist->ttl;
91*00b67f09SDavid van Moolenbroek 	rdataset->trust = 0;
92*00b67f09SDavid van Moolenbroek 	rdataset->private1 = rdatalist;
93*00b67f09SDavid van Moolenbroek 	rdataset->private2 = NULL;
94*00b67f09SDavid van Moolenbroek 	rdataset->private3 = NULL;
95*00b67f09SDavid van Moolenbroek 	rdataset->privateuint4 = 0;
96*00b67f09SDavid van Moolenbroek 	rdataset->private5 = NULL;
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
99*00b67f09SDavid van Moolenbroek }
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek isc_result_t
dns_rdatalist_fromrdataset(dns_rdataset_t * rdataset,dns_rdatalist_t ** rdatalist)102*00b67f09SDavid van Moolenbroek dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
103*00b67f09SDavid van Moolenbroek 			   dns_rdatalist_t **rdatalist)
104*00b67f09SDavid van Moolenbroek {
105*00b67f09SDavid van Moolenbroek 	REQUIRE(rdatalist != NULL && rdataset != NULL);
106*00b67f09SDavid van Moolenbroek 	*rdatalist = rdataset->private1;
107*00b67f09SDavid van Moolenbroek 
108*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
109*00b67f09SDavid van Moolenbroek }
110*00b67f09SDavid van Moolenbroek 
111*00b67f09SDavid van Moolenbroek void
isc__rdatalist_disassociate(dns_rdataset_t * rdataset)112*00b67f09SDavid van Moolenbroek isc__rdatalist_disassociate(dns_rdataset_t *rdataset) {
113*00b67f09SDavid van Moolenbroek 	UNUSED(rdataset);
114*00b67f09SDavid van Moolenbroek }
115*00b67f09SDavid van Moolenbroek 
116*00b67f09SDavid van Moolenbroek isc_result_t
isc__rdatalist_first(dns_rdataset_t * rdataset)117*00b67f09SDavid van Moolenbroek isc__rdatalist_first(dns_rdataset_t *rdataset) {
118*00b67f09SDavid van Moolenbroek 	dns_rdatalist_t *rdatalist;
119*00b67f09SDavid van Moolenbroek 
120*00b67f09SDavid van Moolenbroek 	rdatalist = rdataset->private1;
121*00b67f09SDavid van Moolenbroek 	rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata);
122*00b67f09SDavid van Moolenbroek 
123*00b67f09SDavid van Moolenbroek 	if (rdataset->private2 == NULL)
124*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMORE);
125*00b67f09SDavid van Moolenbroek 
126*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
127*00b67f09SDavid van Moolenbroek }
128*00b67f09SDavid van Moolenbroek 
129*00b67f09SDavid van Moolenbroek isc_result_t
isc__rdatalist_next(dns_rdataset_t * rdataset)130*00b67f09SDavid van Moolenbroek isc__rdatalist_next(dns_rdataset_t *rdataset) {
131*00b67f09SDavid van Moolenbroek 	dns_rdata_t *rdata;
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
134*00b67f09SDavid van Moolenbroek 
135*00b67f09SDavid van Moolenbroek 	rdata = rdataset->private2;
136*00b67f09SDavid van Moolenbroek 	if (rdata == NULL)
137*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMORE);
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek 	rdataset->private2 = ISC_LIST_NEXT(rdata, link);
140*00b67f09SDavid van Moolenbroek 
141*00b67f09SDavid van Moolenbroek 	if (rdataset->private2 == NULL)
142*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMORE);
143*00b67f09SDavid van Moolenbroek 
144*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
145*00b67f09SDavid van Moolenbroek }
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek void
isc__rdatalist_current(dns_rdataset_t * rdataset,dns_rdata_t * rdata)148*00b67f09SDavid van Moolenbroek isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
149*00b67f09SDavid van Moolenbroek 	dns_rdata_t *list_rdata;
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
152*00b67f09SDavid van Moolenbroek 
153*00b67f09SDavid van Moolenbroek 	list_rdata = rdataset->private2;
154*00b67f09SDavid van Moolenbroek 	INSIST(list_rdata != NULL);
155*00b67f09SDavid van Moolenbroek 
156*00b67f09SDavid van Moolenbroek 	dns_rdata_clone(list_rdata, rdata);
157*00b67f09SDavid van Moolenbroek }
158*00b67f09SDavid van Moolenbroek 
159*00b67f09SDavid van Moolenbroek void
isc__rdatalist_clone(dns_rdataset_t * source,dns_rdataset_t * target)160*00b67f09SDavid van Moolenbroek isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
161*00b67f09SDavid van Moolenbroek 
162*00b67f09SDavid van Moolenbroek 	REQUIRE(source != NULL);
163*00b67f09SDavid van Moolenbroek 	REQUIRE(target != NULL);
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek 	*target = *source;
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 	/*
168*00b67f09SDavid van Moolenbroek 	 * Reset iterator state.
169*00b67f09SDavid van Moolenbroek 	 */
170*00b67f09SDavid van Moolenbroek 	target->private2 = NULL;
171*00b67f09SDavid van Moolenbroek }
172*00b67f09SDavid van Moolenbroek 
173*00b67f09SDavid van Moolenbroek unsigned int
isc__rdatalist_count(dns_rdataset_t * rdataset)174*00b67f09SDavid van Moolenbroek isc__rdatalist_count(dns_rdataset_t *rdataset) {
175*00b67f09SDavid van Moolenbroek 	dns_rdatalist_t *rdatalist;
176*00b67f09SDavid van Moolenbroek 	dns_rdata_t *rdata;
177*00b67f09SDavid van Moolenbroek 	unsigned int count;
178*00b67f09SDavid van Moolenbroek 
179*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek 	rdatalist = rdataset->private1;
182*00b67f09SDavid van Moolenbroek 
183*00b67f09SDavid van Moolenbroek 	count = 0;
184*00b67f09SDavid van Moolenbroek 	for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
185*00b67f09SDavid van Moolenbroek 	     rdata != NULL;
186*00b67f09SDavid van Moolenbroek 	     rdata = ISC_LIST_NEXT(rdata, link))
187*00b67f09SDavid van Moolenbroek 		count++;
188*00b67f09SDavid van Moolenbroek 
189*00b67f09SDavid van Moolenbroek 	return (count);
190*00b67f09SDavid van Moolenbroek }
191*00b67f09SDavid van Moolenbroek 
192*00b67f09SDavid van Moolenbroek isc_result_t
isc__rdatalist_addnoqname(dns_rdataset_t * rdataset,dns_name_t * name)193*00b67f09SDavid van Moolenbroek isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
194*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *neg = NULL;
195*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *negsig = NULL;
196*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *rdset;
197*00b67f09SDavid van Moolenbroek 	dns_ttl_t ttl;
198*00b67f09SDavid van Moolenbroek 
199*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 	for (rdset = ISC_LIST_HEAD(name->list);
202*00b67f09SDavid van Moolenbroek 	     rdset != NULL;
203*00b67f09SDavid van Moolenbroek 	     rdset = ISC_LIST_NEXT(rdset, link))
204*00b67f09SDavid van Moolenbroek 	{
205*00b67f09SDavid van Moolenbroek 		if (rdset->rdclass != rdataset->rdclass)
206*00b67f09SDavid van Moolenbroek 			continue;
207*00b67f09SDavid van Moolenbroek 		if (rdset->type == dns_rdatatype_nsec ||
208*00b67f09SDavid van Moolenbroek 		    rdset->type == dns_rdatatype_nsec3)
209*00b67f09SDavid van Moolenbroek 			neg = rdset;
210*00b67f09SDavid van Moolenbroek 	}
211*00b67f09SDavid van Moolenbroek 	if (neg == NULL)
212*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
213*00b67f09SDavid van Moolenbroek 
214*00b67f09SDavid van Moolenbroek 	for (rdset = ISC_LIST_HEAD(name->list);
215*00b67f09SDavid van Moolenbroek 	     rdset != NULL;
216*00b67f09SDavid van Moolenbroek 	     rdset = ISC_LIST_NEXT(rdset, link))
217*00b67f09SDavid van Moolenbroek 	{
218*00b67f09SDavid van Moolenbroek 		if (rdset->type == dns_rdatatype_rrsig &&
219*00b67f09SDavid van Moolenbroek 		    rdset->covers == neg->type)
220*00b67f09SDavid van Moolenbroek 			negsig = rdset;
221*00b67f09SDavid van Moolenbroek 	}
222*00b67f09SDavid van Moolenbroek 
223*00b67f09SDavid van Moolenbroek 	if (negsig == NULL)
224*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
225*00b67f09SDavid van Moolenbroek 	/*
226*00b67f09SDavid van Moolenbroek 	 * Minimise ttl.
227*00b67f09SDavid van Moolenbroek 	 */
228*00b67f09SDavid van Moolenbroek 	ttl = rdataset->ttl;
229*00b67f09SDavid van Moolenbroek 	if (neg->ttl < ttl)
230*00b67f09SDavid van Moolenbroek 		ttl = neg->ttl;
231*00b67f09SDavid van Moolenbroek 	if (negsig->ttl < ttl)
232*00b67f09SDavid van Moolenbroek 		ttl = negsig->ttl;
233*00b67f09SDavid van Moolenbroek 	rdataset->ttl = neg->ttl = negsig->ttl = ttl;
234*00b67f09SDavid van Moolenbroek 	rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
235*00b67f09SDavid van Moolenbroek 	rdataset->private6 = name;
236*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
237*00b67f09SDavid van Moolenbroek }
238*00b67f09SDavid van Moolenbroek 
239*00b67f09SDavid van Moolenbroek isc_result_t
isc__rdatalist_getnoqname(dns_rdataset_t * rdataset,dns_name_t * name,dns_rdataset_t * neg,dns_rdataset_t * negsig)240*00b67f09SDavid van Moolenbroek isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
241*00b67f09SDavid van Moolenbroek 			  dns_rdataset_t *neg, dns_rdataset_t *negsig)
242*00b67f09SDavid van Moolenbroek {
243*00b67f09SDavid van Moolenbroek 	dns_rdataclass_t rdclass = rdataset->rdclass;
244*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *tneg = NULL;
245*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *tnegsig = NULL;
246*00b67f09SDavid van Moolenbroek 	dns_name_t *noqname = rdataset->private6;
247*00b67f09SDavid van Moolenbroek 
248*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
249*00b67f09SDavid van Moolenbroek 	REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
250*00b67f09SDavid van Moolenbroek 
251*00b67f09SDavid van Moolenbroek 	(void)dns_name_dynamic(noqname);	/* Sanity Check. */
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek 	for (rdataset = ISC_LIST_HEAD(noqname->list);
254*00b67f09SDavid van Moolenbroek 	     rdataset != NULL;
255*00b67f09SDavid van Moolenbroek 	     rdataset = ISC_LIST_NEXT(rdataset, link))
256*00b67f09SDavid van Moolenbroek 	{
257*00b67f09SDavid van Moolenbroek 		if (rdataset->rdclass != rdclass)
258*00b67f09SDavid van Moolenbroek 			continue;
259*00b67f09SDavid van Moolenbroek 		if (rdataset->type == dns_rdatatype_nsec ||
260*00b67f09SDavid van Moolenbroek 		    rdataset->type == dns_rdatatype_nsec3)
261*00b67f09SDavid van Moolenbroek 			tneg = rdataset;
262*00b67f09SDavid van Moolenbroek 	}
263*00b67f09SDavid van Moolenbroek 	if (tneg == NULL)
264*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
265*00b67f09SDavid van Moolenbroek 
266*00b67f09SDavid van Moolenbroek 	for (rdataset = ISC_LIST_HEAD(noqname->list);
267*00b67f09SDavid van Moolenbroek 	     rdataset != NULL;
268*00b67f09SDavid van Moolenbroek 	     rdataset = ISC_LIST_NEXT(rdataset, link))
269*00b67f09SDavid van Moolenbroek 	{
270*00b67f09SDavid van Moolenbroek 		if (rdataset->type == dns_rdatatype_rrsig &&
271*00b67f09SDavid van Moolenbroek 		    rdataset->covers == tneg->type)
272*00b67f09SDavid van Moolenbroek 			tnegsig = rdataset;
273*00b67f09SDavid van Moolenbroek 	}
274*00b67f09SDavid van Moolenbroek 	if (tnegsig == NULL)
275*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
276*00b67f09SDavid van Moolenbroek 
277*00b67f09SDavid van Moolenbroek 	dns_name_clone(noqname, name);
278*00b67f09SDavid van Moolenbroek 	dns_rdataset_clone(tneg, neg);
279*00b67f09SDavid van Moolenbroek 	dns_rdataset_clone(tnegsig, negsig);
280*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
281*00b67f09SDavid van Moolenbroek }
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek isc_result_t
isc__rdatalist_addclosest(dns_rdataset_t * rdataset,dns_name_t * name)284*00b67f09SDavid van Moolenbroek isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
285*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *neg = NULL;
286*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *negsig = NULL;
287*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *rdset;
288*00b67f09SDavid van Moolenbroek 	dns_ttl_t ttl;
289*00b67f09SDavid van Moolenbroek 
290*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
291*00b67f09SDavid van Moolenbroek 
292*00b67f09SDavid van Moolenbroek 	for (rdset = ISC_LIST_HEAD(name->list);
293*00b67f09SDavid van Moolenbroek 	     rdset != NULL;
294*00b67f09SDavid van Moolenbroek 	     rdset = ISC_LIST_NEXT(rdset, link))
295*00b67f09SDavid van Moolenbroek 	{
296*00b67f09SDavid van Moolenbroek 		if (rdset->rdclass != rdataset->rdclass)
297*00b67f09SDavid van Moolenbroek 			continue;
298*00b67f09SDavid van Moolenbroek 		if (rdset->type == dns_rdatatype_nsec ||
299*00b67f09SDavid van Moolenbroek 		    rdset->type == dns_rdatatype_nsec3)
300*00b67f09SDavid van Moolenbroek 			neg = rdset;
301*00b67f09SDavid van Moolenbroek 	}
302*00b67f09SDavid van Moolenbroek 	if (neg == NULL)
303*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek 	for (rdset = ISC_LIST_HEAD(name->list);
306*00b67f09SDavid van Moolenbroek 	     rdset != NULL;
307*00b67f09SDavid van Moolenbroek 	     rdset = ISC_LIST_NEXT(rdset, link))
308*00b67f09SDavid van Moolenbroek 	{
309*00b67f09SDavid van Moolenbroek 		if (rdset->type == dns_rdatatype_rrsig &&
310*00b67f09SDavid van Moolenbroek 		    rdset->covers == neg->type)
311*00b67f09SDavid van Moolenbroek 			negsig = rdset;
312*00b67f09SDavid van Moolenbroek 	}
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek 	if (negsig == NULL)
315*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
316*00b67f09SDavid van Moolenbroek 	/*
317*00b67f09SDavid van Moolenbroek 	 * Minimise ttl.
318*00b67f09SDavid van Moolenbroek 	 */
319*00b67f09SDavid van Moolenbroek 	ttl = rdataset->ttl;
320*00b67f09SDavid van Moolenbroek 	if (neg->ttl < ttl)
321*00b67f09SDavid van Moolenbroek 		ttl = neg->ttl;
322*00b67f09SDavid van Moolenbroek 	if (negsig->ttl < ttl)
323*00b67f09SDavid van Moolenbroek 		ttl = negsig->ttl;
324*00b67f09SDavid van Moolenbroek 	rdataset->ttl = neg->ttl = negsig->ttl = ttl;
325*00b67f09SDavid van Moolenbroek 	rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
326*00b67f09SDavid van Moolenbroek 	rdataset->private7 = name;
327*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
328*00b67f09SDavid van Moolenbroek }
329*00b67f09SDavid van Moolenbroek 
330*00b67f09SDavid van Moolenbroek isc_result_t
isc__rdatalist_getclosest(dns_rdataset_t * rdataset,dns_name_t * name,dns_rdataset_t * neg,dns_rdataset_t * negsig)331*00b67f09SDavid van Moolenbroek isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
332*00b67f09SDavid van Moolenbroek 			  dns_rdataset_t *neg, dns_rdataset_t *negsig)
333*00b67f09SDavid van Moolenbroek {
334*00b67f09SDavid van Moolenbroek 	dns_rdataclass_t rdclass = rdataset->rdclass;
335*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *tneg = NULL;
336*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *tnegsig = NULL;
337*00b67f09SDavid van Moolenbroek 	dns_name_t *closest = rdataset->private7;
338*00b67f09SDavid van Moolenbroek 
339*00b67f09SDavid van Moolenbroek 	REQUIRE(rdataset != NULL);
340*00b67f09SDavid van Moolenbroek 	REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0);
341*00b67f09SDavid van Moolenbroek 
342*00b67f09SDavid van Moolenbroek 	(void)dns_name_dynamic(closest);	/* Sanity Check. */
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek 	for (rdataset = ISC_LIST_HEAD(closest->list);
345*00b67f09SDavid van Moolenbroek 	     rdataset != NULL;
346*00b67f09SDavid van Moolenbroek 	     rdataset = ISC_LIST_NEXT(rdataset, link))
347*00b67f09SDavid van Moolenbroek 	{
348*00b67f09SDavid van Moolenbroek 		if (rdataset->rdclass != rdclass)
349*00b67f09SDavid van Moolenbroek 			continue;
350*00b67f09SDavid van Moolenbroek 		if (rdataset->type == dns_rdatatype_nsec ||
351*00b67f09SDavid van Moolenbroek 		    rdataset->type == dns_rdatatype_nsec3)
352*00b67f09SDavid van Moolenbroek 			tneg = rdataset;
353*00b67f09SDavid van Moolenbroek 	}
354*00b67f09SDavid van Moolenbroek 	if (tneg == NULL)
355*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
356*00b67f09SDavid van Moolenbroek 
357*00b67f09SDavid van Moolenbroek 	for (rdataset = ISC_LIST_HEAD(closest->list);
358*00b67f09SDavid van Moolenbroek 	     rdataset != NULL;
359*00b67f09SDavid van Moolenbroek 	     rdataset = ISC_LIST_NEXT(rdataset, link))
360*00b67f09SDavid van Moolenbroek 	{
361*00b67f09SDavid van Moolenbroek 		if (rdataset->type == dns_rdatatype_rrsig &&
362*00b67f09SDavid van Moolenbroek 		    rdataset->covers == tneg->type)
363*00b67f09SDavid van Moolenbroek 			tnegsig = rdataset;
364*00b67f09SDavid van Moolenbroek 	}
365*00b67f09SDavid van Moolenbroek 	if (tnegsig == NULL)
366*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
367*00b67f09SDavid van Moolenbroek 
368*00b67f09SDavid van Moolenbroek 	dns_name_clone(closest, name);
369*00b67f09SDavid van Moolenbroek 	dns_rdataset_clone(tneg, neg);
370*00b67f09SDavid van Moolenbroek 	dns_rdataset_clone(tnegsig, negsig);
371*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
372*00b67f09SDavid van Moolenbroek }
373