Commit b0792d6a authored by Daniel Salzman's avatar Daniel Salzman

nameserver: move zone QPLAN_BEGIN an QPLAN_END processing into process_query_out

parent fc71c1f0
......@@ -621,13 +621,6 @@ static int answer_query(knot_pkt_t *pkt, struct query_data *qdata)
struct query_plan *global_plan = conf()->query_plan;
struct query_step *step = NULL;
/* Before query processing code. */
if (plan != NULL) {
WALK_LIST(step, plan->stage[QPLAN_BEGIN]) {
SOLVE_STEP(step->process, state, step->ctx);
}
}
/* Resolve ANSWER. */
knot_pkt_begin(pkt, KNOT_ANSWER);
if (global_plan != NULL) {
......@@ -673,13 +666,6 @@ static int answer_query(knot_pkt_t *pkt, struct query_data *qdata)
}
}
/* After query processing code. */
if (plan != NULL) {
WALK_LIST(step, plan->stage[QPLAN_END]) {
SOLVE_STEP(step->process, state, step->ctx);
}
}
/* Write resulting RCODE. */
knot_wire_set_rcode(pkt->wire, qdata->rcode);
......
......@@ -308,7 +308,7 @@ static int prepare_answer(const knot_pkt_t *query, knot_pkt_t *resp, knot_layer_
if (ret != KNOT_EOK) {
return ret;
}
knot_wire_clear_cd(resp->wire); // TODO: should be inside knot_pkt_init_response.
knot_wire_clear_cd(resp->wire);
/* Query MUST carry a question. */
const knot_dname_t *qname = knot_pkt_qname(query);
......@@ -361,24 +361,21 @@ static int prepare_answer(const knot_pkt_t *query, knot_pkt_t *resp, knot_layer_
return ret;
}
static int set_rcode_to_packet(knot_pkt_t *pkt, struct query_data *qdata)
static void set_rcode_to_packet(knot_pkt_t *pkt, struct query_data *qdata)
{
int ret = KNOT_EOK;
uint8_t ext_rcode = KNOT_EDNS_RCODE_HI(qdata->rcode);
if (ext_rcode != 0) {
/* No OPT RR and Ext RCODE results in SERVFAIL. */
if (qdata->opt_rr_pos == NULL) {
qdata->rcode = KNOT_RCODE_SERVFAIL;
ret = KNOT_ERROR;
} else {
knot_edns_set_ext_rcode_wire(qdata->opt_rr_pos, ext_rcode);
knot_wire_set_rcode(pkt->wire, KNOT_RCODE_SERVFAIL);
return;
}
knot_edns_set_ext_rcode_wire(qdata->opt_rr_pos, ext_rcode);
}
knot_wire_set_rcode(pkt->wire, KNOT_EDNS_RCODE_LO(qdata->rcode));
return ret;
}
static int process_query_err(knot_layer_t *ctx, knot_pkt_t *pkt)
......@@ -389,7 +386,12 @@ static int process_query_err(knot_layer_t *ctx, knot_pkt_t *pkt)
/* Initialize response from query packet. */
knot_pkt_t *query = qdata->query;
knot_pkt_init_response(pkt, query);
knot_wire_clear_cd(pkt->wire); // TODO: should be inside knot_pkt_init_response.
knot_wire_clear_cd(pkt->wire);
/* Set TC bit if required. */
if (qdata->err_truncated) {
knot_wire_set_tc(pkt->wire);
}
/* Restore original QNAME. */
process_query_qname_case_restore(pkt, qdata);
......@@ -401,18 +403,31 @@ static int process_query_err(knot_layer_t *ctx, knot_pkt_t *pkt)
/* Put OPT RR to the additional section. */
if (answer_edns_reserve(pkt, qdata) == KNOT_EOK) {
(void) answer_edns_put(pkt, qdata);
(void)answer_edns_put(pkt, qdata);
} else {
qdata->rcode = KNOT_RCODE_SERVFAIL;
}
/* Set final RCODE to packet. */
(void) set_rcode_to_packet(pkt, qdata);
set_rcode_to_packet(pkt, qdata);
/* Transaction security (if applicable). */
(void) process_query_sign_response(pkt, qdata);
(void)process_query_sign_response(pkt, qdata);
return KNOT_STATE_DONE;
}
/*! \brief Helper for repetitive code. */
#define PROCESS_STAGE(plan, query_stage, step, next_state, qdata) \
if (plan != NULL) { \
WALK_LIST(step, plan->stage[query_stage]) { \
next_state = step->process(next_state, pkt, qdata, step->ctx); \
if (next_state == KNOT_STATE_FAIL) { \
next_state = process_query_err(ctx, pkt); \
} \
} \
}
static int process_query_out(knot_layer_t *ctx, knot_pkt_t *pkt)
{
assert(pkt && ctx);
......@@ -421,34 +436,33 @@ static int process_query_out(knot_layer_t *ctx, knot_pkt_t *pkt)
struct query_data *qdata = QUERY_DATA(ctx);
struct query_plan *plan = conf()->query_plan;
struct query_plan *zone_plan = NULL;
struct query_step *step = NULL;
int next_state = KNOT_STATE_PRODUCE;
/* Check parse state. */
knot_pkt_t *query = qdata->query;
int next_state = KNOT_STATE_PRODUCE;
if (query->parsed < query->size) {
knot_pkt_clear(pkt);
qdata->rcode = KNOT_RCODE_FORMERR;
next_state = KNOT_STATE_FAIL;
goto finish;
}
/*
* Preprocessing.
*/
/* Preprocessing. */
if (prepare_answer(query, pkt, ctx) != KNOT_EOK) {
next_state = KNOT_STATE_FAIL;
goto finish;
}
/* Before query processing code. */
if (plan) {
WALK_LIST(step, plan->stage[QPLAN_BEGIN]) {
next_state = step->process(next_state, pkt, qdata, step->ctx);
}
if (qdata->zone != NULL && qdata->zone->query_plan != NULL) {
zone_plan = qdata->zone->query_plan;
}
/* Before query processing code. */
PROCESS_STAGE(plan, QPLAN_BEGIN, step, next_state, qdata);
PROCESS_STAGE(zone_plan, QPLAN_BEGIN, step, next_state, qdata);
/* Answer based on qclass. */
if (next_state != KNOT_STATE_DONE) {
switch (knot_pkt_qclass(pkt)) {
......@@ -466,10 +480,7 @@ static int process_query_out(knot_layer_t *ctx, knot_pkt_t *pkt)
}
}
/*
* Postprocessing.
*/
/* Postprocessing. */
if (next_state == KNOT_STATE_DONE || next_state == KNOT_STATE_PRODUCE) {
/* Restore original QNAME. */
......@@ -488,29 +499,28 @@ static int process_query_out(knot_layer_t *ctx, knot_pkt_t *pkt)
/* Transaction security (if applicable). */
if (process_query_sign_response(pkt, qdata) != KNOT_EOK) {
next_state = KNOT_STATE_FAIL;
goto finish;
}
}
finish:
/* Default RCODE is SERVFAIL if not specified otherwise. */
if (next_state == KNOT_STATE_FAIL && qdata->rcode == KNOT_RCODE_NOERROR) {
qdata->rcode = KNOT_RCODE_SERVFAIL;
}
/* Store Extended RCODE - divide between header and OPT if possible. */
if (next_state != KNOT_STATE_FAIL) {
if (set_rcode_to_packet(pkt, qdata) != KNOT_EOK) {
next_state = KNOT_STATE_FAIL;
/* Error processing. */
switch (next_state) {
case KNOT_STATE_FAIL:
/* Default RCODE is SERVFAIL if not otherwise specified. */
if (qdata->rcode == KNOT_RCODE_NOERROR) {
qdata->rcode = KNOT_RCODE_SERVFAIL;
}
process_query_err(ctx, pkt);
break;
default:
/* Store Extended RCODE - divide between header and OPT. */
set_rcode_to_packet(pkt, qdata);
}
/* In case of NS_PROC_FAIL, RCODE is set in the error-processing function. */
/* After query processing code. */
if (plan) {
WALK_LIST(step, plan->stage[QPLAN_END]) {
next_state = step->process(next_state, pkt, qdata, step->ctx);
}
}
PROCESS_STAGE(zone_plan, QPLAN_END, step, next_state, qdata);
PROCESS_STAGE(plan, QPLAN_END, step, next_state, qdata);
rcu_read_unlock();
......
......@@ -50,6 +50,7 @@ struct query_data {
const zone_t *zone; /*!< Zone from which is answered. */
list_t wildcards; /*!< Visited wildcards. */
list_t rrsigs; /*!< Section RRSIGs. */
bool err_truncated; /*!< Set TC bit if error reply. */
/* Current processed name and nodes. */
const zone_node_t *node, *encloser, *previous;
......
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