2 * special zone file structures and functions for better dnssec handling
4 * A zone contains a SOA dnssec_zone_rrset, and an AVL tree of 'normal'
5 * dnssec_zone_rrsets, indexed by name and type
8 #ifndef LDNS_DNSSEC_ZONE_H
9 #define LDNS_DNSSEC_ZONE_H
11 #include <ldns/ldns.h>
12 #include <ldns/rbtree.h>
13 #include <ldns/host2str.h>
20 * Singly linked list of rrs
22 typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
23 struct ldns_struct_dnssec_rrs
26 ldns_dnssec_rrs *next;
30 * Singly linked list of RRsets
32 typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
33 struct ldns_struct_dnssec_rrsets
37 ldns_dnssec_rrs *signatures;
38 ldns_dnssec_rrsets *next;
42 * Structure containing all resource records for a domain name
43 * Including the derived NSEC3, if present
45 typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
46 struct ldns_struct_dnssec_name
49 * pointer to a dname containing the name.
50 * Usually points to the owner name of the first RR of the first RRset
54 * Usually, the name is a pointer to the owner name of the first rr for
55 * this name, but sometimes there is no actual data to point to,
57 * names representing empty nonterminals. If so, set alloced to true to
58 * indicate that this data must also be freed when the name is freed
62 * The rrsets for this name
64 ldns_dnssec_rrsets *rrsets;
66 * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
70 * signatures for the NSEC record
72 ldns_dnssec_rrs *nsec_signatures;
74 * Unlike what the name is_glue suggests, this field is set to true by
75 * ldns_dnssec_zone_mark_glue() or ldns_dnssec_zone_mark_and_get_glue()
76 * when the name, this dnssec_name struct represents, is occluded.
77 * Names that contain other occluded rrsets and records with glue on
78 * the delegation point will NOT have this bool set to true.
79 * This field should NOT be read directly, but only via the
80 * ldns_dnssec_name_is_glue() function!
84 * pointer to store the hashed name (only used when in an NSEC3 zone
86 ldns_rdf *hashed_name;
90 * Structure containing a dnssec zone
92 struct ldns_struct_dnssec_zone {
93 /** points to the name containing the SOA RR */
94 ldns_dnssec_name *soa;
95 /** tree of ldns_dnssec_names */
98 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
101 * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
102 * \return the allocated data
104 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
107 * Frees the list of rrs, but *not* the individual ldns_rr records
108 * contained in the list
110 * \param[in] rrs the data structure to free
112 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
115 * Frees the list of rrs, and the individual ldns_rr records
116 * contained in the list
118 * \param[in] rrs the data structure to free
120 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
123 * Adds an RR to the list of RRs. The list will remain ordered
125 * \param[in] rrs the list to add to
126 * \param[in] rr the RR to add
127 * \return LDNS_STATUS_OK on success
129 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
132 * Prints the given rrs to the file descriptor
134 * \param[in] out the file descriptor to print to
135 * \param[in] rrs the list of RRs to print
137 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
140 * Prints the given rrs to the file descriptor
142 * \param[in] out the file descriptor to print to
143 * \param[in] fmt the format of the textual representation
144 * \param[in] rrs the list of RRs to print
146 void ldns_dnssec_rrs_print_fmt(FILE *out,
147 const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
150 * Creates a new list (entry) of RRsets
151 * \return the newly allocated structure
153 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
156 * Frees the list of rrsets and their rrs, but *not* the ldns_rr
157 * records in the sets
159 * \param[in] rrsets the data structure to free
161 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
164 * Frees the list of rrsets and their rrs, and the ldns_rr
165 * records in the sets
167 * \param[in] rrsets the data structure to free
169 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
172 * Returns the rr type of the rrset (that is head of the given list)
174 * \param[in] rrsets the rrset to get the type of
175 * \return the rr type
177 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
180 * Sets the RR type of the rrset (that is head of the given list)
182 * \param[in] rrsets the rrset to set the type of
183 * \param[in] type the type to set
184 * \return LDNS_STATUS_OK on success
186 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
190 * Add an ldns_rr to the corresponding RRset in the given list of RRsets.
191 * If it is not present, add it as a new RRset with 1 record.
193 * \param[in] rrsets the list of rrsets to add the RR to
194 * \param[in] rr the rr to add to the list of rrsets
195 * \return LDNS_STATUS_OK on success
197 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
200 * Print the given list of rrsets to the fiven file descriptor
202 * \param[in] out the file descriptor to print to
203 * \param[in] rrsets the list of RRsets to print
204 * \param[in] follow if set to false, only print the first RRset
206 void ldns_dnssec_rrsets_print(FILE *out,
207 ldns_dnssec_rrsets *rrsets,
211 * Print the given list of rrsets to the fiven file descriptor
213 * \param[in] out the file descriptor to print to
214 * \param[in] fmt the format of the textual representation
215 * \param[in] rrsets the list of RRsets to print
216 * \param[in] follow if set to false, only print the first RRset
218 void ldns_dnssec_rrsets_print_fmt(FILE *out,
219 const ldns_output_format *fmt,
220 ldns_dnssec_rrsets *rrsets,
225 * Create a new data structure for a dnssec name
226 * \return the allocated structure
228 ldns_dnssec_name *ldns_dnssec_name_new();
231 * Create a new data structure for a dnssec name for the given RR
233 * \param[in] rr the RR to derive properties from, and to add to the name
235 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
238 * Frees the name structure and its rrs and rrsets.
239 * Individual ldns_rr records therein are not freed
241 * \param[in] name the structure to free
243 void ldns_dnssec_name_free(ldns_dnssec_name *name);
246 * Frees the name structure and its rrs and rrsets.
247 * Individual ldns_rr records contained in the name are also freed
249 * \param[in] name the structure to free
251 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
254 * Returns the domain name of the given dnssec_name structure
256 * \param[in] name the dnssec name to get the domain name from
257 * \return the domain name
259 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
263 * Sets the domain name of the given dnssec_name structure
265 * \param[in] name the dnssec name to set the domain name of
266 * \param[in] dname the domain name to set it to. This data is *not* copied.
268 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
271 * Returns if dnssec_name structure is marked as glue.
272 * The ldns_dnssec_zone_mark_glue() function has to be called on a zone before
273 * using this function.
274 * Only names that have only glue rrsets will be marked.
275 * Names that have other occluded rrsets and names containing glue on the
276 * delegation point will NOT be marked!
278 * \param[in] name the dnssec name to get the domain name from
279 * \return true if the structure is marked as glue, false otherwise.
281 bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
284 * Sets the NSEC(3) RR of the given dnssec_name structure
286 * \param[in] name the dnssec name to set the domain name of
287 * \param[in] nsec the nsec rr to set it to. This data is *not* copied.
289 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
292 * Compares the domain names of the two arguments in their
293 * canonical ordening.
295 * \param[in] a The first dnssec_name to compare
296 * \param[in] b The second dnssec_name to compare
297 * \return -1 if the domain name of a comes before that of b in canonical
298 * ordening, 1 if it is the other way around, and 0 if they are
301 int ldns_dnssec_name_cmp(const void *a, const void *b);
304 * Inserts the given rr at the right place in the current dnssec_name
305 * No checking is done whether the name matches
307 * \param[in] name The ldns_dnssec_name to add the RR to
308 * \param[in] rr The RR to add
309 * \return LDNS_STATUS_OK on success, error code otherwise
311 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
315 * Find the RRset with the given type in within this name structure
317 * \param[in] name the name to find the RRset in
318 * \param[in] type the type of the RRset to find
319 * \return the RRset, or NULL if not present
321 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
325 * Find the RRset with the given name and type in the zone
327 * \param[in] zone the zone structure to find the RRset in
328 * \param[in] dname the domain name of the RRset to find
329 * \param[in] type the type of the RRset to find
330 * \return the RRset, or NULL if not present
332 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
337 * Prints the RRs in the dnssec name structure to the given
340 * \param[in] out the file descriptor to print to
341 * \param[in] name the name structure to print the contents of
343 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
346 * Prints the RRs in the dnssec name structure to the given
349 * \param[in] out the file descriptor to print to
350 * \param[in] fmt the format of the textual representation
351 * \param[in] name the name structure to print the contents of
353 void ldns_dnssec_name_print_fmt(FILE *out,
354 const ldns_output_format *fmt, ldns_dnssec_name *name);
357 * Creates a new dnssec_zone structure
358 * \return the allocated structure
360 ldns_dnssec_zone *ldns_dnssec_zone_new();
363 * Frees the given zone structure, and its rbtree of dnssec_names
364 * Individual ldns_rr RRs within those names are *not* freed
365 * \param[in] *zone the zone to free
367 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
370 * Frees the given zone structure, and its rbtree of dnssec_names
371 * Individual ldns_rr RRs within those names are also freed
372 * \param[in] *zone the zone to free
374 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
377 * Adds the given RR to the zone.
378 * It find whether there is a dnssec_name with that name present.
379 * If so, add it to that, if not create a new one.
380 * Special handling of NSEC and RRSIG provided
382 * \param[in] zone the zone to add the RR to
383 * \param[in] rr The RR to add
384 * \return LDNS_STATUS_OK on success, an error code otherwise
386 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
390 * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
392 * \param[in] out the file descriptor to print the names to
393 * \param[in] tree the tree of ldns_dnssec_name structures to print
394 * \param[in] print_soa if true, print SOA records, if false, skip them
396 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
399 * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
401 * \param[in] out the file descriptor to print the names to
402 * \param[in] fmt the format of the textual representation
403 * \param[in] tree the tree of ldns_dnssec_name structures to print
404 * \param[in] print_soa if true, print SOA records, if false, skip them
406 void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
407 ldns_rbtree_t *tree, bool print_soa);
410 * Prints the complete zone to the given file descriptor
412 * \param[in] out the file descriptor to print to
413 * \param[in] zone the dnssec_zone to print
415 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
418 * Prints the complete zone to the given file descriptor
420 * \param[in] out the file descriptor to print to
421 * \param[in] fmt the format of the textual representation
422 * \param[in] zone the dnssec_zone to print
424 void ldns_dnssec_zone_print_fmt(FILE *out,
425 const ldns_output_format *fmt, ldns_dnssec_zone *zone);
428 * Adds explicit dnssec_name structures for the empty nonterminals
429 * in this zone. (this is needed for NSEC3 generation)
431 * \param[in] zone the zone to check for empty nonterminals
432 * return LDNS_STATUS_OK on success.
434 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);