00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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>
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;
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
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
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
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
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
00253 free((void*) owner);
00254 owner = NULL;
00255 domain = NULL;
00256 } else if (ods_strcmp(token, ";;") == 0) {
00257
00258 free((void*) token);
00259 token = NULL;
00260 return ODS_STATUS_OK;
00261 } else {
00262
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
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
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
00535 denial = denial_create(owner);
00536 new_node = denial2node(denial);
00537 ldns_rdf_deep_free(owner);
00538
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
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;
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
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
00711 if (domain_count_rrset(domain) <= 0) {
00712
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
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 }
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
00777 return 1;
00778 }
00779 if (nextdomain->dstatus != DOMAIN_STATUS_OCCLUDED &&
00780 nextdomain->dstatus != DOMAIN_STATUS_ENT &&
00781 nextdomain->dstatus != DOMAIN_STATUS_NONE) {
00782
00783 return 0;
00784 }
00785 nextnode = ldns_rbtree_next(nextnode);
00786 }
00787 } else {
00788
00789 ods_log_assert(domain_count_rrset(domain) != 0);
00790 return 0;
00791 }
00792
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
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
00823 return 0;
00824 }
00825 nextnode = ldns_rbtree_next(nextnode);
00826 }
00827 } else {
00828
00829 ods_log_assert(domain_count_rrset(domain) != 0);
00830 return 0;
00831 }
00832
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
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
00895 domain = parent_domain;
00896 } else {
00897 ldns_rdf_deep_free(parent_rdf);
00898 domain->parent = parent_domain;
00899
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
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
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
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
01093 if (nsec3params->flags) {
01094
01095
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
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
01134
01142
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
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;
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
01319 if (domain_examine_data_exists(parent_domain, LDNS_RR_TYPE_DNAME,
01320 0) && domain_examine_data_exists(domain, 0, 0)) {
01321
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
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
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
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
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
01390 domain_examine_rrset_is_alone(domain, LDNS_RR_TYPE_CNAME) &&
01391
01392 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_CNAME) &&
01393
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
01402 zonedata_examine_domain_is_occluded(zd, domain, apex);
01403 if (result) {
01404 ;
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
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 }