From: Rafael Sadowski Subject: httpd: convert proc.c to new imsg API (sync with relayd) To: tech@openbsd.org Cc: Martijn van Duren , "Kirill A. Korinsky" Date: Sun, 28 Jun 2026 20:53:28 +0200 The following diff synchronizes httpd's proc.c with relayd's latest imsg API chnages. httpd: convert proc.c to new imsg API (sync with relayd proc.c) Replace IMSG_SIZE_CHECK() + memcpy() with imsg_get_data(), which does the length check and copy in one call. Use the imsg accessors (imsg_get_*) instead of touching imsg.hdr directly and imsgbuf_get()/imsgbuf_read() instead of imsg_get(). Rewrite proc_forward_imsg() to use imsg_forward() per target imsgbuf instead of re-composing via proc_compose_imsg(); arm the write event with imsg_event_add() after each forward. proc_forward_imsg() never forwarded an fd, and imsg_forward() rewinds the buffer internally, so multiple forwards per message keep working. Drop the now-unused n parameter (all callers passed -1). OK? diff --git a/usr.sbin/httpd/control.c b/usr.sbin/httpd/control.c index 6bbc9a4ce83..6496543bf52 100644 --- a/usr.sbin/httpd/control.c +++ b/usr.sbin/httpd/control.c @@ -269,7 +269,7 @@ control_dispatch_imsg(int fd, short event, void *arg) case IMSG_CTL_SHUTDOWN: case IMSG_CTL_RELOAD: case IMSG_CTL_REOPEN: - proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1); + proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT); break; case IMSG_CTL_NOTIFY: if (c->flags & CTL_CONN_NOTIFY) { @@ -288,8 +288,8 @@ control_dispatch_imsg(int fd, short event, void *arg) memcpy(&verbose, imsg.data, sizeof(verbose)); - proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1); - proc_forward_imsg(env->sc_ps, &imsg, PROC_SERVER, -1); + proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT); + proc_forward_imsg(env->sc_ps, &imsg, PROC_SERVER); memcpy(imsg.data, &verbose, sizeof(verbose)); control_imsg_forward(env->sc_ps, &imsg); diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index e4cac855b4b..d1f1be85d08 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -785,8 +785,8 @@ int proc_composev_imsg(struct privsep *, enum privsep_procid, int, u_int16_t, u_int32_t, int, const struct iovec *, int); int proc_composev(struct privsep *, enum privsep_procid, uint16_t, const struct iovec *, int); -int proc_forward_imsg(struct privsep *, struct imsg *, - enum privsep_procid, int); +void proc_forward_imsg(struct privsep *, struct imsg *, + enum privsep_procid); struct imsgbuf * proc_ibuf(struct privsep *, enum privsep_procid, int); struct imsgev * diff --git a/usr.sbin/httpd/proc.c b/usr.sbin/httpd/proc.c index e75950c1f49..700dcf8da5d 100644 --- a/usr.sbin/httpd/proc.c +++ b/usr.sbin/httpd/proc.c @@ -600,7 +600,7 @@ proc_dispatch(int fd, short event, void *arg) struct imsgbuf *ibuf; struct imsg imsg; ssize_t n; - int verbose; + int ver; const char *title; struct privsep_fd pf; @@ -608,9 +608,11 @@ proc_dispatch(int fd, short event, void *arg) ibuf = &iev->ibuf; if (event & EV_READ) { - if ((n = imsgbuf_read(ibuf)) == -1) + switch (imsgbuf_read(ibuf)) { + case -1: fatal("%s: imsgbuf_read", __func__); - if (n == 0) { + break; + case 0: /* this pipe is dead, so remove the event handler */ event_del(&iev->ev); event_loopexit(NULL); @@ -631,15 +633,16 @@ proc_dispatch(int fd, short event, void *arg) } for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("%s: imsg_get", __func__); + if ((n = imsgbuf_get(ibuf, &imsg)) == -1) + fatal("%s: imsgbuf_get", __func__); if (n == 0) break; #if DEBUG > 1 log_debug("%s: %s %d got imsg %d peerid %d from %s %d", __func__, title, ps->ps_instance + 1, - imsg.hdr.type, imsg.hdr.peerid, p->p_title, imsg.hdr.pid); + imsg_get_type(&imsg), imsg_get_id(&imsg), + p->p_title, imsg_get_pid(&imsg)); #endif /* @@ -654,11 +657,12 @@ proc_dispatch(int fd, short event, void *arg) /* * Generic message handling */ - switch (imsg.hdr.type) { + switch (imsg_get_type(&imsg)) { case IMSG_CTL_VERBOSE: - IMSG_SIZE_CHECK(&imsg, &verbose); - memcpy(&verbose, imsg.data, sizeof(verbose)); - log_setverbose(verbose); + if (imsg_get_data(&imsg, &ver, sizeof(ver)) == -1) + fatalx("%s: imsg_get_data", __func__); + + log_setverbose(ver); break; case IMSG_CTL_PROCFD: if (p->p_id != PROC_PARENT) { @@ -666,17 +670,19 @@ proc_dispatch(int fd, short event, void *arg) "IMSG_CTL_PROCFD from %s", __func__, p->p_title); } - IMSG_SIZE_CHECK(&imsg, &pf); - memcpy(&pf, imsg.data, sizeof(pf)); + + if (imsg_get_data(&imsg, &pf, sizeof(pf)) == -1) + fatalx("%s: imsg_get_data", __func__); + proc_accept(ps, imsg_get_fd(&imsg), pf.pf_procid, - pf.pf_instance); + pf.pf_instance); break; default: fatalx("%s: %s %d got invalid imsg %d peerid %d " "from %s %d", __func__, title, ps->ps_instance + 1, - imsg.hdr.type, imsg.hdr.peerid, - p->p_title, imsg.hdr.pid); + imsg_get_type(&imsg), imsg_get_id(&imsg), + p->p_title, imsg_get_pid(&imsg)); } imsg_free(&imsg); } @@ -794,12 +800,18 @@ proc_composev(struct privsep *ps, enum privsep_procid id, return (proc_composev_imsg(ps, id, -1, type, -1, -1, iov, iovcnt)); } -int +void proc_forward_imsg(struct privsep *ps, struct imsg *imsg, - enum privsep_procid id, int n) + enum privsep_procid id) { - return (proc_compose_imsg(ps, id, n, imsg->hdr.type, - imsg->hdr.peerid, -1, imsg->data, IMSG_DATA_SIZE(imsg))); + int m, n = -1; + + proc_range(ps, id, &n, &m); + for (; n < m; n++) { + if (imsg_forward(&ps->ps_ievs[id][n].ibuf, imsg) == -1) + fatal("%s: imsg_forward", __func__); + imsg_event_add(&ps->ps_ievs[id][n]); + } } struct imsgbuf *