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>
19 * Singly linked list of rrs
21 typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
22 struct ldns_struct_dnssec_rrs
25 ldns_dnssec_rrs *next;
29 * Singly linked list of RRsets
31 typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
32 struct ldns_struct_dnssec_rrsets
36 ldns_dnssec_rrs *signatures;
37 ldns_dnssec_rrsets *next;
41 * Structure containing all resource records for a domain name
42 * Including the derived NSEC3, if present
44 typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
45 struct ldns_struct_dnssec_name
48 * pointer to a dname containing the name.
49 * Usually points to the owner name of the first RR of the first RRset
53 * Usually, the name is a pointer to the owner name of the first rr for
54 * this name, but sometimes there is no actual data to point to,
56 * names representing empty nonterminals. If so, set alloced to true to
57 * indicate that this data must also be freed when the name is freed
61 * The rrsets for this name
63 ldns_dnssec_rrsets *rrsets;
65 * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
69 * signatures for the NSEC record
71 ldns_dnssec_rrs *nsec_signatures;
73 * Set to true if this name is glue
74 * (as marked by ldns_dnssec_zone_mark_glue())
78 * pointer to store the hashed name (only used when in an NSEC3 zone
80 ldns_rdf *hashed_name;
84 * Structure containing a dnssec zone
86 struct ldns_struct_dnssec_zone {
87 /** points to the name containing the SOA RR */
88 ldns_dnssec_name *soa;
89 /** tree of ldns_dnssec_names */
92 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
95 * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
96 * \return the allocated data
98 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
101 * Frees the list of rrs, but *not* the individual ldns_rr records
102 * contained in the list
104 * \param[in] rrs the data structure to free
106 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
109 * Frees the list of rrs, and the individual ldns_rr records
110 * contained in the list
112 * \param[in] rrs the data structure to free
114 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
117 * Adds an RR to the list of RRs. The list will remain ordered
119 * \param[in] rrs the list to add to
120 * \param[in] rr the RR to add
121 * \return LDNS_STATUS_OK on success
123 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
126 * Prints the given rrs to the file descriptor
128 * \param[in] out the file descriptor to print to
129 * \param[in] rrs the list of RRs to print
131 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
134 * Creates a new list (entry) of RRsets
135 * \return the newly allocated structure
137 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
140 * Frees the list of rrsets and their rrs, but *not* the ldns_rr
141 * records in the sets
143 * \param[in] rrsets the data structure to free
145 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
148 * Frees the list of rrsets and their rrs, and the ldns_rr
149 * records in the sets
151 * \param[in] rrsets the data structure to free
153 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
156 * Returns the rr type of the rrset (that is head of the given list)
158 * \param[in] rrsets the rrset to get the type of
159 * \return the rr type
161 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
164 * Sets the RR type of the rrset (that is head of the given list)
166 * \param[in] rrsets the rrset to set the type of
167 * \param[in] type the type to set
168 * \return LDNS_STATUS_OK on success
170 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
174 * Add an ldns_rr to the corresponding RRset in the given list of RRsets.
175 * If it is not present, add it as a new RRset with 1 record.
177 * \param[in] rrsets the list of rrsets to add the RR to
178 * \param[in] rr the rr to add to the list of rrsets
179 * \return LDNS_STATUS_OK on success
181 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
184 * Print the given list of rrsets to the fiven file descriptor
186 * \param[in] out the file descriptor to print to
187 * \param[in] rrsets the list of RRsets to print
188 * \param[in] follow if set to false, only print the first RRset
190 void ldns_dnssec_rrsets_print(FILE *out,
191 ldns_dnssec_rrsets *rrsets,
195 * Create a new data structure for a dnssec name
196 * \return the allocated structure
198 ldns_dnssec_name *ldns_dnssec_name_new();
201 * Create a new data structure for a dnssec name for the given RR
203 * \param[in] rr the RR to derive properties from, and to add to the name
205 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
208 * Frees the name structure and its rrs and rrsets.
209 * Individual ldns_rr records therein are not freed
211 * \param[in] name the structure to free
213 void ldns_dnssec_name_free(ldns_dnssec_name *name);
216 * Frees the name structure and its rrs and rrsets.
217 * Individual ldns_rr records contained in the name are also freed
219 * \param[in] name the structure to free
221 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
224 * Returns the domain name of the given dnssec_name structure
226 * \param[in] name the dnssec name to get the domain name from
227 * \return the domain name
229 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
233 * Sets the domain name of the given dnssec_name structure
235 * \param[in] name the dnssec name to set the domain name of
236 * \param[in] dname the domain name to set it to. This data is *not* copied.
238 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
242 * Sets the NSEC(3) RR of the given dnssec_name structure
244 * \param[in] name the dnssec name to set the domain name of
245 * \param[in] nsec the nsec rr to set it to. This data is *not* copied.
247 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
250 * Compares the domain names of the two arguments in their
251 * canonical ordening.
253 * \param[in] a The first dnssec_name to compare
254 * \param[in] b The second dnssec_name to compare
255 * \return -1 if the domain name of a comes before that of b in canonical
256 * ordening, 1 if it is the other way around, and 0 if they are
259 int ldns_dnssec_name_cmp(const void *a, const void *b);
262 * Inserts the given rr at the right place in the current dnssec_name
263 * No checking is done whether the name matches
265 * \param[in] name The ldns_dnssec_name to add the RR to
266 * \param[in] rr The RR to add
267 * \return LDNS_STATUS_OK on success, error code otherwise
269 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
273 * Find the RRset with the given type in within this name structure
275 * \param[in] name the name to find the RRset in
276 * \param[in] type the type of the RRset to find
277 * \return the RRset, or NULL if not present
279 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
283 * Find the RRset with the given name and type in the zone
285 * \param[in] zone the zone structure to find the RRset in
286 * \param[in] dname the domain name of the RRset to find
287 * \param[in] type the type of the RRset to find
288 * \return the RRset, or NULL if not present
290 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
295 * Prints the RRs in the dnssec name structure to the given
298 * \param[in] out the file descriptor to print to
299 * \param[in] name the name structure to print the contents of
301 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
304 * Creates a new dnssec_zone structure
305 * \return the allocated structure
307 ldns_dnssec_zone *ldns_dnssec_zone_new();
310 * Frees the given zone structure, and its rbtree of dnssec_names
311 * Individual ldns_rr RRs within those names are *not* freed
312 * \param[in] *zone the zone to free
314 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
317 * Frees the given zone structure, and its rbtree of dnssec_names
318 * Individual ldns_rr RRs within those names are also freed
319 * \param[in] *zone the zone to free
321 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
324 * Adds the given RR to the zone.
325 * It find whether there is a dnssec_name with that name present.
326 * If so, add it to that, if not create a new one.
327 * Special handling of NSEC and RRSIG provided
329 * \param[in] zone the zone to add the RR to
330 * \param[in] rr The RR to add
331 * \return LDNS_STATUS_OK on success, an error code otherwise
333 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
337 * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
339 * \param[in] out the file descriptor to print the names to
340 * \param[in] tree the tree of ldns_dnssec_name structures to print
341 * \param[in] print_soa if true, print SOA records, if false, skip them
343 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
346 * Prints the complete zone to the given file descriptor
348 * \param[in] out the file descriptor to print to
349 * \param[in] zone the dnssec_zone to print
351 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
354 * Adds explicit dnssec_name structures for the empty nonterminals
355 * in this zone. (this is needed for NSEC3 generation)
357 * \param[in] zone the zone to check for empty nonterminals
358 * return LDNS_STATUS_OK on success.
360 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);