Commit ddcda4a3 authored by Marek Vavrusa's avatar Marek Vavrusa

Transfer cleanup callbacks in case of interrupted processing.

Since transfers use the query_data 'ext' pointer for storing things
like current RRSet or list of things to process, it needs to be cleared
after transfer end or failure. But one may also close processing context
abruptly. For this reason a callback is added for 'ext' cleanup.
parent 017e6639
......@@ -83,11 +83,20 @@ static int axfr_process_item(knot_pkt_t *pkt, const void *item, struct xfr_proc
return ret;
}
static void axfr_answer_cleanup(struct query_data *qdata)
{
struct xfr_proc *axfr = (struct xfr_proc *)qdata->ext;
mm_ctx_t *mm = qdata->mm;
ptrlist_free(&axfr->nodes, mm);
mm->free(axfr);
}
static int axfr_answer_init(struct query_data *qdata)
{
assert(qdata);
/* Begin zone iterator. */
/* Create transfer processing context. */
mm_ctx_t *mm = qdata->mm;
knot_zone_contents_t *zone = qdata->zone->contents;
struct xfr_proc *xfer = mm->alloc(mm->ctx, sizeof(struct axfr_proc));
......@@ -96,12 +105,15 @@ static int axfr_answer_init(struct query_data *qdata)
}
memset(xfer, 0, sizeof(struct axfr_proc));
init_list(&xfer->nodes);
gettimeofday(&xfer->tstamp, NULL);
qdata->ext = xfer;
/* Put data to process. */
gettimeofday(&xfer->tstamp, NULL);
ptrlist_add(&xfer->nodes, zone->nodes, mm);
ptrlist_add(&xfer->nodes, zone->nsec3_nodes, mm);
/* Set up cleanup callback. */
qdata->ext = xfer;
qdata->ext_cleanup = &axfr_answer_cleanup;
return KNOT_EOK;
}
......@@ -158,7 +170,6 @@ int axfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata
assert(qdata);
int ret = KNOT_EOK;
mm_ctx_t *mm = qdata->mm;
struct timeval now = {0};
......@@ -195,20 +206,12 @@ int axfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata
AXFR_LOG(LOG_INFO, "Finished in %.02fs (%u messages, ~%.01fkB).",
time_diff(&xfer->tstamp, &now) / 1000.0,
xfer->npkts, xfer->nbytes / 1024.0);
ret = NS_PROC_DONE;
return NS_PROC_DONE;
break;
default: /* Generic error. */
AXFR_LOG(LOG_ERR, "%s", knot_strerror(ret));
ret = NS_PROC_FAIL;
break;
return NS_PROC_FAIL;
}
/* Finished successfuly or fatal error. */
ptrlist_free(&xfer->nodes, mm);
mm->free(xfer);
qdata->ext = NULL;
return ret;
}
#undef AXFR_LOG
......@@ -177,6 +177,16 @@ static int ixfr_query_check(struct query_data *qdata)
return NS_PROC_DONE;
}
static void ixfr_answer_cleanup(struct query_data *qdata)
{
struct ixfr_proc *ixfr = (struct ixfr_proc *)qdata->ext;
mm_ctx_t *mm = qdata->mm;
ptrlist_free(&ixfr->proc.nodes, mm);
knot_changesets_free(&ixfr->changesets);
mm->free(qdata->ext);
}
static int ixfr_answer_init(struct query_data *qdata)
{
/* Check query. */
......@@ -203,10 +213,9 @@ static int ixfr_answer_init(struct query_data *qdata)
memset(xfer, 0, sizeof(struct ixfr_proc));
gettimeofday(&xfer->proc.tstamp, NULL);
init_list(&xfer->proc.nodes);
qdata->ext = xfer;
xfer->qdata = qdata;
/* Put all changesets to process. */
/* Put all changesets to processing queue. */
xfer->changesets = chgsets;
knot_changeset_t *chs = NULL;
WALK_LIST(chs, chgsets->sets) {
......@@ -220,6 +229,10 @@ static int ixfr_answer_init(struct query_data *qdata)
chs = TAIL(chgsets->sets);
xfer->soa_to = chs->soa_to;
/* Set up cleanup callback. */
qdata->ext = xfer;
qdata->ext_cleanup = &ixfr_answer_cleanup;
return KNOT_EOK;
}
......@@ -258,7 +271,6 @@ int ixfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata
}
int ret = KNOT_EOK;
mm_ctx_t *mm = qdata->mm;
struct timeval now = {0};
struct ixfr_proc *ixfr = (struct ixfr_proc*)qdata->ext;
......@@ -307,12 +319,6 @@ int ixfr_answer(knot_pkt_t *pkt, knot_nameserver_t *ns, struct query_data *qdata
break;
}
/* Finished successfuly or fatal error. */
ptrlist_free(&ixfr->proc.nodes, mm);
knot_changesets_free(&ixfr->changesets);
mm->free(qdata->ext);
qdata->ext = NULL;
return ret;
}
......
......@@ -75,6 +75,12 @@ int ns_proc_query_reset(ns_proc_context_t *ctx)
/* Free wildcard list. */
ptrlist_free(&qdata->wildcards, qdata->mm);
/* Clear extensions. */
if (qdata->ext_cleanup != NULL) {
qdata->ext_cleanup(qdata);
}
qdata->ext = qdata->ext_cleanup = NULL;
/* Await packet. */
return NS_PROC_MORE;
}
......
......@@ -87,6 +87,7 @@ struct query_data {
struct ns_proc_query_param *param; /*!< Module parameters. */
mm_ctx_t *mm; /*!< Memory context. */
void *ext; /*!< Extensions. */
void (*ext_cleanup)(struct query_data*); /*!< Extensions cleanup callback. */
};
/*! \brief Visited wildcard node list. */
......
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