ldns  1.8.3
/build/ldns-60Szi3/ldns-1.8.3/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
11{
12 ldns_dnssec_rrs *new_rrs;
14 if(!new_rrs) return NULL;
15 new_rrs->rr = NULL;
16 new_rrs->next = NULL;
17 return new_rrs;
18}
19
20INLINE void
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
34void
39
40void
45
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
79void
81 const 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
96void
101
102
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
116INLINE void
118{
119 if (rrsets) {
120 if (rrsets->rrs) {
121 ldns_dnssec_rrs_free_internal(rrsets->rrs, deep);
122 }
123 if (rrsets->next) {
125 }
126 if (rrsets->signatures) {
128 }
129 LDNS_FREE(rrsets);
130 }
131}
132
133void
138
139void
144
147{
148 if (rrsets) {
149 return rrsets->type;
150 } else {
151 return 0;
152 }
153}
154
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
166static ldns_dnssec_rrsets *
167ldns_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;
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
194{
195 ldns_dnssec_rrsets *new_rrsets;
196 ldns_rr_type rr_type;
197 bool rrsig = false;
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;
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 {
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;
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 {
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
272static void
273ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
274 const 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 ||
285 )
286 ) {
287 ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
288 if (rrsets->signatures) {
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
301void
303 const ldns_dnssec_rrsets *rrsets,
304 bool follow)
305{
306 ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
307}
308
309void
310ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
311{
313 rrsets, follow);
314}
315
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 initializes 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
343{
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
355INLINE void
357 int deep)
358{
359 if (name) {
360 if (name->name_alloced) {
362 }
363 if (name->rrsets) {
365 }
366 if (name->nsec && deep) {
367 ldns_rr_free(name->nsec);
368 }
369 if (name->nsec_signatures) {
371 }
372 if (name->hashed_name) {
373 /* Hashed name is always allocated when signing,
374 * so always deep free
375 */
377 }
378 LDNS_FREE(name);
379 }
380}
381
382void
387
388void
393
394ldns_rdf *
396{
397 if (name) {
398 return name->name;
399 }
400 return NULL;
401}
402
403bool
405{
406 if (name) {
407 return name->is_glue;
408 }
409 return false;
410}
411
412void
414 ldns_rdf *dname)
415{
416 if (rrset && dname) {
417 rrset->name = dname;
418 }
419}
420
421
422void
424{
425 if (rrset && nsec) {
426 rrset->nsec = nsec;
427 }
428}
429
430int
431ldns_dnssec_name_cmp(const void *a, const void *b)
432{
435
436 if (na && nb) {
439 } else if (na) {
440 return 1;
441 } else if (nb) {
442 return -1;
443 } else {
444 return 0;
445 }
446}
447
450 ldns_rr *rr)
451{
453 ldns_rr_type rr_type;
454 ldns_rr_type typecovered = 0;
455
456 /* special handling for NSEC3 and NSECX covering RRSIGS */
457
458 if (!name || !rr) {
459 return LDNS_STATUS_ERR;
460 }
461
462 rr_type = ldns_rr_get_type(rr);
463
464 if (rr_type == LDNS_RR_TYPE_RRSIG) {
466 }
467
468 if (rr_type == LDNS_RR_TYPE_NSEC ||
469 rr_type == LDNS_RR_TYPE_NSEC3) {
470 /* XX check if is already set (and error?) */
471 name->nsec = rr;
472 } else if (typecovered == LDNS_RR_TYPE_NSEC ||
473 typecovered == LDNS_RR_TYPE_NSEC3) {
474 if (name->nsec_signatures) {
475 result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
476 } else {
478 name->nsec_signatures->rr = rr;
479 }
480 } else {
481 /* it's a 'normal' RR, add it to the right rrset */
482 if (name->rrsets) {
483 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
484 } else {
486 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
487 }
488 }
489 return result;
490}
491
494 ldns_rr_type type) {
495 ldns_dnssec_rrsets *result;
496
497 result = name->rrsets;
498 while (result) {
499 if (result->type == type) {
500 return result;
501 } else {
502 result = result->next;
503 }
504 }
505 return NULL;
506}
507
510 const ldns_rdf *dname,
511 ldns_rr_type type)
512{
513 ldns_rbnode_t *node;
514
515 if (!zone || !dname || !zone->names) {
516 return NULL;
517 }
518
519 node = ldns_rbtree_search(zone->names, dname);
520 if (node) {
522 type);
523 } else {
524 return NULL;
525 }
526}
527
528static void
529ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
530 const ldns_dnssec_name *name,
531 bool show_soa)
532{
533 if (name) {
534 if(name->rrsets) {
535 ldns_dnssec_rrsets_print_soa_fmt(out, fmt,
536 name->rrsets, true, show_soa);
537 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
538 fprintf(out, ";; Empty nonterminal: ");
539 ldns_rdf_print(out, name->name);
540 fprintf(out, "\n");
541 }
542 if(name->nsec) {
543 ldns_rr_print_fmt(out, fmt, name->nsec);
544 }
545 if (name->nsec_signatures) {
547 name->nsec_signatures);
548 }
549 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
550 fprintf(out, "; <void>\n");
551 }
552}
553
554
555void
557 const ldns_dnssec_name *name)
558{
559 ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
560}
561
562void
567
568
571{
573 if(!zone) return NULL;
574 zone->soa = NULL;
575 zone->names = NULL;
576 zone->hashed_names = NULL;
577 zone->_nsec3params = NULL;
578
579 return zone;
580}
581
582static bool
583rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
584{
587}
588
589/* When the zone is first read into an list and then inserted into an
590 * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next)
591 * to each other. Because ldns-verify-zone (the only program that uses this
592 * function) uses the rbtree mostly for sequential walking, this results
593 * in a speed increase (of 15% on linux) because we have less CPU-cache misses.
594 */
595#define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
596
597static ldns_status
598ldns_dnssec_zone_add_empty_nonterminals_nsec3(
599 ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s);
600
601static void
602ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) {
603 (void) arg;
605 LDNS_FREE(node);
606}
607
609 uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev,
610 int *line_nr, bool *explicit_ttl);
611
614 uint32_t default_ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
615{
616 ldns_rr* cur_rr;
617 size_t i;
618
619 ldns_rdf *my_origin = NULL;
620 ldns_rdf *my_prev = NULL;
621
623 /* NSEC3s may occur before the names they refer to. We must remember
624 them and add them to the name later on, after the name is read.
625 We track not yet matching NSEC3s*n the todo_nsec3s list */
626 ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
627 /* when reading NSEC3s, there is a chance that we encounter nsecs
628 for empty nonterminals, whose nonterminals we cannot derive yet
629 because the needed information is to be read later.
630
631 nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
632 hold the NSEC3s that still didn't have a matching name in the
633 zone tree, even after all names were read. They can only match
634 after the zone is equipped with all the empty non terminals. */
635 ldns_rbtree_t todo_nsec3_ents;
636 ldns_rbnode_t *new_node;
637 ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
638
639 ldns_status status;
640
641#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
642 ldns_zone* zone = NULL;
643#else
644 ldns_rr *prev_rr = NULL;
645 uint32_t my_ttl = default_ttl;
646 /* RFC 1035 Section 5.1, says 'Omitted class and TTL values are default
647 * to the last explicitly stated values.'
648 */
649 bool ttl_from_TTL = false;
650 bool explicit_ttl = false;
651#endif
652
653 ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
654
655#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
656 status = ldns_zone_new_frm_fp_l(&zone, fp, origin, default_ttl, c, line_nr);
657 if (status != LDNS_STATUS_OK)
658 goto error;
659#endif
660 if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
661 status = LDNS_STATUS_MEM_ERR;
662 goto error;
663 }
664 if (origin) {
665 if (!(my_origin = ldns_rdf_clone(origin))) {
666 status = LDNS_STATUS_MEM_ERR;
667 goto error;
668 }
669 if (!(my_prev = ldns_rdf_clone(origin))) {
670 status = LDNS_STATUS_MEM_ERR;
671 goto error;
672 }
673 }
674
675#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
676 if (ldns_zone_soa(zone)) {
677 status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
678 if (status != LDNS_STATUS_OK)
679 goto error;
680 }
681 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
682 cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
683 status = LDNS_STATUS_OK;
684#else
685 while (!feof(fp)) {
686 /* If ttl came from $TTL line, then it should be the default.
687 * (RFC 2308 Section 4)
688 * Otherwise it "defaults to the last explicitly stated value"
689 * (RFC 1035 Section 5.1)
690 */
691 if (ttl_from_TTL)
692 my_ttl = default_ttl;
693 status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
694 &my_prev, line_nr, &explicit_ttl);
695#endif
696 switch (status) {
697 case LDNS_STATUS_OK:
698#ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
699 if (explicit_ttl) {
700 if (!ttl_from_TTL) {
701 /* No $TTL, so ttl "defaults to the
702 * last explicitly stated value"
703 * (RFC 1035 Section 5.1)
704 */
705 my_ttl = ldns_rr_ttl(cur_rr);
706 }
707 /* When ttl is implicit, try to adhere to the rules as
708 * much as possible. (also for compatibility with bind)
709 * This was changed when fixing an issue with ZONEMD
710 * which hashes the TTL too.
711 */
712 } else if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SIG
713 || ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG) {
714 if (ldns_rr_rd_count(cur_rr) >= 4
716
717 /* SIG without explicit ttl get ttl
718 * from the original_ttl field
719 * (RFC 2535 Section 7.2)
720 *
721 * Similarly for RRSIG, but stated less
722 * specifically in the spec.
723 * (RFC 4034 Section 3)
724 */
725 ldns_rr_set_ttl(cur_rr,
727 ldns_rr_rdf(rr, 3)));
728
729 } else if (prev_rr
730 && ldns_rr_get_type(prev_rr) == ldns_rr_get_type(cur_rr)
732 , ldns_rr_owner(cur_rr)) == 0)
733
734 /* "TTLs of all RRs in an RRSet must be the same"
735 * (RFC 2881 Section 5.2)
736 */
737 ldns_rr_set_ttl(cur_rr, ldns_rr_ttl(prev_rr));
738
739 prev_rr = cur_rr;
740#endif
741 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
742 if (status ==
744
745 if (rr_is_rrsig_covering(cur_rr,
747 ldns_rr_list_push_rr(todo_nsec3_rrsigs,
748 cur_rr);
749 } else {
750 ldns_rr_list_push_rr(todo_nsec3s,
751 cur_rr);
752 }
753 status = LDNS_STATUS_OK;
754
755 } else if (status != LDNS_STATUS_OK)
756 goto error;
757
758 break;
759
760 case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/
761#ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP
762 default_ttl = my_ttl;
763 ttl_from_TTL = true;
764#endif
765 status = LDNS_STATUS_OK;
766 break;
767
768
769 case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */
770 case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/
771 status = LDNS_STATUS_OK;
772 break;
773
774 case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
776 break;
777
778 default:
779 goto error;
780 }
781 }
782
783 for (i = 0; status == LDNS_STATUS_OK &&
784 i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
785 cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
786 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
788 if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
789 status = LDNS_STATUS_MEM_ERR;
790 break;
791 }
792 new_node->key = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
793 new_node->data = cur_rr;
794 if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
795 LDNS_FREE(new_node);
796 status = LDNS_STATUS_MEM_ERR;
797 break;
798 }
799 status = LDNS_STATUS_OK;
800 }
801 }
802 if (todo_nsec3_ents.count > 0)
803 (void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
804 newzone, &todo_nsec3_ents);
805 for (i = 0; status == LDNS_STATUS_OK &&
806 i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
807 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
808 status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
809 }
810 if (z) {
811 *z = newzone;
812 newzone = NULL;
813 } else {
814 ldns_dnssec_zone_free(newzone);
815 newzone = NULL;
816 }
817
818error:
819#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
820 if (zone) {
821 ldns_zone_free(zone);
822 }
823#endif
824 ldns_rr_list_free(todo_nsec3_rrsigs);
825 ldns_traverse_postorder(&todo_nsec3_ents,
826 ldns_todo_nsec3_ents_node_free, NULL);
827 ldns_rr_list_free(todo_nsec3s);
828
829 if (my_origin) {
830 ldns_rdf_deep_free(my_origin);
831 }
832 if (my_prev) {
833 ldns_rdf_deep_free(my_prev);
834 }
835 if (newzone) {
836 ldns_dnssec_zone_free(newzone);
837 }
838 return status;
839}
840
843 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
844{
845 return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
846}
847
848static void
849ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
850 (void) arg;
852 LDNS_FREE(node);
853}
854
855static void
856ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
857 (void) arg;
859 LDNS_FREE(node);
860}
861
862static void
863ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
864 (void) arg;
865 LDNS_FREE(node);
866}
867
868void
870{
871 if (zone) {
872 if (zone->hashed_names) {
874 ldns_hashed_names_node_free, NULL);
875 LDNS_FREE(zone->hashed_names);
876 }
877 if (zone->names) {
878 /* destroy all name structures within the tree */
880 ldns_dnssec_name_node_free,
881 NULL);
882 LDNS_FREE(zone->names);
883 }
884 LDNS_FREE(zone);
885 }
886}
887
888void
890{
891 if (zone) {
892 if (zone->hashed_names) {
894 ldns_hashed_names_node_free, NULL);
895 LDNS_FREE(zone->hashed_names);
896 }
897 if (zone->names) {
898 /* destroy all name structures within the tree */
900 ldns_dnssec_name_node_deep_free,
901 NULL);
902 LDNS_FREE(zone->names);
903 }
904 LDNS_FREE(zone);
905 }
906}
907
908/* use for dname comparison in tree */
909int
910ldns_dname_compare_v(const void *a, const void *b) {
911 return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
912}
913
914static void
915ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
916 ldns_dnssec_name* name, ldns_rr* nsec3rr);
917
918static void
919ldns_dnssec_zone_hashed_names_from_nsec3(
920 ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
921{
922 ldns_rbnode_t* current_node;
923 ldns_dnssec_name* current_name;
924
925 assert(zone != NULL);
926 assert(nsec3rr != NULL);
927
928 if (zone->hashed_names) {
930 ldns_hashed_names_node_free, NULL);
931 LDNS_FREE(zone->hashed_names);
932 }
933 zone->_nsec3params = nsec3rr;
934
935 /* So this is a NSEC3 zone.
936 * Calculate hashes for all names already in the zone
937 */
939 if (zone->hashed_names == NULL) {
940 return;
941 }
942 for ( current_node = ldns_rbtree_first(zone->names)
943 ; current_node != LDNS_RBTREE_NULL
944 ; current_node = ldns_rbtree_next(current_node)
945 ) {
946 current_name = (ldns_dnssec_name *) current_node->data;
947 ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
948
949 }
950}
951
952static void
953ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
954 ldns_dnssec_name* name, ldns_rr* nsec3rr)
955{
956 ldns_rbnode_t* new_node;
957
958 assert(name != NULL);
959 if (! zone->_nsec3params) {
960 if (! nsec3rr) {
961 return;
962 }
963 ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
964
965 } else if (! nsec3rr) {
966 nsec3rr = zone->_nsec3params;
967 }
968 name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
969
970 /* Also store in zone->hashed_names */
971 if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
972
973 new_node->key = name->hashed_name;
974 new_node->data = name;
975
976 if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
977
978 LDNS_FREE(new_node);
979 }
980 }
981}
982
983
984static ldns_rbnode_t *
985ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
986 ldns_rdf *hashed_name;
987 ldns_rbnode_t *to_return;
988
989 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
990
991 ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
992 }
993 if (zone->hashed_names == NULL) {
994 return NULL;
995 }
996 hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
997 if (hashed_name == NULL) {
998 return NULL;
999 }
1000 to_return = ldns_rbtree_search(zone->hashed_names, hashed_name);
1001 ldns_rdf_deep_free(hashed_name);
1002 return to_return;
1003}
1004
1007{
1008 ldns_status result = LDNS_STATUS_OK;
1009 ldns_dnssec_name *cur_name;
1010 ldns_rbnode_t *cur_node;
1011 ldns_rr_type type_covered = 0;
1012
1013 if (!zone || !rr) {
1014 return LDNS_STATUS_ERR;
1015 }
1016
1017 if (!zone->names) {
1019 if(!zone->names) return LDNS_STATUS_MEM_ERR;
1020 }
1021
1022 /* we need the original of the hashed name if this is
1023 an NSEC3, or an RRSIG that covers an NSEC3 */
1025 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
1026 }
1028 type_covered == LDNS_RR_TYPE_NSEC3) {
1029 cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
1030 if (!cur_node) {
1032 }
1033 } else {
1034 cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
1035 }
1036 if (!cur_node) {
1037 /* add */
1038 cur_name = ldns_dnssec_name_new_frm_rr(rr);
1039 if(!cur_name) return LDNS_STATUS_MEM_ERR;
1040 cur_node = LDNS_MALLOC(ldns_rbnode_t);
1041 if(!cur_node) {
1042 ldns_dnssec_name_free(cur_name);
1043 return LDNS_STATUS_MEM_ERR;
1044 }
1045 cur_node->key = ldns_rr_owner(rr);
1046 cur_node->data = cur_name;
1047 (void)ldns_rbtree_insert(zone->names, cur_node);
1048 ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
1049 } else {
1050 cur_name = (ldns_dnssec_name *) cur_node->data;
1051 result = ldns_dnssec_name_add_rr(cur_name, rr);
1052 }
1054 zone->soa = cur_name;
1055 }
1056 return result;
1057}
1058
1059void
1061 const ldns_rbtree_t *tree,
1062 bool print_soa)
1063{
1064 ldns_rbnode_t *node;
1065 ldns_dnssec_name *name;
1066
1067 node = ldns_rbtree_first(tree);
1068 while (node != LDNS_RBTREE_NULL) {
1069 name = (ldns_dnssec_name *) node->data;
1070 ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
1071 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1072 fprintf(out, ";\n");
1073 node = ldns_rbtree_next(node);
1074 }
1075}
1076
1077void
1078ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
1079{
1081 tree, print_soa);
1082}
1083
1084void
1086 const ldns_dnssec_zone *zone)
1087{
1088 if (zone) {
1089 if (zone->soa) {
1090 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
1091 fprintf(out, ";; Zone: ");
1093 zone->soa));
1094 fprintf(out, "\n;\n");
1095 }
1098 zone->soa,
1100 false);
1101 if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1102 fprintf(out, ";\n");
1103 }
1104
1105 if (zone->names) {
1107 zone->names, false);
1108 }
1109 }
1110}
1111
1112void
1117
1118static ldns_status
1119ldns_dnssec_zone_add_empty_nonterminals_nsec3(
1120 ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
1121{
1122 ldns_dnssec_name *new_name;
1123 ldns_rdf *cur_name;
1124 ldns_rdf *next_name;
1125 ldns_rbnode_t *cur_node, *next_node, *new_node;
1126
1127 /* for the detection */
1128 uint16_t i, cur_label_count, next_label_count;
1129 uint16_t soa_label_count = 0;
1130 ldns_rdf *l1, *l2;
1131 int lpos;
1132
1133 if (!zone) {
1134 return LDNS_STATUS_ERR;
1135 }
1136 if (zone->soa && zone->soa->name) {
1137 soa_label_count = ldns_dname_label_count(zone->soa->name);
1138 }
1139
1140 cur_node = ldns_rbtree_first(zone->names);
1141 while (cur_node != LDNS_RBTREE_NULL) {
1142 next_node = ldns_rbtree_next(cur_node);
1143
1144 /* skip glue */
1145 while (next_node != LDNS_RBTREE_NULL &&
1146 next_node->data &&
1147 ((ldns_dnssec_name *)next_node->data)->is_glue
1148 ) {
1149 next_node = ldns_rbtree_next(next_node);
1150 }
1151
1152 if (next_node == LDNS_RBTREE_NULL) {
1153 next_node = ldns_rbtree_first(zone->names);
1154 }
1155 if (! cur_node->data || ! next_node->data) {
1156 return LDNS_STATUS_ERR;
1157 }
1158 cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
1159 next_name = ((ldns_dnssec_name *)next_node->data)->name;
1160 cur_label_count = ldns_dname_label_count(cur_name);
1161 next_label_count = ldns_dname_label_count(next_name);
1162
1163 /* Since the names are in canonical order, we can
1164 * recognize empty non-terminals by their labels;
1165 * every label after the first one on the next owner
1166 * name is a non-terminal if it either does not exist
1167 * in the current name or is different from the same
1168 * label in the current name (counting from the end)
1169 */
1170 for (i = 1; i < next_label_count - soa_label_count; i++) {
1171 lpos = (int)cur_label_count - (int)next_label_count + (int)i;
1172 if (lpos >= 0) {
1173 l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
1174 } else {
1175 l1 = NULL;
1176 }
1177 l2 = ldns_dname_clone_from(next_name, i);
1178
1179 if (!l1 || ldns_dname_compare(l1, l2) != 0) {
1180 /* We have an empty nonterminal, add it to the
1181 * tree
1182 */
1183 ldns_rbnode_t *node = NULL;
1184 ldns_rdf *ent_name;
1185
1186 if (!(ent_name = ldns_dname_clone_from(
1187 next_name, i))) {
1188
1191 return LDNS_STATUS_MEM_ERR;
1192 }
1193
1194 if (nsec3s && zone->_nsec3params) {
1195 ldns_rdf *ent_hashed_name;
1196
1197 if (!(ent_hashed_name =
1199 zone->_nsec3params,
1200 ent_name))) {
1203 ldns_rdf_deep_free(ent_name);
1204 return LDNS_STATUS_MEM_ERR;
1205 }
1206 node = ldns_rbtree_search(nsec3s,
1207 ent_hashed_name);
1208 ldns_rdf_deep_free(ent_hashed_name);
1209 if (!node) {
1212 ldns_rdf_deep_free(ent_name);
1213 continue;
1214 }
1215 }
1216 new_name = ldns_dnssec_name_new();
1217 if (!new_name) {
1220 ldns_rdf_deep_free(ent_name);
1221 return LDNS_STATUS_MEM_ERR;
1222 }
1223 new_name->name = ent_name;
1224 new_name->name_alloced = true;
1225 new_node = LDNS_MALLOC(ldns_rbnode_t);
1226 if (!new_node) {
1229 ldns_dnssec_name_free(new_name);
1230 return LDNS_STATUS_MEM_ERR;
1231 }
1232 new_node->key = new_name->name;
1233 new_node->data = new_name;
1234 (void)ldns_rbtree_insert(zone->names, new_node);
1235 ldns_dnssec_name_make_hashed_name(
1236 zone, new_name, NULL);
1237 if (node)
1238 (void) ldns_dnssec_zone_add_rr(zone,
1239 (ldns_rr *)node->data);
1240 }
1243 }
1244
1245 /* we might have inserted a new node after
1246 * the current one so we can't just use next()
1247 */
1248 if (next_node != ldns_rbtree_first(zone->names)) {
1249 cur_node = next_node;
1250 } else {
1251 cur_node = LDNS_RBTREE_NULL;
1252 }
1253 }
1254 return LDNS_STATUS_OK;
1255}
1256
1259{
1260 return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
1261}
1262
1263bool
1265{
1266 ldns_rr* nsec3;
1267 ldns_rbnode_t* node;
1268
1270 node = ldns_rbtree_first(zone->names);
1271 while (node != LDNS_RBTREE_NULL) {
1272 nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
1273 if (nsec3 &&ldns_rr_get_type(nsec3)
1274 == LDNS_RR_TYPE_NSEC3 &&
1275 ldns_nsec3_optout(nsec3)) {
1276 return true;
1277 }
1278 node = ldns_rbtree_next(node);
1279 }
1280 }
1281 return false;
1282}
1283
1284/*
1285 * Stuff for calculating and verifying zone digests
1286 */
1296
1310
1311INLINE void
1313{
1314 /* Make sure the i->name is "in zone" (i.e. below the apex) */
1315 if (i->apex_name) {
1316 ldns_rdf *name = (ldns_rdf *)i->node->key;
1317
1318 while (i->name && name != i->apex_name /* not apex */
1319
1320 && ( ldns_dname_label_count(name) != i->apex_labs
1321 || ldns_dname_compare(name, i->apex_name)) /* not apex */
1322
1323 && !ldns_dname_is_subdomain(name, i->apex_name) /* no sub */) {
1324
1325 /* next name */
1326 i->node = ldns_rbtree_next(i->node);
1327 if (i->node == LDNS_RBTREE_NULL)
1328 i->name = NULL;
1329 else {
1330 i->name = (ldns_dnssec_name *)i->node->data;
1331 name = (ldns_rdf *)i->node->key;
1332 }
1333 }
1334 }
1335 /* determine state */
1336 if (!i->name) {
1337 if (!i->nsec3_name)
1339 else {
1342 }
1343 } else if (!i->nsec3_name) {
1344 i->rrsets = i->name->rrsets;
1346
1348 , (ldns_rdf *)i->node->key) < 0) {
1351 } else {
1352 i->rrsets = i->name->rrsets;
1354 }
1355}
1356
1398static ldns_rr *
1399dnssec_zone_rr_iter_next(dnssec_zone_rr_iter *i)
1400{
1401 ldns_rr *nsec3;
1402
1403 for (;;) {
1404 if (i->rrs) {
1405 ldns_rr *rr = i->rrs->rr;
1406 i->rrs = i->rrs->next;
1407 return rr;
1408 }
1409 switch (i->state) {
1411 if (i->rrsets
1412 && i->rrsets->type < LDNS_RR_TYPE_RRSIG) {
1413
1414 i->rrs = i->rrsets->rrs;
1415 i->rrsets = i->rrsets->next;
1416 break;
1417 }
1418 i->rrsets4rrsigs = i->name->rrsets;
1419 if (i->name->nsec && ldns_rr_get_type(i->name->nsec)
1420 == LDNS_RR_TYPE_NSEC) {
1421
1423 break;
1424 }
1426 /* fallthrough */
1427
1429 if (i->rrsets4rrsigs) {
1430 i->rrs = i->rrsets4rrsigs->signatures;
1432 break;
1433 }
1435 /* fallthrough */
1436
1438 if (i->rrsets) {
1439 i->rrs = i->rrsets->rrs;
1440 i->rrsets = i->rrsets->next;
1441 break;
1442 }
1443 /* next name */
1444 i->node = ldns_rbtree_next(i->node);
1445 i->name = i->node == LDNS_RBTREE_NULL ? NULL
1446 : (ldns_dnssec_name *)i->node->data;
1447
1449 break;
1450
1452 if (i->rrsets4rrsigs
1454
1455 i->rrs = i->rrsets4rrsigs->signatures;
1457 break;
1458 }
1460 i->rrs = i->name->nsec_signatures;
1461 break;
1462
1464 if (i->rrsets4rrsigs) {
1465 i->rrs = i->rrsets4rrsigs->signatures;
1467 break;
1468 }
1470 return i->name->nsec;
1471
1473 nsec3 = i->nsec3_name->nsec;
1474
1475 /* next nsec3 */
1476 do {
1477 i->nsec3_node
1479 i->nsec3_name
1480 = i->nsec3_node == LDNS_RBTREE_NULL ? NULL
1482
1483 /* names for glue can be in the hashed_names
1484 * tree, but will not have a NSEC3
1485 */
1486 } while (i->nsec3_name && !i->nsec3_name->nsec);
1487
1489 return nsec3;
1490
1492 return NULL;
1493 }
1494 }
1495}
1496
1497static ldns_rr *
1498dnssec_zone_rr_iter_first(dnssec_zone_rr_iter *i, ldns_dnssec_zone *zone)
1499{
1500 if (!i || !zone)
1501 return NULL;
1502
1503 memset(i, 0, sizeof(*i));
1504 i->zone = zone;
1505 if (zone->soa && zone->soa->name) {
1506 i->apex_name = zone->soa->name;
1508 } else
1509 i->apex_name = NULL;
1510
1511
1512 i->node = ldns_rbtree_first(zone->names);
1513 i->name = i->node == LDNS_RBTREE_NULL ? NULL
1514 : (ldns_dnssec_name *)i->node->data;
1515
1516 if (zone->hashed_names) {
1517 do {
1519 i->nsec3_name = i->nsec3_node == LDNS_RBTREE_NULL ?NULL
1521 } while (i->nsec3_name && !i->nsec3_name->nsec);
1522 }
1524 return dnssec_zone_rr_iter_next(i);
1525}
1526
1533
1541
1551
1553{ return zd && (zd->simple_sha384 || zd->simple_sha512); }
1554
1556{ memset(zd, 0, sizeof(*zd)); }
1557
1558static ldns_status
1559zone_digester_add(zone_digester *zd, zonemd_scheme scheme, zonemd_hash hash)
1560{
1561 if (!zd)
1562 return LDNS_STATUS_NULL;
1563
1564 switch (scheme) {
1566 switch (hash) {
1567 case ZONEMD_HASH_SHA384:
1568 if (zd->double_sha384)
1570
1571 else if (zd->simple_sha384) {
1572 zd->simple_sha384 = 0;
1573 zd->double_sha384 = 1;
1575 }
1577 zd->simple_sha384 = 1;
1578 break;
1579
1580 case ZONEMD_HASH_SHA512:
1581 if (zd->double_sha512)
1583
1584 else if (zd->simple_sha512) {
1585 zd->simple_sha512 = 0;
1586 zd->double_sha512 = 1;
1588 }
1590 zd->simple_sha512 = 1;
1591 break;
1592 default:
1594 }
1595 break;
1596 default:
1598 }
1599 return LDNS_STATUS_OK;
1600}
1601
1602static ldns_status
1603zone_digester_update(zone_digester *zd, ldns_rr *rr)
1604{
1605 uint8_t data[65536];
1606 ldns_buffer buf;
1607 ldns_status st;
1608
1609 buf._data = data;
1610 buf._position = 0;
1611 buf._limit = sizeof(data);
1612 buf._capacity = sizeof(data);
1613 buf._fixed = 1;
1614 buf._status = LDNS_STATUS_OK;
1615
1617 return st;
1618
1619 if (zd->simple_sha384)
1620 ldns_sha384_update(&zd->sha384_CTX, data, buf._position);
1621
1622 if (zd->simple_sha512)
1623 ldns_sha512_update(&zd->sha512_CTX, data, buf._position);
1624
1625 return LDNS_STATUS_OK;
1626}
1627
1630{
1631 ldns_rr *rr = NULL;
1632 uint8_t *data = NULL;
1633 ldns_rdf *rdf;
1634 size_t md_len = hash == ZONEMD_HASH_SHA384
1637
1639 return NULL;
1640
1641 if (!(rdf = ldns_rdf_clone(ldns_rr_owner(soa))))
1642 goto error;
1643
1644 ldns_rr_set_owner(rr, rdf);
1646 ldns_rr_set_ttl(rr, ldns_rr_ttl(soa));
1647
1648 if (!(rdf = ldns_rdf_clone(ldns_rr_rdf(soa, 2))))
1649 goto error;
1650 ldns_rr_set_rdf(rr, rdf, 0);
1651
1653 goto error;
1654 ldns_rr_set_rdf(rr, rdf, 1);
1655
1656 if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, hash)))
1657 goto error;
1658 ldns_rr_set_rdf(rr, rdf, 2);
1659
1660 if (!(data = LDNS_XMALLOC(uint8_t, md_len)))
1661 goto error;
1662
1663 if (!(rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, md_len, data)))
1664 goto error;
1665 ldns_rr_set_rdf(rr, rdf, 3);
1666
1667 return rr;
1668error:
1669 if (data)
1670 LDNS_FREE(data);
1671 ldns_rr_free(rr);
1672 return NULL;
1673}
1674
1675static ldns_rr_list *
1676zone_digester_export(
1677 zone_digester *zd, ldns_rr *soa, ldns_status *ret_st)
1678{
1680 ldns_rr_list *rr_list = NULL;
1681 ldns_rr *sha384 = NULL;
1682 ldns_rr *sha512 = NULL;
1683
1684 if (!zd || !soa)
1685 st = LDNS_STATUS_NULL;
1686
1687 else if (ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA
1688 || ldns_rr_rd_count(soa) < 3)
1690
1691 else if (!(rr_list = ldns_rr_list_new()))
1693
1694 else if (zd->simple_sha384
1695 && !(sha384 = new_zonemd(soa, ZONEMD_HASH_SHA384)))
1697
1698 else if (zd->simple_sha512
1699 && !(sha512 = new_zonemd(soa, ZONEMD_HASH_SHA512)))
1701
1702 else if (zd->simple_sha384
1703 && !ldns_rr_list_push_rr(rr_list, sha384))
1705
1706 else if (zd->simple_sha512
1707 && !ldns_rr_list_push_rr(rr_list, sha512)) {
1708 if (zd->simple_sha384)
1709 sha384 = NULL; /* deleted by ldns_rr_list_deep_free */
1711
1712 } else {
1713 if (sha384)
1715 , &zd->sha384_CTX);
1716 if (sha512)
1718 , &zd->sha512_CTX);
1719 return rr_list;
1720 }
1721 if (ret_st)
1722 *ret_st = st;
1723 if (sha384)
1724 ldns_rr_free(sha384);
1725 if (sha512)
1726 ldns_rr_free(sha512);
1727 if (rr_list)
1728 ldns_rr_list_deep_free(rr_list);
1729 return NULL;
1730}
1731
1732static ldns_status
1733ldns_digest_zone(ldns_dnssec_zone *zone, zone_digester *zd)
1734{
1736 dnssec_zone_rr_iter rr_iter;
1737 ldns_rr *rr;
1738 ldns_rdf *apex_name; /* name of zone apex */
1739
1740 if (!zone || !zd || !zone->soa || !zone->soa->name)
1741 return LDNS_STATUS_NULL;
1742
1743 apex_name = zone->soa->name;
1744 for ( rr = dnssec_zone_rr_iter_first(&rr_iter, zone)
1745 ; rr && !st
1746 ; rr = dnssec_zone_rr_iter_next(&rr_iter)) {
1747 /* Skip apex ZONEMD RRs */
1749 && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
1750 continue;
1751 /* Skip RRSIGs for apex ZONEMD RRs */
1755 && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
1756 continue;
1757 st = zone_digester_update(zd, rr);
1758 }
1759 return st;
1760}
1761
1764{
1765 ldns_dnssec_rrsets *zonemd, *soa;
1766 zone_digester zd;
1767 ldns_dnssec_rrs *rrs;
1768 ldns_rr *soa_rr;
1769 ldns_status st;
1772 size_t valid_zonemds;
1773
1774 if (!zone)
1775 return LDNS_STATUS_NULL;
1776
1778 zone, zone->soa->name, LDNS_RR_TYPE_ZONEMD);
1779 if (!zonemd) {
1780 ldns_rbnode_t *nsec3_node;
1781
1782 /* we need proof of non-existence for ZONEMD at the apex */
1783 if (zone->soa->nsec) {
1785 zone->soa->nsec),
1787 return LDNS_STATUS_NO_ZONEMD;
1788
1789 } else if (!zone->soa->hashed_name || !zone->hashed_names)
1790 return LDNS_STATUS_NO_ZONEMD;
1791
1792 else if (LDNS_RBTREE_NULL ==
1793 (nsec3_node = ldns_rbtree_search( zone->hashed_names
1794 , zone->soa->hashed_name)))
1795 return LDNS_STATUS_NO_ZONEMD;
1796 else {
1797 ldns_dnssec_name *nsec3
1798 = (ldns_dnssec_name *)nsec3_node->data;
1800 nsec3->nsec),
1802 return LDNS_STATUS_NO_ZONEMD;
1803 }
1804 /* ZONEMD at apex does really not exist */
1805 return LDNS_STATUS_OK;
1806 }
1808 zone, zone->soa->name, LDNS_RR_TYPE_SOA);
1809 if (!soa || !soa->rrs || !soa->rrs->rr)
1811
1812 soa_rr = soa->rrs->rr;
1813 if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
1814 || ldns_rr_rd_count(soa_rr) < 3)
1816
1817 zone_digester_init(&zd);
1818 for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
1819 if (!rrs->rr
1821 || ldns_rr_rd_count(rrs->rr) < 4)
1822 continue;
1823
1824 /* serial should match SOA's serial */
1825 if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
1827 continue;
1828
1829 /* Add (scheme, hash) to digester */
1830 zone_digester_add(&zd,
1833 }
1834 if (!zone_digester_set(&zd))
1836
1837 if ((st = ldns_digest_zone(zone, &zd)))
1838 return st;
1839
1840 if (zd.simple_sha384)
1842 if (zd.simple_sha512)
1844
1845 valid_zonemds = 0;
1846 for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
1847 if (!rrs->rr
1849 || ldns_rr_rd_count(rrs->rr) < 4)
1850 continue;
1851
1852 /* serial should match SOA's serial */
1853 if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
1855 continue;
1856
1859 continue;
1860
1864 == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
1865 && memcmp( simple_sha384
1866 , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
1868
1869 valid_zonemds += 1;
1870
1874 == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
1875 && memcmp( simple_sha512
1876 , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
1878
1879 valid_zonemds += 1;
1880 }
1881 return valid_zonemds ? LDNS_STATUS_OK : LDNS_STATUS_NO_VALID_ZONEMD;
1882}
1883
1884#ifdef HAVE_SSL
1885static ldns_status
1886rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs,
1887 ldns_rr_list *new_rrs)
1888{
1889 ldns_rr *rr = NULL;
1890
1891 if (!rr_list || !rrs)
1892 return LDNS_STATUS_NULL;
1893
1894 if (ldns_rr_list_rr_count(rr_list) == 0)
1895 return LDNS_STATUS_OK;
1896
1897 if (!*rrs) {
1898 if (!(*rrs = ldns_dnssec_rrs_new()))
1899 return LDNS_STATUS_MEM_ERR;
1900 (*rrs)->rr = ldns_rr_list_pop_rr(rr_list);
1901 if (new_rrs)
1902 ldns_rr_list_push_rr(new_rrs, (*rrs)->rr);
1903 }
1904 while ((rr = ldns_rr_list_pop_rr(rr_list))) {
1905 ldns_status st;
1906
1907 if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) {
1908 ldns_rr_list_push_rr(rr_list, rr);
1909 return st;
1910 } else if (new_rrs)
1911 ldns_rr_list_push_rr(new_rrs, rr);
1912 }
1913 return LDNS_STATUS_OK;
1914}
1915
1916
1919 ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
1920{
1922 zone_digester zd;
1923 ldns_rr_list *zonemd_rr_list = NULL;
1924 ldns_rr_list *zonemd_rrsigs = NULL;
1925 ldns_dnssec_rrsets *soa_rrset;
1926 ldns_rr *soa_rr = NULL;
1927 ldns_dnssec_rrsets **rrset_ref;
1928 ldns_dnssec_rrsets *zonemd_rrset;
1929
1930 zone_digester_init(&zd);
1932 zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
1934
1936 zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
1938
1939 if ((st = ldns_digest_zone(zone, &zd)))
1940 return st;
1941
1942 soa_rrset = ldns_dnssec_zone_find_rrset(
1943 zone, zone->soa->name, LDNS_RR_TYPE_SOA);
1944 if (!soa_rrset || !soa_rrset->rrs || !soa_rrset->rrs->rr)
1946 soa_rr = soa_rrset->rrs->rr;
1947
1948 if (!(zonemd_rr_list = zone_digester_export(&zd, soa_rr, &st)))
1949 return st;
1950
1951 /* - replace or add ZONEMD rrset */
1952 rrset_ref = &zone->soa->rrsets; /* scan rrsets at apex */
1953 while (*rrset_ref && (*rrset_ref)->type < LDNS_RR_TYPE_ZONEMD)
1954 rrset_ref = &(*rrset_ref)->next;
1955 if (*rrset_ref && (*rrset_ref)->type == LDNS_RR_TYPE_ZONEMD) {
1956 /* reuse zonemd rrset */
1957 zonemd_rrset = *rrset_ref;
1958 ldns_dnssec_rrs_free(zonemd_rrset->rrs);
1959 zonemd_rrset->rrs = NULL;
1960 ldns_dnssec_rrs_free(zonemd_rrset->signatures);
1961 zonemd_rrset->signatures = NULL;
1962 } else {
1963 /* insert zonemd rrset */
1964 zonemd_rrset = ldns_dnssec_rrsets_new();
1965 if (!zonemd_rrset) {
1966 ldns_rr_list_deep_free(zonemd_rr_list);
1967 return LDNS_STATUS_MEM_ERR;
1968 }
1969 zonemd_rrset->type = LDNS_RR_TYPE_ZONEMD;
1970 zonemd_rrset->next = *rrset_ref;
1971 *rrset_ref = zonemd_rrset;
1972 }
1973 if ((zonemd_rrsigs = ldns_sign_public(zonemd_rr_list, key_list)))
1974 st = rr_list2dnssec_rrs( zonemd_rrsigs
1975 , &zonemd_rrset->signatures, new_rrs);
1976 if (!st)
1977 st = rr_list2dnssec_rrs( zonemd_rr_list
1978 , &zonemd_rrset->rrs, new_rrs);
1979 ldns_rr_list_deep_free(zonemd_rr_list);
1980 ldns_rr_list_deep_free(zonemd_rrsigs);
1981 return st;
1982}
1983
1984#endif /* HAVE_SSL */
1985
#define ATTR_UNUSED(x)
Definition common.h:72
signed char ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
test whether the name sub falls under parent (i.e.
Definition dname.c:296
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6.
Definition dname.c:359
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_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:560
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
signed char ldns_nsec_bitmap_covers_type(const ldns_rdf *bitmap, ldns_rr_type type)
Check if RR type t is enumerated and set in the RR type bitmap rdf.
Definition dnssec.c:1393
ldns_rdf * ldns_nsec_get_bitmap(const ldns_rr *nsec)
Returns the rdata field that contains the bitmap of the covered types of the given NSEC record.
Definition dnssec.c:89
ldns_rdf * ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, const ldns_rdf *name)
Calculates the hashed name using the parameters of the given NSEC3 RR.
Definition dnssec.c:1368
signed char 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:1286
ldns_rr_list * ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
Sign an rrset.
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384
Definition dnssec_sign.h:18
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512
Definition dnssec_sign.h:19
INLINE void zone_digester_init(zone_digester *zd)
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.
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
ldns_status _ldns_rr_new_frm_fp_l_internal(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr, bool *explicit_ttl)
Definition rr.c:725
ldns_status ldns_dnssec_zone_verify_zonemd(ldns_dnssec_zone *zone)
enum_zonemd_scheme
@ ZONEMD_SCHEME_SIMPLE
@ ZONEMD_SCHEME_FIRST
@ ZONEMD_SCHEME_LAST
INLINE ldns_rr * new_zonemd(ldns_rr *soa, zonemd_hash hash)
void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrsets *rrsets, bool follow)
ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
INLINE void ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep)
void ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
Sets the NSEC(3) RR of the given dnssec_name structure.
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_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
ldns_rdf * ldns_dnssec_name_name(const ldns_dnssec_name *name)
Returns the domain name of the given dnssec_name structure.
void ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, ldns_rdf *dname)
Sets the domain name of the given dnssec_name structure.
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_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_dnssec_rrsets * ldns_dnssec_zone_find_rrset(const ldns_dnssec_zone *zone, const ldns_rdf *dname, ldns_rr_type type)
Find the RRset with the given name and type in the zone.
ldns_status dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
void ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
void ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
bool ldns_dnssec_name_is_glue(const ldns_dnssec_name *name)
Returns if dnssec_name structure is marked as glue.
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.
void ldns_dnssec_name_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_rbtree_t *tree, bool print_soa)
ldns_dnssec_rrsets * ldns_dnssec_name_find_rrset(const ldns_dnssec_name *name, ldns_rr_type type)
Find the RRset with the given type in within this name structure.
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...
void ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrs *rrs)
Prints the given rrs to the file descriptor.
Definition dnssec_zone.c:80
bool ldns_dnssec_zone_is_nsec3_optout(const ldns_dnssec_zone *zone)
If a NSEC3PARAM is available in the apex, walks the zone and returns true on the first optout nsec3.
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
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.
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_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
Adds explicit dnssec_name structures for the empty nonterminals in this zone.
ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t default_ttl, ldns_rr_class ATTR_UNUSED(c), int *line_nr)
INLINE bool zone_digester_set(zone_digester *zd)
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...
void ldns_dnssec_rrs_print(FILE *out, const ldns_dnssec_rrs *rrs)
Prints the given rrs to the file descriptor.
Definition dnssec_zone.c:97
enum enum_zonemd_hash zonemd_hash
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.
void ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_name *name)
Prints the RRs in the dnssec name structure to the given file descriptor.
INLINE void dnssec_zone_rr_iter_set_state_for_next_name(dnssec_zone_rr_iter *i)
enum_zonemd_hash
@ ZONEMD_HASH_SHA512
@ ZONEMD_HASH_LAST
@ ZONEMD_HASH_SHA384
@ ZONEMD_HASH_FIRST
enum enum_zonemd_scheme zonemd_scheme
INLINE void ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep)
Definition dnssec_zone.c:21
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...
void ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
void ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
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)
INLINE void ldns_dnssec_name_free_internal(ldns_dnssec_name *name, int deep)
void ldns_dnssec_name_print(FILE *out, const ldns_dnssec_name *name)
Prints the RRs in the dnssec name structure to the given file descriptor.
ldns_dnssec_rrsets * ldns_dnssec_rrsets_new(void)
Creates a new list (entry) of RRsets.
int ldns_dname_compare_v(const void *a, const void *b)
Given in dnssec_zone.c, also used in dnssec_sign.c:w.
int ldns_dnssec_name_cmp(const void *a, const void *b)
Compares the domain names of the two arguments in their canonical ordering.
dnssec_zone_rr_iter_state
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC
@ DNSSEC_ZONE_RR_ITER_LT_RRSIG
@ DNSSEC_ZONE_RR_ITER_REST
@ DNSSEC_ZONE_RR_ITER_FINI
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST
@ DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
@ DNSSEC_ZONE_RR_ITER_NSEC3
ldns_rr_type ldns_dnssec_rrsets_type(const ldns_dnssec_rrsets *rrsets)
Returns the rr type of the rrset (that is head of the given list)
ldns_dnssec_name * ldns_dnssec_name_new(void)
Create a new data structure for a dnssec name.
@ LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
Definition error.h:101
@ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
Definition error.h:82
@ LDNS_STATUS_ZONEMD_UNKNOWN_SCHEME
Definition error.h:134
@ LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE
Definition error.h:133
@ LDNS_STATUS_NULL
Definition error.h:51
@ LDNS_STATUS_ERR
Definition error.h:37
@ LDNS_STATUS_MEM_ERR
Definition error.h:34
@ LDNS_STATUS_SYNTAX_TTL
Definition error.h:88
@ LDNS_STATUS_NO_ZONEMD
Definition error.h:137
@ LDNS_STATUS_ZONEMD_UNKNOWN_HASH
Definition error.h:135
@ LDNS_STATUS_OK
Definition error.h:26
@ LDNS_STATUS_SYNTAX_EMPTY
Definition error.h:91
@ LDNS_STATUS_ZONEMD_INVALID_SOA
Definition error.h:136
@ LDNS_STATUS_NO_VALID_ZONEMD
Definition error.h:138
@ LDNS_STATUS_SYNTAX_INCLUDE
Definition error.h:90
@ LDNS_STATUS_SYNTAX_ORIGIN
Definition error.h:89
enum ldns_enum_status ldns_status
Definition error.h:146
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:3386
const ldns_output_format * ldns_output_format_default
The default output format record.
Definition host2str.c:142
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:3398
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition host2str.h:62
ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *output, const ldns_rr *rr, int section)
Copies the rr data to the buffer in wire format, in canonical format according to RFC3597 (every dnam...
Definition host2wire.c:171
Including this file will include all ldns files, and define some lookup tables.
@ LDNS_SECTION_ANSWER
Definition packet.h:279
ldns_rbnode_t * ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key)
Find key in tree.
Definition rbtree.c:294
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_rbnode_t * ldns_rbtree_first(const ldns_rbtree_t *rbtree)
Returns first (smallest) node in the tree.
Definition rbtree.c:548
ldns_rbnode_t * ldns_rbtree_next(ldns_rbnode_t *rbtree)
Returns next larger node in the tree.
Definition rbtree.c:574
ldns_rbnode_t * ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data)
Insert data into the tree.
Definition rbtree.c:242
#define LDNS_RBTREE_NULL
The nullpointer, points to empty node.
Definition rbtree.h:76
void ldns_rbtree_init(ldns_rbtree_t *rbtree, int(*cmpf)(const void *, const void *))
Init a new tree (malloced by caller) with given key compare function.
Definition rbtree.c:97
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
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
Definition rdata.c:38
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition rdata.c:222
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition rdata.c:31
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition rdata.c:230
uint32_t ldns_rdf2native_int32(const ldns_rdf *rd)
returns the native uint32_t representation from the rdf.
Definition rdata.c:98
ldns_rdf * ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
returns the rdf containing the native uint8_t repr.
Definition rdata.c:126
uint8_t ldns_rdf2native_int8(const ldns_rdf *rd)
returns the native uint8_t representation from the rdf.
Definition rdata.c:70
@ LDNS_RDF_TYPE_INT32
32 bits
Definition rdata.h:56
@ LDNS_RDF_TYPE_HEX
hex string
Definition rdata.h:70
@ LDNS_RDF_TYPE_INT8
8 bits
Definition rdata.h:52
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition rdata.c:24
ldns_rdf * ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
allocates a new rdf structure and fills it.
Definition rdata.c:179
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition rr.c:1011
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition rr.c:931
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:2750
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition rr.c:1020
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition rr.c:81
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
Definition rr.c:804
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition rr.c:1000
ldns_rr * ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
pops the last rr from an rrlist.
Definition rr.c:1177
enum ldns_enum_rr_type ldns_rr_type
Definition rr.h:243
ldns_rr * ldns_rr_new_frm_type(ldns_rr_type t)
creates a new rr structure, based on the given type.
Definition rr.c:48
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition rr.h:170
@ LDNS_RR_TYPE_ZONEMD
Definition rr.h:194
@ LDNS_RR_TYPE_SOA
marks the start of a zone of authority
Definition rr.h:90
@ LDNS_RR_TYPE_NSEC
Definition rr.h:171
@ LDNS_RR_TYPE_NSEC3PARAM
Definition rr.h:177
@ LDNS_RR_TYPE_SIG
2535typecode
Definition rr.h:126
@ LDNS_RR_TYPE_NSEC3
Definition rr.h:176
signed char ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition rr.c:1132
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition rr.c:937
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition rr.c:909
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition rr.c:957
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition rr.c:943
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition rr.c:816
ldns_rdf * ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position)
sets a rdf member, it will be set on the position given.
Definition rr.c:840
ldns_rr_class ldns_rr_get_class(const ldns_rr *rr)
returns the class of the rr.
Definition rr.c:949
enum ldns_enum_rr_class ldns_rr_class
Definition rr.h:61
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:990
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
sets the class in the rr.
Definition rr.c:834
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **rr, 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:796
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition rr.c:919
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition rr.c:1638
ldns_rdf * ldns_rr_rrsig_typecovered(const ldns_rr *r)
returns the type covered of a LDNS_RR_TYPE_RRSIG rr
void ldns_sha512_update(ldns_sha512_CTX *, const uint8_t *, size_t)
Definition sha2.c:815
void ldns_sha384_init(ldns_sha384_CTX *)
Definition sha2.c:948
void ldns_sha512_init(ldns_sha512_CTX *)
Definition sha2.c:634
#define LDNS_SHA512_DIGEST_LENGTH
Definition sha2.h:69
void ldns_sha512_final(uint8_t[64], ldns_sha512_CTX *)
#define LDNS_SHA384_DIGEST_LENGTH
Definition sha2.h:66
void ldns_sha384_update(ldns_sha384_CTX *, const uint8_t *, size_t)
Definition sha2.c:957
void ldns_sha384_final(uint8_t[48], ldns_sha384_CTX *)
ldns_dnssec_name * nsec3_name
dnssec_zone_rr_iter_state state
ldns_dnssec_name * name
ldns_dnssec_rrsets * rrsets4rrsigs
ldns_dnssec_zone * zone
ldns_rbnode_t * nsec3_node
ldns_rbnode_t * node
ldns_dnssec_rrs * rrs
ldns_dnssec_rrsets * rrsets
The rbnode_t struct definition.
Definition rbtree.h:60
const void * data
pointer to data
Definition rbtree.h:70
const void * key
pointer to sorting key
Definition rbtree.h:68
definition for tree struct
Definition rbtree.h:83
size_t count
The number of the nodes in the tree.
Definition rbtree.h:88
implementation of buffers to ease operations
Definition buffer.h:51
size_t _capacity
The amount of data the buffer can contain.
Definition buffer.h:59
unsigned _fixed
If the buffer is fixed it cannot be resized.
Definition buffer.h:65
size_t _position
The current position used for reading/writing.
Definition buffer.h:53
ldns_status _status
The current state of the buffer.
Definition buffer.h:70
uint8_t * _data
The data contained in the buffer.
Definition buffer.h:62
size_t _limit
The read/write limit.
Definition buffer.h:56
ldns_dnssec_rrs * nsec_signatures
signatures for the NSEC record
Definition dnssec_zone.h:71
ldns_rr * nsec
NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
Definition dnssec_zone.h:67
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_rdf * hashed_name
pointer to store the hashed name (only used when in an NSEC3 zone
Definition dnssec_zone.h:85
ldns_dnssec_rrsets * rrsets
The rrsets for this name.
Definition dnssec_zone.h:63
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_rdf * name
pointer to a dname containing the name.
Definition dnssec_zone.h:51
ldns_dnssec_rrs * next
Definition dnssec_zone.h:25
ldns_dnssec_rrs * rrs
Definition dnssec_zone.h:34
ldns_dnssec_rrs * signatures
Definition dnssec_zone.h:36
ldns_dnssec_rrsets * next
Definition dnssec_zone.h:37
Structure containing a dnssec zone.
Definition dnssec_zone.h:91
ldns_rbtree_t * hashed_names
tree of ldns_dnssec_names by nsec3 hashes (when applicable)
Definition dnssec_zone.h:97
ldns_rbtree_t * names
tree of ldns_dnssec_names
Definition dnssec_zone.h:95
ldns_rr * _nsec3params
points to the first added NSEC3 rr whose parameters will be assumed for all subsequent NSEC3 rr's and...
ldns_dnssec_name * soa
points to the name containing the SOA RR
Definition dnssec_zone.h:93
Same as rr_list, but now for keys.
Definition keys.h:173
Output format specifier.
Definition host2str.h:89
int flags
Specification of how RR's should be formatted in text.
Definition host2str.h:91
Resource record data field.
Definition rdata.h:197
List or Set of Resource Records.
Definition rr.h:338
Resource Record.
Definition rr.h:310
DNS Zone.
Definition zone.h:43
ldns_sha512_CTX sha512_CTX
ldns_sha384_CTX sha384_CTX
#define INLINE
splint static inline workaround
Definition util.h:42
#define LDNS_FREE(ptr)
Definition util.h:60
#define LDNS_CALLOC(type, count)
Definition util.h:53
#define LDNS_MALLOC(type)
Memory management macros.
Definition util.h:49
#define LDNS_XMALLOC(type, count)
Definition util.h:51
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition zone.c:17
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition zone.c:35
void ldns_zone_free(ldns_zone *zone)
Frees the allocated memory for the zone, and the rr_list structure in it.
Definition zone.c:369
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, int *line_nr)
Create a new zone from a file, keep track of the line numbering.