Commit c83f14ba authored by Marek Vavruša's avatar Marek Vavruša

processing: replaced remaining process usage with layers

This is because layers allow packet reuse. Because of this,
query ownership can't be assumed by the layer, while it is
mandated by process.
parent 83593ae0
......@@ -140,6 +140,8 @@ src/knot/nameserver/query_module.h
src/knot/nameserver/tsig_ctx.c
src/knot/nameserver/tsig_ctx.h
src/knot/nameserver/update.c
src/knot/nameserver/update.c
src/knot/nameserver/update.c
src/knot/nameserver/update.h
src/knot/other/debug.h
src/knot/server/dthreads.c
......@@ -234,10 +236,10 @@ src/libknot/processing/layer.c
src/libknot/processing/layer.h
src/libknot/processing/overlay.c
src/libknot/processing/overlay.h
src/libknot/processing/process.c
src/libknot/processing/process.h
src/libknot/processing/requestor.c
src/libknot/processing/requestor.h
src/libknot/processing/requestor.h
src/libknot/processing/requestor.h
src/libknot/rdata.c
src/libknot/rdata.h
src/libknot/rdataset.c
......
......@@ -174,8 +174,6 @@ libknot_la_SOURCES = \
libknot/packet/net.c \
libknot/packet/net.h \
libknot/packet/wire.h \
libknot/processing/process.c \
libknot/processing/process.h \
libknot/processing/layer.c \
libknot/processing/layer.h \
libknot/processing/overlay.c \
......
......@@ -43,7 +43,6 @@ static int capture(knot_layer_t *ctx, knot_pkt_t *pkt)
/* Copy packet contents and free. */
knot_pkt_copy(param->sink, pkt);
knot_pkt_free(&pkt);
return NS_PROC_DONE;
}
......
......@@ -26,7 +26,7 @@
#pragma once
#include "libknot/processing/process.h"
#include "libknot/processing/layer.h"
#include "libknot/packet/pkt.h"
/* Processing module implementation. */
......
......@@ -139,7 +139,6 @@ static int process_answer(knot_layer_t *ctx, knot_pkt_t *pkt)
break;
}
knot_pkt_free(&pkt);
return next_state;
}
......
......@@ -34,7 +34,7 @@ const knot_layer_api_t *process_answer_get_module(void);
#define NS_PROC_ANSWER process_answer_get_module()
#define NS_PROC_ANSWER_ID 2
/*! \brief Answer processsing logging base. */
/*! \brief Answer processing logging base. */
#define ANSWER_LOG(severity, data, operation, msg...) \
NS_PROC_LOG(severity, (data)->param->remote, (data)->param->zone->name, \
operation, msg);
......
......@@ -57,7 +57,6 @@ static int process_query_reset(knot_layer_t *ctx)
struct process_query_param *module_param = qdata->param;
/* Free allocated data. */
knot_pkt_free(&qdata->query);
ptrlist_free(&qdata->wildcards, qdata->mm);
nsec_clear_rrsigs(qdata);
knot_rrset_clear(&qdata->opt_rr, qdata->mm);
......@@ -88,13 +87,11 @@ static int process_query_in(knot_layer_t *ctx, knot_pkt_t *pkt)
/* Check if at least header is parsed. */
if (pkt->parsed < KNOT_WIRE_HEADER_SIZE) {
knot_pkt_free(&pkt);
return NS_PROC_NOOP; /* Ignore. */
}
/* Accept only queries. */
if (knot_wire_get_qr(pkt->wire)) {
knot_pkt_free(&pkt);
return NS_PROC_NOOP; /* Ignore. */
}
......
......@@ -26,7 +26,7 @@
#pragma once
#include "libknot/processing/process.h"
#include "libknot/processing/layer.h"
#include "knot/server/server.h"
#include "knot/updates/acl.h"
......
......@@ -133,21 +133,25 @@ static int tcp_handle(tcp_context_t *tcp, int fd,
rx->iov_len = ret;
}
/* Create packets. */
mm_ctx_t *mm = tcp->query_ctx.mm;
knot_pkt_t *query = knot_pkt_new(rx->iov_base, rx->iov_len, mm);
knot_pkt_t *ans = knot_pkt_new(tx->iov_base, tx->iov_len, mm);
/* Create query processing context. */
knot_process_begin(&tcp->query_ctx, NS_PROC_QUERY, &param);
knot_layer_begin(&tcp->query_ctx, NS_PROC_QUERY, &param);
/* Input packet. */
int state = knot_process_in(&tcp->query_ctx, rx->iov_base, rx->iov_len);
int state = knot_layer_in(&tcp->query_ctx, query);
/* Resolve until NOOP or finished. */
ret = KNOT_EOK;
while (state & (NS_PROC_FULL|NS_PROC_FAIL)) {
uint16_t tx_len = tx->iov_len;
state = knot_process_out(&tcp->query_ctx, tx->iov_base, &tx_len);
state = knot_layer_out(&tcp->query_ctx, ans);
/* If it has response, send it. */
if (tx_len > 0) {
if (tcp_send_msg(fd, tx->iov_base, tx_len) != tx_len) {
if (ans->size > 0) {
if (tcp_send_msg(fd, ans->wire, ans->size) != ans->size) {
ret = KNOT_ECONNREFUSED;
break;
}
......@@ -155,7 +159,11 @@ static int tcp_handle(tcp_context_t *tcp, int fd,
}
/* Reset after processing. */
knot_process_finish(&tcp->query_ctx);
knot_layer_finish(&tcp->query_ctx);
/* Cleanup. */
knot_pkt_free(&query);
knot_pkt_free(&ans);
return ret;
}
......
......@@ -46,7 +46,7 @@
#include "libknot/consts.h"
#include "libknot/packet/pkt.h"
#include "libknot/dnssec/crypto.h"
#include "libknot/processing/process.h"
#include "libknot/processing/layer.h"
/* Buffer identifiers. */
enum {
......@@ -57,9 +57,9 @@ enum {
/*! \brief UDP context data. */
typedef struct udp_context {
knot_layer_t query_ctx; /*!< Query processing context. */
server_t *server; /*!< Name server structure. */
unsigned thread_id; /*!< Thread identifier. */
knot_layer_t layer; /*!< Query processing context. */
server_t *server; /*!< Name server structure. */
unsigned thread_id; /*!< Thread identifier. */
} udp_context_t;
/* FD_COPY macro compat. */
......@@ -132,33 +132,35 @@ void udp_handle(udp_context_t *udp, int fd, struct sockaddr_storage *ss,
param.proc_flags |= NS_QUERY_LIMIT_RATE;
}
/* Create packets. */
mm_ctx_t *mm = udp->layer.mm;
knot_pkt_t *query = knot_pkt_new(rx->iov_base, rx->iov_len, mm);
knot_pkt_t *ans = knot_pkt_new(tx->iov_base, tx->iov_len, mm);
/* Create query processing context. */
knot_process_begin(&udp->query_ctx, NS_PROC_QUERY, &param);
knot_layer_begin(&udp->layer, NS_PROC_QUERY, &param);
/* Input packet. */
int state = knot_process_in(&udp->query_ctx, rx->iov_base, rx->iov_len);
int state = knot_layer_in(&udp->layer, query);
/* Process answer. */
uint16_t tx_len = tx->iov_len;
if (state == NS_PROC_FULL) {
state = knot_process_out(&udp->query_ctx, tx->iov_base, &tx_len);
}
/* Process error response (if failed). */
if (state == NS_PROC_FAIL) {
tx_len = tx->iov_len; /* Reset size. */
state = knot_process_out(&udp->query_ctx, tx->iov_base, &tx_len);
while (state & (NS_PROC_FULL|NS_PROC_FAIL)) {
state = knot_layer_out(&udp->layer, ans);
}
/* Send response only if finished successfuly. */
if (state == NS_PROC_DONE) {
tx->iov_len = tx_len;
tx->iov_len = ans->size;
} else {
tx->iov_len = 0;
}
/* Reset context. */
knot_process_finish(&udp->query_ctx);
knot_layer_finish(&udp->layer);
/* Cleanup. */
knot_pkt_free(&query);
knot_pkt_free(&ans);
}
/* Check for sendmmsg syscall. */
......@@ -507,7 +509,7 @@ int udp_master(dthread_t *thread)
/* Create big enough memory cushion. */
mm_ctx_t mm;
mm_ctx_mempool(&mm, 4 * sizeof(knot_pkt_t));
udp.query_ctx.mm = &mm;
udp.layer.mm = &mm;
/* Chose select as epoll/kqueue has larger overhead for a
* single or handful of sockets. */
......
......@@ -78,6 +78,8 @@ int knot_layer_in(knot_layer_t *ctx, knot_pkt_t *pkt)
return ctx->state;
}
knot_pkt_parse(pkt, 0);
LAYER_CALL(ctx, in, pkt);
dbg_ns("%s -> %s\n", __func__, LAYER_STATE_STR(ctx->state));
return ctx->state;
......
......@@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file process.h
* \file layer.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
......
......@@ -26,13 +26,13 @@
/* @note Test helpers. */
#define TEST_RESET() \
knot_process_reset(proc); \
knot_process_out(proc, pkt->wire, (uint16_t *)&pkt->size); \
knot_layer_reset(proc); \
knot_layer_out(proc, pkt); \
knot_pkt_clear(pkt)
#define TEST_EXEC(expect, info) {\
pkt->parsed = pkt->size; /* Simulate parsed packet. */ \
int state = knot_process_in(proc, pkt->wire, pkt->size); \
int state = knot_layer_in(proc, pkt); \
is_int((expect), state, "proc_answer: " info); \
}
......@@ -133,7 +133,7 @@ int main(int argc, char *argv[])
knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, proc.mm);
/* Begin processing. */
int state = knot_process_begin(&proc, NS_PROC_ANSWER, &param);
int state = knot_layer_begin(&proc, NS_PROC_ANSWER, &param);
ok(state == NS_PROC_FULL, "proc_answer: expects query to be sent");
/* Invalid generic input tests. */
......@@ -151,7 +151,7 @@ int main(int argc, char *argv[])
/* TSIG check tests. */
/* Finish. */
state = knot_process_finish(&proc);
state = knot_layer_finish(&proc);
ok(state == NS_PROC_NOOP, "proc_answer: processing end" );
/* Cleanup. */
......
......@@ -42,29 +42,30 @@ static void answer_sanity_check(const uint8_t *query,
/* Resolve query and check answer for sanity (2 TAP tests). */
static void exec_query(knot_layer_t *query_ctx, const char *name,
const uint8_t *query, uint16_t query_len,
knot_pkt_t *query,
uint8_t expected_rcode)
{
uint16_t answer_len = KNOT_WIRE_MAX_PKTSIZE;
uint8_t answer[KNOT_WIRE_MAX_PKTSIZE];
knot_pkt_t *answer = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL);
assert(answer);
/* Input packet. */
int state = knot_process_in(query_ctx, query, query_len);
int state = knot_layer_in(query_ctx, query);
ok(state & (NS_PROC_FULL|NS_PROC_FAIL), "ns: process %s query", name);
/* Create answer. */
state = knot_process_out(query_ctx, answer, &answer_len);
state = knot_layer_out(query_ctx, answer);
if (state & NS_PROC_FAIL) {
/* Allow 1 generic error response. */
answer_len = KNOT_WIRE_MAX_PKTSIZE;
state = knot_process_out(query_ctx, answer, &answer_len);
state = knot_layer_out(query_ctx, answer);
}
ok(state == NS_PROC_DONE, "ns: answer %s query", name);
/* Check answer. */
answer_sanity_check(query, answer, answer_len, expected_rcode, name);
answer_sanity_check(query->wire, answer->wire, answer->size, expected_rcode, name);
knot_pkt_free(&answer);
}
/* \internal Helpers */
......@@ -103,50 +104,56 @@ int main(int argc, char *argv[])
param.server = &server;
/* Query processor (CH zone) */
knot_process_begin(&proc, NS_PROC_QUERY, &param);
knot_layer_begin(&proc, NS_PROC_QUERY, &param);
knot_pkt_clear(query);
knot_pkt_put_question(query, IDSERVER_DNAME, KNOT_CLASS_CH, KNOT_RRTYPE_TXT);
exec_query(&proc, "CH TXT", query->wire, query->size, KNOT_RCODE_NOERROR);
exec_query(&proc, "CH TXT", query, KNOT_RCODE_NOERROR);
/* Query processor (valid input). */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_pkt_clear(query);
knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
exec_query(&proc, "IN/root", query->wire, query->size, KNOT_RCODE_NOERROR);
exec_query(&proc, "IN/root", query, KNOT_RCODE_NOERROR);
/* Query processor (-1 bytes, not enough data). */
knot_process_reset(&proc);
exec_query(&proc, "IN/few-data", query->wire, query->size - 1, KNOT_RCODE_FORMERR);
knot_layer_reset(&proc);
query->size -= 1;
exec_query(&proc, "IN/few-data", query, KNOT_RCODE_FORMERR);
query->size += 1;
/* Query processor (+1 bytes trailing). */
knot_process_reset(&proc);
knot_layer_reset(&proc);
query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */
exec_query(&proc, "IN/trail-garbage", query->wire, query->size + 1, KNOT_RCODE_FORMERR);
query->size += 1;
exec_query(&proc, "IN/trail-garbage", query, KNOT_RCODE_FORMERR);
query->size -= 1;
/* Forge NOTIFY query from SOA query. */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY);
exec_query(&proc, "IN/notify", query->wire, query->size, KNOT_RCODE_NOTAUTH);
exec_query(&proc, "IN/notify", query, KNOT_RCODE_NOTAUTH);
/* Forge AXFR query. */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_pkt_clear(query);
knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR);
exec_query(&proc, "IN/axfr", query->wire, query->size, KNOT_RCODE_NOTAUTH);
exec_query(&proc, "IN/axfr", query, KNOT_RCODE_NOTAUTH);
/* Forge IXFR query (badly formed, no SOA in AUTHORITY section). */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_pkt_clear(query);
knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR);
exec_query(&proc, "IN/ixfr-formerr", query->wire, query->size, KNOT_RCODE_FORMERR);
exec_query(&proc, "IN/ixfr-formerr", query, KNOT_RCODE_FORMERR);
/* Forge IXFR query (well formed). */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_pkt_clear(query);
knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR);
/* Append SOA RR. */
knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
knot_pkt_begin(query, KNOT_AUTHORITY);
knot_pkt_put(query, COMPR_HINT_NONE, &soa_rr, 0);
exec_query(&proc, "IN/ixfr", query->wire, query->size, KNOT_RCODE_NOTAUTH);
exec_query(&proc, "IN/ixfr", query, KNOT_RCODE_NOTAUTH);
/* \note Tests below are not possible without proper zone and zone data. */
/* #189 Process UPDATE query. */
......@@ -154,20 +161,23 @@ int main(int argc, char *argv[])
/* #189 Process IXFR client. */
/* Query processor (smaller than DNS header, ignore). */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_pkt_clear(query);
knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
int state = knot_process_in(&proc, query->wire, KNOT_WIRE_HEADER_SIZE - 1);
size_t orig_query_size = query->size;
query->size = KNOT_WIRE_HEADER_SIZE - 1;
int state = knot_layer_in(&proc, query);
ok(state == NS_PROC_NOOP, "ns: IN/less-than-header query ignored");
query->size = orig_query_size;
/* Query processor (response, ignore). */
knot_process_reset(&proc);
knot_layer_reset(&proc);
knot_wire_set_qr(query->wire);
state = knot_process_in(&proc, query->wire, query->size);
state = knot_layer_in(&proc, query);
ok(state == NS_PROC_NOOP, "ns: IN/less-than-header query ignored");
/* Finish. */
state = knot_process_finish(&proc);
state = knot_layer_finish(&proc);
ok(state == NS_PROC_NOOP, "ns: processing end" );
/* Cleanup. */
......
......@@ -19,7 +19,7 @@
#include <stdlib.h>
#include "common/mempool.h"
#include "libknot/processing/process.h"
#include "libknot/processing/layer.h"
#include "libknot/processing/requestor.h"
#include "fake_server.h"
......
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