Disconnect hostapd from building in base
[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/rbtree.h>
12 #include <ldns/host2str.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /**
19  * Singly linked list of rrs
20  */
21 typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
22 struct ldns_struct_dnssec_rrs
23 {
24         ldns_rr *rr;
25         ldns_dnssec_rrs *next;
26 };
27
28 /**
29  * Singly linked list of RRsets
30  */
31 typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
32 struct ldns_struct_dnssec_rrsets
33 {
34         ldns_dnssec_rrs *rrs;
35         ldns_rr_type type;
36         ldns_dnssec_rrs *signatures;
37         ldns_dnssec_rrsets *next;
38 };
39
40 /**
41  * Structure containing all resource records for a domain name
42  * Including the derived NSEC3, if present
43  */
44 typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
45 struct ldns_struct_dnssec_name
46 {
47         /**
48          * pointer to a dname containing the name.
49          * Usually points to the owner name of the first RR of the first RRset
50          */
51         ldns_rdf *name;
52         /** 
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, 
55          * for instance in
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
58          */
59         bool name_alloced;
60         /**
61          * The rrsets for this name
62          */
63         ldns_dnssec_rrsets *rrsets;
64         /**
65          * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
66          */
67         ldns_rr *nsec;
68         /**
69          * signatures for the NSEC record
70          */
71         ldns_dnssec_rrs *nsec_signatures;
72         /**
73          * Unlike what the name is_glue suggests, this field is set to true by
74          * ldns_dnssec_zone_mark_glue() or ldns_dnssec_zone_mark_and_get_glue()
75          * when the name, this dnssec_name struct represents, is occluded.
76          * Names that contain other occluded rrsets and records with glue on
77          * the delegation point will NOT have this bool set to true.
78          * This field should NOT be read directly, but only via the 
79          * ldns_dnssec_name_is_glue() function!
80          */
81         bool is_glue;
82         /**
83          * pointer to store the hashed name (only used when in an NSEC3 zone
84          */
85         ldns_rdf *hashed_name;
86 };
87
88 /**
89  * Structure containing a dnssec zone
90  */
91 struct ldns_struct_dnssec_zone {
92         /** points to the name containing the SOA RR */
93         ldns_dnssec_name *soa;
94         /** tree of ldns_dnssec_names */
95         ldns_rbtree_t *names;
96 };
97 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
98
99 /**
100  * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
101  * \return the allocated data
102  */
103 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
104
105 /**
106  * Frees the list of rrs, but *not* the individual ldns_rr records
107  * contained in the list
108  * 
109  * \param[in] rrs the data structure to free
110  */
111 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
112
113 /**
114  * Frees the list of rrs, and the individual ldns_rr records
115  * contained in the list
116  * 
117  * \param[in] rrs the data structure to free
118  */
119 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
120
121 /**
122  * Adds an RR to the list of RRs. The list will remain ordered
123  *
124  * \param[in] rrs the list to add to
125  * \param[in] rr the RR to add
126  * \return LDNS_STATUS_OK on success
127  */
128 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
129
130 /**
131  * Prints the given rrs to the file descriptor
132  *
133  * \param[in] out the file descriptor to print to
134  * \param[in] rrs the list of RRs to print
135  */
136 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
137
138 /**
139  * Prints the given rrs to the file descriptor
140  *
141  * \param[in] out the file descriptor to print to
142  * \param[in] fmt the format of the textual representation
143  * \param[in] rrs the list of RRs to print
144  */
145 void ldns_dnssec_rrs_print_fmt(FILE *out, 
146                 const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
147
148 /**
149  * Creates a new list (entry) of RRsets
150  * \return the newly allocated structure
151  */
152 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
153
154 /**
155  * Frees the list of rrsets and their rrs, but *not* the ldns_rr
156  * records in the sets
157  *
158  * \param[in] rrsets the data structure to free
159  */
160 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
161
162 /**
163  * Frees the list of rrsets and their rrs, and the ldns_rr
164  * records in the sets
165  *
166  * \param[in] rrsets the data structure to free
167  */
168 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
169
170 /**
171  * Returns the rr type of the rrset (that is head of the given list)
172  *
173  * \param[in] rrsets the rrset to get the type of
174  * \return the rr type
175  */
176 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
177
178 /**
179  * Sets the RR type of the rrset (that is head of the given list)
180  *
181  * \param[in] rrsets the rrset to set the type of
182  * \param[in] type the type to set
183  * \return LDNS_STATUS_OK on success
184  */
185 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
186                                            ldns_rr_type type);
187
188 /**
189  * Add an ldns_rr to the corresponding RRset in the given list of RRsets.
190  * If it is not present, add it as a new RRset with 1 record.
191  *
192  * \param[in] rrsets the list of rrsets to add the RR to
193  * \param[in] rr the rr to add to the list of rrsets
194  * \return LDNS_STATUS_OK on success
195  */
196 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
197
198 /**
199  * Print the given list of rrsets to the fiven file descriptor
200  * 
201  * \param[in] out the file descriptor to print to
202  * \param[in] rrsets the list of RRsets to print
203  * \param[in] follow if set to false, only print the first RRset
204  */ 
205 void ldns_dnssec_rrsets_print(FILE *out,
206                 ldns_dnssec_rrsets *rrsets,
207                 bool follow);
208
209 /**
210  * Print the given list of rrsets to the fiven file descriptor
211  * 
212  * \param[in] out the file descriptor to print to
213  * \param[in] fmt the format of the textual representation
214  * \param[in] rrsets the list of RRsets to print
215  * \param[in] follow if set to false, only print the first RRset
216  */ 
217 void ldns_dnssec_rrsets_print_fmt(FILE *out,
218                 const ldns_output_format *fmt,
219                 ldns_dnssec_rrsets *rrsets,
220                 bool follow);
221
222
223 /**
224  * Create a new data structure for a dnssec name
225  * \return the allocated structure
226  */
227 ldns_dnssec_name *ldns_dnssec_name_new();
228
229 /**
230  * Create a new data structure for a dnssec name for the given RR
231  *
232  * \param[in] rr the RR to derive properties from, and to add to the name
233  */
234 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
235
236 /**
237  * Frees the name structure and its rrs and rrsets.
238  * Individual ldns_rr records therein are not freed
239  *
240  * \param[in] name the structure to free
241  */
242 void ldns_dnssec_name_free(ldns_dnssec_name *name);
243
244 /**
245  * Frees the name structure and its rrs and rrsets.
246  * Individual ldns_rr records contained in the name are also freed
247  *
248  * \param[in] name the structure to free
249  */
250 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
251
252 /**
253  * Returns the domain name of the given dnssec_name structure
254  *
255  * \param[in] name the dnssec name to get the domain name from
256  * \return the domain name
257  */
258 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
259
260
261 /**
262  * Sets the domain name of the given dnssec_name structure
263  *
264  * \param[in] name the dnssec name to set the domain name of
265  * \param[in] dname the domain name to set it to. This data is *not* copied.
266  */
267 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
268                                                  ldns_rdf *dname);
269 /**
270  * Returns if dnssec_name structure is marked as glue.
271  * The ldns_dnssec_zone_mark_glue() function has to be called on a zone before
272  * using this function.
273  * Only names that have only glue rrsets will be marked.
274  * Names that have other occluded rrsets and names containing glue on the 
275  * delegation point will NOT be marked!
276  *
277  * \param[in] name the dnssec name to get the domain name from
278  * \return true if the structure is marked as glue, false otherwise.
279  */
280 bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
281
282 /**
283  * Sets the NSEC(3) RR of the given dnssec_name structure
284  *
285  * \param[in] name the dnssec name to set the domain name of
286  * \param[in] nsec the nsec rr to set it to. This data is *not* copied.
287  */
288 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
289
290 /**
291  * Compares the domain names of the two arguments in their
292  * canonical ordening.
293  * 
294  * \param[in] a The first dnssec_name to compare
295  * \param[in] b The second dnssec_name to compare
296  * \return -1 if the domain name of a comes before that of b in canonical
297  *            ordening, 1 if it is the other way around, and 0 if they are
298  *            equal
299  */
300 int ldns_dnssec_name_cmp(const void *a, const void *b);
301
302 /**
303  * Inserts the given rr at the right place in the current dnssec_name
304  * No checking is done whether the name matches
305  *
306  * \param[in] name The ldns_dnssec_name to add the RR to
307  * \param[in] rr The RR to add
308  * \return LDNS_STATUS_OK on success, error code otherwise
309  */
310 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
311                                                          ldns_rr *rr);
312
313 /**
314  * Find the RRset with the given type in within this name structure
315  *
316  * \param[in] name the name to find the RRset in
317  * \param[in] type the type of the RRset to find
318  * \return the RRset, or NULL if not present
319  */
320 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
321                                                                            ldns_rr_type type);
322
323 /**
324  * Find the RRset with the given name and type in the zone
325  *
326  * \param[in] zone the zone structure to find the RRset in
327  * \param[in] dname the domain name of the RRset to find
328  * \param[in] type the type of the RRset to find
329  * \return the RRset, or NULL if not present
330  */
331 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
332                                                                            ldns_rdf *dname,
333                                                                            ldns_rr_type type);
334
335 /**
336  * Prints the RRs in the  dnssec name structure to the given
337  * file descriptor
338  *
339  * \param[in] out the file descriptor to print to
340  * \param[in] name the name structure to print the contents of
341  */
342 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
343
344 /**
345  * Prints the RRs in the  dnssec name structure to the given
346  * file descriptor
347  *
348  * \param[in] out the file descriptor to print to
349  * \param[in] fmt the format of the textual representation
350  * \param[in] name the name structure to print the contents of
351  */
352 void ldns_dnssec_name_print_fmt(FILE *out, 
353                 const ldns_output_format *fmt, ldns_dnssec_name *name);
354
355 /**
356  * Creates a new dnssec_zone structure
357  * \return the allocated structure
358  */
359 ldns_dnssec_zone *ldns_dnssec_zone_new();
360
361 /**
362  * Create a new dnssec zone from a file.
363  * \param[out] z the new zone
364  * \param[in] *fp the filepointer to use
365  * \param[in] *origin the zones' origin
366  * \param[in] c default class to use (IN)
367  * \param[in] ttl default ttl to use
368  *
369  * \return ldns_status mesg with an error or LDNS_STATUS_OK
370  */
371 ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp,
372                 ldns_rdf* origin, uint32_t ttl, ldns_rr_class c);
373
374 /**
375  * Create a new dnssec zone from a file, keep track of the line numbering
376  * \param[out] z the new zone
377  * \param[in] *fp the filepointer to use
378  * \param[in] *origin the zones' origin
379  * \param[in] ttl default ttl to use
380  * \param[in] c default class to use (IN)
381  * \param[out] line_nr used for error msg, to get to the line number
382  *
383  * \return ldns_status mesg with an error or LDNS_STATUS_OK
384  */
385 ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp,
386                 ldns_rdf* origin, uint32_t ttl, ldns_rr_class c, int* line_nr);
387
388 /**
389  * Frees the given zone structure, and its rbtree of dnssec_names
390  * Individual ldns_rr RRs within those names are *not* freed
391  * \param[in] *zone the zone to free
392  */ 
393 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
394
395 /**
396  * Frees the given zone structure, and its rbtree of dnssec_names
397  * Individual ldns_rr RRs within those names are also freed
398  * \param[in] *zone the zone to free
399  */ 
400 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
401
402 /**
403  * Adds the given RR to the zone.
404  * It find whether there is a dnssec_name with that name present.
405  * If so, add it to that, if not create a new one. 
406  * Special handling of NSEC and RRSIG provided
407  *
408  * \param[in] zone the zone to add the RR to
409  * \param[in] rr The RR to add
410  * \return LDNS_STATUS_OK on success, an error code otherwise
411  */
412 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
413                                                          ldns_rr *rr);
414
415 /**
416  * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
417  *
418  * \param[in] out the file descriptor to print the names to
419  * \param[in] tree the tree of ldns_dnssec_name structures to print
420  * \param[in] print_soa if true, print SOA records, if false, skip them
421  */
422 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
423
424 /**
425  * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
426  *
427  * \param[in] out the file descriptor to print the names to
428  * \param[in] fmt the format of the textual representation
429  * \param[in] tree the tree of ldns_dnssec_name structures to print
430  * \param[in] print_soa if true, print SOA records, if false, skip them
431  */
432 void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
433                 ldns_rbtree_t *tree, bool print_soa);
434
435 /**
436  * Prints the complete zone to the given file descriptor
437  *
438  * \param[in] out the file descriptor to print to
439  * \param[in] zone the dnssec_zone to print
440  */
441 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
442
443 /**
444  * Prints the complete zone to the given file descriptor
445  *
446  * \param[in] out the file descriptor to print to
447  * \param[in] fmt the format of the textual representation
448  * \param[in] zone the dnssec_zone to print
449  */
450 void ldns_dnssec_zone_print_fmt(FILE *out, 
451                 const ldns_output_format *fmt, ldns_dnssec_zone *zone);
452
453 /**
454  * Adds explicit dnssec_name structures for the empty nonterminals
455  * in this zone. (this is needed for NSEC3 generation)
456  *
457  * \param[in] zone the zone to check for empty nonterminals
458  * return LDNS_STATUS_OK on success.
459  */
460 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
461
462 /**
463  * If a NSEC3PARAM is available in the apex, walks the zone and returns true
464  * on the first optout nsec3.
465  *
466  * \param[in] zone the zone to check for nsec3 optout records
467  * return true when the zone has at least one nsec3 optout record.
468  */
469 bool ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone);
470
471 #ifdef __cplusplus
472 }
473 #endif
474
475 #endif