Commit 36e76aff authored by Marek Vavruša's avatar Marek Vavruša

zone: signing and diff sort of works

removed most of cruft from zones.c
moved relevant stuff to appropriate files

problems:
- still a lot of duplicated code with changesets (ddns, signing, ixfr..)
- can't store changesets after application (zone.c:186)
- ddns and transfers are unsafe until made into serialized zone events
parent 4fe409c0
......@@ -613,6 +613,119 @@ int remote_answer(int sock, server_t *s, knot_pkt_t *pkt)
return ret;
}
static int zones_verify_tsig_query(const knot_pkt_t *query,
const knot_tsig_key_t *key,
knot_rcode_t *rcode, uint16_t *tsig_rcode,
uint64_t *tsig_prev_time_signed)
{
assert(key != NULL);
assert(rcode != NULL);
assert(tsig_rcode != NULL);
if (query->tsig_rr == NULL) {
dbg_zones("TSIG key required, but not in query - REFUSED.\n");
*rcode = KNOT_RCODE_REFUSED;
return KNOT_TSIG_EBADKEY;
}
/*
* 1) Check if we support the requested algorithm.
*/
knot_tsig_algorithm_t alg = tsig_rdata_alg(query->tsig_rr);
if (knot_tsig_digest_length(alg) == 0) {
log_answer_info("Unsupported digest algorithm "
"requested, treating as bad key\n");
/*! \todo [TSIG] It is unclear from RFC if I
* should treat is as a bad key
* or some other error.
*/
*rcode = KNOT_RCODE_NOTAUTH;
*tsig_rcode = KNOT_RCODE_BADKEY;
return KNOT_TSIG_EBADKEY;
}
const knot_dname_t *kname = knot_rrset_owner(query->tsig_rr);
assert(kname != NULL);
/*
* 2) Find the particular key used by the TSIG.
* Check not only name, but also the algorithm.
*/
if (key && kname && knot_dname_cmp(key->name, kname) == 0
&& key->algorithm == alg) {
dbg_zones_verb("Found claimed TSIG key for comparison\n");
} else {
*rcode = KNOT_RCODE_NOTAUTH;
*tsig_rcode = KNOT_RCODE_BADKEY;
return KNOT_TSIG_EBADKEY;
}
/*
* 3) Validate the query with TSIG.
*/
/* Prepare variables for TSIG */
/*! \todo These need to be saved to the response somehow. */
//size_t tsig_size = tsig_wire_maxsize(key);
size_t digest_max_size = knot_tsig_digest_length(key->algorithm);
//size_t digest_size = 0;
//uint64_t tsig_prev_time_signed = 0;
//uint8_t *digest = (uint8_t *)malloc(digest_max_size);
//memset(digest, 0 , digest_max_size);
/* Copy MAC from query. */
dbg_zones_verb("Validating TSIG from query\n");
//const uint8_t* mac = tsig_rdata_mac(tsig_rr);
size_t mac_len = tsig_rdata_mac_length(query->tsig_rr);
int ret = KNOT_EOK;
if (mac_len > digest_max_size) {
*rcode = KNOT_RCODE_FORMERR;
dbg_zones("MAC length %zu exceeds digest "
"maximum size %zu\n", mac_len, digest_max_size);
return KNOT_EMALF;
} else {
//memcpy(digest, mac, mac_len);
//digest_size = mac_len;
/* Check query TSIG. */
ret = knot_tsig_server_check(query->tsig_rr,
query->wire,
query->size, key);
dbg_zones_verb("knot_tsig_server_check() returned %s\n",
knot_strerror(ret));
/* Evaluate TSIG check results. */
switch(ret) {
case KNOT_EOK:
*rcode = KNOT_RCODE_NOERROR;
break;
case KNOT_TSIG_EBADKEY:
*tsig_rcode = KNOT_RCODE_BADKEY;
*rcode = KNOT_RCODE_NOTAUTH;
break;
case KNOT_TSIG_EBADSIG:
*tsig_rcode = KNOT_RCODE_BADSIG;
*rcode = KNOT_RCODE_NOTAUTH;
break;
case KNOT_TSIG_EBADTIME:
*tsig_rcode = KNOT_RCODE_BADTIME;
// store the time signed from the query
*tsig_prev_time_signed = tsig_rdata_time_signed(query->tsig_rr);
*rcode = KNOT_RCODE_NOTAUTH;
break;
case KNOT_EMALF:
*rcode = KNOT_RCODE_FORMERR;
break;
default:
*rcode = KNOT_RCODE_SERVFAIL;
}
}
return ret;
}
int remote_process(server_t *s, conf_iface_t *ctl_if, int sock,
uint8_t* buf, size_t buflen)
{
......
......@@ -28,7 +28,7 @@
#include "knot/zone/zone.h"
static int init_dnssec_structs(const zone_contents_t *zone,
conf_zone_t *config,
const conf_zone_t *config,
knot_zone_keys_t *zone_keys,
knot_dnssec_policy_t *policy,
knot_update_serial_t soa_up, bool force)
......@@ -65,10 +65,9 @@ static int init_dnssec_structs(const zone_contents_t *zone,
return KNOT_EOK;
}
static int zone_sign(zone_contents_t *zone, conf_zone_t *zone_config,
static int zone_sign(zone_contents_t *zone, const conf_zone_t *zone_config,
knot_changeset_t *out_ch, bool force,
knot_update_serial_t soa_up, uint32_t *refresh_at,
uint32_t new_serial)
knot_update_serial_t soa_up, uint32_t *refresh_at)
{
assert(zone);
assert(out_ch);
......@@ -78,6 +77,9 @@ static int zone_sign(zone_contents_t *zone, conf_zone_t *zone_config,
return KNOT_ENOMEM;
}
log_zone_info("DNSSEC: Zone %s - Signing started...\n", zone_config->name);
uint32_t new_serial = zone_contents_next_serial(zone, zone_config->serial_policy);
dbg_dnssec_verb("Changeset empty before generating NSEC chain: %d\n",
knot_changeset_is_empty(out_ch));
......@@ -147,42 +149,39 @@ static int zone_sign(zone_contents_t *zone, conf_zone_t *zone_config,
knot_free_zone_keys(&zone_keys);
dbg_dnssec_detail("Zone signed: changes=%zu\n",
knot_changeset_size(out_ch));
log_zone_info("%s Successfully signed.\n", msgpref);
free(msgpref);
return KNOT_EOK;
}
int knot_dnssec_zone_sign(zone_contents_t *zone, conf_zone_t *zone_config,
int knot_dnssec_zone_sign(zone_contents_t *zone, const conf_zone_t *zone_config,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up, uint32_t *refresh_at,
uint32_t new_serial)
knot_update_serial_t soa_up, uint32_t *refresh_at)
{
if (zone == NULL || zone_config == NULL || out_ch == NULL) {
return KNOT_EINVAL;
}
return zone_sign(zone, zone_config, out_ch, false, soa_up, refresh_at, new_serial);
return zone_sign(zone, zone_config, out_ch, false, soa_up, refresh_at);
}
int knot_dnssec_zone_sign_force(zone_contents_t *zone, conf_zone_t *zone_config,
knot_changeset_t *out_ch, uint32_t *refresh_at,
uint32_t new_serial)
int knot_dnssec_zone_sign_force(zone_contents_t *zone, const conf_zone_t *zone_config,
knot_changeset_t *out_ch, uint32_t *refresh_at)
{
if (zone == NULL || zone_config == NULL || out_ch == NULL) {
return KNOT_EINVAL;
}
return zone_sign(zone, zone_config, out_ch, true, KNOT_SOA_SERIAL_UPDATE, refresh_at,
new_serial);
return zone_sign(zone, zone_config, out_ch, true, KNOT_SOA_SERIAL_UPDATE, refresh_at);
}
int knot_dnssec_sign_changeset(const zone_contents_t *zone,
conf_zone_t *zone_config,
const knot_changeset_t *in_ch,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up,
uint32_t *refresh_at,
uint32_t new_serial,
hattrie_t **sorted_changes)
{
if (!refresh_at || !sorted_changes) {
......@@ -193,6 +192,10 @@ int knot_dnssec_sign_changeset(const zone_contents_t *zone,
return KNOT_EINVAL;
}
// Keep the original serial
knot_update_serial_t soa_up = KNOT_SOA_SERIAL_KEEP;
uint32_t new_serial = zone_contents_serial(zone);
// Init needed structures
knot_zone_keys_t zone_keys = { '\0' };
knot_dnssec_policy_t policy = { '\0' };
......
......@@ -40,14 +40,12 @@
* \param out_ch New records will be added to this changeset.
* \param soa_up SOA serial update policy.
* \param refresh_at Signature refresh time of the oldest signature in zone.
* \param new_serial
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_dnssec_zone_sign(zone_contents_t *zone, conf_zone_t *zone_config,
int knot_dnssec_zone_sign(zone_contents_t *zone, const conf_zone_t *zone_config,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up, uint32_t *refresh_at,
uint32_t new_serial);
knot_update_serial_t soa_up, uint32_t *refresh_at);
/*!
* \brief DNSSEC sign zone, store new records into changeset. Even valid
......@@ -57,13 +55,12 @@ int knot_dnssec_zone_sign(zone_contents_t *zone, conf_zone_t *zone_config,
* \param zone_config Zone/DNSSEC configuration.
* \param out_ch New records will be added to this changeset.
* \param refresh_at Signature refresh time of the oldest signature in zone.
* \param new_serial
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_dnssec_zone_sign_force(zone_contents_t *zone, conf_zone_t *zone_config,
int knot_dnssec_zone_sign_force(zone_contents_t *zone, const conf_zone_t *zone_config,
knot_changeset_t *out_ch,
uint32_t *refresh_at, uint32_t new_serial);
uint32_t *refresh_at);
/*!
* \brief Sign changeset created by DDNS or zone-diff.
......@@ -72,9 +69,7 @@ int knot_dnssec_zone_sign_force(zone_contents_t *zone, conf_zone_t *zone_config,
* \param zone_config Zone/DNSSEC configuration.
* \param in_ch Changeset created bvy DDNS or zone-diff
* \param out_ch New records will be added to this changeset.
* \param soa_up SOA serial update policy.
* \param refresh_at Signature refresh time of the new signatures.
* \param new_serial New SOA serial.
* \param sorted_changes Info about made changes, used for partial adjustment.
*
* \return Error code, KNOT_EOK if successful.
......@@ -83,9 +78,7 @@ int knot_dnssec_sign_changeset(const zone_contents_t *zone,
conf_zone_t *zone_config,
const knot_changeset_t *in_ch,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up,
uint32_t *refresh_at, uint32_t new_serial,
hattrie_t **sorted_changes);
uint32_t *refresh_at, hattrie_t **sorted_changes);
#endif // _KNOT_DNSSEC_ZONE_EVENTS_H_
/*! @} */
......@@ -140,7 +140,7 @@ static int ixfr_load_chsets(knot_changesets_t **chgsets, const zone_t *zone,
return KNOT_EUPTODATE;
}
*chgsets = knot_changesets_create();
*chgsets = knot_changesets_create(0);
if (*chgsets == NULL) {
return KNOT_ENOMEM;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -54,8 +54,7 @@ typedef enum journal_flag_t {
JOURNAL_NULL = 0 << 0, /*!< Invalid journal entry. */
JOURNAL_FREE = 1 << 0, /*!< Free journal entry. */
JOURNAL_VALID = 1 << 1, /*!< Valid journal entry. */
JOURNAL_DIRTY = 1 << 2, /*!< Journal entry cannot be evicted. */
JOURNAL_TRANS = 1 << 3 /*!< Entry is in transaction (uncommited). */
JOURNAL_DIRTY = 1 << 2 /*!< Journal entry cannot be evicted. */
} journal_flag_t;
/*!
......@@ -103,7 +102,7 @@ typedef struct journal_t
* Journal defaults and constants.
*/
#define JOURNAL_NCOUNT 1024 /*!< Default node count. */
#define JOURNAL_MAGIC {'k', 'n', 'o', 't', '1', '5', '0'}
#define JOURNAL_MAGIC {'k', 'n', 'o', 't', '1', '5', '1'}
#define MAGIC_LENGTH 7
/* HEADER = magic, crc, max_entries, qhead, qtail */
#define JOURNAL_HSIZE (MAGIC_LENGTH + sizeof(crc_t) + sizeof(uint16_t) * 3)
......@@ -150,45 +149,6 @@ int journal_map(journal_t *journal, uint64_t id, char **dst, size_t size, bool r
*/
int journal_unmap(journal_t *journal, uint64_t id, void *ptr, int finalize);
/*!
* \brief Begin transaction of multiple entries.
*
* \note Only one transaction at a time is supported.
*
* \param journal Associated journal.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_EBUSY if transaction is already pending.
*/
int journal_trans_begin(journal_t *journal);
/*!
* \brief Commit pending transaction.
*
* \note Only one transaction at a time is supported.
*
* \param journal Associated journal.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_ENOENT if no transaction is pending.
*/
int journal_trans_commit(journal_t *journal);
/*!
* \brief Rollback pending transaction.
*
* \note Only one transaction at a time is supported.
*
* \param journal Associated journal.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_ENOENT if no transaction is pending.
*/
int journal_trans_rollback(journal_t *journal);
/*!
* \brief Close journal file.
*
......@@ -216,6 +176,24 @@ bool journal_exists(const char *path);
int journal_load_changesets(const char *path, knot_changesets_t *dst,
uint32_t from, uint32_t to);
/*!
* \brief Store changesets in journal.
*
* Changesets will be stored to a permanent storage.
* Journal may be compacted, resulting in flattening changeset history.
*
* \param zone Zone associated with the changeset.
* \param src Changesets.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_EAGAIN if journal needs to be synced with zonefile first.
*
* \todo Expects the xfr structure to be initialized in some way.
* \todo Update documentation!!!
*/
int journal_store_changesets(knot_changesets_t *src, const char *path, size_t size_limit);
/*! \brief Function for unmarking dirty nodes. */
int journal_mark_synced(const char *path);
......
......@@ -572,56 +572,53 @@ static int xfr_async_finish(fdset_t *set, unsigned id)
return ret;
}
/*! \brief Switch zone contents with new. */
int knot_ns_switch_zone(knot_ns_xfr_t *xfr)
static int zones_save_zone(const knot_ns_xfr_t *xfr)
{
/* Zone is already referenced, no need for RCU locking. */
if (xfr == NULL || xfr->new_contents == NULL) {
return KNOT_EINVAL;
}
zone_contents_t *zone = (zone_contents_t *)xfr->new_contents;
dbg_xfr("xfr: %s Saving new zone file.\n", xfr->msg);
dbg_xfr("Replacing zone by new one: %p\n", zone);
if (zone == NULL) {
dbg_xfr("No new zone!\n");
return KNOT_ENOZONE;
}
rcu_read_lock();
/* Zone must not be looked-up from server, as it may be a different zone if
* a reload occurs when transfer is pending. */
zone_t *z = xfr->zone;
if (z == NULL) {
char *name = knot_dname_to_str(knot_node_owner(
zone_contents_apex(zone)));
dbg_xfr("Failed to replace zone %s, old zone "
"not found\n", name);
free(name);
zone_contents_t *new_zone = xfr->new_contents;
return KNOT_ENOZONE;
const char *zonefile = xfr->zone->conf->file;
/* Check if the new zone apex dname matches zone name. */
knot_dname_t *cur_name = knot_dname_from_str(xfr->zone->conf->name);
const knot_dname_t *new_name = NULL;
new_name = knot_node_owner(zone_contents_apex(new_zone));
int r = knot_dname_cmp(cur_name, new_name);
knot_dname_free(&cur_name);
if (r != 0) {
rcu_read_unlock();
return KNOT_EINVAL;
}
rcu_read_unlock();
int ret = xfrin_switch_zone(z, zone, xfr->type);
rcu_read_lock();
assert(zonefile != NULL);
/* dump the zone into text zone file */
int ret = zonefile_write(zonefile, new_zone, &xfr->addr);
rcu_read_unlock();
return ret;
}
/*! \brief Finalize XFR/IN transfer. */
static int xfr_task_finalize(knot_ns_xfr_t *rq)
{
int ret = KNOT_EINVAL;
rcu_read_lock();
if (rq->type == XFR_TYPE_AIN) {
ret = zones_save_zone(rq);
if (ret == KNOT_EOK) {
ret = knot_ns_switch_zone(rq);
if (ret != KNOT_EOK) {
log_zone_error("%s %s\n", rq->msg, knot_strerror(ret));
log_zone_error("%s Failed to switch in-memory "
"zone.\n", rq->msg);
}
zone_contents_t *old_contents = NULL;
old_contents = xfrin_switch_zone(rq->zone, rq->new_contents);
zone_contents_deep_free(&old_contents);
} else {
log_zone_error("%s %s\n",
rq->msg, knot_strerror(ret));
......@@ -630,10 +627,9 @@ static int xfr_task_finalize(knot_ns_xfr_t *rq)
}
} else if (rq->type == XFR_TYPE_IIN) {
knot_changesets_t *chs = (knot_changesets_t *)rq->data;
ret = zones_store_and_apply_chgsets(chs, rq->zone,
&rq->new_contents,
rq->msg,
XFR_TYPE_IIN);
ret = zone_change_apply_and_store(chs, rq->zone,
&rq->new_contents,
rq->msg);
rq->data = NULL; /* Freed or applied in prev function. */
}
......@@ -648,11 +644,103 @@ static int xfr_task_finalize(knot_ns_xfr_t *rq)
rq->new_contents = NULL; /* Do not free. */
}
rcu_read_unlock();
return ret;
}
static int xfr_task_resp_process(server_t *server,
int exp_msgid,
struct sockaddr_storage *from,
knot_pkt_t *packet)
{
if (server == NULL || from == NULL || packet == NULL) {
return KNOT_EINVAL;
}
/* Handle SOA query response, cancel EXPIRE timer
* and start AXFR transfer if needed.
* Reset REFRESH timer on finish.
*/
if (knot_pkt_qtype(packet) == KNOT_RRTYPE_SOA) {
if (knot_wire_get_rcode(packet->wire) != KNOT_RCODE_NOERROR) {
/*! \todo Handle error response. */
return KNOT_ERROR;
}
/* Find matching zone and ID. */
rcu_read_lock();
const knot_dname_t *zone_name = knot_pkt_qname(packet);
/*! \todo Change the access to the zone db. */
zone_t *zone = knot_zonedb_find(server->zone_db, zone_name);
/* Get zone contents. */
if (!zone || !zone->contents) {
rcu_read_unlock();
return KNOT_EINVAL;
}
/* Match ID against awaited. */
uint16_t pkt_id = knot_wire_get_id(packet->wire);
if ((int)pkt_id != exp_msgid) {
rcu_read_unlock();
return KNOT_ERROR;
}
/* Check SOA SERIAL. */
int ret = xfrin_transfer_needed(zone->contents, packet);
dbg_zones_verb("xfrin_transfer_needed() returned %s\n",
knot_strerror(ret));
if (ret < 0) {
/* RETRY/EXPIRE timers running, do not interfere. */
rcu_read_unlock();
return KNOT_ERROR;
}
/* No updates available. */
if (ret == 0) {
zones_schedule_refresh(zone, REFRESH_DEFAULT);
rcu_read_unlock();
return KNOT_EUPTODATE;
}
assert(ret > 0);
/* Check zone transfer state. */
pthread_mutex_lock(&zone->lock);
if (zone->xfr_in.state == XFR_PENDING) {
pthread_mutex_unlock(&zone->lock);
rcu_read_unlock();
return KNOT_EOK; /* Already pending. */
} else {
zone->xfr_in.state = XFR_PENDING;
}
/* Prepare XFR client transfer. */
int rqtype = zones_transfer_to_use(zone);
knot_ns_xfr_t *rq = xfr_task_create(zone, rqtype, XFR_FLAG_TCP);
if (!rq) {
pthread_mutex_unlock(&zone->lock);
rcu_read_unlock();
return KNOT_ENOMEM;
}
const conf_iface_t *master = zone_master(zone);
xfr_task_setaddr(rq, &master->addr, &master->via);
rq->tsig_key = master->key;
rcu_read_unlock();
#warning "XFR enqueue."
// ret = xfr_enqueue(server->xfr, rq);
// if (ret != KNOT_EOK) {
// xfr_task_free(rq);
// zone->xfr_in.state = XFR_SCHED; /* Revert state */
// }
pthread_mutex_unlock(&zone->lock);
}
return KNOT_EOK;
}
/*! \brief Query response event handler function. */
static int xfr_task_resp(xfrhandler_t *xfr, knot_ns_xfr_t *rq)
{
......@@ -702,8 +790,8 @@ static int xfr_task_resp(xfrhandler_t *xfr, knot_ns_xfr_t *rq)
/* Process response. */
switch(rt) {
case KNOT_RESPONSE_NORMAL:
ret = zones_process_response(xfr->server, rq->packet_nr, &rq->addr,
re);
ret = xfr_task_resp_process(xfr->server, rq->packet_nr, &rq->addr,
re);
break;
case KNOT_RESPONSE_NOTIFY:
ret = notify_process_response(re, rq->packet_nr);
......
This diff is collapsed.
......@@ -49,21 +49,6 @@
#define REFRESH_DEFAULT -1 /* Use time value from zone structure. */
#define REFRESH_NOW (knot_random_uint16_t() % 1000) /* Now, but with jitter. */
/*!
* \brief Processes normal response packet.
*
* \param server Name server structure to provide the needed data.
* \param packet Parsed response packet.
*
* \retval KNOT_EOK if a valid response was created.
* \retval KNOT_EINVAL on invalid parameters or packet.
* \retval KNOT_EMALF if an error occured and the response is not valid.
*/
int zones_process_response(server_t *server,
int exp_msgid,
struct sockaddr_storage *from,
knot_pkt_t *packet);
/*!
* \brief Decides what type of transfer should be used to update the given zone.
*.
......@@ -73,75 +58,6 @@ int zones_process_response(server_t *server,
*/
knot_ns_xfr_type_t zones_transfer_to_use(zone_t *zone);
int zones_save_zone(const knot_ns_xfr_t *xfr);
/*!
* \brief Store changesets in journal.
*
* Changesets will be stored to a permanent storage.
* Journal may be compacted, resulting in flattening changeset history.
*
* \param zone Zone associated with the changeset.
* \param src Changesets.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_EAGAIN if journal needs to be synced with zonefile first.
*
* \todo Expects the xfr structure to be initialized in some way.
* \todo Update documentation!!!
*/
int zones_store_changesets(knot_changesets_t *src, journal_t *j);
/*!
* \brief Begin changesets storing transaction.
*
* \retval pointer to journal if successful
* \retval NULL on failure.
*/
journal_t *zones_store_changesets_begin(zone_t *zone);
/*!
* \brief Commit stored changesets.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_ENOENT when no transaction is pending.
*/
int zones_store_changesets_commit(journal_t *j);
/*!
* \brief Rollback stored changesets.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid parameters.
* \retval KNOT_ENOENT when no transaction is pending.
*/
int zones_store_changesets_rollback(journal_t *j);
/*!
* \brief Creates changesets from zones difference.
*
* Also saves changesets to journal, which is taken from old zone.
*
* \param old_zone Old zone, previously served by server.
* \param new_zone New zone, to be served by server, after creating changesets.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EINVAL on invalid arguments.
* \retval KNOT_ERANGE when new serial is lower than the old one.
* \retval KNOT_ENODIFF when new zone's serial are equal.
* \retval KNOT_ERROR when there was error creating changesets.
*/
int zones_create_changeset(const zone_t *old_zone,
const zone_t *new_zone,
knot_changeset_t *changeset);
int zones_store_and_apply_chgsets(knot_changesets_t *chs,
zone_t *zone,
zone_contents_t **new_contents,
const char *msgpref, int type);
/*!
* \brief Update zone timers.
*
......@@ -184,59 +100,10 @@ int zones_cancel_dnssec(zone_t *zone);
*/
int zones_schedule_dnssec(zone_t *zone, time_t unixtime);
/*!
* \brief Verify TSIG in query.
*
* \param query Query packet.
* \param key TSIG key used for this query.
* \param rcode Dst for resulting RCODE.
* \param tsig_rcode Dst for resulting TSIG RCODE.
* \param tsig_prev_time_signed Dst for previout time signed.
*
* \return KNOT_EOK if verified or error if not.
*/
int zones_verify_tsig_query(const knot_pkt_t *query,
const knot_tsig_key_t *key,
knot_rcode_t *rcode, uint16_t *tsig_rcode,
uint64_t *tsig_prev_time_signed);
/*!
* \brief Creates diff and DNSSEC changesets and stores them to journal.
*
* \param z Zone configuration.
* \param zone Zone to sign.
* \param old_zone Previous zone.
* \param zone_changed Set to true if the zone was loaded or modified.
*
* \return Error code, KNOT_OK if successful.
*/
int zones_do_diff_and_sign(zone_t *zone, zone_t *old_zone, bool zone_changed);
/*! \brief Just sign current zone. */
int zones_dnssec_sign(zone_t *zone, bool force, uint32_t *expires_at);
/*
* Event callbacks.
*/
int zones_expire_ev(event_t *event);
int zones_refresh_ev(event_t *event);
int zones_dnssec_ev(event_t *event);
/*! \note Exported API for UPDATE processing, but this should really be done
* in a better way as it's very similar code to ixfr-from-diff signing code. */
bool zones_dnskey_changed(const zone_contents_t *old_contents,
const zone_contents_t *new_contents);
bool zones_nsec3param_changed(const zone_contents_t *old_contents,
const zone_contents_t *new_contents);
int zones_merge_and_store_changesets(zone_t *zone,
knot_changesets_t *diff_chs,
knot_changesets_t *sec_chs,
journal_t **transaction);
void zones_free_merged_changesets(knot_changesets_t *diff_chs,
knot_changesets_t *sec_chs);
uint32_t zones_next_serial(zone_t *zone);
#endif // _KNOTD_ZONES_H_