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  newzone = NULL;
750  }
751 
752 error:
753 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
754  if (zone) {
755  ldns_zone_free(zone);
756  }
757 #endif
758  ldns_rr_list_free(todo_nsec3_rrsigs);
759  ldns_traverse_postorder(&todo_nsec3_ents,
760  ldns_todo_nsec3_ents_node_free, NULL);
761  ldns_rr_list_free(todo_nsec3s);
762 
763  if (my_origin) {
764  ldns_rdf_deep_free(my_origin);
765  }
766  if (my_prev) {
767  ldns_rdf_deep_free(my_prev);
768  }
769  if (newzone) {
770  ldns_dnssec_zone_free(newzone);
771  }
772  return status;
773 }
774 
777  uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
778 {
779  return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
780 }
781 
782 static void
783 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
784  (void) arg;
786  LDNS_FREE(node);
787 }
788 
789 static void
790 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
791  (void) arg;
793  LDNS_FREE(node);
794 }
795 
796 void
798 {
799  if (zone) {
800  if (zone->names) {
801  /* destroy all name structures within the tree */
803  ldns_dnssec_name_node_free,
804  NULL);
805  LDNS_FREE(zone->names);
806  }
807  LDNS_FREE(zone);
808  }
809 }
810 
811 void
813 {
814  if (zone) {
815  if (zone->names) {
816  /* destroy all name structures within the tree */
818  ldns_dnssec_name_node_deep_free,
819  NULL);
820  LDNS_FREE(zone->names);
821  }
822  LDNS_FREE(zone);
823  }
824 }
825 
826 /* use for dname comparison in tree */
827 int
828 ldns_dname_compare_v(const void *a, const void *b) {
829  return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
830 }
831 
832 static void
833 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
834  ldns_dnssec_name* name, ldns_rr* nsec3rr);
835 
836 static void
837 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
838  (void) arg;
839  LDNS_FREE(node);
840 }
841 
842 static void
843 ldns_dnssec_zone_hashed_names_from_nsec3(
844  ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
845 {
846  ldns_rbnode_t* current_node;
847  ldns_dnssec_name* current_name;
848 
849  assert(zone != NULL);
850  assert(nsec3rr != NULL);
851 
852  if (zone->hashed_names) {
854  ldns_hashed_names_node_free, NULL);
855  LDNS_FREE(zone->hashed_names);
856  }
857  zone->_nsec3params = nsec3rr;
858 
859  /* So this is a NSEC3 zone.
860  * Calculate hashes for all names already in the zone
861  */
863  if (zone->hashed_names == NULL) {
864  return;
865  }
866  for ( current_node = ldns_rbtree_first(zone->names)
867  ; current_node != LDNS_RBTREE_NULL
868  ; current_node = ldns_rbtree_next(current_node)
869  ) {
870  current_name = (ldns_dnssec_name *) current_node->data;
871  ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
872 
873  }
874 }
875 
876 static void
877 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
878  ldns_dnssec_name* name, ldns_rr* nsec3rr)
879 {
880  ldns_rbnode_t* new_node;
881 
882  assert(name != NULL);
883  if (! zone->_nsec3params) {
884  if (! nsec3rr) {
885  return;
886  }
887  ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
888 
889  } else if (! nsec3rr) {
890  nsec3rr = zone->_nsec3params;
891  }
892  name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
893 
894  /* Also store in zone->hashed_names */
895  if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
896 
897  new_node->key = name->hashed_name;
898  new_node->data = name;
899 
900  if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
901 
902  LDNS_FREE(new_node);
903  }
904  }
905 }
906 
907 
908 static ldns_rbnode_t *
909 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
910  ldns_rdf *hashed_name;
911 
912  hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
913  if (hashed_name == NULL) {
914  return NULL;
915  }
916  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
917 
918  ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
919  }
920  if (zone->hashed_names == NULL) {
921  ldns_rdf_deep_free(hashed_name);
922  return NULL;
923  }
924  return ldns_rbtree_search(zone->hashed_names, hashed_name);
925 }
926 
929 {
930  ldns_status result = LDNS_STATUS_OK;
931  ldns_dnssec_name *cur_name;
932  ldns_rbnode_t *cur_node;
933  ldns_rr_type type_covered = 0;
934 
935  if (!zone || !rr) {
936  return LDNS_STATUS_ERR;
937  }
938 
939  if (!zone->names) {
941  if(!zone->names) return LDNS_STATUS_MEM_ERR;
942  }
943 
944  /* we need the original of the hashed name if this is
945  an NSEC3, or an RRSIG that covers an NSEC3 */
947  type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
948  }
950  type_covered == LDNS_RR_TYPE_NSEC3) {
951  cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
952  if (!cur_node) {
954  }
955  } else {
956  cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
957  }
958  if (!cur_node) {
959  /* add */
960  cur_name = ldns_dnssec_name_new_frm_rr(rr);
961  if(!cur_name) return LDNS_STATUS_MEM_ERR;
962  cur_node = LDNS_MALLOC(ldns_rbnode_t);
963  if(!cur_node) {
964  ldns_dnssec_name_free(cur_name);
965  return LDNS_STATUS_MEM_ERR;
966  }
967  cur_node->key = ldns_rr_owner(rr);
968  cur_node->data = cur_name;
969  (void)ldns_rbtree_insert(zone->names, cur_node);
970  ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
971  } else {
972  cur_name = (ldns_dnssec_name *) cur_node->data;
973  result = ldns_dnssec_name_add_rr(cur_name, rr);
974  }
975  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
976  zone->soa = cur_name;
977  }
978  return result;
979 }
980 
981 void
983  const ldns_rbtree_t *tree,
984  bool print_soa)
985 {
986  ldns_rbnode_t *node;
987  ldns_dnssec_name *name;
988 
989  node = ldns_rbtree_first(tree);
990  while (node != LDNS_RBTREE_NULL) {
991  name = (ldns_dnssec_name *) node->data;
992  ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
993  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
994  fprintf(out, ";\n");
995  node = ldns_rbtree_next(node);
996  }
997 }
998 
999 void
1000 ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
1001 {
1003  tree, print_soa);
1004 }
1005 
1006 void
1008  const ldns_dnssec_zone *zone)
1009 {
1010  if (zone) {
1011  if (zone->soa) {
1012  if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
1013  fprintf(out, ";; Zone: ");
1015  zone->soa));
1016  fprintf(out, "\n;\n");
1017  }
1020  zone->soa,
1021  LDNS_RR_TYPE_SOA),
1022  false);
1023  if ((fmt->flags & LDNS_COMMENT_LAYOUT))
1024  fprintf(out, ";\n");
1025  }
1026 
1027  if (zone->names) {
1029  zone->names, false);
1030  }
1031  }
1032 }
1033 
1034 void
1036 {
1038 }
1039 
1040 static ldns_status
1041 ldns_dnssec_zone_add_empty_nonterminals_nsec3(
1042  ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
1043 {
1044  ldns_dnssec_name *new_name;
1045  ldns_rdf *cur_name;
1046  ldns_rdf *next_name;
1047  ldns_rbnode_t *cur_node, *next_node, *new_node;
1048 
1049  /* for the detection */
1050  uint16_t i, cur_label_count, next_label_count;
1051  uint16_t soa_label_count = 0;
1052  ldns_rdf *l1, *l2;
1053  int lpos;
1054 
1055  if (!zone) {
1056  return LDNS_STATUS_ERR;
1057  }
1058  if (zone->soa && zone->soa->name) {
1059  soa_label_count = ldns_dname_label_count(zone->soa->name);
1060  }
1061 
1062  cur_node = ldns_rbtree_first(zone->names);
1063  while (cur_node != LDNS_RBTREE_NULL) {
1064  next_node = ldns_rbtree_next(cur_node);
1065 
1066  /* skip glue */
1067  while (next_node != LDNS_RBTREE_NULL &&
1068  next_node->data &&
1069  ((ldns_dnssec_name *)next_node->data)->is_glue
1070  ) {
1071  next_node = ldns_rbtree_next(next_node);
1072  }
1073 
1074  if (next_node == LDNS_RBTREE_NULL) {
1075  next_node = ldns_rbtree_first(zone->names);
1076  }
1077  if (! cur_node->data || ! next_node->data) {
1078  return LDNS_STATUS_ERR;
1079  }
1080  cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
1081  next_name = ((ldns_dnssec_name *)next_node->data)->name;
1082  cur_label_count = ldns_dname_label_count(cur_name);
1083  next_label_count = ldns_dname_label_count(next_name);
1084 
1085  /* Since the names are in canonical order, we can
1086  * recognize empty non-terminals by their labels;
1087  * every label after the first one on the next owner
1088  * name is a non-terminal if it either does not exist
1089  * in the current name or is different from the same
1090  * label in the current name (counting from the end)
1091  */
1092  for (i = 1; i < next_label_count - soa_label_count; i++) {
1093  lpos = (int)cur_label_count - (int)next_label_count + (int)i;
1094  if (lpos >= 0) {
1095  l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
1096  } else {
1097  l1 = NULL;
1098  }
1099  l2 = ldns_dname_clone_from(next_name, i);
1100 
1101  if (!l1 || ldns_dname_compare(l1, l2) != 0) {
1102  /* We have an empty nonterminal, add it to the
1103  * tree
1104  */
1105  ldns_rbnode_t *node = NULL;
1106  ldns_rdf *ent_name;
1107 
1108  if (!(ent_name = ldns_dname_clone_from(
1109  next_name, i))) {
1110 
1111  ldns_rdf_deep_free(l1);
1112  ldns_rdf_deep_free(l2);
1113  return LDNS_STATUS_MEM_ERR;
1114  }
1115 
1116  if (nsec3s && zone->_nsec3params) {
1117  ldns_rdf *ent_hashed_name;
1118 
1119  if (!(ent_hashed_name =
1121  zone->_nsec3params,
1122  ent_name))) {
1123  ldns_rdf_deep_free(l1);
1124  ldns_rdf_deep_free(l2);
1125  ldns_rdf_deep_free(ent_name);
1126  return LDNS_STATUS_MEM_ERR;
1127  }
1128  node = ldns_rbtree_search(nsec3s,
1129  ent_hashed_name);
1130  if (!node) {
1131  ldns_rdf_deep_free(l1);
1132  ldns_rdf_deep_free(l2);
1133  ldns_rdf_deep_free(ent_name);
1134  continue;
1135  }
1136  }
1137  new_name = ldns_dnssec_name_new();
1138  if (!new_name) {
1139  ldns_rdf_deep_free(l1);
1140  ldns_rdf_deep_free(l2);
1141  ldns_rdf_deep_free(ent_name);
1142  return LDNS_STATUS_MEM_ERR;
1143  }
1144  new_name->name = ent_name;
1145  new_name->name_alloced = true;
1146  new_node = LDNS_MALLOC(ldns_rbnode_t);
1147  if (!new_node) {
1148  ldns_rdf_deep_free(l1);
1149  ldns_rdf_deep_free(l2);
1150  ldns_dnssec_name_free(new_name);
1151  return LDNS_STATUS_MEM_ERR;
1152  }
1153  new_node->key = new_name->name;
1154  new_node->data = new_name;
1155  (void)ldns_rbtree_insert(zone->names, new_node);
1156  ldns_dnssec_name_make_hashed_name(
1157  zone, new_name, NULL);
1158  if (node)
1159  (void) ldns_dnssec_zone_add_rr(zone,
1160  (ldns_rr *)node->data);
1161  }
1162  ldns_rdf_deep_free(l1);
1163  ldns_rdf_deep_free(l2);
1164  }
1165 
1166  /* we might have inserted a new node after
1167  * the current one so we can't just use next()
1168  */
1169  if (next_node != ldns_rbtree_first(zone->names)) {
1170  cur_node = next_node;
1171  } else {
1172  cur_node = LDNS_RBTREE_NULL;
1173  }
1174  }
1175  return LDNS_STATUS_OK;
1176 }
1177 
1180 {
1181  return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
1182 }
1183 
1184 bool
1186 {
1187  ldns_rr* nsec3;
1188  ldns_rbnode_t* node;
1189 
1191  node = ldns_rbtree_first(zone->names);
1192  while (node != LDNS_RBTREE_NULL) {
1193  nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
1194  if (nsec3 &&ldns_rr_get_type(nsec3)
1195  == LDNS_RR_TYPE_NSEC3 &&
1196  ldns_nsec3_optout(nsec3)) {
1197  return true;
1198  }
1199  node = ldns_rbtree_next(node);
1200  }
1201  }
1202  return false;
1203 }
#define ATTR_UNUSED(x)
Definition: common.h:69
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
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
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_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
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:1284
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:1366
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
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:1007
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
void ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_rrsets *rrsets, bool follow)
Print the given list of rrsets to the fiven file descriptor.
Definition: dnssec_zone.c:302
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
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
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_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
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:1035
void ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:388
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
void ldns_dnssec_name_free(ldns_dnssec_name *name)
Frees the name structure and its rrs and rrsets.
Definition: dnssec_zone.c:382
ldns_dnssec_name * ldns_dnssec_name_new(void)
Create a new data structure for a dnssec name.
Definition: dnssec_zone.c:317
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_rbtree_t *tree, bool print_soa)
Prints the rbtree of ldns_dnssec_name structures to the file descriptor.
Definition: dnssec_zone.c:982
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
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.
Definition: dnssec_zone.c:1185
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:928
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
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 * 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_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:776
ldns_dnssec_rrsets * ldns_dnssec_rrsets_new(void)
Creates a new list (entry) of RRsets.
Definition: dnssec_zone.c:104
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:1179
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
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:797
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
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
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_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
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:812
void ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
Print the given list of rrsets to the fiven file descriptor.
Definition: dnssec_zone.c:310
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
void ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
Prints the rbtree of ldns_dnssec_name structures to the file descriptor.
Definition: dnssec_zone.c:1000
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
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
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:828
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_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition: dnssec_zone.c:569
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_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_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
Definition: error.h:101
@ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
Definition: error.h:82
@ 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_OK
Definition: error.h:26
@ LDNS_STATUS_SYNTAX_EMPTY
Definition: error.h:91
@ 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:134
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:2559
const ldns_output_format * ldns_output_format_default
The default output format record.
Definition: host2str.c:139
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:2571
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
Including this file will include all ldns files, and define some lookup tables.
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
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 *node)
Returns next larger node in the tree.
Definition: rbtree.c:574
ldns_rbnode_t * ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key)
Find key in tree.
Definition: rbtree.c:294
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_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_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:1006
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:985
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:914
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:2729
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:715
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:75
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:952
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:938
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1127
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:995
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition: rr.c:1632
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:241
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:170
@ 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_NSEC3
Definition: rr.h:176
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
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
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
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
bool 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
bool 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 * 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
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 applicible)
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...
Definition: dnssec_zone.h:102
ldns_dnssec_name * soa
points to the name containing the SOA RR
Definition: dnssec_zone.h:93
Output format specifier.
Definition: host2str.h:87
int flags
Specification of how RR's should be formatted in text.
Definition: host2str.h:89
Resource record data field.
Definition: rdata.h:178
List or Set of Resource Records.
Definition: rr.h:336
Resource Record.
Definition: rr.h:308
DNS Zone.
Definition: zone.h:43
#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
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_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition: zone.c:35
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition: zone.c:17
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