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