88117dafb3a95035682a8a6a91a128d9d7857187
[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 #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          * Set to true if this name is glue
74          * (as marked by ldns_dnssec_zone_mark_glue())
75          */
76         bool is_glue;
77         /**
78          * pointer to store the hashed name (only used when in an NSEC3 zone
79          */
80         ldns_rdf *hashed_name;
81 };
82
83 /**
84  * Structure containing a dnssec zone
85  */
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 */
90         ldns_rbtree_t *names;
91 };
92 typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
93
94 /**
95  * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
96  * \return the allocated data
97  */
98 ldns_dnssec_rrs *ldns_dnssec_rrs_new();
99
100 /**
101  * Frees the list of rrs, but *not* the individual ldns_rr records
102  * contained in the list
103  * 
104  * \param[in] rrs the data structure to free
105  */
106 void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
107
108 /**
109  * Frees the list of rrs, and the individual ldns_rr records
110  * contained in the list
111  * 
112  * \param[in] rrs the data structure to free
113  */
114 void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
115
116 /**
117  * Adds an RR to the list of RRs. The list will remain ordered
118  *
119  * \param[in] rrs the list to add to
120  * \param[in] rr the RR to add
121  * \return LDNS_STATUS_OK on success
122  */
123 ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
124
125 /**
126  * Prints the given rrs to the file descriptor
127  *
128  * \param[in] out the file descriptor to print to
129  * \param[in] rrs the list of RRs to print
130  */
131 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
132
133 /**
134  * Creates a new list (entry) of RRsets
135  * \return the newly allocated structure
136  */
137 ldns_dnssec_rrsets *ldns_dnssec_rrsets_new();
138
139 /**
140  * Frees the list of rrsets and their rrs, but *not* the ldns_rr
141  * records in the sets
142  *
143  * \param[in] rrsets the data structure to free
144  */
145 void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
146
147 /**
148  * Frees the list of rrsets and their rrs, and the ldns_rr
149  * records in the sets
150  *
151  * \param[in] rrsets the data structure to free
152  */
153 void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
154
155 /**
156  * Returns the rr type of the rrset (that is head of the given list)
157  *
158  * \param[in] rrsets the rrset to get the type of
159  * \return the rr type
160  */
161 ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
162
163 /**
164  * Sets the RR type of the rrset (that is head of the given list)
165  *
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
169  */
170 ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
171                                            ldns_rr_type type);
172
173 /**
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.
176  *
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
180  */
181 ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
182
183 /**
184  * Print the given list of rrsets to the fiven file descriptor
185  * 
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
189  */ 
190 void ldns_dnssec_rrsets_print(FILE *out,
191                                                 ldns_dnssec_rrsets *rrsets,
192                                                 bool follow);
193
194 /**
195  * Create a new data structure for a dnssec name
196  * \return the allocated structure
197  */
198 ldns_dnssec_name *ldns_dnssec_name_new();
199
200 /**
201  * Create a new data structure for a dnssec name for the given RR
202  *
203  * \param[in] rr the RR to derive properties from, and to add to the name
204  */
205 ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
206
207 /**
208  * Frees the name structure and its rrs and rrsets.
209  * Individual ldns_rr records therein are not freed
210  *
211  * \param[in] name the structure to free
212  */
213 void ldns_dnssec_name_free(ldns_dnssec_name *name);
214
215 /**
216  * Frees the name structure and its rrs and rrsets.
217  * Individual ldns_rr records contained in the name are also freed
218  *
219  * \param[in] name the structure to free
220  */
221 void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
222
223 /**
224  * Returns the domain name of the given dnssec_name structure
225  *
226  * \param[in] name the dnssec name to get the domain name from
227  * \return the domain name
228  */
229 ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
230
231
232 /**
233  * Sets the domain name of the given dnssec_name structure
234  *
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.
237  */
238 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
239                                                  ldns_rdf *dname);
240
241 /**
242  * Sets the NSEC(3) RR of the given dnssec_name structure
243  *
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.
246  */
247 void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
248
249 /**
250  * Compares the domain names of the two arguments in their
251  * canonical ordening.
252  * 
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
257  *            equal
258  */
259 int ldns_dnssec_name_cmp(const void *a, const void *b);
260
261 /**
262  * Inserts the given rr at the right place in the current dnssec_name
263  * No checking is done whether the name matches
264  *
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
268  */
269 ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
270                                                          ldns_rr *rr);
271
272 /**
273  * Find the RRset with the given type in within this name structure
274  *
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
278  */
279 ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
280                                                                            ldns_rr_type type);
281
282 /**
283  * Find the RRset with the given name and type in the zone
284  *
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
289  */
290 ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
291                                                                            ldns_rdf *dname,
292                                                                            ldns_rr_type type);
293
294 /**
295  * Prints the RRs in the  dnssec name structure to the given
296  * file descriptor
297  *
298  * \param[in] out the file descriptor to print to
299  * \param[in] name the name structure to print the contents of
300  */
301 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
302
303 /**
304  * Creates a new dnssec_zone structure
305  * \return the allocated structure
306  */
307 ldns_dnssec_zone *ldns_dnssec_zone_new();
308
309 /**
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
313  */ 
314 void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
315
316 /**
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
320  */ 
321 void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
322
323 /**
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
328  *
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
332  */
333 ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
334                                                          ldns_rr *rr);
335
336 /**
337  * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
338  *
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
342  */
343 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
344
345 /**
346  * Prints the complete zone to the given file descriptor
347  *
348  * \param[in] out the file descriptor to print to
349  * \param[in] zone the dnssec_zone to print
350  */
351 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
352
353 /**
354  * Adds explicit dnssec_name structures for the empty nonterminals
355  * in this zone. (this is needed for NSEC3 generation)
356  *
357  * \param[in] zone the zone to check for empty nonterminals
358  * return LDNS_STATUS_OK on success.
359  */
360 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
361
362 #ifdef __cplusplus
363 }
364 #endif
365
366 #endif