From: Oto Šťáva Date: Tue, 28 Feb 2023 10:18:36 +0000 (+0100) Subject: daemon: refactor and documentation X-Git-Tag: v6.0.2~42^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e0f4a5bd06905de5a2d72abc0082811f073360f;p=thirdparty%2Fknot-resolver.git daemon: refactor and documentation --- diff --git a/daemon/http.c b/daemon/http.c index ba646b365..aca3a9e0b 100644 --- a/daemon/http.c +++ b/daemon/http.c @@ -389,7 +389,7 @@ static ssize_t send_callback(nghttp2_session *h2, const uint8_t *data, size_t le memcpy(send_ctx->data, data, length); kr_log_debug(DOH, "[%p] send_callback: %p\n", (void *)h2, (void *)send_ctx->data); - session2_wrap_after(http->session, PROTOLAYER_HTTP, + session2_wrap_after(http->session, PROTOLAYER_PROTOCOL_HTTP, protolayer_buffer(send_ctx->data, length), NULL, callback_finished_free_baton, send_ctx); @@ -505,7 +505,7 @@ static int send_data_callback(nghttp2_session *h2, nghttp2_frame *frame, const u dest_iov[cur++] = (struct iovec){ (void *)padding, padlen - 1 }; kr_assert(cur == iovcnt); - int ret = session2_wrap_after(http->session, PROTOLAYER_HTTP, + int ret = session2_wrap_after(http->session, PROTOLAYER_PROTOCOL_HTTP, protolayer_iovec(dest_iov, cur), NULL, callback_finished_free_baton, sdctx); @@ -732,7 +732,7 @@ static int submit_to_wirebuffer(struct pl_http_sess_data *ctx) } ret = 0; - session2_unwrap_after(ctx->session, PROTOLAYER_HTTP, + session2_unwrap_after(ctx->session, PROTOLAYER_PROTOCOL_HTTP, protolayer_wire_buf(wb), NULL, NULL, NULL); cleanup: http_cleanup_stream(ctx); @@ -1032,7 +1032,7 @@ static void pl_http_request_init(struct protolayer_manager *manager, void http_protolayers_init(void) { - protolayer_globals[PROTOLAYER_HTTP] = (struct protolayer_globals) { + protolayer_globals[PROTOLAYER_PROTOCOL_HTTP] = (struct protolayer_globals) { .sess_size = sizeof(struct pl_http_sess_data), .sess_deinit = pl_http_sess_deinit, .wire_buf_overhead = HTTP_MAX_FRAME_SIZE, diff --git a/daemon/io.c b/daemon/io.c index 73ce71bd0..27606c75d 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -348,13 +348,13 @@ static enum protolayer_event_cb_result pl_tcp_event_wrap( void io_protolayers_init(void) { - protolayer_globals[PROTOLAYER_UDP] = (struct protolayer_globals){ + protolayer_globals[PROTOLAYER_PROTOCOL_UDP] = (struct protolayer_globals){ .iter_size = sizeof(struct pl_udp_iter_data), .unwrap = pl_udp_unwrap, .event_wrap = pl_udp_event_wrap, }; - protolayer_globals[PROTOLAYER_TCP] = (struct protolayer_globals){ + protolayer_globals[PROTOLAYER_PROTOCOL_TCP] = (struct protolayer_globals){ .sess_size = sizeof(struct pl_tcp_sess_data), .sess_init = pl_tcp_sess_init, .sess_deinit = pl_tcp_sess_deinit, diff --git a/daemon/session2.c b/daemon/session2.c index e14ade249..85bbd22bd 100644 --- a/daemon/session2.c +++ b/daemon/session2.c @@ -33,39 +33,46 @@ static uint32_t next_log_id = 1; struct protolayer_globals protolayer_globals[PROTOLAYER_PROTOCOL_COUNT] = {{0}}; static const enum protolayer_protocol protolayer_grp_doudp[] = { - PROTOLAYER_UDP, - PROTOLAYER_DNS_DGRAM, - PROTOLAYER_NULL + PROTOLAYER_PROTOCOL_UDP, + PROTOLAYER_PROTOCOL_DNS_DGRAM, + PROTOLAYER_PROTOCOL_NULL }; static const enum protolayer_protocol protolayer_grp_dotcp[] = { - PROTOLAYER_TCP, - PROTOLAYER_DNS_MULTI_STREAM, - PROTOLAYER_NULL + PROTOLAYER_PROTOCOL_TCP, + PROTOLAYER_PROTOCOL_DNS_MULTI_STREAM, + PROTOLAYER_PROTOCOL_NULL }; static const enum protolayer_protocol protolayer_grp_dot[] = { - PROTOLAYER_TCP, - PROTOLAYER_TLS, - PROTOLAYER_DNS_MULTI_STREAM, - PROTOLAYER_NULL + PROTOLAYER_PROTOCOL_TCP, + PROTOLAYER_PROTOCOL_TLS, + PROTOLAYER_PROTOCOL_DNS_MULTI_STREAM, + PROTOLAYER_PROTOCOL_NULL }; static const enum protolayer_protocol protolayer_grp_doh[] = { - PROTOLAYER_TCP, - PROTOLAYER_TLS, - PROTOLAYER_HTTP, - PROTOLAYER_DNS_UNSIZED_STREAM, - PROTOLAYER_NULL + PROTOLAYER_PROTOCOL_TCP, + PROTOLAYER_PROTOCOL_TLS, + PROTOLAYER_PROTOCOL_HTTP, + PROTOLAYER_PROTOCOL_DNS_UNSIZED_STREAM, + PROTOLAYER_PROTOCOL_NULL }; -const char *protolayer_protocol_names[PROTOLAYER_PROTOCOL_COUNT] = { - [PROTOLAYER_NULL] = "(null)", -#define XX(cid) [PROTOLAYER_##cid] = #cid, +const char *protolayer_protocol_name(enum protolayer_protocol p) +{ + switch (p) { + case PROTOLAYER_PROTOCOL_NULL: + return "(null)"; +#define XX(cid) case PROTOLAYER_PROTOCOL_ ## cid: \ + return #cid; PROTOLAYER_PROTOCOL_MAP(XX) #undef XX -}; + default: + return "(invalid)"; + } +} /** Sequences of layers, mapped by `enum protolayer_grp`. * @@ -76,34 +83,52 @@ const char *protolayer_protocol_names[PROTOLAYER_PROTOCOL_COUNT] = { * one defined as *Variable name* (2nd parameter) in the `PROTOLAYER_GRP_MAP` * macro. */ static const enum protolayer_protocol *protolayer_grps[PROTOLAYER_GRP_COUNT] = { -#define XX(cid, vid, name) [PROTOLAYER_GRP_##cid] = protolayer_grp_##vid, +#define XX(cid, vid, name) [PROTOLAYER_GRP_ ## cid] = protolayer_grp_ ## vid, PROTOLAYER_GRP_MAP(XX) #undef XX }; -/** Human-readable names for protocol layer groups. */ -const char *protolayer_grp_names[PROTOLAYER_GRP_COUNT] = { - [PROTOLAYER_GRP_NULL] = "(null)", -#define XX(cid, vid, name) [PROTOLAYER_GRP_##cid] = (name), +const char *protolayer_grp_name(enum protolayer_grp g) +{ + switch (g) { + case PROTOLAYER_GRP_NULL: + return "(null)"; +#define XX(cid, vid, name) case PROTOLAYER_GRP_ ## cid: \ + return (name); PROTOLAYER_GRP_MAP(XX) #undef XX -}; + default: + return "(invalid)"; + } +} -/** Human-readable names for events. */ -const char *protolayer_event_names[PROTOLAYER_EVENT_COUNT] = { - [PROTOLAYER_EVENT_NULL] = "(null)", -#define XX(cid) [PROTOLAYER_EVENT_##cid] = #cid, +const char *protolayer_event_name(enum protolayer_event_type e) +{ + switch (e) { + case PROTOLAYER_EVENT_NULL: + return "(null)"; +#define XX(cid) case PROTOLAYER_EVENT_ ## cid: \ + return #cid; PROTOLAYER_EVENT_MAP(XX) #undef XX -}; + default: + return "(invalid)"; + } +} -/** Human-readable names for payloads. */ -const char *protolayer_payload_names[PROTOLAYER_PAYLOAD_COUNT] = { - [PROTOLAYER_PAYLOAD_NULL] = "(null)", -#define XX(cid, name) [PROTOLAYER_PAYLOAD_##cid] = (name), +const char *protolayer_payload_name(enum protolayer_payload_type p) +{ + switch (p) { + case PROTOLAYER_PAYLOAD_NULL: + return "(null)"; +#define XX(cid, name) case PROTOLAYER_PAYLOAD_ ## cid: \ + return (name); PROTOLAYER_PAYLOAD_MAP(XX) #undef XX -}; + default: + return "(invalid)"; + } +} /* Forward decls. */ @@ -310,8 +335,10 @@ static inline void protolayer_iter_ctx_next(struct protolayer_iter_ctx *ctx) static inline const char *layer_name(enum protolayer_grp grp, ssize_t layer_ix) { + if (grp >= PROTOLAYER_GRP_COUNT) + return "(invalid)"; enum protolayer_protocol p = protolayer_grps[grp][layer_ix]; - return protolayer_protocol_names[p]; + return protolayer_protocol_name(p); } static inline const char *layer_name_ctx(struct protolayer_iter_ctx *ctx) @@ -333,12 +360,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", - protolayer_grp_names[ctx->manager->grp], + protolayer_grp_name(ctx->manager->grp), 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", - protolayer_grp_names[ctx->manager->grp], + protolayer_grp_name(ctx->manager->grp), ctx->layer_ix, layer_name_ctx(ctx), ctx->status); if (ctx->finished_cb) @@ -368,7 +395,7 @@ static int protolayer_push(struct protolayer_iter_ctx *ctx) if (kr_log_is_debug(PROTOLAYER, NULL)) { VERBOSE_LOG(session, "Pushing %s\n", - protolayer_payload_names[ctx->payload.type]); + protolayer_payload_name(ctx->payload.type)); } if (ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER) { @@ -395,6 +422,9 @@ static int protolayer_push(struct protolayer_iter_ctx *ctx) static int protolayer_step(struct protolayer_iter_ctx *ctx) { while (true) { + if (kr_fails_assert(ctx->manager->grp < PROTOLAYER_GRP_COUNT)) + return kr_error(EFAULT); + enum protolayer_protocol protocol = protolayer_grps[ctx->manager->grp][ctx->layer_ix]; struct protolayer_globals *globals = &protolayer_globals[protocol]; @@ -473,8 +503,8 @@ static int protolayer_manager_submit( VERBOSE_LOG(manager->session, "%s submitted to grp '%s' in %s direction (%zu: %s)\n", - protolayer_payload_names[payload.type], - protolayer_grp_names[manager->grp], + protolayer_payload_name(payload.type), + protolayer_grp_name(manager->grp), (direction == PROTOLAYER_UNWRAP) ? "unwrap" : "wrap", layer_ix, layer_name(manager->grp, layer_ix)); @@ -489,6 +519,9 @@ static int protolayer_manager_submit( }; for (size_t i = 0; i < manager->num_layers; i++) { + if (kr_fails_assert(ctx->manager->grp < PROTOLAYER_GRP_COUNT)) + return kr_error(EFAULT); + 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); diff --git a/daemon/session2.h b/daemon/session2.h index b0c200057..a82470127 100644 --- a/daemon/session2.h +++ b/daemon/session2.h @@ -102,7 +102,16 @@ struct comm_info { }; -/** A buffer, with indices marking the chunk containing valid data. +/** A buffer, with indices marking the chunk containing as of yet unprocessed + * data - this chunk is called "valid". The contents may be manipulated using + * `wire_buf_` functions, which ensure the struct's validity. + * + * The struct may be used to retrieve data piecewise, e.g. from a stream-based + * transport like TCP, by writing data to the buffer's free space, then + * "consuming" that space with `wire_buf_consume`. It can also be handy for + * processing message headers, then trimming the beginning of the buffer (using + * `wire_buf_trim`) so that the next part of the data may be processed by a + * next part of a common pipeline. * * May be initialized in two possible ways: * - via `wire_buf_init` @@ -122,30 +131,30 @@ int wire_buf_init(struct wire_buf *wb, size_t initial_size); * intact). */ void wire_buf_deinit(struct wire_buf *wb); -/** Ensures that the wire buffer's size is at least `size`. `*wb` must be - * initialized, either to zero or via `wire_buf_init`. */ +/** Ensures that the wire buffer's size is at least `size`. The memory at `wb` + * must be initialized, either to zero or via `wire_buf_init`. */ int wire_buf_reserve(struct wire_buf *wb, size_t size); /** Adds `length` to the end index of the valid data, marking `length` more * bytes as valid. * * Returns 0 on success. - * Returns `kr_error(EINVAL)` if the end index would exceed the - * buffer size. */ + * Assert-fails and/or returns `kr_error(EINVAL)` if the end index would exceed + * the buffer size. */ int wire_buf_consume(struct wire_buf *wb, size_t length); /** Adds `length` to the start index of the valid data, marking `length` less * bytes as valid. * * Returns 0 on success. - * Returns `kr_error(EINVAL)` if the start index would exceed - * the end index. */ + * Assert-fails and/or returns `kr_error(EINVAL)` if the start index would + * exceed the end index. */ int wire_buf_trim(struct wire_buf *wb, size_t length); /** Moves the valid bytes of the buffer to the buffer's beginning. */ int wire_buf_movestart(struct wire_buf *wb); -/** Resets the valid bytes of the buffer to zero, as well as the error flag. */ +/** Resets the valid bytes of the buffer to zero. */ int wire_buf_reset(struct wire_buf *wb); /** Gets a pointer to the data marked as valid in the wire buffer. */ @@ -210,16 +219,15 @@ static inline size_t wire_buf_free_space_length(const struct wire_buf *wb) /** The identifiers of protocol layer types. */ enum protolayer_protocol { - PROTOLAYER_NULL = 0, -#define XX(cid) PROTOLAYER_##cid, + PROTOLAYER_PROTOCOL_NULL = 0, +#define XX(cid) PROTOLAYER_PROTOCOL_ ## cid, PROTOLAYER_PROTOCOL_MAP(XX) #undef XX PROTOLAYER_PROTOCOL_COUNT /* must be the last! */ }; -/** Maps protocol layer type IDs to string names. - * E.g. PROTOLAYER_HTTP has name 'HTTP'. */ -extern const char *protolayer_protocol_names[]; +/** Gets the constant string name of the specified protocol. */ +const char *protolayer_protocol_name(enum protolayer_protocol p); /** Protocol layer group map * @@ -247,15 +255,14 @@ extern const char *protolayer_protocol_names[]; /** The identifiers of pre-defined protocol layer sequences. */ enum protolayer_grp { PROTOLAYER_GRP_NULL = 0, -#define XX(cid, vid, name) PROTOLAYER_GRP_##cid, +#define XX(cid, vid, name) PROTOLAYER_GRP_ ## cid, PROTOLAYER_GRP_MAP(XX) #undef XX PROTOLAYER_GRP_COUNT }; -/** Maps protocol layer group IDs to human-readable descriptions. - * E.g. PROTOLAYER_GRP_DOH has description 'DNS-over-HTTPS'. */ -extern const char *protolayer_grp_names[]; +/** Gets the constant string name of the specified protocol layer group. */ +const char *protolayer_grp_name(enum protolayer_grp g); /** Flow control indicators for protocol layer `wrap` and `unwrap` callbacks. * Use via `protolayer_continue`, `protolayer_break`, and `protolayer_push` @@ -339,14 +346,14 @@ typedef void (*protolayer_finished_cb)(int status, struct session2 *session, /** Event type, to be interpreted by a layer. */ enum protolayer_event_type { PROTOLAYER_EVENT_NULL = 0, -#define XX(cid) PROTOLAYER_EVENT_##cid, +#define XX(cid) PROTOLAYER_EVENT_ ## cid, PROTOLAYER_EVENT_MAP(XX) #undef XX PROTOLAYER_EVENT_COUNT }; -/** Maps event types to their names. */ -extern const char *protolayer_event_names[]; +/** Gets the constant string name of the specified event. */ +const char *protolayer_event_name(enum protolayer_event_type e); /** Payload types. @@ -363,14 +370,14 @@ extern const char *protolayer_event_names[]; * 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 }; -/** Maps payload type IDs to human-readable names. */ -extern const char *protolayer_payload_names[]; +/** Gets the constant string name of the specified payload type. */ +const char *protolayer_payload_name(enum protolayer_payload_type p); /** Data processed by the sequence of layers. All pointed-to memory is always * owned by its creator. It is also the layer (group) implementor's diff --git a/daemon/tls.c b/daemon/tls.c index 36a7eaa7f..73a31b069 100644 --- a/daemon/tls.c +++ b/daemon/tls.c @@ -226,7 +226,7 @@ static ssize_t kres_gnutls_vec_push(gnutls_transport_ptr_t h, const giovec_t * i push_ctx->sess_data = tls; memcpy(push_ctx->iov, iov, sizeof(struct iovec[iovcnt])); - session2_wrap_after(tls->session, PROTOLAYER_TLS, + session2_wrap_after(tls->session, PROTOLAYER_PROTOCOL_TLS, protolayer_iovec(push_ctx->iov, iovcnt), NULL, kres_gnutls_push_finished, push_ctx); @@ -258,7 +258,7 @@ static void tls_handshake_success(struct pl_tls_sess_data *tls, } } if (!tls->first_handshake_done) { - session2_event_after(session, PROTOLAYER_TLS, + session2_event_after(session, PROTOLAYER_PROTOCOL_TLS, PROTOLAYER_EVENT_CONNECT, NULL); tls->first_handshake_done = true; } @@ -1324,7 +1324,7 @@ static void pl_tls_request_init(struct protolayer_manager *manager, void tls_protolayers_init(void) { - protolayer_globals[PROTOLAYER_TLS] = (struct protolayer_globals){ + protolayer_globals[PROTOLAYER_PROTOCOL_TLS] = (struct protolayer_globals){ .sess_size = sizeof(struct pl_tls_sess_data), .sess_deinit = pl_tls_sess_deinit, .wire_buf_overhead = TLS_CHUNK_SIZE, diff --git a/daemon/worker.c b/daemon/worker.c index f14273629..9b5ad5484 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1085,7 +1085,7 @@ static int tcp_task_make_connection(struct qr_task *task, const struct sockaddr bool has_tls = tls_entry; if (has_tls) { struct protolayer_data_param param = { - .protocol = PROTOLAYER_TLS, + .protocol = PROTOLAYER_PROTOCOL_TLS, .param = tls_entry }; session = ioreq_spawn(SOCK_STREAM, addr->sa_family, @@ -2263,12 +2263,12 @@ int worker_init(void) kr_bindings_register(the_engine->L); // TODO move /* DNS protocol layers */ - protolayer_globals[PROTOLAYER_DNS_DGRAM] = (struct protolayer_globals){ + protolayer_globals[PROTOLAYER_PROTOCOL_DNS_DGRAM] = (struct protolayer_globals){ .wire_buf_overhead = KNOT_WIRE_MAX_PKTSIZE, .unwrap = pl_dns_dgram_unwrap, .event_unwrap = pl_dns_dgram_event_unwrap }; - protolayer_globals[PROTOLAYER_DNS_UNSIZED_STREAM] = (struct protolayer_globals){ + protolayer_globals[PROTOLAYER_PROTOCOL_DNS_UNSIZED_STREAM] = (struct protolayer_globals){ .wire_buf_overhead = KNOT_WIRE_MAX_PKTSIZE, .sess_init = pl_dns_stream_sess_init, .unwrap = pl_dns_dgram_unwrap, @@ -2286,10 +2286,10 @@ int worker_init(void) .event_unwrap = pl_dns_stream_event_unwrap, .request_init = pl_dns_stream_request_init }; - protolayer_globals[PROTOLAYER_DNS_MULTI_STREAM] = stream_common; - protolayer_globals[PROTOLAYER_DNS_MULTI_STREAM].sess_init = pl_dns_stream_sess_init; - protolayer_globals[PROTOLAYER_DNS_SINGLE_STREAM] = stream_common; - protolayer_globals[PROTOLAYER_DNS_SINGLE_STREAM].sess_init = pl_dns_single_stream_sess_init; + protolayer_globals[PROTOLAYER_PROTOCOL_DNS_MULTI_STREAM] = stream_common; + protolayer_globals[PROTOLAYER_PROTOCOL_DNS_MULTI_STREAM].sess_init = pl_dns_stream_sess_init; + protolayer_globals[PROTOLAYER_PROTOCOL_DNS_SINGLE_STREAM] = stream_common; + protolayer_globals[PROTOLAYER_PROTOCOL_DNS_SINGLE_STREAM].sess_init = pl_dns_single_stream_sess_init; /* Create main worker. */ the_worker = &the_worker_value;