Download raw body.
[3/7] relayd: convert control imsg forwarding to imsg_forward()
[3/7] relayd: convert control imsg forwarding to imsg_forward()
On Sun, Jun 07, 2026 at 09:01:24AM +0200, Rafael Sadowski wrote:
> This is a series of commits for an imsg APIv2 rework in relayd. These
> were committed and tested individually. They can be reviewed in their
> entirety here:
>
> gothub: https://rsadowski.gothub.org/?action=summary&headref=imsg_v2&path=relayd.git
> PR: https://codeberg.org/rsadowski/relayd/pulls/1/files
>
> commit cdac3e43ca7856c92948a16de7bd0e4ec3e12f26
> Author: Rafael Sadowski <rafael@sizeofvoid.org>
> Date: Sat Jun 6 16:22:49 2026 +0200
>
> relayd: convert control imsg forwarding to imsg_forward()
>
> Rework control_imsg_forward() to forward the message unaltered via
> imsg_forward() instead of rebuilding it with imsg_compose_event().
>
> read the type via imsg_get_type(), dropping the manual header-length
> Switch to use read the payload with imsg_get_data() and checks and the
> memcpy() that wrote the data back into the imsg before forwarding.
>
> diff --git a/control.c b/control.c
> index 6c29f2b..fe829ce 100644
> --- a/control.c
> +++ b/control.c
> @@ -228,7 +228,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
> struct imsg imsg;
> struct ctl_id id;
> int n;
> - int verbose;
> + int verb;
> struct relayd *env = cs->cs_env;
> struct privsep *ps = env->sc_ps;
>
> @@ -238,7 +238,11 @@ control_dispatch_imsg(int fd, short event, void *arg)
> }
>
> if (event & EV_READ) {
> - if (imsgbuf_read(&c->iev.ibuf) != 1) {
> + switch (imsgbuf_read(&c->iev.ibuf)) {
> + case -1:
> + fatal("%s: imsgbuf_read", __func__);
> + break;
> + case 0:
> control_close(fd, cs);
> return;
> }
> @@ -262,13 +266,13 @@ control_dispatch_imsg(int fd, short event, void *arg)
>
> if (c->waiting) {
> log_debug("%s: unexpected imsg %d",
> - __func__, imsg.hdr.type);
> + __func__, imsg_get_type(&imsg));
> imsg_free(&imsg);
> control_close(fd, cs);
> return;
> }
>
> - switch (imsg.hdr.type) {
> + switch (imsg_get_type(&imsg)) {
> case IMSG_CTL_SHOW_SUM:
> show(c);
> break;
> @@ -276,85 +280,79 @@ control_dispatch_imsg(int fd, short event, void *arg)
> show_sessions(c);
> break;
> case IMSG_CTL_RDR_DISABLE:
> - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
> - fatalx("invalid imsg header len");
> - memcpy(&id, imsg.data, sizeof(id));
> + if (imsg_get_data(&imsg, &id, sizeof(id)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
> +
> if (disable_rdr(c, &id))
> imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> else {
> - memcpy(imsg.data, &id, sizeof(id));
> - control_imsg_forward(ps, &imsg);
> + control_imsg_forward(&imsg);
> imsg_compose_event(&c->iev, IMSG_CTL_OK,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> }
> break;
> case IMSG_CTL_RDR_ENABLE:
> - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
> - fatalx("invalid imsg header len");
> - memcpy(&id, imsg.data, sizeof(id));
> + if (imsg_get_data(&imsg, &id, sizeof(id)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
> +
> if (enable_rdr(c, &id))
> imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> else {
> - memcpy(imsg.data, &id, sizeof(id));
> - control_imsg_forward(ps, &imsg);
> + control_imsg_forward(&imsg);
> imsg_compose_event(&c->iev, IMSG_CTL_OK,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> }
> break;
> case IMSG_CTL_TABLE_DISABLE:
> - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
> - fatalx("invalid imsg header len");
> - memcpy(&id, imsg.data, sizeof(id));
> + if (imsg_get_data(&imsg, &id, sizeof(id)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
> +
> if (disable_table(c, &id))
> imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> else {
> - memcpy(imsg.data, &id, sizeof(id));
> - control_imsg_forward(ps, &imsg);
> + control_imsg_forward(&imsg);
> imsg_compose_event(&c->iev, IMSG_CTL_OK,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> }
> break;
> case IMSG_CTL_TABLE_ENABLE:
> - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
> - fatalx("invalid imsg header len");
> - memcpy(&id, imsg.data, sizeof(id));
> + if (imsg_get_data(&imsg, &id, sizeof(id)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
> +
> if (enable_table(c, &id))
> imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> else {
> - memcpy(imsg.data, &id, sizeof(id));
> - control_imsg_forward(ps, &imsg);
> + control_imsg_forward(&imsg);
> imsg_compose_event(&c->iev, IMSG_CTL_OK,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> }
> break;
> case IMSG_CTL_HOST_DISABLE:
> - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
> - fatalx("invalid imsg header len");
> - memcpy(&id, imsg.data, sizeof(id));
> + if (imsg_get_data(&imsg, &id, sizeof(id)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
> +
> if (disable_host(c, &id, NULL))
> imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> else {
> - memcpy(imsg.data, &id, sizeof(id));
> - control_imsg_forward(ps, &imsg);
> + control_imsg_forward(&imsg);
> imsg_compose_event(&c->iev, IMSG_CTL_OK,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> }
> break;
> case IMSG_CTL_HOST_ENABLE:
> - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
> - fatalx("invalid imsg header len");
> - memcpy(&id, imsg.data, sizeof(id));
> + if (imsg_get_data(&imsg, &id, sizeof(id)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
> +
> if (enable_host(c, &id, NULL))
> imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> else {
> - memcpy(imsg.data, &id, sizeof(id));
> - control_imsg_forward(ps, &imsg);
> + control_imsg_forward(&imsg);
> imsg_compose_event(&c->iev, IMSG_CTL_OK,
> 0, ps->ps_instance + 1, -1, NULL, 0);
> }
> @@ -381,21 +379,19 @@ control_dispatch_imsg(int fd, short event, void *arg)
> c->flags |= CTL_CONN_NOTIFY;
> break;
> case IMSG_CTL_VERBOSE:
> - IMSG_SIZE_CHECK(&imsg, &verbose);
> -
> - memcpy(&verbose, imsg.data, sizeof(verbose));
> + if (imsg_get_data(&imsg, &verb, sizeof(verb)) == -1)
> + fatalx("%s: imsg_get_data", __func__);
>
> proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT);
> proc_forward_imsg(env->sc_ps, &imsg, PROC_HCE);
> proc_forward_imsg(env->sc_ps, &imsg, PROC_RELAY);
>
> - memcpy(imsg.data, &verbose, sizeof(verbose));
> - control_imsg_forward(ps, &imsg);
> - log_setverbose(verbose);
> + control_imsg_forward(&imsg);
> + log_setverbose(verb);
> break;
> default:
> log_debug("%s: error handling imsg %d",
> - __func__, imsg.hdr.type);
> + __func__, imsg_get_type(&imsg));
> break;
> }
> imsg_free(&imsg);
> @@ -405,13 +401,15 @@ control_dispatch_imsg(int fd, short event, void *arg)
> }
>
> void
> -control_imsg_forward(struct privsep *ps, struct imsg *imsg)
> +control_imsg_forward(struct imsg *imsg)
> {
> - struct ctl_conn *c;
> + struct ctl_conn *c;
>
> - TAILQ_FOREACH(c, &ctl_conns, entry)
> - if (c->flags & CTL_CONN_NOTIFY)
> - imsg_compose_event(&c->iev, imsg->hdr.type,
> - 0, ps->ps_instance + 1, -1, imsg->data,
> - imsg->hdr.len - IMSG_HEADER_SIZE);
> + TAILQ_FOREACH(c, &ctl_conns, entry) {
> + if (c->flags & CTL_CONN_NOTIFY) {
> + if (imsg_forward(&c->iev.ibuf, imsg) == -1)
> + fatal("%s: imsg_forward", __func__);
> + imsg_event_add(&c->iev);
> + }
> + }
> }
> diff --git a/pfe.c b/pfe.c
> index 0f865b8..0856ae9 100644
> --- a/pfe.c
> +++ b/pfe.c
> @@ -124,7 +124,7 @@ pfe_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
> struct table *table;
> struct ctl_status st;
>
> - control_imsg_forward(p->p_ps, imsg);
> + control_imsg_forward(imsg);
>
> switch (imsg_get_type(imsg)) {
> case IMSG_HOST_STATUS:
> @@ -737,7 +737,7 @@ pfe_sync(void)
> imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
> imsg.data = &id;
> sync_table(env, rdr, active);
> - control_imsg_forward(env->sc_ps, &imsg);
> + control_imsg_forward(&imsg);
> }
>
> if (rdr->conf.flags & F_DOWN) {
> @@ -750,7 +750,7 @@ pfe_sync(void)
> imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
> imsg.data = &id;
> sync_ruleset(env, rdr, 0);
> - control_imsg_forward(env->sc_ps, &imsg);
> + control_imsg_forward(&imsg);
> }
> } else if (!(rdr->conf.flags & F_ACTIVE_RULESET)) {
> log_debug("%s: enabling ruleset", __func__);
> @@ -760,7 +760,7 @@ pfe_sync(void)
> imsg.hdr.len = sizeof(id) + IMSG_HEADER_SIZE;
> imsg.data = &id;
> sync_ruleset(env, rdr, 1);
> - control_imsg_forward(env->sc_ps, &imsg);
> + control_imsg_forward(&imsg);
> }
> }
>
> diff --git a/relayd.h b/relayd.h
> index 16fe2bf..373255e 100644
> --- a/relayd.h
> +++ b/relayd.h
> @@ -1154,7 +1154,7 @@ int control_init(struct privsep *, struct control_sock *);
> int control_listen(struct control_sock *);
> void control_cleanup(struct control_sock *);
> void control_dispatch_imsg(int, short, void *);
> -void control_imsg_forward(struct privsep *ps, struct imsg *);
> +void control_imsg_forward(struct imsg *);
> struct ctl_conn *
> control_connbyfd(int);
>
>
OK claudio@
--
:wq Claudio
[3/7] relayd: convert control imsg forwarding to imsg_forward()
[3/7] relayd: convert control imsg forwarding to imsg_forward()