From: Oto Šťáva Date: Thu, 23 May 2024 15:33:46 +0000 (+0200) Subject: daemon: merge protolayer_manager and session2 into one struct X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fenvironments%2Fdocs-develop-nits-2dntdj%2Fdeployments%2F4187;p=thirdparty%2Fknot-resolver.git daemon: merge protolayer_manager and session2 into one struct It actually made no real sense to have these two structs separated, it only introduced an extra layer of indirection and many layers actually needed to access both anyway. This should simplify things considerably. --- diff --git a/daemon/http.c b/daemon/http.c index 8509f2bc4..61ebcf9e7 100644 --- a/daemon/http.c +++ b/daemon/http.c @@ -836,7 +836,7 @@ static ssize_t read_callback(nghttp2_session *h2, int32_t stream_id, uint8_t *bu return send; } -static int pl_http_sess_init(struct protolayer_manager *manager, +static int pl_http_sess_init(struct session2 *session, void *data, void *param) { struct pl_http_sess_data *http = data; @@ -868,17 +868,17 @@ static int pl_http_sess_init(struct protolayer_manager *manager, http->current_method = HTTP_METHOD_NONE; http->uri_path = NULL; http->status = HTTP_STATUS_OK; - wire_buf_init(&http->wire_buf, manager->wire_buf.size); + wire_buf_init(&http->wire_buf, session->wire_buf.size); ret = nghttp2_session_server_new(&http->h2, callbacks, http); if (ret < 0) goto exit_callbacks; nghttp2_submit_settings(http->h2, NGHTTP2_FLAG_NONE, iv, ARRAY_SIZE(iv)); - struct sockaddr *peer = session2_get_peer(manager->session); + struct sockaddr *peer = session2_get_peer(session); kr_log_debug(DOH, "[%p] h2 session created for %s\n", (void *)http->h2, kr_straddr(peer)); - manager->session->custom_emalf_handling = true; + session->custom_emalf_handling = true; ret = kr_ok(); @@ -903,8 +903,7 @@ static int stream_write_data_break_err(trie_val_t *val, void *baton) return 0; } -static int pl_http_sess_deinit(struct protolayer_manager *manager, - void *data) +static int pl_http_sess_deinit(struct session2 *session, void *data) { struct pl_http_sess_data *http = data; @@ -1002,7 +1001,7 @@ static enum protolayer_iter_cb_result pl_http_wrap( static enum protolayer_event_cb_result pl_http_event_unwrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *session, void *sess_data) { struct pl_http_sess_data *http = sess_data; @@ -1014,7 +1013,7 @@ static enum protolayer_event_cb_result pl_http_event_unwrap( return PROTOLAYER_EVENT_PROPAGATE; } -static void pl_http_request_init(struct protolayer_manager *manager, +static void pl_http_request_init(struct session2 *session, struct kr_request *req, void *sess_data) { diff --git a/daemon/io.c b/daemon/io.c index dfad835e7..d219f592b 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -49,7 +49,7 @@ static void check_bufsize(uv_handle_t* handle) static void handle_getbuf(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { struct session2 *s = handle->data; - struct wire_buf *wb = &s->layers->wire_buf; + struct wire_buf *wb = &s->wire_buf; buf->base = wire_buf_free_space(wb); buf->len = wire_buf_free_space_length(wb); @@ -58,7 +58,7 @@ static void handle_getbuf(uv_handle_t* handle, size_t suggested_size, uv_buf_t* static void udp_on_unwrapped(int status, struct session2 *session, const struct comm_info *comm, void *baton) { - wire_buf_reset(&session->layers->wire_buf); + wire_buf_reset(&session->wire_buf); } void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, @@ -87,9 +87,9 @@ void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, return; } - int ret = wire_buf_consume(&s->layers->wire_buf, nread); + int ret = wire_buf_consume(&s->wire_buf, nread); if (ret) { - wire_buf_reset(&s->layers->wire_buf); + wire_buf_reset(&s->wire_buf); return; } @@ -97,7 +97,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_payload_wire_buf(&s->layers->wire_buf, true), + session2_unwrap(s, protolayer_payload_wire_buf(&s->wire_buf, true), &in_comm, udp_on_unwrapped, NULL); } @@ -138,7 +138,7 @@ static int family_to_freebind_option(sa_family_t sa_family, int *level, int *nam static enum protolayer_event_cb_result pl_udp_event_wrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *session, void *sess_data) { if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) { the_worker->stats.err_udp += 1; @@ -153,7 +153,7 @@ static enum protolayer_event_cb_result pl_udp_event_wrap( static enum protolayer_event_cb_result pl_tcp_event_wrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *session, void *sess_data) { if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) { the_worker->stats.err_tcp += 1; @@ -306,17 +306,17 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) return; } - if (kr_fails_assert(buf->base == wire_buf_free_space(&s->layers->wire_buf))) { + if (kr_fails_assert(buf->base == wire_buf_free_space(&s->wire_buf))) { return; } - int ret = wire_buf_consume(&s->layers->wire_buf, nread); + int ret = wire_buf_consume(&s->wire_buf, nread); if (ret) { - wire_buf_reset(&s->layers->wire_buf); + wire_buf_reset(&s->wire_buf); return; } - session2_unwrap(s, protolayer_payload_wire_buf(&s->layers->wire_buf, false), + session2_unwrap(s, protolayer_payload_wire_buf(&s->wire_buf, false), NULL, NULL, NULL); } diff --git a/daemon/proxyv2.c b/daemon/proxyv2.c index 1b61f20f4..5f2147ce8 100644 --- a/daemon/proxyv2.c +++ b/daemon/proxyv2.c @@ -325,7 +325,7 @@ static enum protolayer_iter_cb_result pl_proxyv2_dgram_unwrap( return protolayer_break(ctx, kr_error(EINVAL)); } - struct session2 *s = ctx->manager->session; + struct session2 *s = ctx->session; struct pl_proxyv2_dgram_iter_data *udp = iter_data; char *data = ctx->payload.buffer.buf; @@ -385,12 +385,11 @@ struct pl_proxyv2_stream_sess_data { bool has_proxy : 1; }; -static int pl_proxyv2_stream_sess_init(struct protolayer_manager *manager, - void *data, - void *param) +static int pl_proxyv2_stream_sess_init(struct session2 *session, + void *data, void *param) { - struct sockaddr *peer = session2_get_peer(manager->session); - manager->session->comm = (struct comm_info) { + struct sockaddr *peer = session2_get_peer(session); + session->comm = (struct comm_info) { .comm_addr = peer, .src_addr = peer }; @@ -400,7 +399,7 @@ static int pl_proxyv2_stream_sess_init(struct protolayer_manager *manager, static enum protolayer_iter_cb_result pl_proxyv2_stream_unwrap( void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx) { - struct session2 *s = ctx->manager->session; + struct session2 *s = ctx->session; struct pl_proxyv2_stream_sess_data *tcp = sess_data; struct sockaddr *peer = session2_get_peer(s); @@ -411,7 +410,7 @@ static enum protolayer_iter_cb_result pl_proxyv2_stream_unwrap( char *data = wire_buf_data(ctx->payload.wire_buf); /* layer's or session's wirebuf */ ssize_t data_len = wire_buf_data_length(ctx->payload.wire_buf); - struct comm_info *comm = &ctx->manager->session->comm; + struct comm_info *comm = &ctx->session->comm; if (!s->outgoing && !tcp->had_data && proxy_header_present(data, data_len)) { if (!proxy_allowed(comm->src_addr)) { if (kr_log_is_debug(IO, NULL)) { @@ -459,7 +458,7 @@ static enum protolayer_iter_cb_result pl_proxyv2_stream_unwrap( } tcp->had_data = true; - ctx->comm = ctx->manager->session->comm; + ctx->comm = ctx->session->comm; return protolayer_continue(ctx); } diff --git a/daemon/session2.c b/daemon/session2.c index 7ce0dddf1..ca06e47be 100644 --- a/daemon/session2.c +++ b/daemon/session2.c @@ -345,15 +345,15 @@ bool protolayer_queue_has_payload(const protolayer_iter_ctx_queue_t *queue) /** 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) + struct session2 *s, size_t layer_ix) { - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + const struct protolayer_grp *grp = &protolayer_grps[s->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 * grp->num_layers * sizeof(*offsets)]; + /* See doc comment of `struct session2::layer_data` */ + const ssize_t *offsets = (ssize_t *)s->layer_data; + char *pl_data_beg = &s->layer_data[2 * grp->num_layers * sizeof(*offsets)]; ssize_t offset = offsets[layer_ix]; if (offset < 0) /* No session data for this layer */ @@ -367,13 +367,13 @@ static inline struct protolayer_data *protolayer_sess_data_get( static inline struct protolayer_data *protolayer_iter_data_get( struct protolayer_iter_ctx *ctx, size_t layer_ix) { - struct protolayer_manager *m = ctx->manager; - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + struct session2 *s = ctx->session; + const struct protolayer_grp *grp = &protolayer_grps[s->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[grp->num_layers * sizeof(*offsets)]; + /* See doc comment of `struct session2::layer_data` */ + const ssize_t *offsets = (ssize_t *)&s->layer_data[grp->num_layers * sizeof(*offsets)]; ssize_t offset = offsets[layer_ix]; if (offset < 0) /* No iteration data for this layer */ @@ -382,10 +382,10 @@ static inline struct protolayer_data *protolayer_iter_data_get( return (struct protolayer_data *)(ctx->data + offset); } -static inline ssize_t protolayer_manager_get_protocol( - struct protolayer_manager *m, enum protolayer_type protocol) +static inline ssize_t session2_get_protocol( + struct session2 *s, enum protolayer_type protocol) { - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + const struct protolayer_grp *grp = &protolayer_grps[s->proto]; for (ssize_t i = 0; i < grp->num_layers; i++) { enum protolayer_type found = grp->layers[i]; if (protocol == found) @@ -398,7 +398,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) - ? protolayer_grps[ctx->manager->proto].num_layers - 1 + ? protolayer_grps[ctx->session->proto].num_layers - 1 : 0; return ctx->layer_ix == last_ix; } @@ -421,34 +421,32 @@ static inline const char *layer_name(enum kr_proto grp, ssize_t layer_ix) static inline const char *layer_name_ctx(struct protolayer_iter_ctx *ctx) { - return layer_name(ctx->manager->proto, ctx->layer_ix); + return layer_name(ctx->session->proto, ctx->layer_ix); } 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; - const struct protolayer_globals *globals = &protolayer_globals[m->proto]; - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + struct session2 *s = ctx->session; + const struct protolayer_globals *globals = &protolayer_globals[s->proto]; + const struct protolayer_grp *grp = &protolayer_grps[s->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); + globals->iter_deinit(ctx, d); } if (ret) - VERBOSE_LOG(session, "layer context of group '%s' (on %u: %s) ended with return code %d\n", - kr_proto_name(ctx->manager->proto), + VERBOSE_LOG(s, "layer context of group '%s' (on %u: %s) ended with return code %d\n", + kr_proto_name(s->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->proto), + VERBOSE_LOG(s, "iteration of group '%s' (on %u: %s) ended with status %d\n", + kr_proto_name(s->proto), ctx->layer_ix, layer_name_ctx(ctx), ctx->status); if (ctx->finished_cb) - ctx->finished_cb(ret, session, &ctx->comm, + ctx->finished_cb(ret, s, &ctx->comm, ctx->finished_cb_baton); protolayer_buffer_list_deinit(&ctx->async_buffer_list); @@ -467,7 +465,7 @@ static void protolayer_push_finished(int status, struct session2 *s, const struc /** Pushes the specified protocol layer's payload to the session's transport. */ static int protolayer_push(struct protolayer_iter_ctx *ctx) { - struct session2 *session = ctx->manager->session; + struct session2 *session = ctx->session; if (ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) { ctx->payload = protolayer_payload_as_buffer(&ctx->payload); @@ -520,10 +518,10 @@ static void protolayer_payload_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->proto < KR_PROTO_COUNT)) + if (kr_fails_assert(ctx->session->proto < KR_PROTO_COUNT)) return kr_error(EFAULT); - enum protolayer_type protocol = protolayer_grps[ctx->manager->proto].layers[ctx->layer_ix]; + enum protolayer_type protocol = protolayer_grps[ctx->session->proto].layers[ctx->layer_ix]; struct protolayer_globals *globals = &protolayer_globals[protocol]; ctx->async_mode = false; @@ -533,14 +531,14 @@ static int protolayer_step(struct protolayer_iter_ctx *ctx) protolayer_iter_cb cb = (ctx->direction == PROTOLAYER_UNWRAP) ? globals->unwrap : globals->wrap; - if (ctx->manager->session->closing) { + if (ctx->session->closing) { return protolayer_iter_ctx_finish( ctx, kr_error(ECANCELED)); } if (cb) { struct protolayer_data *sess_data = protolayer_sess_data_get( - ctx->manager, ctx->layer_ix); + ctx->session, ctx->layer_ix); struct protolayer_data *iter_data = protolayer_iter_data_get( ctx, ctx->layer_ix); enum protolayer_iter_cb_result result = cb(sess_data, iter_data, ctx); @@ -591,54 +589,54 @@ static int protolayer_step(struct protolayer_iter_ctx *ctx) /** Submits the specified buffer to the sequence of layers represented by the * specified protolayer manager. The sequence will be processed in the - * specified direction. + * specified `direction`, starting by the layer specified by `layer_ix`. * * Returns PROTOLAYER_RET_NORMAL when all layers have finished, * PROTOLAYER_RET_ASYNC when some layers are asynchronous and waiting for * continuation, or a negative number for errors (kr_error). */ -static int protolayer_manager_submit( - struct protolayer_manager *manager, +static int session2_submit( + struct session2 *session, enum protolayer_direction direction, size_t layer_ix, struct protolayer_payload payload, const struct comm_info *comm, protolayer_finished_cb cb, void *baton) { - if (manager->session->closing) + if (session->closing) return kr_error(ECANCELED); - if (kr_fails_assert(manager->proto < KR_PROTO_COUNT)) + if (kr_fails_assert(session->proto < KR_PROTO_COUNT)) return kr_error(EFAULT); - struct protolayer_iter_ctx *ctx = malloc(manager->cb_ctx_size); + struct protolayer_iter_ctx *ctx = malloc(session->iter_ctx_size); kr_require(ctx); - VERBOSE_LOG(manager->session, + VERBOSE_LOG(session, "%s submitted to grp '%s' in %s direction (%zu: %s)\n", protolayer_payload_name(payload.type), - kr_proto_name(manager->proto), + kr_proto_name(session->proto), (direction == PROTOLAYER_UNWRAP) ? "unwrap" : "wrap", - layer_ix, layer_name(manager->proto, layer_ix)); + layer_ix, layer_name(session->proto, layer_ix)); *ctx = (struct protolayer_iter_ctx) { .payload = payload, - .comm = (comm) ? *comm : manager->session->comm, + .comm = (comm) ? *comm : session->comm, .direction = direction, .layer_ix = layer_ix, - .manager = manager, + .session = session, .finished_cb = cb, .finished_cb_baton = baton }; - const struct protolayer_grp *grp = &protolayer_grps[manager->proto]; + const struct protolayer_grp *grp = &protolayer_grps[session->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); - iter_data->session = manager->session; + iter_data->session = session; } if (globals->iter_init) - globals->iter_init(manager, ctx, iter_data); + globals->iter_init(ctx, iter_data); } return protolayer_step(ctx); @@ -657,99 +655,6 @@ static void *get_init_param(enum protolayer_type p, return NULL; } -/** Allocates and initializes a new manager. */ -static struct protolayer_manager *protolayer_manager_new( - struct session2 *s, - enum kr_proto proto, - struct protolayer_data_param *layer_param, - size_t layer_param_count) -{ - if (kr_fails_assert(s && proto)) - return NULL; - - size_t manager_size = sizeof(struct protolayer_manager); - size_t cb_ctx_size = sizeof(struct protolayer_iter_ctx); - - 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 * grp->num_layers]; - manager_size += sizeof(offsets); - - ssize_t *sess_offsets = offsets; - 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 < 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); - - iter_offsets[i] = g->iter_size ? total_iter_data_size : -1; - total_iter_data_size += ALIGN_TO(g->iter_size, CPU_STRUCT_ALIGN); - - size_t wire_buf_overhead = (g->wire_buf_overhead_cb) - ? g->wire_buf_overhead_cb(s->outgoing) - : g->wire_buf_overhead; - wire_buf_length += wire_buf_overhead; - wire_buf_max_length += MAX(g->wire_buf_max_overhead, wire_buf_overhead); - } - manager_size += total_sess_data_size; - cb_ctx_size += total_iter_data_size; - - /* Allocate and initialize manager */ - struct protolayer_manager *m = calloc(1, manager_size); - kr_require(m); - m->proto = proto; - m->session = s; - m->cb_ctx_size = cb_ctx_size; - memcpy(m->data, offsets, sizeof(offsets)); - - m->wire_buf_max_length = wire_buf_max_length; - int ret = wire_buf_init(&m->wire_buf, wire_buf_length); - kr_require(!ret); - - /* Initialize the layer's session data */ - 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(grp->layers[i], layer_param, layer_param_count); - if (globals->sess_init) - globals->sess_init(m, sess_data, param); - } - - return m; -} - -/** Deinitializes all layer data in the manager and deallocates it. */ -static void protolayer_manager_free(struct protolayer_manager *m) -{ - if (!m) return; - - 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); - } - } - - wire_buf_deinit(&m->wire_buf); - free(m); -} - enum protolayer_iter_cb_result protolayer_continue(struct protolayer_iter_ctx *ctx) { if (ctx->async_mode) { @@ -851,14 +756,48 @@ int wire_buf_reset(struct wire_buf *wb) struct session2 *session2_new(enum session2_transport_type transport_type, - enum kr_proto layer_grp, + enum kr_proto proto, struct protolayer_data_param *layer_param, size_t layer_param_count, bool outgoing) { - kr_require(transport_type && layer_grp); + kr_require(transport_type && proto); + + size_t session_size = sizeof(struct session2); + size_t iter_ctx_size = sizeof(struct protolayer_iter_ctx); + + const struct protolayer_grp *grp = &protolayer_grps[proto]; + if (kr_fails_assert(grp->num_layers)) + return NULL; + + size_t wire_buf_length = 0; + ssize_t offsets[2 * grp->num_layers]; + session_size += sizeof(offsets); + + ssize_t *sess_offsets = offsets; + 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 < 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); + + iter_offsets[i] = g->iter_size ? total_iter_data_size : -1; + total_iter_data_size += ALIGN_TO(g->iter_size, CPU_STRUCT_ALIGN); - struct session2 *s = malloc(sizeof(*s)); + size_t wire_buf_overhead = (g->wire_buf_overhead_cb) + ? g->wire_buf_overhead_cb(outgoing) + : g->wire_buf_overhead; + wire_buf_length += wire_buf_overhead; + } + session_size += total_sess_data_size; + iter_ctx_size += total_iter_data_size; + + struct session2 *s = malloc(session_size); kr_require(s); *s = (struct session2) { @@ -868,24 +807,36 @@ struct session2 *session2_new(enum session2_transport_type transport_type, .log_id = next_log_id++, .outgoing = outgoing, .tasks = trie_create(NULL), - }; - struct protolayer_manager *layers = protolayer_manager_new(s, layer_grp, - layer_param, layer_param_count); - if (!layers) { - free(s); - return NULL; - } - s->layers = layers; + .proto = proto, + .iter_ctx_size = iter_ctx_size, + }; + memcpy(&s->layer_data, offsets, sizeof(offsets)); mm_ctx_mempool(&s->pool, CPU_PAGE_SIZE); queue_init(s->waiting); + int ret = wire_buf_init(&s->wire_buf, wire_buf_length); + kr_require(!ret); - int ret = uv_timer_init(uv_default_loop(), &s->timer); + ret = uv_timer_init(uv_default_loop(), &s->timer); kr_require(!ret); s->timer.data = s; s->uv_count++; /* Session owns the timer */ + /* Initialize the layer's session data */ + 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(s, i); + if (sess_data) { + memset(sess_data, 0, globals->sess_size); + sess_data->session = s; + } + + void *param = get_init_param(grp->layers[i], layer_param, layer_param_count); + if (globals->sess_init) + globals->sess_init(s, sess_data, param); + } + session2_touch(s); return s; @@ -895,7 +846,16 @@ struct session2 *session2_new(enum session2_transport_type transport_type, * and timer are already closed, otherwise may leak resources. */ static void session2_free(struct session2 *s) { - protolayer_manager_free(s->layers); + const struct protolayer_grp *grp = &protolayer_grps[s->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(s, i); + globals->sess_deinit(s, sess_data); + } + } + + wire_buf_deinit(&s->wire_buf); mm_ctx_delete(&s->pool); trie_free(s->tasks); queue_deinit(s->waiting); @@ -1219,8 +1179,8 @@ int session2_unwrap(struct session2 *s, struct protolayer_payload payload, const struct comm_info *comm, protolayer_finished_cb cb, void *baton) { - return protolayer_manager_submit(s->layers, PROTOLAYER_UNWRAP, 0, - payload, comm, cb, baton); + return session2_submit(s, PROTOLAYER_UNWRAP, + 0, payload, comm, cb, baton); } int session2_unwrap_after(struct session2 *s, enum protolayer_type protocol, @@ -1228,19 +1188,19 @@ int session2_unwrap_after(struct session2 *s, enum protolayer_type protocol, const struct comm_info *comm, protolayer_finished_cb cb, void *baton) { - ssize_t layer_ix = protolayer_manager_get_protocol(s->layers, protocol) + 1; + ssize_t layer_ix = session2_get_protocol(s, protocol) + 1; if (layer_ix < 0) return layer_ix; - return protolayer_manager_submit(s->layers, PROTOLAYER_UNWRAP, layer_ix, - payload, comm, cb, baton); + return session2_submit(s, PROTOLAYER_UNWRAP, + layer_ix, payload, comm, cb, baton); } int session2_wrap(struct session2 *s, struct protolayer_payload payload, const struct comm_info *comm, protolayer_finished_cb cb, void *baton) { - return protolayer_manager_submit(s->layers, PROTOLAYER_WRAP, - protolayer_grps[s->layers->proto].num_layers - 1, + return session2_submit(s, PROTOLAYER_WRAP, + protolayer_grps[s->proto].num_layers - 1, payload, comm, cb, baton); } @@ -1249,23 +1209,22 @@ int session2_wrap_after(struct session2 *s, enum protolayer_type protocol, const struct comm_info *comm, protolayer_finished_cb cb, void *baton) { - ssize_t layer_ix = protolayer_manager_get_protocol(s->layers, protocol) - 1; + ssize_t layer_ix = session2_get_protocol(s, protocol) - 1; if (layer_ix < 0) return layer_ix; - return protolayer_manager_submit(s->layers, PROTOLAYER_WRAP, layer_ix, + return session2_submit(s, PROTOLAYER_WRAP, layer_ix, payload, comm, cb, baton); } static void session2_event_wrap(struct session2 *s, enum protolayer_event_type event, void *baton) { bool cont; - struct protolayer_manager *m = s->layers; - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + const struct protolayer_grp *grp = &protolayer_grps[s->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); + struct protolayer_data *sess_data = protolayer_sess_data_get(s, i); + cont = globals->event_wrap(event, &baton, s, sess_data); } else { cont = true; } @@ -1280,13 +1239,12 @@ static void session2_event_wrap(struct session2 *s, enum protolayer_event_type e void session2_event_unwrap(struct session2 *s, ssize_t start_ix, enum protolayer_event_type event, void *baton) { bool cont; - struct protolayer_manager *m = s->layers; - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + const struct protolayer_grp *grp = &protolayer_grps[s->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); + struct protolayer_data *sess_data = protolayer_sess_data_get(s, i); + cont = globals->event_unwrap(event, &baton, s, sess_data); } else { cont = true; } @@ -1312,7 +1270,7 @@ void session2_event(struct session2 *s, enum protolayer_event_type event, void * void session2_event_after(struct session2 *s, enum protolayer_type protocol, enum protolayer_event_type event, void *baton) { - ssize_t start_ix = protolayer_manager_get_protocol(s->layers, protocol); + ssize_t start_ix = session2_get_protocol(s, protocol); if (kr_fails_assert(start_ix >= 0)) return; session2_event_unwrap(s, start_ix + 1, event, baton); @@ -1320,13 +1278,12 @@ 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; - const struct protolayer_grp *grp = &protolayer_grps[m->proto]; + const struct protolayer_grp *grp = &protolayer_grps[s->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); + struct protolayer_data *sess_data = protolayer_sess_data_get(s, i); + globals->request_init(s, req, sess_data); } } } diff --git a/daemon/session2.h b/daemon/session2.h index 985fa31e6..eac8da3d6 100644 --- a/daemon/session2.h +++ b/daemon/session2.h @@ -438,7 +438,7 @@ struct protolayer_iter_ctx { /** The index of the layer that is currently being (or has just been) * processed. */ unsigned int layer_ix; - struct protolayer_manager *manager; + struct session2 *session; /** Status passed to the finish callback. */ int status; enum protolayer_iter_action action; @@ -447,7 +447,7 @@ struct protolayer_iter_ctx { struct protolayer_buffer_list async_buffer_list; /** Contains a sequence of variably-sized CPU-aligned layer-specific - * structs. See `struct protolayer_manager::data`. */ + * structs. See `struct session2::layer_data` for details. */ alignas(CPU_STRUCT_ALIGN) char data[]; }; @@ -570,7 +570,7 @@ enum protolayer_event_cb_result { * stops. */ typedef enum protolayer_event_cb_result (*protolayer_event_cb)( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data); + struct session2 *session, void *sess_data); /** Function type for initialization callbacks of layer session data. * @@ -582,9 +582,8 @@ typedef enum protolayer_event_cb_result (*protolayer_event_cb)( * * Returning 0 means success, other return values mean error and halt the * initialization. */ -typedef int (*protolayer_data_sess_init_cb)(struct protolayer_manager *manager, - void *data, - void *param); +typedef int (*protolayer_data_sess_init_cb)(struct session2 *session, + void *data, void *param); /** Function type for determining the size of a layer's wire buffer overhead. */ typedef size_t (*protolayer_wire_buf_overhead_cb)(bool outgoing); @@ -597,8 +596,7 @@ typedef size_t (*protolayer_wire_buf_overhead_cb)(bool outgoing); * * Returning 0 means success, other return values mean error and halt the * initialization. */ -typedef int (*protolayer_iter_data_cb)(struct protolayer_manager *manager, - struct protolayer_iter_ctx *ctx, +typedef int (*protolayer_iter_data_cb)(struct protolayer_iter_ctx *ctx, void *data); /** Function type for (de)initialization callbacks of layers. @@ -607,53 +605,16 @@ typedef int (*protolayer_iter_data_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, - void *data); +typedef int (*protolayer_data_cb)(struct session2 *session, void *data); /** Function type for (de)initialization callbacks of DNS requests. * * `req` points to the request for initialization. * `sess_data` points to layer-specific session data struct. */ -typedef void (*protolayer_request_cb)(struct protolayer_manager *manager, +typedef void (*protolayer_request_cb)(struct session2 *session, struct kr_request *req, void *sess_data); -/** A collection of protocol layers and their layer-specific data, tied to a - * session. The manager contains a sequence of protocol layers (determined by - * `grp`), which define how the data processed by the session is to be - * interpreted. */ -struct protolayer_manager { - enum kr_proto proto; - struct wire_buf wire_buf; - size_t wire_buf_max_length; - struct session2 *session; - size_t cb_ctx_size; /**< Size of a single callback context, including - * layer-specific per-iteration data. */ - - /** 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_data` is a sequence of variably-sized CPU-aligned - * layer-specific structs. - * - * `sess_offsets` determines data offsets in `sess_data` for pointer - * retrieval. - * - * `iter_offsets` determines data offsets in `struct - * protolayer_iter_ctx::data` for pointer retrieval. */ - alignas(CPU_STRUCT_ALIGN) char data[]; -}; - /** Initialization parameters for protocol layer session data. */ struct protolayer_data_param { enum protolayer_type protocol; /**< Which protocol these parameters @@ -788,8 +749,8 @@ enum session2_transport_type { /** A data unit for a single sequential data source. The data may be organized * as a stream or a sequence of datagrams - this is up to the actual individual - * protocols used by the session, as defined by the `layers` member - see - * `struct protolayer_manager` and the types of its members for more info. + * protocols used by the session - see `enum kr_proto` and + * `protolayer_`-prefixed types and functions for more information. * * A session processes data in two directions: * @@ -822,14 +783,13 @@ struct session2 { }; } transport; - struct protolayer_manager *layers; /**< Protocol layers of this session. */ knot_mm_t pool; uv_timer_t timer; /**< For session-wide timeout events. */ enum protolayer_event_type timer_event; /**< The event fired on timeout. */ trie_t *tasks; /**< List of tasks associated with given session. */ queue_t(struct qr_task *) waiting; /**< List of tasks waiting for * sending to upstream. */ - + struct wire_buf wire_buf; uint32_t log_id; /**< Session ID for logging. */ int uv_count; /**< Number of unclosed libUV handles owned by this @@ -874,6 +834,37 @@ struct session2 { /** If true, session is being rate-limited. One of the protocol layers * is going to be the writer for this flag. */ bool throttled : 1; + + /* Protocol layers */ + + /** The set of protocol layers used by this session. */ + enum kr_proto proto; + /** The size of a single iteration context + * (`struct protolayer_iter_ctx`), including layer-specific data. */ + size_t iter_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_data` is a sequence of variably-sized CPU-aligned + * layer-specific structs. + * + * `sess_offsets` determines data offsets in `sess_data` for pointer + * retrieval. + * + * `iter_offsets` determines data offsets in `struct + * protolayer_iter_ctx::data` for pointer retrieval. */ + alignas(CPU_STRUCT_ALIGN) char layer_data[]; }; /** Allocates and initializes a new session with the specified protocol layer diff --git a/daemon/tls.c b/daemon/tls.c index fd6845181..90271bc8e 100644 --- a/daemon/tls.c +++ b/daemon/tls.c @@ -889,7 +889,7 @@ static int pl_tls_sess_data_deinit(struct pl_tls_sess_data *tls) return kr_ok(); } -static int pl_tls_sess_server_init(struct protolayer_manager *manager, +static int pl_tls_sess_server_init(struct session2 *session, struct pl_tls_sess_data *tls) { if (kr_fails_assert(the_worker && the_engine)) @@ -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->proto]; + const gnutls_datum_t *alpn = &tls_grp_alpn[session->proto]; if (alpn->size) { /* ALPN is a non-empty string */ flags = 0; #if GNUTLS_VERSION_NUMBER >= 0x030500 @@ -987,7 +987,7 @@ static int pl_tls_sess_server_init(struct protolayer_manager *manager, return kr_ok(); } -static int pl_tls_sess_client_init(struct protolayer_manager *manager, +static int pl_tls_sess_client_init(struct session2 *session, struct pl_tls_sess_data *tls, tls_client_param_t *param) { @@ -1042,21 +1042,21 @@ static int pl_tls_sess_client_init(struct protolayer_manager *manager, return kr_ok(); } -static int pl_tls_sess_init(struct protolayer_manager *manager, +static int pl_tls_sess_init(struct session2 *session, void *sess_data, void *param) { struct pl_tls_sess_data *tls = sess_data; - manager->session->secure = true; + session->secure = true; queue_init(tls->unwrap_queue); queue_init(tls->wrap_queue); - if (manager->session->outgoing) - return pl_tls_sess_client_init(manager, tls, param); + if (session->outgoing) + return pl_tls_sess_client_init(session, tls, param); else - return pl_tls_sess_server_init(manager, tls); + return pl_tls_sess_server_init(session, tls); } -static int pl_tls_sess_deinit(struct protolayer_manager *manager, +static int pl_tls_sess_deinit(struct session2 *session, void *sess_data) { return pl_tls_sess_data_deinit(sess_data); @@ -1067,7 +1067,7 @@ static enum protolayer_iter_cb_result pl_tls_unwrap(void *sess_data, void *iter_ { int brstatus = kr_ok(); struct pl_tls_sess_data *tls = sess_data; - struct session2 *s = ctx->manager->session; + struct session2 *s = ctx->session; queue_push(tls->unwrap_queue, ctx); @@ -1278,9 +1278,8 @@ static enum protolayer_event_cb_result pl_tls_client_connect_start( static enum protolayer_event_cb_result pl_tls_event_unwrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *s, void *sess_data) { - struct session2 *s = manager->session; struct pl_tls_sess_data *tls = sess_data; if (event == PROTOLAYER_EVENT_CLOSE) { @@ -1308,7 +1307,7 @@ static enum protolayer_event_cb_result pl_tls_event_unwrap( static enum protolayer_event_cb_result pl_tls_event_wrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *session, void *sess_data) { if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) { the_worker->stats.err_tls += 1; @@ -1321,7 +1320,7 @@ static enum protolayer_event_cb_result pl_tls_event_wrap( return PROTOLAYER_EVENT_PROPAGATE; } -static void pl_tls_request_init(struct protolayer_manager *manager, +static void pl_tls_request_init(struct session2 *session, struct kr_request *req, void *sess_data) { diff --git a/daemon/worker.c b/daemon/worker.c index 31070f0da..a73420458 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1710,12 +1710,11 @@ static inline knot_pkt_t *produce_packet(uint8_t *buf, size_t buf_len) static enum protolayer_event_cb_result pl_dns_dgram_event_unwrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *session, void *sess_data) { if (event != PROTOLAYER_EVENT_GENERAL_TIMEOUT) return PROTOLAYER_EVENT_PROPAGATE; - struct session2 *session = manager->session; if (session2_tasklist_get_len(session) != 1 || !session2_waitinglist_is_empty(session)) return PROTOLAYER_EVENT_PROPAGATE; @@ -1753,7 +1752,7 @@ static size_t pl_dns_dgram_wire_buf_overhead(bool outgoing) static enum protolayer_iter_cb_result pl_dns_dgram_unwrap( void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx) { - struct session2 *session = ctx->manager->session; + struct session2 *session = ctx->session; if (ctx->payload.type == PROTOLAYER_PAYLOAD_IOVEC) { int ret = kr_ok(); @@ -1831,26 +1830,25 @@ struct pl_dns_stream_iter_data { } sent; }; -static int pl_dns_stream_sess_init(struct protolayer_manager *manager, - void *sess_data, void *param) +static int pl_dns_stream_sess_init(struct session2 *session, + void *sess_data, void *param) { /* _UNSIZED_STREAM and _MULTI_STREAM - don't forget to split if needed * at some point */ - manager->session->stream = true; + session->stream = true; return kr_ok(); } -static int pl_dns_single_stream_sess_init(struct protolayer_manager *manager, +static int pl_dns_single_stream_sess_init(struct session2 *session, void *sess_data, void *param) { - manager->session->stream = true; + session->stream = true; struct pl_dns_stream_sess_data *stream = sess_data; stream->single = true; return kr_ok(); } -static int pl_dns_stream_iter_deinit(struct protolayer_manager *manager, - struct protolayer_iter_ctx *ctx, +static int pl_dns_stream_iter_deinit(struct protolayer_iter_ctx *ctx, void *iter_data) { struct pl_dns_stream_iter_data *stream = iter_data; @@ -2046,9 +2044,8 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected( static enum protolayer_event_cb_result pl_dns_stream_event_unwrap( enum protolayer_event_type event, void **baton, - struct protolayer_manager *manager, void *sess_data) + struct session2 *session, void *sess_data) { - struct session2 *session = manager->session; if (session->closing) return PROTOLAYER_EVENT_PROPAGATE; @@ -2056,10 +2053,10 @@ static enum protolayer_event_cb_result pl_dns_stream_event_unwrap( switch (event) { case PROTOLAYER_EVENT_GENERAL_TIMEOUT: - return pl_dns_stream_resolution_timeout(manager->session); + return pl_dns_stream_resolution_timeout(session); case PROTOLAYER_EVENT_CONNECT_TIMEOUT: - return pl_dns_stream_connection_fail(manager->session, + return pl_dns_stream_connection_fail(session, KR_SELECTION_TCP_CONNECT_TIMEOUT); case PROTOLAYER_EVENT_CONNECT: @@ -2069,7 +2066,7 @@ static enum protolayer_event_cb_result pl_dns_stream_event_unwrap( enum kr_selection_error err = (*baton) ? *(enum kr_selection_error *)baton : KR_SELECTION_TCP_CONNECT_FAILED; - return pl_dns_stream_connection_fail(manager->session, err); + return pl_dns_stream_connection_fail(session, err); case PROTOLAYER_EVENT_DISCONNECT: case PROTOLAYER_EVENT_CLOSE: @@ -2171,7 +2168,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_unwrap( } int status = kr_ok(); - struct session2 *session = ctx->manager->session; + struct session2 *session = ctx->session; struct pl_dns_stream_sess_data *stream_sess = sess_data; struct wire_buf *wb = ctx->payload.wire_buf; @@ -2236,7 +2233,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap( void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx) { struct pl_dns_stream_iter_data *stream = iter_data; - struct session2 *s = ctx->manager->session; + struct session2 *s = ctx->session; if (kr_fails_assert(!stream->sent.mem)) return protolayer_break(ctx, kr_error(EINVAL)); @@ -2296,7 +2293,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap( } } -static void pl_dns_stream_request_init(struct protolayer_manager *manager, +static void pl_dns_stream_request_init(struct session2 *session, struct kr_request *req, void *sess_data) {