Commit 380672f3 authored by Jan Kadlec's avatar Jan Kadlec

zone-events: Initial IXFR-in implementation.

parent 8d008539
This diff is collapsed.
......@@ -28,9 +28,30 @@
#define _KNOT_IXFR_H_
#include "libknot/packet/pkt.h"
#include "knot/updates/changesets.h"
#include "knot/zone/zone.h"
struct query_data;
struct answer_data;
struct xfr_proc;
/*! \brief IXFR-in processing states. */
enum ixfrin_states {
IXFR_START = 0,
IXFR_SOA_FROM = 1,
IXFR_SOA_TO = 2,
IXFR_DEL = 3,
IXFR_ADD = 4,
IXFR_DONE = 5
};
/*! \brief Extended structure for IXFR-in processing. */
struct ixfrin_proc {
int state;
knot_changesets_t *changesets;
zone_t *zone;
mm_ctx_t *mm;
};
/*!
* \brief IXFR query processing module.
......@@ -39,7 +60,7 @@ struct answer_data;
* \retval FAIL if it encountered an error.
* \retval DONE if finished.
*/
int ixfr_answer(knot_pkt_t *pkt, struct query_data *qdata);
int ixfr_query(knot_pkt_t *pkt, struct query_data *qdata);
/*!
* \brief Process an IXFR query response.
......@@ -64,7 +85,7 @@ int ixfr_answer(knot_pkt_t *pkt, struct query_data *qdata);
* \retval Other If any other error occured. The connection should be closed.
*
*/
int ixfr_process_answer(knot_pkt_t *pkt, struct answer_data *data);
int ixfrin_process_answer(knot_pkt_t *pkt, struct answer_data *adata);
#endif /* _KNOT_IXFR_H_ */
......
......@@ -125,7 +125,7 @@ int process_answer(knot_pkt_t *pkt, knot_process_t *ctx)
next_state = axfr_process_answer(pkt, data);
break;
case KNOT_RESPONSE_IXFR:
next_state = ixfr_process_answer(pkt, data);
next_state = ixfrin_process_answer(pkt, data);
break;
case KNOT_RESPONSE_NOTIFY:
next_state = notify_process_answer(pkt, data);
......@@ -139,4 +139,4 @@ int process_answer(knot_pkt_t *pkt, knot_process_t *ctx)
return next_state;
}
#undef ANSWER_REQUIRES
\ No newline at end of file
#undef ANSWER_REQUIRES
......@@ -372,7 +372,7 @@ static int query_internet(knot_pkt_t *pkt, knot_process_t *ctx)
next_state = axfr_query(pkt, data);
break;
case KNOT_QUERY_IXFR:
next_state = ixfr_answer(pkt, data);
next_state = ixfr_query(pkt, data);
break;
case KNOT_QUERY_UPDATE:
next_state = update_answer(pkt, data);
......
......@@ -162,7 +162,7 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
&refresh_at);
}
if (ret != KNOT_EOK) {
knot_changesets_free(&sec_chs);
knot_changesets_free(&sec_chs, NULL);
return ret;
}
......@@ -170,14 +170,14 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
zone_contents_set_gen_old(new_contents);
ret = xfrin_apply_changesets_directly(new_contents, sec_chs);
if (ret != KNOT_EOK) {
knot_changesets_free(&sec_chs);
knot_changesets_free(&sec_chs, NULL);
return ret;
}
// Merge changesets
ret = knot_changeset_merge(ddns_ch, sec_ch);
if (ret != KNOT_EOK) {
knot_changesets_free(&sec_chs);
knot_changesets_free(&sec_chs, NULL);
return ret;
}
......@@ -211,7 +211,7 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
knot_changeset_t *ddns_ch = knot_changesets_get_last(ddns_chs);
ret = ddns_process_update(zone, query, ddns_ch, rcode);
if (ret != KNOT_EOK) {
knot_changesets_free(&ddns_chs);
knot_changesets_free(&ddns_chs, NULL);
return ret;
}
......@@ -225,11 +225,11 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
} else {
*rcode = KNOT_RCODE_SERVFAIL;
}
knot_changesets_free(&ddns_chs);
knot_changesets_free(&ddns_chs, NULL);
return ret;
}
} else {
knot_changesets_free(&ddns_chs);
knot_changesets_free(&ddns_chs, NULL);
*rcode = KNOT_RCODE_NOERROR;
return KNOT_EOK;
}
......@@ -239,7 +239,7 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
ret = sign_update(zone, zone->contents, new_contents, ddns_ch);
if (ret != KNOT_EOK) {
xfrin_rollback_update(ddns_chs, &new_contents);
knot_changesets_free(&ddns_chs);
knot_changesets_free(&ddns_chs, NULL);
*rcode = KNOT_RCODE_SERVFAIL;
return ret;
}
......@@ -249,7 +249,7 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
ret = zone_change_store(zone, ddns_chs);
if (ret != KNOT_EOK) {
xfrin_rollback_update(ddns_chs, &new_contents);
knot_changesets_free(&ddns_chs);
knot_changesets_free(&ddns_chs, NULL);
*rcode = KNOT_RCODE_SERVFAIL;
return ret;
}
......@@ -261,7 +261,7 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
xfrin_zone_contents_free(&old_contents);
xfrin_cleanup_successful_update(ddns_chs);
knot_changesets_free(&ddns_chs);
knot_changesets_free(&ddns_chs, NULL);
/* Trim extra heap. */
mem_trim();
......
......@@ -862,7 +862,7 @@ static int xfr_task_xfer(xfrhandler_t *xfr, knot_ns_xfr_t *rq, knot_pkt_t *pkt)
ret = axfr_process_answer(pkt, rq);
break;
case XFR_TYPE_IIN:
ret = ixfr_process_answer(pkt, rq);
ret = ixfrin_process_answer(pkt, rq);
break;
default:
ret = KNOT_EINVAL;
......
......@@ -65,7 +65,7 @@ knot_changesets_t *knot_changesets_create(unsigned count)
for (unsigned i = 0; i < count; ++i) {
knot_changeset_t *change = knot_changesets_create_changeset(ch);
if (change == NULL) {
knot_changesets_free(&ch);
knot_changesets_free(&ch, NULL);
return NULL;
}
}
......@@ -260,7 +260,7 @@ static void knot_free_changeset(knot_changeset_t *changeset)
free(changeset->data);
}
static void knot_changesets_deinit(knot_changesets_t *changesets)
static void knot_changesets_deinit(knot_changesets_t *changesets, mm_ctx_t *rr_mm)
{
if (!EMPTY_LIST(changesets->sets)) {
knot_changeset_t *chg = NULL;
......@@ -274,28 +274,28 @@ static void knot_changesets_deinit(knot_changesets_t *changesets)
// Free pool with RRs in sets / changes
mp_delete(changesets->mmc_rr.ctx);
knot_rrset_free(&changesets->first_soa, NULL);
knot_rrset_free(&changesets->first_soa, rr_mm);
}
void knot_changesets_free(knot_changesets_t **changesets)
void knot_changesets_free(knot_changesets_t **changesets, mm_ctx_t *rr_mm)
{
if (changesets == NULL || *changesets == NULL) {
return;
}
knot_changesets_deinit(*changesets);
knot_changesets_deinit(*changesets, rr_mm);
free(*changesets);
*changesets = NULL;
}
int knot_changesets_clear(knot_changesets_t *changesets)
int knot_changesets_clear(knot_changesets_t *changesets, mm_ctx_t *rr_mm)
{
if (changesets == NULL) {
return KNOT_EINVAL;
}
knot_changesets_deinit(changesets);
knot_changesets_deinit(changesets, rr_mm);
return knot_changesets_init(changesets);
}
......@@ -101,15 +101,8 @@ typedef enum {
*/
knot_changesets_t *knot_changesets_create(unsigned count);
/*!
* \brief Frees the 'changesets' structure, including all its internal data.
*
* \param changesets Double pointer to changesets structure to be freed.
*/
void knot_changesets_free(knot_changesets_t **changesets);
/*! \brief Reinitialize changesets structure. */
int knot_changesets_clear(knot_changesets_t *changesets);
int knot_changesets_clear(knot_changesets_t *changesets, mm_ctx_t *rr_mm);
/*!
* \brief Creates new changeset structure and returns it to caller.
......@@ -204,9 +197,10 @@ int knot_changeset_apply(knot_changeset_t *changeset,
/*!
* \brief Frees the 'changesets' structure, including all its internal data.
*
* \param changesets Double pointer to changesets structure to be freed.
* \param changesets Double pointer to changesets structure to be freed.
* \param mm Memory context used to allocate RRSets.
*/
void knot_changesets_free(knot_changesets_t **changesets);
void knot_changesets_free(knot_changesets_t **changesets, mm_ctx_t *rr_mm);
/*!
* \brief Merges two changesets together, second changeset's lists are kept.
......
This diff is collapsed.
......@@ -37,6 +37,7 @@
#include "knot/updates/changesets.h"
struct xfr_proc;
struct ixfrin_proc;
/*----------------------------------------------------------------------------*/
......@@ -100,7 +101,7 @@ void xfrin_free_changesets(knot_changesets_t **changesets);
* \retval KNOT_EMALF
* \retval KNOT_ENOMEM
*/
int xfrin_process_ixfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr);
int xfrin_process_ixfr_packet(knot_pkt_t *pkt, struct ixfrin_proc *proc);
/*!
* \brief Applies changesets *with* zone shallow copy.
......
......@@ -441,8 +441,7 @@ static int event_dnssec(zone_t *zone)
}
if (!knot_changesets_empty(chs)) {
zone_contents_t *new_c = NULL;
ret = zone_change_apply_and_store(chs, zone, &new_c, "DNSSEC");
ret = zone_change_apply_and_store(chs, zone, "DNSSEC", NULL);
chs = NULL; // freed by zone_change_apply_and_store()
if (ret != KNOT_EOK) {
log_zone_error("%s Could not sign zone (%s).\n",
......@@ -461,7 +460,7 @@ static int event_dnssec(zone_t *zone)
}
done:
knot_changesets_free(&chs);
knot_changesets_free(&chs, NULL);
free(msgpref);
return ret;
}
......
......@@ -99,7 +99,7 @@ int zone_load_journal(zone_contents_t *contents, conf_zone_t *conf)
/*! \todo Check what should be the upper bound. */
int ret = journal_load_changesets(conf->ixfr_db, chsets, serial, serial - 1);
if ((ret != KNOT_EOK && ret != KNOT_ERANGE) || EMPTY_LIST(chsets->sets)) {
knot_changesets_free(&chsets);
knot_changesets_free(&chsets, NULL);
/* Absence of records is not an error. */
if (ret == KNOT_ENOENT) {
return KNOT_EOK;
......@@ -115,7 +115,7 @@ int zone_load_journal(zone_contents_t *contents, conf_zone_t *conf)
serial, zone_contents_serial(contents),
knot_strerror(ret));
knot_changesets_free(&chsets);
knot_changesets_free(&chsets, NULL);
return ret;
}
......@@ -137,7 +137,7 @@ int zone_load_post(zone_contents_t *new_contents, zone_t *zone)
if (conf->dnssec_enable) {
change = zone_change_prepare(chset);
if (change == NULL) {
knot_changesets_free(&chset);
knot_changesets_free(&chset, NULL);
return KNOT_ENOMEM;
}
......@@ -153,13 +153,13 @@ int zone_load_post(zone_contents_t *new_contents, zone_t *zone)
/* Commit existing zone change and prepare new. */
int ret = zone_change_commit(new_contents, chset);
if (ret != KNOT_EOK) {
knot_changesets_free(&chset);
knot_changesets_free(&chset, NULL);
return ret;
} else {
knot_changesets_clear(chset);
knot_changesets_clear(chset, NULL);
change = zone_change_prepare(chset);
if (change == NULL) {
knot_changesets_free(&chset);
knot_changesets_free(&chset, NULL);
return KNOT_ENOMEM;
}
}
......@@ -182,7 +182,7 @@ int zone_load_post(zone_contents_t *new_contents, zone_t *zone)
if (ret == KNOT_EOK) {
ret = zone_change_commit(new_contents, chset);
if (ret != KNOT_EOK) {
knot_changesets_free(&chset);
knot_changesets_free(&chset, NULL);
return ret;
}
......@@ -191,7 +191,7 @@ int zone_load_post(zone_contents_t *new_contents, zone_t *zone)
}
/* Free changesets and return. */
knot_changesets_free(&chset);
knot_changesets_free(&chset, NULL);
return ret;
}
......
......@@ -188,17 +188,18 @@ int zone_change_store(zone_t *zone, knot_changesets_t *chset)
/*! \note @mvavrusa Moved from zones.c, this needs a common API. */
int zone_change_apply_and_store(knot_changesets_t *chs,
zone_t *zone,
zone_contents_t **new_contents,
const char *msgpref)
const char *msgpref,
mm_ctx_t *rr_mm)
{
int ret = KNOT_EOK;
/* Now, try to apply the changesets to the zone. */
ret = xfrin_apply_changesets(zone, chs, new_contents);
zone_contents_t *new_contents;
ret = xfrin_apply_changesets(zone, chs, &new_contents);
if (ret != KNOT_EOK) {
log_zone_error("%s Failed to apply changesets.\n", msgpref);
/* Free changesets, but not the data. */
knot_changesets_free(&chs);
knot_changesets_free(&chs, rr_mm);
return ret; // propagate the error above
}
......@@ -206,19 +207,19 @@ int zone_change_apply_and_store(knot_changesets_t *chs,
ret = zone_change_store(zone, chs);
if (ret != KNOT_EOK) {
log_zone_error("%s Failed to store changesets.\n", msgpref);
xfrin_rollback_update(chs, new_contents);
xfrin_rollback_update(chs, &new_contents);
/* Free changesets, but not the data. */
knot_changesets_free(&chs);
knot_changesets_free(&chs, rr_mm);
return ret; // propagate the error above
}
/* Switch zone contents. */
zone_contents_t *old_contents = xfrin_switch_zone(zone, *new_contents);
zone_contents_t *old_contents = xfrin_switch_zone(zone, new_contents);
xfrin_zone_contents_free(&old_contents);
/* Free changesets, but not the data. */
xfrin_cleanup_successful_update(chs);
knot_changesets_free(&chs);
knot_changesets_free(&chs, rr_mm);
assert(ret == KNOT_EOK);
return KNOT_EOK;
}
......
......@@ -118,8 +118,8 @@ int zone_change_store(zone_t *zone, knot_changesets_t *chset);
/*! \note @mvavrusa Moved from zones.c, this needs a common API. */
int zone_change_apply_and_store(knot_changesets_t *chs,
zone_t *zone,
zone_contents_t **new_contents,
const char *msgpref);
const char *msgpref,
mm_ctx_t *rr_mm);
/*!
* \brief Atomically switch the content of the zone.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment