]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/session2: cleanup; clarify naming and docs
authorOto Šťáva <oto.stava@nic.cz>
Wed, 14 Sep 2022 07:45:42 +0000 (09:45 +0200)
committerOto Šťáva <oto.stava@nic.cz>
Thu, 26 Jan 2023 11:56:08 +0000 (12:56 +0100)
daemon/io.c
daemon/session2.c
daemon/session2.h
daemon/tls.c
daemon/worker.c

index daac2ffc93216b158543ce2f1042093a8eb38ec6..c7e1f1f4f3559d47be4861f049593b296945de30 100644 (file)
@@ -137,15 +137,8 @@ struct pl_udp_iter_data {
        bool has_proxy;
 };
 
-static int pl_udp_iter_init(struct protolayer_manager *manager, void *iter_data)
-{
-       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(
-               void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
+static enum protolayer_iter_cb_result pl_udp_unwrap(
+               void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx)
 {
        ctx->payload = protolayer_as_buffer(&ctx->payload);
        if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER)) {
@@ -231,13 +224,6 @@ struct pl_tcp_sess_data {
        bool has_proxy : 1;
 };
 
-static int pl_tcp_sess_init(struct protolayer_manager *manager, void *sess_data, void *param)
-{
-       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, void *sess_data)
 {
        struct pl_tcp_sess_data *tcp = sess_data;
@@ -245,8 +231,8 @@ static int pl_tcp_sess_deinit(struct protolayer_manager *manager, void *sess_dat
        return 0;
 }
 
-static enum protolayer_cb_result pl_tcp_unwrap(
-               void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
+static enum protolayer_iter_cb_result pl_tcp_unwrap(
+               void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx)
 {
        struct session2 *s = ctx->manager->session;
        struct pl_tcp_sess_data *tcp = sess_data;
@@ -363,14 +349,12 @@ void io_protolayers_init(void)
 {
        protolayer_globals[PROTOLAYER_UDP] = (struct protolayer_globals){
                .iter_size = sizeof(struct pl_udp_iter_data),
-               .iter_init = pl_udp_iter_init,
                .unwrap = pl_udp_unwrap,
                .event_wrap = pl_udp_event_wrap,
        };
 
        protolayer_globals[PROTOLAYER_TCP] = (struct protolayer_globals){
                .sess_size = sizeof(struct pl_tcp_sess_data),
-               .sess_init = pl_tcp_sess_init,
                .sess_deinit = pl_tcp_sess_deinit,
                .unwrap = pl_tcp_unwrap,
                .event_wrap = pl_tcp_event_wrap,
index 68363c6bb5a1e611cd8f21d69bb5c0aa06edfe4d..2c78d8769c349fba52bb33c09527160f6a186ae0 100644 (file)
@@ -29,26 +29,26 @@ static int session2_transport_event(struct session2 *s,
 struct protolayer_globals protolayer_globals[PROTOLAYER_PROTOCOL_COUNT] = {0};
 
 
-enum protolayer_protocol protolayer_grp_doudp[] = {
+static enum protolayer_protocol protolayer_grp_doudp[] = {
        PROTOLAYER_UDP,
        PROTOLAYER_DNS_DGRAM,
        PROTOLAYER_NULL
 };
 
-enum protolayer_protocol protolayer_grp_dotcp[] = {
+static enum protolayer_protocol protolayer_grp_dotcp[] = {
        PROTOLAYER_TCP,
        PROTOLAYER_DNS_MSTREAM,
        PROTOLAYER_NULL
 };
 
-enum protolayer_protocol protolayer_grp_dot[] = {
+static enum protolayer_protocol protolayer_grp_dot[] = {
        PROTOLAYER_TCP,
        PROTOLAYER_TLS,
        PROTOLAYER_DNS_MSTREAM,
        PROTOLAYER_NULL
 };
 
-enum protolayer_protocol protolayer_grp_doh[] = {
+static enum protolayer_protocol protolayer_grp_doh[] = {
        PROTOLAYER_TCP,
        PROTOLAYER_TLS,
        PROTOLAYER_HTTP,
@@ -57,12 +57,21 @@ enum protolayer_protocol protolayer_grp_doh[] = {
 };
 
 
-enum protolayer_protocol *protolayer_grps[PROTOLAYER_GRP_COUNT] = {
+/** Sequences of layers, mapped by `enum protolayer_grp`.
+ *
+ * To define a new group, add a new entry in the `PROTOLAYER_GRP_MAP` macro and
+ * create a new static `protolayer_grp_*` array above, similarly to the already
+ * existing ones. Each array must end with `PROTOLAYER_GRP_NULL`, to indicate
+ * the end of the list of protocol layers. The array name's suffix must be the
+ * one defined as *Variable name* (2nd parameter) in the `PROTOLAYER_GRP_MAP`
+ * macro. */
+static enum protolayer_protocol *protolayer_grps[PROTOLAYER_GRP_COUNT] = {
 #define XX(cid, vid, name) [PROTOLAYER_GRP_##cid] = protolayer_grp_##vid,
        PROTOLAYER_GRP_MAP(XX)
 #undef XX
 };
 
+/** Human-readable names for protocol layer groups. */
 char *protolayer_grp_names[PROTOLAYER_GRP_COUNT] = {
        [PROTOLAYER_GRP_NULL] = "(null)",
 #define XX(cid, vid, name) [PROTOLAYER_GRP_##cid] = name,
@@ -70,6 +79,7 @@ char *protolayer_grp_names[PROTOLAYER_GRP_COUNT] = {
 #undef XX
 };
 
+/** Human-readable names for events. */
 char *protolayer_event_names[PROTOLAYER_EVENT_COUNT] = {
        [PROTOLAYER_EVENT_NULL] = "(null)",
 #define XX(cid) [PROTOLAYER_EVENT_##cid] = #cid,
@@ -77,6 +87,7 @@ char *protolayer_event_names[PROTOLAYER_EVENT_COUNT] = {
 #undef XX
 };
 
+/** Human-readable names for payloads. */
 char *protolayer_payload_names[PROTOLAYER_PAYLOAD_COUNT] = {
        [PROTOLAYER_PAYLOAD_NULL] = "(null)",
 #define XX(cid, name) [PROTOLAYER_PAYLOAD_##cid] = name,
@@ -131,7 +142,7 @@ static inline struct protolayer_data *protolayer_sess_data_get(
 /** 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_iter_ctx *ctx, size_t layer_ix)
 {
        struct protolayer_manager *m = ctx->manager;
        if (kr_fails_assert(layer_ix < m->num_layers))
@@ -159,7 +170,7 @@ static inline ssize_t protolayer_manager_get_protocol(
        return -1;
 }
 
-static inline bool protolayer_cb_ctx_is_last(struct protolayer_cb_ctx *ctx)
+static inline bool protolayer_iter_ctx_is_last(struct protolayer_iter_ctx *ctx)
 {
        unsigned int last_ix = (ctx->direction == PROTOLAYER_UNWRAP)
                ? ctx->manager->num_layers - 1
@@ -167,7 +178,7 @@ static inline bool protolayer_cb_ctx_is_last(struct protolayer_cb_ctx *ctx)
        return ctx->layer_ix == last_ix;
 }
 
-static inline void protolayer_cb_ctx_next(struct protolayer_cb_ctx *ctx)
+static inline void protolayer_iter_ctx_next(struct protolayer_iter_ctx *ctx)
 {
        if (ctx->direction == PROTOLAYER_UNWRAP)
                ctx->layer_ix++;
@@ -175,7 +186,7 @@ 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)
+static int protolayer_iter_ctx_finish(struct protolayer_iter_ctx *ctx, int ret)
 {
        struct session2 *session = ctx->manager->session;
 
@@ -206,13 +217,13 @@ static int protolayer_cb_ctx_finish(struct protolayer_cb_ctx *ctx, int ret)
 
 static void protolayer_push_finished(int status, struct session2 *s, const void *target, void *baton)
 {
-       struct protolayer_cb_ctx *ctx = baton;
+       struct protolayer_iter_ctx *ctx = baton;
        ctx->status = status;
-       protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL);
+       protolayer_iter_ctx_finish(ctx, PROTOLAYER_RET_NORMAL);
 }
 
 /** Pushes the specified protocol layer's payload to the session's transport. */
-static int protolayer_push(struct protolayer_cb_ctx *ctx)
+static int protolayer_push(struct protolayer_iter_ctx *ctx)
 {
        struct session2 *session = ctx->manager->session;
 
@@ -241,7 +252,7 @@ static int protolayer_push(struct protolayer_cb_ctx *ctx)
 
        if (status < 0) {
                ctx->status = status;
-               return protolayer_cb_ctx_finish(ctx, status);
+               return protolayer_iter_ctx_finish(ctx, status);
        }
 
        return PROTOLAYER_RET_ASYNC;
@@ -252,7 +263,7 @@ static int protolayer_push(struct protolayer_cb_ctx *ctx)
  *
  * May be called multiple times on the same `ctx` to continue processing
  * after an asynchronous operation. */
-static int protolayer_step(struct protolayer_cb_ctx *ctx)
+static int protolayer_step(struct protolayer_iter_ctx *ctx)
 {
        while (true) {
                enum protolayer_protocol protocol = protolayer_grps[ctx->manager->grp][ctx->layer_ix];
@@ -260,9 +271,9 @@ static int protolayer_step(struct protolayer_cb_ctx *ctx)
 
                ctx->async_mode = false;
                ctx->status = 0;
-               ctx->action = PROTOLAYER_CB_ACTION_NULL;
+               ctx->action = PROTOLAYER_ITER_ACTION_NULL;
 
-               protolayer_cb cb = (ctx->direction == PROTOLAYER_UNWRAP)
+               protolayer_iter_cb cb = (ctx->direction == PROTOLAYER_UNWRAP)
                        ? globals->unwrap : globals->wrap;
 
                if (cb) {
@@ -270,13 +281,13 @@ static int protolayer_step(struct protolayer_cb_ctx *ctx)
                                        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)) {
+                       enum protolayer_iter_cb_result result = cb(sess_data, iter_data, ctx);
+                       if (kr_fails_assert(result == PROTOLAYER_ITER_CB_RESULT_MAGIC)) {
                                /* Callback did not use a continuation function to return. */
-                               return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL));
+                               return protolayer_iter_ctx_finish(ctx, kr_error(EINVAL));
                        }
                } else {
-                       ctx->action = PROTOLAYER_CB_ACTION_CONTINUE;
+                       ctx->action = PROTOLAYER_ITER_ACTION_CONTINUE;
                }
 
 
@@ -286,32 +297,32 @@ static int protolayer_step(struct protolayer_cb_ctx *ctx)
                        return PROTOLAYER_RET_ASYNC;
                }
 
-               if (ctx->action == PROTOLAYER_CB_ACTION_BREAK) {
-                       return protolayer_cb_ctx_finish(
+               if (ctx->action == PROTOLAYER_ITER_ACTION_BREAK) {
+                       return protolayer_iter_ctx_finish(
                                        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));
+                       return protolayer_iter_ctx_finish(ctx, kr_error(ECANCELED));
                }
 
-               if (ctx->action == PROTOLAYER_CB_ACTION_CONTINUE) {
-                       if (protolayer_cb_ctx_is_last(ctx)) {
+               if (ctx->action == PROTOLAYER_ITER_ACTION_CONTINUE) {
+                       if (protolayer_iter_ctx_is_last(ctx)) {
                                if (ctx->direction == PROTOLAYER_WRAP)
                                        return protolayer_push(ctx);
 
-                               return protolayer_cb_ctx_finish(
+                               return protolayer_iter_ctx_finish(
                                                ctx, PROTOLAYER_RET_NORMAL);
                        }
 
-                       protolayer_cb_ctx_next(ctx);
+                       protolayer_iter_ctx_next(ctx);
                        continue;
                }
 
                /* Should never get here */
                kr_assert(false && "Invalid layer callback action");
-               return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL));
+               return protolayer_iter_ctx_finish(ctx, kr_error(EINVAL));
        }
 }
 
@@ -328,7 +339,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(manager->cb_ctx_size);
+       struct protolayer_iter_ctx *ctx = malloc(manager->cb_ctx_size);
        kr_require(ctx);
 
        if (kr_log_is_debug(PROTOLAYER, NULL)) {
@@ -341,7 +352,7 @@ static int protolayer_manager_submit(
                                layer_ix);
        }
 
-       *ctx = (struct protolayer_cb_ctx) {
+       *ctx = (struct protolayer_iter_ctx) {
                .payload = payload,
                .target = target,
                .direction = direction,
@@ -358,7 +369,6 @@ static int protolayer_manager_submit(
                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;
                }
 
@@ -394,7 +404,7 @@ static struct protolayer_manager *protolayer_manager_new(
 
        size_t num_layers = 0;
        size_t manager_size = sizeof(struct protolayer_manager);
-       size_t cb_ctx_size = sizeof(struct protolayer_cb_ctx);
+       size_t cb_ctx_size = sizeof(struct protolayer_iter_ctx);
 
        enum protolayer_protocol *protocols = protolayer_grps[grp];
        if (kr_fails_assert(protocols))
@@ -446,7 +456,6 @@ static struct protolayer_manager *protolayer_manager_new(
                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);
@@ -474,26 +483,26 @@ static void protolayer_manager_free(struct protolayer_manager *m)
        free(m);
 }
 
-enum protolayer_cb_result protolayer_continue(struct protolayer_cb_ctx *ctx)
+enum protolayer_iter_cb_result protolayer_continue(struct protolayer_iter_ctx *ctx)
 {
        if (ctx->async_mode) {
-               protolayer_cb_ctx_next(ctx);
+               protolayer_iter_ctx_next(ctx);
                protolayer_step(ctx);
        } else {
-               ctx->action = PROTOLAYER_CB_ACTION_CONTINUE;
+               ctx->action = PROTOLAYER_ITER_ACTION_CONTINUE;
        }
-       return PROTOLAYER_CB_RESULT_MAGIC;
+       return PROTOLAYER_ITER_CB_RESULT_MAGIC;
 }
 
-enum protolayer_cb_result protolayer_break(struct protolayer_cb_ctx *ctx, int status)
+enum protolayer_iter_cb_result protolayer_break(struct protolayer_iter_ctx *ctx, int status)
 {
        ctx->status = status;
        if (ctx->async_mode) {
-               protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL);
+               protolayer_iter_ctx_finish(ctx, PROTOLAYER_RET_NORMAL);
        } else {
-               ctx->action = PROTOLAYER_CB_ACTION_BREAK;
+               ctx->action = PROTOLAYER_ITER_ACTION_BREAK;
        }
-       return PROTOLAYER_CB_RESULT_MAGIC;
+       return PROTOLAYER_ITER_CB_RESULT_MAGIC;
 }
 
 
index 1f3ec94ed48e885262bbc12e7edfb20659cf0e6d..21634362db54172a2ee3c60724678d18392f1db4 100644 (file)
@@ -5,6 +5,31 @@
 /* HINT: If you are looking to implement a new protocol, start with the doc
  * comment of `enum protolayer_protocol` and continue from there. */
 
+/* GLOSSARY:
+ *
+ * Iteration:
+ *   - The processing of a piece of data (a.k.a. payload) using a particular
+ *   sequence of Protocol layers, either in Wrap or Unwrap direction. It is
+ *   also the lifetime of `struct protolayer_iter_ctx` and layer-specific data.
+ *
+ * Protocol layer:
+ *   - An implementation of a particular protocol. A layer transforms data
+ *   within the resolver to conform to a particular protocol, e.g. UDP, TCP,
+ *   TLS, HTTP, QUIC, etc.
+ *
+ * Protolayer:
+ *   - Same as 'Protocol layer'.
+ *
+ * Unwrap:
+ *   - The direction of data transformation, starting with the transport (e.g.
+ *   data that came from the network), ending with an internal subsystem (e.g.
+ *   DNS query resolution).
+ *
+ * Wrap:
+ *   - The direction of data transformation, starting with an internal
+ *   subsystem (e.g. an answer to a resolved DNS query), ending with the
+ *   transport (e.g. data that is going to be sent to the client). */
+
 #pragma once
 
 #include <stdalign.h>
@@ -19,7 +44,7 @@
 
 /* Forward declarations */
 struct session2;
-struct protolayer_cb_ctx;
+struct protolayer_iter_ctx;
 
 /** Information about the transport - addresses and proxy. */
 struct comm_info {
@@ -50,7 +75,11 @@ struct comm_info {
  * some logical compilation unit (e.g. `daemon/worker.c`), create a function
  * that will initialize the protocol's `protolayer_globals[]`, ideally at the
  * start of the program. See the docs of `struct protolayer_globals` for more
- * details. */
+ * details.
+ *
+ * To use protocols within sessions, protocol layer groups also need to be
+ * defined, to indicate the order in which individual protocols are to be
+ * processed. See `PROTOLAYER_GRP_MAP` below for more details. */
 enum protolayer_protocol {
        PROTOLAYER_NULL = 0,
 
@@ -73,8 +102,12 @@ enum protolayer_protocol {
 };
 
 /** Protocol layer groups. Each of these represents a sequence of layers in the
- * unwrap direction (wrap direction being the opposite). This macro is used to
- * generate `enum protolayer_grp` and `protolayer_grp_descs[]`.
+ * unwrap direction (wrap direction being the opposite). The sequence dictates
+ * the order, in which individual layers are processed. This macro is used to
+ * generate global data about groups.
+ *
+ * For defining new groups, see the docs of `protolayer_grps[]` in
+ * `daemon/session2.h`.
  *
  * Parameters are:
  *   1. Constant name (for e.g. PROTOLAYER_GRP_* constants)
@@ -102,11 +135,11 @@ extern char *protolayer_grp_names[];
 /** Flow control indicators for protocol layer `wrap` and `unwrap` callbacks.
  * Use via `protolayer_continue`, `protolayer_break`, and `protolayer_push`
  * functions. */
-enum protolayer_cb_action {
-       PROTOLAYER_CB_ACTION_NULL = 0,
+enum protolayer_iter_action {
+       PROTOLAYER_ITER_ACTION_NULL = 0,
 
-       PROTOLAYER_CB_ACTION_CONTINUE,
-       PROTOLAYER_CB_ACTION_BREAK,
+       PROTOLAYER_ITER_ACTION_CONTINUE,
+       PROTOLAYER_ITER_ACTION_BREAK,
 };
 
 /** Direction of layer sequence processing. */
@@ -224,10 +257,11 @@ struct protolayer_payload {
        };
 };
 
-/** Context for protocol layer callbacks, containing buffer data and internal
- * information for protocol layer manager. */
-struct protolayer_cb_ctx {
-       /* read-write */
+/** Context for protocol layer iterations, containing payload data,
+ * layer-specific data, and internal information for the protocol layer
+ * manager. */
+struct protolayer_iter_ctx {
+/* read-write: */
        /** The payload */
        struct protolayer_payload payload;
        /** Transport information (e.g. UDP sender address). May be `NULL`. */
@@ -237,20 +271,20 @@ struct protolayer_cb_ctx {
         * Zero-initialized in the beginning. */
        struct comm_info comm;
 
-       /* callback for when the layer iteration has ended - read-only */
+/* callback for when the layer iteration has ended - read-only: */
        protolayer_finished_cb finished_cb;
        const void *finished_cb_target;
        void *finished_cb_baton;
 
-       /* internal information for the manager - private */
+/* internal information for the manager - private: */
        enum protolayer_direction direction;
        bool async_mode;
        unsigned int layer_ix;
        struct protolayer_manager *manager;
        int status;
-       enum protolayer_cb_action action;
+       enum protolayer_iter_action action;
 
-       /** This contains variably-sized layer-specific data. See `struct
+       /** Contains variably-sized layer-specific data. See `struct
         * protolayer_manager::data`. */
        alignas(CPU_STRUCT_ALIGN) char data[];
 };
@@ -293,47 +327,49 @@ static inline struct protolayer_payload protolayer_wire_buf(struct wire_buf *wir
  * Supports only `_BUFFER` and `_WIRE_BUF` on the input, otherwise returns
  * `_NULL` type or aborts on assertion if allowed.
  *
- * If the input payload is `_WIRE_BUF`, the pointed-to wire buffer is reset
- * to indicate that all of its contents have been used and the buffer is ready
+ * If the input payload is `_WIRE_BUF`, the pointed-to wire buffer is reset to
+ * indicate that all of its contents have been used up, and the buffer is ready
  * to be reused. */
 struct protolayer_payload protolayer_as_buffer(const struct protolayer_payload *payload);
 
 /** 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. */\
 }
 
-/** Layer-specific data - generic struct. */
+/** Layer-specific data - the generic struct. */
 struct protolayer_data {
        PROTOLAYER_DATA_HEADER();
 };
 
-/** Return value of `protolayer_cb` callbacks. To be generated by continuation
- * functions, never returned directly. */
-enum protolayer_cb_result {
-       PROTOLAYER_CB_RESULT_MAGIC = 0x364F392E,
+/** Return value of `protolayer_iter_cb` callbacks. To be returned by *layer
+ * sequence return functions* as a sanity check. Not to be used directly by
+ * user code. */
+enum protolayer_iter_cb_result {
+       PROTOLAYER_ITER_CB_RESULT_MAGIC = 0x364F392E,
 };
 
-/** Function type for `wrap` and `unwrap` callbacks of layers. The function
- * processes the provided `ctx->payload` and decides on the next action for the
- * currently processed sequence.
+/** Function type for `struct protolayer_globals::wrap` and `struct
+ * protolayer_globals::unwrap`. The function processes the provided
+ * `ctx->payload` and decides the next action for the currently processed
+ * sequence.
  *
  * The pointed-to function (or another function, that the pointed-to function
- * causes to be called, e.g. through an asynchronous operation), must call one
- * of the *layer sequence return functions* to advance (or end) the layer
- * iteration. The pointed-to function must return the result of such a return
- * function. */
-typedef enum protolayer_cb_result (*protolayer_cb)(
+ * causes to be called, directly or through an asynchronous operation), must
+ * call one of the *layer sequence return functions* to advance (or end) the
+ * layer iteration. The pointed-to function must return the result of such a
+ * return function. */
+typedef enum protolayer_iter_cb_result (*protolayer_iter_cb)(
                void *sess_data,
                void *iter_data,
-               struct protolayer_cb_ctx *ctx);
-
-/** Function type for `event_wrap` and `event_unwrap` callbacks of layers.
- * The `baton` parameter points to the mutable, iteration-specific baton
- * pointer, initialized by the `baton` parameter of one of the `session2_event`
- * functions. The pointed-to value of `baton` may be modified to accommodate
- * for the next layer in the sequence.
+               struct protolayer_iter_ctx *ctx);
+
+/** Function type for `struct protolayer_globals::event_wrap` and `struct
+ * protolayer_globals::event_unwrap` callbacks of layers. The `baton` parameter
+ * points to the mutable, iteration-specific baton pointer, initialized by the
+ * `baton` parameter of one of the `session2_event` functions. The pointed-to
+ * value of `baton` may be modified to accommodate for the next layer in the
+ * sequence.
  *
  * When `true` is returned, iteration over the sequence of layers continues.
  * When `false` is returned, iteration stops. */
@@ -342,10 +378,11 @@ typedef bool (*protolayer_event_cb)(enum protolayer_event_type event,
                                     struct protolayer_manager *manager,
                                     void *sess_data);
 
-/** Function type for initialization callbacks of layer session data. The
- * `param` value is the one associated with the currently initialized layer,
- * from the `layer_param` array of `session2_new()` - may be NULL if none is
- * provided for the current layer.
+/** Function type for initialization callbacks of layer session data.
+ *
+ * The `param` value is the one associated with the currently initialized
+ * layer, from the `layer_param` array of `session2_new()` - may be NULL if
+ * none is provided for the current layer.
  *
  * `data` points to the layer-specific data struct.
  *
@@ -391,7 +428,7 @@ struct protolayer_manager {
         * `sess_offsets` determines data offsets in `sess_data`.
         *
         * `iter_offsets` determines data offsets in
-        * `struct protolayer_cb_ctx::data`. */
+        * `struct protolayer_iter_ctx::data`. */
        alignas(CPU_STRUCT_ALIGN) char data[];
 };
 
@@ -407,62 +444,70 @@ struct protolayer_data_param {
  * the `protolayer_globals` global array (below) during the start of the
  * resolver. It contains pointers to the specific protocol's functions. */
 struct protolayer_globals {
-       /** Size of the layer-specific data struct, that is valid per-session.
+       /** Size of the layer-specific data struct, valid per-session.
         *
         * The struct MUST begin with the `PROTOLAYER_DATA_HEADER()` macro. If
         * no session struct is used by the layer, the value may be zero. */
        size_t sess_size;
 
-       /** Size of the layer-specific data struct, that is valid
-        * per-iteration. It gets created and destroyed together with a `struct
-        * protolayer_cb_ctx`.
+       /** Size of the layer-specific data struct, valid per-iteration. It
+        * gets created and destroyed together with a `struct
+        * protolayer_iter_ctx`.
         *
         * The struct MUST begin with the `PROTOLAYER_DATA_HEADER()` macro. If
         * no iteration struct is used by the layer, the value may be zero. */
        size_t iter_size;
 
-       /** Called during session creation to initialize layer-specific
-        * session data. */
+       /** Called during session creation to initialize layer-specific session
+        * data. Optional. The data is always zero-initialized during session
+        * initialization. */
        protolayer_data_sess_init_cb sess_init;
 
        /** Called during session destruction to deinitialize layer-specific
-        * session data. */
+        * session data. Optional. */
        protolayer_data_cb sess_deinit;
 
        /** Called at the beginning of a layer sequence to initialize
-        * layer-specific iteration data. */
+        * layer-specific iteration data. Optional. The data is always
+        * zero-initialized during iteration context initialization. */
        protolayer_data_cb iter_init;
 
        /** Called at the end of a layer sequence to deinitialize
-        * layer-specific iteration data. */
+        * layer-specific iteration data. Optional. */
        protolayer_data_cb iter_deinit;
 
        /** Strips the buffer of protocol-specific data. E.g. a HTTP layer
-        * removes HTTP status and headers. */
-       protolayer_cb unwrap;
+        * removes HTTP status and headers. Optional - iteration continues
+        * automatically if this is NULL. */
+       protolayer_iter_cb unwrap;
 
        /** Wraps the buffer into protocol-specific data. E.g. a HTTP layer
-        * adds HTTP status and headers. */
-       protolayer_cb wrap;
+        * adds HTTP status and headers. Optional - iteration continues
+        * automatically if this is NULL. */
+       protolayer_iter_cb wrap;
 
-       /** Processes events in the unwrap order (sent from the outside). */
+       /** Processes events in the unwrap order (sent from the outside).
+        * Optional - iteration continues automatically if this is NULL. */
        protolayer_event_cb event_unwrap;
 
-       /** Processes events in the wrap order (bounced back by the session). */
+       /** Processes events in the wrap order (bounced back by the session).
+        * Optional - iteration continues automatically if this is NULL. */
        protolayer_event_cb event_wrap;
 };
 
-/** Global data about layered protocols. Indexed by `enum protolayer_protocol`. */
+/** Global data about layered protocols. Mapped by `enum protolayer_protocol`.
+ * Individual protocols are to be initialized during resolver startup. */
 extern struct protolayer_globals protolayer_globals[PROTOLAYER_PROTOCOL_COUNT];
 
+
 /** *Layer sequence return function* - signalizes the protolayer manager to
  * continue processing the next layer. */
-enum protolayer_cb_result protolayer_continue(struct protolayer_cb_ctx *ctx);
+enum protolayer_iter_cb_result protolayer_continue(struct protolayer_iter_ctx *ctx);
 
 /** *Layer sequence return function* - signalizes that the layer wants to stop
  * processing of the buffer and clean up, possibly due to an error (indicated
  * by a non-zero `status`). */
-enum protolayer_cb_result protolayer_break(struct protolayer_cb_ctx *ctx, int status);
+enum protolayer_iter_cb_result protolayer_break(struct protolayer_iter_ctx *ctx, int status);
 
 /** *Layer sequence return function* - signalizes that the current sequence
  * will continue in an asynchronous manner. The layer should store the context
@@ -473,9 +518,9 @@ enum protolayer_cb_result protolayer_break(struct protolayer_cb_ctx *ctx, int st
  * Note that this return function is just a readability hint - another return
  * function may be called in another stack frame before it and the sequence
  * will continue correctly. */
-static inline enum protolayer_cb_result protolayer_async()
+static inline enum protolayer_iter_cb_result protolayer_async()
 {
-       return PROTOLAYER_CB_RESULT_MAGIC;
+       return PROTOLAYER_ITER_CB_RESULT_MAGIC;
 }
 
 
@@ -638,9 +683,10 @@ struct session2 {
  * group, and the provided transport context.
  *
  * `layer_param` is a pointer to an array of size `layer_param_count`. The
- * parameters are passed to the layer session initializers. The parameters and
- * the pointed-to data are only required to be valid while calling this
- * function. */
+ * parameters are passed to the layer session initializers. The parameter array
+ * is only required to be valid before this function returns. It is up to the
+ * individual layer implementations to determine the lifetime of the data
+ * pointed to by the parameters. */
 struct session2 *session2_new(enum session2_transport_type transport_type,
                               enum protolayer_grp layer_grp,
                               struct protolayer_data_param *layer_param,
@@ -820,7 +866,11 @@ void session2_event(struct session2 *s, enum protolayer_event_type type, void *b
 /** Sends an event to be synchronously processed by the protocol layers of the
  * specified session, starting from the specified `protocol` in the `_UNWRAP`
  * direction. The layers are first iterated through in the `_UNWRAP` direction,
- * then bounced back in the `_WRAP` direction. */
+ * then bounced back in the `_WRAP` direction.
+ *
+ * NOTE: The bounced iteration does not exclude any layers - the layer
+ * specified by `protocol` and those before it are only skipped in the
+ * `_UNWRAP` direction! */
 void session2_event_after(struct session2 *s, enum protolayer_protocol protocol,
                           enum protolayer_event_type type, void *baton);
 
index e6def676d84fe8a41c49afa842b5cadb16c56be8..ae1384ccb680e18f39c7a02cf29ecfda1745e9a8 100644 (file)
@@ -51,7 +51,7 @@ typedef enum tls_client_hs_state {
 } tls_hs_state_t;
 
 typedef int (*tls_handshake_cb) (struct session2 *session, int status);
-typedef queue_t(struct protolayer_cb_ctx *) pl_cb_ctx_queue_t;
+typedef queue_t(struct protolayer_iter_ctx *) pl_cb_ctx_queue_t;
 
 struct pl_tls_sess_data {
        PROTOLAYER_DATA_HEADER();
@@ -102,9 +102,9 @@ static size_t count_avail_payload(pl_cb_ctx_queue_t *queue)
                return 0;
 
        size_t avail = 0;
-       queue_it_t(struct protolayer_cb_ctx *) it = queue_it_begin(*queue);
+       queue_it_t(struct protolayer_iter_ctx *) it = queue_it_begin(*queue);
        for (; !queue_it_finished(it); queue_it_next(it)) {
-               struct protolayer_cb_ctx *ctx = queue_it_val(it);
+               struct protolayer_iter_ctx *ctx = queue_it_val(it);
                struct protolayer_payload *pld = &ctx->payload;
                if (pld->type == PROTOLAYER_PAYLOAD_BUFFER) {
                        avail += pld->buffer.len;
@@ -144,7 +144,7 @@ static ssize_t kres_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len)
        char *dest = buf;
        size_t transfer = 0;
        while (queue_len(tls->unwrap_queue) > 0 && len > 0) {
-               struct protolayer_cb_ctx *ctx = queue_head(tls->unwrap_queue);
+               struct protolayer_iter_ctx *ctx = queue_head(tls->unwrap_queue);
                struct protolayer_payload *pld = &ctx->payload;
 
                bool fully_consumed = false;
@@ -233,7 +233,7 @@ static void kres_gnutls_push_finished(int status, struct session2 *session,
        struct kres_gnutls_push_ctx *push_ctx = baton;
        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);
+               struct protolayer_iter_ctx *ctx = queue_head(tls->wrap_queue);
                protolayer_break(ctx, kr_ok());
                queue_pop(tls->wrap_queue);
        }
@@ -1072,8 +1072,8 @@ static int pl_tls_sess_deinit(struct protolayer_manager *manager,
        return pl_tls_sess_data_deinit(sess_data);
 }
 
-static enum protolayer_cb_result pl_tls_unwrap(void *sess_data, void *iter_data,
-                                               struct protolayer_cb_ctx *ctx)
+static enum protolayer_iter_cb_result pl_tls_unwrap(void *sess_data, void *iter_data,
+                                               struct protolayer_iter_ctx *ctx)
 {
        struct pl_tls_sess_data *tls = sess_data;
        struct session2 *s = ctx->manager->session;
@@ -1144,7 +1144,7 @@ static enum protolayer_cb_result pl_tls_unwrap(void *sess_data, void *iter_data,
                if (kr_fails_assert(queue_len(tls->unwrap_queue) == 1))
                        return protolayer_break(ctx, kr_error(EINVAL));
 
-               struct protolayer_cb_ctx *ctx_head = queue_head(tls->unwrap_queue);
+               struct protolayer_iter_ctx *ctx_head = queue_head(tls->unwrap_queue);
                if (kr_fails_assert(ctx == ctx_head)) {
                        protolayer_break(ctx, kr_error(EINVAL));
                        ctx = ctx_head;
@@ -1197,8 +1197,8 @@ static ssize_t pl_tls_submit(gnutls_session_t tls_session,
        return kr_error(EINVAL);
 }
 
-static enum protolayer_cb_result pl_tls_wrap(void *sess_data, void *iter_data,
-                                             struct protolayer_cb_ctx *ctx)
+static enum protolayer_iter_cb_result pl_tls_wrap(void *sess_data, void *iter_data,
+                                             struct protolayer_iter_ctx *ctx)
 {
        struct pl_tls_sess_data *tls = sess_data;
        gnutls_session_t tls_session = tls->tls_session;
index b1ba883e38129249caa3cb9f2f8d6b776e6b7719..e57d0cacf95dd814ac19e03514c31ccbbfbfe545 100644 (file)
@@ -1909,8 +1909,8 @@ static bool pl_dns_dgram_event_unwrap(enum protolayer_event_type event,
        return true;
 }
 
-static enum protolayer_cb_result pl_dns_dgram_unwrap(
-               void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
+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;
 
@@ -2232,8 +2232,8 @@ static knot_pkt_t *produce_stream_packet(struct wire_buf *wb)
        return pkt;
 }
 
-static enum protolayer_cb_result pl_dns_stream_unwrap(
-               void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
+static enum protolayer_iter_cb_result pl_dns_stream_unwrap(
+               void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx)
 {
        if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)) {
                /* DNS stream only works with a wire buffer */
@@ -2277,8 +2277,8 @@ struct sized_iovs {
        struct iovec iovs[];
 };
 
-static enum protolayer_cb_result pl_dns_stream_wrap(
-               void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
+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;