1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup dnsdbzone Zone related functions
36 * @ingroup dnsdb
37 * @brief Functions used to iterate through the labels of a zone
38 *
39 * @{
40 */
41
42 #include "dnsdb/dnsdb-config.h"
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <dnsdb/avl.h>
46
47 #include "dnscore/logger.h"
48 #include "dnsdb/zdb_types.h"
49 #include "dnsdb/nsec3_item.h"
50 #include "dnsdb/zdb_rr_label.h"
51 #include "dnsdb/zdb_zone_label_iterator_ex.h"
52 #include "dnsdb/zdb_zone_label_iterator.h"
53
54 extern logger_handle* g_database_logger;
55 #define MODULE_MSG_HANDLE g_database_logger
56
57 /**
58 * @brief Initializes a zone label iterator
59 *
60 * Initializes a zone label iterator (iterates zdb_rr_label)
61 *
62 * @param[in] zone The zone to explore
63 * @param[in] iter a pointer to the iterator to initialize
64 *
65 */
66
67
68 #define ZLI_DEBUG 0
69
70 void
zdb_zone_label_iterator_ex_init(zdb_zone_label_iterator_ex * iter,const zdb_zone * zone)71 zdb_zone_label_iterator_ex_init(zdb_zone_label_iterator_ex* iter, const zdb_zone* zone)
72 {
73 memset(iter, 0, sizeof(zdb_zone_label_iterator_ex));
74
75 //iter->mode = ZDB_ZONE_LABEL_ITERATOR_ZONE_RECORDS; // set by the memset
76 iter->min_ttl = zone->min_ttl;
77 iter->zone = zone;
78 iter->n3 = zone->nsec.nsec3;
79 iter->pool = &iter->pool_buffer[0];
80 //iter->nsec3_owner = NULL;
81
82 //iter->nsec3_label.next = NULL;
83 //iter->nsec3_label.sub.count = 0;
84
85 iter->nsec3_label.resource_record_set = &iter->nsec3_label_nsec3;
86
87 iter->nsec3_label_nsec3.hash = TYPE_NSEC3;
88 iter->nsec3_label_rrsig.hash = TYPE_RRSIG;
89
90 zdb_zone_label_iterator_init(&iter->iter.label_iter, zone);
91 }
92
93 /**
94 * @brief Checks if there is still data available from an iterator
95 *
96 * Checks if there is still data available from an iterator
97 *
98 * @param[in] iter a pointer to the iterator
99 *
100 * @return TRUE if data is available, FALSE otherwise.
101 *
102 */
103
104 bool
zdb_zone_label_iterator_ex_hasnext(zdb_zone_label_iterator_ex * iter)105 zdb_zone_label_iterator_ex_hasnext(zdb_zone_label_iterator_ex* iter)
106 {
107 bool ret;
108 switch(iter->mode)
109 {
110 case ZDB_ZONE_LABEL_ITERATOR_ZONE_RECORDS:
111 {
112 ret = zdb_zone_label_iterator_hasnext(&iter->iter.label_iter);
113 if(ret)
114 {
115 return ret;
116 }
117
118 // end of the labels, prepare the NSEC3 if any
119
120 if(iter->n3 == NULL)
121 {
122 return FALSE;
123 }
124
125 nsec3_iterator_init(&iter->n3->items, &iter->iter.nsec3_iter);
126
127 iter->mode = ZDB_ZONE_LABEL_ITERATOR_NSEC3_CHAIN; // falls through on purpose
128
129 FALLTHROUGH // fallthrough
130 }
131 case ZDB_ZONE_LABEL_ITERATOR_NSEC3_CHAIN:
132 {
133 ret = nsec3_iterator_hasnext(&iter->iter.nsec3_iter);
134
135 if(ret)
136 {
137 iter->pool = &iter->pool_buffer[0];
138 // get the record and convert it to an zdb_rr_label
139
140 nsec3_node *nsec3_node = nsec3_iterator_next_node(&iter->iter.nsec3_iter);
141
142 nsec3_zone_item_to_new_zdb_packed_ttlrdata_parm nsec3_parms =
143 {
144 iter->n3,
145 nsec3_node, /// note: in an iterator, if used properly, the returned node cannot be NULL
146 iter->zone->origin,
147 &iter->pool,
148 iter->min_ttl
149 };
150
151 nsec3_zone_item_to_new_zdb_packed_ttlrdata(
152 &nsec3_parms,
153 &iter->nsec3_owner,
154 (zdb_packed_ttlrdata**)&iter->nsec3_label_nsec3.data,
155 (const zdb_packed_ttlrdata**)&iter->nsec3_label_rrsig.data);
156
157 // craft an zdb_rr_label that suits our needs
158
159 if(iter->nsec3_label_rrsig.data != NULL)
160 {
161 iter->nsec3_label_nsec3.balance = -1;
162 iter->nsec3_label_nsec3.children.lr.left = &iter->nsec3_label_rrsig;
163 }
164 else
165 {
166 iter->nsec3_label_nsec3.balance = 0;
167 iter->nsec3_label_nsec3.children.lr.left = NULL;
168 }
169
170 return TRUE;
171 }
172 else
173 {
174 iter->mode = ZDB_ZONE_LABEL_ITERATOR_END_OF_ITERATION;
175 }
176
177 // FALLTHROUGH // fallthrough
178 break;
179 }
180 }
181
182 return FALSE;
183 }
184
185 /**
186 * @brief Copies the full name of the next label returned by the "next" call.
187 *
188 * Copies the full name of the next label returned by the "next" call.
189 *
190 * @param[in] iter a pointer to the iterator
191 * @param[in] buffer256 a pointer to a buffer that will hold the full dns name
192 *
193 * @return the size of the dns name
194 *
195 */
196
197 u32
zdb_zone_label_iterator_ex_nextname_to_cstr(zdb_zone_label_iterator_ex * iter,char * buffer256)198 zdb_zone_label_iterator_ex_nextname_to_cstr(zdb_zone_label_iterator_ex* iter, char* buffer256)
199 {
200 u32 ret;
201
202 switch(iter->mode)
203 {
204 case ZDB_ZONE_LABEL_ITERATOR_ZONE_RECORDS:
205 {
206 ret = zdb_zone_label_iterator_nextname_to_cstr(&iter->iter.label_iter, buffer256);
207 return ret;
208 }
209 case ZDB_ZONE_LABEL_ITERATOR_NSEC3_CHAIN:
210 {
211 ret = dnsname_to_cstr(buffer256, iter->nsec3_owner);
212 return ret;
213 }
214 }
215
216 return 0;
217 }
218
219 u32
zdb_zone_label_iterator_ex_nextname(zdb_zone_label_iterator_ex * iter,u8 * buffer256)220 zdb_zone_label_iterator_ex_nextname(zdb_zone_label_iterator_ex* iter, u8* buffer256)
221 { /* TOP-DOWN stack */
222 u32 ret;
223
224 switch(iter->mode)
225 {
226 case ZDB_ZONE_LABEL_ITERATOR_ZONE_RECORDS:
227 {
228 ret = zdb_zone_label_iterator_nextname(&iter->iter.label_iter, buffer256);
229 return ret;
230 }
231 case ZDB_ZONE_LABEL_ITERATOR_NSEC3_CHAIN:
232 {
233 ret = dnsname_copy(buffer256, iter->nsec3_owner);
234 return ret;
235 }
236 }
237
238 return 0;
239 }
240
241 /**
242 * @brief Returns the next data available from an iterator
243 *
244 * Returns the next data available from an iterator
245 *
246 * @param[in] iter a pointer to the iterator
247 *
248 * @return a pointer to the next label
249 *
250 */
251
252 zdb_rr_label*
zdb_zone_label_iterator_ex_next(zdb_zone_label_iterator_ex * iter)253 zdb_zone_label_iterator_ex_next(zdb_zone_label_iterator_ex* iter)
254 {
255 zdb_rr_label *ret;
256
257 switch(iter->mode)
258 {
259 case ZDB_ZONE_LABEL_ITERATOR_ZONE_RECORDS:
260 {
261 ret = zdb_zone_label_iterator_next(&iter->iter.label_iter);
262 return ret;
263 }
264 case ZDB_ZONE_LABEL_ITERATOR_NSEC3_CHAIN:
265 {
266 ret = &iter->nsec3_label;
267
268 return ret;
269 }
270 }
271
272 return NULL;
273 }
274
275 /** @} */
276