OpenDNSSEC-signer
1.3.8
|
00001 /* 00002 * $Id: zonedata.c 6050 2012-01-10 11:25:28Z matthijs $ 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 static domain_type* 00292 zonedata_domain_search(ldns_rbtree_t* tree, ldns_rdf* dname) 00293 { 00294 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00295 00296 if (!tree || !dname) { 00297 return NULL; 00298 } 00299 node = ldns_rbtree_search(tree, dname); 00300 if (node && node != LDNS_RBTREE_NULL) { 00301 return (domain_type*) node->data; 00302 } 00303 return NULL; 00304 } 00305 00306 00311 domain_type* 00312 zonedata_lookup_domain(zonedata_type* zd, ldns_rdf* dname) 00313 { 00314 if (!zd) return NULL; 00315 00316 return zonedata_domain_search(zd->domains, dname); 00317 } 00318 00319 00324 domain_type* 00325 zonedata_add_domain(zonedata_type* zd, domain_type* domain) 00326 { 00327 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00328 00329 if (!domain) { 00330 ods_log_error("[%s] unable to add domain: no domain", zd_str); 00331 return NULL; 00332 } 00333 ods_log_assert(domain); 00334 00335 if (!zd || !zd->domains) { 00336 log_rdf(domain->dname, "unable to add domain, no storage", 1); 00337 return NULL; 00338 } 00339 ods_log_assert(zd); 00340 ods_log_assert(zd->domains); 00341 00342 new_node = domain2node(domain); 00343 if (ldns_rbtree_insert(zd->domains, new_node) == NULL) { 00344 log_rdf(domain->dname, "unable to add domain, already present", 1); 00345 free((void*)new_node); 00346 return NULL; 00347 } 00348 log_rdf(domain->dname, "+DD", 6); 00349 return domain; 00350 } 00351 00352 00357 static domain_type* 00358 zonedata_del_domain_fixup(ldns_rbtree_t* tree, domain_type* domain) 00359 { 00360 domain_type* del_domain = NULL; 00361 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL; 00362 00363 ods_log_assert(tree); 00364 ods_log_assert(domain); 00365 ods_log_assert(domain->dname); 00366 00367 del_node = ldns_rbtree_search(tree, (const void*)domain->dname); 00368 if (del_node) { 00369 del_node = ldns_rbtree_delete(tree, (const void*)domain->dname); 00370 del_domain = (domain_type*) del_node->data; 00371 domain_cleanup(del_domain); 00372 free((void*)del_node); 00373 return NULL; 00374 } else { 00375 log_rdf(domain->dname, "unable to del domain, not found", 1); 00376 } 00377 return domain; 00378 } 00379 00380 00385 domain_type* 00386 zonedata_del_domain(zonedata_type* zd, domain_type* domain) 00387 { 00388 if (!domain) { 00389 ods_log_error("[%s] unable to delete domain: no domain", zd_str); 00390 return NULL; 00391 } 00392 ods_log_assert(domain); 00393 ods_log_assert(domain->dname); 00394 00395 if (!zd || !zd->domains) { 00396 log_rdf(domain->dname, "unable to delete domain, no zonedata", 1); 00397 return domain; 00398 } 00399 ods_log_assert(zd); 00400 ods_log_assert(zd->domains); 00401 00402 if (domain->denial && zonedata_del_denial(zd, domain->denial) != NULL) { 00403 log_rdf(domain->dname, "unable to delete domain, failed to delete " 00404 "denial of existence data point", 1); 00405 return domain; 00406 } 00407 domain->denial = NULL; 00408 log_rdf(domain->dname, "-DD", 6); 00409 return zonedata_del_domain_fixup(zd->domains, domain); 00410 } 00411 00412 00417 static denial_type* 00418 zonedata_denial_search(ldns_rbtree_t* tree, ldns_rdf* dname) 00419 { 00420 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00421 00422 if (!tree || !dname) { 00423 return NULL; 00424 } 00425 node = ldns_rbtree_search(tree, dname); 00426 if (node && node != LDNS_RBTREE_NULL) { 00427 return (denial_type*) node->data; 00428 } 00429 return NULL; 00430 } 00431 00432 00437 denial_type* 00438 zonedata_lookup_denial(zonedata_type* zd, ldns_rdf* dname) 00439 { 00440 if (!zd) return NULL; 00441 00442 return zonedata_denial_search(zd->denial_chain, dname); 00443 } 00444 00445 00450 static ldns_rdf* 00451 dname_hash(ldns_rdf* dname, ldns_rdf* apex, nsec3params_type* nsec3params) 00452 { 00453 ldns_rdf* hashed_ownername = NULL; 00454 ldns_rdf* hashed_label = NULL; 00455 00456 ods_log_assert(dname); 00457 ods_log_assert(apex); 00458 ods_log_assert(nsec3params); 00459 00464 hashed_label = ldns_nsec3_hash_name(dname, nsec3params->algorithm, 00465 nsec3params->iterations, nsec3params->salt_len, 00466 nsec3params->salt_data); 00467 if (!hashed_label) { 00468 log_rdf(dname, "unable to hash dname, hash failed", 1); 00469 return NULL; 00470 } 00471 hashed_ownername = ldns_dname_cat_clone((const ldns_rdf*) hashed_label, 00472 (const ldns_rdf*) apex); 00473 if (!hashed_ownername) { 00474 log_rdf(dname, "unable to hash dname, concat apex failed", 1); 00475 return NULL; 00476 } 00477 ldns_rdf_deep_free(hashed_label); 00478 return hashed_ownername; 00479 } 00480 00481 00486 ods_status 00487 zonedata_add_denial(zonedata_type* zd, domain_type* domain, ldns_rdf* apex, 00488 nsec3params_type* nsec3params) 00489 { 00490 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00491 ldns_rbnode_t* prev_node = LDNS_RBTREE_NULL; 00492 ldns_rdf* owner = NULL; 00493 denial_type* denial = NULL; 00494 denial_type* prev_denial = NULL; 00495 00496 if (!domain) { 00497 ods_log_error("[%s] unable to add denial of existence data point: " 00498 "no domain", zd_str); 00499 return ODS_STATUS_ASSERT_ERR; 00500 } 00501 ods_log_assert(domain); 00502 00503 if (!zd || !zd->denial_chain) { 00504 log_rdf(domain->dname, "unable to add denial of existence data " 00505 "point for domain, no denial chain", 1); 00506 return ODS_STATUS_ASSERT_ERR; 00507 } 00508 ods_log_assert(zd); 00509 ods_log_assert(zd->denial_chain); 00510 00511 if (!apex) { 00512 log_rdf(domain->dname, "unable to add denial of existence data " 00513 "point for domain, apex unknown", 1); 00514 return ODS_STATUS_ASSERT_ERR; 00515 } 00516 ods_log_assert(apex); 00517 00518 /* nsec or nsec3 */ 00519 if (nsec3params) { 00520 owner = dname_hash(domain->dname, apex, nsec3params); 00521 if (!owner) { 00522 log_rdf(domain->dname, "unable to add denial of existence data " 00523 "point for domain, dname hash failed", 1); 00524 return ODS_STATUS_ERR; 00525 } 00526 } else { 00527 owner = ldns_rdf_clone(domain->dname); 00528 } 00529 /* lookup */ 00530 if (zonedata_lookup_denial(zd, owner) != NULL) { 00531 log_rdf(domain->dname, "unable to add denial of existence for " 00532 "domain, data point exists", 1); 00533 return ODS_STATUS_CONFLICT_ERR; 00534 } 00535 /* create */ 00536 denial = denial_create(owner); 00537 new_node = denial2node(denial); 00538 ldns_rdf_deep_free(owner); 00539 /* insert */ 00540 if (!ldns_rbtree_insert(zd->denial_chain, new_node)) { 00541 log_rdf(domain->dname, "unable to add denial of existence for " 00542 "domain, insert failed", 1); 00543 free((void*)new_node); 00544 denial_cleanup(denial); 00545 return ODS_STATUS_ERR; 00546 } 00547 /* denial of existence data point added */ 00548 denial->bitmap_changed = 1; 00549 denial->nxt_changed = 1; 00550 prev_node = ldns_rbtree_previous(new_node); 00551 if (!prev_node || prev_node == LDNS_RBTREE_NULL) { 00552 prev_node = ldns_rbtree_last(zd->denial_chain); 00553 } 00554 ods_log_assert(prev_node); 00555 prev_denial = (denial_type*) prev_node->data; 00556 ods_log_assert(prev_denial); 00557 prev_denial->nxt_changed = 1; 00558 domain->denial = denial; 00559 domain->denial->domain = domain; /* back reference */ 00560 return ODS_STATUS_OK; 00561 } 00562 00563 00568 static denial_type* 00569 zonedata_del_denial_fixup(ldns_rbtree_t* tree, denial_type* denial) 00570 { 00571 denial_type* del_denial = NULL; 00572 denial_type* prev_denial = NULL; 00573 ldns_rbnode_t* prev_node = LDNS_RBTREE_NULL; 00574 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL; 00575 ods_status status = ODS_STATUS_OK; 00576 00577 ods_log_assert(tree); 00578 ods_log_assert(denial); 00579 ods_log_assert(denial->owner); 00580 00581 del_node = ldns_rbtree_search(tree, (const void*)denial->owner); 00582 if (del_node) { 00587 prev_node = ldns_rbtree_previous(del_node); 00588 if (!prev_node || prev_node == LDNS_RBTREE_NULL) { 00589 prev_node = ldns_rbtree_last(tree); 00590 } 00591 ods_log_assert(prev_node); 00592 ods_log_assert(prev_node->data); 00593 prev_denial = (denial_type*) prev_node->data; 00594 prev_denial->nxt_changed = 1; 00595 00596 /* delete old NSEC RR(s) */ 00597 if (denial->rrset) { 00598 status = rrset_wipe_out(denial->rrset); 00599 if (status != ODS_STATUS_OK) { 00600 ods_log_alert("[%s] unable to del denial of existence data " 00601 "point: failed to wipe out NSEC RRset", zd_str); 00602 return denial; 00603 } 00604 status = rrset_commit(denial->rrset); 00605 if (status != ODS_STATUS_OK) { 00606 ods_log_alert("[%s] unable to del denial of existence data " 00607 "point: failed to commit NSEC RRset", zd_str); 00608 return denial; 00609 } 00610 } 00611 00612 del_node = ldns_rbtree_delete(tree, (const void*)denial->owner); 00613 del_denial = (denial_type*) del_node->data; 00614 denial_cleanup(del_denial); 00615 free((void*)del_node); 00616 return NULL; 00617 } else { 00618 log_rdf(denial->owner, "unable to del denial of existence data " 00619 "point, not found", 1); 00620 } 00621 return denial; 00622 } 00623 00624 00629 denial_type* 00630 zonedata_del_denial(zonedata_type* zd, denial_type* denial) 00631 { 00632 if (!denial) { 00633 ods_log_error("[%s] unable to delete denial of existence data " 00634 "point: no data point", zd_str); 00635 return NULL; 00636 } 00637 ods_log_assert(denial); 00638 00639 if (!zd || !zd->denial_chain) { 00640 log_rdf(denial->owner, "unable to delete denial of existence data " 00641 "point, no zone data", 1); 00642 return denial; 00643 } 00644 ods_log_assert(zd); 00645 ods_log_assert(zd->denial_chain); 00646 00647 return zonedata_del_denial_fixup(zd->denial_chain, denial); 00648 } 00649 00650 00655 ods_status 00656 zonedata_diff(zonedata_type* zd, keylist_type* kl) 00657 { 00658 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00659 domain_type* domain = NULL; 00660 ods_status status = ODS_STATUS_OK; 00661 00662 if (!zd || !zd->domains) { 00663 return status; 00664 } 00665 if (zd->domains->root != LDNS_RBTREE_NULL) { 00666 node = ldns_rbtree_first(zd->domains); 00667 } 00668 while (node && node != LDNS_RBTREE_NULL) { 00669 domain = (domain_type*) node->data; 00670 status = domain_diff(domain, kl); 00671 if (status != ODS_STATUS_OK) { 00672 return status; 00673 } 00674 node = ldns_rbtree_next(node); 00675 } 00676 return status; 00677 } 00678 00679 00684 ods_status 00685 zonedata_commit(zonedata_type* zd) 00686 { 00687 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00688 ldns_rbnode_t* nxtnode = LDNS_RBTREE_NULL; 00689 ldns_rbnode_t* tmpnode = LDNS_RBTREE_NULL; 00690 domain_type* domain = NULL; 00691 domain_type* nxtdomain = NULL; 00692 ods_status status = ODS_STATUS_OK; 00693 size_t oldnum = 0; 00694 00695 if (!zd || !zd->domains) { 00696 return ODS_STATUS_OK; 00697 } 00698 if (zd->domains->root != LDNS_RBTREE_NULL) { 00699 node = ldns_rbtree_last(zd->domains); 00700 } 00701 while (node && node != LDNS_RBTREE_NULL) { 00702 domain = (domain_type*) node->data; 00703 oldnum = domain_count_rrset(domain); 00704 status = domain_commit(domain); 00705 if (status != ODS_STATUS_OK) { 00706 return status; 00707 } 00708 tmpnode = node; 00709 node = ldns_rbtree_previous(node); 00710 00711 /* delete memory if empty leaf domain */ 00712 if (domain_count_rrset(domain) <= 0) { 00713 /* empty domain */ 00714 nxtnode = ldns_rbtree_next(tmpnode); 00715 nxtdomain = NULL; 00716 if (nxtnode && nxtnode != LDNS_RBTREE_NULL) { 00717 nxtdomain = (domain_type*) nxtnode->data; 00718 } 00719 if (!nxtdomain || 00720 !ldns_dname_is_subdomain(nxtdomain->dname, domain->dname)) { 00721 /* leaf domain */ 00722 if (zonedata_del_domain(zd, domain) != NULL) { 00723 ods_log_warning("[%s] unable to delete obsoleted " 00724 "domain", zd_str); 00725 return ODS_STATUS_ERR; 00726 } 00727 } 00728 } /* if (domain_count_rrset(domain) <= 0) */ 00729 } 00730 return status; 00731 } 00732 00733 00738 void 00739 zonedata_rollback(zonedata_type* zd) 00740 { 00741 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00742 domain_type* domain = NULL; 00743 00744 if (!zd || !zd->domains) { 00745 return; 00746 } 00747 if (zd->domains->root != LDNS_RBTREE_NULL) { 00748 node = ldns_rbtree_first(zd->domains); 00749 } 00750 while (node && node != LDNS_RBTREE_NULL) { 00751 domain = (domain_type*) node->data; 00752 domain_rollback(domain); 00753 node = ldns_rbtree_next(node); 00754 } 00755 return; 00756 } 00757 00758 00763 static int 00764 domain_ent2glue(ldns_rbnode_t* node) 00765 { 00766 ldns_rbnode_t* nextnode = LDNS_RBTREE_NULL; 00767 domain_type* nextdomain = NULL; 00768 domain_type* domain = NULL; 00769 ods_log_assert(node && node != LDNS_RBTREE_NULL); 00770 domain = (domain_type*) node->data; 00771 if (domain->dstatus == DOMAIN_STATUS_ENT) { 00772 ods_log_assert(domain_count_rrset(domain) == 0); 00773 nextnode = ldns_rbtree_next(node); 00774 while (nextnode && nextnode != LDNS_RBTREE_NULL) { 00775 nextdomain = (domain_type*) nextnode->data; 00776 if (!ldns_dname_is_subdomain(nextdomain->dname, domain->dname)) { 00777 /* we are done, no non-glue found */ 00778 return 1; 00779 } 00780 if (nextdomain->dstatus != DOMAIN_STATUS_OCCLUDED && 00781 nextdomain->dstatus != DOMAIN_STATUS_ENT && 00782 nextdomain->dstatus != DOMAIN_STATUS_NONE) { 00783 /* found non-glue */ 00784 return 0; 00785 } 00786 nextnode = ldns_rbtree_next(nextnode); 00787 } 00788 } else { 00789 /* no empty non-terminal */ 00790 ods_log_assert(domain_count_rrset(domain) != 0); 00791 return 0; 00792 } 00793 /* no non-glue found */ 00794 return 1; 00795 } 00796 00797 00802 static int 00803 domain_ent2unsigned(ldns_rbnode_t* node) 00804 { 00805 ldns_rbnode_t* nextnode = LDNS_RBTREE_NULL; 00806 domain_type* nextdomain = NULL; 00807 domain_type* domain = NULL; 00808 ods_log_assert(node && node != LDNS_RBTREE_NULL); 00809 domain = (domain_type*) node->data; 00810 if (domain->dstatus == DOMAIN_STATUS_ENT) { 00811 ods_log_assert(domain_count_rrset(domain) == 0); 00812 nextnode = ldns_rbtree_next(node); 00813 while (nextnode && nextnode != LDNS_RBTREE_NULL) { 00814 nextdomain = (domain_type*) nextnode->data; 00815 if (!ldns_dname_is_subdomain(nextdomain->dname, domain->dname)) { 00816 /* we are done, no unsigned delegation found */ 00817 return 1; 00818 } 00819 if (nextdomain->dstatus != DOMAIN_STATUS_OCCLUDED && 00820 nextdomain->dstatus != DOMAIN_STATUS_ENT && 00821 nextdomain->dstatus != DOMAIN_STATUS_NS && 00822 nextdomain->dstatus != DOMAIN_STATUS_NONE) { 00823 /* found data that has to be signed */ 00824 return 0; 00825 } 00826 nextnode = ldns_rbtree_next(nextnode); 00827 } 00828 } else { 00829 /* no empty non-terminal */ 00830 ods_log_assert(domain_count_rrset(domain) != 0); 00831 return 0; 00832 } 00833 /* no unsigned delegation found */ 00834 return 1; 00835 } 00836 00837 00842 static ods_status 00843 domain_entize(zonedata_type* zd, domain_type* domain, ldns_rdf* apex) 00844 { 00845 ldns_rdf* parent_rdf = NULL; 00846 domain_type* parent_domain = NULL; 00847 00848 ods_log_assert(apex); 00849 ods_log_assert(domain); 00850 ods_log_assert(domain->dname); 00851 ods_log_assert(zd); 00852 ods_log_assert(zd->domains); 00853 00854 if (domain->parent) { 00855 /* domain already has parent */ 00856 return ODS_STATUS_OK; 00857 } 00858 00859 while (domain && ldns_dname_is_subdomain(domain->dname, apex) && 00860 ldns_dname_compare(domain->dname, apex) != 0) { 00861 00869 parent_rdf = ldns_dname_left_chop(domain->dname); 00870 if (!parent_rdf) { 00871 log_rdf(domain->dname, "unable to entize domain, left chop " 00872 "failed", 1); 00873 return ODS_STATUS_ERR; 00874 } 00875 ods_log_assert(parent_rdf); 00876 00877 parent_domain = zonedata_lookup_domain(zd, parent_rdf); 00878 if (!parent_domain) { 00879 parent_domain = domain_create(parent_rdf); 00880 ldns_rdf_deep_free(parent_rdf); 00881 if (!parent_domain) { 00882 log_rdf(domain->dname, "unable to entize domain, create " 00883 "parent failed", 1); 00884 return ODS_STATUS_ERR; 00885 } 00886 ods_log_assert(parent_domain); 00887 if (zonedata_add_domain(zd, parent_domain) == NULL) { 00888 log_rdf(domain->dname, "unable to entize domain, add parent " 00889 "failed", 1); 00890 domain_cleanup(parent_domain); 00891 return ODS_STATUS_ERR; 00892 } 00893 parent_domain->dstatus = DOMAIN_STATUS_ENT; 00894 domain->parent = parent_domain; 00895 /* continue with the parent domain */ 00896 domain = parent_domain; 00897 } else { 00898 ldns_rdf_deep_free(parent_rdf); 00899 domain->parent = parent_domain; 00900 /* we are done with this domain */ 00901 domain = NULL; 00902 } 00903 } 00904 return ODS_STATUS_OK; 00905 } 00906 00907 00912 ods_status 00913 zonedata_entize(zonedata_type* zd, ldns_rdf* apex) 00914 { 00915 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00916 ods_status status = ODS_STATUS_OK; 00917 domain_type* domain = NULL; 00918 00919 if (!zd || !zd->domains) { 00920 ods_log_error("[%s] unable to entize zone data: no zone data", 00921 zd_str); 00922 return ODS_STATUS_ASSERT_ERR; 00923 } 00924 ods_log_assert(zd); 00925 ods_log_assert(zd->domains); 00926 00927 if (!apex) { 00928 ods_log_error("[%s] unable to entize zone data: no zone apex", 00929 zd_str); 00930 return ODS_STATUS_ASSERT_ERR; 00931 } 00932 ods_log_assert(apex); 00933 00934 node = ldns_rbtree_first(zd->domains); 00935 while (node && node != LDNS_RBTREE_NULL) { 00936 domain = (domain_type*) node->data; 00937 status = domain_entize(zd, domain, apex); 00938 if (status != ODS_STATUS_OK) { 00939 ods_log_error("[%s] unable to entize zone data: entize domain " 00940 "failed", zd_str); 00941 return status; 00942 } 00943 domain_dstatus(domain); 00944 node = ldns_rbtree_next(node); 00945 } 00946 return ODS_STATUS_OK; 00947 } 00948 00949 00954 ods_status 00955 zonedata_nsecify(zonedata_type* zd, ldns_rr_class klass, uint32_t ttl, 00956 uint32_t* num_added) 00957 { 00958 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00959 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL; 00960 ods_status status = ODS_STATUS_OK; 00961 domain_type* domain = NULL; 00962 domain_type* apex = NULL; 00963 denial_type* denial = NULL; 00964 denial_type* nxt = NULL; 00965 size_t nsec_added = 0; 00966 00967 if (!zd || !zd->domains) { 00968 return ODS_STATUS_OK; 00969 } 00970 ods_log_assert(zd); 00971 ods_log_assert(zd->domains); 00972 00973 node = ldns_rbtree_first(zd->domains); 00974 while (node && node != LDNS_RBTREE_NULL) { 00975 domain = (domain_type*) node->data; 00976 if (domain->dstatus == DOMAIN_STATUS_APEX) { 00977 apex = domain; 00978 } 00979 /* don't do glue-only or empty domains */ 00980 if (domain->dstatus == DOMAIN_STATUS_NONE || 00981 domain->dstatus == DOMAIN_STATUS_ENT || 00982 domain->dstatus == DOMAIN_STATUS_OCCLUDED || 00983 domain_count_rrset(domain) <= 0) { 00984 if (domain_count_rrset(domain)) { 00985 log_rdf(domain->dname, "nsecify: don't do glue domain", 6); 00986 } else { 00987 log_rdf(domain->dname, "nsecify: don't do empty domain", 6); 00988 } 00989 if (domain->denial) { 00990 if (zonedata_del_denial(zd, domain->denial) != NULL) { 00991 ods_log_warning("[%s] unable to nsecify: failed to " 00992 "delete denial of existence data point", zd_str); 00993 return ODS_STATUS_ERR; 00994 } 00995 domain->denial = NULL; 00996 } 00997 node = ldns_rbtree_next(node); 00998 continue; 00999 } 01000 if (!apex) { 01001 ods_log_alert("[%s] unable to nsecify: apex unknown", zd_str); 01002 return ODS_STATUS_ASSERT_ERR; 01003 } 01004 01005 /* add the denial of existence */ 01006 if (!domain->denial) { 01007 status = zonedata_add_denial(zd, domain, apex->dname, NULL); 01008 if (status != ODS_STATUS_OK) { 01009 log_rdf(domain->dname, "unable to nsecify: failed to add " 01010 "denial of existence for domain", 1); 01011 return status; 01012 } 01013 nsec_added++; 01014 } 01015 node = ldns_rbtree_next(node); 01016 } 01017 01019 node = ldns_rbtree_first(zd->denial_chain); 01020 while (node && node != LDNS_RBTREE_NULL) { 01021 denial = (denial_type*) node->data; 01022 nxt_node = ldns_rbtree_next(node); 01023 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) { 01024 nxt_node = ldns_rbtree_first(zd->denial_chain); 01025 } 01026 nxt = (denial_type*) nxt_node->data; 01027 01028 status = denial_nsecify(denial, nxt, ttl, klass); 01029 if (status != ODS_STATUS_OK) { 01030 ods_log_error("[%s] unable to nsecify: failed to add NSEC record", 01031 zd_str); 01032 return status; 01033 } 01034 node = ldns_rbtree_next(node); 01035 } 01036 if (num_added) { 01037 *num_added = nsec_added; 01038 } 01039 return ODS_STATUS_OK; 01040 } 01041 01042 01047 ods_status 01048 zonedata_nsecify3(zonedata_type* zd, ldns_rr_class klass, 01049 uint32_t ttl, nsec3params_type* nsec3params, uint32_t* num_added) 01050 { 01051 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01052 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL; 01053 ods_status status = ODS_STATUS_OK; 01054 domain_type* domain = NULL; 01055 domain_type* apex = NULL; 01056 denial_type* denial = NULL; 01057 denial_type* nxt = NULL; 01058 size_t nsec3_added = 0; 01059 01060 if (!zd || !zd->domains) { 01061 return ODS_STATUS_OK; 01062 } 01063 ods_log_assert(zd); 01064 ods_log_assert(zd->domains); 01065 01066 if (!nsec3params) { 01067 ods_log_error("[%s] unable to nsecify3: no nsec3 paramaters", zd_str); 01068 return ODS_STATUS_ASSERT_ERR; 01069 } 01070 ods_log_assert(nsec3params); 01071 01072 node = ldns_rbtree_first(zd->domains); 01073 while (node && node != LDNS_RBTREE_NULL) { 01074 domain = (domain_type*) node->data; 01075 if (domain->dstatus == DOMAIN_STATUS_APEX) { 01076 apex = domain; 01077 } 01078 01079 /* don't do glue-only domains */ 01080 if (domain->dstatus == DOMAIN_STATUS_NONE || 01081 domain->dstatus == DOMAIN_STATUS_OCCLUDED || 01082 domain_ent2glue(node)) { 01083 log_rdf(domain->dname, "nsecify3: don't do glue domain" , 6); 01084 if (domain->denial) { 01085 if (zonedata_del_denial(zd, domain->denial) != NULL) { 01086 ods_log_error("[%s] unable to nsecify3: failed to " 01087 "delete denial of existence data point", zd_str); 01088 return ODS_STATUS_ERR; 01089 } 01090 domain->denial = NULL; 01091 } 01092 node = ldns_rbtree_next(node); 01093 continue; 01094 } 01095 /* Opt-Out? */ 01096 if (nsec3params->flags) { 01097 /* If Opt-Out is being used, owner names of unsigned delegations 01098 MAY be excluded. */ 01099 if (domain->dstatus == DOMAIN_STATUS_NS || 01100 domain_ent2unsigned(node)) { 01101 if (domain->dstatus == DOMAIN_STATUS_NS) { 01102 log_rdf(domain->dname, "nsecify3: opt-out (unsigned " 01103 "delegation)", 5); 01104 } else { 01105 log_rdf(domain->dname, "nsecify3: opt-out (empty " 01106 "non-terminal (to unsigned delegation))", 5); 01107 } 01108 if (domain->denial) { 01109 if (zonedata_del_denial(zd, domain->denial) != NULL) { 01110 ods_log_error("[%s] unable to nsecify3: failed to " 01111 "delete denial of existence data point", zd_str); 01112 return ODS_STATUS_ERR; 01113 } 01114 domain->denial = NULL; 01115 } 01116 node = ldns_rbtree_next(node); 01117 continue; 01118 } 01119 } 01120 if (!apex) { 01121 ods_log_alert("[%s] unable to nsecify3: apex unknown", zd_str); 01122 return ODS_STATUS_ASSERT_ERR; 01123 } 01124 01125 /* add the denial of existence */ 01126 if (!domain->denial) { 01127 status = zonedata_add_denial(zd, domain, apex->dname, 01128 nsec3params); 01129 if (status != ODS_STATUS_OK) { 01130 log_rdf(domain->dname, "unable to nsecify3: failed to add " 01131 "denial of existence for domain", 1); 01132 return status; 01133 } 01134 nsec3_added++; 01135 } 01136 01137 /* The Next Hashed Owner Name field is left blank for the moment. */ 01138 01146 /* [TODO] */ 01156 node = ldns_rbtree_next(node); 01157 } 01158 01160 node = ldns_rbtree_first(zd->denial_chain); 01161 while (node && node != LDNS_RBTREE_NULL) { 01162 denial = (denial_type*) node->data; 01163 nxt_node = ldns_rbtree_next(node); 01164 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) { 01165 nxt_node = ldns_rbtree_first(zd->denial_chain); 01166 } 01167 nxt = (denial_type*) nxt_node->data; 01168 01169 status = denial_nsecify3(denial, nxt, ttl, klass, nsec3params); 01170 if (status != ODS_STATUS_OK) { 01171 ods_log_error("[%s] unable to nsecify3: failed to add NSEC3 " 01172 "record", zd_str); 01173 return status; 01174 } 01175 node = ldns_rbtree_next(node); 01176 } 01177 if (num_added) { 01178 *num_added = nsec3_added; 01179 } 01180 return ODS_STATUS_OK; 01181 } 01182 01183 01188 ods_status 01189 zonedata_update_serial(zonedata_type* zd, signconf_type* sc) 01190 { 01191 uint32_t soa = 0; 01192 uint32_t prev = 0; 01193 uint32_t update = 0; 01194 01195 ods_log_assert(zd); 01196 ods_log_assert(sc); 01197 01198 prev = zd->outbound_serial; 01199 ods_log_debug("[%s] update serial: in=%u internal=%u out=%u now=%u", 01200 zd_str, zd->inbound_serial, zd->internal_serial, zd->outbound_serial, 01201 (uint32_t) time_now()); 01202 01203 if (!sc->soa_serial) { 01204 ods_log_error("[%s] no serial type given", zd_str); 01205 return ODS_STATUS_ERR; 01206 } 01207 if (ods_strcmp(sc->soa_serial, "unixtime") == 0) { 01208 soa = (uint32_t) time_now(); 01209 if (!zd->initialized) { 01210 if (!DNS_SERIAL_GT(soa, zd->inbound_serial)) { 01211 ods_log_warning("[%s] unable to use unixtime %u as serial: " 01212 "not greater than inbound serial %u", zd_str, soa, 01213 zd->inbound_serial); 01214 soa = zd->inbound_serial + 1; 01215 } 01216 } else if (!DNS_SERIAL_GT(soa, prev)) { 01217 soa = prev + 1; 01218 } 01219 } else if (strncmp(sc->soa_serial, "counter", 7) == 0) { 01220 soa = zd->inbound_serial; 01221 if (!zd->initialized) { 01222 soa = zd->inbound_serial + 1; 01223 } else if (!DNS_SERIAL_GT(soa, prev)) { 01224 soa = prev + 1; 01225 } 01226 } else if (strncmp(sc->soa_serial, "datecounter", 11) == 0) { 01227 soa = (uint32_t) time_datestamp(0, "%Y%m%d", NULL) * 100; 01228 if (!zd->initialized) { 01229 if (!DNS_SERIAL_GT(soa, zd->inbound_serial)) { 01230 ods_log_warning("[%s] unable to use datecounter %u as serial: " 01231 "not greater than inbound serial %u", zd_str, soa, 01232 zd->inbound_serial); 01233 soa = zd->inbound_serial + 1; 01234 } 01235 } else if (!DNS_SERIAL_GT(soa, prev)) { 01236 soa = prev + 1; 01237 } 01238 } else if (strncmp(sc->soa_serial, "keep", 4) == 0) { 01239 soa = zd->inbound_serial; 01240 if (zd->initialized && !DNS_SERIAL_GT(soa, prev)) { 01241 ods_log_error("[%s] cannot keep SOA SERIAL from input zone " 01242 " (%u): previous output SOA SERIAL is %u", zd_str, soa, prev); 01243 return ODS_STATUS_CONFLICT_ERR; 01244 } 01245 } else { 01246 ods_log_error("[%s] unknown serial type %s", zd_str, sc->soa_serial); 01247 return ODS_STATUS_ERR; 01248 } 01249 01250 /* serial is stored in 32 bits */ 01251 update = soa - prev; 01252 if (update > 0x7FFFFFFF) { 01253 update = 0x7FFFFFFF; 01254 } 01255 01256 if (!zd->initialized) { 01257 zd->internal_serial = soa; 01258 } else { 01259 zd->internal_serial = prev + update; /* automatically does % 2^32 */ 01260 } 01261 ods_log_debug("[%s] update serial: %u + %u = %u", zd_str, prev, update, 01262 zd->internal_serial); 01263 return ODS_STATUS_OK; 01264 } 01265 01266 01271 ods_status 01272 zonedata_queue(zonedata_type* zd, fifoq_type* q, worker_type* worker) 01273 { 01274 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01275 domain_type* domain = NULL; 01276 ods_status status = ODS_STATUS_OK; 01277 01278 if (!zd || !zd->domains) { 01279 return ODS_STATUS_OK; 01280 } 01281 if (zd->domains->root != LDNS_RBTREE_NULL) { 01282 node = ldns_rbtree_first(zd->domains); 01283 } 01284 while (node && node != LDNS_RBTREE_NULL) { 01285 domain = (domain_type*) node->data; 01286 status = domain_queue(domain, q, worker); 01287 if (status != ODS_STATUS_OK) { 01288 return status; 01289 } 01290 node = ldns_rbtree_next(node); 01291 } 01292 return status; 01293 } 01294 01295 01300 static int 01301 zonedata_examine_domain_is_occluded(zonedata_type* zd, domain_type* domain, 01302 ldns_rdf* apex) 01303 { 01304 ldns_rdf* parent_rdf = NULL; 01305 ldns_rdf* next_rdf = NULL; 01306 domain_type* parent_domain = NULL; 01307 char* str_name = NULL; 01308 char* str_parent = NULL; 01309 01310 ods_log_assert(apex); 01311 ods_log_assert(domain); 01312 ods_log_assert(domain->dname); 01313 ods_log_assert(zd); 01314 ods_log_assert(zd->domains); 01315 01316 if (ldns_dname_compare(domain->dname, apex) == 0) { 01317 return 0; 01318 } 01319 01320 if (domain_examine_valid_zonecut(domain) != 0) { 01321 log_rdf(domain->dname, "occluded (non-glue non-DS) data at NS", 2); 01322 return 1; 01323 } 01324 01325 parent_rdf = ldns_dname_left_chop(domain->dname); 01326 while (parent_rdf && ldns_dname_is_subdomain(parent_rdf, apex) && 01327 ldns_dname_compare(parent_rdf, apex) != 0) { 01328 01329 parent_domain = zonedata_lookup_domain(zd, parent_rdf); 01330 next_rdf = ldns_dname_left_chop(parent_rdf); 01331 ldns_rdf_deep_free(parent_rdf); 01332 01333 if (parent_domain) { 01334 /* check for DNAME or NS */ 01335 if (domain_examine_data_exists(parent_domain, LDNS_RR_TYPE_DNAME, 01336 0) && domain_examine_data_exists(domain, 0, 0)) { 01337 /* data below DNAME */ 01338 str_name = ldns_rdf2str(domain->dname); 01339 str_parent = ldns_rdf2str(parent_domain->dname); 01340 ods_log_warning("[%s] occluded data at %s (below %s DNAME)", 01341 zd_str, str_name, str_parent); 01342 free((void*)str_name); 01343 free((void*)str_parent); 01344 return 1; 01345 } else if (domain_examine_data_exists(parent_domain, 01346 LDNS_RR_TYPE_NS, 0) && 01347 domain_examine_data_exists(domain, 0, 1)) { 01348 /* data (non-glue) below NS */ 01349 str_name = ldns_rdf2str(domain->dname); 01350 str_parent = ldns_rdf2str(parent_domain->dname); 01351 ods_log_warning("[%s] occluded (non-glue) data at %s (below " 01352 "%s NS)", zd_str, str_name, str_parent); 01353 free((void*)str_name); 01354 free((void*)str_parent); 01355 return 1; 01356 /* allow for now (root zone has it) 01357 } else if (domain_examine_data_exists(parent_domain, 01358 LDNS_RR_TYPE_NS, 0) && 01359 domain_examine_data_exists(domain, 0, 0) && 01360 !domain_examine_ns_rdata(parent_domain, domain->dname)) { 01361 str_name = ldns_rdf2str(domain->dname); 01362 str_parent = ldns_rdf2str(parent_domain->dname); 01363 ods_log_warning("[%s] occluded data at %s (below %s NS)", 01364 zd_str, str_name, str_parent); 01365 free((void*)str_name); 01366 free((void*)str_parent); 01367 return 1; 01368 */ 01369 } 01370 } 01371 parent_rdf = next_rdf; 01372 } 01373 if (parent_rdf) { 01374 ldns_rdf_deep_free(parent_rdf); 01375 } 01376 return 0; 01377 } 01378 01379 01384 ods_status 01385 zonedata_examine(zonedata_type* zd, ldns_rdf* apex, adapter_mode mode) 01386 { 01387 int result = 0; 01388 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01389 domain_type* domain = NULL; 01390 ods_status status = ODS_STATUS_OK; 01391 01392 if (!zd || !zd->domains) { 01393 /* no zone data, no error */ 01394 return ODS_STATUS_OK; 01395 } 01396 ods_log_assert(zd); 01397 ods_log_assert(zd->domains); 01398 01399 if (zd->domains->root != LDNS_RBTREE_NULL) { 01400 node = ldns_rbtree_first(zd->domains); 01401 } 01402 while (node && node != LDNS_RBTREE_NULL) { 01403 domain = (domain_type*) node->data; 01404 result = 01405 /* Thou shall not have other data next to CNAME */ 01406 domain_examine_rrset_is_alone(domain, LDNS_RR_TYPE_CNAME) && 01407 /* Thou shall have at most one CNAME per name */ 01408 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_CNAME) && 01409 /* Thou shall have at most one DNAME per name */ 01410 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_DNAME); 01411 if (!result) { 01412 status = ODS_STATUS_ERR; 01413 } 01414 01415 if (mode == ADAPTER_FILE) { 01416 result = 01417 /* Thou shall not have occluded data in your zone file */ 01418 zonedata_examine_domain_is_occluded(zd, domain, apex); 01419 if (result) { 01420 ; /* just warn if there is occluded data */ 01421 } 01422 } 01423 node = ldns_rbtree_next(node); 01424 } 01425 return status; 01426 } 01427 01428 01433 void 01434 zonedata_wipe_denial(zonedata_type* zd) 01435 { 01436 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01437 denial_type* denial = NULL; 01438 01439 if (zd && zd->denial_chain) { 01440 node = ldns_rbtree_first(zd->denial_chain); 01441 while (node && node != LDNS_RBTREE_NULL) { 01442 denial = (denial_type*) node->data; 01443 if (denial->rrset) { 01444 /* [TODO] IXFR delete NSEC */ 01445 rrset_cleanup(denial->rrset); 01446 denial->rrset = NULL; 01447 } 01448 node = ldns_rbtree_next(node); 01449 } 01450 } 01451 return; 01452 } 01453 01454 01459 static void 01460 domain_delfunc(ldns_rbnode_t* elem) 01461 { 01462 domain_type* domain = NULL; 01463 01464 if (elem && elem != LDNS_RBTREE_NULL) { 01465 domain = (domain_type*) elem->data; 01466 domain_delfunc(elem->left); 01467 domain_delfunc(elem->right); 01468 01469 domain_cleanup(domain); 01470 free((void*)elem); 01471 } 01472 return; 01473 } 01474 01475 01480 static void 01481 denial_delfunc(ldns_rbnode_t* elem) 01482 { 01483 denial_type* denial = NULL; 01484 domain_type* domain = NULL; 01485 01486 01487 if (elem && elem != LDNS_RBTREE_NULL) { 01488 denial = (denial_type*) elem->data; 01489 denial_delfunc(elem->left); 01490 denial_delfunc(elem->right); 01491 01492 domain = denial->domain; 01493 if (domain) { 01494 domain->denial = NULL; 01495 } 01496 denial_cleanup(denial); 01497 01498 free((void*)elem); 01499 } 01500 return; 01501 } 01502 01503 01508 static void 01509 zonedata_cleanup_domains(zonedata_type* zd) 01510 { 01511 if (zd && zd->domains) { 01512 domain_delfunc(zd->domains->root); 01513 ldns_rbtree_free(zd->domains); 01514 zd->domains = NULL; 01515 } 01516 return; 01517 } 01518 01519 01524 void 01525 zonedata_cleanup_chain(zonedata_type* zd) 01526 { 01527 if (zd && zd->denial_chain) { 01528 denial_delfunc(zd->denial_chain->root); 01529 ldns_rbtree_free(zd->denial_chain); 01530 zd->denial_chain = NULL; 01531 } 01532 return; 01533 } 01534 01535 01540 void 01541 zonedata_cleanup(zonedata_type* zd) 01542 { 01543 allocator_type* allocator; 01544 01545 if (!zd) { 01546 return; 01547 } 01548 zonedata_cleanup_chain(zd); 01549 zonedata_cleanup_domains(zd); 01550 allocator = zd->allocator; 01551 allocator_deallocate(allocator, (void*) zd); 01552 return; 01553 } 01554 01555 01560 void 01561 zonedata_backup(FILE* fd, zonedata_type* zd) 01562 { 01563 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01564 domain_type* domain = NULL; 01565 01566 if (!fd || !zd) { 01567 return; 01568 } 01569 01570 node = ldns_rbtree_first(zd->domains); 01571 while (node && node != LDNS_RBTREE_NULL) { 01572 domain = (domain_type*) node->data; 01573 domain_backup(fd, domain); 01574 node = ldns_rbtree_next(node); 01575 } 01576 fprintf(fd, ";;\n"); 01577 return; 01578 } 01579 01580 01585 ods_status 01586 zonedata_print(FILE* fd, zonedata_type* zd) 01587 { 01588 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01589 domain_type* domain = NULL; 01590 01591 if (!fd) { 01592 ods_log_error("[%s] unable to print zone data: no file descriptor", 01593 zd_str); 01594 return ODS_STATUS_ASSERT_ERR; 01595 } 01596 ods_log_assert(fd); 01597 01598 if (!zd || !zd->domains) { 01599 ods_log_error("[%s] unable to print zone data: no zone data", 01600 zd_str); 01601 return ODS_STATUS_ASSERT_ERR; 01602 } 01603 ods_log_assert(zd); 01604 ods_log_assert(zd->domains); 01605 01606 node = ldns_rbtree_first(zd->domains); 01607 if (!node || node == LDNS_RBTREE_NULL) { 01608 fprintf(fd, "; empty zone\n"); 01609 return ODS_STATUS_OK; 01610 } 01611 while (node && node != LDNS_RBTREE_NULL) { 01612 domain = (domain_type*) node->data; 01613 domain_print(fd, domain); 01614 node = ldns_rbtree_next(node); 01615 } 01616 return ODS_STATUS_OK; 01617 }