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

/build/buildd-opendnssec_1.3.2-1~bpo60+1-powerpc-mjESd6/opendnssec-1.3.2/signer/src/signer/zonedata.c

Go to the documentation of this file.
00001 /*
00002  * $Id: zonedata.c 5432 2011-08-22 12:55:04Z 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     if (!zd->initialized) {
01196         prev = zd->inbound_serial;
01197     }
01198     ods_log_debug("[%s] update serial: in=%u internal=%u out=%u now=%u",
01199         zd_str, zd->inbound_serial, zd->internal_serial, zd->outbound_serial,
01200         (uint32_t) time_now());
01201 
01202     if (!sc->soa_serial) {
01203         ods_log_error("[%s] no serial type given", zd_str);
01204         return ODS_STATUS_ERR;
01205     }
01206 
01207     if (ods_strcmp(sc->soa_serial, "unixtime") == 0) {
01208         soa = (uint32_t) time_now();
01209         if (!DNS_SERIAL_GT(soa, prev)) {
01210             soa = prev + 1;
01211         }
01212     } else if (strncmp(sc->soa_serial, "counter", 7) == 0) {
01213         soa = zd->inbound_serial;
01214         if (zd->initialized && !DNS_SERIAL_GT(soa, prev)) {
01215             soa = prev + 1;
01216         }
01217     } else if (strncmp(sc->soa_serial, "datecounter", 11) == 0) {
01218         soa = (uint32_t) time_datestamp(0, "%Y%m%d", NULL) * 100;
01219         if (!DNS_SERIAL_GT(soa, prev)) {
01220             soa = prev + 1;
01221         }
01222     } else if (strncmp(sc->soa_serial, "keep", 4) == 0) {
01223         soa = zd->inbound_serial;
01224         if (zd->initialized && !DNS_SERIAL_GT(soa, prev)) {
01225             ods_log_error("[%s] cannot keep SOA SERIAL from input zone "
01226                 " (%u): previous output SOA SERIAL is %u", zd_str, soa, prev);
01227             return ODS_STATUS_CONFLICT_ERR;
01228         }
01229     } else {
01230         ods_log_error("[%s] unknown serial type %s", zd_str, sc->soa_serial);
01231         return ODS_STATUS_ERR;
01232     }
01233 
01234     /* serial is stored in 32 bits */
01235     update = soa - prev;
01236     if (update > 0x7FFFFFFF) {
01237         update = 0x7FFFFFFF;
01238     }
01239 
01240     if (!zd->initialized) {
01241         zd->internal_serial = soa;
01242     } else {
01243         zd->internal_serial += update; /* automatically does % 2^32 */
01244     }
01245     ods_log_debug("[%s] update serial: %u + %u = %u", zd_str, prev, update,
01246         zd->internal_serial);
01247     return ODS_STATUS_OK;
01248 }
01249 
01250 
01255 ods_status
01256 zonedata_queue(zonedata_type* zd, fifoq_type* q, worker_type* worker)
01257 {
01258     ldns_rbnode_t* node = LDNS_RBTREE_NULL;
01259     domain_type* domain = NULL;
01260     ods_status status = ODS_STATUS_OK;
01261 
01262     if (!zd || !zd->domains) {
01263         return ODS_STATUS_OK;
01264     }
01265     if (zd->domains->root != LDNS_RBTREE_NULL) {
01266         node = ldns_rbtree_first(zd->domains);
01267     }
01268     while (node && node != LDNS_RBTREE_NULL) {
01269         domain = (domain_type*) node->data;
01270         status = domain_queue(domain, q, worker);
01271         if (status != ODS_STATUS_OK) {
01272             return status;
01273         }
01274         node = ldns_rbtree_next(node);
01275     }
01276     return status;
01277 }
01278 
01279 
01284 static int
01285 zonedata_examine_domain_is_occluded(zonedata_type* zd, domain_type* domain,
01286     ldns_rdf* apex)
01287 {
01288     ldns_rdf* parent_rdf = NULL;
01289     ldns_rdf* next_rdf = NULL;
01290     domain_type* parent_domain = NULL;
01291     char* str_name = NULL;
01292     char* str_parent = NULL;
01293 
01294     ods_log_assert(apex);
01295     ods_log_assert(domain);
01296     ods_log_assert(domain->dname);
01297     ods_log_assert(zd);
01298     ods_log_assert(zd->domains);
01299 
01300     if (ldns_dname_compare(domain->dname, apex) == 0) {
01301         return 0;
01302     }
01303 
01304     if (domain_examine_valid_zonecut(domain) != 0) {
01305         log_rdf(domain->dname, "occluded (non-glue non-DS) data at NS", 2);
01306         return 1;
01307     }
01308 
01309     parent_rdf = ldns_dname_left_chop(domain->dname);
01310     while (parent_rdf && ldns_dname_is_subdomain(parent_rdf, apex) &&
01311            ldns_dname_compare(parent_rdf, apex) != 0) {
01312 
01313         parent_domain = zonedata_lookup_domain(zd, parent_rdf);
01314         next_rdf = ldns_dname_left_chop(parent_rdf);
01315         ldns_rdf_deep_free(parent_rdf);
01316 
01317         if (parent_domain) {
01318             /* check for DNAME or NS */
01319             if (domain_examine_data_exists(parent_domain, LDNS_RR_TYPE_DNAME,
01320                 0) && domain_examine_data_exists(domain, 0, 0)) {
01321                 /* data below DNAME */
01322                 str_name = ldns_rdf2str(domain->dname);
01323                 str_parent = ldns_rdf2str(parent_domain->dname);
01324                 ods_log_warning("[%s] occluded data at %s (below %s DNAME)",
01325                     zd_str, str_name, str_parent);
01326                 free((void*)str_name);
01327                 free((void*)str_parent);
01328                 return 1;
01329             } else if (domain_examine_data_exists(parent_domain,
01330                 LDNS_RR_TYPE_NS, 0) &&
01331                 domain_examine_data_exists(domain, 0, 1)) {
01332                 /* data (non-glue) below NS */
01333                 str_name = ldns_rdf2str(domain->dname);
01334                 str_parent = ldns_rdf2str(parent_domain->dname);
01335                 ods_log_warning("[%s] occluded (non-glue) data at %s (below "
01336                     "%s NS)", zd_str, str_name, str_parent);
01337                 free((void*)str_name);
01338                 free((void*)str_parent);
01339                 return 1;
01340 /* allow for now (root zone has it)
01341             } else if (domain_examine_data_exists(parent_domain,
01342                 LDNS_RR_TYPE_NS, 0) &&
01343                 domain_examine_data_exists(domain, 0, 0) &&
01344                 !domain_examine_ns_rdata(parent_domain, domain->dname)) {
01345                 str_name = ldns_rdf2str(domain->dname);
01346                 str_parent = ldns_rdf2str(parent_domain->dname);
01347                 ods_log_warning("[%s] occluded data at %s (below %s NS)",
01348                     zd_str, str_name, str_parent);
01349                 free((void*)str_name);
01350                 free((void*)str_parent);
01351                 return 1;
01352 */
01353             }
01354         }
01355         parent_rdf = next_rdf;
01356     }
01357     if (parent_rdf) {
01358         ldns_rdf_deep_free(parent_rdf);
01359     }
01360     return 0;
01361 }
01362 
01363 
01368 ods_status
01369 zonedata_examine(zonedata_type* zd, ldns_rdf* apex, adapter_mode mode)
01370 {
01371     int result = 0;
01372     ldns_rbnode_t* node = LDNS_RBTREE_NULL;
01373     domain_type* domain = NULL;
01374     ods_status status = ODS_STATUS_OK;
01375 
01376     if (!zd || !zd->domains) {
01377        /* no zone data, no error */
01378        return ODS_STATUS_OK;
01379     }
01380     ods_log_assert(zd);
01381     ods_log_assert(zd->domains);
01382 
01383     if (zd->domains->root != LDNS_RBTREE_NULL) {
01384         node = ldns_rbtree_first(zd->domains);
01385     }
01386     while (node && node != LDNS_RBTREE_NULL) {
01387         domain = (domain_type*) node->data;
01388         result =
01389         /* Thou shall not have other data next to CNAME */
01390         domain_examine_rrset_is_alone(domain, LDNS_RR_TYPE_CNAME) &&
01391         /* Thou shall have at most one CNAME per name */
01392         domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_CNAME) &&
01393         /* Thou shall have at most one DNAME per name */
01394         domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_DNAME);
01395         if (!result) {
01396             status = ODS_STATUS_ERR;
01397         }
01398 
01399         if (mode == ADAPTER_FILE) {
01400             result =
01401             /* Thou shall not have occluded data in your zone file */
01402             zonedata_examine_domain_is_occluded(zd, domain, apex);
01403             if (result) {
01404                 ; /* just warn if there is occluded data */
01405             }
01406         }
01407         node = ldns_rbtree_next(node);
01408     }
01409     return status;
01410 }
01411 
01412 
01417 void
01418 zonedata_wipe_denial(zonedata_type* zd)
01419 {
01420     ldns_rbnode_t* node = LDNS_RBTREE_NULL;
01421     denial_type* denial = NULL;
01422 
01423     if (zd && zd->denial_chain) {
01424         node = ldns_rbtree_first(zd->denial_chain);
01425         while (node && node != LDNS_RBTREE_NULL) {
01426             denial = (denial_type*) node->data;
01427             if (denial->rrset) {
01428                 /* [TODO] IXFR delete NSEC */
01429                 rrset_cleanup(denial->rrset);
01430                 denial->rrset = NULL;
01431             }
01432             node = ldns_rbtree_next(node);
01433         }
01434     }
01435     return;
01436 }
01437 
01438 
01443 static void
01444 domain_delfunc(ldns_rbnode_t* elem)
01445 {
01446     domain_type* domain = NULL;
01447 
01448     if (elem && elem != LDNS_RBTREE_NULL) {
01449         domain = (domain_type*) elem->data;
01450         domain_delfunc(elem->left);
01451         domain_delfunc(elem->right);
01452 
01453         domain_cleanup(domain);
01454         free((void*)elem);
01455     }
01456     return;
01457 }
01458 
01459 
01464 static void
01465 denial_delfunc(ldns_rbnode_t* elem)
01466 {
01467     denial_type* denial = NULL;
01468     domain_type* domain = NULL;
01469 
01470 
01471     if (elem && elem != LDNS_RBTREE_NULL) {
01472         denial = (denial_type*) elem->data;
01473         denial_delfunc(elem->left);
01474         denial_delfunc(elem->right);
01475 
01476         domain = denial->domain;
01477         if (domain) {
01478             domain->denial = NULL;
01479         }
01480         denial_cleanup(denial);
01481 
01482         free((void*)elem);
01483     }
01484     return;
01485 }
01486 
01487 
01492 static void
01493 zonedata_cleanup_domains(zonedata_type* zd)
01494 {
01495     if (zd && zd->domains) {
01496         domain_delfunc(zd->domains->root);
01497         ldns_rbtree_free(zd->domains);
01498         zd->domains = NULL;
01499     }
01500     return;
01501 }
01502 
01503 
01508 void
01509 zonedata_cleanup_chain(zonedata_type* zd)
01510 {
01511     if (zd && zd->denial_chain) {
01512         denial_delfunc(zd->denial_chain->root);
01513         ldns_rbtree_free(zd->denial_chain);
01514         zd->denial_chain = NULL;
01515     }
01516     return;
01517 }
01518 
01519 
01524 void
01525 zonedata_cleanup(zonedata_type* zd)
01526 {
01527     allocator_type* allocator;
01528 
01529     if (!zd) {
01530         return;
01531     }
01532     zonedata_cleanup_chain(zd);
01533     zonedata_cleanup_domains(zd);
01534     allocator = zd->allocator;
01535     allocator_deallocate(allocator, (void*) zd);
01536     return;
01537 }
01538 
01539 
01544 void
01545 zonedata_backup(FILE* fd, zonedata_type* zd)
01546 {
01547     ldns_rbnode_t* node = LDNS_RBTREE_NULL;
01548     domain_type* domain = NULL;
01549 
01550     if (!fd || !zd) {
01551         return;
01552     }
01553 
01554     node = ldns_rbtree_first(zd->domains);
01555     while (node && node != LDNS_RBTREE_NULL) {
01556         domain = (domain_type*) node->data;
01557         domain_backup(fd, domain);
01558         node = ldns_rbtree_next(node);
01559     }
01560     fprintf(fd, ";;\n");
01561     return;
01562 }
01563 
01564 
01569 ods_status
01570 zonedata_print(FILE* fd, zonedata_type* zd)
01571 {
01572     ldns_rbnode_t* node = LDNS_RBTREE_NULL;
01573     domain_type* domain = NULL;
01574 
01575     if (!fd) {
01576         ods_log_error("[%s] unable to print zone data: no file descriptor",
01577             zd_str);
01578         return ODS_STATUS_ASSERT_ERR;
01579     }
01580     ods_log_assert(fd);
01581 
01582     if (!zd || !zd->domains) {
01583         ods_log_error("[%s] unable to print zone data: no zone data",
01584             zd_str);
01585         return ODS_STATUS_ASSERT_ERR;
01586     }
01587     ods_log_assert(zd);
01588     ods_log_assert(zd->domains);
01589 
01590     node = ldns_rbtree_first(zd->domains);
01591     if (!node || node == LDNS_RBTREE_NULL) {
01592         fprintf(fd, "; empty zone\n");
01593         return ODS_STATUS_OK;
01594     }
01595     while (node && node != LDNS_RBTREE_NULL) {
01596         domain = (domain_type*) node->data;
01597         domain_print(fd, domain);
01598         node = ldns_rbtree_next(node);
01599     }
01600     return ODS_STATUS_OK;
01601 }

Generated on Sat Dec 17 2011 10:26:15 for OpenDNSSEC-signer by  doxygen 1.7.1