Commit da492263 authored by Jan Včelák's avatar Jan Včelák 🚀

requestor: layer state is not a bitmap

parent 8e90439f
......@@ -19,16 +19,18 @@
#include "libknot/packet/pkt.h"
#include "libknot/mm_ctx.h"
/*! Layer processing states.
* Each state represents the state machine transition,
* and determines readiness for the next action.
/*!
* \brief Layer processing states.
*
* Each state represents the state machine transition,
* and determines readiness for the next action.
*/
enum knot_layer_state {
KNOT_STATE_NOOP = 0, /*!< N/A */
KNOT_STATE_CONSUME = 1 << 0, /*!< Consume data. */
KNOT_STATE_PRODUCE = 1 << 1, /*!< Produce data. */
KNOT_STATE_DONE = 1 << 2, /*!< Finished. */
KNOT_STATE_FAIL = 1 << 3 /*!< Error. */
KNOT_STATE_NOOP = 0, //!< Invalid.
KNOT_STATE_CONSUME, //!< Consume data.
KNOT_STATE_PRODUCE, //!< Produce data.
KNOT_STATE_DONE, //!< Finished.
KNOT_STATE_FAIL //!< Error.
};
struct knot_layer_api;
......@@ -39,9 +41,9 @@ typedef struct knot_layer knot_layer_t;
/*! \brief Packet processing context. */
struct knot_layer {
knot_mm_t *mm; /* Processing memory context. */
int state; /* Bitmap of enum knot_layer_state. */
void *data; /* Module specific. */
knot_mm_t *mm; //!< Processing memory context.
enum knot_layer_state state; //!< Processing state.
void *data; //!< Module specific.
const struct knot_layer_api *api;
};
......
......@@ -215,6 +215,17 @@ static int request_io(struct knot_requestor *req, struct knot_request *last,
return KNOT_EOK;
}
static bool layer_active(enum knot_layer_state state)
{
switch (state) {
case KNOT_STATE_PRODUCE:
case KNOT_STATE_CONSUME:
return true;
default:
return false;
}
}
int knot_requestor_exec(struct knot_requestor *requestor,
struct knot_request *request,
int timeout_ms)
......@@ -226,7 +237,7 @@ int knot_requestor_exec(struct knot_requestor *requestor,
int ret = KNOT_EOK;
/* Do I/O until the processing is satisifed or fails. */
while (requestor->layer.state & (KNOT_STATE_PRODUCE|KNOT_STATE_CONSUME)) {
while (layer_active(requestor->layer.state)) {
ret = request_io(requestor, request, timeout_ms);
if (ret != KNOT_EOK) {
knot_layer_reset(&requestor->layer);
......
......@@ -89,6 +89,16 @@ static enum fdset_sweep_state tcp_sweep(fdset_t *set, int i, void *data)
return FDSET_SWEEP;
}
static bool tcp_active_state(int state)
{
return (state == KNOT_STATE_PRODUCE || state == KNOT_STATE_FAIL);
}
static bool tcp_send_state(int state)
{
return (state != KNOT_STATE_FAIL && state != KNOT_STATE_NOOP);
}
/*!
* \brief TCP event handler function.
*/
......@@ -132,8 +142,7 @@ static int tcp_handle(tcp_context_t *tcp, int fd,
}
/* Initialize processing layer. */
tcp->layer.state = knot_layer_begin(&tcp->layer, &param);
knot_layer_begin(&tcp->layer, &param);
/* Create packets. */
knot_pkt_t *ans = knot_pkt_new(tx->iov_base, tx->iov_len, tcp->layer.mm);
......@@ -141,15 +150,14 @@ static int tcp_handle(tcp_context_t *tcp, int fd,
/* Input packet. */
(void) knot_pkt_parse(query, 0);
int state = knot_layer_consume(&tcp->layer, query);
knot_layer_consume(&tcp->layer, query);
/* Resolve until NOOP or finished. */
ret = KNOT_EOK;
while (state & (KNOT_STATE_PRODUCE|KNOT_STATE_FAIL)) {
state = knot_layer_produce(&tcp->layer, ans);
while (tcp_active_state(tcp->layer.state)) {
knot_layer_produce(&tcp->layer, ans);
/* Send, if response generation passed and wasn't ignored. */
if (ans->size > 0 && !(state & (KNOT_STATE_FAIL|KNOT_STATE_NOOP))) {
if (ans->size > 0 && tcp_send_state(tcp->layer.state)) {
if (net_dns_tcp_send(fd, ans->wire, ans->size, timeout) != ans->size) {
ret = KNOT_ECONNREFUSED;
break;
......
......@@ -56,6 +56,11 @@ typedef struct udp_context {
unsigned thread_id; /*!< Thread identifier. */
} udp_context_t;
static bool udp_state_active(int state)
{
return (state == KNOT_STATE_PRODUCE || state == KNOT_STATE_FAIL);
}
static void udp_handle(udp_context_t *udp, int fd, struct sockaddr_storage *ss,
struct iovec *rx, struct iovec *tx)
{
......@@ -75,7 +80,7 @@ static void udp_handle(udp_context_t *udp, int fd, struct sockaddr_storage *ss,
}
/* Start query processing. */
udp->layer.state = knot_layer_begin(&udp->layer, &param);
knot_layer_begin(&udp->layer, &param);
/* Create packets. */
knot_pkt_t *query = knot_pkt_new(rx->iov_base, rx->iov_len, udp->layer.mm);
......@@ -83,15 +88,15 @@ static void udp_handle(udp_context_t *udp, int fd, struct sockaddr_storage *ss,
/* Input packet. */
(void) knot_pkt_parse(query, 0);
int state = knot_layer_consume(&udp->layer, query);
knot_layer_consume(&udp->layer, query);
/* Process answer. */
while (state & (KNOT_STATE_PRODUCE|KNOT_STATE_FAIL)) {
state = knot_layer_produce(&udp->layer, ans);
while (udp_state_active(udp->layer.state)) {
knot_layer_produce(&udp->layer, ans);
}
/* Send response only if finished successfully. */
if (state == KNOT_STATE_DONE) {
if (udp->layer.state == KNOT_STATE_DONE) {
tx->iov_len = ans->size;
} else {
tx->iov_len = 0;
......
......@@ -53,11 +53,11 @@ static void exec_query(knot_layer_t *query_ctx, const char *name,
knot_pkt_parse(query, 0);
int state = knot_layer_consume(query_ctx, query);
ok(state & (KNOT_STATE_PRODUCE|KNOT_STATE_FAIL), "ns: process %s query", name);
ok(state == KNOT_STATE_PRODUCE || state == KNOT_STATE_FAIL, "ns: process %s query", name);
/* Create answer. */
state = knot_layer_produce(query_ctx, answer);
if (state & KNOT_STATE_FAIL) {
if (state == KNOT_STATE_FAIL) {
/* Allow 1 generic error response. */
state = knot_layer_produce(query_ctx, answer);
}
......
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