OpenDNSSEC-signer  1.3.16
domain.c
Go to the documentation of this file.
1 /*
2  * $Id: domain.c 7104 2013-04-18 14:04:27Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "shared/duration.h"
36 #include "shared/allocator.h"
37 #include "shared/log.h"
38 #include "shared/status.h"
39 #include "shared/util.h"
40 #include "signer/backup.h"
41 #include "signer/domain.h"
42 #include "signer/rrset.h"
43 
44 #include <ldns/ldns.h>
45 
46 static const char* dname_str = "domain";
47 
48 
53 static int
54 rrset_compare(const void* a, const void* b)
55 {
56  ldns_rr_type* x = (ldns_rr_type*)a;
57  ldns_rr_type* y = (ldns_rr_type*)b;
58  return (*x)-(*y);
59 }
60 
61 
67 domain_create(ldns_rdf* dname)
68 {
69  allocator_type* allocator = NULL;
70  domain_type* domain = NULL;
71  char* str = NULL;
72 
73  if (!dname) {
74  ods_log_error("[%s] unable to create domain: no dname", dname_str);
75  return NULL;
76  }
77  ods_log_assert(dname);
78 
79  allocator = allocator_create(malloc, free);
80  if (!allocator) {
81  str = ldns_rdf2str(dname);
82  ods_log_error("[%s] unable to create domain %s: create allocator "
83  "failed", dname_str, str?str:"(null)");
84  free((void*)str);
85  return NULL;
86  }
87  ods_log_assert(allocator);
88 
89  domain = (domain_type*) allocator_alloc(allocator, sizeof(domain_type));
90  if (!domain) {
91  str = ldns_rdf2str(dname);
92  ods_log_error("[%s] unable to create domain %s: allocator failed",
93  dname_str, str);
94  free(str);
95  allocator_cleanup(allocator);
96  return NULL;
97  }
98  ods_log_assert(domain);
99 
100  domain->allocator = allocator;
101  domain->dname = ldns_rdf_clone(dname);
102  domain->dstatus = DOMAIN_STATUS_NONE;
103  domain->parent = NULL;
104  domain->denial = NULL;
105  domain->rrsets = ldns_rbtree_create(rrset_compare);
106  return domain;
107 }
108 
109 
116 {
117  const char* token = NULL;
118  const char* locator = NULL;
119  uint32_t flags = 0;
120  ldns_rr* rr = NULL;
121  rrset_type* rrset = NULL;
122  ldns_status lstatus = LDNS_STATUS_OK;
123  ldns_rr_type type_covered = LDNS_RR_TYPE_FIRST;
124 
125  ods_log_assert(domain);
126  ods_log_assert(fd);
127 
128  domain->dstatus = dstatus;
129 
130  while (backup_read_str(fd, &token)) {
131  if (ods_strcmp(token, ";;RRSIG") == 0) {
132  /* recover signature */
133  if (!backup_read_str(fd, &locator) ||
134  !backup_read_uint32_t(fd, &flags)) {
135  ods_log_error("[%s] signature in backup corrupted",
136  dname_str);
137  goto recover_dname_error;
138  }
139  /* expect signature */
140  lstatus = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL);
141  if (lstatus != LDNS_STATUS_OK) {
142  ods_log_error("[%s] missing signature in backup", dname_str);
143  ods_log_error("[%s] ldns status: %s", dname_str,
144  ldns_get_errorstr_by_id(lstatus));
145  goto recover_dname_error;
146  }
147  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
148  ods_log_error("[%s] expecting signature in backup", dname_str);
149  ldns_rr_free(rr);
150  goto recover_dname_error;
151  }
152 
153  type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
154  rrset = domain_lookup_rrset(domain, type_covered);
155  if (!rrset) {
156  ods_log_error("[%s] signature type %i not covered",
157  dname_str, type_covered);
158  ldns_rr_free(rr);
159  goto recover_dname_error;
160  }
161  ods_log_assert(rrset);
162  if (rrset_recover(rrset, rr, locator, flags) != ODS_STATUS_OK) {
163  ods_log_error("[%s] unable to recover signature", dname_str);
164  ldns_rr_free(rr);
165  goto recover_dname_error;
166  }
167  /* signature done */
168  free((void*) locator);
169  locator = NULL;
170  rr = NULL;
171  } else if (ods_strcmp(token, ";;Denial") == 0) {
172  /* expect nsec(3) record */
173  lstatus = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL);
174  if (lstatus != LDNS_STATUS_OK) {
175  ods_log_error("[%s] missing denial in backup", dname_str);
176  goto recover_dname_error;
177  }
178  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_NSEC &&
179  ldns_rr_get_type(rr) != LDNS_RR_TYPE_NSEC3) {
180  ods_log_error("[%s] expecting denial in backup", dname_str);
181  ldns_rr_free(rr);
182  goto recover_dname_error;
183  }
184 
185  /* recover denial structure */
186  ods_log_assert(!domain->denial);
187  domain->denial = denial_create(ldns_rr_owner(rr));
188  ods_log_assert(domain->denial);
189  domain->denial->domain = domain; /* back reference */
190  /* add the NSEC(3) rr */
191  if (!domain->denial->rrset) {
192  domain->denial->rrset = rrset_create(ldns_rr_get_type(rr));
193  }
194  ods_log_assert(domain->denial->rrset);
195 
196  if (!rrset_add_rr(domain->denial->rrset, rr)) {
197  ods_log_error("[%s] unable to recover denial", dname_str);
198  ldns_rr_free(rr);
199  goto recover_dname_error;
200  }
201  /* commit */
202  if (rrset_commit(domain->denial->rrset) != ODS_STATUS_OK) {
203  ods_log_error("[%s] unable to recover denial", dname_str);
204  goto recover_dname_error;
205  }
206  /* denial done */
207  rr = NULL;
208 
209  /* recover signature */
210  if (!backup_read_check_str(fd, ";;RRSIG") ||
211  !backup_read_str(fd, &locator) ||
212  !backup_read_uint32_t(fd, &flags)) {
213  ods_log_error("[%s] signature in backup corrupted (denial)",
214  dname_str);
215  goto recover_dname_error;
216  }
217  /* expect signature */
218  lstatus = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL);
219  if (lstatus != LDNS_STATUS_OK) {
220  ods_log_error("[%s] missing signature in backup (denial)",
221  dname_str);
222  ods_log_error("[%s] ldns status: %s", dname_str,
223  ldns_get_errorstr_by_id(lstatus));
224  goto recover_dname_error;
225  }
226  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
227  ods_log_error("[%s] expecting signature in backup (denial)",
228  dname_str);
229  ldns_rr_free(rr);
230  goto recover_dname_error;
231  }
232  if (!domain->denial->rrset) {
233  ods_log_error("[%s] signature type not covered (denial)",
234  dname_str);
235  ldns_rr_free(rr);
236  goto recover_dname_error;
237  }
238  ods_log_assert(domain->denial->rrset);
239  if (rrset_recover(domain->denial->rrset, rr, locator, flags) !=
240  ODS_STATUS_OK) {
241  ods_log_error("[%s] unable to recover signature (denial)",
242  dname_str);
243  ldns_rr_free(rr);
244  goto recover_dname_error;
245  }
246  /* signature done */
247  free((void*) locator);
248  locator = NULL;
249  rr = NULL;
250  } else if (ods_strcmp(token, ";;Domaindone") == 0) {
251  /* domain done */
252  free((void*) token);
253  token = NULL;
254  break;
255  } else {
256  /* domain corrupted */
257  goto recover_dname_error;
258  }
259  /* done, next token */
260  free((void*) token);
261  token = NULL;
262  }
263 
264  return ODS_STATUS_OK;
265 
266 recover_dname_error:
267  free((void*) token);
268  token = NULL;
269 
270  free((void*) locator);
271  locator = NULL;
272  return ODS_STATUS_ERR;
273 }
274 
275 
280 static ldns_rbnode_t*
281 rrset2node(rrset_type* rrset)
282 {
283  ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t));
284  if (!node) {
285  return NULL;
286  }
287  node->key = (const void*) &(rrset->rr_type);
288  node->data = rrset;
289  return node;
290 }
291 
292 
297 static rrset_type*
298 domain_rrset_search(ldns_rbtree_t* tree, ldns_rr_type rrtype)
299 {
300  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
301 
302  if (!tree || !rrtype) {
303  return NULL;
304  }
305  node = ldns_rbtree_search(tree, (const void*) &rrtype);
306  if (node && node != LDNS_RBTREE_NULL) {
307  return (rrset_type*) node->data;
308  }
309  return NULL;
310 }
311 
312 
317 rrset_type*
318 domain_lookup_rrset(domain_type* domain, ldns_rr_type rrtype)
319 {
320  if (!domain || !rrtype) {
321  return NULL;
322  }
323  return domain_rrset_search(domain->rrsets, rrtype);
324 }
325 
326 
331 rrset_type*
333 {
334  ldns_rbnode_t* new_node = LDNS_RBTREE_NULL;
335 
336  if (!rrset) {
337  ods_log_error("[%s] unable to add RRset: no RRset", dname_str);
338  return NULL;
339  }
340  ods_log_assert(rrset);
341 
342  if (!domain || !domain->rrsets) {
343  ods_log_error("[%s] unable to add RRset: no storage", dname_str);
344  return NULL;
345  }
346  ods_log_assert(domain);
347  ods_log_assert(domain->rrsets);
348 
349  new_node = rrset2node(rrset);
350  if (ldns_rbtree_insert(domain->rrsets, new_node) == NULL) {
351  ods_log_error("[%s] unable to add RRset: already present", dname_str);
352  free((void*)new_node);
353  return NULL;
354  }
355  return rrset;
356 }
357 
358 
363 rrset_type*
365 {
366  ldns_rbnode_t* del_node = LDNS_RBTREE_NULL;
367  rrset_type* del_rrset = NULL;
368 
369  if (!rrset) {
370  ods_log_error("[%s] unable to delete RRset: no RRset", dname_str);
371  return NULL;
372  }
373  ods_log_assert(rrset);
374 
375  if (!domain || !domain->rrsets) {
376  ods_log_error("[%s] unable to delete RRset: no storage", dname_str);
377  return rrset;
378  }
379  ods_log_assert(domain);
380  ods_log_assert(domain->rrsets);
381 
382  del_node = ldns_rbtree_search(domain->rrsets,
383  (const void*) &(rrset->rr_type));
384  if (del_node) {
385  del_node = ldns_rbtree_delete(domain->rrsets,
386  (const void*) &(rrset->rr_type));
387  del_rrset = (rrset_type*) del_node->data;
388  rrset_cleanup(del_rrset);
389  free((void*)del_node);
390  return NULL;
391  }
392  return rrset;
393 }
394 
395 
400 size_t
402 {
403  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
404  rrset_type* rrset = NULL;
405  size_t count = 0;
406 
407  if (!domain || !domain->rrsets) {
408  return 0;
409  }
410 
411  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
412  node = ldns_rbtree_first(domain->rrsets);
413  }
414  while (node && node != LDNS_RBTREE_NULL) {
415  rrset = (rrset_type*) node->data;
416  if (rrset_count_rr(rrset, COUNT_RR) > 0) {
417  count++;
418  }
419  node = ldns_rbtree_next(node);
420  }
421  return count;
422 }
423 
424 
431 {
432  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
433  rrset_type* rrset = NULL;
434  ods_status status = ODS_STATUS_OK;
435 
436  if (!domain || !domain->rrsets) {
437  return status;
438  }
439  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
440  node = ldns_rbtree_first(domain->rrsets);
441  }
442  while (node && node != LDNS_RBTREE_NULL) {
443  rrset = (rrset_type*) node->data;
444  /* special cases */
445  if (rrset->rr_type == LDNS_RR_TYPE_NSEC3PARAMS) {
446  node = ldns_rbtree_next(node);
447  continue;
448  }
449  /* normal cases */
450  status = rrset_diff(rrset, kl);
451  if (status != ODS_STATUS_OK) {
452  return status;
453  }
454  node = ldns_rbtree_next(node);
455  }
456  return status;
457 }
458 
459 
464 int
465 domain_examine_data_exists(domain_type* domain, ldns_rr_type rrtype,
466  int skip_glue)
467 {
468  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
469  rrset_type* rrset = NULL;
470 
471  if (!domain) {
472  return 0;
473  }
474  ods_log_assert(domain);
475 
476  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
477  node = ldns_rbtree_first(domain->rrsets);
478  }
479  while (node && node != LDNS_RBTREE_NULL) {
480  rrset = (rrset_type*) node->data;
481  if (rrset_count_RR(rrset) > 0) {
482  if (rrtype) {
483  /* looking for a specific RRset */
484  if (rrset->rr_type == rrtype) {
485  return 1;
486  }
487  } else if (!skip_glue ||
488  (rrset->rr_type != LDNS_RR_TYPE_A &&
489  rrset->rr_type != LDNS_RR_TYPE_AAAA)) {
490  /* not glue or not skipping glue */
491  return 1;
492  }
493  }
494  node = ldns_rbtree_next(node);
495  }
496  return 0;
497 }
498 
499 
504 int
505 domain_examine_rrset_is_alone(domain_type* domain, ldns_rr_type rrtype)
506 {
507  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
508  rrset_type* rrset = NULL;
509  ldns_dnssec_rrs* rrs = NULL;
510  char* str_name = NULL;
511  char* str_type = NULL;
512  size_t count = 0;
513 
514  if (!domain || !rrtype) {
515  return 1;
516  }
517  ods_log_assert(domain);
518  ods_log_assert(rrtype);
519 
520  rrset = domain_lookup_rrset(domain, rrtype);
521  if (rrset) {
522  count = rrset_count_RR(rrset);
523  }
524  if (count) {
525  if (domain_count_rrset(domain) < 2) {
526  /* one or zero, that's ok */
527  return 1;
528  }
529  /* make sure all other RRsets become empty */
530  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
531  node = ldns_rbtree_first(domain->rrsets);
532  }
533  while (node && node != LDNS_RBTREE_NULL) {
534  rrset = (rrset_type*) node->data;
535  if (rrset->rr_type != rrtype && rrset_count_RR(rrset) > 0) {
536  /* found other data next to rrtype */
537  str_name = ldns_rdf2str(domain->dname);
538  str_type = ldns_rr_type2str(rrtype);
539  ods_log_error("[%s] other data next to %s %s", dname_str, str_name, str_type);
540  rrs = rrset->rrs;
541  while (rrs) {
542  if (rrs->rr) {
543  log_rr(rrs->rr, "next-to-CNAME: ", 1);
544  }
545  rrs = rrs->next;
546  }
547  rrs = rrset->add;
548  while (rrs) {
549  if (rrs->rr) {
550  log_rr(rrs->rr, "next-to-CNAME: ", 1);
551  }
552  rrs = rrs->next;
553  }
554  free((void*)str_name);
555  free((void*)str_type);
556  return 0;
557  }
558  node = ldns_rbtree_next(node);
559  }
560  }
561  return 1;
562 }
563 
564 
569 int
571 {
572  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
573  rrset_type* rrset = NULL;
574  size_t count = 0;
575 
576  if (!domain) {
577  return 1;
578  }
579  ods_log_assert(domain);
580 
581  rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS);
582  if (rrset) {
583  count = rrset_count_RR(rrset);
584  }
585 
586  if (count) {
587  /* make sure all other RRsets become empty (except DS, glue) */
588  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
589  node = ldns_rbtree_first(domain->rrsets);
590  }
591  while (node && node != LDNS_RBTREE_NULL) {
592  rrset = (rrset_type*) node->data;
593  if (rrset->rr_type != LDNS_RR_TYPE_DS &&
594  rrset->rr_type != LDNS_RR_TYPE_NS &&
595  rrset->rr_type != LDNS_RR_TYPE_A &&
596  rrset->rr_type != LDNS_RR_TYPE_AAAA &&
597  rrset_count_RR(rrset) > 0) {
598  /* found occluded data next to delegation */
599  ods_log_error("[%s] occluded glue data at zonecut, RRtype=%u",
600  dname_str, rrset->rr_type);
601  return 0;
602  } else if (rrset->rr_type == LDNS_RR_TYPE_A ||
603  rrset->rr_type == LDNS_RR_TYPE_AAAA) {
604  /* check if glue is allowed at the delegation */
605 /* TODO: allow for now (root zone has it)
606  if (rrset_count_RR(rrset) > 0 &&
607  !domain_examine_ns_rdata(domain, domain->dname)) {
608  ods_log_error("[%s] occluded glue data at zonecut, #RR=%u",
609  dname_str, rrset_count_RR(rrset));
610  return 0;
611  }
612 */
613  }
614  node = ldns_rbtree_next(node);
615  }
616  }
617  return 0;
618 }
619 
620 
625 int
626 domain_examine_rrset_is_singleton(domain_type* domain, ldns_rr_type rrtype)
627 {
628  rrset_type* rrset = NULL;
629  char* str_name = NULL;
630  char* str_type = NULL;
631  size_t count = 0;
632 
633  if (!domain || !rrtype) {
634  return 1;
635  }
636  ods_log_assert(domain);
637  ods_log_assert(rrtype);
638 
639  rrset = domain_lookup_rrset(domain, rrtype);
640  if (rrset) {
641  count = rrset_count_RR(rrset);
642  }
643 
644  if (count > 1) {
645  /* multiple RRs in the RRset for singleton RRtype*/
646  str_name = ldns_rdf2str(domain->dname);
647  str_type = ldns_rr_type2str(rrtype);
648  ods_log_error("[%s] multiple records for singleton type at %s %s",
649  dname_str, str_name, str_type);
650  free((void*)str_name);
651  free((void*)str_type);
652  return 0;
653  }
654  return 1;
655 }
656 
657 
664 {
665  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
666  rrset_type* rrset = NULL;
667  ods_status status = ODS_STATUS_OK;
668  size_t numadd = 0;
669  size_t numdel = 0;
670  size_t numrrs = 0;
671  size_t numnew = 0;
672 
673  if (!domain || !domain->rrsets) {
674  return ODS_STATUS_OK;
675  }
676  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
677  node = ldns_rbtree_first(domain->rrsets);
678  }
679  while (node && node != LDNS_RBTREE_NULL) {
680  rrset = (rrset_type*) node->data;
681  numrrs = rrset_count_rr(rrset, COUNT_RR);
682  numadd = rrset_count_rr(rrset, COUNT_ADD);
683  numdel = rrset_count_rr(rrset, COUNT_DEL);
684 
685  if (rrset->rr_type == LDNS_RR_TYPE_SOA && rrset->rrs &&
686  rrset->rrs->rr) {
687  rrset->needs_signing = 1;
688  }
689  status = rrset_commit(rrset);
690  if (status != ODS_STATUS_OK) {
691  return status;
692  }
693  node = ldns_rbtree_next(node);
694  numnew = rrset_count_rr(rrset, COUNT_RR);
695 
696  if (numrrs > 0 && numnew <= 0) {
697  if (domain_del_rrset(domain, rrset) != NULL) {
698  ods_log_warning("[%s] unable to commit: failed ",
699  "to delete RRset", dname_str);
700  return ODS_STATUS_UNCHANGED;
701  }
702  if (domain->denial) {
703  domain->denial->bitmap_changed = 1;
704  }
705  } else if (numrrs <= 0 && numnew == numadd) {
706  if (domain->denial) {
707  domain->denial->bitmap_changed = 1;
708  }
709  }
710  }
711  return status;
712 }
713 
714 
719 void
721 {
722  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
723  rrset_type* rrset = NULL;
724 
725  if (!domain || !domain->rrsets) {
726  return;
727  }
728  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
729  node = ldns_rbtree_first(domain->rrsets);
730  }
731  while (node && node != LDNS_RBTREE_NULL) {
732  rrset = (rrset_type*) node->data;
733  rrset_rollback(rrset);
734  node = ldns_rbtree_next(node);
735  }
736  return;
737 }
738 
739 
744 void
746 {
747  domain_type* parent = NULL;
748 
749  if (!domain) {
750  ods_log_error("[%s] unable to set status: no domain", dname_str);
751  return;
752  }
753  if (domain->dstatus == DOMAIN_STATUS_APEX) {
754  /* that doesn't change... */
755  return;
756  }
757  if (domain_count_rrset(domain) <= 0) {
758  domain->dstatus = DOMAIN_STATUS_ENT;
759  return;
760  }
761 
762  if (domain_lookup_rrset(domain, LDNS_RR_TYPE_NS)) {
763  if (domain_lookup_rrset(domain, LDNS_RR_TYPE_DS)) {
764  domain->dstatus = DOMAIN_STATUS_DS;
765  } else {
766  domain->dstatus = DOMAIN_STATUS_NS;
767  }
768  } else {
769  domain->dstatus = DOMAIN_STATUS_AUTH;
770  }
771 
772  parent = domain->parent;
773  while (parent && parent->dstatus != DOMAIN_STATUS_APEX) {
774  if (domain_lookup_rrset(parent, LDNS_RR_TYPE_DNAME) ||
775  domain_lookup_rrset(parent, LDNS_RR_TYPE_NS)) {
777  return;
778  }
779  parent = parent->parent;
780  }
781  return;
782 }
783 
784 
791 {
792  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
793  rrset_type* rrset = NULL;
794  ods_status status = ODS_STATUS_OK;
795 
796  if (!domain || !domain->rrsets) {
797  return ODS_STATUS_OK;
798  }
799  if (domain->dstatus == DOMAIN_STATUS_NONE ||
800  domain->dstatus == DOMAIN_STATUS_OCCLUDED) {
801  return ODS_STATUS_OK;
802  }
803 
804  if (domain->rrsets->root != LDNS_RBTREE_NULL) {
805  node = ldns_rbtree_first(domain->rrsets);
806  }
807  while (node && node != LDNS_RBTREE_NULL) {
808  rrset = (rrset_type*) node->data;
809 
810  /* skip delegation RRsets */
811  if (domain->dstatus != DOMAIN_STATUS_APEX &&
812  rrset->rr_type == LDNS_RR_TYPE_NS) {
813  node = ldns_rbtree_next(node);
814  continue;
815  }
816  /* skip glue at the delegation */
817  if ((domain->dstatus == DOMAIN_STATUS_DS ||
818  domain->dstatus == DOMAIN_STATUS_NS) &&
819  (rrset->rr_type == LDNS_RR_TYPE_A ||
820  rrset->rr_type == LDNS_RR_TYPE_AAAA)) {
821  node = ldns_rbtree_next(node);
822  continue;
823  }
824  /* queue RRset for signing */
825  status = rrset_queue(rrset, q, worker);
826  if (status != ODS_STATUS_OK) {
827  return status;
828  }
829  node = ldns_rbtree_next(node);
830  }
831 
832  /* queue NSEC(3) RRset for signing */
833  if (domain->denial && domain->denial->rrset) {
834  status = rrset_queue(domain->denial->rrset, q, worker);
835  }
836  return status;
837 }
838 
839 
844 int
845 domain_examine_ns_rdata(domain_type* domain, ldns_rdf* nsdname)
846 {
847  rrset_type* rrset = NULL;
848 
849  if (!domain || !nsdname) {
850  return 0;
851  }
852  rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS);
853  if (rrset) {
854  if (rrset_examine_ns_rdata(rrset, nsdname)) {
855  return 1;
856  }
857  }
858  return 0;
859 }
860 
861 
866 static void
867 rrset_delfunc(ldns_rbnode_t* elem)
868 {
869  rrset_type* rrset;
870 
871  if (elem && elem != LDNS_RBTREE_NULL) {
872  rrset = (rrset_type*) elem->data;
873  rrset_delfunc(elem->left);
874  rrset_delfunc(elem->right);
875 
876  rrset_cleanup(rrset);
877  free(elem);
878  }
879  return;
880 }
881 
882 
887 void
889 {
891 
892  if (!domain) {
893  return;
894  }
895  allocator = domain->allocator;
896 
897  if (domain->dname) {
898  ldns_rdf_deep_free(domain->dname);
899  domain->dname = NULL;
900  }
901  if (domain->rrsets) {
902  rrset_delfunc(domain->rrsets->root);
903  ldns_rbtree_free(domain->rrsets);
904  domain->rrsets = NULL;
905  }
906  allocator_deallocate(allocator, (void*) domain);
907  allocator_cleanup(allocator);
908  return;
909 }
910 
911 
916 void
917 domain_print(FILE* fd, domain_type* domain)
918 {
919  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
920  rrset_type* rrset = NULL;
921  rrset_type* soa_rrset = NULL;
922  rrset_type* cname_rrset = NULL;
923 
924  if (!domain || !fd) {
925  return;
926  }
927  ods_log_assert(fd);
928  ods_log_assert(domain);
929 
930  if (domain->rrsets) {
931  node = ldns_rbtree_first(domain->rrsets);
932  }
933  /* no other data may accompany a CNAME */
934  cname_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_CNAME);
935  if (cname_rrset) {
936  rrset_print(fd, cname_rrset, 0);
937  } else {
938  /* if SOA, print soa first */
939  if (domain->dstatus == DOMAIN_STATUS_APEX) {
940  soa_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_SOA);
941  if (soa_rrset) {
942  rrset_print(fd, soa_rrset, 0);
943  }
944  }
945  /* print other RRsets */
946  while (node && node != LDNS_RBTREE_NULL) {
947  rrset = (rrset_type*) node->data;
948  /* skip SOA RRset */
949  if (rrset->rr_type != LDNS_RR_TYPE_SOA) {
950  if (domain->dstatus == DOMAIN_STATUS_OCCLUDED) {
951  /* glue? */
952  rrset_print(fd, rrset, 1);
953  } else {
954  rrset_print(fd, rrset, 0);
955  }
956  }
957  node = ldns_rbtree_next(node);
958  }
959  }
960  /* denial of existence */
961  if (domain->denial) {
962  rrset_print(fd, domain->denial->rrset, 0);
963  }
964  return;
965 }
966 
967 
972 void
973 domain_backup(FILE* fd, domain_type* domain)
974 {
975  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
976  char* str = NULL;
977  rrset_type* rrset = NULL;
978 
979  if (!domain || !fd) {
980  return;
981  }
982 
983  str = ldns_rdf2str(domain->dname);
984  if (domain->rrsets) {
985  node = ldns_rbtree_first(domain->rrsets);
986  }
987 
988  fprintf(fd, ";;Domain: name %s status %i\n", str, (int) domain->dstatus);
989  while (node && node != LDNS_RBTREE_NULL) {
990  rrset = (rrset_type*) node->data;
991  rrset_backup(fd, rrset);
992  node = ldns_rbtree_next(node);
993  }
994  free((void*)str);
995 
996  /* denial of existence */
997  if (domain->denial) {
998  fprintf(fd, ";;Denial\n");
999  rrset_print(fd, domain->denial->rrset, 1);
1000  rrset_backup(fd, domain->denial->rrset);
1001  }
1002 
1003  fprintf(fd, ";;Domaindone\n");
1004  return;
1005 }
void domain_cleanup(domain_type *domain)
Definition: domain.c:888
#define COUNT_ADD
Definition: rrset.h:52
int backup_read_str(FILE *in, const char **str)
Definition: backup.c:94
#define COUNT_RR
Definition: rrset.h:51
rrset_type * rrset
Definition: denial.h:54
void rrset_cleanup(rrset_type *rrset)
Definition: rrset.c:1189
rrset_type * domain_lookup_rrset(domain_type *domain, ldns_rr_type rrtype)
Definition: domain.c:318
int domain_examine_rrset_is_alone(domain_type *domain, ldns_rr_type rrtype)
Definition: domain.c:505
struct domain_struct * domain
Definition: denial.h:55
ods_status rrset_queue(rrset_type *rrset, fifoq_type *q, worker_type *worker)
Definition: rrset.c:1130
int domain_examine_rrset_is_singleton(domain_type *domain, ldns_rr_type rrtype)
Definition: domain.c:626
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:67
size_t rrset_count_RR(rrset_type *rrset)
Definition: rrset.c:229
int needs_signing
Definition: rrset.h:63
enum ods_enum_status ods_status
Definition: status.h:64
allocator_type * allocator
Definition: domain.h:75
domain_status dstatus
Definition: domain.h:74
void ods_log_error(const char *format,...)
Definition: log.c:349
void rrset_rollback(rrset_type *rrset)
Definition: rrset.c:708
void domain_dstatus(domain_type *domain)
Definition: domain.c:745
void rrset_backup(FILE *fd, rrset_type *rrset)
Definition: rrset.c:1257
int ods_strcmp(const char *s1, const char *s2)
Definition: file.c:317
ldns_rbtree_t * rrsets
Definition: domain.h:84
void rrset_print(FILE *fd, rrset_type *rrset, int skip_rrsigs)
Definition: rrset.c:1226
void log_rr(ldns_rr *rr, const char *pre, int level)
Definition: rrset.c:58
denial_type * denial
Definition: domain.h:81
ldns_rr * rrset_add_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:265
domain_type * parent
Definition: domain.h:78
rrset_type * domain_add_rrset(domain_type *domain, rrset_type *rrset)
Definition: domain.c:332
void domain_backup(FILE *fd, domain_type *domain)
Definition: domain.c:973
int domain_examine_ns_rdata(domain_type *domain, ldns_rdf *nsdname)
Definition: domain.c:845
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
Definition: allocator.c:48
ods_status domain_commit(domain_type *domain)
Definition: domain.c:663
ods_status rrset_recover(rrset_type *rrset, ldns_rr *rrsig, const char *locator, uint32_t flags)
Definition: rrset.c:149
ods_status rrset_diff(rrset_type *rrset, keylist_type *kl)
Definition: rrset.c:427
ods_status domain_queue(domain_type *domain, fifoq_type *q, worker_type *worker)
Definition: domain.c:790
#define COUNT_DEL
Definition: rrset.h:53
enum domain_status_enum domain_status
Definition: domain.h:58
uint8_t bitmap_changed
Definition: denial.h:56
ldns_rr_type rr_type
Definition: rrset.h:58
size_t domain_count_rrset(domain_type *domain)
Definition: domain.c:401
int rrset_examine_ns_rdata(rrset_type *rrset, ldns_rdf *nsdname)
Definition: rrset.c:209
int domain_examine_valid_zonecut(domain_type *domain)
Definition: domain.c:570
void allocator_cleanup(allocator_type *allocator)
Definition: allocator.c:153
denial_type * denial_create(ldns_rdf *owner)
Definition: denial.c:53
int backup_read_check_str(FILE *in, const char *str)
Definition: backup.c:74
void domain_print(FILE *fd, domain_type *domain)
Definition: domain.c:917
ods_status domain_diff(domain_type *domain, keylist_type *kl)
Definition: domain.c:430
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:136
int domain_examine_data_exists(domain_type *domain, ldns_rr_type rrtype, int skip_glue)
Definition: domain.c:465
ldns_dnssec_rrs * add
Definition: rrset.h:65
ods_status domain_recover(domain_type *domain, FILE *fd, domain_status dstatus)
Definition: domain.c:115
#define ods_log_assert(x)
Definition: log.h:141
rrset_type * rrset_create(ldns_rr_type rrtype)
Definition: rrset.c:101
ods_status rrset_commit(rrset_type *rrset)
Definition: rrset.c:653
void ods_log_warning(const char *format,...)
Definition: log.c:333
size_t rrset_count_rr(rrset_type *rrset, int which)
Definition: rrset.c:241
domain_type * domain_create(ldns_rdf *dname)
Definition: domain.c:67
ldns_dnssec_rrs * rrs
Definition: rrset.h:64
ldns_rdf * dname
Definition: domain.h:73
int backup_read_uint32_t(FILE *in, uint32_t *v)
Definition: backup.c:230
rrset_type * domain_del_rrset(domain_type *domain, rrset_type *rrset)
Definition: domain.c:364
void domain_rollback(domain_type *domain)
Definition: domain.c:720