00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include "config.h"
00035 #include "shared/duration.h"
00036 #include "shared/allocator.h"
00037 #include "shared/log.h"
00038 #include "shared/status.h"
00039 #include "shared/util.h"
00040 #include "signer/backup.h"
00041 #include "signer/domain.h"
00042 #include "signer/rrset.h"
00043
00044 #include <ldns/ldns.h>
00045
00046 static const char* dname_str = "domain";
00047
00048
00053 static int
00054 rrset_compare(const void* a, const void* b)
00055 {
00056 ldns_rr_type* x = (ldns_rr_type*)a;
00057 ldns_rr_type* y = (ldns_rr_type*)b;
00058 return (*x)-(*y);
00059 }
00060
00061
00066 domain_type*
00067 domain_create(ldns_rdf* dname)
00068 {
00069 allocator_type* allocator = NULL;
00070 domain_type* domain = NULL;
00071 char* str = NULL;
00072
00073 if (!dname) {
00074 ods_log_error("[%s] unable to create domain: no dname", dname_str);
00075 return NULL;
00076 }
00077 ods_log_assert(dname);
00078
00079 allocator = allocator_create(malloc, free);
00080 if (!allocator) {
00081 str = ldns_rdf2str(dname);
00082 ods_log_error("[%s] unable to create domain %s: create allocator "
00083 "failed", dname_str, str?str:"(null)");
00084 free((void*)str);
00085 return NULL;
00086 }
00087 ods_log_assert(allocator);
00088
00089 domain = (domain_type*) allocator_alloc(allocator, sizeof(domain_type));
00090 if (!domain) {
00091 str = ldns_rdf2str(dname);
00092 ods_log_error("[%s] unable to create domain %s: allocator failed",
00093 dname_str, str);
00094 free(str);
00095 allocator_cleanup(allocator);
00096 return NULL;
00097 }
00098 ods_log_assert(domain);
00099
00100 domain->allocator = allocator;
00101 domain->dname = ldns_rdf_clone(dname);
00102 domain->dstatus = DOMAIN_STATUS_NONE;
00103 domain->parent = NULL;
00104 domain->denial = NULL;
00105 domain->rrsets = ldns_rbtree_create(rrset_compare);
00106 return domain;
00107 }
00108
00109
00114 ods_status
00115 domain_recover(domain_type* domain, FILE* fd, domain_status dstatus)
00116 {
00117 const char* token = NULL;
00118 const char* locator = NULL;
00119 uint32_t flags = 0;
00120 ldns_rr* rr = NULL;
00121 rrset_type* rrset = NULL;
00122 ldns_status lstatus = LDNS_STATUS_OK;
00123 ldns_rr_type type_covered = LDNS_RR_TYPE_FIRST;
00124
00125 ods_log_assert(domain);
00126 ods_log_assert(fd);
00127
00128 domain->dstatus = dstatus;
00129
00130 while (backup_read_str(fd, &token)) {
00131 if (ods_strcmp(token, ";;RRSIG") == 0) {
00132
00133 if (!backup_read_str(fd, &locator) ||
00134 !backup_read_uint32_t(fd, &flags)) {
00135 ods_log_error("[%s] signature in backup corrupted",
00136 dname_str);
00137 goto recover_dname_error;
00138 }
00139
00140 lstatus = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL);
00141 if (lstatus != LDNS_STATUS_OK) {
00142 ods_log_error("[%s] missing signature in backup", dname_str);
00143 ods_log_error("[%s] ldns status: %s", dname_str,
00144 ldns_get_errorstr_by_id(lstatus));
00145 goto recover_dname_error;
00146 }
00147 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
00148 ods_log_error("[%s] expecting signature in backup", dname_str);
00149 ldns_rr_free(rr);
00150 goto recover_dname_error;
00151 }
00152
00153 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
00154 rrset = domain_lookup_rrset(domain, type_covered);
00155 if (!rrset) {
00156 ods_log_error("[%s] signature type %i not covered",
00157 dname_str, type_covered);
00158 ldns_rr_free(rr);
00159 goto recover_dname_error;
00160 }
00161 ods_log_assert(rrset);
00162 if (rrset_recover(rrset, rr, locator, flags) != ODS_STATUS_OK) {
00163 ods_log_error("[%s] unable to recover signature", dname_str);
00164 ldns_rr_free(rr);
00165 goto recover_dname_error;
00166 }
00167
00168 free((void*) locator);
00169 locator = NULL;
00170 rr = NULL;
00171 } else if (ods_strcmp(token, ";;Denial") == 0) {
00172
00173 lstatus = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL);
00174 if (lstatus != LDNS_STATUS_OK) {
00175 ods_log_error("[%s] missing denial in backup", dname_str);
00176 goto recover_dname_error;
00177 }
00178 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_NSEC &&
00179 ldns_rr_get_type(rr) != LDNS_RR_TYPE_NSEC3) {
00180 ods_log_error("[%s] expecting denial in backup", dname_str);
00181 ldns_rr_free(rr);
00182 goto recover_dname_error;
00183 }
00184
00185
00186 ods_log_assert(!domain->denial);
00187 domain->denial = denial_create(ldns_rr_owner(rr));
00188 ods_log_assert(domain->denial);
00189 domain->denial->domain = domain;
00190
00191 if (!domain->denial->rrset) {
00192 domain->denial->rrset = rrset_create(ldns_rr_get_type(rr));
00193 }
00194 ods_log_assert(domain->denial->rrset);
00195
00196 if (!rrset_add_rr(domain->denial->rrset, rr)) {
00197 ods_log_error("[%s] unable to recover denial", dname_str);
00198 ldns_rr_free(rr);
00199 goto recover_dname_error;
00200 }
00201
00202 if (rrset_commit(domain->denial->rrset) != ODS_STATUS_OK) {
00203 ods_log_error("[%s] unable to recover denial", dname_str);
00204 goto recover_dname_error;
00205 }
00206
00207 rr = NULL;
00208
00209
00210 if (!backup_read_check_str(fd, ";;RRSIG") ||
00211 !backup_read_str(fd, &locator) ||
00212 !backup_read_uint32_t(fd, &flags)) {
00213 ods_log_error("[%s] signature in backup corrupted (denial)",
00214 dname_str);
00215 goto recover_dname_error;
00216 }
00217
00218 lstatus = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL);
00219 if (lstatus != LDNS_STATUS_OK) {
00220 ods_log_error("[%s] missing signature in backup (denial)",
00221 dname_str);
00222 ods_log_error("[%s] ldns status: %s", dname_str,
00223 ldns_get_errorstr_by_id(lstatus));
00224 goto recover_dname_error;
00225 }
00226 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
00227 ods_log_error("[%s] expecting signature in backup (denial)",
00228 dname_str);
00229 ldns_rr_free(rr);
00230 goto recover_dname_error;
00231 }
00232 if (!domain->denial->rrset) {
00233 ods_log_error("[%s] signature type not covered (denial)",
00234 dname_str);
00235 ldns_rr_free(rr);
00236 goto recover_dname_error;
00237 }
00238 ods_log_assert(domain->denial->rrset);
00239 if (rrset_recover(domain->denial->rrset, rr, locator, flags) !=
00240 ODS_STATUS_OK) {
00241 ods_log_error("[%s] unable to recover signature (denial)",
00242 dname_str);
00243 ldns_rr_free(rr);
00244 goto recover_dname_error;
00245 }
00246
00247 free((void*) locator);
00248 locator = NULL;
00249 rr = NULL;
00250 } else if (ods_strcmp(token, ";;Domaindone") == 0) {
00251
00252 free((void*) token);
00253 token = NULL;
00254 break;
00255 } else {
00256
00257 goto recover_dname_error;
00258 }
00259
00260 free((void*) token);
00261 token = NULL;
00262 }
00263
00264 return ODS_STATUS_OK;
00265
00266 recover_dname_error:
00267 free((void*) token);
00268 token = NULL;
00269
00270 free((void*) locator);
00271 locator = NULL;
00272 return ODS_STATUS_ERR;
00273 }
00274
00275
00280 static ldns_rbnode_t*
00281 rrset2node(rrset_type* rrset)
00282 {
00283 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t));
00284 if (!node) {
00285 return NULL;
00286 }
00287 node->key = (const void*) &(rrset->rr_type);
00288 node->data = rrset;
00289 return node;
00290 }
00291
00292
00297 static rrset_type*
00298 domain_rrset_search(ldns_rbtree_t* tree, ldns_rr_type rrtype)
00299 {
00300 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00301
00302 if (!tree || !rrtype) {
00303 return NULL;
00304 }
00305 node = ldns_rbtree_search(tree, (const void*) &rrtype);
00306 if (node && node != LDNS_RBTREE_NULL) {
00307 return (rrset_type*) node->data;
00308 }
00309 return NULL;
00310 }
00311
00312
00317 rrset_type*
00318 domain_lookup_rrset(domain_type* domain, ldns_rr_type rrtype)
00319 {
00320 if (!domain || !rrtype) {
00321 return NULL;
00322 }
00323 return domain_rrset_search(domain->rrsets, rrtype);
00324 }
00325
00326
00331 rrset_type*
00332 domain_add_rrset(domain_type* domain, rrset_type* rrset)
00333 {
00334 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL;
00335
00336 if (!rrset) {
00337 ods_log_error("[%s] unable to add RRset: no RRset", dname_str);
00338 return NULL;
00339 }
00340 ods_log_assert(rrset);
00341
00342 if (!domain || !domain->rrsets) {
00343 ods_log_error("[%s] unable to add RRset: no storage", dname_str);
00344 return NULL;
00345 }
00346 ods_log_assert(domain);
00347 ods_log_assert(domain->rrsets);
00348
00349 new_node = rrset2node(rrset);
00350 if (ldns_rbtree_insert(domain->rrsets, new_node) == NULL) {
00351 ods_log_error("[%s] unable to add RRset: already present", dname_str);
00352 free((void*)new_node);
00353 return NULL;
00354 }
00355 return rrset;
00356 }
00357
00358
00363 rrset_type*
00364 domain_del_rrset(domain_type* domain, rrset_type* rrset)
00365 {
00366 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL;
00367 rrset_type* del_rrset = NULL;
00368
00369 if (!rrset) {
00370 ods_log_error("[%s] unable to delete RRset: no RRset", dname_str);
00371 return NULL;
00372 }
00373 ods_log_assert(rrset);
00374
00375 if (!domain || !domain->rrsets) {
00376 ods_log_error("[%s] unable to delete RRset: no storage", dname_str);
00377 return rrset;
00378 }
00379 ods_log_assert(domain);
00380 ods_log_assert(domain->rrsets);
00381
00382 del_node = ldns_rbtree_search(domain->rrsets,
00383 (const void*) &(rrset->rr_type));
00384 if (del_node) {
00385 del_node = ldns_rbtree_delete(domain->rrsets,
00386 (const void*) &(rrset->rr_type));
00387 del_rrset = (rrset_type*) del_node->data;
00388 rrset_cleanup(del_rrset);
00389 free((void*)del_node);
00390 return NULL;
00391 }
00392 return rrset;
00393 }
00394
00395
00400 size_t
00401 domain_count_rrset(domain_type* domain)
00402 {
00403 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00404 rrset_type* rrset = NULL;
00405 size_t count = 0;
00406
00407 if (!domain || !domain->rrsets) {
00408 return 0;
00409 }
00410
00411 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00412 node = ldns_rbtree_first(domain->rrsets);
00413 }
00414 while (node && node != LDNS_RBTREE_NULL) {
00415 rrset = (rrset_type*) node->data;
00416 if (rrset_count_rr(rrset, COUNT_RR) > 0) {
00417 count++;
00418 }
00419 node = ldns_rbtree_next(node);
00420 }
00421 return count;
00422 }
00423
00424
00429 ods_status
00430 domain_diff(domain_type* domain, keylist_type* kl)
00431 {
00432 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00433 rrset_type* rrset = NULL;
00434 ods_status status = ODS_STATUS_OK;
00435
00436 if (!domain || !domain->rrsets) {
00437 return status;
00438 }
00439 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00440 node = ldns_rbtree_first(domain->rrsets);
00441 }
00442 while (node && node != LDNS_RBTREE_NULL) {
00443 rrset = (rrset_type*) node->data;
00444
00445 if (rrset->rr_type == LDNS_RR_TYPE_NSEC3PARAMS) {
00446 node = ldns_rbtree_next(node);
00447 continue;
00448 }
00449
00450 status = rrset_diff(rrset, kl);
00451 if (status != ODS_STATUS_OK) {
00452 return status;
00453 }
00454 node = ldns_rbtree_next(node);
00455 }
00456 return status;
00457 }
00458
00459
00464 int
00465 domain_examine_data_exists(domain_type* domain, ldns_rr_type rrtype,
00466 int skip_glue)
00467 {
00468 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00469 rrset_type* rrset = NULL;
00470
00471 if (!domain) {
00472 return 0;
00473 }
00474 ods_log_assert(domain);
00475
00476 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00477 node = ldns_rbtree_first(domain->rrsets);
00478 }
00479 while (node && node != LDNS_RBTREE_NULL) {
00480 rrset = (rrset_type*) node->data;
00481 if (rrset_count_RR(rrset) > 0) {
00482 if (rrtype) {
00483
00484 if (rrset->rr_type == rrtype) {
00485 return 1;
00486 }
00487 } else if (!skip_glue ||
00488 (rrset->rr_type != LDNS_RR_TYPE_A &&
00489 rrset->rr_type != LDNS_RR_TYPE_AAAA)) {
00490
00491 return 1;
00492 }
00493 }
00494 node = ldns_rbtree_next(node);
00495 }
00496 return 0;
00497 }
00498
00499
00504 int
00505 domain_examine_rrset_is_alone(domain_type* domain, ldns_rr_type rrtype)
00506 {
00507 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00508 rrset_type* rrset = NULL;
00509 ldns_dnssec_rrs* rrs = NULL;
00510 char* str_name = NULL;
00511 char* str_type = NULL;
00512 size_t count = 0;
00513
00514 if (!domain || !rrtype) {
00515 return 1;
00516 }
00517 ods_log_assert(domain);
00518 ods_log_assert(rrtype);
00519
00520 rrset = domain_lookup_rrset(domain, rrtype);
00521 if (rrset) {
00522 count = rrset_count_RR(rrset);
00523 }
00524 if (count) {
00525 if (domain_count_rrset(domain) < 2) {
00526
00527 return 1;
00528 }
00529
00530 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00531 node = ldns_rbtree_first(domain->rrsets);
00532 }
00533 while (node && node != LDNS_RBTREE_NULL) {
00534 rrset = (rrset_type*) node->data;
00535 if (rrset->rr_type != rrtype && rrset_count_RR(rrset) > 0) {
00536
00537 str_name = ldns_rdf2str(domain->dname);
00538 str_type = ldns_rr_type2str(rrtype);
00539 ods_log_error("[%s] other data next to %s %s", dname_str, str_name, str_type);
00540 rrs = rrset->rrs;
00541 while (rrs) {
00542 if (rrs->rr) {
00543 log_rr(rrs->rr, "next-to-CNAME: ", 1);
00544 }
00545 rrs = rrs->next;
00546 }
00547 rrs = rrset->add;
00548 while (rrs) {
00549 if (rrs->rr) {
00550 log_rr(rrs->rr, "next-to-CNAME: ", 1);
00551 }
00552 rrs = rrs->next;
00553 }
00554 free((void*)str_name);
00555 free((void*)str_type);
00556 return 0;
00557 }
00558 node = ldns_rbtree_next(node);
00559 }
00560 }
00561 return 1;
00562 }
00563
00564
00569 int
00570 domain_examine_valid_zonecut(domain_type* domain)
00571 {
00572 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00573 rrset_type* rrset = NULL;
00574 size_t count = 0;
00575
00576 if (!domain) {
00577 return 1;
00578 }
00579 ods_log_assert(domain);
00580
00581 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS);
00582 if (rrset) {
00583 count = rrset_count_RR(rrset);
00584 }
00585
00586 if (count) {
00587
00588 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00589 node = ldns_rbtree_first(domain->rrsets);
00590 }
00591 while (node && node != LDNS_RBTREE_NULL) {
00592 rrset = (rrset_type*) node->data;
00593 if (rrset->rr_type != LDNS_RR_TYPE_DS &&
00594 rrset->rr_type != LDNS_RR_TYPE_NS &&
00595 rrset->rr_type != LDNS_RR_TYPE_A &&
00596 rrset->rr_type != LDNS_RR_TYPE_AAAA &&
00597 rrset_count_RR(rrset) > 0) {
00598
00599 ods_log_error("[%s] occluded glue data at zonecut, RRtype=%u",
00600 dname_str, rrset->rr_type);
00601 return 0;
00602 } else if (rrset->rr_type == LDNS_RR_TYPE_A ||
00603 rrset->rr_type == LDNS_RR_TYPE_AAAA) {
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 }
00614 node = ldns_rbtree_next(node);
00615 }
00616 }
00617 return 0;
00618 }
00619
00620
00625 int
00626 domain_examine_rrset_is_singleton(domain_type* domain, ldns_rr_type rrtype)
00627 {
00628 rrset_type* rrset = NULL;
00629 char* str_name = NULL;
00630 char* str_type = NULL;
00631 size_t count = 0;
00632
00633 if (!domain || !rrtype) {
00634 return 1;
00635 }
00636 ods_log_assert(domain);
00637 ods_log_assert(rrtype);
00638
00639 rrset = domain_lookup_rrset(domain, rrtype);
00640 if (rrset) {
00641 count = rrset_count_RR(rrset);
00642 }
00643
00644 if (count > 1) {
00645
00646 str_name = ldns_rdf2str(domain->dname);
00647 str_type = ldns_rr_type2str(rrtype);
00648 ods_log_error("[%s] multiple records for singleton type at %s %s",
00649 dname_str, str_name, str_type);
00650 free((void*)str_name);
00651 free((void*)str_type);
00652 return 0;
00653 }
00654 return 1;
00655 }
00656
00657
00662 ods_status
00663 domain_commit(domain_type* domain)
00664 {
00665 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00666 rrset_type* rrset = NULL;
00667 ods_status status = ODS_STATUS_OK;
00668 size_t numadd = 0;
00669 size_t numdel = 0;
00670 size_t numrrs = 0;
00671 size_t numnew = 0;
00672
00673 if (!domain || !domain->rrsets) {
00674 return ODS_STATUS_OK;
00675 }
00676 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00677 node = ldns_rbtree_first(domain->rrsets);
00678 }
00679 while (node && node != LDNS_RBTREE_NULL) {
00680 rrset = (rrset_type*) node->data;
00681 numrrs = rrset_count_rr(rrset, COUNT_RR);
00682 numadd = rrset_count_rr(rrset, COUNT_ADD);
00683 numdel = rrset_count_rr(rrset, COUNT_DEL);
00684
00685 if (rrset->rr_type == LDNS_RR_TYPE_SOA && rrset->rrs &&
00686 rrset->rrs->rr) {
00687 rrset->needs_signing = 1;
00688 }
00689 status = rrset_commit(rrset);
00690 if (status != ODS_STATUS_OK) {
00691 return status;
00692 }
00693 node = ldns_rbtree_next(node);
00694 numnew = rrset_count_rr(rrset, COUNT_RR);
00695
00696 if (numrrs > 0 && numnew <= 0) {
00697 if (domain_del_rrset(domain, rrset) != NULL) {
00698 ods_log_warning("[%s] unable to commit: failed ",
00699 "to delete RRset", dname_str);
00700 return ODS_STATUS_UNCHANGED;
00701 }
00702 if (domain->denial) {
00703 domain->denial->bitmap_changed = 1;
00704 }
00705 } else if (numrrs <= 0 && numnew == numadd) {
00706 if (domain->denial) {
00707 domain->denial->bitmap_changed = 1;
00708 }
00709 }
00710 }
00711 return status;
00712 }
00713
00714
00719 void
00720 domain_rollback(domain_type* domain)
00721 {
00722 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00723 rrset_type* rrset = NULL;
00724
00725 if (!domain || !domain->rrsets) {
00726 return;
00727 }
00728 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00729 node = ldns_rbtree_first(domain->rrsets);
00730 }
00731 while (node && node != LDNS_RBTREE_NULL) {
00732 rrset = (rrset_type*) node->data;
00733 rrset_rollback(rrset);
00734 node = ldns_rbtree_next(node);
00735 }
00736 return;
00737 }
00738
00739
00744 void
00745 domain_dstatus(domain_type* domain)
00746 {
00747 domain_type* parent = NULL;
00748
00749 if (!domain) {
00750 ods_log_error("[%s] unable to set status: no domain", dname_str);
00751 return;
00752 }
00753 if (domain->dstatus == DOMAIN_STATUS_APEX) {
00754
00755 return;
00756 }
00757 if (domain_count_rrset(domain) <= 0) {
00758 domain->dstatus = DOMAIN_STATUS_ENT;
00759 return;
00760 }
00761
00762 if (domain_lookup_rrset(domain, LDNS_RR_TYPE_NS)) {
00763 if (domain_lookup_rrset(domain, LDNS_RR_TYPE_DS)) {
00764 domain->dstatus = DOMAIN_STATUS_DS;
00765 } else {
00766 domain->dstatus = DOMAIN_STATUS_NS;
00767 }
00768 } else {
00769 domain->dstatus = DOMAIN_STATUS_AUTH;
00770 }
00771
00772 parent = domain->parent;
00773 while (parent && parent->dstatus != DOMAIN_STATUS_APEX) {
00774 if (domain_lookup_rrset(parent, LDNS_RR_TYPE_DNAME) ||
00775 domain_lookup_rrset(parent, LDNS_RR_TYPE_NS)) {
00776 domain->dstatus = DOMAIN_STATUS_OCCLUDED;
00777 return;
00778 }
00779 parent = parent->parent;
00780 }
00781 return;
00782 }
00783
00784
00789 ods_status
00790 domain_queue(domain_type* domain, fifoq_type* q, worker_type* worker)
00791 {
00792 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00793 rrset_type* rrset = NULL;
00794 ods_status status = ODS_STATUS_OK;
00795
00796 if (!domain || !domain->rrsets) {
00797 return ODS_STATUS_OK;
00798 }
00799 if (domain->dstatus == DOMAIN_STATUS_NONE ||
00800 domain->dstatus == DOMAIN_STATUS_OCCLUDED) {
00801 return ODS_STATUS_OK;
00802 }
00803
00804 if (domain->rrsets->root != LDNS_RBTREE_NULL) {
00805 node = ldns_rbtree_first(domain->rrsets);
00806 }
00807 while (node && node != LDNS_RBTREE_NULL) {
00808 rrset = (rrset_type*) node->data;
00809
00810
00811 if (domain->dstatus != DOMAIN_STATUS_APEX &&
00812 rrset->rr_type == LDNS_RR_TYPE_NS) {
00813 node = ldns_rbtree_next(node);
00814 continue;
00815 }
00816
00817 if ((domain->dstatus == DOMAIN_STATUS_DS ||
00818 domain->dstatus == DOMAIN_STATUS_NS) &&
00819 (rrset->rr_type == LDNS_RR_TYPE_A ||
00820 rrset->rr_type == LDNS_RR_TYPE_AAAA)) {
00821 node = ldns_rbtree_next(node);
00822 continue;
00823 }
00824
00825 status = rrset_queue(rrset, q, worker);
00826 if (status != ODS_STATUS_OK) {
00827 return status;
00828 }
00829 node = ldns_rbtree_next(node);
00830 }
00831
00832
00833 if (domain->denial && domain->denial->rrset) {
00834 status = rrset_queue(domain->denial->rrset, q, worker);
00835 }
00836 return status;
00837 }
00838
00839
00844 int
00845 domain_examine_ns_rdata(domain_type* domain, ldns_rdf* nsdname)
00846 {
00847 rrset_type* rrset = NULL;
00848
00849 if (!domain || !nsdname) {
00850 return 0;
00851 }
00852 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS);
00853 if (rrset) {
00854 if (rrset_examine_ns_rdata(rrset, nsdname)) {
00855 return 1;
00856 }
00857 }
00858 return 0;
00859 }
00860
00861
00866 static void
00867 rrset_delfunc(ldns_rbnode_t* elem)
00868 {
00869 rrset_type* rrset;
00870
00871 if (elem && elem != LDNS_RBTREE_NULL) {
00872 rrset = (rrset_type*) elem->data;
00873 rrset_delfunc(elem->left);
00874 rrset_delfunc(elem->right);
00875
00876 rrset_cleanup(rrset);
00877 free(elem);
00878 }
00879 return;
00880 }
00881
00882
00887 void
00888 domain_cleanup(domain_type* domain)
00889 {
00890 allocator_type* allocator;
00891
00892 if (!domain) {
00893 return;
00894 }
00895 allocator = domain->allocator;
00896
00897 if (domain->dname) {
00898 ldns_rdf_deep_free(domain->dname);
00899 domain->dname = NULL;
00900 }
00901 if (domain->rrsets) {
00902 rrset_delfunc(domain->rrsets->root);
00903 ldns_rbtree_free(domain->rrsets);
00904 domain->rrsets = NULL;
00905 }
00906 allocator_deallocate(allocator, (void*) domain);
00907 allocator_cleanup(allocator);
00908 return;
00909 }
00910
00911
00916 void
00917 domain_print(FILE* fd, domain_type* domain)
00918 {
00919 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00920 int print_glue = 0;
00921 rrset_type* rrset = NULL;
00922 rrset_type* soa_rrset = NULL;
00923 rrset_type* cname_rrset = NULL;
00924
00925 if (!domain || !fd) {
00926 return;
00927 }
00928 ods_log_assert(fd);
00929 ods_log_assert(domain);
00930
00931 if (domain->rrsets) {
00932 node = ldns_rbtree_first(domain->rrsets);
00933 }
00934
00935 cname_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_CNAME);
00936 if (cname_rrset) {
00937 rrset_print(fd, cname_rrset, 0);
00938 } else {
00939
00940 if (domain->dstatus == DOMAIN_STATUS_APEX) {
00941 soa_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_SOA);
00942 if (soa_rrset) {
00943 rrset_print(fd, soa_rrset, 0);
00944 }
00945 }
00946
00947 while (node && node != LDNS_RBTREE_NULL) {
00948 rrset = (rrset_type*) node->data;
00949
00950 if (rrset->rr_type != LDNS_RR_TYPE_SOA) {
00951 if (domain->dstatus == DOMAIN_STATUS_OCCLUDED) {
00952
00953 print_glue = 1;
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 if (print_glue && (rrset->rr_type == LDNS_RR_TYPE_A ||
00965 rrset->rr_type == LDNS_RR_TYPE_AAAA)) {
00966 rrset_print(fd, rrset, 0);
00967 }
00968 } else {
00969 rrset_print(fd, rrset, 0);
00970 }
00971 }
00972 node = ldns_rbtree_next(node);
00973 }
00974 }
00975
00976 if (domain->denial) {
00977 rrset_print(fd, domain->denial->rrset, 0);
00978 }
00979 return;
00980 }
00981
00982
00987 void
00988 domain_backup(FILE* fd, domain_type* domain)
00989 {
00990 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
00991 char* str = NULL;
00992 rrset_type* rrset = NULL;
00993
00994 if (!domain || !fd) {
00995 return;
00996 }
00997
00998 str = ldns_rdf2str(domain->dname);
00999 if (domain->rrsets) {
01000 node = ldns_rbtree_first(domain->rrsets);
01001 }
01002
01003 fprintf(fd, ";;Domain: name %s status %i\n", str, (int) domain->dstatus);
01004 while (node && node != LDNS_RBTREE_NULL) {
01005 rrset = (rrset_type*) node->data;
01006 rrset_backup(fd, rrset);
01007 node = ldns_rbtree_next(node);
01008 }
01009 free((void*)str);
01010
01011
01012 if (domain->denial) {
01013 fprintf(fd, ";;Denial\n");
01014 rrset_print(fd, domain->denial->rrset, 1);
01015 rrset_backup(fd, domain->denial->rrset);
01016 }
01017
01018 fprintf(fd, ";;Domaindone\n");
01019 return;
01020 }