summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOto Šťáva <oto.stava@nic.cz>2024-05-21 18:38:56 +0200
committerOto Šťáva <oto.stava@nic.cz>2024-06-04 13:04:59 +0200
commitdfe44a99c815609660a5bd9c16d5b1a34e20d2ff (patch)
tree49acbead2898d60322d733e0b36067e4f91c2673
parentdaemon, lib: unify protolayer_grp and kr_proto enums (diff)
downloadknot-resolver-dfe44a99c815609660a5bd9c16d5b1a34e20d2ff.tar.xz
knot-resolver-dfe44a99c815609660a5bd9c16d5b1a34e20d2ff.zip
daemon/session2: protocol layer refactors + docs
This makes some readability enhancements to the `protolayer_` API as well as clarifies some of the documentation. There is also a change where the definitions of protocol layer sequences does not require a `_NULL` layer to be present at the end anymore, as the number of layers in a sequence is determined at compile time. This makes defining new sequences less error-prone.
-rw-r--r--daemon/http.c11
-rw-r--r--daemon/io.c12
-rw-r--r--daemon/session2.c147
-rw-r--r--daemon/session2.h30
-rw-r--r--daemon/tls.c10
-rw-r--r--daemon/worker.c6
6 files changed, 114 insertions, 102 deletions
diff --git a/daemon/http.c b/daemon/http.c
index 411fe222..8509f2bc 100644
--- a/daemon/http.c
+++ b/daemon/http.c
@@ -390,8 +390,8 @@ static ssize_t send_callback(nghttp2_session *h2, const uint8_t *data, size_t le
kr_log_debug(DOH, "[%p] send_callback: %p\n", (void *)h2, (void *)send_ctx->data);
session2_wrap_after(http->h.session, PROTOLAYER_TYPE_HTTP,
- protolayer_buffer(send_ctx->data, length, false), NULL,
- callback_finished_free_baton, send_ctx);
+ protolayer_payload_buffer(send_ctx->data, length, false),
+ NULL, callback_finished_free_baton, send_ctx);
return length;
}
@@ -506,7 +506,7 @@ static int send_data_callback(nghttp2_session *h2, nghttp2_frame *frame, const u
kr_assert(cur == iovcnt);
int ret = session2_wrap_after(http->h.session, PROTOLAYER_TYPE_HTTP,
- protolayer_iovec(dest_iov, cur, false),
+ protolayer_payload_iovec(dest_iov, cur, false),
NULL, callback_finished_free_baton, sdctx);
if (ret < 0)
@@ -733,7 +733,8 @@ static int submit_to_wirebuffer(struct pl_http_sess_data *ctx)
ret = 0;
session2_unwrap_after(ctx->h.session, PROTOLAYER_TYPE_HTTP,
- protolayer_wire_buf(wb, false), NULL, NULL, NULL);
+ protolayer_payload_wire_buf(wb, false),
+ NULL, NULL, NULL);
cleanup:
http_cleanup_stream(ctx);
return ret;
@@ -938,7 +939,7 @@ static enum protolayer_iter_cb_result pl_http_unwrap(
struct protolayer_payload pld = ctx->payload;
if (pld.type == PROTOLAYER_PAYLOAD_WIRE_BUF) {
- pld = protolayer_as_buffer(&pld);
+ pld = protolayer_payload_as_buffer(&pld);
}
if (pld.type == PROTOLAYER_PAYLOAD_BUFFER) {
diff --git a/daemon/io.c b/daemon/io.c
index d8aee074..8333577d 100644
--- a/daemon/io.c
+++ b/daemon/io.c
@@ -98,7 +98,7 @@ void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf,
.comm_addr = comm_addr,
.src_addr = comm_addr
};
- session2_unwrap(s, protolayer_wire_buf(&s->layers->wire_buf, false),
+ session2_unwrap(s, protolayer_payload_wire_buf(&s->layers->wire_buf, false),
&in_comm, udp_on_unwrapped, NULL);
}
@@ -146,7 +146,7 @@ struct pl_udp_iter_data {
static enum protolayer_iter_cb_result pl_udp_unwrap(
void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx)
{
- ctx->payload = protolayer_as_buffer(&ctx->payload);
+ ctx->payload = protolayer_payload_as_buffer(&ctx->payload);
if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER)) {
/* unsupported payload */
return protolayer_break(ctx, kr_error(EINVAL));
@@ -197,7 +197,7 @@ static enum protolayer_iter_cb_result pl_udp_unwrap(
}
}
- ctx->payload = protolayer_buffer(
+ ctx->payload = protolayer_payload_buffer(
data + trimmed, data_len - trimmed, false);
}
@@ -278,7 +278,7 @@ static enum protolayer_iter_cb_result pl_tcp_unwrap(
memcpy(wire_buf_free_space(&tcp->wire_buf), buf, len);
wire_buf_consume(&tcp->wire_buf, ctx->payload.buffer.len);
- ctx->payload = protolayer_wire_buf(&tcp->wire_buf, false);
+ ctx->payload = protolayer_payload_wire_buf(&tcp->wire_buf, false);
}
if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)) {
@@ -511,7 +511,7 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
return;
}
- session2_unwrap(s, protolayer_wire_buf(&s->layers->wire_buf, false),
+ session2_unwrap(s, protolayer_payload_wire_buf(&s->layers->wire_buf, false),
NULL, NULL, NULL);
}
@@ -950,7 +950,7 @@ static void xdp_rx(uv_poll_t* handle, int status, int events)
memcpy(comm.eth_from, msg->eth_from, sizeof(comm.eth_from));
memcpy(comm.eth_to, msg->eth_to, sizeof(comm.eth_to));
session2_unwrap(xhd->session,
- protolayer_buffer(
+ protolayer_payload_buffer(
msg->payload.iov_base,
msg->payload.iov_len, false),
&comm, NULL, NULL);
diff --git a/daemon/session2.c b/daemon/session2.c
index dc9911a0..fa3feb9c 100644
--- a/daemon/session2.c
+++ b/daemon/session2.c
@@ -36,20 +36,17 @@ struct protolayer_globals protolayer_globals[PROTOLAYER_TYPE_COUNT] = {{0}};
static const enum protolayer_type protolayer_grp_udp53[] = {
PROTOLAYER_TYPE_UDP,
PROTOLAYER_TYPE_DNS_DGRAM,
- PROTOLAYER_TYPE_NULL
};
static const enum protolayer_type protolayer_grp_tcp53[] = {
PROTOLAYER_TYPE_TCP,
PROTOLAYER_TYPE_DNS_MULTI_STREAM,
- PROTOLAYER_TYPE_NULL
};
static const enum protolayer_type protolayer_grp_dot[] = {
PROTOLAYER_TYPE_TCP,
PROTOLAYER_TYPE_TLS,
PROTOLAYER_TYPE_DNS_MULTI_STREAM,
- PROTOLAYER_TYPE_NULL
};
static const enum protolayer_type protolayer_grp_doh[] = {
@@ -57,14 +54,23 @@ static const enum protolayer_type protolayer_grp_doh[] = {
PROTOLAYER_TYPE_TLS,
PROTOLAYER_TYPE_HTTP,
PROTOLAYER_TYPE_DNS_UNSIZED_STREAM,
- PROTOLAYER_TYPE_NULL
};
static const enum protolayer_type protolayer_grp_doq[] = {
// not yet used
- PROTOLAYER_TYPE_NULL
+ PROTOLAYER_TYPE_NULL,
};
+struct protolayer_grp {
+ const enum protolayer_type *layers;
+ size_t num_layers;
+};
+
+#define PROTOLAYER_GRP(p_array) { \
+ .layers = (p_array), \
+ .num_layers = sizeof((p_array)) / sizeof((p_array)[0]), \
+}
+
/** Sequences of layers, or groups, mapped by `enum kr_proto`.
*
* Each group represents a sequence of layers in the unwrap direction (wrap
@@ -78,8 +84,8 @@ static const enum protolayer_type protolayer_grp_doq[] = {
* indicate the end of the list of protocol layers. The array name's suffix must
* be the one defined as *Variable name* (2nd parameter) in the
* `KR_PROTO_MAP` macro. */
-static const enum protolayer_type *protolayer_grps[KR_PROTO_COUNT] = {
-#define XX(cid, vid, name) [KR_PROTO_##cid] = protolayer_grp_##vid,
+static const struct protolayer_grp protolayer_grps[KR_PROTO_COUNT] = {
+#define XX(cid, vid, name) [KR_PROTO_##cid] = PROTOLAYER_GRP(protolayer_grp_##vid),
KR_PROTO_MAP(XX)
#undef XX
};
@@ -222,7 +228,8 @@ size_t protolayer_payload_copy(void *dest,
}
}
-struct protolayer_payload protolayer_as_buffer(const struct protolayer_payload *payload)
+struct protolayer_payload protolayer_payload_as_buffer(
+ const struct protolayer_payload *payload)
{
if (payload->type == PROTOLAYER_PAYLOAD_BUFFER)
return *payload;
@@ -296,12 +303,13 @@ bool protolayer_queue_has_payload(const protolayer_iter_ctx_queue_t *queue)
static inline struct protolayer_data *protolayer_sess_data_get(
struct protolayer_manager *m, size_t layer_ix)
{
- if (kr_fails_assert(layer_ix < m->num_layers))
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ if (kr_fails_assert(layer_ix < grp->num_layers))
return NULL;
/* See doc comment of `struct protolayer_manager::data` */
const ssize_t *offsets = (ssize_t *)m->data;
- char *pl_data_beg = &m->data[2 * m->num_layers * sizeof(*offsets)];
+ char *pl_data_beg = &m->data[2 * grp->num_layers * sizeof(*offsets)];
ssize_t offset = offsets[layer_ix];
if (offset < 0) /* No session data for this layer */
@@ -316,11 +324,12 @@ static inline struct protolayer_data *protolayer_iter_data_get(
struct protolayer_iter_ctx *ctx, size_t layer_ix)
{
struct protolayer_manager *m = ctx->manager;
- if (kr_fails_assert(layer_ix < m->num_layers))
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ if (kr_fails_assert(layer_ix < grp->num_layers))
return NULL;
/* See doc comment of `struct protolayer_manager::data` */
- const ssize_t *offsets = (ssize_t *)&m->data[m->num_layers * sizeof(*offsets)];
+ const ssize_t *offsets = (ssize_t *)&m->data[grp->num_layers * sizeof(*offsets)];
ssize_t offset = offsets[layer_ix];
if (offset < 0) /* No iteration data for this layer */
@@ -332,8 +341,9 @@ static inline struct protolayer_data *protolayer_iter_data_get(
static inline ssize_t protolayer_manager_get_protocol(
struct protolayer_manager *m, enum protolayer_type protocol)
{
- for (ssize_t i = 0; i < m->num_layers; i++) {
- enum protolayer_type found = protolayer_grps[m->grp][i];
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ for (ssize_t i = 0; i < grp->num_layers; i++) {
+ enum protolayer_type found = grp->layers[i];
if (protocol == found)
return i;
}
@@ -344,7 +354,7 @@ static inline ssize_t protolayer_manager_get_protocol(
static inline bool protolayer_iter_ctx_is_last(struct protolayer_iter_ctx *ctx)
{
unsigned int last_ix = (ctx->direction == PROTOLAYER_UNWRAP)
- ? ctx->manager->num_layers - 1
+ ? protolayer_grps[ctx->manager->proto].num_layers - 1
: 0;
return ctx->layer_ix == last_ix;
}
@@ -361,13 +371,13 @@ static inline const char *layer_name(enum kr_proto grp, ssize_t layer_ix)
{
if (grp >= KR_PROTO_COUNT)
return "(invalid)";
- enum protolayer_type p = protolayer_grps[grp][layer_ix];
+ enum protolayer_type p = protolayer_grps[grp].layers[layer_ix];
return protolayer_layer_name(p);
}
static inline const char *layer_name_ctx(struct protolayer_iter_ctx *ctx)
{
- return layer_name(ctx->manager->grp, ctx->layer_ix);
+ return layer_name(ctx->manager->proto, ctx->layer_ix);
}
static int protolayer_iter_ctx_finish(struct protolayer_iter_ctx *ctx, int ret)
@@ -375,8 +385,9 @@ static int protolayer_iter_ctx_finish(struct protolayer_iter_ctx *ctx, int ret)
struct session2 *session = ctx->manager->session;
struct protolayer_manager *m = ctx->manager;
- struct protolayer_globals *globals = &protolayer_globals[m->grp];
- for (size_t i = 0; i < m->num_layers; i++) {
+ const struct protolayer_globals *globals = &protolayer_globals[m->proto];
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ for (size_t i = 0; i < grp->num_layers; i++) {
struct protolayer_data *d = protolayer_iter_data_get(ctx, i);
if (globals->iter_deinit)
globals->iter_deinit(m, ctx, d);
@@ -384,12 +395,12 @@ static int protolayer_iter_ctx_finish(struct protolayer_iter_ctx *ctx, int ret)
if (ret)
VERBOSE_LOG(session, "layer context of group '%s' (on %u: %s) ended with return code %d\n",
- kr_proto_name(ctx->manager->grp),
+ kr_proto_name(ctx->manager->proto),
ctx->layer_ix, layer_name_ctx(ctx), ret);
if (ctx->status)
VERBOSE_LOG(session, "iteration of group '%s' (on %u: %s) ended with status %d\n",
- kr_proto_name(ctx->manager->grp),
+ kr_proto_name(ctx->manager->proto),
ctx->layer_ix, layer_name_ctx(ctx), ctx->status);
if (ctx->finished_cb)
@@ -415,7 +426,7 @@ static int protolayer_push(struct protolayer_iter_ctx *ctx)
struct session2 *session = ctx->manager->session;
if (ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) {
- ctx->payload = protolayer_as_buffer(&ctx->payload);
+ ctx->payload = protolayer_payload_as_buffer(&ctx->payload);
}
if (kr_log_is_debug(PROTOLAYER, NULL)) {
@@ -441,7 +452,7 @@ static int protolayer_push(struct protolayer_iter_ctx *ctx)
return PROTOLAYER_RET_ASYNC;
}
-static void protolayer_ensure_long_lived(struct protolayer_iter_ctx *ctx)
+static void protolayer_payload_ensure_long_lived(struct protolayer_iter_ctx *ctx)
{
if (!ctx->payload.short_lived)
return;
@@ -455,7 +466,7 @@ static void protolayer_ensure_long_lived(struct protolayer_iter_ctx *ctx)
protolayer_payload_copy(buf, &ctx->payload, buf_len);
ctx->async_buffer = buf;
- ctx->payload = protolayer_buffer(buf, buf_len, false);
+ ctx->payload = protolayer_payload_buffer(buf, buf_len, false);
}
/** Processes as many layers as possible synchronously, returning when either
@@ -466,10 +477,10 @@ static void protolayer_ensure_long_lived(struct protolayer_iter_ctx *ctx)
static int protolayer_step(struct protolayer_iter_ctx *ctx)
{
while (true) {
- if (kr_fails_assert(ctx->manager->grp < KR_PROTO_COUNT))
+ if (kr_fails_assert(ctx->manager->proto < KR_PROTO_COUNT))
return kr_error(EFAULT);
- enum protolayer_type protocol = protolayer_grps[ctx->manager->grp][ctx->layer_ix];
+ enum protolayer_type protocol = protolayer_grps[ctx->manager->proto].layers[ctx->layer_ix];
struct protolayer_globals *globals = &protolayer_globals[protocol];
ctx->async_mode = false;
@@ -502,7 +513,7 @@ static int protolayer_step(struct protolayer_iter_ctx *ctx)
if (!ctx->action) {
/* Next step is from a callback */
ctx->async_mode = true;
- protolayer_ensure_long_lived(ctx);
+ protolayer_payload_ensure_long_lived(ctx);
return PROTOLAYER_RET_ASYNC;
}
@@ -551,15 +562,18 @@ static int protolayer_manager_submit(
if (manager->session->closing)
return kr_error(ECANCELED);
+ if (kr_fails_assert(manager->proto < KR_PROTO_COUNT))
+ return kr_error(EFAULT);
+
struct protolayer_iter_ctx *ctx = malloc(manager->cb_ctx_size);
kr_require(ctx);
VERBOSE_LOG(manager->session,
"%s submitted to grp '%s' in %s direction (%zu: %s)\n",
protolayer_payload_name(payload.type),
- kr_proto_name(manager->grp),
+ kr_proto_name(manager->proto),
(direction == PROTOLAYER_UNWRAP) ? "unwrap" : "wrap",
- layer_ix, layer_name(manager->grp, layer_ix));
+ layer_ix, layer_name(manager->proto, layer_ix));
*ctx = (struct protolayer_iter_ctx) {
.payload = payload,
@@ -571,12 +585,9 @@ static int protolayer_manager_submit(
.finished_cb_baton = baton
};
- for (size_t i = 0; i < manager->num_layers; i++) {
- if (kr_fails_assert(ctx->manager->grp < KR_PROTO_COUNT))
- return kr_error(EFAULT);
-
- enum protolayer_type p = protolayer_grps[manager->grp][i];
- struct protolayer_globals *globals = &protolayer_globals[p];
+ const struct protolayer_grp *grp = &protolayer_grps[manager->proto];
+ for (size_t i = 0; i < grp->num_layers; i++) {
+ struct protolayer_globals *globals = &protolayer_globals[grp->layers[i]];
struct protolayer_data *iter_data = protolayer_iter_data_get(ctx, i);
if (iter_data) {
memset(iter_data, 0, globals->iter_size);
@@ -606,41 +617,33 @@ static void *get_init_param(enum protolayer_type p,
/** Allocates and initializes a new manager. */
static struct protolayer_manager *protolayer_manager_new(
struct session2 *s,
- enum kr_proto grp,
+ enum kr_proto proto,
struct protolayer_data_param *layer_param,
size_t layer_param_count)
{
- if (kr_fails_assert(s && grp))
+ if (kr_fails_assert(s && proto))
return NULL;
- size_t num_layers = 0;
size_t manager_size = sizeof(struct protolayer_manager);
size_t cb_ctx_size = sizeof(struct protolayer_iter_ctx);
- const enum protolayer_type *protocols = protolayer_grps[grp];
- if (kr_fails_assert(protocols))
- return NULL;
- const enum protolayer_type *p = protocols;
-
- /* Space for offset index */
- for (; *p; p++)
- num_layers++;
- if (kr_fails_assert(num_layers))
+ const struct protolayer_grp *grp = &protolayer_grps[proto];
+ if (kr_fails_assert(grp->num_layers))
return NULL;
size_t wire_buf_length = 0;
size_t wire_buf_max_length = 0;
- ssize_t offsets[2 * num_layers];
+ ssize_t offsets[2 * grp->num_layers];
manager_size += sizeof(offsets);
ssize_t *sess_offsets = offsets;
- ssize_t *iter_offsets = &offsets[num_layers];
+ ssize_t *iter_offsets = &offsets[grp->num_layers];
/* Space for layer-specific data, guaranteeing alignment */
size_t total_sess_data_size = 0;
size_t total_iter_data_size = 0;
- for (size_t i = 0; i < num_layers; i++) {
- const struct protolayer_globals *g = &protolayer_globals[protocols[i]];
+ for (size_t i = 0; i < grp->num_layers; i++) {
+ const struct protolayer_globals *g = &protolayer_globals[grp->layers[i]];
sess_offsets[i] = g->sess_size ? total_sess_data_size : -1;
total_sess_data_size += ALIGN_TO(g->sess_size, CPU_STRUCT_ALIGN);
@@ -660,9 +663,8 @@ static struct protolayer_manager *protolayer_manager_new(
/* Allocate and initialize manager */
struct protolayer_manager *m = calloc(1, manager_size);
kr_require(m);
- m->grp = grp;
+ m->proto = proto;
m->session = s;
- m->num_layers = num_layers;
m->cb_ctx_size = cb_ctx_size;
memcpy(m->data, offsets, sizeof(offsets));
@@ -671,15 +673,15 @@ static struct protolayer_manager *protolayer_manager_new(
kr_require(!ret);
/* Initialize the layer's session data */
- for (size_t i = 0; i < num_layers; i++) {
- struct protolayer_globals *globals = &protolayer_globals[protocols[i]];
+ for (size_t i = 0; i < grp->num_layers; i++) {
+ struct protolayer_globals *globals = &protolayer_globals[grp->layers[i]];
struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
if (sess_data) {
memset(sess_data, 0, globals->sess_size);
sess_data->session = s;
}
- void *param = get_init_param(protocols[i], layer_param, layer_param_count);
+ void *param = get_init_param(grp->layers[i], layer_param, layer_param_count);
if (globals->sess_init)
globals->sess_init(m, sess_data, param);
}
@@ -692,9 +694,9 @@ static void protolayer_manager_free(struct protolayer_manager *m)
{
if (!m) return;
- for (size_t i = 0; i < m->num_layers; i++) {
- enum protolayer_type p = protolayer_grps[m->grp][i];
- struct protolayer_globals *globals = &protolayer_globals[p];
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ for (size_t i = 0; i < grp->num_layers; i++) {
+ struct protolayer_globals *globals = &protolayer_globals[grp->layers[i]];
if (globals->sess_deinit) {
struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
globals->sess_deinit(m, sess_data);
@@ -751,8 +753,9 @@ int wire_buf_reserve(struct wire_buf *wb, size_t size)
if (wb->buf && wb->size >= size)
return kr_ok();
- wb->buf = realloc(wb->buf, size);
- kr_require(wb->buf);
+ char *newbuf = realloc(wb->buf, size);
+ kr_require(newbuf);
+ wb->buf = newbuf;
wb->size = size;
return kr_ok();
}
@@ -1194,7 +1197,7 @@ int session2_wrap(struct session2 *s, struct protolayer_payload payload,
void *baton)
{
return protolayer_manager_submit(s->layers, PROTOLAYER_WRAP,
- s->layers->num_layers - 1,
+ protolayer_grps[s->layers->proto].num_layers - 1,
payload, comm, cb, baton);
}
@@ -1214,9 +1217,9 @@ static void session2_event_wrap(struct session2 *s, enum protolayer_event_type e
{
bool cont;
struct protolayer_manager *m = s->layers;
- for (ssize_t i = m->num_layers - 1; i >= 0; i--) {
- enum protolayer_type p = protolayer_grps[s->layers->grp][i];
- struct protolayer_globals *globals = &protolayer_globals[p];
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ for (ssize_t i = grp->num_layers - 1; i >= 0; i--) {
+ struct protolayer_globals *globals = &protolayer_globals[grp->layers[i]];
if (globals->event_wrap) {
struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
cont = globals->event_wrap(event, &baton, m, sess_data);
@@ -1235,9 +1238,9 @@ void session2_event_unwrap(struct session2 *s, ssize_t start_ix, enum protolayer
{
bool cont;
struct protolayer_manager *m = s->layers;
- for (ssize_t i = start_ix; i < m->num_layers; i++) {
- enum protolayer_type p = protolayer_grps[s->layers->grp][i];
- struct protolayer_globals *globals = &protolayer_globals[p];
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ for (ssize_t i = start_ix; i < grp->num_layers; i++) {
+ struct protolayer_globals *globals = &protolayer_globals[grp->layers[i]];
if (globals->event_unwrap) {
struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
cont = globals->event_unwrap(event, &baton, m, sess_data);
@@ -1275,9 +1278,9 @@ void session2_event_after(struct session2 *s, enum protolayer_type protocol,
void session2_init_request(struct session2 *s, struct kr_request *req)
{
struct protolayer_manager *m = s->layers;
- for (ssize_t i = 0; i < m->num_layers; i++) {
- enum protolayer_type p = protolayer_grps[s->layers->grp][i];
- struct protolayer_globals *globals = &protolayer_globals[p];
+ const struct protolayer_grp *grp = &protolayer_grps[m->proto];
+ for (ssize_t i = 0; i < grp->num_layers; i++) {
+ struct protolayer_globals *globals = &protolayer_globals[grp->layers[i]];
if (globals->request_init) {
struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
globals->request_init(m, req, sess_data);
@@ -1519,7 +1522,7 @@ static int session2_transport_pushv(struct session2 *s,
goto exit_err;
}
int ret = session2_wrap(parent,
- protolayer_iovec(iov, iovcnt, iov_short_lived),
+ protolayer_payload_iovec(iov, iovcnt, iov_short_lived),
comm, session2_transport_parent_pushv_finished,
ctx);
return (ret < 0) ? ret : kr_ok();
diff --git a/daemon/session2.h b/daemon/session2.h
index cda0bd5a..f65cf5d6 100644
--- a/daemon/session2.h
+++ b/daemon/session2.h
@@ -338,7 +338,7 @@ const char *protolayer_event_name(enum protolayer_event_type e);
* valid. */
enum protolayer_payload_type {
PROTOLAYER_PAYLOAD_NULL = 0,
-#define XX(cid, name) PROTOLAYER_PAYLOAD_ ## cid,
+#define XX(cid, name) PROTOLAYER_PAYLOAD_##cid,
PROTOLAYER_PAYLOAD_MAP(XX)
#undef XX
PROTOLAYER_PAYLOAD_COUNT
@@ -357,9 +357,17 @@ struct protolayer_payload {
/** Time-to-live hint (e.g. for HTTP Cache-Control) */
unsigned int ttl;
- /** If `true`, the payload's memory may be freed early as kresd does not
- * completely control its lifetime. When going asynchronous, it needs to
- * be copied. */
+ /** If `true`, signifies that the memory this payload points to may
+ * become invalid when we return from one of the functions in the
+ * current stack. That is fine as long as all the protocol layer
+ * processing for this payload takes place in a single `session2_wrap()`
+ * or `session2_unwrap()` call, but may become a problem, when a layer
+ * goes asynchronous (via `protolayer_async()`).
+ *
+ * Setting this to `true` will ensure that the payload will get copied
+ * into a separate memory buffer if and only if a layer goes
+ * asynchronous. It makes sure that if all processing for the payload is
+ * synchronous, no copies or reallocations for the payload are done. */
bool short_lived;
union {
@@ -421,8 +429,8 @@ size_t protolayer_payload_copy(void *dest,
size_t max_len);
/** Convenience function to get a buffer-type payload. */
-static inline struct protolayer_payload protolayer_buffer(void *buf, size_t len,
- bool short_lived)
+static inline struct protolayer_payload protolayer_payload_buffer(
+ void *buf, size_t len, bool short_lived)
{
return (struct protolayer_payload){
.type = PROTOLAYER_PAYLOAD_BUFFER,
@@ -435,7 +443,7 @@ static inline struct protolayer_payload protolayer_buffer(void *buf, size_t len,
}
/** Convenience function to get an iovec-type payload. */
-static inline struct protolayer_payload protolayer_iovec(
+static inline struct protolayer_payload protolayer_payload_iovec(
struct iovec *iov, int iovcnt, bool short_lived)
{
return (struct protolayer_payload){
@@ -449,7 +457,7 @@ static inline struct protolayer_payload protolayer_iovec(
}
/** Convenience function to get a wire-buf-type payload. */
-static inline struct protolayer_payload protolayer_wire_buf(
+static inline struct protolayer_payload protolayer_payload_wire_buf(
struct wire_buf *wire_buf, bool short_lived)
{
return (struct protolayer_payload){
@@ -466,7 +474,8 @@ static inline struct protolayer_payload protolayer_wire_buf(
* If the input payload is `_WIRE_BUF`, the pointed-to wire buffer is reset to
* indicate that all of its contents have been used up, and the buffer is ready
* to be reused. */
-struct protolayer_payload protolayer_as_buffer(const struct protolayer_payload *payload);
+struct protolayer_payload protolayer_payload_as_buffer(
+ const struct protolayer_payload *payload);
/** A predefined queue type for iteration context. */
typedef queue_t(struct protolayer_iter_ctx *) protolayer_iter_ctx_queue_t;
@@ -580,11 +589,10 @@ typedef void (*protolayer_request_cb)(struct protolayer_manager *manager,
* `grp`), which define how the data processed by the session is to be
* interpreted. */
struct protolayer_manager {
- enum kr_proto grp;
+ enum kr_proto proto;
struct wire_buf wire_buf;
size_t wire_buf_max_length;
struct session2 *session;
- size_t num_layers;
size_t cb_ctx_size; /**< Size of a single callback context, including
* layer-specific per-iteration data. */
diff --git a/daemon/tls.c b/daemon/tls.c
index 377355f7..fd684518 100644
--- a/daemon/tls.c
+++ b/daemon/tls.c
@@ -229,8 +229,8 @@ static ssize_t kres_gnutls_vec_push(gnutls_transport_ptr_t h, const giovec_t * i
memcpy(push_ctx->iov, iov, sizeof(struct iovec[iovcnt]));
session2_wrap_after(tls->h.session, PROTOLAYER_TYPE_TLS,
- protolayer_iovec(push_ctx->iov, iovcnt, true), NULL,
- kres_gnutls_push_finished, push_ctx);
+ protolayer_payload_iovec(push_ctx->iov, iovcnt, true),
+ NULL, kres_gnutls_push_finished, push_ctx);
return total_len;
}
@@ -967,7 +967,7 @@ static int pl_tls_sess_server_init(struct protolayer_manager *manager,
tls->tls_session);
}
- const gnutls_datum_t *alpn = &tls_grp_alpn[manager->grp];
+ const gnutls_datum_t *alpn = &tls_grp_alpn[manager->proto];
if (alpn->size) { /* ALPN is a non-empty string */
flags = 0;
#if GNUTLS_VERSION_NUMBER >= 0x030500
@@ -1160,7 +1160,7 @@ static enum protolayer_iter_cb_result pl_tls_unwrap(void *sess_data, void *iter_
struct protolayer_iter_ctx *ctx_head = queue_head(tls->unwrap_queue);
if (!kr_fails_assert(ctx == ctx_head))
queue_pop(tls->unwrap_queue);
- ctx->payload = protolayer_wire_buf(&tls->unwrap_buf, false);
+ ctx->payload = protolayer_payload_wire_buf(&tls->unwrap_buf, false);
return protolayer_continue(ctx);
exit_break:
@@ -1174,7 +1174,7 @@ static ssize_t pl_tls_submit(gnutls_session_t tls_session,
struct protolayer_payload payload)
{
if (payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)
- payload = protolayer_as_buffer(&payload);
+ payload = protolayer_payload_as_buffer(&payload);
if (payload.type == PROTOLAYER_PAYLOAD_BUFFER) {
ssize_t count = gnutls_record_send(tls_session,
diff --git a/daemon/worker.c b/daemon/worker.c
index 1ac52266..31070f0d 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -662,7 +662,7 @@ static int qr_task_send(struct qr_task *task, struct session2 *session,
/* Pending '_finished' callback on current task */
qr_task_ref(task);
- struct protolayer_payload payload = protolayer_buffer(
+ struct protolayer_payload payload = protolayer_payload_buffer(
(char *)pkt->wire, pkt->size, false);
payload.ttl = packet_ttl(pkt);
ret = session2_wrap(session, payload, comm, qr_task_wrap_finished, task);
@@ -2262,7 +2262,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap(
stream->sent.mem = siov;
stream->sent.pool = &s->pool;
- ctx->payload = protolayer_iovec(siov->iovs, iovcnt, false);
+ ctx->payload = protolayer_payload_iovec(siov->iovs, iovcnt, false);
return protolayer_continue(ctx);
} else if (ctx->payload.type == PROTOLAYER_PAYLOAD_IOVEC) {
const int iovcnt = 1 + ctx->payload.iovec.cnt;
@@ -2288,7 +2288,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap(
stream->sent.mem = siov;
stream->sent.pool = &s->pool;
- ctx->payload = protolayer_iovec(siov->iovs, iovcnt, false);
+ ctx->payload = protolayer_payload_iovec(siov->iovs, iovcnt, false);
return protolayer_continue(ctx);
} else {
kr_assert(false && "Invalid payload");