diff options
author | Oto Šťáva <oto.stava@nic.cz> | 2024-05-21 18:38:56 +0200 |
---|---|---|
committer | Oto Šťáva <oto.stava@nic.cz> | 2024-06-04 13:04:59 +0200 |
commit | dfe44a99c815609660a5bd9c16d5b1a34e20d2ff (patch) | |
tree | 49acbead2898d60322d733e0b36067e4f91c2673 | |
parent | daemon, lib: unify protolayer_grp and kr_proto enums (diff) | |
download | knot-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.c | 11 | ||||
-rw-r--r-- | daemon/io.c | 12 | ||||
-rw-r--r-- | daemon/session2.c | 147 | ||||
-rw-r--r-- | daemon/session2.h | 30 | ||||
-rw-r--r-- | daemon/tls.c | 10 | ||||
-rw-r--r-- | daemon/worker.c | 6 |
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"); |