OpenDNSSEC-signer 1.3.0rc3
|
00001 /* 00002 * $Id: zonedata.c 5227 2011-06-12 08:51:24Z jakob $ 00003 * 00004 * Copyright (c) 2009 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00034 #include "config.h" 00035 #include "adapter/adapter.h" 00036 #include "shared/allocator.h" 00037 #include "shared/log.h" 00038 #include "shared/util.h" 00039 #include "signer/backup.h" 00040 #include "signer/domain.h" 00041 #include "signer/nsec3params.h" 00042 #include "signer/zonedata.h" 00043 00044 #include <ldns/ldns.h> /* ldns_dname_*(), ldns_rbtree_*() */ 00045 00046 static const char* zd_str = "data"; 00047 00048 static ldns_rbnode_t* domain2node(domain_type* domain); 00049 00054 void 00055 log_rdf(ldns_rdf *rdf, const char* pre, int level) 00056 { 00057 char* str = NULL; 00058 00059 if (ods_log_get_level() < level + 2) return; 00060 00061 str = ldns_rdf2str(rdf); 00062 00063 if (level == 1) { 00064 ods_log_error("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00065 } else if (level == 2) { 00066 ods_log_warning("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00067 } else if (level == 3) { 00068 ods_log_info("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00069 } else if (level == 4) { 00070 ods_log_verbose("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00071 } else if (level == 5) { 00072 ods_log_debug("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00073 } else if (level == 6) { 00074 ods_log_deeebug("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00075 } else { 00076 ods_log_deeebug("[%s] %s : %s", zd_str, pre?pre:"", str?str:"(null)"); 00077 } 00078 00079 free((void*)str); 00080 00081 return; 00082 } 00083 00084 00089 static ldns_rbnode_t* 00090 domain2node(domain_type* domain) 00091 { 00092 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t)); 00093 if (!node) { 00094 return NULL; 00095 } 00096 node->key = domain->dname; 00097 node->data = domain; 00098 return node; 00099 } 00100 00101 00106 static ldns_rbnode_t* 00107 denial2node(denial_type* denial) 00108 { 00109 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t)); 00110 if (!node) { 00111 return NULL; 00112 } 00113 node->key = denial->owner; 00114 node->data = denial; 00115 return node; 00116 } 00117 00118 00123 static int 00124 domain_compare(const void* a, const void* b) 00125 { 00126 ldns_rdf* x = (ldns_rdf*)a; 00127 ldns_rdf* y = (ldns_rdf*)b; 00128 return ldns_dname_compare(x, y); 00129 } 00130 00131 00136 void 00137 zonedata_init_denial(zonedata_type* zd) 00138 { 00139 if (zd) { 00140 zd->denial_chain = ldns_rbtree_create(domain_compare); 00141 } 00142 return; 00143 } 00144 00145 00150 static void 00151 zonedata_init_domains(zonedata_type* zd) 00152 { 00153 if (zd) { 00154 zd->domains = ldns_rbtree_create(domain_compare); 00155 } 00156 return; 00157 } 00158 00159 00164 zonedata_type* 00165 zonedata_create(allocator_type* allocator) 00166 { 00167 zonedata_type* zd = NULL; 00168 00169 if (!allocator) { 00170 ods_log_error("[%s] cannot create zonedata: no allocator", zd_str); 00171 return NULL; 00172 } 00173 ods_log_assert(allocator); 00174 00175 zd = (zonedata_type*) allocator_alloc(allocator, sizeof(zonedata_type)); 00176 if (!zd) { 00177 ods_log_error("[%s] cannot create zonedata: allocator failed", 00178 zd_str); 00179 return NULL; 00180 } 00181 ods_log_assert(zd); 00182 00183 zd->allocator = allocator; 00184 zonedata_init_domains(zd); 00185 zonedata_init_denial(zd); 00186 zd->initialized = 0; 00187 zd->inbound_serial = 0; 00188 zd->internal_serial = 0; 00189 zd->outbound_serial = 0; 00190 zd->default_ttl = 3600; /* TODO: configure --default-ttl option? */ 00191 return zd; 00192 } 00193 00194 00199 ods_status 00200 zonedata_recover(zonedata_type* zd, FILE* fd) 00201 { 00202 const char* token = NULL; 00203 const char* owner = NULL; 00204 int dstatus = 0; 00205 ods_status status = ODS_STATUS_OK; 00206 domain_type* domain = NULL; 00207 ldns_rdf* rdf = NULL; 00208 ldns_rbnode_t* denial_node = LDNS_RBTREE_NULL; 00209 00210 ods_log_assert(zd); 00211 ods_log_assert(fd); 00212 00213 while (backup_read_str(fd, &token)) { 00214 /* domain part */ 00215 if (ods_strcmp(token, ";;Domain:") == 0) { 00216 if (!backup_read_check_str(fd, "name") || 00217 !backup_read_str(fd, &owner) || 00218 !backup_read_check_str(fd, "status") || 00219 !backup_read_int(fd, &dstatus)) { 00220 ods_log_error("[%s] domain in backup corrupted", zd_str); 00221 goto recover_domain_error; 00222 } 00223 /* ok, look up domain */ 00224 rdf = ldns_dname_new_frm_str(owner); 00225 if (rdf) { 00226 domain = zonedata_lookup_domain(zd, rdf); 00227 ldns_rdf_deep_free(rdf); 00228 rdf = NULL; 00229 } 00230 if (!domain) { 00231 ods_log_error("[%s] domain in backup, but not in zonedata", 00232 zd_str); 00233 goto recover_domain_error; 00234 } 00235 /* lookup success */ 00236 status = domain_recover(domain, fd, dstatus); 00237 if (status != ODS_STATUS_OK) { 00238 ods_log_error("[%s] unable to recover domain", zd_str); 00239 goto recover_domain_error; 00240 } 00241 if (domain->denial) { 00242 denial_node = denial2node(domain->denial); 00243 /* insert */ 00244 if (!ldns_rbtree_insert(zd->denial_chain, denial_node)) { 00245 ods_log_error("[%s] unable to recover denial", zd_str); 00246 free((void*)denial_node); 00247 goto recover_domain_error; 00248 } 00249 denial_node = NULL; 00250 } 00251 00252 /* done, next domain */ 00253 free((void*) owner); 00254 owner = NULL; 00255 domain = NULL; 00256 } else if (ods_strcmp(token, ";;") == 0) { 00257 /* done with all zone data */ 00258 free((void*) token); 00259 token = NULL; 00260 return ODS_STATUS_OK; 00261 } else { 00262 /* domain corrupted */ 00263 ods_log_error("[%s] domain in backup corrupted", zd_str); 00264 goto recover_domain_error; 00265 } 00266 free((void*) token); 00267 token = NULL; 00268 } 00269 00270 if (!backup_read_check_str(fd, ODS_SE_FILE_MAGIC)) { 00271 goto recover_domain_error; 00272 } 00273 00274 return ODS_STATUS_OK; 00275 00276 recover_domain_error: 00277 free((void*) owner); 00278 owner = NULL; 00279 00280 free((void*) token); 00281 token = NULL; 00282 00283 return ODS_STATUS_ERR; 00284 } 00285 00286 00291 /* 00292 int 00293 zonedata_recover_rr_from_backup(zonedata_type* zd, ldns_rr* rr) 00294 { 00295 domain_type* domain = NULL; 00296 00297 ods_log_assert(zd); 00298 ods_log_assert(zd->domains); 00299 ods_log_assert(rr); 00300 00301 domain = zonedata_lookup_domain(zd, ldns_rr_owner(rr)); 00302 if (domain) { 00303 return domain_recover_rr_from_backup(domain, rr); 00304 } 00305 00306 ods_log_error("[%s] unable to recover RR to zonedata: domain does not exist", 00307 zd_str); 00308 return 1; 00309 } 00310 */ 00311 00316 /* 00317 int 00318 zonedata_recover_rrsig_from_backup(zonedata_type* zd, ldns_rr* rrsig, 00319 const char* locator, uint32_t flags) 00320 { 00321 domain_type* domain = NULL; 00322 ldns_rr_type type_covered; 00323 00324 ods_log_assert(zd); 00325 ods_log_assert(zd->domains); 00326 ods_log_assert(rrsig); 00327 00328 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)); 00329 domain = zonedata_lookup_domain(zd, ldns_rr_owner(rrsig)); 00330 if (domain) { 00331 return domain_recover_rrsig_from_backup(domain, rrsig, type_covered, 00332 locator, flags); 00333 } 00334 ods_log_error("[%s] unable to recover RRSIG to zonedata: domain does not " 00335 "exist", zd_str); 00336 return 1; 00337 } 00338 */ 00339 00340 00345 static domain_type* 00346 zonedata_domain_search(ldns_rbtree_t* tree, ldns_rdf* dname) 00347 { 00348 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00349 00350 if (!tree || !dname) { 00351 return NULL; 00352 } 00353 node = ldns_rbtree_search(tree, dname); 00354 if (node && node != LDNS_RBTREE_NULL) { 00355 return (domain_type*) node->data; 00356 } 00357 return NULL; 00358 } 00359 00360 00365 domain_type* 00366 zonedata_lookup_domain(zonedata_type* zd, ldns_rdf* dname) 00367 { 00368 if (!zd) return NULL; 00369 00370 return zonedata_domain_search(zd->domains, dname); 00371 } 00372 00373 00378 domain_type* 00379 zonedata_add_domain(zonedata_type* zd, domain_type* domain) 00380 { 00381 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00382 00383 if (!domain) { 00384 ods_log_error("[%s] unable to add domain: no domain", zd_str); 00385 return NULL; 00386 } 00387 ods_log_assert(domain); 00388 00389 if (!zd || !zd->domains) { 00390 log_rdf(domain->dname, "unable to add domain, no storage", 1); 00391 return NULL; 00392 } 00393 ods_log_assert(zd); 00394 ods_log_assert(zd->domains); 00395 00396 new_node = domain2node(domain); 00397 if (ldns_rbtree_insert(zd->domains, new_node) == NULL) { 00398 log_rdf(domain->dname, "unable to add domain, already present", 1); 00399 free((void*)new_node); 00400 return NULL; 00401 } 00402 log_rdf(domain->dname, "+DD", 6); 00403 return domain; 00404 } 00405 00406 00411 static domain_type* 00412 zonedata_del_domain_fixup(ldns_rbtree_t* tree, domain_type* domain) 00413 { 00414 domain_type* del_domain = NULL; 00415 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL; 00416 00417 ods_log_assert(tree); 00418 ods_log_assert(domain); 00419 ods_log_assert(domain->dname); 00420 00421 del_node = ldns_rbtree_search(tree, (const void*)domain->dname); 00422 if (del_node) { 00423 del_node = ldns_rbtree_delete(tree, (const void*)domain->dname); 00424 del_domain = (domain_type*) del_node->data; 00425 domain_cleanup(del_domain); 00426 free((void*)del_node); 00427 return NULL; 00428 } else { 00429 log_rdf(domain->dname, "unable to del domain, not found", 1); 00430 } 00431 return domain; 00432 } 00433 00434 00439 domain_type* 00440 zonedata_del_domain(zonedata_type* zd, domain_type* domain) 00441 { 00442 if (!domain) { 00443 ods_log_error("[%s] unable to delete domain: no domain", zd_str); 00444 return NULL; 00445 } 00446 ods_log_assert(domain); 00447 ods_log_assert(domain->dname); 00448 00449 if (!zd || !zd->domains) { 00450 log_rdf(domain->dname, "unable to delete domain, no zonedata", 1); 00451 return domain; 00452 } 00453 ods_log_assert(zd); 00454 ods_log_assert(zd->domains); 00455 00456 if (domain->denial && zonedata_del_denial(zd, domain->denial) != NULL) { 00457 log_rdf(domain->dname, "unable to delete domain, failed to delete " 00458 "denial of existence data point", 1); 00459 return domain; 00460 } 00461 log_rdf(domain->dname, "-DD", 6); 00462 return zonedata_del_domain_fixup(zd->domains, domain); 00463 } 00464 00465 00470 static denial_type* 00471 zonedata_denial_search(ldns_rbtree_t* tree, ldns_rdf* dname) 00472 { 00473 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00474 00475 if (!tree || !dname) { 00476 return NULL; 00477 } 00478 node = ldns_rbtree_search(tree, dname); 00479 if (node && node != LDNS_RBTREE_NULL) { 00480 return (denial_type*) node->data; 00481 } 00482 return NULL; 00483 } 00484 00485 00490 denial_type* 00491 zonedata_lookup_denial(zonedata_type* zd, ldns_rdf* dname) 00492 { 00493 if (!zd) return NULL; 00494 00495 return zonedata_denial_search(zd->denial_chain, dname); 00496 } 00497 00498 00503 static ldns_rdf* 00504 dname_hash(ldns_rdf* dname, ldns_rdf* apex, nsec3params_type* nsec3params) 00505 { 00506 ldns_rdf* hashed_ownername = NULL; 00507 ldns_rdf* hashed_label = NULL; 00508 00509 ods_log_assert(dname); 00510 ods_log_assert(apex); 00511 ods_log_assert(nsec3params); 00512 00517 hashed_label = ldns_nsec3_hash_name(dname, nsec3params->algorithm, 00518 nsec3params->iterations, nsec3params->salt_len, 00519 nsec3params->salt_data); 00520 if (!hashed_label) { 00521 log_rdf(dname, "unable to hash dname, hash failed", 1); 00522 return NULL; 00523 } 00524 hashed_ownername = ldns_dname_cat_clone((const ldns_rdf*) hashed_label, 00525 (const ldns_rdf*) apex); 00526 if (!hashed_ownername) { 00527 log_rdf(dname, "unable to hash dname, concat apex failed", 1); 00528 return NULL; 00529 } 00530 ldns_rdf_deep_free(hashed_label); 00531 return hashed_ownername; 00532 } 00533 00534 00539 ods_status 00540 zonedata_add_denial(zonedata_type* zd, domain_type* domain, ldns_rdf* apex, 00541 nsec3params_type* nsec3params) 00542 { 00543 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00544 ldns_rbnode_t* prev_node = LDNS_RBTREE_NULL; 00545 ldns_rdf* owner = NULL; 00546 denial_type* denial = NULL; 00547 denial_type* prev_denial = NULL; 00548 00549 if (!domain) { 00550 ods_log_error("[%s] unable to add denial of existence data point: " 00551 "no domain", zd_str); 00552 return ODS_STATUS_ASSERT_ERR; 00553 } 00554 ods_log_assert(domain); 00555 00556 if (!zd || !zd->denial_chain) { 00557 log_rdf(domain->dname, "unable to add denial of existence data " 00558 "point for domain, no denial chain", 1); 00559 return ODS_STATUS_ASSERT_ERR; 00560 } 00561 ods_log_assert(zd); 00562 ods_log_assert(zd->denial_chain); 00563 00564 if (!apex) { 00565 log_rdf(domain->dname, "unable to add denial of existence data " 00566 "point for domain, apex unknown", 1); 00567 return ODS_STATUS_ASSERT_ERR; 00568 } 00569 ods_log_assert(apex); 00570 00571 /* nsec or nsec3 */ 00572 if (nsec3params) { 00573 owner = dname_hash(domain->dname, apex, nsec3params); 00574 if (!owner) { 00575 log_rdf(domain->dname, "unable to add denial of existence data " 00576 "point for domain, dname hash failed", 1); 00577 return ODS_STATUS_ERR; 00578 } 00579 } else { 00580 owner = ldns_rdf_clone(domain->dname); 00581 } 00582 /* lookup */ 00583 if (zonedata_lookup_denial(zd, owner) != NULL) { 00584 log_rdf(domain->dname, "unable to add denial of existence for " 00585 "domain, data point exists", 1); 00586 return ODS_STATUS_CONFLICT_ERR; 00587 } 00588 /* create */ 00589 denial = denial_create(owner); 00590 new_node = denial2node(denial); 00591 ldns_rdf_deep_free(owner); 00592 /* insert */ 00593 if (!ldns_rbtree_insert(zd->denial_chain, new_node)) { 00594 log_rdf(domain->dname, "unable to add denial of existence for " 00595 "domain, insert failed", 1); 00596 free((void*)new_node); 00597 denial_cleanup(denial); 00598 return ODS_STATUS_ERR; 00599 } 00600 /* denial of existence data point added */ 00601 denial->bitmap_changed = 1; 00602 denial->nxt_changed = 1; 00603 prev_node = ldns_rbtree_previous(new_node); 00604 if (!prev_node || prev_node == LDNS_RBTREE_NULL) { 00605 prev_node = ldns_rbtree_last(zd->denial_chain); 00606 } 00607 ods_log_assert(prev_node); 00608 prev_denial = (denial_type*) prev_node->data; 00609 ods_log_assert(prev_denial); 00610 prev_denial->nxt_changed = 1; 00611 domain->denial = denial; 00612 domain->denial->domain = domain; /* back reference */ 00613 return ODS_STATUS_OK; 00614 } 00615 00616 00621 static denial_type* 00622 zonedata_del_denial_fixup(ldns_rbtree_t* tree, denial_type* denial) 00623 { 00624 denial_type* del_denial = NULL; 00625 denial_type* prev_denial = NULL; 00626 ldns_rbnode_t* prev_node = LDNS_RBTREE_NULL; 00627 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL; 00628 ods_status status = ODS_STATUS_OK; 00629 00630 ods_log_assert(tree); 00631 ods_log_assert(denial); 00632 ods_log_assert(denial->owner); 00633 00634 del_node = ldns_rbtree_search(tree, (const void*)denial->owner); 00635 if (del_node) { 00640 prev_node = ldns_rbtree_previous(del_node); 00641 if (!prev_node || prev_node == LDNS_RBTREE_NULL) { 00642 prev_node = ldns_rbtree_last(tree); 00643 } 00644 ods_log_assert(prev_node); 00645 ods_log_assert(prev_node->data); 00646 prev_denial = (denial_type*) prev_node->data; 00647 prev_denial->nxt_changed = 1; 00648 00649 /* delete old NSEC RR(s) */ 00650 if (denial->rrset) { 00651 status = rrset_wipe_out(denial->rrset); 00652 if (status != ODS_STATUS_OK) { 00653 ods_log_alert("[%s] unable to del denial of existence data " 00654 "point: failed to wipe out NSEC RRset", zd_str); 00655 return denial; 00656 } 00657 status = rrset_commit(denial->rrset); 00658 if (status != ODS_STATUS_OK) { 00659 ods_log_alert("[%s] unable to del denial of existence data " 00660 "point: failed to commit NSEC RRset", zd_str); 00661 return denial; 00662 } 00663 } 00664 00665 del_node = ldns_rbtree_delete(tree, (const void*)denial->owner); 00666 del_denial = (denial_type*) del_node->data; 00667 denial_cleanup(del_denial); 00668 free((void*)del_node); 00669 return NULL; 00670 } else { 00671 log_rdf(denial->owner, "unable to del denial of existence data " 00672 "point, not found", 1); 00673 } 00674 return denial; 00675 } 00676 00677 00682 denial_type* 00683 zonedata_del_denial(zonedata_type* zd, denial_type* denial) 00684 { 00685 if (!denial) { 00686 ods_log_error("[%s] unable to delete denial of existence data " 00687 "point: no data point", zd_str); 00688 return NULL; 00689 } 00690 ods_log_assert(denial); 00691 00692 if (!zd || !zd->denial_chain) { 00693 log_rdf(denial->owner, "unable to delete denial of existence data " 00694 "point, no zone data", 1); 00695 return denial; 00696 } 00697 ods_log_assert(zd); 00698 ods_log_assert(zd->denial_chain); 00699 00700 return zonedata_del_denial_fixup(zd->denial_chain, denial); 00701 } 00702 00703 00708 ods_status 00709 zonedata_diff(zonedata_type* zd, keylist_type* kl) 00710 { 00711 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00712 domain_type* domain = NULL; 00713 ods_status status = ODS_STATUS_OK; 00714 00715 if (!zd || !zd->domains) { 00716 return status; 00717 } 00718 if (zd->domains->root != LDNS_RBTREE_NULL) { 00719 node = ldns_rbtree_first(zd->domains); 00720 } 00721 while (node && node != LDNS_RBTREE_NULL) { 00722 domain = (domain_type*) node->data; 00723 status = domain_diff(domain, kl); 00724 if (status != ODS_STATUS_OK) { 00725 return status; 00726 } 00727 node = ldns_rbtree_next(node); 00728 } 00729 return status; 00730 } 00731 00732 00737 ods_status 00738 zonedata_commit(zonedata_type* zd) 00739 { 00740 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00741 ldns_rbnode_t* nxtnode = LDNS_RBTREE_NULL; 00742 ldns_rbnode_t* tmpnode = LDNS_RBTREE_NULL; 00743 domain_type* domain = NULL; 00744 domain_type* nxtdomain = NULL; 00745 ods_status status = ODS_STATUS_OK; 00746 size_t oldnum = 0; 00747 00748 if (!zd || !zd->domains) { 00749 return ODS_STATUS_OK; 00750 } 00751 if (zd->domains->root != LDNS_RBTREE_NULL) { 00752 node = ldns_rbtree_last(zd->domains); 00753 } 00754 while (node && node != LDNS_RBTREE_NULL) { 00755 domain = (domain_type*) node->data; 00756 oldnum = domain_count_rrset(domain); 00757 status = domain_commit(domain); 00758 if (status != ODS_STATUS_OK) { 00759 return status; 00760 } 00761 tmpnode = node; 00762 node = ldns_rbtree_previous(node); 00763 00764 /* delete memory if empty leaf domain */ 00765 if (domain_count_rrset(domain) <= 0) { 00766 /* empty domain */ 00767 nxtnode = ldns_rbtree_next(tmpnode); 00768 nxtdomain = NULL; 00769 if (nxtnode && nxtnode != LDNS_RBTREE_NULL) { 00770 nxtdomain = (domain_type*) nxtnode->data; 00771 } 00772 if (!nxtdomain || 00773 !ldns_dname_is_subdomain(nxtdomain->dname, domain->dname)) { 00774 /* leaf domain */ 00775 if (zonedata_del_domain(zd, domain) != NULL) { 00776 ods_log_warning("[%s] unable to delete obsoleted " 00777 "domain", zd_str); 00778 return ODS_STATUS_ERR; 00779 } 00780 } 00781 } /* if (domain_count_rrset(domain) <= 0) */ 00782 } 00783 return status; 00784 } 00785 00786 00791 void 00792 zonedata_rollback(zonedata_type* zd) 00793 { 00794 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00795 domain_type* domain = NULL; 00796 00797 if (!zd || !zd->domains) { 00798 return; 00799 } 00800 if (zd->domains->root != LDNS_RBTREE_NULL) { 00801 node = ldns_rbtree_first(zd->domains); 00802 } 00803 while (node && node != LDNS_RBTREE_NULL) { 00804 domain = (domain_type*) node->data; 00805 domain_rollback(domain); 00806 node = ldns_rbtree_next(node); 00807 } 00808 return; 00809 } 00810 00811 00816 static int 00817 domain_ent2glue(ldns_rbnode_t* node) 00818 { 00819 ldns_rbnode_t* nextnode = LDNS_RBTREE_NULL; 00820 domain_type* nextdomain = NULL; 00821 domain_type* domain = NULL; 00822 ods_log_assert(node && node != LDNS_RBTREE_NULL); 00823 domain = (domain_type*) node->data; 00824 if (domain->dstatus == DOMAIN_STATUS_ENT) { 00825 ods_log_assert(domain_count_rrset(domain) == 0); 00826 nextnode = ldns_rbtree_next(node); 00827 while (nextnode && nextnode != LDNS_RBTREE_NULL) { 00828 nextdomain = (domain_type*) nextnode->data; 00829 if (!ldns_dname_is_subdomain(nextdomain->dname, domain->dname)) { 00830 /* we are done, no non-glue found */ 00831 return 1; 00832 } 00833 if (nextdomain->dstatus != DOMAIN_STATUS_OCCLUDED && 00834 nextdomain->dstatus != DOMAIN_STATUS_ENT && 00835 nextdomain->dstatus != DOMAIN_STATUS_NONE) { 00836 /* found non-glue */ 00837 return 0; 00838 } 00839 nextnode = ldns_rbtree_next(nextnode); 00840 } 00841 } else { 00842 /* no empty non-terminal */ 00843 ods_log_assert(domain_count_rrset(domain) != 0); 00844 return 0; 00845 } 00846 /* no non-glue found */ 00847 return 1; 00848 } 00849 00850 00855 static int 00856 domain_ent2unsigned(ldns_rbnode_t* node) 00857 { 00858 ldns_rbnode_t* nextnode = LDNS_RBTREE_NULL; 00859 domain_type* nextdomain = NULL; 00860 domain_type* domain = NULL; 00861 ods_log_assert(node && node != LDNS_RBTREE_NULL); 00862 domain = (domain_type*) node->data; 00863 if (domain->dstatus == DOMAIN_STATUS_ENT) { 00864 ods_log_assert(domain_count_rrset(domain) == 0); 00865 nextnode = ldns_rbtree_next(node); 00866 while (nextnode && nextnode != LDNS_RBTREE_NULL) { 00867 nextdomain = (domain_type*) nextnode->data; 00868 if (!ldns_dname_is_subdomain(nextdomain->dname, domain->dname)) { 00869 /* we are done, no unsigned delegation found */ 00870 return 1; 00871 } 00872 if (nextdomain->dstatus != DOMAIN_STATUS_OCCLUDED && 00873 nextdomain->dstatus != DOMAIN_STATUS_ENT && 00874 nextdomain->dstatus != DOMAIN_STATUS_NS && 00875 nextdomain->dstatus != DOMAIN_STATUS_NONE) { 00876 /* found data that has to be signed */ 00877 return 0; 00878 } 00879 nextnode = ldns_rbtree_next(nextnode); 00880 } 00881 } else { 00882 /* no empty non-terminal */ 00883 ods_log_assert(domain_count_rrset(domain) != 0); 00884 return 0; 00885 } 00886 /* no unsigned delegation found */ 00887 return 1; 00888 } 00889 00890 00895 static ods_status 00896 domain_entize(zonedata_type* zd, domain_type* domain, ldns_rdf* apex) 00897 { 00898 ldns_rdf* parent_rdf = NULL; 00899 domain_type* parent_domain = NULL; 00900 00901 ods_log_assert(apex); 00902 ods_log_assert(domain); 00903 ods_log_assert(domain->dname); 00904 ods_log_assert(zd); 00905 ods_log_assert(zd->domains); 00906 00907 if (domain->parent) { 00908 /* domain already has parent */ 00909 return ODS_STATUS_OK; 00910 } 00911 00912 while (domain && ldns_dname_is_subdomain(domain->dname, apex) && 00913 ldns_dname_compare(domain->dname, apex) != 0) { 00914 00922 parent_rdf = ldns_dname_left_chop(domain->dname); 00923 if (!parent_rdf) { 00924 log_rdf(domain->dname, "unable to entize domain, left chop " 00925 "failed", 1); 00926 return ODS_STATUS_ERR; 00927 } 00928 ods_log_assert(parent_rdf); 00929 00930 parent_domain = zonedata_lookup_domain(zd, parent_rdf); 00931 if (!parent_domain) { 00932 parent_domain = domain_create(parent_rdf); 00933 ldns_rdf_deep_free(parent_rdf); 00934 if (!parent_domain) { 00935 log_rdf(domain->dname, "unable to entize domain, create " 00936 "parent failed", 1); 00937 return ODS_STATUS_ERR; 00938 } 00939 ods_log_assert(parent_domain); 00940 if (zonedata_add_domain(zd, parent_domain) == NULL) { 00941 log_rdf(domain->dname, "unable to entize domain, add parent " 00942 "failed", 1); 00943 domain_cleanup(parent_domain); 00944 return ODS_STATUS_ERR; 00945 } 00946 parent_domain->dstatus = DOMAIN_STATUS_ENT; 00947 domain->parent = parent_domain; 00948 /* continue with the parent domain */ 00949 domain = parent_domain; 00950 } else { 00951 ldns_rdf_deep_free(parent_rdf); 00952 domain->parent = parent_domain; 00953 /* we are done with this domain */ 00954 domain = NULL; 00955 } 00956 } 00957 return ODS_STATUS_OK; 00958 } 00959 00960 00965 ods_status 00966 zonedata_entize(zonedata_type* zd, ldns_rdf* apex) 00967 { 00968 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00969 ods_status status = ODS_STATUS_OK; 00970 domain_type* domain = NULL; 00971 00972 if (!zd || !zd->domains) { 00973 ods_log_error("[%s] unable to entize zone data: no zone data", 00974 zd_str); 00975 return ODS_STATUS_ASSERT_ERR; 00976 } 00977 ods_log_assert(zd); 00978 ods_log_assert(zd->domains); 00979 00980 if (!apex) { 00981 ods_log_error("[%s] unable to entize zone data: no zone apex", 00982 zd_str); 00983 return ODS_STATUS_ASSERT_ERR; 00984 } 00985 ods_log_assert(apex); 00986 00987 node = ldns_rbtree_first(zd->domains); 00988 while (node && node != LDNS_RBTREE_NULL) { 00989 domain = (domain_type*) node->data; 00990 status = domain_entize(zd, domain, apex); 00991 if (status != ODS_STATUS_OK) { 00992 ods_log_error("[%s] unable to entize zone data: entize domain " 00993 "failed", zd_str); 00994 return status; 00995 } 00996 domain_dstatus(domain); 00997 node = ldns_rbtree_next(node); 00998 } 00999 return ODS_STATUS_OK; 01000 } 01001 01002 01007 ods_status 01008 zonedata_nsecify(zonedata_type* zd, ldns_rr_class klass, uint32_t ttl, 01009 uint32_t* num_added) 01010 { 01011 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01012 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL; 01013 ods_status status = ODS_STATUS_OK; 01014 domain_type* domain = NULL; 01015 domain_type* apex = NULL; 01016 denial_type* denial = NULL; 01017 denial_type* nxt = NULL; 01018 size_t nsec_added = 0; 01019 01020 if (!zd || !zd->domains) { 01021 return ODS_STATUS_OK; 01022 } 01023 ods_log_assert(zd); 01024 ods_log_assert(zd->domains); 01025 01026 node = ldns_rbtree_first(zd->domains); 01027 while (node && node != LDNS_RBTREE_NULL) { 01028 domain = (domain_type*) node->data; 01029 if (domain->dstatus == DOMAIN_STATUS_APEX) { 01030 apex = domain; 01031 } 01032 /* don't do glue-only or empty domains */ 01033 if (domain->dstatus == DOMAIN_STATUS_NONE || 01034 domain->dstatus == DOMAIN_STATUS_ENT || 01035 domain->dstatus == DOMAIN_STATUS_OCCLUDED || 01036 domain_count_rrset(domain) <= 0) { 01037 if (domain_count_rrset(domain)) { 01038 log_rdf(domain->dname, "nsecify: don't do glue domain", 6); 01039 } else { 01040 log_rdf(domain->dname, "nsecify: don't do empty domain", 6); 01041 } 01042 if (domain->denial) { 01043 if (zonedata_del_denial(zd, domain->denial) != NULL) { 01044 ods_log_warning("[%s] unable to nsecify: failed to " 01045 "delete denial of existence data point", zd_str); 01046 return ODS_STATUS_ERR; 01047 } 01048 } 01049 node = ldns_rbtree_next(node); 01050 continue; 01051 } 01052 if (!apex) { 01053 ods_log_alert("[%s] unable to nsecify: apex unknown", zd_str); 01054 return ODS_STATUS_ASSERT_ERR; 01055 } 01056 01057 /* add the denial of existence */ 01058 if (!domain->denial) { 01059 status = zonedata_add_denial(zd, domain, apex->dname, NULL); 01060 if (status != ODS_STATUS_OK) { 01061 log_rdf(domain->dname, "unable to nsecify: failed to add " 01062 "denial of existence for domain", 1); 01063 return status; 01064 } 01065 nsec_added++; 01066 } 01067 node = ldns_rbtree_next(node); 01068 } 01069 01071 node = ldns_rbtree_first(zd->denial_chain); 01072 while (node && node != LDNS_RBTREE_NULL) { 01073 denial = (denial_type*) node->data; 01074 nxt_node = ldns_rbtree_next(node); 01075 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) { 01076 nxt_node = ldns_rbtree_first(zd->denial_chain); 01077 } 01078 nxt = (denial_type*) nxt_node->data; 01079 01080 status = denial_nsecify(denial, nxt, ttl, klass); 01081 if (status != ODS_STATUS_OK) { 01082 ods_log_error("[%s] unable to nsecify: failed to add NSEC record", 01083 zd_str); 01084 return status; 01085 } 01086 node = ldns_rbtree_next(node); 01087 } 01088 if (num_added) { 01089 *num_added = nsec_added; 01090 } 01091 return ODS_STATUS_OK; 01092 } 01093 01094 01099 ods_status 01100 zonedata_nsecify3(zonedata_type* zd, ldns_rr_class klass, 01101 uint32_t ttl, nsec3params_type* nsec3params, uint32_t* num_added) 01102 { 01103 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01104 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL; 01105 ods_status status = ODS_STATUS_OK; 01106 domain_type* domain = NULL; 01107 domain_type* apex = NULL; 01108 denial_type* denial = NULL; 01109 denial_type* nxt = NULL; 01110 size_t nsec3_added = 0; 01111 01112 if (!zd || !zd->domains) { 01113 return ODS_STATUS_OK; 01114 } 01115 ods_log_assert(zd); 01116 ods_log_assert(zd->domains); 01117 01118 if (!nsec3params) { 01119 ods_log_error("[%s] unable to nsecify3: no nsec3 paramaters", zd_str); 01120 return ODS_STATUS_ASSERT_ERR; 01121 } 01122 ods_log_assert(nsec3params); 01123 01124 node = ldns_rbtree_first(zd->domains); 01125 while (node && node != LDNS_RBTREE_NULL) { 01126 domain = (domain_type*) node->data; 01127 if (domain->dstatus == DOMAIN_STATUS_APEX) { 01128 apex = domain; 01129 } 01130 01131 /* don't do glue-only domains */ 01132 if (domain->dstatus == DOMAIN_STATUS_NONE || 01133 domain->dstatus == DOMAIN_STATUS_OCCLUDED || 01134 domain_ent2glue(node)) { 01135 log_rdf(domain->dname, "nsecify3: don't do glue domain" , 6); 01136 if (domain->denial) { 01137 if (zonedata_del_denial(zd, domain->denial) != NULL) { 01138 ods_log_error("[%s] unable to nsecify3: failed to " 01139 "delete denial of existence data point", zd_str); 01140 return ODS_STATUS_ERR; 01141 } 01142 } 01143 node = ldns_rbtree_next(node); 01144 continue; 01145 } 01146 /* Opt-Out? */ 01147 if (nsec3params->flags) { 01148 /* If Opt-Out is being used, owner names of unsigned delegations 01149 MAY be excluded. */ 01150 if (domain->dstatus == DOMAIN_STATUS_NS || 01151 domain_ent2unsigned(node)) { 01152 if (domain->dstatus == DOMAIN_STATUS_NS) { 01153 log_rdf(domain->dname, "nsecify3: opt-out (unsigned " 01154 "delegation)", 5); 01155 } else { 01156 log_rdf(domain->dname, "nsecify3: opt-out (empty " 01157 "non-terminal (to unsigned delegation))", 5); 01158 } 01159 if (domain->denial) { 01160 if (zonedata_del_denial(zd, domain->denial) != NULL) { 01161 ods_log_error("[%s] unable to nsecify3: failed to " 01162 "delete denial of existence data point", zd_str); 01163 return ODS_STATUS_ERR; 01164 } 01165 } 01166 node = ldns_rbtree_next(node); 01167 continue; 01168 } 01169 } 01170 if (!apex) { 01171 ods_log_alert("[%s] unable to nsecify3: apex unknown", zd_str); 01172 return ODS_STATUS_ASSERT_ERR; 01173 } 01174 01175 /* add the denial of existence */ 01176 if (!domain->denial) { 01177 status = zonedata_add_denial(zd, domain, apex->dname, 01178 nsec3params); 01179 if (status != ODS_STATUS_OK) { 01180 log_rdf(domain->dname, "unable to nsecify3: failed to add " 01181 "denial of existence for domain", 1); 01182 return status; 01183 } 01184 nsec3_added++; 01185 } 01186 01187 /* The Next Hashed Owner Name field is left blank for the moment. */ 01188 01196 /* [TODO] */ 01206 node = ldns_rbtree_next(node); 01207 } 01208 01210 node = ldns_rbtree_first(zd->denial_chain); 01211 while (node && node != LDNS_RBTREE_NULL) { 01212 denial = (denial_type*) node->data; 01213 nxt_node = ldns_rbtree_next(node); 01214 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) { 01215 nxt_node = ldns_rbtree_first(zd->denial_chain); 01216 } 01217 nxt = (denial_type*) nxt_node->data; 01218 01219 status = denial_nsecify3(denial, nxt, ttl, klass, nsec3params); 01220 if (status != ODS_STATUS_OK) { 01221 ods_log_error("[%s] unable to nsecify3: failed to add NSEC3 " 01222 "record", zd_str); 01223 return status; 01224 } 01225 node = ldns_rbtree_next(node); 01226 } 01227 if (num_added) { 01228 *num_added = nsec3_added; 01229 } 01230 return ODS_STATUS_OK; 01231 } 01232 01233 01238 ods_status 01239 zonedata_update_serial(zonedata_type* zd, signconf_type* sc) 01240 { 01241 uint32_t soa = 0; 01242 uint32_t prev = 0; 01243 uint32_t update = 0; 01244 01245 ods_log_assert(zd); 01246 ods_log_assert(sc); 01247 01248 prev = zd->outbound_serial; 01249 if (!zd->initialized) { 01250 prev = zd->inbound_serial; 01251 } 01252 ods_log_debug("[%s] update serial: in=%u internal=%u out=%u now=%u", 01253 zd_str, zd->inbound_serial, zd->internal_serial, zd->outbound_serial, 01254 (uint32_t) time_now()); 01255 01256 if (!sc->soa_serial) { 01257 ods_log_error("[%s] no serial type given", zd_str); 01258 return ODS_STATUS_ERR; 01259 } 01260 01261 if (ods_strcmp(sc->soa_serial, "unixtime") == 0) { 01262 soa = (uint32_t) time_now(); 01263 if (!DNS_SERIAL_GT(soa, prev)) { 01264 soa = prev + 1; 01265 } 01266 } else if (strncmp(sc->soa_serial, "counter", 7) == 0) { 01267 soa = zd->inbound_serial; 01268 if (zd->initialized && !DNS_SERIAL_GT(soa, prev)) { 01269 soa = prev + 1; 01270 } 01271 } else if (strncmp(sc->soa_serial, "datecounter", 11) == 0) { 01272 soa = (uint32_t) time_datestamp(0, "%Y%m%d", NULL) * 100; 01273 if (!DNS_SERIAL_GT(soa, prev)) { 01274 soa = prev + 1; 01275 } 01276 } else if (strncmp(sc->soa_serial, "keep", 4) == 0) { 01277 soa = zd->inbound_serial; 01278 if (zd->initialized && !DNS_SERIAL_GT(soa, prev)) { 01279 ods_log_error("[%s] cannot keep SOA SERIAL from input zone " 01280 " (%u): output SOA SERIAL is %u", zd_str, soa, prev); 01281 return ODS_STATUS_CONFLICT_ERR; 01282 } 01283 } else { 01284 ods_log_error("[%s] unknown serial type %s", zd_str, sc->soa_serial); 01285 return ODS_STATUS_ERR; 01286 } 01287 01288 /* serial is stored in 32 bits */ 01289 update = soa - prev; 01290 if (update > 0x7FFFFFFF) { 01291 update = 0x7FFFFFFF; 01292 } 01293 01294 if (!zd->initialized) { 01295 zd->internal_serial = soa; 01296 } else { 01297 zd->internal_serial += update; /* automatically does % 2^32 */ 01298 } 01299 ods_log_debug("[%s] update serial: %u + %u = %u", zd_str, prev, update, 01300 zd->internal_serial); 01301 return ODS_STATUS_OK; 01302 } 01303 01304 01309 ods_status 01310 zonedata_queue(zonedata_type* zd, fifoq_type* q, worker_type* worker) 01311 { 01312 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01313 domain_type* domain = NULL; 01314 ods_status status = ODS_STATUS_OK; 01315 01316 if (!zd || !zd->domains) { 01317 return ODS_STATUS_OK; 01318 } 01319 if (zd->domains->root != LDNS_RBTREE_NULL) { 01320 node = ldns_rbtree_first(zd->domains); 01321 } 01322 while (node && node != LDNS_RBTREE_NULL) { 01323 domain = (domain_type*) node->data; 01324 status = domain_queue(domain, q, worker); 01325 if (status != ODS_STATUS_OK) { 01326 return status; 01327 } 01328 node = ldns_rbtree_next(node); 01329 } 01330 return status; 01331 } 01332 01333 01338 static int 01339 zonedata_examine_domain_is_occluded(zonedata_type* zd, domain_type* domain, 01340 ldns_rdf* apex) 01341 { 01342 ldns_rdf* parent_rdf = NULL; 01343 ldns_rdf* next_rdf = NULL; 01344 domain_type* parent_domain = NULL; 01345 char* str_name = NULL; 01346 char* str_parent = NULL; 01347 01348 ods_log_assert(apex); 01349 ods_log_assert(domain); 01350 ods_log_assert(domain->dname); 01351 ods_log_assert(zd); 01352 ods_log_assert(zd->domains); 01353 01354 if (ldns_dname_compare(domain->dname, apex) == 0) { 01355 return 0; 01356 } 01357 01358 if (domain_examine_valid_zonecut(domain) != 0) { 01359 log_rdf(domain->dname, "occluded (non-glue non-DS) data at NS", 2); 01360 return 1; 01361 } 01362 01363 parent_rdf = ldns_dname_left_chop(domain->dname); 01364 while (parent_rdf && ldns_dname_is_subdomain(parent_rdf, apex) && 01365 ldns_dname_compare(parent_rdf, apex) != 0) { 01366 01367 parent_domain = zonedata_lookup_domain(zd, parent_rdf); 01368 next_rdf = ldns_dname_left_chop(parent_rdf); 01369 ldns_rdf_deep_free(parent_rdf); 01370 01371 if (parent_domain) { 01372 /* check for DNAME or NS */ 01373 if (domain_examine_data_exists(parent_domain, LDNS_RR_TYPE_DNAME, 01374 0) && domain_examine_data_exists(domain, 0, 0)) { 01375 /* data below DNAME */ 01376 str_name = ldns_rdf2str(domain->dname); 01377 str_parent = ldns_rdf2str(parent_domain->dname); 01378 ods_log_warning("[%s] occluded data at %s (below %s DNAME)", 01379 zd_str, str_name, str_parent); 01380 free((void*)str_name); 01381 free((void*)str_parent); 01382 return 1; 01383 } else if (domain_examine_data_exists(parent_domain, 01384 LDNS_RR_TYPE_NS, 0) && 01385 domain_examine_data_exists(domain, 0, 1)) { 01386 /* data (non-glue) below NS */ 01387 str_name = ldns_rdf2str(domain->dname); 01388 str_parent = ldns_rdf2str(parent_domain->dname); 01389 ods_log_warning("[%s] occluded (non-glue) data at %s (below " 01390 "%s NS)", zd_str, str_name, str_parent); 01391 free((void*)str_name); 01392 free((void*)str_parent); 01393 return 1; 01394 /* allow for now (root zone has it) 01395 } else if (domain_examine_data_exists(parent_domain, 01396 LDNS_RR_TYPE_NS, 0) && 01397 domain_examine_data_exists(domain, 0, 0) && 01398 !domain_examine_ns_rdata(parent_domain, domain->dname)) { 01399 str_name = ldns_rdf2str(domain->dname); 01400 str_parent = ldns_rdf2str(parent_domain->dname); 01401 ods_log_warning("[%s] occluded data at %s (below %s NS)", 01402 zd_str, str_name, str_parent); 01403 free((void*)str_name); 01404 free((void*)str_parent); 01405 return 1; 01406 */ 01407 } 01408 } 01409 parent_rdf = next_rdf; 01410 } 01411 if (parent_rdf) { 01412 ldns_rdf_deep_free(parent_rdf); 01413 } 01414 return 0; 01415 } 01416 01417 01422 ods_status 01423 zonedata_examine(zonedata_type* zd, ldns_rdf* apex, adapter_mode mode) 01424 { 01425 int result = 0; 01426 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01427 domain_type* domain = NULL; 01428 ods_status status = ODS_STATUS_OK; 01429 01430 if (!zd || !zd->domains) { 01431 /* no zone data, no error */ 01432 return ODS_STATUS_OK; 01433 } 01434 ods_log_assert(zd); 01435 ods_log_assert(zd->domains); 01436 01437 if (zd->domains->root != LDNS_RBTREE_NULL) { 01438 node = ldns_rbtree_first(zd->domains); 01439 } 01440 while (node && node != LDNS_RBTREE_NULL) { 01441 domain = (domain_type*) node->data; 01442 result = 01443 /* Thou shall not have other data next to CNAME */ 01444 domain_examine_rrset_is_alone(domain, LDNS_RR_TYPE_CNAME) && 01445 /* Thou shall have at most one CNAME per name */ 01446 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_CNAME) && 01447 /* Thou shall have at most one DNAME per name */ 01448 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_DNAME); 01449 if (!result) { 01450 status = ODS_STATUS_ERR; 01451 } 01452 01453 if (mode == ADAPTER_FILE) { 01454 result = 01455 /* Thou shall not have occluded data in your zone file */ 01456 zonedata_examine_domain_is_occluded(zd, domain, apex); 01457 if (result) { 01458 ; /* just warn if there is occluded data */ 01459 } 01460 } 01461 node = ldns_rbtree_next(node); 01462 } 01463 return status; 01464 } 01465 01466 01471 void 01472 zonedata_wipe_denial(zonedata_type* zd) 01473 { 01474 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01475 denial_type* denial = NULL; 01476 01477 if (zd && zd->denial_chain) { 01478 node = ldns_rbtree_first(zd->denial_chain); 01479 while (node && node != LDNS_RBTREE_NULL) { 01480 denial = (denial_type*) node->data; 01481 if (denial->rrset) { 01482 /* [TODO] IXFR delete NSEC */ 01483 rrset_cleanup(denial->rrset); 01484 denial->rrset = NULL; 01485 } 01486 node = ldns_rbtree_next(node); 01487 } 01488 } 01489 return; 01490 } 01491 01492 01497 static void 01498 domain_delfunc(ldns_rbnode_t* elem) 01499 { 01500 domain_type* domain = NULL; 01501 01502 if (elem && elem != LDNS_RBTREE_NULL) { 01503 domain = (domain_type*) elem->data; 01504 domain_delfunc(elem->left); 01505 domain_delfunc(elem->right); 01506 01507 domain_cleanup(domain); 01508 free((void*)elem); 01509 } 01510 return; 01511 } 01512 01513 01518 static void 01519 denial_delfunc(ldns_rbnode_t* elem) 01520 { 01521 denial_type* denial = NULL; 01522 domain_type* domain = NULL; 01523 01524 01525 if (elem && elem != LDNS_RBTREE_NULL) { 01526 denial = (denial_type*) elem->data; 01527 denial_delfunc(elem->left); 01528 denial_delfunc(elem->right); 01529 01530 domain = denial->domain; 01531 if (domain) { 01532 domain->denial = NULL; 01533 } 01534 denial_cleanup(denial); 01535 01536 free((void*)elem); 01537 } 01538 return; 01539 } 01540 01541 01546 static void 01547 zonedata_cleanup_domains(zonedata_type* zd) 01548 { 01549 if (zd && zd->domains) { 01550 domain_delfunc(zd->domains->root); 01551 ldns_rbtree_free(zd->domains); 01552 zd->domains = NULL; 01553 } 01554 return; 01555 } 01556 01557 01562 void 01563 zonedata_cleanup_chain(zonedata_type* zd) 01564 { 01565 if (zd && zd->denial_chain) { 01566 denial_delfunc(zd->denial_chain->root); 01567 ldns_rbtree_free(zd->denial_chain); 01568 zd->denial_chain = NULL; 01569 } 01570 return; 01571 } 01572 01573 01578 void 01579 zonedata_cleanup(zonedata_type* zd) 01580 { 01581 allocator_type* allocator; 01582 01583 if (!zd) { 01584 return; 01585 } 01586 zonedata_cleanup_chain(zd); 01587 zonedata_cleanup_domains(zd); 01588 allocator = zd->allocator; 01589 allocator_deallocate(allocator, (void*) zd); 01590 return; 01591 } 01592 01593 01598 void 01599 zonedata_backup(FILE* fd, zonedata_type* zd) 01600 { 01601 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01602 domain_type* domain = NULL; 01603 01604 if (!fd || !zd) { 01605 return; 01606 } 01607 01608 node = ldns_rbtree_first(zd->domains); 01609 while (node && node != LDNS_RBTREE_NULL) { 01610 domain = (domain_type*) node->data; 01611 domain_backup(fd, domain); 01612 node = ldns_rbtree_next(node); 01613 } 01614 fprintf(fd, ";;\n"); 01615 return; 01616 } 01617 01618 01623 ods_status 01624 zonedata_print(FILE* fd, zonedata_type* zd) 01625 { 01626 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01627 domain_type* domain = NULL; 01628 01629 if (!fd) { 01630 ods_log_error("[%s] unable to print zone data: no file descriptor", 01631 zd_str); 01632 return ODS_STATUS_ASSERT_ERR; 01633 } 01634 ods_log_assert(fd); 01635 01636 if (!zd || !zd->domains) { 01637 ods_log_error("[%s] unable to print zone data: no zone data", 01638 zd_str); 01639 return ODS_STATUS_ASSERT_ERR; 01640 } 01641 ods_log_assert(zd); 01642 ods_log_assert(zd->domains); 01643 01644 node = ldns_rbtree_first(zd->domains); 01645 if (!node || node == LDNS_RBTREE_NULL) { 01646 fprintf(fd, "; empty zone\n"); 01647 return ODS_STATUS_OK; 01648 } 01649 while (node && node != LDNS_RBTREE_NULL) { 01650 domain = (domain_type*) node->data; 01651 domain_print(fd, domain); 01652 node = ldns_rbtree_next(node); 01653 } 01654 return ODS_STATUS_OK; 01655 }