Initial vendor import of ldns-1.6.4 into contrib.
[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
14 /**
15  * Singly linked list of rrs
16  */
17 typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
18 struct ldns_struct_dnssec_rrs
19 {
20         ldns_rr *rr;
21         ldns_dnssec_rrs *next;
22 };
23
24 /**
25  * Singly linked list of RRsets
26  */
27 typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
28 struct ldns_struct_dnssec_rrsets
29 {
30         ldns_dnssec_rrs *rrs;
31         ldns_rr_type type;
32         ldns_dnssec_rrs *signatures;
33         ldns_dnssec_rrsets *next;
34 };
35
36 /**
37  * Structure containing all resource records for a domain name
38  * Including the derived NSEC3, if present
39  */
40 typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
41 struct ldns_struct_dnssec_name
42 {
43         /**
44          * pointer to a dname containing the name.
45          * Usually points to the owner name of the first RR of the first RRset
46          */
47         ldns_rdf *name;
48         /** 
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, 
51          * for instance in
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
54          */
55         bool name_alloced;
56         /**
57          * The rrsets for this name
58          */
59         ldns_dnssec_rrsets *rrsets;
60         /**
61          * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
62          */
63         ldns_rr *nsec;
64         /**
65          * signatures for the NSEC record
66          */
67         ldns_dnssec_rrs *nsec_signatures;
68         /**
69          * Set to true if this name is glue
70          * (as marked by ldns_dnssec_zone_mark_glue())
71          */
72         bool is_glue;
73         /**
74          * pointer to store the hashed name (only used when in an NSEC3 zone
75          */
76         ldns_rdf *hashed_name;
77 };
78
79 /**
80  * Structure containing a dnssec zone
81  */
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 */
86         ldns_rbtree_t *names;
87 };
88 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
89
90 /**
91  * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
92  * \return the allocated data
93  */
94 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
95
96 /**
97  * Frees the list of rrs, but *not* the individual ldns_rr records
98  * contained in the list
99  * 
100  * \param[in] rrs the data structure to free
101  */
102 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
103
104 /**
105  * Frees the list of rrs, and the individual ldns_rr records
106  * contained in the list
107  * 
108  * \param[in] rrs the data structure to free
109  */
110 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
111
112 /**
113  * Adds an RR to the list of RRs. The list will remain ordered
114  *
115  * \param[in] rrs the list to add to
116  * \param[in] rr the RR to add
117  * \return LDNS_STATUS_OK on success
118  */
119 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
120
121 /**
122  * Prints the given rrs to the file descriptor
123  *
124  * \param[in] out the file descriptor to print to
125  * \param[in] rrs the list of RRs to print
126  */
127 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
128
129 /**
130  * Creates a new list (entry) of RRsets
131  * \return the newly allocated structure
132  */
133 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
134
135 /**
136  * Frees the list of rrsets and their rrs, but *not* the ldns_rr
137  * records in the sets
138  *
139  * \param[in] rrsets the data structure to free
140  */
141 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
142
143 /**
144  * Frees the list of rrsets and their rrs, and the ldns_rr
145  * records in the sets
146  *
147  * \param[in] rrsets the data structure to free
148  */
149 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
150
151 /**
152  * Returns the rr type of the rrset (that is head of the given list)
153  *
154  * \param[in] rrsets the rrset to get the type of
155  * \return the rr type
156  */
157 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
158
159 /**
160  * Sets the RR type of the rrset (that is head of the given list)
161  *
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
165  */
166 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
167                                            ldns_rr_type type);
168
169 /**
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.
172  *
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
176  */
177 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
178
179 /**
180  * Print the given list of rrsets to the fiven file descriptor
181  * 
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
185  */ 
186 void ldns_dnssec_rrsets_print(FILE *out,
187                                                 ldns_dnssec_rrsets *rrsets,
188                                                 bool follow);
189
190 /**
191  * Create a new data structure for a dnssec name
192  * \return the allocated structure
193  */
194 ldns_dnssec_name *ldns_dnssec_name_new();
195
196 /**
197  * Create a new data structure for a dnssec name for the given RR
198  *
199  * \param[in] rr the RR to derive properties from, and to add to the name
200  */
201 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
202
203 /**
204  * Frees the name structure and its rrs and rrsets.
205  * Individual ldns_rr records therein are not freed
206  *
207  * \param[in] name the structure to free
208  */
209 void ldns_dnssec_name_free(ldns_dnssec_name *name);
210
211 /**
212  * Frees the name structure and its rrs and rrsets.
213  * Individual ldns_rr records contained in the name are also freed
214  *
215  * \param[in] name the structure to free
216  */
217 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
218
219 /**
220  * Returns the domain name of the given dnssec_name structure
221  *
222  * \param[in] name the dnssec name to get the domain name from
223  * \return the domain name
224  */
225 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
226
227
228 /**
229  * Sets the domain name of the given dnssec_name structure
230  *
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.
233  */
234 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
235                                                  ldns_rdf *dname);
236
237 /**
238  * Sets the NSEC(3) RR of the given dnssec_name structure
239  *
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.
242  */
243 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
244
245 /**
246  * Compares the domain names of the two arguments in their
247  * canonical ordening.
248  * 
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
253  *            equal
254  */
255 int ldns_dnssec_name_cmp(const void *a, const void *b);
256
257 /**
258  * Inserts the given rr at the right place in the current dnssec_name
259  * No checking is done whether the name matches
260  *
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
264  */
265 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
266                                                          ldns_rr *rr);
267
268 /**
269  * Find the RRset with the given type in within this name structure
270  *
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
274  */
275 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
276                                                                            ldns_rr_type type);
277
278 /**
279  * Find the RRset with the given name and type in the zone
280  *
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
285  */
286 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
287                                                                            ldns_rdf *dname,
288                                                                            ldns_rr_type type);
289
290 /**
291  * Prints the RRs in the  dnssec name structure to the given
292  * file descriptor
293  *
294  * \param[in] out the file descriptor to print to
295  * \param[in] name the name structure to print the contents of
296  */
297 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
298
299 /**
300  * Creates a new dnssec_zone structure
301  * \return the allocated structure
302  */
303 ldns_dnssec_zone *ldns_dnssec_zone_new();
304
305 /**
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
309  */ 
310 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
311
312 /**
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
316  */ 
317 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
318
319 /**
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
324  *
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
328  */
329 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
330                                                          ldns_rr *rr);
331
332 /**
333  * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
334  *
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
338  */
339 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
340
341 /**
342  * Prints the complete zone to the given file descriptor
343  *
344  * \param[in] out the file descriptor to print to
345  * \param[in] zone the dnssec_zone to print
346  */
347 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
348
349 /**
350  * Adds explicit dnssec_name structures for the empty nonterminals
351  * in this zone. (this is needed for NSEC3 generation)
352  *
353  * \param[in] zone the zone to check for empty nonterminals
354  * return LDNS_STATUS_OK on success.
355  */
356 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
357
358 #endif