OpenDNSSEC-signer 1.2.1
|
00001 /* 00002 * $Id: domain.c 4523 2011-03-03 12:48:18Z 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 "signer/backup.h" 00036 #include "signer/domain.h" 00037 #include "signer/hsm.h" 00038 #include "signer/rrset.h" 00039 #include "util/duration.h" 00040 #include "util/log.h" 00041 #include "util/se_malloc.h" 00042 #include "util/util.h" 00043 00044 #include <ldns/ldns.h> /* ldns_*() */ 00045 00046 00051 static int 00052 rrset_compare(const void* a, const void* b) 00053 { 00054 ldns_rr_type* x = (ldns_rr_type*)a; 00055 ldns_rr_type* y = (ldns_rr_type*)b; 00056 return (*x)-(*y); 00057 } 00058 00059 00064 domain_type* 00065 domain_create(ldns_rdf* dname) 00066 { 00067 domain_type* domain = (domain_type*) se_malloc(sizeof(domain_type)); 00068 se_log_assert(dname); 00069 00070 domain->name = ldns_rdf_clone(dname); 00071 domain->parent = NULL; 00072 domain->denial = NULL; 00073 domain->rrsets = ldns_rbtree_create(rrset_compare); 00074 domain->domain_status = DOMAIN_STATUS_NONE; 00075 domain->internal_serial = 0; 00076 domain->initialized = 0; 00077 domain->outbound_serial = 0; 00078 domain->subdomain_count = 0; 00079 domain->subdomain_auth = 0; 00080 return domain; 00081 } 00082 00083 00088 domain_type* 00089 domain_recover_from_backup(FILE* fd, int* curnxt, int* curbm) 00090 { 00091 domain_type* domain = NULL; 00092 const char* name = NULL; 00093 uint32_t internal_serial = 0; 00094 uint32_t outbound_serial = 0; 00095 int domain_status = DOMAIN_STATUS_NONE; 00096 size_t subdomain_count = 0; 00097 size_t subdomain_auth = 0; 00098 int nsec_bitmap_changed = 0; 00099 int nsec_nxt_changed = 0; 00100 00101 se_log_assert(fd); 00102 00103 if (!backup_read_str(fd, &name) || 00104 !backup_read_uint32_t(fd, &internal_serial) || 00105 !backup_read_uint32_t(fd, &outbound_serial) || 00106 !backup_read_int(fd, &domain_status) || 00107 !backup_read_size_t(fd, &subdomain_count) || 00108 !backup_read_size_t(fd, &subdomain_auth) || 00109 !backup_read_int(fd, &nsec_bitmap_changed) || 00110 !backup_read_int(fd, &nsec_nxt_changed)) { 00111 se_log_error("domain part in backup file is corrupted"); 00112 if (name) { 00113 se_free((void*)name); 00114 } 00115 return NULL; 00116 } 00117 00118 domain = (domain_type*) se_malloc(sizeof(domain_type)); 00119 se_log_assert(name); 00120 domain->name = ldns_dname_new_frm_str(name); 00121 if (!domain->name) { 00122 se_log_error("failed to create domain from name"); 00123 se_free((void*)name); 00124 se_free((void*)domain); 00125 return NULL; 00126 } 00127 domain->parent = NULL; 00128 domain->denial = NULL; 00129 domain->rrsets = ldns_rbtree_create(rrset_compare); 00130 domain->domain_status = domain_status; 00131 domain->internal_serial = internal_serial; 00132 domain->initialized = 0; 00133 domain->outbound_serial = outbound_serial; 00134 domain->subdomain_count = subdomain_count; 00135 domain->subdomain_auth = subdomain_auth; 00136 se_log_deeebug("recovered domain %s internal_serial=%u, " 00137 "outbound_serial=%u, domain_status=%i, nsec_status=(%i, %i)", 00138 name, domain->internal_serial, domain->outbound_serial, 00139 domain->domain_status, nsec_bitmap_changed, 00140 nsec_nxt_changed); 00141 00142 se_free((void*)name); 00143 if (curnxt) { 00144 *curnxt = nsec_nxt_changed; 00145 } 00146 if (curbm) { 00147 *curbm = nsec_bitmap_changed; 00148 } 00149 return domain; 00150 } 00151 00156 static ldns_rbnode_t* 00157 rrset2node(rrset_type* rrset) 00158 { 00159 ldns_rbnode_t* node = (ldns_rbnode_t*) se_malloc(sizeof(ldns_rbnode_t)); 00160 node->key = &(rrset->rr_type); 00161 node->data = rrset; 00162 return node; 00163 } 00164 00165 00170 rrset_type* 00171 domain_lookup_rrset(domain_type* domain, ldns_rr_type type) 00172 { 00173 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00174 00175 se_log_assert(domain); 00176 se_log_assert(domain->rrsets); 00177 00178 node = ldns_rbtree_search(domain->rrsets, &(type)); 00179 if (node && node != LDNS_RBTREE_NULL) { 00180 return (rrset_type*) node->data; 00181 } 00182 return NULL; 00183 } 00184 00185 00190 rrset_type* 00191 domain_add_rrset(domain_type* domain, rrset_type* rrset, int recover) 00192 { 00193 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00194 char* str = NULL; 00195 00196 se_log_assert(rrset); 00197 se_log_assert(domain); 00198 se_log_assert(domain->rrsets); 00199 00200 new_node = rrset2node(rrset); 00201 if (ldns_rbtree_insert(domain->rrsets, new_node) == NULL) { 00202 str = ldns_rdf2str(domain->name); 00203 se_log_error("unable to add RRset %i to domain %s: already present", 00204 rrset->rr_type, str?str:"(null)"); 00205 se_free((void*)str); 00206 se_free((void*)new_node); 00207 return NULL; 00208 } 00209 if (!recover && domain->denial) { 00210 domain->denial->bitmap_changed = 1; 00211 } 00212 return rrset; 00213 } 00214 00215 00220 rrset_type* 00221 domain_del_rrset(domain_type* domain, rrset_type* rrset, int recover) 00222 { 00223 rrset_type* del_rrset = NULL; 00224 ldns_rbnode_t* del_node = NULL; 00225 char* str = NULL; 00226 00227 se_log_assert(rrset); 00228 se_log_assert(domain); 00229 se_log_assert(domain->rrsets); 00230 00231 del_node = ldns_rbtree_delete(domain->rrsets, 00232 (const void*)&rrset->rr_type); 00233 if (del_node) { 00234 del_rrset = (rrset_type*) del_node->data; 00235 rrset_cleanup(del_rrset); 00236 se_free((void*)del_node); 00237 if (!recover && domain->denial) { 00238 domain->denial->bitmap_changed = 1; 00239 } 00240 return NULL; 00241 } else { 00242 str = ldns_rdf2str(domain->name); 00243 se_log_error("unable to delete RRset %i from domain %s: " 00244 "not in tree", rrset->rr_type, str?str:"(null)"); 00245 se_free((void*)str); 00246 return rrset; 00247 } 00248 return rrset; 00249 } 00250 00251 00256 int domain_count_rrset(domain_type* domain) 00257 { 00258 se_log_assert(domain); 00259 if (!domain->rrsets) { 00260 return 0; 00261 } 00262 return domain->rrsets->count; 00263 } 00264 00265 00270 int 00271 domain_examine_data_exists(domain_type* domain, ldns_rr_type rrtype, 00272 int skip_glue) 00273 { 00274 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00275 rrset_type* rrset = NULL; 00276 00277 se_log_assert(domain); 00278 00279 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00280 node = ldns_rbtree_first(domain->rrsets); 00281 } 00282 while (node && node != LDNS_RBTREE_NULL) { 00283 rrset = (rrset_type*) node->data; 00284 if (rrset_count_RR(rrset) > 0) { 00285 if (rrtype) { 00286 /* looking for a specific RRset */ 00287 if (rrset->rr_type == rrtype) { 00288 return 0; 00289 } 00290 } else if (!skip_glue || 00291 (rrset->rr_type != LDNS_RR_TYPE_A && 00292 rrset->rr_type != LDNS_RR_TYPE_AAAA)) { 00293 /* not glue or not skipping glue */ 00294 return 0; 00295 } 00296 } 00297 node = ldns_rbtree_next(node); 00298 } 00299 return 1; 00300 } 00301 00302 00307 int 00308 domain_examine_ns_rdata(domain_type* domain, ldns_rdf* nsdname) 00309 { 00310 rrset_type* rrset = NULL; 00311 00312 se_log_assert(domain); 00313 if (!nsdname) { 00314 return 1; 00315 } 00316 00317 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS); 00318 if (rrset && rrset_count_RR(rrset) > 0) { 00319 /* NS RRset exists after update */ 00320 if (rrset_examine_ns_rdata(rrset, nsdname) == 0) { 00321 return 0; 00322 } 00323 } 00324 return 1; 00325 } 00326 00327 00332 int 00333 domain_examine_rrset_is_alone(domain_type* domain, ldns_rr_type rrtype) 00334 { 00335 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00336 rrset_type* rrset = NULL; 00337 ldns_dnssec_rrs* rrs = NULL; 00338 char* str_name = NULL; 00339 char* str_type = NULL; 00340 00341 se_log_assert(domain); 00342 se_log_assert(rrtype); 00343 00344 rrset = domain_lookup_rrset(domain, rrtype); 00345 if (rrset && rrset_count_RR(rrset) > 0) { 00346 if (domain_count_rrset(domain) < 2) { 00347 /* one or zero, that's ok */ 00348 return 0; 00349 } 00350 /* make sure all other RRsets become empty */ 00351 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00352 node = ldns_rbtree_first(domain->rrsets); 00353 } 00354 while (node && node != LDNS_RBTREE_NULL) { 00355 rrset = (rrset_type*) node->data; 00356 if (rrset->rr_type != rrtype && rrset_count_RR(rrset) > 0) { 00357 /* found other data next to rrtype */ 00358 str_name = ldns_rdf2str(domain->name); 00359 str_type = ldns_rr_type2str(rrtype); 00360 se_log_error("other data next to %s %s", str_name, str_type); 00361 rrs = rrset->rrs; 00362 while (rrs) { 00363 if (rrs->rr) { 00364 log_rr(rrs->rr, "next-to-CNAME: ", 2); 00365 } 00366 rrs = rrs->next; 00367 } 00368 rrs = rrset->add; 00369 while (rrs) { 00370 if (rrs->rr) { 00371 log_rr(rrs->rr, "next-to-CNAME: ", 2); 00372 } 00373 rrs = rrs->next; 00374 } 00375 se_free((void*)str_name); 00376 se_free((void*)str_type); 00377 return 1; 00378 } 00379 node = ldns_rbtree_next(node); 00380 } 00381 } 00382 return 0; 00383 } 00384 00385 00390 int 00391 domain_examine_valid_zonecut(domain_type* domain) 00392 { 00393 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00394 rrset_type* rrset = NULL; 00395 00396 se_log_assert(domain); 00397 00398 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS); 00399 if (rrset && rrset_count_RR(rrset) > 0) { 00400 /* make sure all other RRsets become empty (except DS, glue) */ 00401 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00402 node = ldns_rbtree_first(domain->rrsets); 00403 } 00404 while (node && node != LDNS_RBTREE_NULL) { 00405 rrset = (rrset_type*) node->data; 00406 if (rrset->rr_type != LDNS_RR_TYPE_DS && 00407 rrset->rr_type != LDNS_RR_TYPE_NS && 00408 rrset->rr_type != LDNS_RR_TYPE_A && 00409 rrset->rr_type != LDNS_RR_TYPE_AAAA && 00410 rrset_count_RR(rrset) > 0) { 00411 /* found occluded data next to delegation */ 00412 se_log_error("occluded glue data at zonecut, RRtype=%u", 00413 rrset->rr_type); 00414 return 1; 00415 } else if (rrset->rr_type == LDNS_RR_TYPE_A || 00416 rrset->rr_type == LDNS_RR_TYPE_AAAA) { 00417 /* check if glue is allowed at the delegation */ 00418 if (rrset_count_RR(rrset) > 0 && 00419 domain_examine_ns_rdata(domain, domain->name) != 0) { 00420 se_log_error("occluded glue data at zonecut, #RR=%u", 00421 rrset_count_RR(rrset)); 00422 return 1; 00423 } 00424 } 00425 00426 node = ldns_rbtree_next(node); 00427 } 00428 } 00429 return 0; 00430 } 00431 00432 00437 int 00438 domain_examine_rrset_is_singleton(domain_type* domain, ldns_rr_type rrtype) 00439 { 00440 rrset_type* rrset = NULL; 00441 char* str_name = NULL; 00442 char* str_type = NULL; 00443 00444 se_log_assert(domain); 00445 se_log_assert(rrtype); 00446 00447 rrset = domain_lookup_rrset(domain, rrtype); 00448 if (rrset && rrset_count_RR(rrset) > 1) { 00449 /* multiple RRs in the RRset for singleton RRtype*/ 00450 str_name = ldns_rdf2str(domain->name); 00451 str_type = ldns_rr_type2str(rrtype); 00452 se_log_error("multiple records for singleton type at %s %s", 00453 str_name, str_type); 00454 se_free((void*)str_name); 00455 se_free((void*)str_type); 00456 return 1; 00457 } 00458 return 0; 00459 } 00460 00461 00466 int 00467 domain_update(domain_type* domain, uint32_t serial) 00468 { 00469 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00470 rrset_type* rrset = NULL; 00471 00472 se_log_assert(serial); 00473 se_log_assert(domain); 00474 se_log_assert(domain->rrsets); 00475 00476 if (!domain->initialized || DNS_SERIAL_GT(serial, domain->internal_serial)) { 00477 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00478 node = ldns_rbtree_first(domain->rrsets); 00479 } 00480 while (node && node != LDNS_RBTREE_NULL) { 00481 rrset = (rrset_type*) node->data; 00482 if (rrset->rr_type == LDNS_RR_TYPE_SOA && rrset->rrs && 00483 rrset->rrs->rr) { 00484 rrset->drop_signatures = 1; 00485 } 00486 00487 if (rrset_update(rrset, serial) != 0) { 00488 se_log_error("failed to update domain to serial %u: failed " 00489 "to update RRset", serial); 00490 return 1; 00491 } 00492 node = ldns_rbtree_next(node); 00493 /* delete memory of RRsets if no RRs exist */ 00494 if (rrset_count_rr(rrset) <= 0) { 00495 rrset = domain_del_rrset(domain, rrset, 0); 00496 if (rrset) { 00497 se_log_error("failed to delete obsoleted RRset"); 00498 } 00499 } 00500 } 00501 domain->internal_serial = serial; 00502 domain->initialized = 1; 00503 } else { 00504 se_log_error("cannot update domain: serial %u should be larger than " 00505 "domain internal serial %u", serial, domain->internal_serial); 00506 return 2; 00507 } 00508 return 0; 00509 } 00510 00511 00516 void 00517 domain_cancel_update(domain_type* domain) 00518 { 00519 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00520 rrset_type* rrset = NULL; 00521 00522 se_log_assert(domain); 00523 se_log_assert(domain->rrsets); 00524 00525 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00526 node = ldns_rbtree_first(domain->rrsets); 00527 } 00528 while (node && node != LDNS_RBTREE_NULL) { 00529 rrset = (rrset_type*) node->data; 00530 rrset_cancel_update(rrset); 00531 node = ldns_rbtree_next(node); 00532 } 00533 return; 00534 } 00535 00536 00541 void 00542 domain_update_status(domain_type* domain) 00543 { 00544 domain_type* parent = NULL; 00545 00546 se_log_assert(domain); 00547 if (domain->domain_status == DOMAIN_STATUS_APEX) { 00548 return; 00549 } 00550 00551 if (domain_count_rrset(domain) <= 0) { 00552 /* Empty Non-Terminal */ 00553 return; /* we don't care */ 00554 } 00555 00556 if (domain_lookup_rrset(domain, LDNS_RR_TYPE_NS)) { 00557 if (domain_lookup_rrset(domain, LDNS_RR_TYPE_DS)) { 00558 domain->domain_status = DOMAIN_STATUS_DS; 00559 } else { 00560 domain->domain_status = DOMAIN_STATUS_NS; 00561 } 00562 } else { /* else, it is just an authoritative domain */ 00563 domain->domain_status = DOMAIN_STATUS_AUTH; 00564 } 00565 00566 parent = domain->parent; 00567 while (parent && parent->domain_status != DOMAIN_STATUS_APEX) { 00568 if (domain_lookup_rrset(parent, LDNS_RR_TYPE_DNAME) || 00569 domain_lookup_rrset(parent, LDNS_RR_TYPE_NS)) { 00570 domain->domain_status = DOMAIN_STATUS_OCCLUDED; 00571 return; 00572 } 00573 parent = parent->parent; 00574 } 00575 return; 00576 } 00577 00578 00583 int 00584 domain_sign(hsm_ctx_t* ctx, domain_type* domain, ldns_rdf* owner, 00585 signconf_type* sc, time_t signtime, uint32_t serial, stats_type* stats) 00586 { 00587 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00588 ldns_rdf* soa_serial = NULL; 00589 rrset_type* rrset = NULL; 00590 int error = 0; 00591 00592 se_log_assert(domain); 00593 se_log_assert(domain->rrsets); 00594 se_log_assert(owner); 00595 se_log_assert(sc); 00596 se_log_assert(signtime); 00597 se_log_assert(stats); 00598 00599 if (domain->domain_status == DOMAIN_STATUS_NONE || 00600 domain->domain_status == DOMAIN_STATUS_OCCLUDED) { 00601 return 0; 00602 } 00603 00604 if (domain->denial && domain->denial->rrset) { 00605 error = rrset_sign(ctx, domain->denial->rrset, owner, sc, signtime, stats); 00606 if (error) { 00607 return error; 00608 } 00609 } 00610 00611 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00612 node = ldns_rbtree_first(domain->rrsets); 00613 } 00614 while (node && node != LDNS_RBTREE_NULL) { 00615 rrset = (rrset_type*) node->data; 00616 00617 /* skip delegation RRsets */ 00618 if (domain->domain_status != DOMAIN_STATUS_APEX && 00619 rrset->rr_type == LDNS_RR_TYPE_NS) { 00620 node = ldns_rbtree_next(node); 00621 continue; 00622 } 00623 /* skip glue at the delegation */ 00624 if ((domain->domain_status == DOMAIN_STATUS_DS || 00625 domain->domain_status == DOMAIN_STATUS_NS) && 00626 (rrset->rr_type == LDNS_RR_TYPE_A || 00627 rrset->rr_type == LDNS_RR_TYPE_AAAA)) { 00628 node = ldns_rbtree_next(node); 00629 continue; 00630 } 00631 00632 if (rrset->rr_type == LDNS_RR_TYPE_SOA && rrset->rrs && 00633 rrset->rrs->rr) { 00634 soa_serial = ldns_rr_set_rdf(rrset->rrs->rr, 00635 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, serial), 00636 SE_SOA_RDATA_SERIAL); 00637 if (soa_serial) { 00638 if (ldns_rdf2native_int32(soa_serial) != serial) { 00639 rrset->drop_signatures = 1; 00640 } 00641 ldns_rdf_deep_free(soa_serial); 00642 } else { 00643 se_log_error("unable to sign domain: failed to replace " 00644 "SOA SERIAL rdata"); 00645 return 1; 00646 } 00647 } 00648 00649 error = rrset_sign(ctx, rrset, owner, sc, signtime, stats); 00650 if (error) { 00651 se_log_error("failed to sign RRset[%i]", (int) rrset->rr_type); 00652 return error; 00653 } 00654 node = ldns_rbtree_next(node); 00655 } 00656 00657 return 0; 00658 } 00659 00660 00665 int 00666 domain_add_rr(domain_type* domain, ldns_rr* rr) 00667 { 00668 rrset_type* rrset = NULL; 00669 00670 se_log_assert(rr); 00671 se_log_assert(domain); 00672 se_log_assert(domain->name); 00673 se_log_assert(domain->rrsets); 00674 se_log_assert((ldns_dname_compare(domain->name, ldns_rr_owner(rr)) == 0)); 00675 00676 rrset = domain_lookup_rrset(domain, ldns_rr_get_type(rr)); 00677 if (rrset) { 00678 return rrset_add_rr(rrset, rr); 00679 } 00680 /* no RRset with this RRtype yet */ 00681 rrset = rrset_create(ldns_rr_get_type(rr)); 00682 rrset = domain_add_rrset(domain, rrset, 0); 00683 if (!rrset) { 00684 se_log_error("unable to add RR to domain: failed to add RRset"); 00685 return 1; 00686 } 00687 return rrset_add_rr(rrset, rr); 00688 } 00689 00690 00695 int 00696 domain_recover_rr_from_backup(domain_type* domain, ldns_rr* rr) 00697 { 00698 rrset_type* rrset = NULL; 00699 00700 se_log_assert(rr); 00701 se_log_assert(domain); 00702 se_log_assert(domain->name); 00703 se_log_assert(domain->rrsets); 00704 se_log_assert((ldns_dname_compare(domain->name, ldns_rr_owner(rr)) == 0)); 00705 00706 rrset = domain_lookup_rrset(domain, ldns_rr_get_type(rr)); 00707 if (rrset) { 00708 return rrset_recover_rr_from_backup(rrset, rr); 00709 } 00710 /* no RRset with this RRtype yet */ 00711 rrset = rrset_create(ldns_rr_get_type(rr)); 00712 rrset = domain_add_rrset(domain, rrset, 1); 00713 if (!rrset) { 00714 se_log_error("unable to recover RR to domain: failed to add RRset"); 00715 return 1; 00716 } 00717 return rrset_recover_rr_from_backup(rrset, rr); 00718 } 00719 00720 00725 int 00726 domain_recover_rrsig_from_backup(domain_type* domain, ldns_rr* rrsig, 00727 ldns_rr_type type_covered, const char* locator, uint32_t flags) 00728 { 00729 rrset_type* rrset = NULL; 00730 00731 se_log_assert(rrsig); 00732 se_log_assert(domain); 00733 se_log_assert(domain->name); 00734 se_log_assert(domain->rrsets); 00735 se_log_assert((ldns_dname_compare(domain->name, 00736 ldns_rr_owner(rrsig)) == 0)); 00737 00738 if (type_covered == LDNS_RR_TYPE_NSEC || 00739 type_covered == LDNS_RR_TYPE_NSEC3) { 00740 if (domain->denial && domain->denial->rrset) { 00741 return rrset_recover_rrsig_from_backup(domain->denial->rrset, 00742 rrsig, locator, flags); 00743 } else if (type_covered == LDNS_RR_TYPE_NSEC) { 00744 se_log_error("unable to recover RRSIG to domain: no NSEC RRset"); 00745 } else { 00746 se_log_error("unable to recover RRSIG to domain: no NSEC3 RRset"); 00747 } 00748 } else { 00749 rrset = domain_lookup_rrset(domain, type_covered); 00750 if (rrset) { 00751 return rrset_recover_rrsig_from_backup(rrset, rrsig, 00752 locator, flags); 00753 } else { 00754 se_log_error("unable to recover RRSIG to domain: no such RRset"); 00755 } 00756 } 00757 return 1; 00758 } 00759 00760 00765 int 00766 domain_del_rr(domain_type* domain, ldns_rr* rr) 00767 { 00768 rrset_type* rrset = NULL; 00769 00770 se_log_assert(rr); 00771 se_log_assert(domain); 00772 se_log_assert(domain->name); 00773 se_log_assert(domain->rrsets); 00774 se_log_assert((ldns_dname_compare(domain->name, ldns_rr_owner(rr)) == 0)); 00775 00776 rrset = domain_lookup_rrset(domain, ldns_rr_get_type(rr)); 00777 if (rrset) { 00778 return rrset_del_rr(rrset, rr); 00779 } 00780 /* no RRset with this RRtype yet */ 00781 se_log_warning("unable to delete RR from domain: no such RRset " 00782 "[rrtype %i]", ldns_rr_get_type(rr)); 00783 return 0; /* well, it is not present in the zone anymore, is it? */ 00784 } 00785 00786 00791 int 00792 domain_del_rrs(domain_type* domain) 00793 { 00794 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00795 rrset_type* rrset = NULL; 00796 00797 se_log_assert(domain); 00798 se_log_assert(domain->rrsets); 00799 00800 if (domain->rrsets->root != LDNS_RBTREE_NULL) { 00801 node = ldns_rbtree_first(domain->rrsets); 00802 } 00803 while (node && node != LDNS_RBTREE_NULL) { 00804 rrset = (rrset_type*) node->data; 00805 if (rrset_del_rrs(rrset) != 0) { 00806 return 1; 00807 } 00808 node = ldns_rbtree_next(node); 00809 } 00810 return 0; 00811 } 00812 00813 00818 static void 00819 domain_cleanup_rrsets(ldns_rbtree_t* rrset_tree) 00820 { 00821 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00822 rrset_type* rrset = NULL; 00823 00824 if (rrset_tree && rrset_tree->root != LDNS_RBTREE_NULL) { 00825 node = ldns_rbtree_first(rrset_tree); 00826 } 00827 while (node && node != LDNS_RBTREE_NULL) { 00828 rrset = (rrset_type*) node->data; 00829 rrset_cleanup(rrset); 00830 node = ldns_rbtree_next(node); 00831 } 00832 if (rrset_tree && rrset_tree->root != LDNS_RBTREE_NULL) { 00833 se_rbnode_free(rrset_tree->root); 00834 } 00835 if (rrset_tree) { 00836 ldns_rbtree_free(rrset_tree); 00837 } 00838 return; 00839 } 00840 00841 00846 void 00847 domain_cleanup(domain_type* domain) 00848 { 00849 if (domain) { 00850 if (domain->name) { 00851 ldns_rdf_deep_free(domain->name); 00852 domain->name = NULL; 00853 } 00854 if (domain->rrsets) { 00855 domain_cleanup_rrsets(domain->rrsets); 00856 domain->rrsets = NULL; 00857 } 00858 /* don't destroy corresponding parent and nsec3 domain */ 00859 se_free((void*) domain); 00860 } else { 00861 se_log_warning("cleanup empty domain"); 00862 } 00863 return; 00864 } 00865 00866 00871 void 00872 domain_print(FILE* fd, domain_type* domain) 00873 { 00874 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00875 domain_type* parent = NULL; 00876 int print_glue = 0; 00877 rrset_type* rrset = NULL; 00878 rrset_type* soa_rrset = NULL; 00879 rrset_type* cname_rrset = NULL; 00880 00881 if (domain->rrsets && domain->rrsets->root != LDNS_RBTREE_NULL) { 00882 node = ldns_rbtree_first(domain->rrsets); 00883 } 00884 00885 /* no other data may accompany a CNAME */ 00886 cname_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_CNAME); 00887 if (cname_rrset) { 00888 rrset_print(fd, cname_rrset, 0); 00889 } else { 00890 /* if SOA, print soa first */ 00891 soa_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_SOA); 00892 if (soa_rrset) { 00893 rrset_print(fd, soa_rrset, 0); 00894 } 00895 00896 /* print other RRsets */ 00897 while (node && node != LDNS_RBTREE_NULL) { 00898 rrset = (rrset_type*) node->data; 00899 if (rrset->rr_type != LDNS_RR_TYPE_SOA) { 00900 if (domain->domain_status == DOMAIN_STATUS_NONE || 00901 domain->domain_status == DOMAIN_STATUS_OCCLUDED) { 00902 00903 parent = domain->parent; 00904 print_glue = 0; 00905 while (parent && parent->domain_status != DOMAIN_STATUS_APEX) { 00906 if (domain_lookup_rrset(parent, LDNS_RR_TYPE_NS)) { 00907 print_glue = 1; 00908 break; 00909 } 00910 parent = parent->parent; 00911 } 00912 00913 /* only output glue */ 00914 if (print_glue && (rrset->rr_type == LDNS_RR_TYPE_A || 00915 rrset->rr_type == LDNS_RR_TYPE_AAAA)) { 00916 rrset_print(fd, rrset, 0); 00917 } 00918 } else { 00919 rrset_print(fd, rrset, 0); 00920 } 00921 } 00922 00923 node = ldns_rbtree_next(node); 00924 } 00925 } 00926 00927 /* print NSEC(3) */ 00928 if (domain->denial && domain->denial->rrset) { 00929 rrset_print(fd, domain->denial->rrset, 0); 00930 } 00931 return; 00932 } 00933 00934 00939 void 00940 domain_print_nsec(FILE* fd, domain_type* domain) 00941 { 00942 char* str = NULL; 00943 int nsec_bitmap_changed = 0; 00944 int nsec_nxt_changed = 0; 00945 ldns_rr* rr = NULL; 00946 00947 if (domain->denial) { 00948 nsec_bitmap_changed = domain->denial->bitmap_changed; 00949 nsec_nxt_changed = domain->denial->nxt_changed; 00950 } 00951 00952 str = ldns_rdf2str(domain->name); 00953 fprintf(fd, ";DNAME %s %u %u %i %i %i %i %i\n", str, 00954 domain->internal_serial, domain->outbound_serial, 00955 (int) domain->domain_status, 00956 (int) domain->subdomain_count, (int) domain->subdomain_auth, 00957 nsec_bitmap_changed, nsec_nxt_changed); 00958 se_free((void*) str); 00959 00960 if (domain->denial && domain->denial->rrset && 00961 domain->denial->rrset->rrs && domain->denial->rrset->rrs->rr) { 00962 00963 rr = domain->denial->rrset->rrs->rr; 00964 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3) { 00965 str = ldns_rdf2str(domain->denial->owner); 00966 fprintf(fd, ";DNAME3 %s %u %u %i %i %i %i %i\n", str, 00967 domain->internal_serial, domain->outbound_serial, 00968 DOMAIN_STATUS_HASH, 0, 0, nsec_bitmap_changed, 00969 nsec_nxt_changed); 00970 se_free((void*) str); 00971 00972 fprintf(fd, ";NSEC3\n"); 00973 00974 00975 } else { 00976 fprintf(fd, ";NSEC\n"); 00977 } 00978 ldns_rr_print(fd, rr); 00979 } 00980 return; 00981 } 00982 00983 00988 void 00989 domain_print_rrsig(FILE* fd, domain_type* domain) 00990 { 00991 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00992 rrset_type* rrset = NULL; 00993 00994 if (domain->rrsets && domain->rrsets->root != LDNS_RBTREE_NULL) { 00995 node = ldns_rbtree_first(domain->rrsets); 00996 } 00997 00998 while (node && node != LDNS_RBTREE_NULL) { 00999 rrset = (rrset_type*) node->data; 01000 rrset_print_rrsig(fd, rrset); 01001 node = ldns_rbtree_next(node); 01002 } 01003 01004 /* print nsec */ 01005 if (domain->denial && domain->denial->rrset) { 01006 rrset_print_rrsig(fd, domain->denial->rrset); 01007 } 01008 return; 01009 }