• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

/build/buildd-opendnssec_1.3.2-1~bpo60+1-kfreebsd-i386-KuwQV_/opendnssec-1.3.2/signer/src/signer/domain.c

Go to the documentation of this file.
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 }

Generated on Sun Dec 18 2011 10:32:15 for OpenDNSSEC-signer by  doxygen 1.7.1