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