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 "daemon/worker.h"
00036 #include "scheduler/fifoq.h"
00037 #include "shared/allocator.h"
00038 #include "shared/duration.h"
00039 #include "shared/file.h"
00040 #include "shared/hsm.h"
00041 #include "shared/log.h"
00042 #include "shared/status.h"
00043 #include "shared/util.h"
00044 #include "signer/rrset.h"
00045
00046 #include <ldns/ldns.h>
00047 #include <stdlib.h>
00048
00049 static const char* rrset_str = "rrset";
00050
00051
00056 void
00057 log_rr(ldns_rr* rr, const char* pre, int level)
00058 {
00059 char* str = NULL;
00060 size_t i = 0;
00061
00062 if (ods_log_get_level() < level + 2) return;
00063
00064 str = ldns_rr2str(rr);
00065 if (str) {
00066 str[(strlen(str))-1] = '\0';
00067
00068 for (i=0; i < strlen(str); i++) {
00069 if (str[i] == '\t') {
00070 str[i] = ' ';
00071 }
00072 }
00073
00074 if (level == 1) {
00075 ods_log_error("%s %s", pre?pre:"", str);
00076 } else if (level == 2) {
00077 ods_log_warning("%s %s", pre?pre:"", str);
00078 } else if (level == 3) {
00079 ods_log_info("%s %s", pre?pre:"", str);
00080 } else if (level == 4) {
00081 ods_log_verbose("%s %s", pre?pre:"", str);
00082 } else if (level == 5) {
00083 ods_log_debug("%s %s", pre?pre:"", str);
00084 } else if (level == 6) {
00085 ods_log_deeebug("%s %s", pre?pre:"", str);
00086 } else {
00087 ods_log_deeebug("%s %s", pre?pre:"", str);
00088 }
00089 free((void*)str);
00090 }
00091 return;
00092 }
00093
00094
00099 rrset_type*
00100 rrset_create(ldns_rr_type rrtype)
00101 {
00102 allocator_type* allocator = NULL;
00103 rrset_type* rrset = NULL;
00104
00105 if (!rrtype) {
00106 ods_log_error("[%s] unable to create RRset: no RRtype", rrset_str);
00107 return NULL;
00108 }
00109 ods_log_assert(rrtype);
00110
00111 allocator = allocator_create(malloc, free);
00112 if (!allocator) {
00113 ods_log_error("[%s] unable to create RRset %u: create allocator "
00114 "failed", rrset_str, (unsigned) rrtype);
00115 return NULL;
00116 }
00117 ods_log_assert(allocator);
00118
00119 rrset = (rrset_type*) allocator_alloc(allocator, sizeof(rrset_type));
00120 if (!rrset) {
00121 ods_log_error("[%s] unable to create RRset %u: allocator failed",
00122 rrset_str, (unsigned) rrtype);
00123 allocator_cleanup(allocator);
00124 return NULL;
00125 }
00126 ods_log_assert(rrset);
00127
00128 rrset->allocator = allocator;
00129 rrset->rr_type = rrtype;
00130 rrset->rr_count = 0;
00131 rrset->add_count = 0;
00132 rrset->del_count = 0;
00133 rrset->rrsig_count = 0;
00134 rrset->needs_signing = 0;
00135 rrset->rrs = ldns_dnssec_rrs_new();
00136 rrset->add = NULL;
00137 rrset->del = NULL;
00138 rrset->rrsigs = NULL;
00139 return rrset;
00140 }
00141
00142
00147 ods_status
00148 rrset_recover(rrset_type* rrset, ldns_rr* rrsig, const char* locator,
00149 uint32_t flags)
00150 {
00151 ods_status status = ODS_STATUS_OK;
00152
00153 ods_log_assert(rrset);
00154 ods_log_assert(rrsig);
00155 ods_log_assert(locator);
00156 ods_log_assert(flags);
00157
00158 if (!rrset->rrsigs) {
00159 rrset->rrsigs = rrsigs_create();
00160 }
00161
00162 status = rrsigs_add_sig(rrset->rrsigs, rrsig, locator, flags);
00163 if (status != ODS_STATUS_OK) {
00164 ods_log_error("[%s] unable to recover RRSIG", rrset_str);
00165 log_rr(rrsig, "+RRSIG", 1);
00166 } else {
00167 rrset->rrsig_count += 1;
00173 rrset->needs_signing = 0;
00174 }
00175 return status;
00176 }
00177
00178
00183 static int
00184 rrs_examine_ns_rdata(ldns_dnssec_rrs* rrs, ldns_rdf* nsdname)
00185 {
00186 ldns_dnssec_rrs* walk = NULL;
00187 if (!rrs || !nsdname) {
00188 return 0;
00189 }
00190 walk = rrs;
00191 while (walk) {
00192 if (walk->rr &&
00193 ldns_dname_compare(ldns_rr_rdf(walk->rr, 0), nsdname) == 0) {
00194 return 1;
00195 }
00196 walk = walk->next;
00197 }
00198 return 0;
00199 }
00200
00201
00206 int
00207 rrset_examine_ns_rdata(rrset_type* rrset, ldns_rdf* nsdname)
00208 {
00209 if (!rrset || !nsdname || rrset->rr_type != LDNS_RR_TYPE_NS) {
00210 return 0;
00211 }
00212 if (rrs_examine_ns_rdata(rrset->add, nsdname)) {
00213 return 1;
00214 }
00215 if (rrs_examine_ns_rdata(rrset->del, nsdname)) {
00216 return 0;
00217 }
00218 return rrs_examine_ns_rdata(rrset->rrs, nsdname);
00219 }
00220
00221
00226 size_t
00227 rrset_count_RR(rrset_type* rrset)
00228 {
00229 ods_log_assert(rrset);
00230 return ((rrset->rr_count + rrset->add_count) - rrset->del_count);
00231 }
00232
00233
00238 size_t
00239 rrset_count_rr(rrset_type* rrset, int which)
00240 {
00241 if (!rrset) {
00242 return 0;
00243 }
00244 switch (which) {
00245 case COUNT_ADD:
00246 return rrset->add_count;
00247 case COUNT_DEL:
00248 return rrset->del_count;
00249 case COUNT_RR:
00250 default:
00251 return rrset->rr_count;
00252 }
00253
00254 return rrset->rr_count;
00255 }
00256
00257
00262 ldns_rr*
00263 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
00264 {
00265 ldns_status status = LDNS_STATUS_OK;
00266
00267 if (!rr) {
00268 ods_log_error("[%s] unable to add RR: no RR", rrset_str);
00269 return NULL;
00270 }
00271 ods_log_assert(rr);
00272
00273 if (!rrset) {
00274 ods_log_error("[%s] unable to add RR: no storage", rrset_str);
00275 return NULL;
00276 }
00277 ods_log_assert(rrset);
00278
00279 if (rrset->rr_type != ldns_rr_get_type(rr)) {
00280 ods_log_error("[%s] unable to add RR: RRtype mismatch", rrset_str);
00281 return NULL;
00282 }
00283
00284 if (!rrset->add) {
00285 rrset->add = ldns_dnssec_rrs_new();
00286 }
00287
00288 if (!rrset->add->rr) {
00289 rrset->add->rr = rr;
00290 rrset->add_count = 1;
00291 log_rr(rr, "+rr", 7);
00292 } else {
00293 status = util_dnssec_rrs_add_rr(rrset->add, rr);
00294 if (status != LDNS_STATUS_OK) {
00295 if (status == LDNS_STATUS_NO_DATA) {
00296 ods_log_warning("[%s] unable to add RR to RRset (%i): "
00297 "duplicate", rrset_str, rrset->rr_type);
00298 log_rr(rr, "+rr", 2);
00299
00300 return rr;
00301 } else {
00302 ods_log_error("[%s] unable to add RR to RRset (%i): %s",
00303 rrset_str, rrset->rr_type,
00304 ldns_get_errorstr_by_id(status));
00305 log_rr(rr, "+rr", 1);
00306 ldns_dnssec_rrs_deep_free(rrset->add);
00307 rrset->add = NULL;
00308 rrset->add_count = 0;
00309 return NULL;
00310 }
00311 }
00312 rrset->add_count += 1;
00313 log_rr(rr, "+rr", 7);
00314 }
00315 return rr;
00316 }
00317
00318
00323 ldns_rr*
00324 rrset_del_rr(rrset_type* rrset, ldns_rr* rr, int dupallowed)
00325 {
00326 ldns_status status = LDNS_STATUS_OK;
00327
00328 if (!rr) {
00329 ods_log_error("[%s] unable to delete RR: no RR", rrset_str);
00330 return NULL;
00331 }
00332 ods_log_assert(rr);
00333
00334 if (!rrset) {
00335 ods_log_error("[%s] unable to delete RR: no storage", rrset_str);
00336 return NULL;
00337 }
00338 ods_log_assert(rrset);
00339
00340 if (rrset->rr_type != ldns_rr_get_type(rr)) {
00341 ods_log_error("[%s] unable to delete RR: RRtype mismatch", rrset_str);
00342 return NULL;
00343 }
00344
00345 if (!rrset->del) {
00346 rrset->del = ldns_dnssec_rrs_new();
00347 }
00348
00349 if (!rrset->del->rr) {
00350 rrset->del->rr = rr;
00351 rrset->del_count = 1;
00352 log_rr(rr, "-rr", 7);
00353 } else {
00354 status = util_dnssec_rrs_add_rr(rrset->del, rr);
00355 if (status != LDNS_STATUS_OK) {
00356 if (status == LDNS_STATUS_NO_DATA) {
00357 if (dupallowed) {
00358 return rr;
00359 }
00360 ods_log_warning("[%s] unable to delete RR from RRset (%i): "
00361 "duplicate", rrset_str, rrset->rr_type);
00362 log_rr(rr, "-rr", 2);
00363
00364 return rr;
00365 } else {
00366 ods_log_error("[%s] unable to delete RR from RRset (%i): %s",
00367 rrset_str, rrset->rr_type,
00368 ldns_get_errorstr_by_id(status));
00369 log_rr(rr, "-rr", 1);
00370 ldns_dnssec_rrs_deep_free(rrset->del);
00371 rrset->del = NULL;
00372 rrset->del_count = 0;
00373 return NULL;
00374 }
00375 }
00376 rrset->del_count += 1;
00377 log_rr(rr, "-rr", 7);
00378 }
00379 return rr;
00380 }
00381
00382
00387 ods_status
00388 rrset_wipe_out(rrset_type* rrset)
00389 {
00390 ldns_dnssec_rrs* rrs = NULL;
00391 ldns_rr* del_rr = NULL;
00392 int error = 0;
00393
00394 if (rrset) {
00395 rrs = rrset->rrs;
00396 }
00397
00398 while (rrs) {
00399 if (rrs->rr) {
00400 del_rr = ldns_rr_clone(rrs->rr);
00401 if (rrset_del_rr(rrset, del_rr,
00402 (ldns_rr_get_type(del_rr) == LDNS_RR_TYPE_DNSKEY)) == NULL) {
00403 ods_log_error("[%s] unable to wipe RR from RRset (%i)",
00404 rrset_str, rrset->rr_type);
00405 ldns_rr_free(del_rr);
00406 error = 1;
00407 }
00408 del_rr = NULL;
00409 }
00410 rrs = rrs->next;
00411 }
00412
00413 if (error) {
00414 return ODS_STATUS_ERR;
00415 }
00416 return ODS_STATUS_OK;
00417 }
00418
00419
00424 ods_status
00425 rrset_diff(rrset_type* rrset, keylist_type* kl)
00426 {
00427 ods_status status = ODS_STATUS_OK;
00428 ldns_status lstatus = LDNS_STATUS_OK;
00429 ldns_dnssec_rrs* current = NULL;
00430 ldns_dnssec_rrs* pending = NULL;
00431 ldns_dnssec_rrs* prev = NULL;
00432 ldns_rr* rr = NULL;
00433 int cmp = 0;
00434
00435 if (!rrset) {
00436 return status;
00437 }
00438
00439 current = rrset->rrs;
00440 pending = rrset->add;
00441
00442 if (!current || !current->rr) {
00443 current = NULL;
00444 }
00445 if (!pending || !pending->rr) {
00446 pending = NULL;
00447 }
00448
00449 while (current && pending) {
00450 lstatus = util_dnssec_rrs_compare(current->rr, pending->rr, &cmp);
00451 if (lstatus != LDNS_STATUS_OK) {
00452 ods_log_error("[%s] diff failed: compare failed (%s)",
00453 rrset_str, ldns_get_errorstr_by_id(lstatus));
00454 return ODS_STATUS_ERR;
00455 }
00456
00457 if (cmp > 0) {
00458 prev = pending;
00459 pending = pending->next;
00460 } else if (cmp < 0) {
00461
00462 if (rrset->rr_type != LDNS_RR_TYPE_DNSKEY ||
00463 !keylist_lookup_by_dnskey(kl, current->rr)) {
00464
00465 rr = ldns_rr_clone(current->rr);
00466 rr = rrset_del_rr(rrset, rr,
00467 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY));
00468 if (!rr) {
00469 ods_log_error("[%s] diff failed: failed to delete RR",
00470 rrset_str);
00471 return ODS_STATUS_ERR;
00472 }
00473 }
00474
00475 current = current->next;
00476 } else {
00477
00478 if (!prev) {
00479 rrset->add = pending->next;
00480 } else {
00481 prev->next = pending->next;
00482 }
00483 pending->next = NULL;
00484 rrset->add_count -= 1;
00485
00486 ldns_dnssec_rrs_deep_free(pending);
00487 pending = NULL;
00488
00489 current = current->next;
00490 if (!prev) {
00491 pending = rrset->add;
00492 } else {
00493 pending = prev->next;
00494 }
00495 }
00496 }
00497
00498 if (pending) {
00499 ods_log_assert(!current);
00500
00501 }
00502
00503 if (current) {
00504 ods_log_assert(!pending);
00505 while (current) {
00506
00507 if (rrset->rr_type != LDNS_RR_TYPE_DNSKEY ||
00508 !keylist_lookup_by_dnskey(kl, current->rr)) {
00509
00510 rr = ldns_rr_clone(current->rr);
00511 rr = rrset_del_rr(rrset, rr,
00512 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY));
00513 if (!rr) {
00514 ods_log_error("[%s] diff failed: failed to delete RR",
00515 rrset_str);
00516 return ODS_STATUS_ERR;
00517 }
00518 }
00519 current = current->next;
00520 }
00521 }
00522 return ODS_STATUS_OK;
00523 }
00524
00525
00530 static ods_status
00531 rrset_commit_del(rrset_type* rrset, ldns_rr* rr)
00532 {
00533 ldns_status status = LDNS_STATUS_OK;
00534 ldns_dnssec_rrs* rrs = NULL;
00535 ldns_dnssec_rrs* prev_rrs = NULL;
00536 int cmp = 0;
00537
00538 if (!rr) {
00539 ods_log_error("[%s] unable to commit del RR: no RR", rrset_str);
00540 return ODS_STATUS_ASSERT_ERR;
00541 }
00542 ods_log_assert(rr);
00543 if (!rrset) {
00544 ods_log_error("[%s] unable to commit del RR: no storage", rrset_str);
00545 return ODS_STATUS_ASSERT_ERR;
00546 }
00547 ods_log_assert(rrset);
00548
00549 rrs = rrset->rrs;
00550 while (rrs) {
00551 status = util_dnssec_rrs_compare(rrs->rr, rr, &cmp);
00552 if (status != LDNS_STATUS_OK) {
00553 ods_log_error("[%s] unable to commit del RR: compare failed",
00554 rrset_str);
00555 return ODS_STATUS_ERR;
00556 }
00557
00558 if (cmp == 0) {
00559
00560 if (prev_rrs) {
00561 prev_rrs->next = rrs->next;
00562 } else {
00563 rrset->rrs = rrs->next;
00564 }
00565 rrs->next = NULL;
00566 ldns_dnssec_rrs_deep_free(rrs);
00567 rrs = NULL;
00568
00569 rrset->rr_count -= 1;
00570 rrset->del_count -= 1;
00571 log_rr(rr, "-RR", 6);
00572 return ODS_STATUS_OK;
00573 }
00574
00575
00576 prev_rrs = rrs;
00577 rrs = rrs->next;
00578 }
00579
00580 ods_log_warning("[%s] unable to commit del RR: no such RR", rrset_str);
00581 log_rr(rr, "-RR", 2);
00582 return ODS_STATUS_UNCHANGED;
00583 }
00584
00585
00590 static ods_status
00591 rrset_commit_add(rrset_type* rrset, ldns_rr* rr)
00592 {
00593 ldns_status status = LDNS_STATUS_OK;
00594
00595 if (!rr) {
00596 ods_log_error("[%s] unable to commit add RR: no RR", rrset_str);
00597 return ODS_STATUS_ASSERT_ERR;
00598 }
00599 ods_log_assert(rr);
00600 if (!rrset) {
00601 ods_log_error("[%s] unable to commit add RR: no storage", rrset_str);
00602 return ODS_STATUS_ASSERT_ERR;
00603 }
00604 ods_log_assert(rrset);
00605
00606 if (!rrset->rrs) {
00607 rrset->rrs = ldns_dnssec_rrs_new();
00608 }
00609
00610 if (!rrset->rrs->rr) {
00611 rrset->rrs->rr = rr;
00612 rrset->rr_count += 1;
00613 rrset->add_count -= 1;
00614 log_rr(rr, "+RR", 6);
00615 return ODS_STATUS_OK;
00616 } else {
00617 status = util_dnssec_rrs_add_rr(rrset->rrs, rr);
00618 if (status != LDNS_STATUS_OK) {
00619 if (status == LDNS_STATUS_NO_DATA) {
00620 ods_log_warning("[%s] unable to commit add RR: duplicate",
00621 rrset_str);
00622 log_rr(rr, "+RR", 2);
00623 return ODS_STATUS_UNCHANGED;
00624 } else {
00625 ods_log_error("[%s] unable to commit add RR: %s",
00626 rrset_str, ldns_get_errorstr_by_id(status));
00627 log_rr(rr, "+RR", 1);
00628 return ODS_STATUS_ERR;
00629 }
00630 }
00631 log_rr(rr, "+RR", 6);
00632 rrset->rr_count += 1;
00633 rrset->add_count -= 1;
00634 return ODS_STATUS_OK;
00635 }
00636
00637 return ODS_STATUS_ERR;
00638 }
00639
00640
00645 ods_status
00646 rrset_commit(rrset_type* rrset)
00647 {
00648 ldns_dnssec_rrs* rrs = NULL;
00649 ods_status status = ODS_STATUS_OK;
00650
00651 if (!rrset) {
00652 return ODS_STATUS_ASSERT_ERR;
00653 }
00654 ods_log_assert(rrset);
00655
00656 if (rrset->del_count || rrset->add_count) {
00657 rrset->needs_signing = 1;
00658 }
00659
00660
00661 rrs = rrset->del;
00662 while (rrs) {
00663 status = rrset_commit_del(rrset, rrs->rr);
00664 if (status != ODS_STATUS_OK) {
00665 ods_log_alert("[%s] commit RRset (%i) failed: %s", rrset_str,
00666 rrset->rr_type, ods_status2str(status));
00667 return status;
00668 }
00669 rrs = rrs->next;
00670 }
00671 ldns_dnssec_rrs_deep_free(rrset->del);
00672 rrset->del = NULL;
00673 rrset->del_count = 0;
00674
00675
00676 rrs = rrset->add;
00677 while (rrs) {
00678 status = rrset_commit_add(rrset, rrs->rr);
00679 if (status != ODS_STATUS_OK) {
00680 ods_log_alert("[%s] commit RRset (%i) failed: %s", rrset_str,
00681 rrset->rr_type, ods_status2str(status));
00682 return status;
00683 }
00684 rrs = rrs->next;
00685 }
00686 ldns_dnssec_rrs_free(rrset->add);
00687 rrset->add = NULL;
00688 rrset->add_count = 0;
00689
00690
00691
00692 return ODS_STATUS_OK;
00693 }
00694
00695
00700 void
00701 rrset_rollback(rrset_type* rrset)
00702 {
00703 if (!rrset) {
00704 return;
00705 }
00706
00707 if (rrset->add) {
00708 ldns_dnssec_rrs_deep_free(rrset->add);
00709 rrset->add = NULL;
00710 rrset->add_count = 0;
00711 }
00712 if (rrset->del) {
00713 ldns_dnssec_rrs_deep_free(rrset->del);
00714 rrset->del = NULL;
00715 rrset->del_count = 0;
00716 }
00717 return;
00718 }
00719
00720
00725 static uint32_t
00726 rrset_recycle(rrset_type* rrset, signconf_type* sc, time_t signtime)
00727 {
00728 rrsigs_type* rrsigs = NULL;
00729 rrsigs_type* prev_rrsigs = NULL;
00730 rrsigs_type* next_rrsigs = NULL;
00731 uint32_t refresh = 0;
00732 uint32_t expiration = 0;
00733 uint32_t inception = 0;
00734 uint32_t reusedsigs = 0;
00735 int drop_sig = 0;
00736 key_type* key = NULL;
00737
00738
00739 if (sc && sc->sig_refresh_interval) {
00740 refresh = (uint32_t) (signtime +
00741 duration2time(sc->sig_refresh_interval));
00742 }
00743
00744
00745
00746 if (rrset->needs_signing || !refresh) {
00747 ods_log_debug("[%s] drop signatures for RRset[%i]", rrset_str,
00748 rrset->rr_type);
00749 if (rrset->rrsigs) {
00750 rrsigs_cleanup(rrset->rrsigs);
00751 rrset->rrsigs = NULL;
00752 }
00753 rrset->rrsig_count = 0;
00754 rrset->needs_signing = 0;
00755 return 0;
00756 }
00757
00758
00759 rrsigs = rrset->rrsigs;
00760 while (rrsigs) {
00761 if (!rrsigs->rr) {
00762 ods_log_warning("[%s] signature set has no RRSIG record: "
00763 "drop signatures for RRset[%i]", rrset_str, rrset->rr_type);
00764 rrsigs_cleanup(rrset->rrsigs);
00765 rrset->rrsigs = NULL;
00766 rrset->rrsig_count = 0;
00767 rrset->needs_signing = 0;
00768 return 0;
00769 }
00770
00771 expiration = ldns_rdf2native_int32(
00772 ldns_rr_rrsig_expiration(rrsigs->rr));
00773 inception = ldns_rdf2native_int32(
00774 ldns_rr_rrsig_inception(rrsigs->rr));
00775
00776 if (expiration < refresh) {
00777
00778 drop_sig = 1;
00779 ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
00780 "expiration minus refresh has passed: %u - %u < (signtime)",
00781 rrset_str, rrset->rr_type, expiration, refresh,
00782 (uint32_t) signtime);
00783 } else if (inception > (uint32_t) signtime) {
00784
00785 drop_sig = 1;
00786 ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
00787 "inception has not passed: %u < %u (signtime)", rrset_str,
00788 rrset->rr_type, inception, (uint32_t) signtime);
00789 } else {
00790
00791 key = keylist_lookup(sc->keys, rrsigs->key_locator);
00792 if (!key) {
00793 drop_sig = 1;
00794 ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
00795 "key %s %u is dead", rrset_str,
00796 rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags);
00797 } else if (key->flags != rrsigs->key_flags) {
00798 drop_sig = 1;
00799 ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
00800 "key %s %u flags mismatch", rrset_str,
00801 rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags);
00802 }
00803 }
00804
00805 next_rrsigs = rrsigs->next;
00806 if (drop_sig) {
00807
00808 if (prev_rrsigs) {
00809 prev_rrsigs->next = rrsigs->next;
00810 } else {
00811 rrset->rrsigs = rrsigs->next;
00812 }
00813 log_rr(rrsigs->rr, "-RRSIG", 6);
00814 rrset->rrsig_count -= 1;
00815 rrsigs->next = NULL;
00816 rrsigs_cleanup(rrsigs);
00817 } else {
00818
00819 ods_log_deeebug("[%s] recycle signature for RRset[%i] "
00820 "(refresh=%u, signtime=%u, inception=%u, expiration=%u)",
00821 rrset_str, rrset->rr_type, refresh, (uint32_t) signtime,
00822 inception, expiration);
00823 log_rr(rrsigs->rr, "*RRSIG", 7);
00824 reusedsigs += 1;
00825 prev_rrsigs = rrsigs;
00826 }
00827 drop_sig = 0;
00828 rrsigs = next_rrsigs;
00829 }
00830 return reusedsigs;
00831 }
00832
00833
00838 static int
00839 rrset_signed_with_algorithm(rrset_type* rrset, uint8_t algorithm)
00840 {
00841 rrsigs_type* rrsigs = NULL;
00842
00843 if (!rrset || !algorithm) {
00844 return 0;
00845 }
00846
00847 rrsigs = rrset->rrsigs;
00848 while (rrsigs) {
00849 if (rrsigs->rr && algorithm ==
00850 ldns_rdf2native_int8(ldns_rr_rrsig_algorithm(rrsigs->rr))) {
00851 return 1;
00852 }
00853 rrsigs = rrsigs->next;
00854 }
00855
00856 return 0;
00857 }
00858
00859
00864 static ldns_rr_list*
00865 rrset2rrlist(rrset_type* rrset)
00866 {
00867 ldns_dnssec_rrs* rrs = NULL;
00868 ldns_rr_list* rr_list = NULL;
00869 int error = 0;
00870
00871 rr_list = ldns_rr_list_new();
00872 rrs = rrset->rrs;
00873 while (rrs && rrs->rr) {
00874 error = (int) ldns_rr_list_push_rr(rr_list, rrs->rr);
00875 if (!error) {
00876 ldns_rr_list_free(rr_list);
00877 return NULL;
00878 }
00879 if (rrset->rr_type == LDNS_RR_TYPE_CNAME ||
00880 rrset->rr_type == LDNS_RR_TYPE_DNAME) {
00881
00882 return rr_list;
00883 }
00884 rrs = rrs->next;
00885 }
00886 return rr_list;
00887 }
00888
00889
00894 static void
00895 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime,
00896 time_t* inception, time_t* expiration)
00897 {
00898 time_t jitter = 0;
00899 time_t offset = 0;
00900 time_t validity = 0;
00901 time_t random_jitter = 0;
00902
00903 if (!sc || !rrtype || !signtime) {
00904 return;
00905 }
00906
00907 jitter = duration2time(sc->sig_jitter);
00908 if (jitter) {
00909 random_jitter = ods_rand(jitter*2);
00910 }
00911 offset = duration2time(sc->sig_inception_offset);
00912 if (rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3) {
00913 validity = duration2time(sc->sig_validity_denial);
00914 } else {
00915 validity = duration2time(sc->sig_validity_default);
00916 }
00917
00921 if (((validity + offset + random_jitter) - jitter) <
00922 ((validity + offset) - jitter) ) {
00923 ods_log_error("[%s] signature validity %u too low, should be at "
00924 "least %u", rrset_str,
00925 ((validity + offset + random_jitter) - jitter),
00926 ((validity + offset) - jitter));
00927 } else if (((validity + offset + random_jitter) - jitter) >
00928 ((validity + offset) + jitter) ) {
00929 ods_log_error("[%s] signature validity %u too high, should be at "
00930 "most %u", rrset_str,
00931 ((validity + offset + random_jitter) - jitter),
00932 ((validity + offset) + jitter));
00933 } else {
00934 ods_log_debug("[%s] signature validity %u in range [%u - %u]",
00935 rrset_str, ((validity + offset + random_jitter) - jitter),
00936 ((validity + offset) - jitter),
00937 ((validity + offset) + jitter));
00938 }
00939 *inception = signtime - offset;
00940 *expiration = (signtime + validity + random_jitter) - jitter;
00941 return;
00942 }
00943
00944
00949 ods_status
00950 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, ldns_rdf* owner,
00951 signconf_type* sc, time_t signtime, stats_type* stats)
00952 {
00953 ods_status status = ODS_STATUS_OK;
00954 uint32_t newsigs = 0;
00955 uint32_t reusedsigs = 0;
00956 ldns_rr* rrsig = NULL;
00957 ldns_rr_list* rr_list = NULL;
00958 rrsigs_type* new_rrsigs = NULL;
00959 rrsigs_type* walk_rrsigs = NULL;
00960 key_type* key = NULL;
00961 time_t inception = 0;
00962 time_t expiration = 0;
00963
00964 if (!rrset) {
00965 ods_log_error("[%s] unable to sign RRset: no RRset", rrset_str);
00966 return ODS_STATUS_ASSERT_ERR;
00967 }
00968 ods_log_assert(rrset);
00969
00970 if (!owner) {
00971 ods_log_error("[%s] unable to sign RRset: no owner", rrset_str);
00972 return ODS_STATUS_ASSERT_ERR;
00973 }
00974 ods_log_assert(owner);
00975
00976 if (!sc) {
00977 ods_log_error("[%s] unable to sign RRset: no signconf", rrset_str);
00978 return ODS_STATUS_ASSERT_ERR;
00979 }
00980 ods_log_assert(sc);
00981
00982
00983 reusedsigs = rrset_recycle(rrset, sc, signtime);
00984
00985
00986 rr_list = rrset2rrlist(rrset);
00987 if (!rr_list) {
00988 ods_log_error("[%s] unable to sign RRset[%i]: to RRlist failed",
00989 rrset_str, rrset->rr_type);
00990 return ODS_STATUS_ERR;
00991 }
00992 if (ldns_rr_list_rr_count(rr_list) <= 0) {
00993
00994 ldns_rr_list_free(rr_list);
00995 return ODS_STATUS_OK;
00996 }
00997
00998
00999 new_rrsigs = rrsigs_create();
01000 if (!rrset->rrsigs) {
01001 rrset->rrsigs = rrsigs_create();
01002 }
01003 rrset_sigvalid_period(sc, rrset->rr_type, signtime,
01004 &inception, &expiration);
01005
01006 key = sc->keys->first_key;
01007 while (key) {
01008
01009 if (!key->zsk && rrset->rr_type != LDNS_RR_TYPE_DNSKEY) {
01010 ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no "
01011 "active ZSK", rrset_str, key->locator, rrset->rr_type);
01012 key = key->next;
01013 continue;
01014 }
01015 if (!key->ksk && rrset->rr_type == LDNS_RR_TYPE_DNSKEY) {
01016 ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no "
01017 "active KSK", rrset_str, key->locator, rrset->rr_type);
01018 key = key->next;
01019 continue;
01020 }
01021
01022
01023 if (rrset_signed_with_algorithm(rrset, key->algorithm)) {
01024 ods_log_deeebug("skipping key %s for signing: RRset[%i] "
01025 "already has signature with same algorithm", key->locator);
01026 key = key->next;
01027 continue;
01028 }
01029
01035
01036 ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
01037 rrset->rr_type, key->locator);
01038 rrsig = lhsm_sign(ctx, rr_list, key, owner, inception, expiration);
01039 if (!rrsig) {
01040 ods_log_error("[%s] unable to sign RRset[%i]: error creating "
01041 "RRSIG RR", rrset_str, rrset->rr_type);
01042 ldns_rr_list_free(rr_list);
01043 rrsigs_cleanup(new_rrsigs);
01044 return ODS_STATUS_ERR;
01045 }
01046
01047 ods_log_deeebug("[%s] new signature created for RRset[%i]", rrset_str,
01048 rrset->rr_type);
01049 log_rr(rrsig, "+rrsig", 7);
01050 status = rrsigs_add_sig(new_rrsigs, rrsig, key->locator, key->flags);
01051 if (status != ODS_STATUS_OK) {
01052 ods_log_error("[%s] unable to sign RRset[%i]: error adding RRSIG",
01053 rrset_str, rrset->rr_type);
01054 log_rr(rrsig, "+RRSIG", 1);
01055 ldns_rr_list_free(rr_list);
01056 rrsigs_cleanup(new_rrsigs);
01057 return status;
01058 }
01059
01060 key = key->next;
01061 }
01062
01063
01064 walk_rrsigs = new_rrsigs;
01065 while (walk_rrsigs) {
01066 if (walk_rrsigs->rr) {
01067 ods_log_deeebug("[%s] adding signature to RRset[%i]", rrset_str,
01068 rrset->rr_type);
01069 status = rrsigs_add_sig(rrset->rrsigs,
01070 ldns_rr_clone(walk_rrsigs->rr),
01071 walk_rrsigs->key_locator, walk_rrsigs->key_flags);
01072 if (status != ODS_STATUS_OK) {
01073 ods_log_error("[%s] unable to sign RRset[%i]: error adding "
01074 "RRSIG to RRset[%i]", rrset_str, rrset->rr_type,
01075 rrset->rr_type);
01076 log_rr(walk_rrsigs->rr, "+RRSIG", 1);
01077 ldns_rr_list_free(rr_list);
01078 rrsigs_cleanup(new_rrsigs);
01079 return status;
01080 }
01081 rrset->rrsig_count += 1;
01082 newsigs++;
01083 log_rr(walk_rrsigs->rr, "+RRSIG", 6);
01084 }
01085 walk_rrsigs = walk_rrsigs->next;
01086 }
01087
01088
01089 rrsigs_cleanup(new_rrsigs);
01090 ldns_rr_list_free(rr_list);
01091
01092 lock_basic_lock(&stats->stats_lock);
01093 if (rrset->rr_type == LDNS_RR_TYPE_SOA) {
01094 stats->sig_soa_count += newsigs;
01095 }
01096 stats->sig_count += newsigs;
01097 stats->sig_reuse += reusedsigs;
01098 lock_basic_unlock(&stats->stats_lock);
01099 return ODS_STATUS_OK;
01100 }
01101
01102
01107 ods_status
01108 rrset_queue(rrset_type* rrset, fifoq_type* q, worker_type* worker)
01109 {
01110 ods_status status = ODS_STATUS_UNCHANGED;
01111
01112 if (!rrset) {
01113 ods_log_error("[%s] unable to queue RRset: no RRset", rrset_str);
01114 return ODS_STATUS_ASSERT_ERR;
01115 }
01116 ods_log_assert(rrset);
01117 if (!worker) {
01118 ods_log_error("[%s] unable to queue RRset: no worker", rrset_str);
01119 return ODS_STATUS_ASSERT_ERR;
01120 }
01121 ods_log_assert(worker);
01122 if (!q) {
01123 ods_log_error("[%s] unable to queue RRset: no queue", rrset_str);
01124 return ODS_STATUS_ASSERT_ERR;
01125 }
01126 ods_log_assert(q);
01127
01128 while (status == ODS_STATUS_UNCHANGED && !worker->need_to_exit) {
01129 lock_basic_lock(&q->q_lock);
01130 status = fifoq_push(q, (void*) rrset, worker);
01131 lock_basic_unlock(&q->q_lock);
01132 }
01133 if (status == ODS_STATUS_OK) {
01134 lock_basic_lock(&worker->worker_lock);
01135
01136 worker->jobs_appointed += 1;
01137
01138 lock_basic_unlock(&worker->worker_lock);
01139 }
01140 return status;
01141 }
01142
01143
01148 void
01149 rrset_cleanup(rrset_type* rrset)
01150 {
01151 allocator_type* allocator;
01152
01153 if (!rrset) {
01154 return;
01155 }
01156 allocator = rrset->allocator;
01157
01158 if (rrset->rrs) {
01159 ldns_dnssec_rrs_deep_free(rrset->rrs);
01160 rrset->rrs = NULL;
01161 }
01162 if (rrset->add) {
01163 ldns_dnssec_rrs_deep_free(rrset->add);
01164 rrset->add = NULL;
01165 }
01166 if (rrset->del) {
01167 ldns_dnssec_rrs_deep_free(rrset->del);
01168 rrset->del = NULL;
01169 }
01170 if (rrset->rrsigs) {
01171 rrsigs_cleanup(rrset->rrsigs);
01172 rrset->rrsigs = NULL;
01173 }
01174
01175 allocator_deallocate(allocator, (void*) rrset);
01176 allocator_cleanup(allocator);
01177 return;
01178 }
01179
01180
01185 void
01186 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs)
01187 {
01188 if (!rrset || !fd) {
01189 return;
01190 }
01191 ods_log_assert(fd);
01192 ods_log_assert(rrset);
01193
01194 if (rrset->rrs) {
01195 if (rrset->rr_type == LDNS_RR_TYPE_CNAME ||
01196 rrset->rr_type == LDNS_RR_TYPE_DNAME) {
01197
01198 if (rrset->rrs->rr) {
01199 ldns_rr_print(fd, rrset->rrs->rr);
01200 }
01201 } else {
01202 ldns_dnssec_rrs_print(fd, rrset->rrs);
01203 }
01204 }
01205 if (rrset->rrsigs && !skip_rrsigs) {
01206 rrsigs_print(fd, rrset->rrsigs, 0);
01207 }
01208 return;
01209 }
01210
01211
01216 void
01217 rrset_backup(FILE* fd, rrset_type* rrset)
01218 {
01219 if (!rrset || !fd) {
01220 return;
01221 }
01222 if (rrset->rrsigs) {
01223 rrsigs_print(fd, rrset->rrsigs, 1);
01224 }
01225 return;
01226 }