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 records_labels Internal functions for the database: zoned resource records label.
36  *  @ingroup dnsdb
37  *  @brief Internal functions for the database: zoned resource records label.
38  *
39  *  Internal functions for the database: zoned resource records label.
40  *
41  * @{
42  */
43 #ifndef _RR_LABEL_H
44 #define	_RR_LABEL_H
45 
46 #include <dnsdb/zdb_record.h>
47 
48 #ifdef	__cplusplus
49 extern "C" {
50 #endif
51 
52 #define ZDB_RR_LABEL_DELETE_NODE     COLLECTION_PROCESS_DELETENODE /* = 2 matches the dictionary delete node   */
53 #define ZDB_RR_LABEL_DELETE_TREE     3                             /*                                          */
54 
55 #define ZDB_RRLABEL_TAG 0x4c424c525242445a     /** "ZDBRRLBL" */
56 
57 /**
58  *  Instanciate a new rr_label.
59  */
60 
61 zdb_rr_label* zdb_rr_label_new_instance(const u8* label_name);
62 
63 /**
64  * @brief Finds the resource record label matching a path of labels starting from another rr label
65  *
66  * Finds the resource record label matching a path of labels starting from another rr label
67  * Typically the starting label is a zone cut.
68  *
69  * @param[in] apex the starting label
70  * @param[in] path a stack of labels
71  * @param[in] path_index the index of the top of the stack
72  *
73  * @return the matching label or NULL if it has not been found
74  */
75 
76 /* 3 USES */
77 zdb_rr_label* zdb_rr_label_find_exact(zdb_rr_label* apex,dnslabel_vector_reference path,s32 path_index);
78 
79 /**
80  * @brief Finds the resource record label matching a path of labels starting from another rr label or the wildcard label
81  *
82  * Finds the resource record label matching a path of labels starting from another rr label or the wildcard label
83  * Typically the starting label is a zone cut.
84  *
85  * @param[in] apex the starting label
86  * @param[in] path a stack of labels
87  * @param[in] path_index the index of the top of the stack
88  *
89  * @return the matching label, the * label or NULL if none of them has not been found
90  */
91 
92 /* NOT USED (YET) */
93 zdb_rr_label* zdb_rr_label_find(zdb_rr_label* apex, dnslabel_vector_reference sections, s32 index);
94 
95 int zdb_rr_label_find_path(zdb_rr_label* apex, dnslabel_vector_reference sections, s32 index, zdb_rr_label** out_array_64);
96 
97 zdb_rr_label* zdb_rr_label_find_from_name(zdb_zone* zone, const u8 *fqdn);
98 
99 int zdb_rr_label_find_path_from_name(zdb_zone *zone, const u8 *fqdn, zdb_rr_label** out_array_64);
100 
101 zdb_rr_label* zdb_rr_label_find_from_name_delete_empty_terminal(zdb_zone* zone, const u8 *fqdn);
102 
103 zdb_rr_label* zdb_rr_label_stack_find(zdb_rr_label* apex, const_dnslabel_stack_reference sections, s32 pos, s32 index);
104 
105 zdb_rr_label* zdb_rr_label_find_child(zdb_rr_label* parent, const u8* dns_label);
106 
107 /**
108  * @brief Finds the closest resource record label matching a path of labels starting from another rr label
109  *
110  * Finds the resource record label matching a path of labels starting from another rr label
111  * Typically the starting label is a zone cut.
112  *
113  * @param[in] apex the starting label
114  * @param[in] path a stack of labels
115  * @param[inout] path_index the index of the top of the stack, set the index of the label in the stack at return
116  *
117  * @return the matching label or the apex if none has been found
118  */
119 
120 /* 3 USES */
121 zdb_rr_label* zdb_rr_label_find_closest(zdb_rr_label* apex, dnslabel_vector_reference path, s32* closest_level);
122 
123 zdb_rr_label* zdb_rr_label_find_closest_authority(zdb_rr_label* apex, dnslabel_vector_reference path, s32* closest_level);
124 
125 struct zdb_rr_label_find_ext_data
126 {
127     zdb_rr_label *authority;
128     zdb_rr_label *closest;
129     zdb_rr_label *answer;
130     s32 authority_index;
131     s32 closest_index;
132 };
133 
134 typedef struct zdb_rr_label_find_ext_data zdb_rr_label_find_ext_data;
135 
136 zdb_rr_label* zdb_rr_label_find_ext(zdb_rr_label* apex, dnslabel_vector_reference sections, s32 index_, zdb_rr_label_find_ext_data *ext);
137 
138 /**
139  * @brief Returns the authority fqdn
140  *
141  * Returns the pointer to the authority fqdn located inside the qname (based on the rr_label_info)
142  *
143  * @param qname
144  * @param rr_label_info
145  * @return
146  */
147 
148 static inline const u8 *
zdb_rr_label_info_get_authority_qname(const u8 * qname,const zdb_rr_label_find_ext_data * rr_label_info)149 zdb_rr_label_info_get_authority_qname(const u8 *qname, const zdb_rr_label_find_ext_data *rr_label_info)
150 {
151     const u8 * authority_qname = qname;
152 
153     s32 i = rr_label_info->authority_index;
154     while(i > 0)
155     {
156         authority_qname += authority_qname[0] + 1;
157         i--;
158     }
159 
160     return authority_qname;
161 }
162 
163 /**
164  * @brief Adds the resource record label matching a path of labels starting from another rr label
165  *
166  * Adds the resource record label matching a path of labels starting from another rr label
167  * Typically the starting label is a zone cut.
168  *
169  * @param[in] apex the starting label
170  * @param[in] path a stack of labels
171  * @param[in] path_index the index of the top of the stack
172  *
173  * @return the matching label or NULL if it has not been found
174  */
175 
176 /* 1 USE */
177 zdb_rr_label* zdb_rr_label_add(zdb_zone* zone, dnslabel_vector_reference sections, s32 index);
178 
179 /**
180  * @brief Deletes the resource record of the given type on the label matching a path of labels starting from another rr label
181  *
182  * Deletes the resource record of the given type on the label matching a path of labels starting from another rr label
183  * Typically the starting label is a zone cut.
184  *
185  * @param[in] apex the starting label
186  * @param[in] path a stack of labels
187  * @param[in] path_index the index of the top of the stack
188  *
189  * @return the matching label or NULL if it has not been found
190  */
191 
192 /* 2 USES */
193 ya_result zdb_rr_label_delete_record(zdb_zone* zone, dnslabel_vector_reference path, s32 path_index, u16 type);
194 
195 /**
196  * @brief Deletes the resource record of the given type on the label matching a path of labels starting from another rr label
197  *
198  * Deletes the resource record of the given type on the label matching a path of labels starting from another rr label
199  * Typically the starting label is a zone cut.
200  * This variation on zdb_rr_label_delete_record also removes labels that are empty terminals even if they are linked by a dnssec node.
201  *
202  * @param[in] apex the starting label
203  * @param[in] path a stack of labels
204  * @param[in] path_index the index of the top of the stack
205  *
206  * @return the matching label or NULL if it has not been found
207  */
208 
209 
210 ya_result zdb_rr_label_delete_record_and_empty_terminal(zdb_zone* zone, dnslabel_vector_reference path, s32 path_index, u16 type);
211 
212 /**
213  * @brief Deletes the resource record of the given type, ttl and rdata on the label matching a path of labels starting from another rr label
214  *
215  * Deletes the resource record of the given type, ttl and rdata on the label matching a path of labels starting from another rr label
216  * Typically the starting label is a zone cut.
217  *
218  * @param[in] apex the starting label
219  * @param[in] path a stack of labels
220  * @param[in] path_index the index of the top of the stack
221  *
222  * @return the matching label or NULL if it has not been found
223  */
224 
225 /* 1 USE */
226 ya_result zdb_rr_label_delete_record_exact(zdb_zone* zone, dnslabel_vector_reference path, s32 path_index, u16 type, const zdb_ttlrdata* ttlrdata);
227 
228 /**
229  * For all tool to browse all labels under this one
230  *
231  * @param rr_label
232  * @param type
233  * @return
234  */
235 
236 typedef ya_result zdb_rr_label_forall_cb(zdb_rr_label *rr_label, const u8 *rr_label_fqdn, void *data);
237 
238 ya_result zdb_rr_label_forall_children_of_fqdn(zdb_rr_label *rr_label, const u8 *rr_label_fqdn, zdb_rr_label_forall_cb *callback, void *data);
239 
240 /**
241  * @brief Deletes an EMPTY label
242  *
243  * Deletes an EMPTY label an all it's EMPTY parents
244  * Parents bound to an NSEC structures are not removed
245  *
246  * @param[in] apex the starting label
247  * @param[in] path a stack of labels
248  * @param[in] path_index the index of the top of the stack
249  *
250  * @return the matching label or NULL if it has not been found
251  */
252 
zdb_rr_label_get_rrset(const zdb_rr_label * rr_label,u16 type)253 static inline zdb_packed_ttlrdata* zdb_rr_label_get_rrset(const zdb_rr_label *rr_label, u16 type)
254 {
255     zdb_packed_ttlrdata* rrset = zdb_record_find(&rr_label->resource_record_set, type);
256     return rrset;
257 }
258 
zdb_rr_label_has_rrset(const zdb_rr_label * rr_label,u16 type)259 static inline bool zdb_rr_label_has_rrset(const zdb_rr_label *rr_label, u16 type)
260 {
261     bool ret = (zdb_rr_label_get_rrset(rr_label, type) != NULL); // zone is locked
262     return ret;
263 }
264 
265 /**
266  * @brief Destroys a zone label and its contents
267  *
268  * Destroys a zone label and its contents
269  *
270  * @param[in] zone_labep a pointer to a pointer to the label to destroy
271  *
272  */
273 
274 /* 1 USE */
275 void zdb_rr_label_destroy(zdb_zone* zone, zdb_rr_label** rr_labelp);
276 
277 void zdb_rr_label_truncate(zdb_zone* zone, zdb_rr_label *rr_labelp);
278 
zdb_rr_label_is_glue(const zdb_rr_label * label)279 static inline bool zdb_rr_label_is_glue(const zdb_rr_label* label)
280 {
281     return (label->_flags & (ZDB_RR_LABEL_UNDERDELEGATION | ZDB_RR_LABEL_DELEGATION)) == ZDB_RR_LABEL_UNDERDELEGATION;
282 }
283 
zdb_rr_label_at_delegation(const zdb_rr_label * label)284 static inline bool zdb_rr_label_at_delegation(const zdb_rr_label* label)
285 {
286     return (label->_flags & ZDB_RR_LABEL_DELEGATION) != 0;
287 }
288 
289 #if ZDB_HAS_DNSSEC_SUPPORT
290 /* 2 USES */
291 #define RR_LABEL_RELEVANT(rr_label_)   ((dictionary_notempty(&(rr_label_)->sub))||(btree_notempty((rr_label_)->resource_record_set))||(rr_label_->nsec.dnssec != NULL))
292 
zdb_rr_label_has_children(const zdb_rr_label * label)293 static inline bool zdb_rr_label_has_children(const zdb_rr_label *label) {return dictionary_notempty(&label->sub);}
zdb_rr_label_has_records(const zdb_rr_label * label)294 static inline bool zdb_rr_label_has_records(const zdb_rr_label *label) {return btree_notempty(label->resource_record_set);}
zdb_rr_label_has_no_children(const zdb_rr_label * label)295 static inline bool zdb_rr_label_has_no_children(const zdb_rr_label *label) {return dictionary_isempty(&label->sub);}
zdb_rr_label_has_no_records(const zdb_rr_label * label)296 static inline bool zdb_rr_label_has_no_records(const zdb_rr_label *label) {return btree_isempty(label->resource_record_set);}
zdb_rr_label_has_dnssec_extension(const zdb_rr_label * label)297 static inline bool zdb_rr_label_has_dnssec_extension(const zdb_rr_label *label) {return label->nsec.dnssec != NULL;}
298 
zdb_rr_label_is_empty_terminal(const zdb_rr_label * label)299 static inline bool zdb_rr_label_is_empty_terminal(const zdb_rr_label *label)
300 {
301     return zdb_rr_label_has_no_children(label) && zdb_rr_label_has_no_records(label);
302 }
303 
zdb_rr_label_must_keep(const zdb_rr_label * label)304 static inline bool zdb_rr_label_must_keep(const zdb_rr_label *label)
305 {
306     return (label->_flags & ZDB_RR_LABEL_KEEP) != 0;
307 }
308 
zdb_rr_label_can_be_deleted(const zdb_rr_label * label)309 static inline bool zdb_rr_label_can_be_deleted(const zdb_rr_label *label)
310 {
311     return zdb_rr_label_is_empty_terminal(label) && (!zdb_rr_label_must_keep(label));
312 }
313 
zdb_rr_label_cannot_be_deleted(const zdb_rr_label * label)314 static inline bool zdb_rr_label_cannot_be_deleted(const zdb_rr_label *label)
315 {
316     return (!zdb_rr_label_is_empty_terminal(label)) || zdb_rr_label_must_keep(label);
317 }
318 
319 /* label is only alive because of NSEC3 */
320 #define RR_LABEL_HASSUB(rr_label_)      (dictionary_notempty(&(rr_label_)->sub))
321 #define RR_LABEL_HASSUBORREC(rr_label_)((dictionary_notempty(&(rr_label_)->sub))||(btree_notempty((rr_label_)->resource_record_set)))
322 #define RR_LABEL_NOSUBNORREC(rr_label_)((dictionary_notempty(&(rr_label_)->sub))&&(btree_notempty((rr_label_)->resource_record_set)))
323 
324 /* 9 USES */
325 #define RR_LABEL_IRRELEVANT(rr_label_) ((dictionary_isempty(&(rr_label_)->sub))&&(btree_isempty((rr_label_)->resource_record_set))&&(rr_label_->nsec.dnssec == NULL))
326 #define RR_LABEL_EMPTY_TERMINAL(rr_label_) ((dictionary_isempty(&(rr_label_)->sub))&&(btree_isempty((rr_label_)->resource_record_set)))
327 
328 
329 #else
330 /* 2 USES */
331 #define RR_LABEL_RELEVANT(rr_label_)   (dictionary_notempty(&(rr_label_)->sub)||(btree_notempty((rr_label_)->resource_record_set)))
332 
333 /* 9 USES */
334 #define RR_LABEL_IRRELEVANT(rr_label_) (dictionary_isempty(&(rr_label_)->sub)&&(btree_isempty((rr_label_)->resource_record_set)))
335 
336 #endif
337 
338 u16 zdb_rr_label_bitmap_type_init(zdb_rr_label *rr_label, type_bit_maps_context *bitmap);
339 
340 void zdb_rr_label_print_indented(const zdb_rr_label *rr_label, output_stream *os, int indent);
341 
342 void zdb_rr_label_print(const zdb_rr_label *rr_label, output_stream *os);
343 
344 #ifdef	__cplusplus
345 }
346 #endif
347 
348 #endif	/* _rr_LABEL_H */
349 
350 /** @} */
351