From: Oto Šťáva Date: Tue, 13 Sep 2022 10:12:30 +0000 (+0200) Subject: daemon/session2: move iteration data into struct protolayer_cb_ctx X-Git-Tag: v6.0.2~42^2~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=afc8a32a9ac37fa8ed32ce2bb3dc1e17e7091c57;p=thirdparty%2Fknot-resolver.git daemon/session2: move iteration data into struct protolayer_cb_ctx --- diff --git a/daemon/io.c b/daemon/io.c index 6d1d069e7..daac2ffc9 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -132,18 +132,20 @@ static int family_to_freebind_option(sa_family_t sa_family, int *level, int *nam struct pl_udp_iter_data { + PROTOLAYER_DATA_HEADER(); struct proxy_result proxy; bool has_proxy; }; -static int pl_udp_iter_init(struct protolayer_manager *manager, struct protolayer_data *layer) +static int pl_udp_iter_init(struct protolayer_manager *manager, void *iter_data) { - struct pl_udp_iter_data *udp = protolayer_iter_data(layer); + struct pl_udp_iter_data *udp = iter_data; *udp = (struct pl_udp_iter_data){0}; return 0; } -static enum protolayer_cb_result pl_udp_unwrap(struct protolayer_data *layer, struct protolayer_cb_ctx *ctx) +static enum protolayer_cb_result pl_udp_unwrap( + void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { ctx->payload = protolayer_as_buffer(&ctx->payload); if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER)) { @@ -152,7 +154,7 @@ static enum protolayer_cb_result pl_udp_unwrap(struct protolayer_data *layer, st } struct session2 *s = ctx->manager->session; - struct pl_udp_iter_data *udp = protolayer_iter_data(layer); + struct pl_udp_iter_data *udp = iter_data; char *data = ctx->payload.buffer.buf; ssize_t data_len = ctx->payload.buffer.len; @@ -207,7 +209,7 @@ static enum protolayer_cb_result pl_udp_unwrap(struct protolayer_data *layer, st static bool pl_udp_event_wrap(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) { the_worker->stats.err_udp += 1; @@ -222,30 +224,32 @@ static bool pl_udp_event_wrap(enum protolayer_event_type event, struct pl_tcp_sess_data { + PROTOLAYER_DATA_HEADER(); struct proxy_result proxy; struct wire_buf wire_buf; bool had_data : 1; bool has_proxy : 1; }; -static int pl_tcp_sess_init(struct protolayer_manager *manager, struct protolayer_data *layer, void *param) +static int pl_tcp_sess_init(struct protolayer_manager *manager, void *sess_data, void *param) { - struct pl_tcp_sess_data *tcp = protolayer_sess_data(layer); + struct pl_tcp_sess_data *tcp = sess_data; *tcp = (struct pl_tcp_sess_data){0}; return 0; } -static int pl_tcp_sess_deinit(struct protolayer_manager *manager, struct protolayer_data *layer) +static int pl_tcp_sess_deinit(struct protolayer_manager *manager, void *sess_data) { - struct pl_tcp_sess_data *tcp = protolayer_sess_data(layer); + struct pl_tcp_sess_data *tcp = sess_data; wire_buf_deinit(&tcp->wire_buf); return 0; } -static enum protolayer_cb_result pl_tcp_unwrap(struct protolayer_data *layer, struct protolayer_cb_ctx *ctx) +static enum protolayer_cb_result pl_tcp_unwrap( + void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { struct session2 *s = ctx->manager->session; - struct pl_tcp_sess_data *tcp = protolayer_sess_data(layer); + struct pl_tcp_sess_data *tcp = sess_data; struct sockaddr *peer = session2_get_peer(s); if (ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER) { @@ -342,7 +346,7 @@ static enum protolayer_cb_result pl_tcp_unwrap(struct protolayer_data *layer, st static bool pl_tcp_event_wrap(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) { the_worker->stats.err_tcp += 1; diff --git a/daemon/session2.c b/daemon/session2.c index 474772898..68363c6bb 100644 --- a/daemon/session2.c +++ b/daemon/session2.c @@ -109,24 +109,50 @@ struct protolayer_payload protolayer_as_buffer(const struct protolayer_payload * } -/** Gets context for the layer with the specified index from the manager. */ -static inline struct protolayer_data *protolayer_manager_get( +/** Gets layer-specific session data for the layer with the specified index + * from the manager. */ +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)) return NULL; - const size_t *offsets = (size_t *)m->data; - char *pl_data_beg = m->data + (m->num_layers * sizeof(*offsets)); - return (struct protolayer_data *)(pl_data_beg + offsets[layer_ix]); + /* 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)]; + ssize_t offset = offsets[layer_ix]; + + if (offset < 0) /* No session data for this layer */ + return NULL; + + return (struct protolayer_data *)(pl_data_beg + offset); +} + +/** Gets layer-specific iteration data for the layer with the specified index + * from the context. */ +static inline struct protolayer_data *protolayer_iter_data_get( + struct protolayer_cb_ctx *ctx, size_t layer_ix) +{ + struct protolayer_manager *m = ctx->manager; + if (kr_fails_assert(layer_ix < m->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)]; + ssize_t offset = offsets[layer_ix]; + + if (offset < 0) /* No iteration data for this layer */ + return NULL; + + return (struct protolayer_data *)(ctx->data + offset); } static inline ssize_t protolayer_manager_get_protocol( struct protolayer_manager *m, enum protolayer_protocol protocol) { for (ssize_t i = 0; i < m->num_layers; i++) { - struct protolayer_data *d = protolayer_manager_get(m, i); - if (d->protocol == protocol) + enum protolayer_protocol found = protolayer_grps[m->grp][i]; + if (protocol == found) return i; } @@ -149,20 +175,16 @@ static inline void protolayer_cb_ctx_next(struct protolayer_cb_ctx *ctx) ctx->layer_ix--; } -static int protolayer_cb_ctx_finish(struct protolayer_cb_ctx *ctx, int ret, - bool deinit_iter_data) +static int protolayer_cb_ctx_finish(struct protolayer_cb_ctx *ctx, int ret) { struct session2 *session = ctx->manager->session; - if (deinit_iter_data) { - struct protolayer_manager *m = ctx->manager; - struct protolayer_globals *globals = &protolayer_globals[m->grp]; - for (size_t i = 0; i < m->num_layers; i++) { - struct protolayer_data *d = protolayer_manager_get(m, i); - if (globals->iter_deinit) - globals->iter_deinit(m, d); - } - m->iter_data_inited = false; + struct protolayer_manager *m = ctx->manager; + struct protolayer_globals *globals = &protolayer_globals[m->grp]; + for (size_t i = 0; i < m->num_layers; i++) { + struct protolayer_data *d = protolayer_iter_data_get(ctx, i); + if (globals->iter_deinit) + globals->iter_deinit(m, d); } if (ret) @@ -186,7 +208,7 @@ static void protolayer_push_finished(int status, struct session2 *s, const void { struct protolayer_cb_ctx *ctx = baton; ctx->status = status; - protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL, true); + protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL); } /** Pushes the specified protocol layer's payload to the session's transport. */ @@ -219,7 +241,7 @@ static int protolayer_push(struct protolayer_cb_ctx *ctx) if (status < 0) { ctx->status = status; - return protolayer_cb_ctx_finish(ctx, status, true); + return protolayer_cb_ctx_finish(ctx, status); } return PROTOLAYER_RET_ASYNC; @@ -233,40 +255,30 @@ static int protolayer_push(struct protolayer_cb_ctx *ctx) static int protolayer_step(struct protolayer_cb_ctx *ctx) { while (true) { - struct protolayer_data *ldata = protolayer_manager_get( - ctx->manager, ctx->layer_ix); - if (kr_fails_assert(ldata)) { - /* Probably layer index or data corruption */ - return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL), true); - } - - enum protolayer_protocol protocol = ldata->protocol; + enum protolayer_protocol protocol = protolayer_grps[ctx->manager->grp][ctx->layer_ix]; struct protolayer_globals *globals = &protolayer_globals[protocol]; - enum protolayer_cb_result result = PROTOLAYER_CB_RESULT_MAGIC; - if (!ldata->processed) { /* Avoid repetition */ - ctx->async_mode = false; - ctx->status = 0; - ctx->action = PROTOLAYER_CB_ACTION_NULL; - - protolayer_cb cb = (ctx->direction == PROTOLAYER_UNWRAP) - ? globals->unwrap : globals->wrap; - - if (cb) - result = cb(ldata, ctx); - else - ctx->action = PROTOLAYER_CB_ACTION_CONTINUE; - - ldata->processed = true; + ctx->async_mode = false; + ctx->status = 0; + ctx->action = PROTOLAYER_CB_ACTION_NULL; + + protolayer_cb cb = (ctx->direction == PROTOLAYER_UNWRAP) + ? globals->unwrap : globals->wrap; + + if (cb) { + struct protolayer_data *sess_data = protolayer_sess_data_get( + ctx->manager, ctx->layer_ix); + struct protolayer_data *iter_data = protolayer_iter_data_get( + ctx, ctx->layer_ix); + enum protolayer_cb_result result = cb(sess_data, iter_data, ctx); + if (kr_fails_assert(result == PROTOLAYER_CB_RESULT_MAGIC)) { + /* Callback did not use a continuation function to return. */ + return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL)); + } } else { - kr_assert(false && "Repeated protocol layer step"); - //kr_log_debug(PROTOLAYER, "Repeated protocol layer step\n"); + ctx->action = PROTOLAYER_CB_ACTION_CONTINUE; } - if (kr_fails_assert(result == PROTOLAYER_CB_RESULT_MAGIC)) { - /* Callback did not use a continuation function to return. */ - return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL), true); - } if (!ctx->action) { /* Next step is from a callback */ @@ -276,13 +288,12 @@ static int protolayer_step(struct protolayer_cb_ctx *ctx) if (ctx->action == PROTOLAYER_CB_ACTION_BREAK) { return protolayer_cb_ctx_finish( - ctx, PROTOLAYER_RET_NORMAL, true); + ctx, PROTOLAYER_RET_NORMAL); } if (kr_fails_assert(ctx->status == 0)) { /* Status should be zero without a BREAK. */ - return protolayer_cb_ctx_finish( - ctx, kr_error(ECANCELED), true); + return protolayer_cb_ctx_finish(ctx, kr_error(ECANCELED)); } if (ctx->action == PROTOLAYER_CB_ACTION_CONTINUE) { @@ -291,7 +302,7 @@ static int protolayer_step(struct protolayer_cb_ctx *ctx) return protolayer_push(ctx); return protolayer_cb_ctx_finish( - ctx, PROTOLAYER_RET_NORMAL, true); + ctx, PROTOLAYER_RET_NORMAL); } protolayer_cb_ctx_next(ctx); @@ -300,7 +311,7 @@ static int protolayer_step(struct protolayer_cb_ctx *ctx) /* Should never get here */ kr_assert(false && "Invalid layer callback action"); - return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL), true); + return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL)); } } @@ -317,7 +328,7 @@ static int protolayer_manager_submit( struct protolayer_payload payload, const void *target, protolayer_finished_cb cb, void *baton) { - struct protolayer_cb_ctx *ctx = malloc(sizeof(*ctx)); // TODO - mempool? + struct protolayer_cb_ctx *ctx = malloc(manager->cb_ctx_size); kr_require(ctx); if (kr_log_is_debug(PROTOLAYER, NULL)) { @@ -330,14 +341,6 @@ static int protolayer_manager_submit( layer_ix); } - for (size_t i = 0; i < manager->num_layers; i++) { - struct protolayer_data *data = protolayer_manager_get(manager, i); - data->processed = false; - struct protolayer_globals *globals = &protolayer_globals[data->protocol]; - if (globals->iter_init) - globals->iter_init(manager, data); - } - *ctx = (struct protolayer_cb_ctx) { .payload = payload, .target = target, @@ -349,6 +352,20 @@ static int protolayer_manager_submit( .finished_cb_baton = baton }; + for (size_t i = 0; i < manager->num_layers; i++) { + enum protolayer_protocol p = protolayer_grps[manager->grp][i]; + struct protolayer_globals *globals = &protolayer_globals[p]; + struct protolayer_data *iter_data = protolayer_iter_data_get(ctx, i); + if (iter_data) { + bzero(iter_data, globals->iter_size); + iter_data->protocol = p; + iter_data->session = manager->session; + } + + if (globals->iter_init) + globals->iter_init(manager, iter_data); + } + return protolayer_step(ctx); } @@ -372,11 +389,13 @@ static struct protolayer_manager *protolayer_manager_new( struct protolayer_data_param *layer_param, size_t layer_param_count) { - if (kr_fails_assert(grp)) + if (kr_fails_assert(s && grp)) return NULL; size_t num_layers = 0; - size_t size = sizeof(struct protolayer_manager); + size_t manager_size = sizeof(struct protolayer_manager); + size_t cb_ctx_size = sizeof(struct protolayer_cb_ctx); + enum protolayer_protocol *protocols = protolayer_grps[grp]; if (kr_fails_assert(protocols)) return NULL; @@ -387,40 +406,52 @@ static struct protolayer_manager *protolayer_manager_new( num_layers++; if (kr_fails_assert(num_layers)) return NULL; - size_t offsets[num_layers]; - size += sizeof(offsets); + + ssize_t offsets[2 * num_layers]; + manager_size += sizeof(offsets); + + ssize_t *sess_offsets = offsets; + ssize_t *iter_offsets = &offsets[num_layers]; /* Space for layer-specific data, guaranteeing alignment */ - size_t total_data_size = 0; + size_t total_sess_data_size = 0; + size_t total_iter_data_size = 0; for (size_t i = 0; i < num_layers; i++) { - offsets[i] = total_data_size; - total_data_size += ALIGN_TO(sizeof(struct protolayer_data), - CPU_STRUCT_ALIGN); - total_data_size += ALIGN_TO(protolayer_globals[protocols[i]].sess_size, + sess_offsets[i] = protolayer_globals[protocols[i]].sess_size + ? total_sess_data_size : -1; + total_sess_data_size += ALIGN_TO(protolayer_globals[protocols[i]].sess_size, CPU_STRUCT_ALIGN); - total_data_size += ALIGN_TO(protolayer_globals[protocols[i]].iter_size, + + iter_offsets[i] = protolayer_globals[protocols[i]].iter_size + ? total_iter_data_size : -1; + total_iter_data_size += ALIGN_TO(protolayer_globals[protocols[i]].iter_size, CPU_STRUCT_ALIGN); } - size += total_data_size; + manager_size += total_sess_data_size; + cb_ctx_size += total_iter_data_size; /* Allocate and initialize manager */ - struct protolayer_manager *m = calloc(1, size); + struct protolayer_manager *m = calloc(1, manager_size); kr_require(m); m->grp = grp; m->session = s; m->num_layers = num_layers; + m->cb_ctx_size = cb_ctx_size; memcpy(m->data, offsets, sizeof(offsets)); - /* Initialize layer data */ + /* Initialize the layer's session data */ for (size_t i = 0; i < num_layers; i++) { struct protolayer_globals *globals = &protolayer_globals[protocols[i]]; - struct protolayer_data *data = protolayer_manager_get(m, i); - data->manager = m; - data->protocol = protocols[i]; - data->sess_size = ALIGN_TO(globals->sess_size, CPU_STRUCT_ALIGN); + struct protolayer_data *sess_data = protolayer_sess_data_get(m, i); + if (sess_data) { + bzero(sess_data, globals->sess_size); + sess_data->session = s; + sess_data->protocol = protocols[i]; + } + void *param = get_init_param(protocols[i], layer_param, layer_param_count); if (globals->sess_init) - globals->sess_init(m, data, param); + globals->sess_init(m, sess_data, param); } return m; @@ -432,10 +463,12 @@ static void protolayer_manager_free(struct protolayer_manager *m) if (!m) return; for (size_t i = 0; i < m->num_layers; i++) { - struct protolayer_data *data = protolayer_manager_get(m, i); - struct protolayer_globals *globals = &protolayer_globals[data->protocol]; - if (globals->sess_deinit) - globals->sess_deinit(m, data); + enum protolayer_protocol p = protolayer_grps[m->grp][i]; + struct protolayer_globals *globals = &protolayer_globals[p]; + if (globals->sess_deinit) { + struct protolayer_data *sess_data = protolayer_sess_data_get(m, i); + globals->sess_deinit(m, sess_data); + } } free(m); @@ -456,7 +489,7 @@ enum protolayer_cb_result protolayer_break(struct protolayer_cb_ctx *ctx, int st { ctx->status = status; if (ctx->async_mode) { - protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL, true); + protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL); } else { ctx->action = PROTOLAYER_CB_ACTION_BREAK; } @@ -917,12 +950,14 @@ 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--) { - struct protolayer_data *data = protolayer_manager_get(m, i); - struct protolayer_globals *globals = &protolayer_globals[data->protocol]; - if (globals->event_wrap) - cont = globals->event_wrap(event, &baton, m, data); - else + enum protolayer_protocol p = protolayer_grps[s->layers->grp][i]; + struct protolayer_globals *globals = &protolayer_globals[p]; + if (globals->event_wrap) { + struct protolayer_data *sess_data = protolayer_sess_data_get(m, i); + cont = globals->event_wrap(event, &baton, m, sess_data); + } else { cont = true; + } if (!cont) return; @@ -936,12 +971,14 @@ 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++) { - struct protolayer_data *data = protolayer_manager_get(m, i); - struct protolayer_globals *globals = &protolayer_globals[data->protocol]; - if (globals->event_unwrap) - cont = globals->event_unwrap(event, &baton, m, data); - else + enum protolayer_protocol p = protolayer_grps[s->layers->grp][i]; + struct protolayer_globals *globals = &protolayer_globals[p]; + if (globals->event_unwrap) { + struct protolayer_data *sess_data = protolayer_sess_data_get(m, i); + cont = globals->event_unwrap(event, &baton, m, sess_data); + } else { cont = true; + } if (!cont) return; diff --git a/daemon/session2.h b/daemon/session2.h index a7b496f02..50f18cb93 100644 --- a/daemon/session2.h +++ b/daemon/session2.h @@ -240,6 +240,10 @@ struct protolayer_cb_ctx { struct protolayer_manager *manager; int status; enum protolayer_cb_action action; + + /** This contains variably-sized layer-specific data. See `struct + * protolayer_manager::data`. */ + alignas(CPU_STRUCT_ALIGN) char data[]; }; /** Convenience function to get a buffer-type payload. */ @@ -285,33 +289,17 @@ static inline struct protolayer_payload protolayer_wire_buf(struct wire_buf *wir * to be reused. */ struct protolayer_payload protolayer_as_buffer(const struct protolayer_payload *payload); +/** Mandatory header members for any layer-specific data. */ +#define PROTOLAYER_DATA_HEADER() struct {\ + enum protolayer_protocol protocol;\ + struct session2 *session; /**< Pointer to the owner session. */\ +} -/** Per-session layer-specific data - generic struct. */ +/** Layer-specific data - generic struct. */ struct protolayer_data { - enum protolayer_protocol protocol; - size_t sess_size; /**< Size of the session data (aligned). */ - size_t iter_size; /**< Size of the iteration data (aligned). */ - struct protolayer_manager *manager; /**< Pointer to the owner manager. */ - bool processed : 1; /**< Internal safeguard so that the layer does not - * get executed multiple times on the same buffer. */ - alignas(CPU_STRUCT_ALIGN) uint8_t data[]; /**< Memory for the layer-specific structs. */ + PROTOLAYER_DATA_HEADER(); }; -/** Get a pointer to the session data of the layer. This data shares - * its lifetime with a session. */ -static inline void *protolayer_sess_data(struct protolayer_data *d) -{ - return d->data; -} - -/** Gets a pointer to the iteration data of the layer. This data shares its - * lifetime with an iteration through layers; it is also kept intact when - * an iteration ends with a `_WAIT` action. */ -static inline void *protolayer_iter_data(struct protolayer_data *d) -{ - return d->data + d->sess_size; -} - /** Return value of `protolayer_cb` callbacks. To be generated by continuation * functions, never returned directly. */ enum protolayer_cb_result { @@ -324,7 +312,9 @@ enum protolayer_cb_result { * call one of the *layer sequence return functions*. The pointed-to function * must return the result of such a return function. */ typedef enum protolayer_cb_result (*protolayer_cb)( - struct protolayer_data *layer, struct protolayer_cb_ctx *ctx); + void *sess_data, + void *iter_data, + struct protolayer_cb_ctx *ctx); /** Function type for `event_wrap` and `event_unwrap` callbacks of layers. * `baton` always points to some memory; it may be modified accommodate for @@ -335,7 +325,7 @@ typedef enum protolayer_cb_result (*protolayer_cb)( typedef bool (*protolayer_event_cb)(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer); + void *sess_data); /** Function type for initialization callbacks of layer session data, with * `param`, if any is passed to the layer. @@ -343,7 +333,7 @@ typedef bool (*protolayer_event_cb)(enum protolayer_event_type event, * Returning 0 means success, other return values mean error and halt the * initialization. */ typedef int (*protolayer_data_sess_init_cb)(struct protolayer_manager *manager, - struct protolayer_data *layer, + void *data, void *param); /** Function type for (de)initialization callbacks of layers. @@ -351,18 +341,33 @@ typedef int (*protolayer_data_sess_init_cb)(struct protolayer_manager *manager, * Returning 0 means success, other return values mean error and halt the * initialization. */ typedef int (*protolayer_data_cb)(struct protolayer_manager *manager, - struct protolayer_data *layer); + void *data); /** A collection of protocol layers and their layer-specific data. */ struct protolayer_manager { enum protolayer_grp grp; - /* TODO: move iter data to `struct protolayer_cb_ctx` */ - bool iter_data_inited : 1; /**< True: layers' iteration data is - * initialized (e.g. from a previous - * iteration). */ struct session2 *session; size_t num_layers; - char data[]; + size_t cb_ctx_size; + + /** The following flexible array has basically this structure: + * + * struct { + * size_t sess_offsets[num_layers]; + * size_t iter_offsets[num_layers]; + * variably-sized-data sess_data[num_layers]; + * } + * + * It is done this way, because different layer groups will have + * different numbers of layers and differently-sized layer-specific + * data. C does not have a convenient way to define this in structs, so + * we do it via this flexible array. + * + * `sess_offsets` determines data offsets in `sess_data`. + * + * `iter_offsets` determines data offsets in + * `struct protolayer_cb_ctx::data`. */ + alignas(CPU_STRUCT_ALIGN) char data[]; }; /** Initialization parameters for protocol layer session data. */ diff --git a/daemon/tls.c b/daemon/tls.c index 0ec2d4e73..e6def676d 100644 --- a/daemon/tls.c +++ b/daemon/tls.c @@ -54,6 +54,7 @@ typedef int (*tls_handshake_cb) (struct session2 *session, int status); typedef queue_t(struct protolayer_cb_ctx *) pl_cb_ctx_queue_t; struct pl_tls_sess_data { + PROTOLAYER_DATA_HEADER(); bool client_side; gnutls_session_t tls_session; tls_hs_state_t handshake_state; @@ -125,8 +126,7 @@ static size_t count_avail_payload(pl_cb_ctx_queue_t *queue) static ssize_t kres_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len) { - struct protolayer_data *layer = h; - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); + struct pl_tls_sess_data *tls = h; if (kr_fails_assert(tls)) { errno = EFAULT; return -1; @@ -223,7 +223,7 @@ static ssize_t kres_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len) } struct kres_gnutls_push_ctx { - struct protolayer_data *layer; + void *sess_data; struct iovec iov[]; }; @@ -231,7 +231,7 @@ static void kres_gnutls_push_finished(int status, struct session2 *session, const void *target, void *baton) { struct kres_gnutls_push_ctx *push_ctx = baton; - struct pl_tls_sess_data *tls = protolayer_sess_data(push_ctx->layer); + struct pl_tls_sess_data *tls = push_ctx->sess_data; while (queue_len(tls->wrap_queue)) { struct protolayer_cb_ctx *ctx = queue_head(tls->wrap_queue); protolayer_break(ctx, kr_ok()); @@ -242,8 +242,7 @@ static void kres_gnutls_push_finished(int status, struct session2 *session, static ssize_t kres_gnutls_vec_push(gnutls_transport_ptr_t h, const giovec_t * iov, int iovcnt) { - struct protolayer_data *layer = h; - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); + struct pl_tls_sess_data *tls = h; if (kr_fails_assert(tls)) { errno = EFAULT; return -1; @@ -260,10 +259,10 @@ static ssize_t kres_gnutls_vec_push(gnutls_transport_ptr_t h, const giovec_t * i struct kres_gnutls_push_ctx *push_ctx = malloc(sizeof(*push_ctx) + sizeof(struct iovec[iovcnt])); kr_require(push_ctx); - push_ctx->layer = layer; + push_ctx->sess_data = tls; memcpy(push_ctx->iov, iov, sizeof(struct iovec[iovcnt])); - session2_wrap_after(layer->manager->session, PROTOLAYER_TLS, + session2_wrap_after(tls->session, PROTOLAYER_TLS, protolayer_iovec(push_ctx->iov, iovcnt), NULL, kres_gnutls_push_finished, push_ctx); @@ -883,8 +882,7 @@ static int client_verify_certificate(gnutls_session_t tls_session) static int tls_pull_timeout_func(gnutls_transport_ptr_t h, unsigned int ms) { - struct protolayer_data *layer = h; - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); + struct pl_tls_sess_data *tls = h; if (kr_fails_assert(tls)) { errno = EFAULT; return -1; @@ -919,9 +917,8 @@ static int pl_tls_sess_data_deinit(struct pl_tls_sess_data *tls) } static int pl_tls_sess_server_init(struct protolayer_manager *manager, - struct protolayer_data *layer) + struct pl_tls_sess_data *tls) { - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); if (kr_fails_assert(the_worker && the_engine)) return kr_error(EINVAL); @@ -990,7 +987,7 @@ static int pl_tls_sess_server_init(struct protolayer_manager *manager, gnutls_transport_set_pull_function(tls->tls_session, kres_gnutls_pull); gnutls_transport_set_vec_push_function(tls->tls_session, kres_gnutls_vec_push); - gnutls_transport_set_ptr(tls->tls_session, layer); + gnutls_transport_set_ptr(tls->tls_session, tls); if (the_network->tls_session_ticket_ctx) { tls_session_ticket_enable(the_network->tls_session_ticket_ctx, @@ -1001,10 +998,9 @@ static int pl_tls_sess_server_init(struct protolayer_manager *manager, } static int pl_tls_sess_client_init(struct protolayer_manager *manager, - struct protolayer_data *layer, + struct pl_tls_sess_data *tls, tls_client_param_t *param) { - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); unsigned int flags = GNUTLS_CLIENT | GNUTLS_NONBLOCK #ifdef GNUTLS_ENABLE_FALSE_START | GNUTLS_ENABLE_FALSE_START @@ -1051,37 +1047,35 @@ static int pl_tls_sess_client_init(struct protolayer_manager *manager, gnutls_transport_set_pull_function(tls->tls_session, kres_gnutls_pull); gnutls_transport_set_vec_push_function(tls->tls_session, kres_gnutls_vec_push); - gnutls_transport_set_ptr(tls->tls_session, layer); + gnutls_transport_set_ptr(tls->tls_session, tls); return kr_ok(); } static int pl_tls_sess_init(struct protolayer_manager *manager, - struct protolayer_data *layer, + void *sess_data, void *param) { - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); - *tls = (struct pl_tls_sess_data){0}; + struct pl_tls_sess_data *tls = sess_data; manager->session->secure = true; queue_init(tls->unwrap_queue); queue_init(tls->wrap_queue); if (manager->session->outgoing) - return pl_tls_sess_client_init(manager, layer, param); + return pl_tls_sess_client_init(manager, tls, param); else - return pl_tls_sess_server_init(manager, layer); + return pl_tls_sess_server_init(manager, tls); } static int pl_tls_sess_deinit(struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); - return pl_tls_sess_data_deinit(tls); + return pl_tls_sess_data_deinit(sess_data); } -static enum protolayer_cb_result pl_tls_unwrap(struct protolayer_data *layer, +static enum protolayer_cb_result pl_tls_unwrap(void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); + struct pl_tls_sess_data *tls = sess_data; struct session2 *s = ctx->manager->session; queue_push(tls->unwrap_queue, ctx); @@ -1172,8 +1166,7 @@ static enum protolayer_cb_result pl_tls_unwrap(struct protolayer_data *layer, return protolayer_continue(ctx); } -static ssize_t pl_tls_submit(struct protolayer_data *layer, - gnutls_session_t tls_session, +static ssize_t pl_tls_submit(gnutls_session_t tls_session, struct protolayer_payload payload) { if (payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) @@ -1204,15 +1197,15 @@ static ssize_t pl_tls_submit(struct protolayer_data *layer, return kr_error(EINVAL); } -static enum protolayer_cb_result pl_tls_wrap(struct protolayer_data *layer, +static enum protolayer_cb_result pl_tls_wrap(void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); + struct pl_tls_sess_data *tls = sess_data; gnutls_session_t tls_session = tls->tls_session; gnutls_record_cork(tls_session); - ssize_t submitted = pl_tls_submit(layer, tls_session, ctx->payload); + ssize_t submitted = pl_tls_submit(tls_session, ctx->payload); if (submitted < 0) { VERBOSE_MSG(tls->client_side, "pl_tls_submit failed: %s (%zd)\n", gnutls_strerror_name(submitted), submitted); @@ -1275,10 +1268,10 @@ static bool pl_tls_client_connect_start(struct pl_tls_sess_data *tls, static bool pl_tls_event_unwrap(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { struct session2 *s = manager->session; - struct pl_tls_sess_data *tls = protolayer_sess_data(layer); + struct pl_tls_sess_data *tls = sess_data; if (event == PROTOLAYER_EVENT_CLOSE) { tls_close(tls, s, true); /* WITH gnutls_bye */ @@ -1306,7 +1299,7 @@ static bool pl_tls_event_unwrap(enum protolayer_event_type event, static bool pl_tls_event_wrap(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) { the_worker->stats.err_tls += 1; diff --git a/daemon/worker.c b/daemon/worker.c index b348f2201..b1ba883e3 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1881,7 +1881,7 @@ static inline knot_pkt_t *produce_packet(char *buf, size_t buf_len) static bool pl_dns_dgram_event_unwrap(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { if (event != PROTOLAYER_EVENT_TIMEOUT) return true; @@ -1910,7 +1910,7 @@ static bool pl_dns_dgram_event_unwrap(enum protolayer_event_type event, } static enum protolayer_cb_result pl_dns_dgram_unwrap( - struct protolayer_data *layer, struct protolayer_cb_ctx *ctx) + void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { struct session2 *session = ctx->manager->session; @@ -1960,11 +1960,13 @@ static enum protolayer_cb_result pl_dns_dgram_unwrap( } struct pl_dns_stream_sess_data { + PROTOLAYER_DATA_HEADER(); bool single : 1; /**< True: Stream only allows a single packet */ bool produced : 1; /**< True: At least one packet has been produced */ }; struct pl_dns_stream_iter_data { + PROTOLAYER_DATA_HEADER(); struct { knot_mm_t *pool; void *mem; @@ -1982,35 +1984,35 @@ static void pl_dns_stream_sess_init_common(struct session2 *session, } static int pl_dns_mstream_sess_init(struct protolayer_manager *manager, - struct protolayer_data *layer, + void *sess_data, void *param) { - struct pl_dns_stream_sess_data *stream = protolayer_sess_data(layer); + struct pl_dns_stream_sess_data *stream = sess_data; pl_dns_stream_sess_init_common(manager->session, stream, false); return kr_ok(); } static int pl_dns_sstream_sess_init(struct protolayer_manager *manager, - struct protolayer_data *layer, + void *sess_data, void *param) { - struct pl_dns_stream_sess_data *stream = protolayer_sess_data(layer); + struct pl_dns_stream_sess_data *stream = sess_data; pl_dns_stream_sess_init_common(manager->session, stream, true); return kr_ok(); } static int pl_dns_stream_iter_init(struct protolayer_manager *manager, - struct protolayer_data *layer) + void *iter_data) { - struct pl_dns_stream_iter_data *stream = protolayer_iter_data(layer); + struct pl_dns_stream_iter_data *stream = iter_data; *stream = (struct pl_dns_stream_iter_data){0}; return kr_ok(); } static int pl_dns_stream_iter_deinit(struct protolayer_manager *manager, - struct protolayer_data *layer) + void *iter_data) { - struct pl_dns_stream_iter_data *stream = protolayer_iter_data(layer); + struct pl_dns_stream_iter_data *stream = iter_data; mm_free(stream->sent.pool, stream->sent.mem); return kr_ok(); } @@ -2190,7 +2192,7 @@ static bool pl_dns_stream_disconnected(struct session2 *session) static bool pl_dns_stream_event_unwrap(enum protolayer_event_type event, void **baton, struct protolayer_manager *manager, - struct protolayer_data *layer) + void *sess_data) { struct session2 *session = manager->session; if (session->closing) @@ -2231,7 +2233,7 @@ static knot_pkt_t *produce_stream_packet(struct wire_buf *wb) } static enum protolayer_cb_result pl_dns_stream_unwrap( - struct protolayer_data *layer, struct protolayer_cb_ctx *ctx) + void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)) { /* DNS stream only works with a wire buffer */ @@ -2239,12 +2241,12 @@ static enum protolayer_cb_result pl_dns_stream_unwrap( } struct session2 *session = ctx->manager->session; - struct pl_dns_stream_sess_data *stream = protolayer_sess_data(layer); + struct pl_dns_stream_sess_data *stream_sess = sess_data; struct wire_buf *wb = ctx->payload.wire_buf; knot_pkt_t *pkt; while ((pkt = produce_stream_packet(wb))) { - if (stream->single && stream->produced) { + if (stream_sess->single && stream_sess->produced) { if (kr_log_is_debug(WORKER, NULL)) { kr_log_debug(WORKER, "Unexpected extra data from %s\n", kr_straddr(ctx->comm.src_addr)); @@ -2254,7 +2256,7 @@ static enum protolayer_cb_result pl_dns_stream_unwrap( return protolayer_break(ctx, KNOT_EMALF); } - stream->produced = true; + stream_sess->produced = true; if (!pkt) return protolayer_break(ctx, KNOT_EMALF); @@ -2276,9 +2278,9 @@ struct sized_iovs { }; static enum protolayer_cb_result pl_dns_stream_wrap( - struct protolayer_data *layer, struct protolayer_cb_ctx *ctx) + void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx) { - struct pl_dns_stream_iter_data *stream = protolayer_iter_data(layer); + struct pl_dns_stream_iter_data *stream = iter_data; struct session2 *s = ctx->manager->session; if (kr_fails_assert(!stream->sent.mem))