ldns  1.7.0
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;
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
36 {
37  ldns_dnssec_rrs_free_internal(rrs, 0);
38 }
39 
40 void
42 {
43  ldns_dnssec_rrs_free_internal(rrs, 1);
44 }
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 
79 void
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 
96 void
97 ldns_dnssec_rrs_print(FILE *out, const ldns_dnssec_rrs *rrs)
98 {
100 }
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 
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
135 {
136  ldns_dnssec_rrsets_free_internal(rrsets, 0);
137 }
138 
139 void
141 {
142  ldns_dnssec_rrsets_free_internal(rrsets, 1);
143 }
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 
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;
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;
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;
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  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) {
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
303  const 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, 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 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 
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 
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) {
375  }
376  }
377  LDNS_FREE(name);
378  }
379 }
380 
381 void
383 {
384  ldns_dnssec_name_free_internal(name, 0);
385 }
386 
387 void
389 {
390  ldns_dnssec_name_free_internal(name, 1);
391 }
392 
393 ldns_rdf *
395 {
396  if (name) {
397  return name->name;
398  }
399  return NULL;
400 }
401 
402 bool
404 {
405  if (name) {
406  return name->is_glue;
407  }
408  return false;
409 }
410 
411 void
413  ldns_rdf *dname)
414 {
415  if (rrset && dname) {
416  rrset->name = dname;
417  }
418 }
419 
420 
421 void
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 {
434 
435  if (na && nb) {
438  } else if (na) {
439  return 1;
440  } else if (nb) {
441  return -1;
442  } else {
443  return 0;
444  }
445 }
446 
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 {
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 
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 
509  const ldns_rdf *dname,
510  ldns_rr_type type)
511 {
512  ldns_rbnode_t *node;
513 
514  if (!zone || !dname || !zone->names) {
515  return NULL;
516  }
517 
518  node = ldns_rbtree_search(zone->names, dname);
519  if (node) {
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  const 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
556  const ldns_dnssec_name *name)
557 {
558  ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
559 }
560 
561 void
563 {
565 }
566 
567 
570 {
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 {
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 static ldns_status
597 ldns_dnssec_zone_add_empty_nonterminals_nsec3(
598  ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s);
599 
600 static void
601 ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) {
602  (void) arg;
603  ldns_rdf_deep_free((ldns_rdf *)node->key);
604  LDNS_FREE(node);
605 }
606 
609  uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
610 {
611  ldns_rr* cur_rr;
612  size_t i;
613 
614  ldns_rdf *my_origin = NULL;
615  ldns_rdf *my_prev = NULL;
616 
618  /* NSEC3s may occur before the names they refer to. We must remember
619  them and add them to the name later on, after the name is read.
620  We track not yet matching NSEC3s*n the todo_nsec3s list */
621  ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
622  /* when reading NSEC3s, there is a chance that we encounter nsecs
623  for empty nonterminals, whose nonterminals we cannot derive yet
624  because the needed information is to be read later.
625 
626  nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
627  hold the NSEC3s that still didn't have a matching name in the
628  zone tree, even after all names were read. They can only match
629  after the zone is equiped with all the empty non terminals. */
630  ldns_rbtree_t todo_nsec3_ents;
631  ldns_rbnode_t *new_node;
632  ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
633 
634  ldns_status status;
635 
636 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
637  ldns_zone* zone = NULL;
638 #else
639  uint32_t my_ttl = ttl;
640 #endif
641 
642  ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
643 
644 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
645  status = ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr);
646  if (status != LDNS_STATUS_OK)
647  goto error;
648 #endif
649  if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
650  status = LDNS_STATUS_MEM_ERR;
651  goto error;
652  }
653  if (origin) {
654  if (!(my_origin = ldns_rdf_clone(origin))) {
655  status = LDNS_STATUS_MEM_ERR;
656  goto error;
657  }
658  if (!(my_prev = ldns_rdf_clone(origin))) {
659  status = LDNS_STATUS_MEM_ERR;
660  goto error;
661  }
662  }
663 
664 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
665  if (ldns_zone_soa(zone)) {
666  status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
667  if (status != LDNS_STATUS_OK)
668  goto error;
669  }
670  for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
671  cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
672  status = LDNS_STATUS_OK;
673 #else
674  while (!feof(fp)) {
675  status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
676  &my_prev, line_nr);
677 
678 #endif
679  switch (status) {
680  case LDNS_STATUS_OK:
681 
682  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
683  if (status ==
685 
686  if (rr_is_rrsig_covering(cur_rr,
688  ldns_rr_list_push_rr(todo_nsec3_rrsigs,
689  cur_rr);
690  } else {
691  ldns_rr_list_push_rr(todo_nsec3s,
692  cur_rr);
693  }
694  status = LDNS_STATUS_OK;
695 
696  } else if (status != LDNS_STATUS_OK)
697  goto error;
698 
699  break;
700 
701 
702  case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */
703  case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/
704  case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/
705  status = LDNS_STATUS_OK;
706  break;
707 
708  case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
710  break;
711 
712  default:
713  goto error;
714  }
715  }
716 
717  for (i = 0; status == LDNS_STATUS_OK &&
718  i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
719  cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
720  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
722  if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
723  status = LDNS_STATUS_MEM_ERR;
724  break;
725  }
726  new_node->key = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
727  new_node->data = cur_rr;
728  if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
729  LDNS_FREE(new_node);
730  status = LDNS_STATUS_MEM_ERR;
731  break;
732  }
733  status = LDNS_STATUS_OK;
734  }
735  }
736  if (todo_nsec3_ents.count > 0)
737  (void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
738  newzone, &todo_nsec3_ents);
739  for (i = 0; status == LDNS_STATUS_OK &&
740  i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
741  cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
742  status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
743  }
744  if (z) {
745  *z = newzone;
746  newzone = NULL;
747  } else {
748  ldns_dnssec_zone_free(newzone);
749  }
750 
751 error:
752 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
753  if (zone) {
754  ldns_zone_free(zone);
755  }
756 #endif
757  ldns_rr_list_free(todo_nsec3_rrsigs);
758  ldns_traverse_postorder(&todo_nsec3_ents,
759  ldns_todo_nsec3_ents_node_free, NULL);
760  ldns_rr_list_free(todo_nsec3s);
761 
762  if (my_origin) {
763  ldns_rdf_deep_free(my_origin);
764  }
765  if (my_prev) {
766  ldns_rdf_deep_free(my_prev);
767  }
768  if (newzone) {
769  ldns_dnssec_zone_free(newzone);
770  }
771  return status;
772 }
773 
776  uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
777 {
778  return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
779 }
780 
781 static void
782 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
783  (void) arg;
785  LDNS_FREE(node);
786 }
787 
788 static void
789 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
790  (void) arg;
792  LDNS_FREE(node);
793 }
794 
795 void
797 {
798  if (zone) {
799  if (zone->names) {
800  /* destroy all name structures within the tree */
802  ldns_dnssec_name_node_free,
803  NULL);
804  LDNS_FREE(zone->names);
805  }
806  LDNS_FREE(zone);
807  }
808 }
809 
810 void
812 {
813  if (zone) {
814  if (zone->names) {
815  /* destroy all name structures within the tree */
817  ldns_dnssec_name_node_deep_free,
818  NULL);
819  LDNS_FREE(zone->names);
820  }
821  LDNS_FREE(zone);
822  }
823 }
824 
825 /* use for dname comparison in tree */
826 int
827 ldns_dname_compare_v(const void *a, const void *b) {
828  return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
829 }
830 
831 static void
832 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
833  ldns_dnssec_name* name, ldns_rr* nsec3rr);
834 
835 static void
836 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
837  (void) arg;
838  LDNS_FREE(node);
839 }
840 
841 static void
842 ldns_dnssec_zone_hashed_names_from_nsec3(
843  ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
844 {
845  ldns_rbnode_t* current_node;
846  ldns_dnssec_name* current_name;
847 
848  assert(zone != NULL);
849  assert(nsec3rr != NULL);
850 
851  if (zone->hashed_names) {
853  ldns_hashed_names_node_free, NULL);
854  LDNS_FREE(zone->hashed_names);
855  }
856  zone->_nsec3params = nsec3rr;
857 
858  /* So this is a NSEC3 zone.
859  * Calculate hashes for all names already in the zone
860  */
862  if (zone->hashed_names == NULL) {
863  return;
864  }
865  for ( current_node = ldns_rbtree_first(zone->names)
866  ; current_node != LDNS_RBTREE_NULL
867  ; current_node = ldns_rbtree_next(current_node)
868  ) {
869  current_name = (ldns_dnssec_name *) current_node->data;
870  ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
871 
872  }
873 }
874 
875 static void
876 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
877  ldns_dnssec_name* name, ldns_rr* nsec3rr)
878 {
879  ldns_rbnode_t* new_node;
880 
881  assert(name != NULL);
882  if (! zone->_nsec3params) {
883  if (! nsec3rr) {
884  return;
885  }
886  ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
887 
888  } else if (! nsec3rr) {
889  nsec3rr = zone->_nsec3params;
890  }
891  name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
892 
893  /* Also store in zone->hashed_names */
894  if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
895 
896  new_node->key = name->hashed_name;
897  new_node->data = name;
898 
899  if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
900 
901  LDNS_FREE(new_node);
902  }
903  }
904 }
905 
906 
907 static ldns_rbnode_t *
908 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
909  ldns_rdf *hashed_name;
910 
911  hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
912  if (hashed_name == NULL) {
913  return NULL;
914  }
915  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
916 
917  ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
918  }
919  if (zone->hashed_names == NULL) {
920  ldns_rdf_deep_free(hashed_name);
921  return NULL;
922  }
923  return ldns_rbtree_search(zone->hashed_names, hashed_name);
924 }
925 
928 {
929  ldns_status result = LDNS_STATUS_OK;
930  ldns_dnssec_name *cur_name;
931  ldns_rbnode_t *cur_node;
932  ldns_rr_type type_covered = 0;
933 
934  if (!zone || !rr) {
935  return LDNS_STATUS_ERR;
936  }
937 
938  if (!zone->names) {
940  if(!zone->names) return LDNS_STATUS_MEM_ERR;
941  }
942 
943  /* we need the original of the hashed name if this is
944  an NSEC3, or an RRSIG that covers an NSEC3 */
946  type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
947  }
949  type_covered == LDNS_RR_TYPE_NSEC3) {
950  cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
951  if (!cur_node) {
953  }
954  } else {
955  cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
956  }
957  if (!cur_node) {
958  /* add */
959  cur_name = ldns_dnssec_name_new_frm_rr(rr);
960  if(!cur_name) return LDNS_STATUS_MEM_ERR;
961  cur_node = LDNS_MALLOC(ldns_rbnode_t);
962  if(!cur_node) {
963  ldns_dnssec_name_free(cur_name);
964  return LDNS_STATUS_MEM_ERR;
965  }
966  cur_node->key = ldns_rr_owner(rr);
967  cur_node->data = cur_name;
968  (void)ldns_rbtree_insert(zone->names, cur_node);
969  ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
970  } else {
971  cur_name = (ldns_dnssec_name *) cur_node->data;
972  result = ldns_dnssec_name_add_rr(cur_name, rr);
973  }
974  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
975  zone->soa = cur_name;
976  }
977  return result;
978 }
979 
980 void
982  const ldns_rbtree_t *tree,
983  bool print_soa)
984 {
985  ldns_rbnode_t *node;
986  ldns_dnssec_name *name;
987 
988  node = ldns_rbtree_first(tree);
989  while (node != LDNS_RBTREE_NULL) {
990  name = (ldns_dnssec_name *) node->data;
991  ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
992  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
993  fprintf(out, ";\n");
994  node = ldns_rbtree_next(node);
995  }
996 }
997 
998 void
999 ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
1000 {
1002  tree, print_soa);
1003 }
1004 
1005 void
1007  const ldns_dnssec_zone *zone)
1008 {
1009  if (zone) {
1010  if (zone->soa) {
1011  if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
1012  fprintf(out, ";; Zone: ");
1014  zone->soa));
1015  fprintf(out, "\n;\n");
1016  }
1019  zone->soa,
1020  LDNS_RR_TYPE_SOA),
1021  false);
1022  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1023  fprintf(out, ";\n");
1024  }
1025 
1026  if (zone->names) {
1028  zone->names, false);
1029  }
1030  }
1031 }
1032 
1033 void
1035 {
1037 }
1038 
1039 static ldns_status
1040 ldns_dnssec_zone_add_empty_nonterminals_nsec3(
1041  ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
1042 {
1043  ldns_dnssec_name *new_name;
1044  ldns_rdf *cur_name;
1045  ldns_rdf *next_name;
1046  ldns_rbnode_t *cur_node, *next_node, *new_node;
1047 
1048  /* for the detection */
1049  uint16_t i, cur_label_count, next_label_count;
1050  uint16_t soa_label_count = 0;
1051  ldns_rdf *l1, *l2;
1052  int lpos;
1053 
1054  if (!zone) {
1055  return LDNS_STATUS_ERR;
1056  }
1057  if (zone->soa && zone->soa->name) {
1058  soa_label_count = ldns_dname_label_count(zone->soa->name);
1059  }
1060 
1061  cur_node = ldns_rbtree_first(zone->names);
1062  while (cur_node != LDNS_RBTREE_NULL) {
1063  next_node = ldns_rbtree_next(cur_node);
1064 
1065  /* skip glue */
1066  while (next_node != LDNS_RBTREE_NULL &&
1067  next_node->data &&
1068  ((ldns_dnssec_name *)next_node->data)->is_glue
1069  ) {
1070  next_node = ldns_rbtree_next(next_node);
1071  }
1072 
1073  if (next_node == LDNS_RBTREE_NULL) {
1074  next_node = ldns_rbtree_first(zone->names);
1075  }
1076  if (! cur_node->data || ! next_node->data) {
1077  return LDNS_STATUS_ERR;
1078  }
1079  cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
1080  next_name = ((ldns_dnssec_name *)next_node->data)->name;
1081  cur_label_count = ldns_dname_label_count(cur_name);
1082  next_label_count = ldns_dname_label_count(next_name);
1083 
1084  /* Since the names are in canonical order, we can
1085  * recognize empty non-terminals by their labels;
1086  * every label after the first one on the next owner
1087  * name is a non-terminal if it either does not exist
1088  * in the current name or is different from the same
1089  * label in the current name (counting from the end)
1090  */
1091  for (i = 1; i < next_label_count - soa_label_count; i++) {
1092  lpos = (int)cur_label_count - (int)next_label_count + (int)i;
1093  if (lpos >= 0) {
1094  l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
1095  } else {
1096  l1 = NULL;
1097  }
1098  l2 = ldns_dname_clone_from(next_name, i);
1099 
1100  if (!l1 || ldns_dname_compare(l1, l2) != 0) {
1101  /* We have an empty nonterminal, add it to the
1102  * tree
1103  */
1104  ldns_rbnode_t *node = NULL;
1105  ldns_rdf *ent_name;
1106 
1107  if (!(ent_name = ldns_dname_clone_from(
1108  next_name, i)))
1109  return LDNS_STATUS_MEM_ERR;
1110 
1111  if (nsec3s && zone->_nsec3params) {
1112  ldns_rdf *ent_hashed_name;
1113 
1114  if (!(ent_hashed_name =
1116  zone->_nsec3params,
1117  ent_name)))
1118  return LDNS_STATUS_MEM_ERR;
1119  node = ldns_rbtree_search(nsec3s,
1120  ent_hashed_name);
1121  if (!node) {
1122  ldns_rdf_deep_free(l1);
1123  ldns_rdf_deep_free(l2);
1124  continue;
1125  }
1126  }
1127  new_name = ldns_dnssec_name_new();
1128  if (!new_name) {
1129  return LDNS_STATUS_MEM_ERR;
1130  }
1131  new_name->name = ent_name;
1132  if (!new_name->name) {
1133  ldns_dnssec_name_free(new_name);
1134  return LDNS_STATUS_MEM_ERR;
1135  }
1136  new_name->name_alloced = true;
1137  new_node = LDNS_MALLOC(ldns_rbnode_t);
1138  if (!new_node) {
1139  ldns_dnssec_name_free(new_name);
1140  return LDNS_STATUS_MEM_ERR;
1141  }
1142  new_node->key = new_name->name;
1143  new_node->data = new_name;
1144  (void)ldns_rbtree_insert(zone->names, new_node);
1145  ldns_dnssec_name_make_hashed_name(
1146  zone, new_name, NULL);
1147  if (node)
1148  (void) ldns_dnssec_zone_add_rr(zone,
1149  (ldns_rr *)node->data);
1150  }
1151  ldns_rdf_deep_free(l1);
1152  ldns_rdf_deep_free(l2);
1153  }
1154 
1155  /* we might have inserted a new node after
1156  * the current one so we can't just use next()
1157  */
1158  if (next_node != ldns_rbtree_first(zone->names)) {
1159  cur_node = next_node;
1160  } else {
1161  cur_node = LDNS_RBTREE_NULL;
1162  }
1163  }
1164  return LDNS_STATUS_OK;
1165 }
1166 
1169 {
1170  return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
1171 }
1172 
1173 bool
1175 {
1176  ldns_rr* nsec3;
1177  ldns_rbnode_t* node;
1178 
1180  node = ldns_rbtree_first(zone->names);
1181  while (node != LDNS_RBTREE_NULL) {
1182  nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
1183  if (nsec3 &&ldns_rr_get_type(nsec3)
1184  == LDNS_RR_TYPE_NSEC3 &&
1185  ldns_nsec3_optout(nsec3)) {
1186  return true;
1187  }
1188  node = ldns_rbtree_next(node);
1189  }
1190  }
1191  return false;
1192 }
LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
@ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
Definition: error.h:82
ldns_struct_rr_list
List or Set of Resource Records.
Definition: rr.h:330
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:64
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_rbtree_t
definition for tree struct
Definition: rbtree.h:83
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_struct_dnssec_rrs::rr
ldns_rr * rr
Definition: dnssec_zone.h:24
ldns_zone_new_frm_fp_l
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: zone.c:194
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_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_dnssec_name_is_glue
bool ldns_dnssec_name_is_glue(const ldns_dnssec_name *name)
Returns if dnssec_name structure is marked as glue.
Definition: dnssec_zone.c:403
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's and...
Definition: dnssec_zone.h:102
LDNS_COMMENT_LAYOUT
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
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_STATUS_SYNTAX_ORIGIN
@ LDNS_STATUS_SYNTAX_ORIGIN
Definition: error.h:89
ldns_dnssec_zone_is_nsec3_optout
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.
Definition: dnssec_zone.c:1174
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_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_struct_rr
Resource Record.
Definition: rr.h:302
ldns_dnssec_rrsets_type
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)
Definition: dnssec_zone.c:146
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_FREE
#define LDNS_FREE(ptr)
Definition: util.h:60
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:927
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:2406
ldns_dnssec_zone_new_frm_fp
ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)))
Definition: dnssec_zone.c:775
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:2687
ldns_struct_output_format
Output format specifier.
Definition: host2str.h:86
LDNS_STATUS_OK
@ LDNS_STATUS_OK
Definition: error.h:26
LDNS_STATUS_ERR
@ LDNS_STATUS_ERR
Definition: error.h:37
ldns_dnssec_zone_names_print
void ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
Definition: dnssec_zone.c:999
ldns_dnssec_name_print
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.
Definition: dnssec_zone.c:562
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_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:1118
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:560
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_struct_dnssec_rrs::next
ldns_dnssec_rrs * next
Definition: dnssec_zone.h:25
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_zone_rrs
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition: zone.c:35
ldns_rbnode_t::key
const void * key
pointer to sorting key
Definition: rbtree.h:68
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_STATUS_SYNTAX_INCLUDE
@ LDNS_STATUS_SYNTAX_INCLUDE
Definition: error.h:90
LDNS_RR_TYPE_NSEC3PARAM
@ LDNS_RR_TYPE_NSEC3PARAM
Definition: rr.h:180
ldns_rr_compare
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition: rr.c:1623
ldns_dnssec_rrsets_print
void ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
Definition: dnssec_zone.c:310
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:75
ldns_struct_dnssec_name::rrsets
ldns_dnssec_rrsets * rrsets
The rrsets for this name.
Definition: dnssec_zone.h:63
ldns_struct_dnssec_name::nsec_signatures
ldns_dnssec_rrs * nsec_signatures
signatures for the NSEC record
Definition: dnssec_zone.h:71
ldns_struct_dnssec_name::name
ldns_rdf * name
pointer to a dname containing the name.
Definition: dnssec_zone.h:51
LDNS_STATUS_SYNTAX_EMPTY
@ LDNS_STATUS_SYNTAX_EMPTY
Definition: error.h:91
ldns_struct_dnssec_name
Definition: dnssec_zone.h:45
ldns_struct_dnssec_zone
Structure containing a dnssec zone.
Definition: dnssec_zone.h:91
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_dnssec_zone_new_frm_fp_l
ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: dnssec_zone.c:608
ldns_struct_dnssec_rrsets::signatures
ldns_dnssec_rrs * signatures
Definition: dnssec_zone.h:36
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:796
ldns_output_format_default
const ldns_output_format * ldns_output_format_default
The default output format record.
Definition: host2str.c:131
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_CALLOC
#define LDNS_CALLOC(type, count)
Definition: util.h:53
ldns_dnssec_rrs_print_fmt
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
ldns_dnssec_rrs_print
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
ldns_rr_type
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:239
ldns_dnssec_name_name
ldns_rdf * ldns_dnssec_name_name(const ldns_dnssec_name *name)
Returns the domain name of the given dnssec_name structure.
Definition: dnssec_zone.c:394
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_RR_TYPE_SOA
@ LDNS_RR_TYPE_SOA
marks the start of a zone of authority
Definition: rr.h:93
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_rdf_deep_free
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
ldns_rdf_clone
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
LDNS_MALLOC
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
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_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:1168
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_status
enum ldns_enum_status ldns_status
Definition: error.h:134
ATTR_UNUSED
#define ATTR_UNUSED(x)
Definition: common.h:69
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:1279
ldns_struct_dnssec_rrsets
Definition: dnssec_zone.h:32
ldns_struct_dnssec_zone::names
ldns_rbtree_t * names
tree of ldns_dnssec_names
Definition: dnssec_zone.h:95
INLINE
#define INLINE
splint static inline workaround
Definition: util.h:42
ldns_zone_soa
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition: zone.c:17
config.h
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_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_struct_rdf
Resource record data field.
Definition: rdata.h:174
ldns_rbtree_t::count
size_t count
The number of the nodes in the tree.
Definition: rbtree.h:88
ldns_struct_dnssec_rrsets::type
ldns_rr_type type
Definition: dnssec_zone.h:35
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:827
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_output_format::flags
int flags
Specification of how RR's should be formatted in text.
Definition: host2str.h:89
ldns_dnssec_zone_names_print_fmt
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_rbtree_t *tree, bool print_soa)
Definition: dnssec_zone.c:981
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:305
ldns_dnssec_rrsets_print_fmt
void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrsets *rrsets, bool follow)
Definition: dnssec_zone.c:302
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_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.h
LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
@ LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
Definition: error.h:101
ldns_struct_zone
DNS Zone.
Definition: zone.h:42
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_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_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_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:986
ldns_struct_dnssec_rrsets::next
ldns_dnssec_rrsets * next
Definition: dnssec_zone.h:37
LDNS_RR_TYPE_RRSIG
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:173
ldns_rbtree_init
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_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_rbnode_t::data
const void * data
pointer to data
Definition: rbtree.h:70
ldns_dnssec_zone_find_rrset
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.
Definition: dnssec_zone.c:508
LDNS_STATUS_SYNTAX_TTL
@ LDNS_STATUS_SYNTAX_TTL
Definition: error.h:88
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:811
ldns_dname_compare
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_dnssec_name_find_rrset
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.
Definition: dnssec_zone.c:492
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:2418
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:976
LDNS_STATUS_MEM_ERR
@ LDNS_STATUS_MEM_ERR
Definition: error.h:34
LDNS_RBTREE_NULL
#define LDNS_RBTREE_NULL
The nullpointer, points to empty node.
Definition: rbtree.h:76
ldns_rr_list_free
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:997
LDNS_RR_TYPE_NSEC
@ LDNS_RR_TYPE_NSEC
Definition: rr.h:174
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_struct_dnssec_rrsets::rrs
ldns_dnssec_rrs * rrs
Definition: dnssec_zone.h:34
ldns_dnssec_zone_print
void ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:1034
ldns_rbnode_t
The rbnode_t struct definition.
Definition: rbtree.h:60
ldns_dnssec_name_print_fmt
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.
Definition: dnssec_zone.c:555
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:905
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
@ LDNS_RR_TYPE_NSEC3
Definition: rr.h:179
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_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_struct_dnssec_rrs
Definition: dnssec_zone.h:22
ldns_rbtree_first
ldns_rbnode_t * ldns_rbtree_first(const ldns_rbtree_t *rbtree)
Returns first (smallest) node in the tree.
Definition: rbtree.c:548
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:706
ldns_dnssec_zone_print_fmt
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.
Definition: dnssec_zone.c:1006
ldns_nsec3_hash_name_frm_nsec3
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:1359
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:929
ldns_rr_list_rr_count
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:943