ldns documentation

- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

dnssec_zone.c
Go to the documentation of this file.
1 /*
2 * special zone file structures and functions for better dnssec handling
3 */
4
5 #include <ldns/config.h>
6
7 #include <ldns/ldns.h>
8
9 ldns_dnssec_rrs *
10 ldns_dnssec_rrs_new(void)
11 {
12 ldns_dnssec_rrs *new_rrs;
13 new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
14 if(!new_rrs) return NULL;
15 new_rrs->rr = NULL;
16 new_rrs->next = NULL;
17 return new_rrs;
18 }
19
20 INLINE void
21 ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep)
22 {
23 ldns_dnssec_rrs *next;
24 while (rrs) {
25 next = rrs->next;
26 if (deep) {
27 ldns_rr_free(rrs->rr);
28 }
29 LDNS_FREE(rrs);
30 rrs = next;
31 }
32 }
33
34 void
35 ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
36 {
37 ldns_dnssec_rrs_free_internal(rrs, 0);
38 }
39
40 void
41 ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs)
42 {
43 ldns_dnssec_rrs_free_internal(rrs, 1);
44 }
45
46 ldns_status
47 ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
48 {
49 int cmp;
50 ldns_dnssec_rrs *new_rrs;
51 if (!rrs || !rr) {
52 return LDNS_STATUS_ERR;
53 }
54
55 /* this could be done more efficiently; name and type should already
56 be equal */
57 cmp = ldns_rr_compare(rrs->rr, rr);
58 if (cmp < 0) {
59 if (rrs->next) {
60 return ldns_dnssec_rrs_add_rr(rrs->next, rr);
61 } else {
62 new_rrs = ldns_dnssec_rrs_new();
63 new_rrs->rr = rr;
64 rrs->next = new_rrs;
65 }
66 } else if (cmp > 0) {
67 /* put the current old rr in the new next, put the new
68 rr in the current container */
69 new_rrs = ldns_dnssec_rrs_new();
70 new_rrs->rr = rrs->rr;
71 new_rrs->next = rrs->next;
72 rrs->rr = rr;
73 rrs->next = new_rrs;
74 }
75 /* Silently ignore equal rr's */
76 return LDNS_STATUS_OK;
77 }
78
79 void
80 ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
81 ldns_dnssec_rrs *rrs)
82 {
83 if (!rrs) {
84 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
85 fprintf(out, "; <void>");
86 } else {
87 if (rrs->rr) {
88 ldns_rr_print_fmt(out, fmt, rrs->rr);
89 }
90 if (rrs->next) {
91 ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next);
92 }
93 }
94 }
95
96 void
97 ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
98 {
99 ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs);
100 }
101
102
103 ldns_dnssec_rrsets *
104 ldns_dnssec_rrsets_new(void)
105 {
106 ldns_dnssec_rrsets *new_rrsets;
107 new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
108 if(!new_rrsets) return NULL;
109 new_rrsets->rrs = NULL;
110 new_rrsets->type = 0;
111 new_rrsets->signatures = NULL;
112 new_rrsets->next = NULL;
113 return new_rrsets;
114 }
115
116 INLINE void
117 ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep)
118 {
119 if (rrsets) {
120 if (rrsets->rrs) {
121 ldns_dnssec_rrs_free_internal(rrsets->rrs, deep);
122 }
123 if (rrsets->next) {
124 ldns_dnssec_rrsets_free_internal(rrsets->next, deep);
125 }
126 if (rrsets->signatures) {
127 ldns_dnssec_rrs_free_internal(rrsets->signatures, deep);
128 }
129 LDNS_FREE(rrsets);
130 }
131 }
132
133 void
134 ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
135 {
136 ldns_dnssec_rrsets_free_internal(rrsets, 0);
137 }
138
139 void
140 ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
141 {
142 ldns_dnssec_rrsets_free_internal(rrsets, 1);
143 }
144
145 ldns_rr_type
146 ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
147 {
148 if (rrsets) {
149 return rrsets->type;
150 } else {
151 return 0;
152 }
153 }
154
155 ldns_status
156 ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
157 ldns_rr_type type)
158 {
159 if (rrsets) {
160 rrsets->type = type;
161 return LDNS_STATUS_OK;
162 }
163 return LDNS_STATUS_ERR;
164 }
165
166 static ldns_dnssec_rrsets *
167 ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr)
168 {
169 ldns_dnssec_rrsets *new_rrsets;
170 ldns_rr_type rr_type;
171 bool rrsig;
172
173 new_rrsets = ldns_dnssec_rrsets_new();
174 rr_type = ldns_rr_get_type(rr);
175 if (rr_type == LDNS_RR_TYPE_RRSIG) {
176 rrsig = true;
177 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
178 } else {
179 rrsig = false;
180 }
181 if (!rrsig) {
182 new_rrsets->rrs = ldns_dnssec_rrs_new();
183 new_rrsets->rrs->rr = rr;
184 } else {
185 new_rrsets->signatures = ldns_dnssec_rrs_new();
186 new_rrsets->signatures->rr = rr;
187 }
188 new_rrsets->type = rr_type;
189 return new_rrsets;
190 }
191
192 ldns_status
193 ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
194 {
195 ldns_dnssec_rrsets *new_rrsets;
196 ldns_rr_type rr_type;
197 bool rrsig = false;
198 ldns_status result = LDNS_STATUS_OK;
199
200 if (!rrsets || !rr) {
201 return LDNS_STATUS_ERR;
202 }
203
204 rr_type = ldns_rr_get_type(rr);
205
206 if (rr_type == LDNS_RR_TYPE_RRSIG) {
207 rrsig = true;
208 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
209 }
210
211 if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) {
212 if (!rrsig) {
213 rrsets->rrs = ldns_dnssec_rrs_new();
214 rrsets->rrs->rr = rr;
215 rrsets->type = rr_type;
216 } else {
217 rrsets->signatures = ldns_dnssec_rrs_new();
218 rrsets->signatures->rr = rr;
219 rrsets->type = rr_type;
220 }
221 return LDNS_STATUS_OK;
222 }
223
224 if (rr_type > ldns_dnssec_rrsets_type(rrsets)) {
225 if (rrsets->next) {
226 result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr);
227 } else {
228 new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr);
229 rrsets->next = new_rrsets;
230 }
231 } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) {
232 /* move the current one into the new next,
233 replace field of current with data from new rr */
234 new_rrsets = ldns_dnssec_rrsets_new();
235 new_rrsets->rrs = rrsets->rrs;
236 new_rrsets->type = rrsets->type;
237 new_rrsets->signatures = rrsets->signatures;
238 new_rrsets->next = rrsets->next;
239 if (!rrsig) {
240 rrsets->rrs = ldns_dnssec_rrs_new();
241 rrsets->rrs->rr = rr;
242 rrsets->signatures = NULL;
243 } else {
244 rrsets->rrs = NULL;
245 rrsets->signatures = ldns_dnssec_rrs_new();
246 rrsets->signatures->rr = rr;
247 }
248 rrsets->type = rr_type;
249 rrsets->next = new_rrsets;
250 } else {
251 /* equal, add to current rrsets */
252 if (rrsig) {
253 if (rrsets->signatures) {
254 result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr);
255 } else {
256 rrsets->signatures = ldns_dnssec_rrs_new();
257 rrsets->signatures->rr = rr;
258 }
259 } else {
260 if (rrsets->rrs) {
261 result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr);
262 } else {
263 rrsets->rrs = ldns_dnssec_rrs_new();
264 rrsets->rrs->rr = rr;
265 }
266 }
267 }
268
269 return result;
270 }
271
272 static void
273 ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
274 ldns_dnssec_rrsets *rrsets,
275 bool follow,
276 bool show_soa)
277 {
278 if (!rrsets) {
279 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
280 fprintf(out, "; <void>\n");
281 } else {
282 if (rrsets->rrs &&
283 (show_soa ||
284 ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA
285 )
286 ) {
287 ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
288 if (rrsets->signatures) {
289 ldns_dnssec_rrs_print_fmt(out, fmt,
290 rrsets->signatures);
291 }
292 }
293 if (follow && rrsets->next) {
294 ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
295 rrsets->next, follow, show_soa);
296 }
297 }
298 }
299
300
301 void
302 ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt,
303 ldns_dnssec_rrsets *rrsets,
304 bool follow)
305 {
306 ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
307 }
308
309 void
310 ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
311 {
312 ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default,
313 rrsets, follow);
314 }
315
316 ldns_dnssec_name *
317 ldns_dnssec_name_new(void)
318 {
319 ldns_dnssec_name *new_name;
320
321 new_name = LDNS_CALLOC(ldns_dnssec_name, 1);
322 if (!new_name) {
323 return NULL;
324 }
325 /*
326 * not needed anymore because CALLOC initalizes everything to zero.
327
328 new_name->name = NULL;
329 new_name->rrsets = NULL;
330 new_name->name_alloced = false;
331 new_name->nsec = NULL;
332 new_name->nsec_signatures = NULL;
333
334 new_name->is_glue = false;
335 new_name->hashed_name = NULL;
336
337 */
338 return new_name;
339 }
340
341 ldns_dnssec_name *
342 ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
343 {
344 ldns_dnssec_name *new_name = ldns_dnssec_name_new();
345
346 new_name->name = ldns_rr_owner(rr);
347 if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) {
348 ldns_dnssec_name_free(new_name);
349 return NULL;
350 }
351
352 return new_name;
353 }
354
355 INLINE void
356 ldns_dnssec_name_free_internal(ldns_dnssec_name *name,
357 int deep)
358 {
359 if (name) {
360 if (name->name_alloced) {
361 ldns_rdf_deep_free(name->name);
362 }
363 if (name->rrsets) {
364 ldns_dnssec_rrsets_free_internal(name->rrsets, deep);
365 }
366 if (name->nsec && deep) {
367 ldns_rr_free(name->nsec);
368 }
369 if (name->nsec_signatures) {
370 ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
371 }
372 if (name->hashed_name) {
373 if (deep) {
374 ldns_rdf_deep_free(name->hashed_name);
375 }
376 }
377 LDNS_FREE(name);
378 }
379 }
380
381 void
382 ldns_dnssec_name_free(ldns_dnssec_name *name)
383 {
384 ldns_dnssec_name_free_internal(name, 0);
385 }
386
387 void
388 ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
389 {
390 ldns_dnssec_name_free_internal(name, 1);
391 }
392
393 ldns_rdf *
394 ldns_dnssec_name_name(ldns_dnssec_name *name)
395 {
396 if (name) {
397 return name->name;
398 }
399 return NULL;
400 }
401
402 bool
403 ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
404 {
405 if (name) {
406 return name->is_glue;
407 }
408 return false;
409 }
410
411 void
412 ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
413 ldns_rdf *dname)
414 {
415 if (rrset && dname) {
416 rrset->name = dname;
417 }
418 }
419
420
421 void
422 ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
423 {
424 if (rrset && nsec) {
425 rrset->nsec = nsec;
426 }
427 }
428
429 int
430 ldns_dnssec_name_cmp(const void *a, const void *b)
431 {
432 ldns_dnssec_name *na = (ldns_dnssec_name *) a;
433 ldns_dnssec_name *nb = (ldns_dnssec_name *) b;
434
435 if (na && nb) {
436 return ldns_dname_compare(ldns_dnssec_name_name(na),
437 ldns_dnssec_name_name(nb));
438 } else if (na) {
439 return 1;
440 } else if (nb) {
441 return -1;
442 } else {
443 return 0;
444 }
445 }
446
447 ldns_status
448 ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
449 ldns_rr *rr)
450 {
451 ldns_status result = LDNS_STATUS_OK;
452 ldns_rr_type rr_type;
453 ldns_rr_type typecovered = 0;
454
455 /* special handling for NSEC3 and NSECX covering RRSIGS */
456
457 if (!name || !rr) {
458 return LDNS_STATUS_ERR;
459 }
460
461 rr_type = ldns_rr_get_type(rr);
462
463 if (rr_type == LDNS_RR_TYPE_RRSIG) {
464 typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
465 }
466
467 if (rr_type == LDNS_RR_TYPE_NSEC ||
468 rr_type == LDNS_RR_TYPE_NSEC3) {
469 /* XX check if is already set (and error?) */
470 name->nsec = rr;
471 } else if (typecovered == LDNS_RR_TYPE_NSEC ||
472 typecovered == LDNS_RR_TYPE_NSEC3) {
473 if (name->nsec_signatures) {
474 result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
475 } else {
476 name->nsec_signatures = ldns_dnssec_rrs_new();
477 name->nsec_signatures->rr = rr;
478 }
479 } else {
480 /* it's a 'normal' RR, add it to the right rrset */
481 if (name->rrsets) {
482 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
483 } else {
484 name->rrsets = ldns_dnssec_rrsets_new();
485 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
486 }
487 }
488 return result;
489 }
490
491 ldns_dnssec_rrsets *
492 ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
493 ldns_rr_type type) {
494 ldns_dnssec_rrsets *result;
495
496 result = name->rrsets;
497 while (result) {
498 if (result->type == type) {
499 return result;
500 } else {
501 result = result->next;
502 }
503 }
504 return NULL;
505 }
506
507 ldns_dnssec_rrsets *
508 ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
509 ldns_rdf *dname,
510 ldns_rr_type type)
511 {
512 ldns_rbnode_t *node;
513
514 if (!zone || !dname) {
515 return NULL;
516 }
517
518 node = ldns_rbtree_search(zone->names, dname);
519 if (node) {
520 return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data,
521 type);
522 } else {
523 return NULL;
524 }
525 }
526
527 static void
528 ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
529 ldns_dnssec_name *name,
530 bool show_soa)
531 {
532 if (name) {
533 if(name->rrsets) {
534 ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
535 name->rrsets, true, show_soa);
536 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
537 fprintf(out, ";; Empty nonterminal: ");
538 ldns_rdf_print(out, name->name);
539 fprintf(out, "\n");
540 }
541 if(name->nsec) {
542 ldns_rr_print_fmt(out, fmt, name->nsec);
543 }
544 if (name->nsec_signatures) {
545 ldns_dnssec_rrs_print_fmt(out, fmt,
546 name->nsec_signatures);
547 }
548 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
549 fprintf(out, "; <void>\n");
550 }
551 }
552
553
554 void
555 ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt,
556 ldns_dnssec_name *name)
557 {
558 ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
559 }
560
561 void
562 ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
563 {
564 ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name);
565 }
566
567
568 ldns_dnssec_zone *
569 ldns_dnssec_zone_new(void)
570 {
571 ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
572 if(!zone) return NULL;
573 zone->soa = NULL;
574 zone->names = NULL;
575 zone->hashed_names = NULL;
576 zone->_nsec3params = NULL;
577
578 return zone;
579 }
580
581 static bool
582 rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
583 {
584 return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG
585 && ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t;
586 }
587
588 /* When the zone is first read into an list and then inserted into an
589 * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next)
590 * to each other. Because ldns-verify-zone (the only program that uses this
591 * function) uses the rbtree mostly for sequentual walking, this results
592 * in a speed increase (of 15% on linux) because we have less CPU-cache misses.
593 */
594 #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
595
596 ldns_status
597 ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
598 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
599 {
600 ldns_rr* cur_rr;
601 size_t i;
602
603 ldns_rdf *my_origin = NULL;
604 ldns_rdf *my_prev = NULL;
605
606 ldns_dnssec_zone *newzone = ldns_dnssec_zone_new();
607 /* when reading NSEC3s, there is a chance that we encounter nsecs
608 for empty nonterminals, whose nonterminals we cannot derive yet
609 because the needed information is to be read later. in that case
610 we keep a list of those nsec3's and retry to add them later */
611 ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
612 ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
613
614 ldns_status status = LDNS_STATUS_MEM_ERR;
615
616 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
617 ldns_zone* zone = NULL;
618 if (ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr)
619 != LDNS_STATUS_OK) goto error;
620 #else
621 uint32_t my_ttl = ttl;
622 #endif
623
624 if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) goto error;
625
626 if (origin) {
627 if (!(my_origin = ldns_rdf_clone(origin))) goto error;
628 if (!(my_prev = ldns_rdf_clone(origin))) goto error;
629 }
630
631 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
632 if (ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone))
633 != LDNS_STATUS_OK) goto error;
634
635 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
636 cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
637 status = LDNS_STATUS_OK;
638 #else
639 while (!feof(fp)) {
640 status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
641 &my_prev, line_nr);
642
643 #endif
644 switch (status) {
645 case LDNS_STATUS_OK:
646
647 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
648 if (status ==
649 LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
650
651 if (rr_is_rrsig_covering(cur_rr,
652 LDNS_RR_TYPE_NSEC3)){
653 ldns_rr_list_push_rr(todo_nsec3_rrsigs,
654 cur_rr);
655 } else {
656 ldns_rr_list_push_rr(todo_nsec3s,
657 cur_rr);
658 }
659 status = LDNS_STATUS_OK;
660
661 } else if (status != LDNS_STATUS_OK)
662 goto error;
663
664 break;
665
666
667 case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */
668 case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/
669 case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/
670 status = LDNS_STATUS_OK;
671 break;
672
673 case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
674 status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
675 break;
676
677 default:
678 goto error;
679 }
680 }
681
682 if (ldns_rr_list_rr_count(todo_nsec3s) > 0) {
683 (void) ldns_dnssec_zone_add_empty_nonterminals(newzone);
684 for (i = 0; status == LDNS_STATUS_OK &&
685 i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
686 cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
687 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
688 }
689 }
690 if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) {
691 for (i = 0; status == LDNS_STATUS_OK &&
692 i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
693 i++){
694 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
695 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
696 }
697 }
698
699 if (z) {
700 *z = newzone;
701 newzone = NULL;
702 } else {
703 ldns_dnssec_zone_free(newzone);
704 }
705
706 error:
707 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
708 if (zone) {
709 ldns_zone_free(zone);
710 }
711 #endif
712 ldns_rr_list_free(todo_nsec3_rrsigs);
713 ldns_rr_list_free(todo_nsec3s);
714
715 if (my_origin) {
716 ldns_rdf_deep_free(my_origin);
717 }
718 if (my_prev) {
719 ldns_rdf_deep_free(my_prev);
720 }
721 if (newzone) {
722 ldns_dnssec_zone_free(newzone);
723 }
724 return status;
725 }
726
727 ldns_status
728 ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
729 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
730 {
731 return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
732 }
733
734 static void
735 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
736 (void) arg;
737 ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
738 LDNS_FREE(node);
739 }
740
741 static void
742 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
743 (void) arg;
744 ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data);
745 LDNS_FREE(node);
746 }
747
748 void
749 ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
750 {
751 if (zone) {
752 if (zone->names) {
753 /* destroy all name structures within the tree */
754 ldns_traverse_postorder(zone->names,
755 ldns_dnssec_name_node_free,
756 NULL);
757 LDNS_FREE(zone->names);
758 }
759 LDNS_FREE(zone);
760 }
761 }
762
763 void
764 ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
765 {
766 if (zone) {
767 if (zone->names) {
768 /* destroy all name structures within the tree */
769 ldns_traverse_postorder(zone->names,
770 ldns_dnssec_name_node_deep_free,
771 NULL);
772 LDNS_FREE(zone->names);
773 }
774 LDNS_FREE(zone);
775 }
776 }
777
778 /* use for dname comparison in tree */
779 int
780 ldns_dname_compare_v(const void *a, const void *b) {
781 return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
782 }
783
784 static void
785 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
786 ldns_dnssec_name* name, ldns_rr* nsec3rr);
787
788 static void
789 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
790 (void) arg;
791 LDNS_FREE(node);
792 }
793
794 static void
795 ldns_dnssec_zone_hashed_names_from_nsec3(
796 ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
797 {
798 ldns_rbnode_t* current_node;
799 ldns_dnssec_name* current_name;
800
801 assert(zone != NULL);
802 assert(nsec3rr != NULL);
803
804 if (zone->hashed_names) {
805 ldns_traverse_postorder(zone->hashed_names,
806 ldns_hashed_names_node_free, NULL);
807 LDNS_FREE(zone->hashed_names);
808 }
809 zone->_nsec3params = nsec3rr;
810
811 /* So this is a NSEC3 zone.
812 * Calculate hashes for all names already in the zone
813 */
814 zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
815 if (zone->hashed_names == NULL) {
816 return;
817 }
818 for ( current_node = ldns_rbtree_first(zone->names)
819 ; current_node != LDNS_RBTREE_NULL
820 ; current_node = ldns_rbtree_next(current_node)
821 ) {
822 current_name = (ldns_dnssec_name *) current_node->data;
823 ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
824
825 }
826 }
827
828 static void
829 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
830 ldns_dnssec_name* name, ldns_rr* nsec3rr)
831 {
832 ldns_rbnode_t* new_node;
833
834 assert(name != NULL);
835 if (! zone->_nsec3params) {
836 if (! nsec3rr) {
837 return;
838 }
839 ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
840
841 } else if (! nsec3rr) {
842 nsec3rr = zone->_nsec3params;
843 }
844 name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
845
846 /* Also store in zone->hashed_names */
847 if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
848
849 new_node->key = name->hashed_name;
850 new_node->data = name;
851
852 if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
853
854 LDNS_FREE(new_node);
855 }
856 }
857 }
858
859
860 static ldns_rbnode_t *
861 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
862 ldns_rdf *hashed_name;
863
864 hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
865 if (hashed_name == NULL) {
866 return NULL;
867 }
868 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
869
870 ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
871 }
872 if (zone->hashed_names == NULL) {
873 ldns_rdf_deep_free(hashed_name);
874 return NULL;
875 }
876 return ldns_rbtree_search(zone->hashed_names, hashed_name);
877 }
878
879 ldns_status
880 ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
881 {
882 ldns_status result = LDNS_STATUS_OK;
883 ldns_dnssec_name *cur_name;
884 ldns_rbnode_t *cur_node;
885 ldns_rr_type type_covered = 0;
886
887 if (!zone || !rr) {
888 return LDNS_STATUS_ERR;
889 }
890
891 if (!zone->names) {
892 zone->names = ldns_rbtree_create(ldns_dname_compare_v);
893 if(!zone->names) return LDNS_STATUS_MEM_ERR;
894 }
895
896 /* we need the original of the hashed name if this is
897 an NSEC3, or an RRSIG that covers an NSEC3 */
898 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
899 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
900 }
901 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
902 type_covered == LDNS_RR_TYPE_NSEC3) {
903 cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
904 if (!cur_node) {
905 return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
906 }
907 } else {
908 cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
909 }
910 if (!cur_node) {
911 /* add */
912 cur_name = ldns_dnssec_name_new_frm_rr(rr);
913 if(!cur_name) return LDNS_STATUS_MEM_ERR;
914 cur_node = LDNS_MALLOC(ldns_rbnode_t);
915 if(!cur_node) {
916 ldns_dnssec_name_free(cur_name);
917 return LDNS_STATUS_MEM_ERR;
918 }
919 cur_node->key = ldns_rr_owner(rr);
920 cur_node->data = cur_name;
921 (void)ldns_rbtree_insert(zone->names, cur_node);
922 ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
923 } else {
924 cur_name = (ldns_dnssec_name *) cur_node->data;
925 result = ldns_dnssec_name_add_rr(cur_name, rr);
926 }
927 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
928 zone->soa = cur_name;
929 }
930 return result;
931 }
932
933 void
934 ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
935 ldns_rbtree_t *tree,
936 bool print_soa)
937 {
938 ldns_rbnode_t *node;
939 ldns_dnssec_name *name;
940
941 node = ldns_rbtree_first(tree);
942 while (node != LDNS_RBTREE_NULL) {
943 name = (ldns_dnssec_name *) node->data;
944 ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
945 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
946 fprintf(out, ";\n");
947 node = ldns_rbtree_next(node);
948 }
949 }
950
951 void
952 ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
953 {
954 ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
955 tree, print_soa);
956 }
957
958 void
959 ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
960 ldns_dnssec_zone *zone)
961 {
962 if (zone) {
963 if (zone->soa) {
964 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
965 fprintf(out, ";; Zone: ");
966 ldns_rdf_print(out, ldns_dnssec_name_name(
967 zone->soa));
968 fprintf(out, "\n;\n");
969 }
970 ldns_dnssec_rrsets_print_fmt(out, fmt,
971 ldns_dnssec_name_find_rrset(
972 zone->soa,
973 LDNS_RR_TYPE_SOA),
974 false);
975 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
976 fprintf(out, ";\n");
977 }
978
979 if (zone->names) {
980 ldns_dnssec_zone_names_print_fmt(out, fmt,
981 zone->names, false);
982 }
983 }
984 }
985
986 void
987 ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
988 {
989 ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
990 }
991
992 ldns_status
993 ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
994 {
995 ldns_dnssec_name *new_name;
996 ldns_rdf *cur_name;
997 ldns_rdf *next_name;
998 ldns_rbnode_t *cur_node, *next_node, *new_node;
999
1000 /* for the detection */
1001 uint16_t i, cur_label_count, next_label_count;
1002 uint16_t soa_label_count = 0;
1003 ldns_rdf *l1, *l2;
1004 int lpos;
1005
1006 if (!zone) {
1007 return LDNS_STATUS_ERR;
1008 }
1009 if (zone->soa && zone->soa->name) {
1010 soa_label_count = ldns_dname_label_count(zone->soa->name);
1011 }
1012
1013 cur_node = ldns_rbtree_first(zone->names);
1014 while (cur_node != LDNS_RBTREE_NULL) {
1015 next_node = ldns_rbtree_next(cur_node);
1016
1017 /* skip glue */
1018 while (next_node != LDNS_RBTREE_NULL &&
1019 next_node->data &&
1020 ((ldns_dnssec_name *)next_node->data)->is_glue
1021 ) {
1022 next_node = ldns_rbtree_next(next_node);
1023 }
1024
1025 if (next_node == LDNS_RBTREE_NULL) {
1026 next_node = ldns_rbtree_first(zone->names);
1027 }
1028 if (! cur_node->data || ! next_node->data) {
1029 return LDNS_STATUS_ERR;
1030 }
1031 cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
1032 next_name = ((ldns_dnssec_name *)next_node->data)->name;
1033 cur_label_count = ldns_dname_label_count(cur_name);
1034 next_label_count = ldns_dname_label_count(next_name);
1035
1036 /* Since the names are in canonical order, we can
1037 * recognize empty non-terminals by their labels;
1038 * every label after the first one on the next owner
1039 * name is a non-terminal if it either does not exist
1040 * in the current name or is different from the same
1041 * label in the current name (counting from the end)
1042 */
1043 for (i = 1; i < next_label_count - soa_label_count; i++) {
1044 lpos = (int)cur_label_count - (int)next_label_count + (int)i;
1045 if (lpos >= 0) {
1046 l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
1047 } else {
1048 l1 = NULL;
1049 }
1050 l2 = ldns_dname_clone_from(next_name, i);
1051
1052 if (!l1 || ldns_dname_compare(l1, l2) != 0) {
1053 /* We have an empty nonterminal, add it to the
1054 * tree
1055 */
1056 new_name = ldns_dnssec_name_new();
1057 if (!new_name) {
1058 return LDNS_STATUS_MEM_ERR;
1059 }
1060 new_name->name = ldns_dname_clone_from(next_name,
1061 i);
1062 if (!new_name->name) {
1063 ldns_dnssec_name_free(new_name);
1064 return LDNS_STATUS_MEM_ERR;
1065 }
1066 new_name->name_alloced = true;
1067 new_node = LDNS_MALLOC(ldns_rbnode_t);
1068 if (!new_node) {
1069 ldns_dnssec_name_free(new_name);
1070 return LDNS_STATUS_MEM_ERR;
1071 }
1072 new_node->key = new_name->name;
1073 new_node->data = new_name;
1074 (void)ldns_rbtree_insert(zone->names, new_node);
1075 ldns_dnssec_name_make_hashed_name(
1076 zone, new_name, NULL);
1077 }
1078 ldns_rdf_deep_free(l1);
1079 ldns_rdf_deep_free(l2);
1080 }
1081
1082 /* we might have inserted a new node after
1083 * the current one so we can't just use next()
1084 */
1085 if (next_node != ldns_rbtree_first(zone->names)) {
1086 cur_node = next_node;
1087 } else {
1088 cur_node = LDNS_RBTREE_NULL;
1089 }
1090 }
1091 return LDNS_STATUS_OK;
1092 }
1093
1094 bool
1095 ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
1096 {
1097 ldns_rr* nsec3;
1098 ldns_rbnode_t* node;
1099
1100 if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) {
1101 node = ldns_rbtree_first(zone->names);
1102 while (node != LDNS_RBTREE_NULL) {
1103 nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
1104 if (nsec3 &&ldns_rr_get_type(nsec3)
1105 == LDNS_RR_TYPE_NSEC3 &&
1106 ldns_nsec3_optout(nsec3)) {
1107 return true;
1108 }
1109 node = ldns_rbtree_next(node);
1110 }
1111 }
1112 return false;
1113 }
LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
Definition: error.h:101
ldns_struct_dnssec_rrsets::rrs
ldns_dnssec_rrs * rrs
Definition: dnssec_zone.h:34
LDNS_STATUS_SYNTAX_INCLUDE
Definition: error.h:90
ldns_dnssec_rrs_deep_free
void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs)
Frees the list of rrs, and the individual ldns_rr records contained in the list.
Definition: dnssec_zone.c:41
ldns_zone_soa
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition: zone.c:17
ldns_rdf_deep_free
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
ldns_dnssec_zone_deep_free
void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition: dnssec_zone.c:764
ldns_dname_label_count
uint8_t ldns_dname_label_count(const ldns_rdf *r)
count the number of labels inside a LDNS_RDF_DNAME type rdf.
Definition: dname.c:214
ldns_rdf2rr_type
ldns_rr_type ldns_rdf2rr_type(const ldns_rdf *rd)
convert an rdf of type LDNS_RDF_TYPE_TYPE to an actual LDNS_RR_TYPE.
Definition: rr.c:2653
LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:173
ldns_dnssec_zone_new_frm_fp_l
ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: dnssec_zone.c:597
ldns_dnssec_rrsets_print_fmt
void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_rrsets *rrsets, bool follow)
Definition: dnssec_zone.c:302
ldns_dname_compare
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf&#39;s according to the algorithm for ordering in RFC4034 Section 6...
Definition: dname.c:356
ldns_rbtree_insert
ldns_rbnode_t * ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data)
Insert data into the tree.
Definition: rbtree.c:242
LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
Definition: error.h:82
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:64
ldns_rr_list_push_rr
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1096
ldns_struct_rr_list
List or Set of Resource Records.
Definition: rr.h:327
LDNS_STATUS_SYNTAX_TTL
Definition: error.h:88
ldns_struct_output_format
Output format specifier.
Definition: host2str.h:86
LDNS_STATUS_OK
Definition: error.h:26
ldns_struct_dnssec_name::name_alloced
signed char name_alloced
Usually, the name is a pointer to the owner name of the first rr for this name, but sometimes there i...
Definition: dnssec_zone.h:59
ldns_dnssec_name_is_glue
bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
Returns if dnssec_name structure is marked as glue.
Definition: dnssec_zone.c:403
ldns_struct_dnssec_name::rrsets
ldns_dnssec_rrsets * rrsets
The rrsets for this name.
Definition: dnssec_zone.h:63
ldns_zone_new_frm_fp_l
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: zone.c:195
LDNS_CALLOC
#define LDNS_CALLOC(type, count)
Definition: util.h:53
ldns_struct_zone
DNS Zone.
Definition: zone.h:42
ldns_rdf_clone
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
ldns_dnssec_zone_print_fmt
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:959
ldns_nsec3_hash_name_frm_nsec3
ldns_rdf * ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name)
Calculates the hashed name using the parameters of the given NSEC3 RR.
Definition: dnssec.c:1332
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:75
ldns_struct_dnssec_name
Definition: dnssec_zone.h:45
ldns_dnssec_name_set_nsec
void ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
Sets the NSEC(3) RR of the given dnssec_name structure.
Definition: dnssec_zone.c:422
ldns_struct_dnssec_zone
Structure containing a dnssec zone.
Definition: dnssec_zone.h:91
ldns_rr_list_free
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:975
ldns_dnssec_rrsets_type
ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
Returns the rr type of the rrset (that is head of the given list)
Definition: dnssec_zone.c:146
ldns_dnssec_rrsets_set_type
ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, ldns_rr_type type)
Sets the RR type of the rrset (that is head of the given list)
Definition: dnssec_zone.c:156
ldns_output_format_default
const ldns_output_format * ldns_output_format_default
The default output format record.
Definition: host2str.c:125
ldns_struct_rr
Resource Record.
Definition: rr.h:299
INLINE
#define INLINE
splint static inline workaround
Definition: util.h:42
ldns_rbnode_t::data
const void * data
pointer to data
Definition: rbtree.h:70
ldns_dnssec_name_add_rr
ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name, ldns_rr *rr)
Inserts the given rr at the right place in the current dnssec_name No checking is done whether the na...
Definition: dnssec_zone.c:448
ldns_struct_dnssec_zone::names
ldns_rbtree_t * names
tree of ldns_dnssec_names
Definition: dnssec_zone.h:95
ldns.h
Including this file will include all ldns files, and define some lookup tables.
LDNS_RR_TYPE_SOA
marks the start of a zone of authority
Definition: rr.h:93
ldns_dnssec_name_free
void ldns_dnssec_name_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:382
ldns_dnssec_name_set_name
void ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, ldns_rdf *dname)
Sets the domain name of the given dnssec_name structure.
Definition: dnssec_zone.c:412
ldns_dname_compare_v
int ldns_dname_compare_v(const void *a, const void *b)
Given in dnssec_zone.c, also used in dnssec_sign.c:w.
Definition: dnssec_zone.c:780
ldns_dname_clone_from
ldns_rdf * ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
Clones the given dname from the nth label on.
Definition: dname.c:160
ldns_rr_list_rr
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition: rr.c:954
ldns_rr_print_fmt
void ldns_rr_print_fmt(FILE *output, const ldns_output_format *fmt, const ldns_rr *rr)
Prints the data in the resource record to the given file stream (in presentation format) ...
Definition: host2str.c:2501
ldns_dnssec_zone_add_rr
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
Definition: dnssec_zone.c:880
ldns_dnssec_rrs_new
ldns_dnssec_rrs * ldns_dnssec_rrs_new(void)
Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs.
Definition: dnssec_zone.c:10
ldns_struct_dnssec_rrs::rr
ldns_rr * rr
Definition: dnssec_zone.h:24
ATTR_UNUSED
#define ATTR_UNUSED(x)
Definition: common.h:67
ldns_dnssec_zone_names_print_fmt
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_rbtree_t *tree, bool print_soa)
Definition: dnssec_zone.c:934
ldns_rbnode_t
The rbnode_t struct definition.
Definition: rbtree.h:60
ldns_dnssec_name_new
ldns_dnssec_name * ldns_dnssec_name_new(void)
Create a new data structure for a dnssec name.
Definition: dnssec_zone.c:317
ldns_dnssec_name_print_fmt
void ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_name *name)
Prints the RRs in the dnssec name structure to the given file descriptor.
Definition: dnssec_zone.c:555
ldns_rbtree_create
ldns_rbtree_t * ldns_rbtree_create(int(*cmpf)(const void *, const void *))
Create new tree (malloced) with given key compare function.
Definition: rbtree.c:80
ldns_struct_dnssec_rrsets::type
ldns_rr_type type
Definition: dnssec_zone.h:35
ldns_dnssec_zone_is_nsec3_optout
bool ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone *zone)
If a NSEC3PARAM is available in the apex, walks the zone and returns true on the first optout nsec3...
Definition: dnssec_zone.c:1095
ldns_struct_dnssec_name::is_glue
signed char is_glue
Unlike what the name is_glue suggests, this field is set to true by ldns_dnssec_zone_mark_glue() or l...
Definition: dnssec_zone.h:81
ldns_dnssec_rrs_print_fmt
void ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_rrs *rrs)
Prints the given rrs to the file descriptor.
Definition: dnssec_zone.c:80
ldns_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:964
ldns_struct_dnssec_rrsets::signatures
ldns_dnssec_rrs * signatures
Definition: dnssec_zone.h:36
ldns_struct_output_format::flags
int flags
Specification of how RR&#39;s should be formatted in text.
Definition: host2str.h:89
ldns_dnssec_rrsets_deep_free
void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
Frees the list of rrsets and their rrs, and the ldns_rr records in the sets.
Definition: dnssec_zone.c:140
ldns_nsec3_optout
bool ldns_nsec3_optout(const ldns_rr *nsec3_rr)
Returns true if the opt-out flag has been set in the given NSEC3 RR.
Definition: dnssec.c:1252
ldns_dnssec_rrsets_new
ldns_dnssec_rrsets * ldns_dnssec_rrsets_new(void)
Creates a new list (entry) of RRsets.
Definition: dnssec_zone.c:104
LDNS_RR_TYPE_NSEC
Definition: rr.h:174
ldns_rr_compare
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition: rr.c:1601
ldns_rbtree_search
ldns_rbnode_t * ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key)
Find key in tree.
Definition: rbtree.c:294
ldns_rbtree_t
definition for tree struct
Definition: rbtree.h:83
ldns_rdf_print
void ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
Prints the data in the rdata field to the given file stream (in presentation format) ...
Definition: host2str.c:2489
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:907
ldns_rr_rrsig_typecovered
ldns_rdf * ldns_rr_rrsig_typecovered(const ldns_rr *r)
returns the type covered of a LDNS_RR_TYPE_RRSIG rr
Definition: rr_functions.c:111
LDNS_STATUS_SYNTAX_ORIGIN
Definition: error.h:89
ldns_dnssec_zone_new_frm_fp
ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)))
Definition: dnssec_zone.c:728
ldns_struct_dnssec_zone::soa
ldns_dnssec_name * soa
points to the name containing the SOA RR
Definition: dnssec_zone.h:93
LDNS_RR_TYPE_NSEC3
Definition: rr.h:179
LDNS_STATUS_MEM_ERR
Definition: error.h:34
ldns_dnssec_rrs_print
void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
Prints the given rrs to the file descriptor.
Definition: dnssec_zone.c:97
ldns_status
enum ldns_enum_status ldns_status
Definition: error.h:131
ldns_struct_dnssec_rrs::next
ldns_dnssec_rrs * next
Definition: dnssec_zone.h:25
LDNS_MALLOC
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
ldns_dnssec_name_find_rrset
ldns_dnssec_rrsets * ldns_dnssec_name_find_rrset(ldns_dnssec_name *name, ldns_rr_type type)
Find the RRset with the given type in within this name structure.
Definition: dnssec_zone.c:492
ldns_struct_dnssec_name::hashed_name
ldns_rdf * hashed_name
pointer to store the hashed name (only used when in an NSEC3 zone
Definition: dnssec_zone.h:85
ldns_dnssec_name_print
void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
Prints the RRs in the dnssec name structure to the given file descriptor.
Definition: dnssec_zone.c:562
ldns_dnssec_zone_free
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition: dnssec_zone.c:749
ldns_dnssec_rrs_free
void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
Frees the list of rrs, but not the individual ldns_rr records contained in the list.
Definition: dnssec_zone.c:35
ldns_struct_dnssec_zone::_nsec3params
ldns_rr * _nsec3params
points to the first added NSEC3 rr whose parameters will be assumed for all subsequent NSEC3 rr&#39;s and...
Definition: dnssec_zone.h:102
ldns_rr_new_frm_fp_l
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
creates a new rr from a file containing a string.
Definition: rr.c:680
LDNS_STATUS_SYNTAX_EMPTY
Definition: error.h:91
ldns_dnssec_rrsets_print
void ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
Definition: dnssec_zone.c:310
LDNS_RBTREE_NULL
#define LDNS_RBTREE_NULL
The nullpointer, points to empty node.
Definition: rbtree.h:76
LDNS_RR_TYPE_NSEC3PARAM
Definition: rr.h:180
ldns_zone_rrs
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone&#39;s content.
Definition: zone.c:35
ldns_dnssec_name_new_frm_rr
ldns_dnssec_name * ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
Create a new data structure for a dnssec name for the given RR.
Definition: dnssec_zone.c:342
ldns_rbnode_t::key
const void * key
pointer to sorting key
Definition: rbtree.h:68
ldns_dnssec_zone_print
void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:987
ldns_dnssec_rrsets_add_rr
ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
Add an ldns_rr to the corresponding RRset in the given list of RRsets.
Definition: dnssec_zone.c:193
ldns_struct_rdf
Resource record data field.
Definition: rdata.h:166
ldns_dnssec_zone_new
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition: dnssec_zone.c:569
ldns_dnssec_rrsets_free
void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
Frees the list of rrsets and their rrs, but not the ldns_rr records in the sets.
Definition: dnssec_zone.c:134
ldns_struct_dnssec_rrsets::next
ldns_dnssec_rrsets * next
Definition: dnssec_zone.h:37
ldns_traverse_postorder
void ldns_traverse_postorder(ldns_rbtree_t *tree, void(*func)(ldns_rbnode_t *, void *), void *arg)
Call function for all elements in the redblack tree, such that leaf elements are called before parent...
Definition: rbtree.c:666
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:883
ldns_rr_list_rr_count
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr&#39;s in an rr_list.
Definition: rr.c:921
ldns_rr_type
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:236
LDNS_FREE
#define LDNS_FREE(ptr)
Definition: util.h:60
LDNS_COMMENT_LAYOUT
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
ldns_dnssec_name_deep_free
void ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:388
ldns_rbtree_first
ldns_rbnode_t * ldns_rbtree_first(ldns_rbtree_t *rbtree)
Returns first (smallest) node in the tree.
Definition: rbtree.c:548
ldns_dnssec_zone_names_print
void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
Definition: dnssec_zone.c:952
ldns_dname_label
ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME try and retrieve a specific label...
Definition: dname.c:556
ldns_dnssec_zone_find_rrset
ldns_dnssec_rrsets * ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone, ldns_rdf *dname, ldns_rr_type type)
Find the RRset with the given name and type in the zone.
Definition: dnssec_zone.c:508
ldns_zone_free
void ldns_zone_free(ldns_zone *zone)
Frees the allocated memory for the zone, and the rr_list structure in it.
Definition: zone.c:306
ldns_struct_dnssec_name::nsec_signatures
ldns_dnssec_rrs * nsec_signatures
signatures for the NSEC record
Definition: dnssec_zone.h:71
ldns_rbtree_next
ldns_rbnode_t * ldns_rbtree_next(ldns_rbnode_t *node)
Returns next larger node in the tree.
Definition: rbtree.c:574
ldns_struct_dnssec_zone::hashed_names
ldns_rbtree_t * hashed_names
tree of ldns_dnssec_names by nsec3 hashes (when applicible)
Definition: dnssec_zone.h:97
ldns_dnssec_name_name
ldns_rdf * ldns_dnssec_name_name(ldns_dnssec_name *name)
Returns the domain name of the given dnssec_name structure.
Definition: dnssec_zone.c:394
ldns_dnssec_zone_add_empty_nonterminals
ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
Adds explicit dnssec_name structures for the empty nonterminals in this zone.
Definition: dnssec_zone.c:993
ldns_dnssec_name_cmp
int ldns_dnssec_name_cmp(const void *a, const void *b)
Compares the domain names of the two arguments in their canonical ordening.
Definition: dnssec_zone.c:430
ldns_struct_dnssec_rrs
Definition: dnssec_zone.h:22
ldns_dnssec_rrs_add_rr
ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
Adds an RR to the list of RRs.
Definition: dnssec_zone.c:47
ldns_struct_dnssec_name::nsec
ldns_rr * nsec
NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
Definition: dnssec_zone.h:67
LDNS_STATUS_ERR
Definition: error.h:37
config.h
ldns_struct_dnssec_rrsets
Definition: dnssec_zone.h:32
ldns_struct_dnssec_name::name
ldns_rdf * name
pointer to a dname containing the name.
Definition: dnssec_zone.h:51