struct pl_udp_iter_data {
+ PROTOLAYER_DATA_HEADER();
struct proxy_result proxy;
bool has_proxy;
};
-static int pl_udp_iter_init(struct protolayer_manager *manager, struct protolayer_data *layer)
+static int pl_udp_iter_init(struct protolayer_manager *manager, void *iter_data)
{
- struct pl_udp_iter_data *udp = protolayer_iter_data(layer);
+ struct pl_udp_iter_data *udp = iter_data;
*udp = (struct pl_udp_iter_data){0};
return 0;
}
-static enum protolayer_cb_result pl_udp_unwrap(struct protolayer_data *layer, struct protolayer_cb_ctx *ctx)
+static enum protolayer_cb_result pl_udp_unwrap(
+ void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
{
ctx->payload = protolayer_as_buffer(&ctx->payload);
if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER)) {
}
struct session2 *s = ctx->manager->session;
- struct pl_udp_iter_data *udp = protolayer_iter_data(layer);
+ struct pl_udp_iter_data *udp = iter_data;
char *data = ctx->payload.buffer.buf;
ssize_t data_len = ctx->payload.buffer.len;
static bool pl_udp_event_wrap(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) {
the_worker->stats.err_udp += 1;
struct pl_tcp_sess_data {
+ PROTOLAYER_DATA_HEADER();
struct proxy_result proxy;
struct wire_buf wire_buf;
bool had_data : 1;
bool has_proxy : 1;
};
-static int pl_tcp_sess_init(struct protolayer_manager *manager, struct protolayer_data *layer, void *param)
+static int pl_tcp_sess_init(struct protolayer_manager *manager, void *sess_data, void *param)
{
- struct pl_tcp_sess_data *tcp = protolayer_sess_data(layer);
+ struct pl_tcp_sess_data *tcp = sess_data;
*tcp = (struct pl_tcp_sess_data){0};
return 0;
}
-static int pl_tcp_sess_deinit(struct protolayer_manager *manager, struct protolayer_data *layer)
+static int pl_tcp_sess_deinit(struct protolayer_manager *manager, void *sess_data)
{
- struct pl_tcp_sess_data *tcp = protolayer_sess_data(layer);
+ struct pl_tcp_sess_data *tcp = sess_data;
wire_buf_deinit(&tcp->wire_buf);
return 0;
}
-static enum protolayer_cb_result pl_tcp_unwrap(struct protolayer_data *layer, struct protolayer_cb_ctx *ctx)
+static enum protolayer_cb_result pl_tcp_unwrap(
+ void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
{
struct session2 *s = ctx->manager->session;
- struct pl_tcp_sess_data *tcp = protolayer_sess_data(layer);
+ struct pl_tcp_sess_data *tcp = sess_data;
struct sockaddr *peer = session2_get_peer(s);
if (ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER) {
static bool pl_tcp_event_wrap(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) {
the_worker->stats.err_tcp += 1;
}
-/** Gets context for the layer with the specified index from the manager. */
-static inline struct protolayer_data *protolayer_manager_get(
+/** Gets layer-specific session data for the layer with the specified index
+ * from the manager. */
+static inline struct protolayer_data *protolayer_sess_data_get(
struct protolayer_manager *m, size_t layer_ix)
{
if (kr_fails_assert(layer_ix < m->num_layers))
return NULL;
- const size_t *offsets = (size_t *)m->data;
- char *pl_data_beg = m->data + (m->num_layers * sizeof(*offsets));
- return (struct protolayer_data *)(pl_data_beg + offsets[layer_ix]);
+ /* See doc comment of `struct protolayer_manager::data` */
+ const ssize_t *offsets = (ssize_t *)m->data;
+ char *pl_data_beg = &m->data[2 * m->num_layers * sizeof(*offsets)];
+ ssize_t offset = offsets[layer_ix];
+
+ if (offset < 0) /* No session data for this layer */
+ return NULL;
+
+ return (struct protolayer_data *)(pl_data_beg + offset);
+}
+
+/** Gets layer-specific iteration data for the layer with the specified index
+ * from the context. */
+static inline struct protolayer_data *protolayer_iter_data_get(
+ struct protolayer_cb_ctx *ctx, size_t layer_ix)
+{
+ struct protolayer_manager *m = ctx->manager;
+ if (kr_fails_assert(layer_ix < m->num_layers))
+ return NULL;
+
+ /* See doc comment of `struct protolayer_manager::data` */
+ const ssize_t *offsets = (ssize_t *)&m->data[m->num_layers * sizeof(*offsets)];
+ ssize_t offset = offsets[layer_ix];
+
+ if (offset < 0) /* No iteration data for this layer */
+ return NULL;
+
+ return (struct protolayer_data *)(ctx->data + offset);
}
static inline ssize_t protolayer_manager_get_protocol(
struct protolayer_manager *m, enum protolayer_protocol protocol)
{
for (ssize_t i = 0; i < m->num_layers; i++) {
- struct protolayer_data *d = protolayer_manager_get(m, i);
- if (d->protocol == protocol)
+ enum protolayer_protocol found = protolayer_grps[m->grp][i];
+ if (protocol == found)
return i;
}
ctx->layer_ix--;
}
-static int protolayer_cb_ctx_finish(struct protolayer_cb_ctx *ctx, int ret,
- bool deinit_iter_data)
+static int protolayer_cb_ctx_finish(struct protolayer_cb_ctx *ctx, int ret)
{
struct session2 *session = ctx->manager->session;
- if (deinit_iter_data) {
- struct protolayer_manager *m = ctx->manager;
- struct protolayer_globals *globals = &protolayer_globals[m->grp];
- for (size_t i = 0; i < m->num_layers; i++) {
- struct protolayer_data *d = protolayer_manager_get(m, i);
- if (globals->iter_deinit)
- globals->iter_deinit(m, d);
- }
- m->iter_data_inited = false;
+ struct protolayer_manager *m = ctx->manager;
+ struct protolayer_globals *globals = &protolayer_globals[m->grp];
+ for (size_t i = 0; i < m->num_layers; i++) {
+ struct protolayer_data *d = protolayer_iter_data_get(ctx, i);
+ if (globals->iter_deinit)
+ globals->iter_deinit(m, d);
}
if (ret)
{
struct protolayer_cb_ctx *ctx = baton;
ctx->status = status;
- protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL, true);
+ protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL);
}
/** Pushes the specified protocol layer's payload to the session's transport. */
if (status < 0) {
ctx->status = status;
- return protolayer_cb_ctx_finish(ctx, status, true);
+ return protolayer_cb_ctx_finish(ctx, status);
}
return PROTOLAYER_RET_ASYNC;
static int protolayer_step(struct protolayer_cb_ctx *ctx)
{
while (true) {
- struct protolayer_data *ldata = protolayer_manager_get(
- ctx->manager, ctx->layer_ix);
- if (kr_fails_assert(ldata)) {
- /* Probably layer index or data corruption */
- return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL), true);
- }
-
- enum protolayer_protocol protocol = ldata->protocol;
+ enum protolayer_protocol protocol = protolayer_grps[ctx->manager->grp][ctx->layer_ix];
struct protolayer_globals *globals = &protolayer_globals[protocol];
- enum protolayer_cb_result result = PROTOLAYER_CB_RESULT_MAGIC;
- if (!ldata->processed) { /* Avoid repetition */
- ctx->async_mode = false;
- ctx->status = 0;
- ctx->action = PROTOLAYER_CB_ACTION_NULL;
-
- protolayer_cb cb = (ctx->direction == PROTOLAYER_UNWRAP)
- ? globals->unwrap : globals->wrap;
-
- if (cb)
- result = cb(ldata, ctx);
- else
- ctx->action = PROTOLAYER_CB_ACTION_CONTINUE;
-
- ldata->processed = true;
+ ctx->async_mode = false;
+ ctx->status = 0;
+ ctx->action = PROTOLAYER_CB_ACTION_NULL;
+
+ protolayer_cb cb = (ctx->direction == PROTOLAYER_UNWRAP)
+ ? globals->unwrap : globals->wrap;
+
+ if (cb) {
+ struct protolayer_data *sess_data = protolayer_sess_data_get(
+ ctx->manager, ctx->layer_ix);
+ struct protolayer_data *iter_data = protolayer_iter_data_get(
+ ctx, ctx->layer_ix);
+ enum protolayer_cb_result result = cb(sess_data, iter_data, ctx);
+ if (kr_fails_assert(result == PROTOLAYER_CB_RESULT_MAGIC)) {
+ /* Callback did not use a continuation function to return. */
+ return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL));
+ }
} else {
- kr_assert(false && "Repeated protocol layer step");
- //kr_log_debug(PROTOLAYER, "Repeated protocol layer step\n");
+ ctx->action = PROTOLAYER_CB_ACTION_CONTINUE;
}
- if (kr_fails_assert(result == PROTOLAYER_CB_RESULT_MAGIC)) {
- /* Callback did not use a continuation function to return. */
- return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL), true);
- }
if (!ctx->action) {
/* Next step is from a callback */
if (ctx->action == PROTOLAYER_CB_ACTION_BREAK) {
return protolayer_cb_ctx_finish(
- ctx, PROTOLAYER_RET_NORMAL, true);
+ ctx, PROTOLAYER_RET_NORMAL);
}
if (kr_fails_assert(ctx->status == 0)) {
/* Status should be zero without a BREAK. */
- return protolayer_cb_ctx_finish(
- ctx, kr_error(ECANCELED), true);
+ return protolayer_cb_ctx_finish(ctx, kr_error(ECANCELED));
}
if (ctx->action == PROTOLAYER_CB_ACTION_CONTINUE) {
return protolayer_push(ctx);
return protolayer_cb_ctx_finish(
- ctx, PROTOLAYER_RET_NORMAL, true);
+ ctx, PROTOLAYER_RET_NORMAL);
}
protolayer_cb_ctx_next(ctx);
/* Should never get here */
kr_assert(false && "Invalid layer callback action");
- return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL), true);
+ return protolayer_cb_ctx_finish(ctx, kr_error(EINVAL));
}
}
struct protolayer_payload payload, const void *target,
protolayer_finished_cb cb, void *baton)
{
- struct protolayer_cb_ctx *ctx = malloc(sizeof(*ctx)); // TODO - mempool?
+ struct protolayer_cb_ctx *ctx = malloc(manager->cb_ctx_size);
kr_require(ctx);
if (kr_log_is_debug(PROTOLAYER, NULL)) {
layer_ix);
}
- for (size_t i = 0; i < manager->num_layers; i++) {
- struct protolayer_data *data = protolayer_manager_get(manager, i);
- data->processed = false;
- struct protolayer_globals *globals = &protolayer_globals[data->protocol];
- if (globals->iter_init)
- globals->iter_init(manager, data);
- }
-
*ctx = (struct protolayer_cb_ctx) {
.payload = payload,
.target = target,
.finished_cb_baton = baton
};
+ for (size_t i = 0; i < manager->num_layers; i++) {
+ enum protolayer_protocol p = protolayer_grps[manager->grp][i];
+ struct protolayer_globals *globals = &protolayer_globals[p];
+ struct protolayer_data *iter_data = protolayer_iter_data_get(ctx, i);
+ if (iter_data) {
+ bzero(iter_data, globals->iter_size);
+ iter_data->protocol = p;
+ iter_data->session = manager->session;
+ }
+
+ if (globals->iter_init)
+ globals->iter_init(manager, iter_data);
+ }
+
return protolayer_step(ctx);
}
struct protolayer_data_param *layer_param,
size_t layer_param_count)
{
- if (kr_fails_assert(grp))
+ if (kr_fails_assert(s && grp))
return NULL;
size_t num_layers = 0;
- size_t size = sizeof(struct protolayer_manager);
+ size_t manager_size = sizeof(struct protolayer_manager);
+ size_t cb_ctx_size = sizeof(struct protolayer_cb_ctx);
+
enum protolayer_protocol *protocols = protolayer_grps[grp];
if (kr_fails_assert(protocols))
return NULL;
num_layers++;
if (kr_fails_assert(num_layers))
return NULL;
- size_t offsets[num_layers];
- size += sizeof(offsets);
+
+ ssize_t offsets[2 * num_layers];
+ manager_size += sizeof(offsets);
+
+ ssize_t *sess_offsets = offsets;
+ ssize_t *iter_offsets = &offsets[num_layers];
/* Space for layer-specific data, guaranteeing alignment */
- size_t total_data_size = 0;
+ size_t total_sess_data_size = 0;
+ size_t total_iter_data_size = 0;
for (size_t i = 0; i < num_layers; i++) {
- offsets[i] = total_data_size;
- total_data_size += ALIGN_TO(sizeof(struct protolayer_data),
- CPU_STRUCT_ALIGN);
- total_data_size += ALIGN_TO(protolayer_globals[protocols[i]].sess_size,
+ sess_offsets[i] = protolayer_globals[protocols[i]].sess_size
+ ? total_sess_data_size : -1;
+ total_sess_data_size += ALIGN_TO(protolayer_globals[protocols[i]].sess_size,
CPU_STRUCT_ALIGN);
- total_data_size += ALIGN_TO(protolayer_globals[protocols[i]].iter_size,
+
+ iter_offsets[i] = protolayer_globals[protocols[i]].iter_size
+ ? total_iter_data_size : -1;
+ total_iter_data_size += ALIGN_TO(protolayer_globals[protocols[i]].iter_size,
CPU_STRUCT_ALIGN);
}
- size += total_data_size;
+ manager_size += total_sess_data_size;
+ cb_ctx_size += total_iter_data_size;
/* Allocate and initialize manager */
- struct protolayer_manager *m = calloc(1, size);
+ struct protolayer_manager *m = calloc(1, manager_size);
kr_require(m);
m->grp = grp;
m->session = s;
m->num_layers = num_layers;
+ m->cb_ctx_size = cb_ctx_size;
memcpy(m->data, offsets, sizeof(offsets));
- /* Initialize layer data */
+ /* Initialize the layer's session data */
for (size_t i = 0; i < num_layers; i++) {
struct protolayer_globals *globals = &protolayer_globals[protocols[i]];
- struct protolayer_data *data = protolayer_manager_get(m, i);
- data->manager = m;
- data->protocol = protocols[i];
- data->sess_size = ALIGN_TO(globals->sess_size, CPU_STRUCT_ALIGN);
+ struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
+ if (sess_data) {
+ bzero(sess_data, globals->sess_size);
+ sess_data->session = s;
+ sess_data->protocol = protocols[i];
+ }
+
void *param = get_init_param(protocols[i], layer_param, layer_param_count);
if (globals->sess_init)
- globals->sess_init(m, data, param);
+ globals->sess_init(m, sess_data, param);
}
return m;
if (!m) return;
for (size_t i = 0; i < m->num_layers; i++) {
- struct protolayer_data *data = protolayer_manager_get(m, i);
- struct protolayer_globals *globals = &protolayer_globals[data->protocol];
- if (globals->sess_deinit)
- globals->sess_deinit(m, data);
+ enum protolayer_protocol p = protolayer_grps[m->grp][i];
+ struct protolayer_globals *globals = &protolayer_globals[p];
+ if (globals->sess_deinit) {
+ struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
+ globals->sess_deinit(m, sess_data);
+ }
}
free(m);
{
ctx->status = status;
if (ctx->async_mode) {
- protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL, true);
+ protolayer_cb_ctx_finish(ctx, PROTOLAYER_RET_NORMAL);
} else {
ctx->action = PROTOLAYER_CB_ACTION_BREAK;
}
bool cont;
struct protolayer_manager *m = s->layers;
for (ssize_t i = m->num_layers - 1; i >= 0; i--) {
- struct protolayer_data *data = protolayer_manager_get(m, i);
- struct protolayer_globals *globals = &protolayer_globals[data->protocol];
- if (globals->event_wrap)
- cont = globals->event_wrap(event, &baton, m, data);
- else
+ enum protolayer_protocol p = protolayer_grps[s->layers->grp][i];
+ struct protolayer_globals *globals = &protolayer_globals[p];
+ if (globals->event_wrap) {
+ struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
+ cont = globals->event_wrap(event, &baton, m, sess_data);
+ } else {
cont = true;
+ }
if (!cont)
return;
bool cont;
struct protolayer_manager *m = s->layers;
for (ssize_t i = start_ix; i < m->num_layers; i++) {
- struct protolayer_data *data = protolayer_manager_get(m, i);
- struct protolayer_globals *globals = &protolayer_globals[data->protocol];
- if (globals->event_unwrap)
- cont = globals->event_unwrap(event, &baton, m, data);
- else
+ enum protolayer_protocol p = protolayer_grps[s->layers->grp][i];
+ struct protolayer_globals *globals = &protolayer_globals[p];
+ if (globals->event_unwrap) {
+ struct protolayer_data *sess_data = protolayer_sess_data_get(m, i);
+ cont = globals->event_unwrap(event, &baton, m, sess_data);
+ } else {
cont = true;
+ }
if (!cont)
return;
struct protolayer_manager *manager;
int status;
enum protolayer_cb_action action;
+
+ /** This contains variably-sized layer-specific data. See `struct
+ * protolayer_manager::data`. */
+ alignas(CPU_STRUCT_ALIGN) char data[];
};
/** Convenience function to get a buffer-type payload. */
* to be reused. */
struct protolayer_payload protolayer_as_buffer(const struct protolayer_payload *payload);
+/** Mandatory header members for any layer-specific data. */
+#define PROTOLAYER_DATA_HEADER() struct {\
+ enum protolayer_protocol protocol;\
+ struct session2 *session; /**< Pointer to the owner session. */\
+}
-/** Per-session layer-specific data - generic struct. */
+/** Layer-specific data - generic struct. */
struct protolayer_data {
- enum protolayer_protocol protocol;
- size_t sess_size; /**< Size of the session data (aligned). */
- size_t iter_size; /**< Size of the iteration data (aligned). */
- struct protolayer_manager *manager; /**< Pointer to the owner manager. */
- bool processed : 1; /**< Internal safeguard so that the layer does not
- * get executed multiple times on the same buffer. */
- alignas(CPU_STRUCT_ALIGN) uint8_t data[]; /**< Memory for the layer-specific structs. */
+ PROTOLAYER_DATA_HEADER();
};
-/** Get a pointer to the session data of the layer. This data shares
- * its lifetime with a session. */
-static inline void *protolayer_sess_data(struct protolayer_data *d)
-{
- return d->data;
-}
-
-/** Gets a pointer to the iteration data of the layer. This data shares its
- * lifetime with an iteration through layers; it is also kept intact when
- * an iteration ends with a `_WAIT` action. */
-static inline void *protolayer_iter_data(struct protolayer_data *d)
-{
- return d->data + d->sess_size;
-}
-
/** Return value of `protolayer_cb` callbacks. To be generated by continuation
* functions, never returned directly. */
enum protolayer_cb_result {
* call one of the *layer sequence return functions*. The pointed-to function
* must return the result of such a return function. */
typedef enum protolayer_cb_result (*protolayer_cb)(
- struct protolayer_data *layer, struct protolayer_cb_ctx *ctx);
+ void *sess_data,
+ void *iter_data,
+ struct protolayer_cb_ctx *ctx);
/** Function type for `event_wrap` and `event_unwrap` callbacks of layers.
* `baton` always points to some memory; it may be modified accommodate for
typedef bool (*protolayer_event_cb)(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer);
+ void *sess_data);
/** Function type for initialization callbacks of layer session data, with
* `param`, if any is passed to the layer.
* Returning 0 means success, other return values mean error and halt the
* initialization. */
typedef int (*protolayer_data_sess_init_cb)(struct protolayer_manager *manager,
- struct protolayer_data *layer,
+ void *data,
void *param);
/** Function type for (de)initialization callbacks of layers.
* Returning 0 means success, other return values mean error and halt the
* initialization. */
typedef int (*protolayer_data_cb)(struct protolayer_manager *manager,
- struct protolayer_data *layer);
+ void *data);
/** A collection of protocol layers and their layer-specific data. */
struct protolayer_manager {
enum protolayer_grp grp;
- /* TODO: move iter data to `struct protolayer_cb_ctx` */
- bool iter_data_inited : 1; /**< True: layers' iteration data is
- * initialized (e.g. from a previous
- * iteration). */
struct session2 *session;
size_t num_layers;
- char data[];
+ size_t cb_ctx_size;
+
+ /** The following flexible array has basically this structure:
+ *
+ * struct {
+ * size_t sess_offsets[num_layers];
+ * size_t iter_offsets[num_layers];
+ * variably-sized-data sess_data[num_layers];
+ * }
+ *
+ * It is done this way, because different layer groups will have
+ * different numbers of layers and differently-sized layer-specific
+ * data. C does not have a convenient way to define this in structs, so
+ * we do it via this flexible array.
+ *
+ * `sess_offsets` determines data offsets in `sess_data`.
+ *
+ * `iter_offsets` determines data offsets in
+ * `struct protolayer_cb_ctx::data`. */
+ alignas(CPU_STRUCT_ALIGN) char data[];
};
/** Initialization parameters for protocol layer session data. */
typedef queue_t(struct protolayer_cb_ctx *) pl_cb_ctx_queue_t;
struct pl_tls_sess_data {
+ PROTOLAYER_DATA_HEADER();
bool client_side;
gnutls_session_t tls_session;
tls_hs_state_t handshake_state;
static ssize_t kres_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len)
{
- struct protolayer_data *layer = h;
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
+ struct pl_tls_sess_data *tls = h;
if (kr_fails_assert(tls)) {
errno = EFAULT;
return -1;
}
struct kres_gnutls_push_ctx {
- struct protolayer_data *layer;
+ void *sess_data;
struct iovec iov[];
};
const void *target, void *baton)
{
struct kres_gnutls_push_ctx *push_ctx = baton;
- struct pl_tls_sess_data *tls = protolayer_sess_data(push_ctx->layer);
+ struct pl_tls_sess_data *tls = push_ctx->sess_data;
while (queue_len(tls->wrap_queue)) {
struct protolayer_cb_ctx *ctx = queue_head(tls->wrap_queue);
protolayer_break(ctx, kr_ok());
static ssize_t kres_gnutls_vec_push(gnutls_transport_ptr_t h, const giovec_t * iov, int iovcnt)
{
- struct protolayer_data *layer = h;
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
+ struct pl_tls_sess_data *tls = h;
if (kr_fails_assert(tls)) {
errno = EFAULT;
return -1;
struct kres_gnutls_push_ctx *push_ctx =
malloc(sizeof(*push_ctx) + sizeof(struct iovec[iovcnt]));
kr_require(push_ctx);
- push_ctx->layer = layer;
+ push_ctx->sess_data = tls;
memcpy(push_ctx->iov, iov, sizeof(struct iovec[iovcnt]));
- session2_wrap_after(layer->manager->session, PROTOLAYER_TLS,
+ session2_wrap_after(tls->session, PROTOLAYER_TLS,
protolayer_iovec(push_ctx->iov, iovcnt), NULL,
kres_gnutls_push_finished, push_ctx);
static int tls_pull_timeout_func(gnutls_transport_ptr_t h, unsigned int ms)
{
- struct protolayer_data *layer = h;
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
+ struct pl_tls_sess_data *tls = h;
if (kr_fails_assert(tls)) {
errno = EFAULT;
return -1;
}
static int pl_tls_sess_server_init(struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ struct pl_tls_sess_data *tls)
{
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
if (kr_fails_assert(the_worker && the_engine))
return kr_error(EINVAL);
gnutls_transport_set_pull_function(tls->tls_session, kres_gnutls_pull);
gnutls_transport_set_vec_push_function(tls->tls_session, kres_gnutls_vec_push);
- gnutls_transport_set_ptr(tls->tls_session, layer);
+ gnutls_transport_set_ptr(tls->tls_session, tls);
if (the_network->tls_session_ticket_ctx) {
tls_session_ticket_enable(the_network->tls_session_ticket_ctx,
}
static int pl_tls_sess_client_init(struct protolayer_manager *manager,
- struct protolayer_data *layer,
+ struct pl_tls_sess_data *tls,
tls_client_param_t *param)
{
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
unsigned int flags = GNUTLS_CLIENT | GNUTLS_NONBLOCK
#ifdef GNUTLS_ENABLE_FALSE_START
| GNUTLS_ENABLE_FALSE_START
gnutls_transport_set_pull_function(tls->tls_session, kres_gnutls_pull);
gnutls_transport_set_vec_push_function(tls->tls_session, kres_gnutls_vec_push);
- gnutls_transport_set_ptr(tls->tls_session, layer);
+ gnutls_transport_set_ptr(tls->tls_session, tls);
return kr_ok();
}
static int pl_tls_sess_init(struct protolayer_manager *manager,
- struct protolayer_data *layer,
+ void *sess_data,
void *param)
{
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
- *tls = (struct pl_tls_sess_data){0};
+ struct pl_tls_sess_data *tls = sess_data;
manager->session->secure = true;
queue_init(tls->unwrap_queue);
queue_init(tls->wrap_queue);
if (manager->session->outgoing)
- return pl_tls_sess_client_init(manager, layer, param);
+ return pl_tls_sess_client_init(manager, tls, param);
else
- return pl_tls_sess_server_init(manager, layer);
+ return pl_tls_sess_server_init(manager, tls);
}
static int pl_tls_sess_deinit(struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
- return pl_tls_sess_data_deinit(tls);
+ return pl_tls_sess_data_deinit(sess_data);
}
-static enum protolayer_cb_result pl_tls_unwrap(struct protolayer_data *layer,
+static enum protolayer_cb_result pl_tls_unwrap(void *sess_data, void *iter_data,
struct protolayer_cb_ctx *ctx)
{
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
+ struct pl_tls_sess_data *tls = sess_data;
struct session2 *s = ctx->manager->session;
queue_push(tls->unwrap_queue, ctx);
return protolayer_continue(ctx);
}
-static ssize_t pl_tls_submit(struct protolayer_data *layer,
- gnutls_session_t tls_session,
+static ssize_t pl_tls_submit(gnutls_session_t tls_session,
struct protolayer_payload payload)
{
if (payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)
return kr_error(EINVAL);
}
-static enum protolayer_cb_result pl_tls_wrap(struct protolayer_data *layer,
+static enum protolayer_cb_result pl_tls_wrap(void *sess_data, void *iter_data,
struct protolayer_cb_ctx *ctx)
{
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
+ struct pl_tls_sess_data *tls = sess_data;
gnutls_session_t tls_session = tls->tls_session;
gnutls_record_cork(tls_session);
- ssize_t submitted = pl_tls_submit(layer, tls_session, ctx->payload);
+ ssize_t submitted = pl_tls_submit(tls_session, ctx->payload);
if (submitted < 0) {
VERBOSE_MSG(tls->client_side, "pl_tls_submit failed: %s (%zd)\n",
gnutls_strerror_name(submitted), submitted);
static bool pl_tls_event_unwrap(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
struct session2 *s = manager->session;
- struct pl_tls_sess_data *tls = protolayer_sess_data(layer);
+ struct pl_tls_sess_data *tls = sess_data;
if (event == PROTOLAYER_EVENT_CLOSE) {
tls_close(tls, s, true); /* WITH gnutls_bye */
static bool pl_tls_event_wrap(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
if (event == PROTOLAYER_EVENT_STATS_SEND_ERR) {
the_worker->stats.err_tls += 1;
static bool pl_dns_dgram_event_unwrap(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
if (event != PROTOLAYER_EVENT_TIMEOUT)
return true;
}
static enum protolayer_cb_result pl_dns_dgram_unwrap(
- struct protolayer_data *layer, struct protolayer_cb_ctx *ctx)
+ void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
{
struct session2 *session = ctx->manager->session;
}
struct pl_dns_stream_sess_data {
+ PROTOLAYER_DATA_HEADER();
bool single : 1; /**< True: Stream only allows a single packet */
bool produced : 1; /**< True: At least one packet has been produced */
};
struct pl_dns_stream_iter_data {
+ PROTOLAYER_DATA_HEADER();
struct {
knot_mm_t *pool;
void *mem;
}
static int pl_dns_mstream_sess_init(struct protolayer_manager *manager,
- struct protolayer_data *layer,
+ void *sess_data,
void *param)
{
- struct pl_dns_stream_sess_data *stream = protolayer_sess_data(layer);
+ struct pl_dns_stream_sess_data *stream = sess_data;
pl_dns_stream_sess_init_common(manager->session, stream, false);
return kr_ok();
}
static int pl_dns_sstream_sess_init(struct protolayer_manager *manager,
- struct protolayer_data *layer,
+ void *sess_data,
void *param)
{
- struct pl_dns_stream_sess_data *stream = protolayer_sess_data(layer);
+ struct pl_dns_stream_sess_data *stream = sess_data;
pl_dns_stream_sess_init_common(manager->session, stream, true);
return kr_ok();
}
static int pl_dns_stream_iter_init(struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *iter_data)
{
- struct pl_dns_stream_iter_data *stream = protolayer_iter_data(layer);
+ struct pl_dns_stream_iter_data *stream = iter_data;
*stream = (struct pl_dns_stream_iter_data){0};
return kr_ok();
}
static int pl_dns_stream_iter_deinit(struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *iter_data)
{
- struct pl_dns_stream_iter_data *stream = protolayer_iter_data(layer);
+ struct pl_dns_stream_iter_data *stream = iter_data;
mm_free(stream->sent.pool, stream->sent.mem);
return kr_ok();
}
static bool pl_dns_stream_event_unwrap(enum protolayer_event_type event,
void **baton,
struct protolayer_manager *manager,
- struct protolayer_data *layer)
+ void *sess_data)
{
struct session2 *session = manager->session;
if (session->closing)
}
static enum protolayer_cb_result pl_dns_stream_unwrap(
- struct protolayer_data *layer, struct protolayer_cb_ctx *ctx)
+ void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
{
if (kr_fails_assert(ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF)) {
/* DNS stream only works with a wire buffer */
}
struct session2 *session = ctx->manager->session;
- struct pl_dns_stream_sess_data *stream = protolayer_sess_data(layer);
+ struct pl_dns_stream_sess_data *stream_sess = sess_data;
struct wire_buf *wb = ctx->payload.wire_buf;
knot_pkt_t *pkt;
while ((pkt = produce_stream_packet(wb))) {
- if (stream->single && stream->produced) {
+ if (stream_sess->single && stream_sess->produced) {
if (kr_log_is_debug(WORKER, NULL)) {
kr_log_debug(WORKER, "Unexpected extra data from %s\n",
kr_straddr(ctx->comm.src_addr));
return protolayer_break(ctx, KNOT_EMALF);
}
- stream->produced = true;
+ stream_sess->produced = true;
if (!pkt)
return protolayer_break(ctx, KNOT_EMALF);
};
static enum protolayer_cb_result pl_dns_stream_wrap(
- struct protolayer_data *layer, struct protolayer_cb_ctx *ctx)
+ void *sess_data, void *iter_data, struct protolayer_cb_ctx *ctx)
{
- struct pl_dns_stream_iter_data *stream = protolayer_iter_data(layer);
+ struct pl_dns_stream_iter_data *stream = iter_data;
struct session2 *s = ctx->manager->session;
if (kr_fails_assert(!stream->sent.mem))