ldns: Update vendor branch to 1.6.11
[dragonfly.git] / contrib / ldns / ldns / dnssec_zone.h
1 /*
2  * special zone file structures and functions for better dnssec handling
3  *
4  * A zone contains a SOA dnssec_zone_rrset, and an AVL tree of 'normal'
5  * dnssec_zone_rrsets, indexed by name and type
6  */
7
8 #ifndef LDNS_DNSSEC_ZONE_H
9 #define LDNS_DNSSEC_ZONE_H
10  
11 #include <ldns/ldns.h>
12 #include <ldns/rbtree.h>
13 #include <ldns/host2str.h>
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /**
20  * Singly linked list of rrs
21  */
22 typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
23 struct ldns_struct_dnssec_rrs
24 {
25         ldns_rr *rr;
26         ldns_dnssec_rrs *next;
27 };
28
29 /**
30  * Singly linked list of RRsets
31  */
32 typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
33 struct ldns_struct_dnssec_rrsets
34 {
35         ldns_dnssec_rrs *rrs;
36         ldns_rr_type type;
37         ldns_dnssec_rrs *signatures;
38         ldns_dnssec_rrsets *next;
39 };
40
41 /**
42  * Structure containing all resource records for a domain name
43  * Including the derived NSEC3, if present
44  */
45 typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
46 struct ldns_struct_dnssec_name
47 {
48         /**
49          * pointer to a dname containing the name.
50          * Usually points to the owner name of the first RR of the first RRset
51          */
52         ldns_rdf *name;
53         /** 
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, 
56          * for instance in
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
59          */
60         bool name_alloced;
61         /**
62          * The rrsets for this name
63          */
64         ldns_dnssec_rrsets *rrsets;
65         /**
66          * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
67          */
68         ldns_rr *nsec;
69         /**
70          * signatures for the NSEC record
71          */
72         ldns_dnssec_rrs *nsec_signatures;
73         /**
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!
81          */
82         bool is_glue;
83         /**
84          * pointer to store the hashed name (only used when in an NSEC3 zone
85          */
86         ldns_rdf *hashed_name;
87 };
88
89 /**
90  * Structure containing a dnssec zone
91  */
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 */
96         ldns_rbtree_t *names;
97 };
98 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
99
100 /**
101  * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
102  * \return the allocated data
103  */
104 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
105
106 /**
107  * Frees the list of rrs, but *not* the individual ldns_rr records
108  * contained in the list
109  * 
110  * \param[in] rrs the data structure to free
111  */
112 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
113
114 /**
115  * Frees the list of rrs, and the individual ldns_rr records
116  * contained in the list
117  * 
118  * \param[in] rrs the data structure to free
119  */
120 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
121
122 /**
123  * Adds an RR to the list of RRs. The list will remain ordered
124  *
125  * \param[in] rrs the list to add to
126  * \param[in] rr the RR to add
127  * \return LDNS_STATUS_OK on success
128  */
129 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
130
131 /**
132  * Prints the given rrs to the file descriptor
133  *
134  * \param[in] out the file descriptor to print to
135  * \param[in] rrs the list of RRs to print
136  */
137 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
138
139 /**
140  * Prints the given rrs to the file descriptor
141  *
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
145  */
146 void ldns_dnssec_rrs_print_fmt(FILE *out, 
147                 const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
148
149 /**
150  * Creates a new list (entry) of RRsets
151  * \return the newly allocated structure
152  */
153 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
154
155 /**
156  * Frees the list of rrsets and their rrs, but *not* the ldns_rr
157  * records in the sets
158  *
159  * \param[in] rrsets the data structure to free
160  */
161 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
162
163 /**
164  * Frees the list of rrsets and their rrs, and the ldns_rr
165  * records in the sets
166  *
167  * \param[in] rrsets the data structure to free
168  */
169 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
170
171 /**
172  * Returns the rr type of the rrset (that is head of the given list)
173  *
174  * \param[in] rrsets the rrset to get the type of
175  * \return the rr type
176  */
177 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
178
179 /**
180  * Sets the RR type of the rrset (that is head of the given list)
181  *
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
185  */
186 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
187                                            ldns_rr_type type);
188
189 /**
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.
192  *
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
196  */
197 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
198
199 /**
200  * Print the given list of rrsets to the fiven file descriptor
201  * 
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
205  */ 
206 void ldns_dnssec_rrsets_print(FILE *out,
207                 ldns_dnssec_rrsets *rrsets,
208                 bool follow);
209
210 /**
211  * Print the given list of rrsets to the fiven file descriptor
212  * 
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
217  */ 
218 void ldns_dnssec_rrsets_print_fmt(FILE *out,
219                 const ldns_output_format *fmt,
220                 ldns_dnssec_rrsets *rrsets,
221                 bool follow);
222
223
224 /**
225  * Create a new data structure for a dnssec name
226  * \return the allocated structure
227  */
228 ldns_dnssec_name *ldns_dnssec_name_new();
229
230 /**
231  * Create a new data structure for a dnssec name for the given RR
232  *
233  * \param[in] rr the RR to derive properties from, and to add to the name
234  */
235 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
236
237 /**
238  * Frees the name structure and its rrs and rrsets.
239  * Individual ldns_rr records therein are not freed
240  *
241  * \param[in] name the structure to free
242  */
243 void ldns_dnssec_name_free(ldns_dnssec_name *name);
244
245 /**
246  * Frees the name structure and its rrs and rrsets.
247  * Individual ldns_rr records contained in the name are also freed
248  *
249  * \param[in] name the structure to free
250  */
251 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
252
253 /**
254  * Returns the domain name of the given dnssec_name structure
255  *
256  * \param[in] name the dnssec name to get the domain name from
257  * \return the domain name
258  */
259 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
260
261
262 /**
263  * Sets the domain name of the given dnssec_name structure
264  *
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.
267  */
268 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
269                                                  ldns_rdf *dname);
270 /**
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!
277  *
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.
280  */
281 bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
282
283 /**
284  * Sets the NSEC(3) RR of the given dnssec_name structure
285  *
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.
288  */
289 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
290
291 /**
292  * Compares the domain names of the two arguments in their
293  * canonical ordening.
294  * 
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
299  *            equal
300  */
301 int ldns_dnssec_name_cmp(const void *a, const void *b);
302
303 /**
304  * Inserts the given rr at the right place in the current dnssec_name
305  * No checking is done whether the name matches
306  *
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
310  */
311 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
312                                                          ldns_rr *rr);
313
314 /**
315  * Find the RRset with the given type in within this name structure
316  *
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
320  */
321 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
322                                                                            ldns_rr_type type);
323
324 /**
325  * Find the RRset with the given name and type in the zone
326  *
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
331  */
332 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
333                                                                            ldns_rdf *dname,
334                                                                            ldns_rr_type type);
335
336 /**
337  * Prints the RRs in the  dnssec name structure to the given
338  * file descriptor
339  *
340  * \param[in] out the file descriptor to print to
341  * \param[in] name the name structure to print the contents of
342  */
343 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
344
345 /**
346  * Prints the RRs in the  dnssec name structure to the given
347  * file descriptor
348  *
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
352  */
353 void ldns_dnssec_name_print_fmt(FILE *out, 
354                 const ldns_output_format *fmt, ldns_dnssec_name *name);
355
356 /**
357  * Creates a new dnssec_zone structure
358  * \return the allocated structure
359  */
360 ldns_dnssec_zone *ldns_dnssec_zone_new();
361
362 /**
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
366  */ 
367 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
368
369 /**
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
373  */ 
374 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
375
376 /**
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
381  *
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
385  */
386 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
387                                                          ldns_rr *rr);
388
389 /**
390  * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
391  *
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
395  */
396 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
397
398 /**
399  * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
400  *
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
405  */
406 void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
407                 ldns_rbtree_t *tree, bool print_soa);
408
409 /**
410  * Prints the complete zone to the given file descriptor
411  *
412  * \param[in] out the file descriptor to print to
413  * \param[in] zone the dnssec_zone to print
414  */
415 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
416
417 /**
418  * Prints the complete zone to the given file descriptor
419  *
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
423  */
424 void ldns_dnssec_zone_print_fmt(FILE *out, 
425                 const ldns_output_format *fmt, ldns_dnssec_zone *zone);
426
427 /**
428  * Adds explicit dnssec_name structures for the empty nonterminals
429  * in this zone. (this is needed for NSEC3 generation)
430  *
431  * \param[in] zone the zone to check for empty nonterminals
432  * return LDNS_STATUS_OK on success.
433  */
434 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
435
436 #ifdef __cplusplus
437 }
438 #endif
439
440 #endif