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>
15 * Singly linked list of rrs
17 typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
18 struct ldns_struct_dnssec_rrs
21 ldns_dnssec_rrs *next;
25 * Singly linked list of RRsets
27 typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
28 struct ldns_struct_dnssec_rrsets
32 ldns_dnssec_rrs *signatures;
33 ldns_dnssec_rrsets *next;
37 * Structure containing all resource records for a domain name
38 * Including the derived NSEC3, if present
40 typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
41 struct ldns_struct_dnssec_name
44 * pointer to a dname containing the name.
45 * Usually points to the owner name of the first RR of the first RRset
49 * Usually, the name is a pointer to the owner name of the first rr for
50 * this name, but sometimes there is no actual data to point to,
52 * names representing empty nonterminals. If so, set alloced to true to
53 * indicate that this data must also be freed when the name is freed
57 * The rrsets for this name
59 ldns_dnssec_rrsets *rrsets;
61 * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
65 * signatures for the NSEC record
67 ldns_dnssec_rrs *nsec_signatures;
69 * Set to true if this name is glue
70 * (as marked by ldns_dnssec_zone_mark_glue())
74 * pointer to store the hashed name (only used when in an NSEC3 zone
76 ldns_rdf *hashed_name;
80 * Structure containing a dnssec zone
82 struct ldns_struct_dnssec_zone {
83 /** points to the name containing the SOA RR */
84 ldns_dnssec_name *soa;
85 /** tree of ldns_dnssec_names */
88 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
91 * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
92 * \return the allocated data
94 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
97 * Frees the list of rrs, but *not* the individual ldns_rr records
98 * contained in the list
100 * \param[in] rrs the data structure to free
102 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
105 * Frees the list of rrs, and the individual ldns_rr records
106 * contained in the list
108 * \param[in] rrs the data structure to free
110 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
113 * Adds an RR to the list of RRs. The list will remain ordered
115 * \param[in] rrs the list to add to
116 * \param[in] rr the RR to add
117 * \return LDNS_STATUS_OK on success
119 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
122 * Prints the given rrs to the file descriptor
124 * \param[in] out the file descriptor to print to
125 * \param[in] rrs the list of RRs to print
127 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
130 * Creates a new list (entry) of RRsets
131 * \return the newly allocated structure
133 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
136 * Frees the list of rrsets and their rrs, but *not* the ldns_rr
137 * records in the sets
139 * \param[in] rrsets the data structure to free
141 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
144 * Frees the list of rrsets and their rrs, and the ldns_rr
145 * records in the sets
147 * \param[in] rrsets the data structure to free
149 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
152 * Returns the rr type of the rrset (that is head of the given list)
154 * \param[in] rrsets the rrset to get the type of
155 * \return the rr type
157 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
160 * Sets the RR type of the rrset (that is head of the given list)
162 * \param[in] rrsets the rrset to set the type of
163 * \param[in] type the type to set
164 * \return LDNS_STATUS_OK on success
166 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
170 * Add an ldns_rr to the corresponding RRset in the given list of RRsets.
171 * If it is not present, add it as a new RRset with 1 record.
173 * \param[in] rrsets the list of rrsets to add the RR to
174 * \param[in] rr the rr to add to the list of rrsets
175 * \return LDNS_STATUS_OK on success
177 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
180 * Print the given list of rrsets to the fiven file descriptor
182 * \param[in] out the file descriptor to print to
183 * \param[in] rrsets the list of RRsets to print
184 * \param[in] follow if set to false, only print the first RRset
186 void ldns_dnssec_rrsets_print(FILE *out,
187 ldns_dnssec_rrsets *rrsets,
191 * Create a new data structure for a dnssec name
192 * \return the allocated structure
194 ldns_dnssec_name *ldns_dnssec_name_new();
197 * Create a new data structure for a dnssec name for the given RR
199 * \param[in] rr the RR to derive properties from, and to add to the name
201 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
204 * Frees the name structure and its rrs and rrsets.
205 * Individual ldns_rr records therein are not freed
207 * \param[in] name the structure to free
209 void ldns_dnssec_name_free(ldns_dnssec_name *name);
212 * Frees the name structure and its rrs and rrsets.
213 * Individual ldns_rr records contained in the name are also freed
215 * \param[in] name the structure to free
217 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
220 * Returns the domain name of the given dnssec_name structure
222 * \param[in] name the dnssec name to get the domain name from
223 * \return the domain name
225 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
229 * Sets the domain name of the given dnssec_name structure
231 * \param[in] name the dnssec name to set the domain name of
232 * \param[in] dname the domain name to set it to. This data is *not* copied.
234 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
238 * Sets the NSEC(3) RR of the given dnssec_name structure
240 * \param[in] name the dnssec name to set the domain name of
241 * \param[in] nsec the nsec rr to set it to. This data is *not* copied.
243 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
246 * Compares the domain names of the two arguments in their
247 * canonical ordening.
249 * \param[in] a The first dnssec_name to compare
250 * \param[in] b The second dnssec_name to compare
251 * \return -1 if the domain name of a comes before that of b in canonical
252 * ordening, 1 if it is the other way around, and 0 if they are
255 int ldns_dnssec_name_cmp(const void *a, const void *b);
258 * Inserts the given rr at the right place in the current dnssec_name
259 * No checking is done whether the name matches
261 * \param[in] name The ldns_dnssec_name to add the RR to
262 * \param[in] rr The RR to add
263 * \return LDNS_STATUS_OK on success, error code otherwise
265 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
269 * Find the RRset with the given type in within this name structure
271 * \param[in] name the name to find the RRset in
272 * \param[in] type the type of the RRset to find
273 * \return the RRset, or NULL if not present
275 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
279 * Find the RRset with the given name and type in the zone
281 * \param[in] zone the zone structure to find the RRset in
282 * \param[in] dname the domain name of the RRset to find
283 * \param[in] type the type of the RRset to find
284 * \return the RRset, or NULL if not present
286 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
291 * Prints the RRs in the dnssec name structure to the given
294 * \param[in] out the file descriptor to print to
295 * \param[in] name the name structure to print the contents of
297 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
300 * Creates a new dnssec_zone structure
301 * \return the allocated structure
303 ldns_dnssec_zone *ldns_dnssec_zone_new();
306 * Frees the given zone structure, and its rbtree of dnssec_names
307 * Individual ldns_rr RRs within those names are *not* freed
308 * \param[in] *zone the zone to free
310 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
313 * Frees the given zone structure, and its rbtree of dnssec_names
314 * Individual ldns_rr RRs within those names are also freed
315 * \param[in] *zone the zone to free
317 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
320 * Adds the given RR to the zone.
321 * It find whether there is a dnssec_name with that name present.
322 * If so, add it to that, if not create a new one.
323 * Special handling of NSEC and RRSIG provided
325 * \param[in] zone the zone to add the RR to
326 * \param[in] rr The RR to add
327 * \return LDNS_STATUS_OK on success, an error code otherwise
329 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
333 * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
335 * \param[in] out the file descriptor to print the names to
336 * \param[in] tree the tree of ldns_dnssec_name structures to print
337 * \param[in] print_soa if true, print SOA records, if false, skip them
339 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
342 * Prints the complete zone to the given file descriptor
344 * \param[in] out the file descriptor to print to
345 * \param[in] zone the dnssec_zone to print
347 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
350 * Adds explicit dnssec_name structures for the empty nonterminals
351 * in this zone. (this is needed for NSEC3 generation)
353 * \param[in] zone the zone to check for empty nonterminals
354 * return LDNS_STATUS_OK on success.
356 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);