diff --git a/Knot.files b/Knot.files index d865ad67868e3d59bbd8242278302d2ec5edc20f..e766ce60fae3a81d9f3c0b57797ebfc221a89335 100644 --- a/Knot.files +++ b/Knot.files @@ -128,14 +128,13 @@ src/knot/events/events.c src/knot/events/events.h src/knot/events/handlers.h src/knot/events/handlers/dnssec.c -src/knot/events/handlers/ds_check.c -src/knot/events/handlers/ds_push.c src/knot/events/handlers/expire.c src/knot/events/handlers/flush.c src/knot/events/handlers/freeze_thaw.c src/knot/events/handlers/load.c src/knot/events/handlers/notify.c src/knot/events/handlers/nsec3resalt.c +src/knot/events/handlers/parent_ds_query.c src/knot/events/handlers/refresh.c src/knot/events/handlers/update.c src/knot/events/replan.c diff --git a/doc/man/knot.conf.5in b/doc/man/knot.conf.5in index e4f79f69463b36f2ad48b5bd58385ce6d3cb1e0a..abaed61297094b48a9d4abb1502ae6395da20f22 100644 --- a/doc/man/knot.conf.5in +++ b/doc/man/knot.conf.5in @@ -706,7 +706,6 @@ policy: nsec3\-salt\-lifetime: TIME signing\-threads: INT ksk\-submission: submission_id - ds\-push: remote_id cds\-cdnskey\-publish: none | delete\-dnssec | rollover | always | double\-ds offline\-ksk: BOOL .ft P @@ -930,28 +929,6 @@ A reference to \fI\%submission\fP section holding parameters of KSK submittion checks. .sp \fIDefault:\fP not set -.SS ds\-push -.sp -A \fI\%reference\fP to parent\(aqs DNS server. Whenever the CDS record in -this zone is changed, corresponding DS record is sent as an update (DDNS) to -parent DNS server. -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -For proper operation ref:\fIcds\-cdnskey\-publish<policy_cds\-cdnskey\-publish>\fP -must not be disabled. -.UNINDENT -.UNINDENT -.sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -This feature does not work with Onlinesign module. -.UNINDENT -.UNINDENT -.sp -\fIDefault:\fP not set .SS signing\-threads .sp When signing zone or update, use this number of threads for parallel signing. diff --git a/doc/reference.rst b/doc/reference.rst index d45222642e76bd3cfae42305557c50fd13f394fc..64e22889b20d76f7d0a6f706d079c447e63c6fa3 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -770,7 +770,6 @@ DNSSEC policy configuration. nsec3-salt-lifetime: TIME signing-threads: INT ksk-submission: submission_id - ds-push: remote_id cds-cdnskey-publish: none | delete-dnssec | rollover | always | double-ds offline-ksk: BOOL @@ -1035,24 +1034,6 @@ KSK submittion checks. *Default:* not set -.. _policy_ds-push: - -ds-push -------- - -A :ref:`reference<remote_id>` to parent's DNS server. Whenever the CDS record in -this zone is changed, corresponding DS record is sent as an update (DDNS) to -parent DNS server. - -.. NOTE:: - For proper operation ref:`cds-cdnskey-publish<policy_cds-cdnskey-publish>` - must not be disabled. - -.. NOTE:: - This feature does not work with :ref:`Onlinesign<mod-onlinesign>` module. - -*Default:* not set - .. _policy_signing-threads: signing-threads diff --git a/scripts/timerdb-info.py b/scripts/timerdb-info.py index 6a7cd3610989c510f369fb4bca57618e9854f606..26eb079c8511d95a22b4169b4aee50ff3c3ad8b9 100755 --- a/scripts/timerdb-info.py +++ b/scripts/timerdb-info.py @@ -37,10 +37,8 @@ class TimerDBInfo: 0x82: ("last_refresh", cls.format_timestamp), 0x83: ("next_refresh", cls.format_timestamp), # knot >= 2.6 - 0x84: ("last_resalt", cls.format_timestamp), - 0x85: ("next_ds_check", cls.format_timestamp), - # knot >= 2.8 - 0x86: ("next_ds_push", cls.format_timestamp), + 0x84: ("last_resalt", cls.format_timestamp), + 0x85: ("next_parent_ds_q", cls.format_timestamp), } if id in timers: return (timers[id][0], timers[id][1](value)) diff --git a/src/knot/Makefile.inc b/src/knot/Makefile.inc index ea2cbb497f5277990428853626cc5f90b5230d81..f9a5f4d2dbc643fc025a35242bb7bc45a3fb8c74 100644 --- a/src/knot/Makefile.inc +++ b/src/knot/Makefile.inc @@ -66,8 +66,6 @@ libknotd_la_SOURCES = \ knot/events/events.h \ knot/events/handlers.h \ knot/events/handlers/dnssec.c \ - knot/events/handlers/ds_check.c \ - knot/events/handlers/ds_push.c \ knot/events/handlers/expire.c \ knot/events/handlers/flush.c \ knot/events/handlers/freeze_thaw.c \ @@ -76,6 +74,7 @@ libknotd_la_SOURCES = \ knot/events/handlers/nsec3resalt.c \ knot/events/handlers/refresh.c \ knot/events/handlers/update.c \ + knot/events/handlers/parent_ds_query.c \ knot/events/replan.c \ knot/events/replan.h \ knot/nameserver/axfr.c \ diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c index 97ba8c586400621a033fa740b5ab954a65e63ace..cc081ebf52c67ea4e0145e6a176908c76d39f5cd 100644 --- a/src/knot/conf/schema.c +++ b/src/knot/conf/schema.c @@ -291,8 +291,6 @@ static const yp_item_t desc_policy[] = { CONF_IO_FRLD_ZONES }, { C_KSK_SBM, YP_TREF, YP_VREF = { C_SBM }, CONF_IO_FRLD_ZONES, { check_ref } }, - { C_DS_PUSH, YP_TREF, YP_VREF = { C_RMT }, YP_FMULTI | CONF_IO_FRLD_ZONES, - { check_ref } }, { C_SIGNING_THREADS, YP_TINT, YP_VINT = { 1, UINT16_MAX, 1 } }, { C_CDS_CDNSKEY, YP_TOPT, YP_VOPT = { cds_cdnskey, CDS_CDNSKEY_ROLLOVER } }, { C_OFFLINE_KSK, YP_TBOOL, YP_VNONE, CONF_IO_FRLD_ZONES }, diff --git a/src/knot/conf/schema.h b/src/knot/conf/schema.h index 742072b25e5137603a3d769e794e7bc4a7e5a8fb..befbf2bd9ef5b274ea151de11bb2450111f6c4c0 100644 --- a/src/knot/conf/schema.h +++ b/src/knot/conf/schema.h @@ -41,7 +41,6 @@ #define C_DNSSEC_POLICY "\x0D""dnssec-policy" #define C_DNSSEC_SIGNING "\x0E""dnssec-signing" #define C_DOMAIN "\x06""domain" -#define C_DS_PUSH "\x07""ds-push" #define C_ECS "\x12""edns-client-subnet" #define C_FILE "\x04""file" #define C_GLOBAL_MODULE "\x0D""global-module" diff --git a/src/knot/conf/tools.c b/src/knot/conf/tools.c index 88c58483c3b9d0de70d2b9bd579f72cd40b4d701..1e3d3c4a4322fa913b088857e0d5c7496fd9ed35 100644 --- a/src/knot/conf/tools.c +++ b/src/knot/conf/tools.c @@ -400,16 +400,6 @@ int check_policy( } } - conf_val_t cds_cdnskey = conf_rawid_get_txn(args->extra->conf, args->extra->txn, C_POLICY, - C_CDS_CDNSKEY, args->id, args->id_len); - conf_val_t ds_push = conf_rawid_get_txn(args->extra->conf, args->extra->txn, C_POLICY, - C_DS_PUSH, args->id, args->id_len); - - if (conf_val_count(&ds_push) > 0 && conf_opt(&cds_cdnskey) == CDS_CDNSKEY_NONE) { - args->err_str = "DS push requires enabled CDS/CDNSKEY publication"; - return KNOT_EINVAL; - } - return KNOT_EOK; } diff --git a/src/knot/dnssec/key-events.c b/src/knot/dnssec/key-events.c index 3172efbb93dee63ed015b5402294ea4c3d0de8c3..658fa770331ba286cee2e5744aaef94d5577f2bd 100644 --- a/src/knot/dnssec/key-events.c +++ b/src/knot/dnssec/key-events.c @@ -594,7 +594,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags, ret = generate_key(ctx, GEN_KSK_FLAGS, ctx->now, false); } if (ret == KNOT_EOK) { - reschedule->plan_ds_check = true; + reschedule->plan_ds_query = true; plan_ds_keytag = dnssec_key_get_keytag(ctx->zone->keys[0].key); } } @@ -685,7 +685,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags, case SUBMIT: ret = submit_key(ctx, next.key); if (ret == KNOT_EOK) { - reschedule->plan_ds_check = true; + reschedule->plan_ds_query = true; plan_ds_keytag = dnssec_key_get_keytag(next.key->key); } break; @@ -716,7 +716,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags, if (ret == KNOT_EOK && next.ready_key >= 0) { // just to make sure DS check is scheduled - reschedule->plan_ds_check = true; + reschedule->plan_ds_query = true; plan_ds_keytag = next.ready_key; } @@ -728,7 +728,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags, ret = kdnssec_ctx_commit(ctx); } - if (ret == KNOT_EOK && reschedule->plan_ds_check) { + if (ret == KNOT_EOK && reschedule->plan_ds_query) { char param[32]; (void)snprintf(param, sizeof(param), "KEY_SUBMISSION=%hu", plan_ds_keytag); log_fmt_zone(LOG_NOTICE, LOG_SOURCE_ZONE, ctx->zone->dname, param, diff --git a/src/knot/dnssec/zone-events.h b/src/knot/dnssec/zone-events.h index 292bdb1adf39cbb8c9063cc7e01a111fb6c60442..7039d7b29d016309616bf5e24cfbdc8390046e83 100644 --- a/src/knot/dnssec/zone-events.h +++ b/src/knot/dnssec/zone-events.h @@ -48,7 +48,7 @@ typedef struct { knot_time_t next_nsec3resalt; knot_time_t last_nsec3resalt; bool keys_changed; - bool plan_ds_check; + bool plan_ds_query; } zone_sign_reschedule_t; /*! diff --git a/src/knot/dnssec/zone-sign.c b/src/knot/dnssec/zone-sign.c index 85a8ff0bcfe2ef1d400bd9dd316619bd8210d947..aa0f4140c27a89e4d91ffc1dfdcf5f9e38860c60 100644 --- a/src/knot/dnssec/zone-sign.c +++ b/src/knot/dnssec/zone-sign.c @@ -816,11 +816,6 @@ int knot_zone_sign_update_dnskeys(zone_update_t *update, if (!knot_rrset_empty(&add_r.cds)) { ret = changeset_add_addition(&ch, &add_r.cds, CHANGESET_CHECK); - if (node_rrtype_exists(ch.add->apex, KNOT_RRTYPE_CDS)) { - // there is indeed a change to CDS - update->zone->timers.next_ds_push = time(NULL); - zone_events_schedule_now(update->zone, ZONE_EVENT_DS_PUSH); - } CHECK_RET; } diff --git a/src/knot/events/events.c b/src/knot/events/events.c index 6082c042af93ebc7d0f3ec6e6bdf03b58b9fbf3c..f62843a6421dbd7c8be328f619cc6fb813e28f79 100644 --- a/src/knot/events/events.c +++ b/src/knot/events/events.c @@ -48,8 +48,7 @@ static const event_info_t EVENT_INFO[] = { { ZONE_EVENT_UFREEZE, event_ufreeze, "update freeze" }, { ZONE_EVENT_UTHAW, event_uthaw, "update thaw" }, { ZONE_EVENT_NSEC3RESALT, event_nsec3resalt, "NSEC3 resalt" }, - { ZONE_EVENT_DS_CHECK, event_ds_check, "DS check" }, - { ZONE_EVENT_DS_PUSH, event_ds_push, "DS push" }, + { ZONE_EVENT_PARENT_DS_Q, event_parent_ds_q, "parent DS query" }, { 0 } }; @@ -80,7 +79,7 @@ bool ufreeze_applies(zone_event_type_t type) case ZONE_EVENT_FLUSH: case ZONE_EVENT_DNSSEC: case ZONE_EVENT_NSEC3RESALT: - case ZONE_EVENT_DS_CHECK: + case ZONE_EVENT_PARENT_DS_Q: return true; default: return false; diff --git a/src/knot/events/events.h b/src/knot/events/events.h index 53612f731ff9b38dc7584d99ef02529ffd1a5b82..e14daae0adf186423b14b26648788fd4a036ebfc 100644 --- a/src/knot/events/events.h +++ b/src/knot/events/events.h @@ -40,8 +40,7 @@ typedef enum zone_event_type { ZONE_EVENT_UFREEZE, ZONE_EVENT_UTHAW, ZONE_EVENT_NSEC3RESALT, - ZONE_EVENT_DS_CHECK, - ZONE_EVENT_DS_PUSH, + ZONE_EVENT_PARENT_DS_Q, // terminator ZONE_EVENT_COUNT, } zone_event_type_t; diff --git a/src/knot/events/handlers.h b/src/knot/events/handlers.h index b000ba22f61684ab184cded5a6b9c4d1bad4ee5d..ca50ccbcac9d08054651e4e2256a05de054e558a 100644 --- a/src/knot/events/handlers.h +++ b/src/knot/events/handlers.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,6 +44,4 @@ int event_uthaw(conf_t *conf, zone_t *zone); /*! \brief Recreates salt for NSEC3 hashing. */ int event_nsec3resalt(conf_t *conf, zone_t *zone); /*! \brief When CDS/CDNSKEY published, look for matching DS */ -int event_ds_check(conf_t *conf, zone_t *zone); -/*! \brief After change of CDS/CDNSKEY, push the new DS to parent zone as DDNS. */ -int event_ds_push(conf_t *conf, zone_t *zone); +int event_parent_ds_q(conf_t *conf, zone_t *zone); diff --git a/src/knot/events/handlers/dnssec.c b/src/knot/events/handlers/dnssec.c index 50af00a6e2dc9a9270fc0c15900342882bcc7767..32d3b7d3d204059289e6fb19ad4bd3fffa3a5001 100644 --- a/src/knot/events/handlers/dnssec.c +++ b/src/knot/events/handlers/dnssec.c @@ -50,8 +50,8 @@ void event_dnssec_reschedule(conf_t *conf, zone_t *zone, log_dnssec_next(zone->name, (time_t)refresh_at); - if (refresh->plan_ds_check) { - zone->timers.next_ds_check = now; + if (refresh->plan_ds_query) { + zone->timers.next_parent_ds_q = now; } if (refresh->last_nsec3resalt) { @@ -60,7 +60,7 @@ void event_dnssec_reschedule(conf_t *conf, zone_t *zone, zone_events_schedule_at(zone, ZONE_EVENT_DNSSEC, refresh_at ? (time_t)refresh_at : ignore, - ZONE_EVENT_DS_CHECK, refresh->plan_ds_check ? now : ignore, + ZONE_EVENT_PARENT_DS_Q, refresh->plan_ds_query ? now : ignore, ZONE_EVENT_NSEC3RESALT, refresh->next_nsec3resalt ? refresh->next_nsec3resalt : ignore, ZONE_EVENT_NOTIFY, zone_changed ? now : ignore ); diff --git a/src/knot/events/handlers/ds_push.c b/src/knot/events/handlers/ds_push.c deleted file mode 100644 index 603dd8abb36fde46413afa4a579fd22bd5377378..0000000000000000000000000000000000000000 --- a/src/knot/events/handlers/ds_push.c +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -#include <assert.h> - -#include "knot/common/log.h" -#include "knot/conf/conf.h" -#include "knot/query/query.h" -#include "knot/query/requestor.h" -#include "knot/zone/zone.h" -#include "libknot/errcode.h" - -struct ds_push_data { - const knot_dname_t *zone; - knot_dname_t *parent_soa; - knot_rrset_t del_old_ds; - knot_rrset_t new_ds; - const struct sockaddr *remote; - struct query_edns_data edns; -}; - -#define DS_PUSH_RETRY 600 - -#define DS_PUSH_LOG(priority, zone, remote, fmt, ...) \ - ns_log(priority, zone, LOG_OPERATION_DS_PUSH, LOG_DIRECTION_OUT, remote, \ - fmt, ## __VA_ARGS__) - -static const knot_rdata_t remove_cds = { 5, { 0, 0, 0, 0, 0 } }; - -static int ds_push_begin(knot_layer_t *layer, void *params) -{ - layer->data = params; - - return KNOT_STATE_PRODUCE; -} - -static int parent_soa_produce(struct ds_push_data *data, knot_pkt_t *pkt) -{ - const knot_dname_t *query_name = knot_wire_next_label(data->zone, NULL); - - int ret = knot_pkt_put_question(pkt, query_name, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); - if (ret != KNOT_EOK) { - return KNOT_STATE_FAIL; - } - - ret = query_put_edns(pkt, &data->edns); - if (ret != KNOT_EOK) { - return KNOT_STATE_FAIL; - } - - return KNOT_STATE_CONSUME; -} - -static int ds_push_produce(knot_layer_t *layer, knot_pkt_t *pkt) -{ - struct ds_push_data *data = layer->data; - - query_init_pkt(pkt); - - if (data->parent_soa == NULL) { - return parent_soa_produce(data, pkt); - } - - knot_wire_set_opcode(pkt->wire, KNOT_OPCODE_UPDATE); - int ret = knot_pkt_put_question(pkt, data->parent_soa, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); - if (ret != KNOT_EOK) { - return KNOT_STATE_FAIL; - } - - knot_pkt_begin(pkt, KNOT_AUTHORITY); - - assert(data->del_old_ds.type == KNOT_RRTYPE_DS); - ret = knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, &data->del_old_ds, 0); - if (ret != KNOT_EOK) { - return KNOT_STATE_FAIL; - } - - assert(data->new_ds.type == KNOT_RRTYPE_DS); - assert(!knot_rrset_empty(&data->new_ds)); - if (knot_rdata_cmp(data->new_ds.rrs.rdata, &remove_cds) != 0) { - // Otherwise only remove DS - it was a special "remove CDS". - ret = knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, &data->new_ds, 0); - if (ret != KNOT_EOK) { - return KNOT_STATE_FAIL; - } - } - - query_put_edns(pkt, &data->edns); - - return KNOT_STATE_CONSUME; -} - -static const knot_rrset_t *sect_soa(const knot_pkt_t *pkt, knot_section_t sect) -{ - const knot_pktsection_t *s = knot_pkt_section(pkt, sect); - const knot_rrset_t *rr = s->count > 0 ? knot_pkt_rr(s, 0) : NULL; - if (rr == NULL || rr->type != KNOT_RRTYPE_SOA || rr->rrs.count != 1) { - return NULL; - } - return rr; -} - -static int ds_push_consume(knot_layer_t *layer, knot_pkt_t *pkt) -{ - struct ds_push_data *data = layer->data; - - if (data->parent_soa != NULL) { - // DS push has already been sent, just finish the action. - free(data->parent_soa); - return KNOT_STATE_DONE; - } - - const knot_rrset_t *parent_soa = sect_soa(pkt, KNOT_ANSWER); - if (parent_soa == NULL) { - parent_soa = sect_soa(pkt, KNOT_AUTHORITY); - } - if (parent_soa == NULL) { - DS_PUSH_LOG(LOG_WARNING, data->zone, data->remote, - "malformed message"); - return KNOT_STATE_FAIL; - } - - data->parent_soa = knot_dname_copy(parent_soa->owner, NULL); - - return KNOT_STATE_RESET; -} - -static int ds_push_reset(knot_layer_t *layer) -{ - (void)layer; - return KNOT_STATE_PRODUCE; -} - -static const knot_layer_api_t DS_PUSH_API = { - .begin = ds_push_begin, - .produce = ds_push_produce, - .reset = ds_push_reset, - .consume = ds_push_consume, -}; - -static int send_ds_push(conf_t *conf, zone_t *zone, - const conf_remote_t *parent, int timeout) -{ - knot_rrset_t zone_cds = node_rrset(zone->contents->apex, KNOT_RRTYPE_CDS); - if (knot_rrset_empty(&zone_cds)) { - return KNOT_EOK; // No CDS, do nothing. - } - zone_cds.type = KNOT_RRTYPE_DS; - - struct ds_push_data data = { - .zone = zone->name, - .new_ds = zone_cds, - .remote = (struct sockaddr *)&parent->addr, - }; - - knot_rrset_init(&data.del_old_ds, zone->name, KNOT_RRTYPE_DS, KNOT_CLASS_ANY, 0); - query_edns_data_init(&data.edns, conf, zone->name, parent->addr.ss_family); - - knot_requestor_t requestor; - knot_requestor_init(&requestor, &DS_PUSH_API, &data, NULL); - - knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); - if (pkt == NULL) { - knot_requestor_clear(&requestor); - return KNOT_ENOMEM; - } - - const struct sockaddr *dst = (struct sockaddr *)&parent->addr; - const struct sockaddr *src = (struct sockaddr *)&parent->via; - knot_request_t *req = knot_request_make(NULL, dst, src, pkt, &parent->key, 0); - if (req == NULL) { - knot_request_free(req, NULL); - knot_requestor_clear(&requestor); - return KNOT_ENOMEM; - } - - int ret = knot_requestor_exec(&requestor, req, timeout); - - if (ret == KNOT_EOK && knot_pkt_ext_rcode(req->resp) == 0) { - DS_PUSH_LOG(LOG_INFO, zone->name, dst, "success"); - } else if (knot_pkt_ext_rcode(req->resp) == 0) { - DS_PUSH_LOG(LOG_WARNING, zone->name, dst, - "failed (%s)", knot_strerror(ret)); - } else { - DS_PUSH_LOG(LOG_WARNING, zone->name, dst, - "server responded with error '%s'", - knot_pkt_ext_rcode_name(req->resp)); - } - - knot_request_free(req, NULL); - knot_requestor_clear(&requestor); - - return ret; -} - -int event_ds_push(conf_t *conf, zone_t *zone) -{ - assert(zone); - - if (zone_contents_is_empty(zone->contents)) { - return KNOT_EOK; - } - - int timeout = conf->cache.srv_tcp_reply_timeout * 1000; - - conf_val_t policy_id = conf_zone_get(conf, C_DNSSEC_POLICY, zone->name); - conf_val_t ds_push = conf_id_get(conf, C_POLICY, C_DS_PUSH, &policy_id); - while (ds_push.code == KNOT_EOK) { - conf_val_t addr = conf_id_get(conf, C_RMT, C_ADDR, &ds_push); - size_t addr_count = conf_val_count(&addr); - - int ret = KNOT_EOK; - for (int i = 0; i < addr_count; i++) { - conf_remote_t parent = conf_remote(conf, &ds_push, i); - ret = send_ds_push(conf, zone, &parent, timeout); - if (ret == KNOT_EOK) { - break; - } - } - - if (ret != KNOT_EOK) { - time_t next_push = time(NULL) + DS_PUSH_RETRY; - zone_events_schedule_at(zone, ZONE_EVENT_DS_PUSH, next_push); - zone->timers.next_ds_push = next_push; - } - - conf_val_next(&ds_push); - } - - return KNOT_EOK; -} diff --git a/src/knot/events/handlers/ds_check.c b/src/knot/events/handlers/parent_ds_query.c similarity index 88% rename from src/knot/events/handlers/ds_check.c rename to src/knot/events/handlers/parent_ds_query.c index 96006f4d0f5f12772f35850c5f91383b42429109..2056a654a65bef55dee0afa9c68562b4c3204ec1 100644 --- a/src/knot/events/handlers/ds_check.c +++ b/src/knot/events/handlers/parent_ds_query.c @@ -17,7 +17,7 @@ #include "knot/dnssec/ds_query.h" #include "knot/zone/zone.h" -int event_ds_check(conf_t *conf, zone_t *zone) +int event_parent_ds_q(conf_t *conf, zone_t *zone) { kdnssec_ctx_t ctx = { 0 }; @@ -35,12 +35,12 @@ int event_ds_check(conf_t *conf, zone_t *zone) ret = knot_parent_ds_query(&ctx, &keyset, conf->cache.srv_tcp_reply_timeout * 1000); - zone->timers.next_ds_check = 0; + zone->timers.next_parent_ds_q = 0; if (ret != KNOT_EOK) { if (ctx.policy->ksk_sbm_check_interval > 0) { time_t next_check = time(NULL) + ctx.policy->ksk_sbm_check_interval; - zone->timers.next_ds_check = next_check; - zone_events_schedule_at(zone, ZONE_EVENT_DS_CHECK, next_check); + zone->timers.next_parent_ds_q = next_check; + zone_events_schedule_at(zone, ZONE_EVENT_PARENT_DS_Q, next_check); } } else { zone_events_schedule_now(zone, ZONE_EVENT_DNSSEC); diff --git a/src/knot/events/replan.c b/src/knot/events/replan.c index 206bd3aad7398fade0d4b29fafcd60aa3b5821d4..9df2e2d10701c759b5c3fd781fd7c5a81919a5ea 100644 --- a/src/knot/events/replan.c +++ b/src/knot/events/replan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -130,14 +130,10 @@ void replan_from_timers(conf_t *conf, zone_t *zone) } } - time_t ds = zone->timers.next_ds_check; + time_t ds = zone->timers.next_parent_ds_q; if (ds == 0) { ds = TIME_IGNORE; } - time_t ds_push = zone->timers.next_ds_push; - if (ds_push == 0) { - ds_push = TIME_IGNORE; - } zone_events_schedule_at(zone, ZONE_EVENT_REFRESH, refresh, @@ -145,8 +141,7 @@ void replan_from_timers(conf_t *conf, zone_t *zone) ZONE_EVENT_EXPIRE, expire, ZONE_EVENT_FLUSH, flush, ZONE_EVENT_NSEC3RESALT, resalt, - ZONE_EVENT_DS_CHECK, ds, - ZONE_EVENT_DS_PUSH, ds_push); + ZONE_EVENT_PARENT_DS_Q, ds); } void replan_load_new(zone_t *zone) diff --git a/src/knot/modules/onlinesign/onlinesign.c b/src/knot/modules/onlinesign/onlinesign.c index 6c55ece808732530e8d45941bb87a8528799313f..72538a66ea5b15a4b9473aa4bedae49264e817c8 100644 --- a/src/knot/modules/onlinesign/onlinesign.c +++ b/src/knot/modules/onlinesign/onlinesign.c @@ -518,7 +518,7 @@ static knotd_in_state_t pre_routine(knotd_in_state_t state, knot_pkt_t *pkt, ret = knot_dnssec_key_rollover(mod->dnssec, KEY_ROLL_ALLOW_KSK_ROLL | KEY_ROLL_ALLOW_ZSK_ROLL, &resch); } if (ret == KNOT_EOK) { - if (resch.plan_ds_check && mod->dnssec->policy->ksk_sbm_check_interval > 0) { + if (resch.plan_ds_query && mod->dnssec->policy->ksk_sbm_check_interval > 0) { ctx->event_parent_ds_q = mod->dnssec->now + mod->dnssec->policy->ksk_sbm_check_interval; } else { ctx->event_parent_ds_q = 0; @@ -646,7 +646,7 @@ static int online_sign_ctx_new(online_sign_ctx_t **ctx_ptr, knotd_mod_t *mod) return ret; } - if (resch.plan_ds_check) { + if (resch.plan_ds_query) { ctx->event_parent_ds_q = time(NULL); } ctx->event_rollover = resch.next_rollover; diff --git a/src/knot/zone/timers.c b/src/knot/zone/timers.c index 886039a9e9c67bc04523bebf9b938d9150c7a0c2..fff69fdd1b95d697d155ff454e89233f7f0ceb46 100644 --- a/src/knot/zone/timers.c +++ b/src/knot/zone/timers.c @@ -54,8 +54,7 @@ enum timer_id { TIMER_LAST_REFRESH, TIMER_NEXT_REFRESH, TIMER_LAST_RESALT, - TIMER_NEXT_DS_CHECK, - TIMER_NEXT_DS_PUSH, + TIMER_NEXT_PARENT_DS_Q }; #define TIMER_SIZE (sizeof(uint8_t) + sizeof(uint64_t)) @@ -79,13 +78,12 @@ static int deserialize_timers(zone_timers_t *timers_ptr, uint8_t id = wire_ctx_read_u8(&wire); uint64_t value = wire_ctx_read_u64(&wire); switch (id) { - case TIMER_SOA_EXPIRE: timers.soa_expire = value; break; - case TIMER_LAST_FLUSH: timers.last_flush = value; break; - case TIMER_LAST_REFRESH: timers.last_refresh = value; break; - case TIMER_NEXT_REFRESH: timers.next_refresh = value; break; - case TIMER_LAST_RESALT: timers.last_resalt = value; break; - case TIMER_NEXT_DS_CHECK: timers.next_ds_check = value; break; - case TIMER_NEXT_DS_PUSH: timers.next_ds_push = value; break; + case TIMER_SOA_EXPIRE: timers.soa_expire = value; break; + case TIMER_LAST_FLUSH: timers.last_flush = value; break; + case TIMER_LAST_REFRESH: timers.last_refresh = value; break; + case TIMER_NEXT_REFRESH: timers.next_refresh = value; break; + case TIMER_LAST_RESALT: timers.last_resalt = value; break; + case TIMER_NEXT_PARENT_DS_Q: timers.next_parent_ds_q = value; break; default: break; // ignore } } @@ -104,14 +102,13 @@ static void txn_write_timers(knot_lmdb_txn_t *txn, const knot_dname_t *zone, const zone_timers_t *timers) { MDB_val k = { knot_dname_size(zone), (void *)zone }; - MDB_val v = knot_lmdb_make_key("BLBLBLBLBLBLBL", - TIMER_SOA_EXPIRE, (uint64_t)timers->soa_expire, - TIMER_LAST_FLUSH, (uint64_t)timers->last_flush, - TIMER_LAST_REFRESH, (uint64_t)timers->last_refresh, - TIMER_NEXT_REFRESH, (uint64_t)timers->next_refresh, - TIMER_LAST_RESALT, (uint64_t)timers->last_resalt, - TIMER_NEXT_DS_CHECK, (uint64_t)timers->next_ds_check, - TIMER_NEXT_DS_PUSH, (uint64_t)timers->next_ds_push); + MDB_val v = knot_lmdb_make_key("BLBLBLBLBLBL", + TIMER_SOA_EXPIRE, (uint64_t)timers->soa_expire, + TIMER_LAST_FLUSH, (uint64_t)timers->last_flush, + TIMER_LAST_REFRESH, (uint64_t)timers->last_refresh, + TIMER_NEXT_REFRESH, (uint64_t)timers->next_refresh, + TIMER_LAST_RESALT, (uint64_t)timers->last_resalt, + TIMER_NEXT_PARENT_DS_Q, (uint64_t)timers->next_parent_ds_q); knot_lmdb_insert(txn, &k, &v); free(v.mv_data); } diff --git a/src/knot/zone/timers.h b/src/knot/zone/timers.h index 62ab9f4f4b9fd7aab36baa69239d4c7e77e530ab..5fd5b003ce09b0c089035eae0655eab597d6c7c6 100644 --- a/src/knot/zone/timers.h +++ b/src/knot/zone/timers.h @@ -30,9 +30,8 @@ struct zone_timers { time_t last_flush; //!< Last zone file synchronization. time_t last_refresh; //!< Last successful zone refresh attempt. time_t next_refresh; //!< Next zone refresh attempt. - time_t last_resalt; //!< Last NSEC3 resalt. - time_t next_ds_check; //!< Next parent DS check. - time_t next_ds_push; //!< Next DDNS to parent zone with updated DS record. + time_t last_resalt; //!< Last NSEC3 resalt + time_t next_parent_ds_q; //!< Next parent ds query }; typedef struct zone_timers zone_timers_t; diff --git a/tests-extra/tests/dnssec/ds_push/data/com.zone b/tests-extra/tests/dnssec/ds_push/data/com.zone deleted file mode 100644 index 34859ad30ceedf225a754e4ac78f928ccb8ad156..0000000000000000000000000000000000000000 --- a/tests-extra/tests/dnssec/ds_push/data/com.zone +++ /dev/null @@ -1,6 +0,0 @@ -$ORIGIN com. -$TTL 1200 - -@ SOA ns admin 20110100 7 7 16 600 -ns AAAA ::0 - diff --git a/tests-extra/tests/dnssec/ds_push/data/example.com.zone b/tests-extra/tests/dnssec/ds_push/data/example.com.zone deleted file mode 100644 index ecd27e06e967ddb34a7420fd99137c0eec1dbdb2..0000000000000000000000000000000000000000 --- a/tests-extra/tests/dnssec/ds_push/data/example.com.zone +++ /dev/null @@ -1,9 +0,0 @@ -example.com. 3 SOA dns1.example.com. hostmaster.example.com. 2010111227 21600 3600 604800 3 -example.com. 0 NS dns1.example.com. -example.com. 2 MX 10 mail.example.com. -dns1.example.com. 4 A 192.0.2.1 -dns1.example.com. 3 AAAA 2001:db8::1 -foo.example.com. 5 A 192.0.2.4 -mail.example.com. 3 A 192.0.2.3 -mail.example.com. 1 AAAA 2001:db8::3 - diff --git a/tests-extra/tests/dnssec/ds_push/test.py b/tests-extra/tests/dnssec/ds_push/test.py deleted file mode 100644 index 62f81c9357956902456b4ad1d30f8d33a43da823..0000000000000000000000000000000000000000 --- a/tests-extra/tests/dnssec/ds_push/test.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 - -""" -Check of automatic KSK rollover with DS push. -""" - -import collections -import os -import shutil -import datetime -import subprocess -from subprocess import check_call - -from dnstest.utils import * -from dnstest.keys import Keymgr -from dnstest.test import Test - -def pregenerate_key(server, zone, alg): - class a_class_with_name: - def __init__(self, name): - self.name = name - - server.gen_key(a_class_with_name("notexisting.zone."), ksk=True, alg=alg, - addtopolicy=zone[0].name) - -# check zone if keys are present and used for signing -def check_zone(server, zone, dnskeys, dnskey_rrsigs, cdnskeys, soa_rrsigs, msg): - qdnskeys = server.dig("example.com", "DNSKEY", bufsize=4096) - found_dnskeys = qdnskeys.count("DNSKEY") - - qdnskeyrrsig = server.dig("example.com", "DNSKEY", dnssec=True, bufsize=4096) - found_rrsigs = qdnskeyrrsig.count("RRSIG") - - qcdnskey = server.dig("example.com", "CDNSKEY", bufsize=4096) - found_cdnskeys = qcdnskey.count("CDNSKEY") - - qsoa = server.dig("example.com", "SOA", dnssec=True, bufsize=4096) - found_soa_rrsigs = qsoa.count("RRSIG") - - check_log("DNSKEYs: %d (expected %d)" % (found_dnskeys, dnskeys)); - check_log("RRSIGs: %d (expected %d)" % (found_soa_rrsigs, soa_rrsigs)); - check_log("DNSKEY-RRSIGs: %d (expected %d)" % (found_rrsigs, dnskey_rrsigs)); - check_log("CDNSKEYs: %d (expected %d)" % (found_cdnskeys, cdnskeys)); - - if found_dnskeys != dnskeys: - set_err("BAD DNSKEY COUNT: " + msg) - detail_log("!DNSKEYs not published and activated as expected: " + msg) - - if found_soa_rrsigs != soa_rrsigs: - set_err("BAD RRSIG COUNT: " + msg) - detail_log("!RRSIGs not published and activated as expected: " + msg) - - if found_rrsigs != dnskey_rrsigs: - set_err("BAD DNSKEY RRSIG COUNT: " + msg) - detail_log("!RRSIGs not published and activated as expected: " + msg) - - if found_cdnskeys != cdnskeys: - set_err("BAD CDNSKEY COUNT: " + msg) - detail_log("!CDNSKEYs not published and activated as expected: " + msg) - - detail_log(SEP) - - # Valgrind delay breaks the timing! - if not server.valgrind: - server.zone_backup(zone, flush=True) - server.zone_verify(zone) - -def wait_for_rrsig_count(t, server, rrtype, rrsig_count, timeout): - rtime = 0 - while True: - qdnskeyrrsig = server.dig("example.com", rrtype, dnssec=True, bufsize=4096) - found_rrsigs = qdnskeyrrsig.count("RRSIG") - if found_rrsigs == rrsig_count: - break - rtime = rtime + 1 - t.sleep(1) - if rtime > timeout: - break - -def wait_for_dnskey_count(t, server, dnskey_count, timeout): - rtime = 0 - while True: - qdnskeyrrsig = server.dig("example.com", "DNSKEY", dnssec=True, bufsize=4096) - found_dnskeys = qdnskeyrrsig.count("DNSKEY") - if found_dnskeys == dnskey_count: - break - rtime = rtime + 1 - t.sleep(1) - if rtime > timeout: - break - -def watch_ksk_rollover(t, server, zone, before_keys, after_keys, total_keys, desc, set_ksk_lifetime): - check_zone(server, zone, before_keys, 1, 1, 1, desc + ": initial keys") - orig_ksk_lifetime = server.dnssec(zone).ksk_lifetime - - server.dnssec(zone).ksk_lifetime = set_ksk_lifetime if set_ksk_lifetime > 0 else orig_ksk_lifetime - server.gen_confile() - server.reload() - - wait_for_dnskey_count(t, server, total_keys, 20) - - t.sleep(3) - check_zone(server, zone, total_keys, 1, 1, 1, desc + ": published new") - - server.dnssec(zone).ksk_lifetime = orig_ksk_lifetime - server.gen_confile() - server.reload() - - wait_for_rrsig_count(t, server, "DNSKEY", 2, 20) - check_zone(server, zone, total_keys, 2, 1, 1 if before_keys > 1 else 2, desc + ": both keys active") - - wait_for_rrsig_count(t, server, "DNSKEY", 1, 20) - check_zone(server, zone, total_keys, 1, 1, 1, desc + ": old key retired") - - wait_for_dnskey_count(t, server, after_keys, 20) - check_zone(server, zone, after_keys, 1, 1, 1, desc + ": old key removed") - -t = Test(tsig=False) - -parent = t.server("knot") -parent_zone = t.zone("com.", storage=".") -t.link(parent_zone, parent, ddns=True) - -parent.dnssec(parent_zone).enable = True - -child = t.server("knot") -child_zone = t.zone("example.com.", storage=".") -t.link(child_zone, child) - -child.zonefile_sync = 24 * 60 * 60 - -child.dnssec(child_zone).enable = True -child.dnssec(child_zone).manual = False -child.dnssec(child_zone).alg = "ECDSAP256SHA256" -child.dnssec(child_zone).dnskey_ttl = 2 -child.dnssec(child_zone).zsk_lifetime = 99999 -child.dnssec(child_zone).ksk_lifetime = 300 # this can be possibly left also infinity -child.dnssec(child_zone).propagation_delay = 11 -child.dnssec(child_zone).ksk_sbm_check = [ parent ] -child.dnssec(child_zone).ksk_sbm_check_interval = 2 -child.dnssec(child_zone).ds_push = parent -child.dnssec(child_zone).ksk_shared = True -child.dnssec(child_zone).cds_publish = "always" - -# parameters -ZONE = "example.com." - -#t.start() -t.generate_conf() -parent.start() -t.sleep(2) -child.start() -child.zone_wait(child_zone) - -t.sleep(5) - -pregenerate_key(child, child_zone, "ECDSAP256SHA256") -watch_ksk_rollover(t, child, child_zone, 2, 2, 3, "KSK rollover", 27) - -t.end() diff --git a/tests-extra/tools/dnstest/server.py b/tests-extra/tools/dnstest/server.py index b54489ed202ca1c078e657c39b5deba3307dc9ac..079db0b22cdc131d0e1a5c7371cabb6eeb57d36b 100644 --- a/tests-extra/tools/dnstest/server.py +++ b/tests-extra/tools/dnstest/server.py @@ -58,7 +58,6 @@ class ZoneDnssec(object): self.nsec3_salt_len = None self.ksk_sbm_check = [] self.ksk_sbm_check_interval = None - self.ds_push = None self.ksk_shared = None self.cds_publish = None self.offline_ksk = None @@ -1117,7 +1116,7 @@ class Knot(Server): if slave.tsig: s.item_str("key", slave.tsig.name) servers.add(slave.name) - for parent in z.dnssec.ksk_sbm_check + [ z.dnssec.ds_push ] if z.dnssec.ds_push else z.dnssec.ksk_sbm_check: + for parent in z.dnssec.ksk_sbm_check: if parent.name not in servers: if not have_remote: s.begin("remote") @@ -1225,8 +1224,6 @@ class Knot(Server): self._str(s, "nsec3-salt-length", z.dnssec.nsec3_salt_len) if len(z.dnssec.ksk_sbm_check) > 0: s.item("ksk-submission", z.name) - if z.dnssec.ds_push: - self._str(s, "ds-push", z.dnssec.ds_push.name) self._bool(s, "ksk-shared", z.dnssec.ksk_shared) self._str(s, "cds-cdnskey-publish", z.dnssec.cds_publish) self._str(s, "offline-ksk", z.dnssec.offline_ksk) diff --git a/tests/knot/test_zone_timers.c b/tests/knot/test_zone_timers.c index f364155b89d25607e382af4beb3d0cab916320dd..849081be3aadc1a376b2b6eb81b4b27dd98a5f3e 100644 --- a/tests/knot/test_zone_timers.c +++ b/tests/knot/test_zone_timers.c @@ -31,21 +31,9 @@ static const zone_timers_t MOCK_TIMERS = { .next_refresh = 1474559960, .last_flush = 1, .last_resalt = 2, - .next_ds_check = 1474559961, - .next_ds_push = 1474559962, + .next_parent_ds_q = 0, }; -static bool timers_eq(const zone_timers_t *a, const zone_timers_t *b) -{ - return a->soa_expire == b->soa_expire && - a->last_refresh == b->last_refresh && - a->next_refresh == b->next_refresh && - a->last_flush == b->last_flush && - a->last_resalt == b->last_resalt && - a->next_ds_check == b->next_ds_check && - a->next_ds_push == b->next_ds_push; -} - static bool keep_all(const knot_dname_t *zone, void *data) { return true; @@ -56,6 +44,14 @@ static bool remove_all(const knot_dname_t *zone, void *data) return false; } +static bool timers_eq(const zone_timers_t *a, const zone_timers_t *b) +{ + return a->soa_expire == b->soa_expire && + a->last_refresh == b->last_refresh && + a->next_refresh == b->next_refresh && + a->last_flush == b->last_flush; +} + int main(int argc, char *argv[]) { plan_lazy(); @@ -87,7 +83,9 @@ int main(int argc, char *argv[]) memset(&timers, 0, sizeof(timers)); ret = zone_timers_read(db, zone, &timers); ok(ret == KNOT_EOK, "zone_timers_read()"); - ok(timers_eq(&timers, &MOCK_TIMERS), "inconsistent timers"); + ok(timers_eq(&timers, &MOCK_TIMERS), "timers unmalformed (%u == %u, %ld == %ld etc.)", + timers.soa_expire, MOCK_TIMERS.soa_expire, (long)timers.last_refresh, + (long)MOCK_TIMERS.last_refresh); // Sweep none ret = zone_timers_sweep(db, keep_all, NULL);