2 * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
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.
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.
18 /* $Id: rdatalist.c,v 1.33.128.2 2008/04/03 06:08:27 tbox Exp $ */
29 #include <dns/rdata.h>
30 #include <dns/rdatalist.h>
31 #include <dns/rdataset.h>
33 #include "rdatalist_p.h"
35 static dns_rdatasetmethods_t methods
= {
36 isc__rdatalist_disassociate
,
39 isc__rdatalist_current
,
42 isc__rdatalist_addnoqname
,
43 isc__rdatalist_getnoqname
,
50 dns_rdatalist_init(dns_rdatalist_t
*rdatalist
) {
53 * Initialize rdatalist.
56 rdatalist
->rdclass
= 0;
58 rdatalist
->covers
= 0;
60 ISC_LIST_INIT(rdatalist
->rdata
);
61 ISC_LINK_INIT(rdatalist
, link
);
65 dns_rdatalist_tordataset(dns_rdatalist_t
*rdatalist
,
66 dns_rdataset_t
*rdataset
) {
69 * Make 'rdataset' refer to the rdata in 'rdatalist'.
72 REQUIRE(rdatalist
!= NULL
);
73 REQUIRE(DNS_RDATASET_VALID(rdataset
));
74 REQUIRE(! dns_rdataset_isassociated(rdataset
));
76 rdataset
->methods
= &methods
;
77 rdataset
->rdclass
= rdatalist
->rdclass
;
78 rdataset
->type
= rdatalist
->type
;
79 rdataset
->covers
= rdatalist
->covers
;
80 rdataset
->ttl
= rdatalist
->ttl
;
82 rdataset
->private1
= rdatalist
;
83 rdataset
->private2
= NULL
;
84 rdataset
->private3
= NULL
;
85 rdataset
->privateuint4
= 0;
86 rdataset
->private5
= NULL
;
88 return (ISC_R_SUCCESS
);
92 dns_rdatalist_fromrdataset(dns_rdataset_t
*rdataset
,
93 dns_rdatalist_t
**rdatalist
)
95 REQUIRE(rdatalist
!= NULL
&& rdataset
!= NULL
);
96 *rdatalist
= rdataset
->private1
;
98 return (ISC_R_SUCCESS
);
102 isc__rdatalist_disassociate(dns_rdataset_t
*rdataset
) {
107 isc__rdatalist_first(dns_rdataset_t
*rdataset
) {
108 dns_rdatalist_t
*rdatalist
;
110 rdatalist
= rdataset
->private1
;
111 rdataset
->private2
= ISC_LIST_HEAD(rdatalist
->rdata
);
113 if (rdataset
->private2
== NULL
)
114 return (ISC_R_NOMORE
);
116 return (ISC_R_SUCCESS
);
120 isc__rdatalist_next(dns_rdataset_t
*rdataset
) {
123 rdata
= rdataset
->private2
;
125 return (ISC_R_NOMORE
);
127 rdataset
->private2
= ISC_LIST_NEXT(rdata
, link
);
129 if (rdataset
->private2
== NULL
)
130 return (ISC_R_NOMORE
);
132 return (ISC_R_SUCCESS
);
136 isc__rdatalist_current(dns_rdataset_t
*rdataset
, dns_rdata_t
*rdata
) {
137 dns_rdata_t
*list_rdata
;
139 list_rdata
= rdataset
->private2
;
140 INSIST(list_rdata
!= NULL
);
142 dns_rdata_clone(list_rdata
, rdata
);
146 isc__rdatalist_clone(dns_rdataset_t
*source
, dns_rdataset_t
*target
) {
150 * Reset iterator state.
152 target
->private2
= NULL
;
156 isc__rdatalist_count(dns_rdataset_t
*rdataset
) {
157 dns_rdatalist_t
*rdatalist
;
161 rdatalist
= rdataset
->private1
;
164 for (rdata
= ISC_LIST_HEAD(rdatalist
->rdata
);
166 rdata
= ISC_LIST_NEXT(rdata
, link
))
173 isc__rdatalist_addnoqname(dns_rdataset_t
*rdataset
, dns_name_t
*name
) {
174 dns_rdataset_t
*nsec
= NULL
;
175 dns_rdataset_t
*nsecsig
= NULL
;
176 dns_rdataset_t
*rdset
;
179 for (rdset
= ISC_LIST_HEAD(name
->list
);
181 rdset
= ISC_LIST_NEXT(rdset
, link
))
183 if (rdset
->rdclass
!= rdataset
->rdclass
)
185 if (rdset
->type
== dns_rdatatype_nsec
)
187 if (rdset
->type
== dns_rdatatype_rrsig
&&
188 rdset
->covers
== dns_rdatatype_nsec
)
192 if (nsec
== NULL
|| nsecsig
== NULL
)
193 return (ISC_R_NOTFOUND
);
200 if (nsecsig
->ttl
< ttl
)
202 rdataset
->ttl
= nsec
->ttl
= nsecsig
->ttl
= ttl
;
203 rdataset
->attributes
|= DNS_RDATASETATTR_NOQNAME
;
204 rdataset
->private6
= name
;
205 return (ISC_R_SUCCESS
);
209 isc__rdatalist_getnoqname(dns_rdataset_t
*rdataset
, dns_name_t
*name
,
210 dns_rdataset_t
*nsec
, dns_rdataset_t
*nsecsig
)
212 dns_rdataclass_t rdclass
= rdataset
->rdclass
;
213 dns_rdataset_t
*tnsec
= NULL
;
214 dns_rdataset_t
*tnsecsig
= NULL
;
215 dns_name_t
*noqname
= rdataset
->private6
;
217 REQUIRE((rdataset
->attributes
& DNS_RDATASETATTR_NOQNAME
) != 0);
218 (void)dns_name_dynamic(noqname
); /* Sanity Check. */
220 for (rdataset
= ISC_LIST_HEAD(noqname
->list
);
222 rdataset
= ISC_LIST_NEXT(rdataset
, link
))
224 if (rdataset
->rdclass
!= rdclass
)
226 if (rdataset
->type
== dns_rdatatype_nsec
)
228 if (rdataset
->type
== dns_rdatatype_rrsig
&&
229 rdataset
->covers
== dns_rdatatype_nsec
)
232 if (tnsec
== NULL
|| tnsecsig
== NULL
)
233 return (ISC_R_NOTFOUND
);
235 dns_name_clone(noqname
, name
);
236 dns_rdataset_clone(tnsec
, nsec
);
237 dns_rdataset_clone(tnsecsig
, nsecsig
);
238 return (ISC_R_SUCCESS
);