diff options
author | Mathieu Sauve-Frankel <msf@cvs.openbsd.org> | 2007-06-12 15:16:11 +0000 |
---|---|---|
committer | Mathieu Sauve-Frankel <msf@cvs.openbsd.org> | 2007-06-12 15:16:11 +0000 |
commit | 02d3a3cfb9a2f15691ac239c00c0dbc365806bd8 (patch) | |
tree | 97073def1962bdcdd5bb5d2a121673086b870a69 /usr.sbin | |
parent | 2d9ab07ad3aa6f25f68d89c4c70890c3b37fc57e (diff) |
put the fd passing from bgpd back in to hoststated's version of imsg,
needed for layer 7 reload support.
ok pyr@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/hoststated/buffer.c | 31 | ||||
-rw-r--r-- | usr.sbin/hoststated/check_script.c | 4 | ||||
-rw-r--r-- | usr.sbin/hoststated/control.c | 40 | ||||
-rw-r--r-- | usr.sbin/hoststated/hce.c | 6 | ||||
-rw-r--r-- | usr.sbin/hoststated/hoststated.c | 33 | ||||
-rw-r--r-- | usr.sbin/hoststated/hoststated.h | 11 | ||||
-rw-r--r-- | usr.sbin/hoststated/imsg.c | 54 | ||||
-rw-r--r-- | usr.sbin/hoststated/pfe.c | 41 | ||||
-rw-r--r-- | usr.sbin/hoststated/relay.c | 9 | ||||
-rw-r--r-- | usr.sbin/relayd/buffer.c | 31 | ||||
-rw-r--r-- | usr.sbin/relayd/check_script.c | 4 | ||||
-rw-r--r-- | usr.sbin/relayd/control.c | 40 | ||||
-rw-r--r-- | usr.sbin/relayd/hce.c | 6 | ||||
-rw-r--r-- | usr.sbin/relayd/imsg.c | 54 | ||||
-rw-r--r-- | usr.sbin/relayd/pfe.c | 41 | ||||
-rw-r--r-- | usr.sbin/relayd/relay.c | 9 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.c | 33 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 11 |
18 files changed, 316 insertions, 142 deletions
diff --git a/usr.sbin/hoststated/buffer.c b/usr.sbin/hoststated/buffer.c index 0c957aa8642..cb61f4c5271 100644 --- a/usr.sbin/hoststated/buffer.c +++ b/usr.sbin/hoststated/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.6 2007/02/07 13:39:58 reyk Exp $ */ +/* $OpenBSD: buffer.c,v 1.7 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -50,6 +50,7 @@ buf_open(size_t len) return (NULL); } buf->size = buf->max = len; + buf->fd = -1; return (buf); } @@ -156,6 +157,8 @@ msgbuf_write(struct msgbuf *msgbuf) int i = 0; ssize_t n; struct msghdr msg; + struct cmsghdr *cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; bzero(&iov, sizeof(iov)); bzero(&msg, sizeof(msg)); @@ -165,11 +168,23 @@ msgbuf_write(struct msgbuf *msgbuf) iov[i].iov_base = buf->buf + buf->rpos; iov[i].iov_len = buf->size - buf->rpos; i++; + if (buf->fd != -1) + break; } msg.msg_iov = iov; msg.msg_iovlen = i; + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)cmsgbuf; + msg.msg_controllen = CMSG_LEN(sizeof(int)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { if (errno == EAGAIN || errno == ENOBUFS || errno == EINTR) /* try later */ @@ -183,6 +198,16 @@ msgbuf_write(struct msgbuf *msgbuf) return (-2); } + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)cmsgbuf; + msg.msg_controllen = CMSG_LEN(sizeof(int)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; buf = next) { next = TAILQ_NEXT(buf, entry); @@ -209,6 +234,10 @@ void buf_dequeue(struct msgbuf *msgbuf, struct buf *buf) { TAILQ_REMOVE(&msgbuf->bufs, buf, entry); + + if (buf->fd != -1) + close(buf->fd); + msgbuf->queued--; buf_free(buf); } diff --git a/usr.sbin/hoststated/check_script.c b/usr.sbin/hoststated/check_script.c index d347d882846..19b9b0da49a 100644 --- a/usr.sbin/hoststated/check_script.c +++ b/usr.sbin/hoststated/check_script.c @@ -1,4 +1,4 @@ -/* $OpenBSD: check_script.c,v 1.1 2007/05/29 17:12:04 reyk Exp $ */ +/* $OpenBSD: check_script.c,v 1.2 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> @@ -53,7 +53,7 @@ check_script(struct host *host) host->flags &= ~(F_CHECK_SENT|F_CHECK_DONE); scr.host = host->conf.id; - imsg_compose(ibuf_main, IMSG_SCRIPT, 0, 0, &scr, sizeof(scr)); + imsg_compose(ibuf_main, IMSG_SCRIPT, 0, 0, -1, &scr, sizeof(scr)); } void diff --git a/usr.sbin/hoststated/control.c b/usr.sbin/hoststated/control.c index 33d4dca084a..e9a664735f1 100644 --- a/usr.sbin/hoststated/control.c +++ b/usr.sbin/hoststated/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.16 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: control.c,v 1.17 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -230,12 +230,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_service(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -244,12 +244,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_service(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -258,12 +258,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_table(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -272,12 +272,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_table(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -286,12 +286,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_host(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -300,25 +300,27 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_host(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_SHUTDOWN: - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, + 0); break; case IMSG_CTL_RELOAD: if (env->prefork_relay > 0) { - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } - imsg_compose(ibuf_main, IMSG_CTL_RELOAD, 0, 0, NULL, 0); + imsg_compose(ibuf_main, IMSG_CTL_RELOAD, 0, 0, -1, NULL, + 0); /* * we unconditionnaly return a CTL_OK imsg because * we have no choice. @@ -327,13 +329,13 @@ control_dispatch_imsg(int fd, short event, void *arg) * that the reload command has been set, * it doesn't say wether the command succeeded or not. */ - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_CTL_NOTIFY: if (c->flags & CTL_CONN_NOTIFY) { log_debug("control_dispatch_imsg: " "client requested notify more than once"); - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } @@ -358,7 +360,7 @@ control_imsg_forward(struct imsg *imsg) TAILQ_FOREACH(c, &ctl_conns, entry) if (c->flags & CTL_CONN_NOTIFY) imsg_compose(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid, - imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); + -1, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); } void diff --git a/usr.sbin/hoststated/hce.c b/usr.sbin/hoststated/hce.c index b674886ade9..9e9677a742e 100644 --- a/usr.sbin/hoststated/hce.c +++ b/usr.sbin/hoststated/hce.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hce.c,v 1.26 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: hce.c,v 1.27 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -220,7 +220,7 @@ hce_launch_checks(int fd, short event, void *arg) /* * notify pfe checks are done and schedule next check */ - imsg_compose(ibuf_pfe, IMSG_SYNC, 0, 0, NULL, 0); + imsg_compose(ibuf_pfe, IMSG_SYNC, 0, 0, -1, NULL, 0); TAILQ_FOREACH(table, env->tables, entry) { TAILQ_FOREACH(host, &table->hosts, entry) { host->flags &= ~(F_CHECK_SENT|F_CHECK_DONE); @@ -295,7 +295,7 @@ hce_notify_done(struct host *host, const char *msg) if (msg) log_debug("hce_notify_done: %s (%s)", host->conf.name, msg); - imsg_compose(ibuf_pfe, IMSG_HOST_STATUS, 0, 0, &st, sizeof(st)); + imsg_compose(ibuf_pfe, IMSG_HOST_STATUS, 0, 0, -1, &st, sizeof(st)); if (host->up != host->last_up) logopt = HOSTSTATED_OPT_LOGUPDATE; else diff --git a/usr.sbin/hoststated/hoststated.c b/usr.sbin/hoststated/hoststated.c index 0858dfe42e2..6b0a1c6f833 100644 --- a/usr.sbin/hoststated/hoststated.c +++ b/usr.sbin/hoststated/hoststated.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hoststated.c,v 1.35 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: hoststated.c,v 1.36 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -328,12 +328,13 @@ send_all(struct hoststated *env, enum imsg_type type, void *buf, u_int16_t len) { int i; - if (imsg_compose(ibuf_pfe, type, 0, 0, buf, len) == -1) + if (imsg_compose(ibuf_pfe, type, 0, 0, -1, buf, len) == -1) return (-1); - if (imsg_compose(ibuf_hce, type, 0, 0, buf, len) == -1) + if (imsg_compose(ibuf_hce, type, 0, 0, -1, buf, len) == -1) return (-1); for (i = 0; i < env->prefork_relay; i++) { - if (imsg_compose(&ibuf_relay[i], type, 0, 0, buf, len) == -1) + if (imsg_compose(&ibuf_relay[i], type, 0, 0, -1, buf, len) + == -1) return (-1); } return (0); @@ -387,40 +388,40 @@ reconfigure(void) /* * first reconfigure pfe */ - imsg_compose(ibuf_pfe, IMSG_RECONF, 0, 0, env, sizeof(*env)); + imsg_compose(ibuf_pfe, IMSG_RECONF, 0, 0, -1, env, sizeof(*env)); TAILQ_FOREACH(table, env->tables, entry) { - imsg_compose(ibuf_pfe, IMSG_RECONF_TABLE, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_TABLE, 0, 0, -1, &table->conf, sizeof(table->conf)); TAILQ_FOREACH(host, &table->hosts, entry) { - imsg_compose(ibuf_pfe, IMSG_RECONF_HOST, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_HOST, 0, 0, -1, &host->conf, sizeof(host->conf)); } } TAILQ_FOREACH(service, env->services, entry) { - imsg_compose(ibuf_pfe, IMSG_RECONF_SERVICE, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_SERVICE, 0, 0, -1, &service->conf, sizeof(service->conf)); TAILQ_FOREACH(virt, &service->virts, entry) - imsg_compose(ibuf_pfe, IMSG_RECONF_VIRT, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_VIRT, 0, 0, -1, virt, sizeof(*virt)); } - imsg_compose(ibuf_pfe, IMSG_RECONF_END, 0, 0, NULL, 0); + imsg_compose(ibuf_pfe, IMSG_RECONF_END, 0, 0, -1, NULL, 0); /* * then reconfigure hce */ - imsg_compose(ibuf_hce, IMSG_RECONF, 0, 0, env, sizeof(*env)); + imsg_compose(ibuf_hce, IMSG_RECONF, 0, 0, -1, env, sizeof(*env)); TAILQ_FOREACH(table, env->tables, entry) { - imsg_compose(ibuf_hce, IMSG_RECONF_TABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_RECONF_TABLE, 0, 0, -1, &table->conf, sizeof(table->conf)); if (table->sendbuf != NULL) - imsg_compose(ibuf_hce, IMSG_RECONF_SENDBUF, 0, 0, + imsg_compose(ibuf_hce, IMSG_RECONF_SENDBUF, 0, 0, -1, table->sendbuf, strlen(table->sendbuf) + 1); TAILQ_FOREACH(host, &table->hosts, entry) { - imsg_compose(ibuf_hce, IMSG_RECONF_HOST, 0, 0, + imsg_compose(ibuf_hce, IMSG_RECONF_HOST, 0, 0, -1, &host->conf, sizeof(host->conf)); } } - imsg_compose(ibuf_hce, IMSG_RECONF_END, 0, 0, NULL, 0); + imsg_compose(ibuf_hce, IMSG_RECONF_END, 0, 0, -1, NULL, 0); } void @@ -625,7 +626,7 @@ main_dispatch_hce(int fd, short event, void * ptr) bcopy(imsg.data, &scr, sizeof(scr)); scr.retval = script_exec(env, &scr); imsg_compose(ibuf_hce, IMSG_SCRIPT, - 0, 0, &scr, sizeof(scr)); + 0, 0, -1, &scr, sizeof(scr)); break; default: log_debug("main_dispatch_hce: unexpected imsg %d", diff --git a/usr.sbin/hoststated/hoststated.h b/usr.sbin/hoststated/hoststated.h index 67d492efffb..e05330391cf 100644 --- a/usr.sbin/hoststated/hoststated.h +++ b/usr.sbin/hoststated/hoststated.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hoststated.h,v 1.51 2007/05/31 03:24:05 pyr Exp $ */ +/* $OpenBSD: hoststated.h,v 1.52 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -62,6 +62,7 @@ struct buf { size_t max; size_t wpos; size_t rpos; + int fd; }; struct msgbuf { @@ -79,6 +80,11 @@ struct buf_read { size_t wpos; }; +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + struct imsgbuf { TAILQ_HEAD(, imsg_fd) fds; struct buf_read r; @@ -645,13 +651,14 @@ void imsg_init(struct imsgbuf *, int, void (*)(int, short, void *)); ssize_t imsg_read(struct imsgbuf *); ssize_t imsg_get(struct imsgbuf *, struct imsg *); int imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, - void *, u_int16_t); + int, void *, u_int16_t); struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, u_int16_t); int imsg_add(struct buf *, void *, u_int16_t); int imsg_close(struct imsgbuf *, struct buf *); void imsg_free(struct imsg *); void imsg_event_add(struct imsgbuf *); /* needs to be provided externally */ +int imsg_get_fd(struct imsgbuf *); /* pfe.c */ pid_t pfe(struct hoststated *, int [2], int [2], int [RELAY_MAXPROC][2], diff --git a/usr.sbin/hoststated/imsg.c b/usr.sbin/hoststated/imsg.c index 4b21fbe0934..b1a9a9e302f 100644 --- a/usr.sbin/hoststated/imsg.c +++ b/usr.sbin/hoststated/imsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.c,v 1.6 2007/03/19 10:11:59 henning Exp $ */ +/* $OpenBSD: imsg.c,v 1.7 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -47,10 +47,24 @@ imsg_init(struct imsgbuf *ibuf, int fd, void (*handler)(int, short, void *)) ssize_t imsg_read(struct imsgbuf *ibuf) { + struct msghdr msg; + struct cmsghdr *cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int) * 16)]; + struct iovec iov; ssize_t n; + int fd; + struct imsg_fd *ifd; - if ((n = recv(ibuf->fd, ibuf->r.buf + ibuf->r.wpos, - sizeof(ibuf->r.buf) - ibuf->r.wpos, 0)) == -1) { + bzero(&msg, sizeof(msg)); + + iov.iov_base = ibuf->r.buf + ibuf->r.wpos; + iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { if (errno != EINTR && errno != EAGAIN) { log_warn("imsg_read: pipe read error"); return (-1); @@ -60,6 +74,20 @@ imsg_read(struct imsgbuf *ibuf) ibuf->r.wpos += n; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + fd = (*(int *)CMSG_DATA(cmsg)); + if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) + fatal("imsg_read calloc"); + ifd->fd = fd; + TAILQ_INSERT_TAIL(&ibuf->fds, ifd, entry); + } else + log_warn("imsg_read: got unexpected ctl data level %d " + "type %d", cmsg->cmsg_level, cmsg->cmsg_type); + } + return (n); } @@ -102,7 +130,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) int imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, - pid_t pid, void *data, u_int16_t datalen) + pid_t pid, int fd, void *data, u_int16_t datalen) { struct buf *wbuf; int n; @@ -113,6 +141,8 @@ imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, if (imsg_add(wbuf, data, datalen) == -1) return (-1); + wbuf->fd = fd; + if ((n = imsg_close(ibuf, wbuf)) < 0) return (-1); @@ -181,3 +211,19 @@ imsg_free(struct imsg *imsg) { free(imsg->data); } + +int +imsg_get_fd(struct imsgbuf *ibuf) +{ + int fd; + struct imsg_fd *ifd; + + if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + return (-1); + + fd = ifd->fd; + TAILQ_REMOVE(&ibuf->fds, ifd, entry); + free(ifd); + + return (fd); +} diff --git a/usr.sbin/hoststated/pfe.c b/usr.sbin/hoststated/pfe.c index 3d2f73cd6c1..b0d4f35bf60 100644 --- a/usr.sbin/hoststated/pfe.c +++ b/usr.sbin/hoststated/pfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfe.c,v 1.30 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: pfe.c,v 1.31 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -275,7 +275,8 @@ pfe_dispatch_imsg(int fd, short event, void *ptr) /* Forward to relay engine(s) */ for (n = 0; n < env->prefork_relay; n++) imsg_compose(&ibuf_relay[n], - IMSG_HOST_STATUS, 0, 0, &st, sizeof(st)); + IMSG_HOST_STATUS, 0, 0, -1, &st, + sizeof(st)); if ((table = table_find(env, host->conf.tableid)) == NULL) @@ -471,7 +472,7 @@ pfe_dispatch_relay(int fd, short event, void * ptr) if (natlook(env, &cnl) != 0) cnl.in = -1; imsg_compose(&ibuf_relay[cnl.proc], IMSG_NATLOOK, 0, 0, - &cnl, sizeof(cnl)); + -1, &cnl, sizeof(cnl)); break; case IMSG_STATISTICS: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(crs)) @@ -504,45 +505,45 @@ show(struct ctl_conn *c) struct relay *rlay; TAILQ_FOREACH(service, env->services, entry) { - imsg_compose(&c->ibuf, IMSG_CTL_SERVICE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_SERVICE, 0, 0, -1, service, sizeof(*service)); if (service->conf.flags & F_DISABLE) continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1, service->table, sizeof(*service->table)); if (!(service->table->conf.flags & F_DISABLE)) TAILQ_FOREACH(host, &service->table->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, -1, host, sizeof(*host)); if (service->backup->conf.id == EMPTY_TABLE) continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1, service->backup, sizeof(*service->backup)); if (!(service->backup->conf.flags & F_DISABLE)) TAILQ_FOREACH(host, &service->backup->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, -1, host, sizeof(*host)); } TAILQ_FOREACH(rlay, &env->relays, entry) { rlay->stats[env->prefork_relay].id = EMPTY_ID; - imsg_compose(&c->ibuf, IMSG_CTL_RELAY, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_RELAY, 0, 0, -1, rlay, sizeof(*rlay)); - imsg_compose(&c->ibuf, IMSG_CTL_STATISTICS, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_STATISTICS, 0, 0, -1, &rlay->stats, sizeof(rlay->stats)); if (rlay->dsttable == NULL) continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1, rlay->dsttable, sizeof(*rlay->dsttable)); if (!(rlay->dsttable->conf.flags & F_DISABLE)) TAILQ_FOREACH(host, &rlay->dsttable->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, -1, host, sizeof(*host)); } - imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, -1, NULL, 0); } @@ -630,7 +631,7 @@ disable_table(struct ctl_conn *c, struct ctl_id *id) table->up = 0; TAILQ_FOREACH(host, &table->hosts, entry) host->up = HOST_UNKNOWN; - imsg_compose(ibuf_hce, IMSG_TABLE_DISABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_TABLE_DISABLE, 0, 0, -1, &table->conf.id, sizeof(table->conf.id)); log_debug("disable_table: disabled table %d", table->conf.id); pfe_sync(); @@ -662,7 +663,7 @@ enable_table(struct ctl_conn *c, struct ctl_id *id) table->up = 0; TAILQ_FOREACH(host, &table->hosts, entry) host->up = HOST_UNKNOWN; - imsg_compose(ibuf_hce, IMSG_TABLE_ENABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_TABLE_ENABLE, 0, 0, -1, &table->conf.id, sizeof(table->conf.id)); log_debug("enable_table: enabled table %d", table->conf.id); pfe_sync(); @@ -701,12 +702,12 @@ disable_host(struct ctl_conn *c, struct ctl_id *id) host->check_cnt = 0; host->up_cnt = 0; - imsg_compose(ibuf_hce, IMSG_HOST_DISABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_HOST_DISABLE, 0, 0, -1, &host->conf.id, sizeof(host->conf.id)); /* Forward to relay engine(s) */ for (n = 0; n < env->prefork_relay; n++) imsg_compose(&ibuf_relay[n], - IMSG_HOST_DISABLE, 0, 0, + IMSG_HOST_DISABLE, 0, 0, -1, &host->conf.id, sizeof(host->conf.id)); log_debug("disable_host: disabled host %d", host->conf.id); pfe_sync(); @@ -735,12 +736,12 @@ enable_host(struct ctl_conn *c, struct ctl_id *id) host->flags &= ~(F_DEL); host->flags &= ~(F_ADD); - imsg_compose(ibuf_hce, IMSG_HOST_ENABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_HOST_ENABLE, 0, 0, -1, &host->conf.id, sizeof (host->conf.id)); /* Forward to relay engine(s) */ for (n = 0; n < env->prefork_relay; n++) imsg_compose(&ibuf_relay[n], - IMSG_HOST_ENABLE, 0, 0, + IMSG_HOST_ENABLE, 0, 0, -1, &host->conf.id, sizeof(host->conf.id)); log_debug("enable_host: enabled host %d", host->conf.id); pfe_sync(); @@ -831,7 +832,7 @@ pfe_sync(void) demote.level, table->conf.name, table->conf.demote_group); (void)strlcpy(demote.group, table->conf.demote_group, sizeof(demote.group)); - imsg_compose(ibuf_main, IMSG_DEMOTE, 0, 0, + imsg_compose(ibuf_main, IMSG_DEMOTE, 0, 0, -1, &demote, sizeof(demote)); } } diff --git a/usr.sbin/hoststated/relay.c b/usr.sbin/hoststated/relay.c index cfdd3a8dbc9..0733aaa9cd1 100644 --- a/usr.sbin/hoststated/relay.c +++ b/usr.sbin/hoststated/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.33 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: relay.c,v 1.34 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org> @@ -464,7 +464,7 @@ relay_statistics(int fd, short events, void *arg) crs.id = rlay->conf.id; crs.proc = proc_id; - imsg_compose(ibuf_pfe, IMSG_STATISTICS, 0, 0, + imsg_compose(ibuf_pfe, IMSG_STATISTICS, 0, 0, -1, &crs, sizeof(crs)); for (con = TAILQ_FIRST(&rlay->sessions); @@ -1532,7 +1532,8 @@ relay_accept(int fd, short sig, void *arg) cnl->proc = proc_id; bcopy(&con->in.ss, &cnl->src, sizeof(cnl->src)); bcopy(&rlay->conf.ss, &cnl->dst, sizeof(cnl->dst)); - imsg_compose(ibuf_pfe, IMSG_NATLOOK, 0, 0, cnl, sizeof(*cnl)); + imsg_compose(ibuf_pfe, IMSG_NATLOOK, 0, 0, -1, cnl, + sizeof(*cnl)); /* Schedule timeout */ evtimer_set(&con->ev, relay_natlook, con); @@ -1784,7 +1785,7 @@ relay_close(struct session *con, const char *msg) if (con->cnl != NULL) { #if 0 - imsg_compose(ibuf_pfe, IMSG_KILLSTATES, 0, 0, + imsg_compose(ibuf_pfe, IMSG_KILLSTATES, 0, 0, -1, cnl, sizeof(*cnl)); #endif free(con->cnl); diff --git a/usr.sbin/relayd/buffer.c b/usr.sbin/relayd/buffer.c index 0c957aa8642..cb61f4c5271 100644 --- a/usr.sbin/relayd/buffer.c +++ b/usr.sbin/relayd/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.6 2007/02/07 13:39:58 reyk Exp $ */ +/* $OpenBSD: buffer.c,v 1.7 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -50,6 +50,7 @@ buf_open(size_t len) return (NULL); } buf->size = buf->max = len; + buf->fd = -1; return (buf); } @@ -156,6 +157,8 @@ msgbuf_write(struct msgbuf *msgbuf) int i = 0; ssize_t n; struct msghdr msg; + struct cmsghdr *cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; bzero(&iov, sizeof(iov)); bzero(&msg, sizeof(msg)); @@ -165,11 +168,23 @@ msgbuf_write(struct msgbuf *msgbuf) iov[i].iov_base = buf->buf + buf->rpos; iov[i].iov_len = buf->size - buf->rpos; i++; + if (buf->fd != -1) + break; } msg.msg_iov = iov; msg.msg_iovlen = i; + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)cmsgbuf; + msg.msg_controllen = CMSG_LEN(sizeof(int)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { if (errno == EAGAIN || errno == ENOBUFS || errno == EINTR) /* try later */ @@ -183,6 +198,16 @@ msgbuf_write(struct msgbuf *msgbuf) return (-2); } + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)cmsgbuf; + msg.msg_controllen = CMSG_LEN(sizeof(int)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; buf = next) { next = TAILQ_NEXT(buf, entry); @@ -209,6 +234,10 @@ void buf_dequeue(struct msgbuf *msgbuf, struct buf *buf) { TAILQ_REMOVE(&msgbuf->bufs, buf, entry); + + if (buf->fd != -1) + close(buf->fd); + msgbuf->queued--; buf_free(buf); } diff --git a/usr.sbin/relayd/check_script.c b/usr.sbin/relayd/check_script.c index d347d882846..19b9b0da49a 100644 --- a/usr.sbin/relayd/check_script.c +++ b/usr.sbin/relayd/check_script.c @@ -1,4 +1,4 @@ -/* $OpenBSD: check_script.c,v 1.1 2007/05/29 17:12:04 reyk Exp $ */ +/* $OpenBSD: check_script.c,v 1.2 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> @@ -53,7 +53,7 @@ check_script(struct host *host) host->flags &= ~(F_CHECK_SENT|F_CHECK_DONE); scr.host = host->conf.id; - imsg_compose(ibuf_main, IMSG_SCRIPT, 0, 0, &scr, sizeof(scr)); + imsg_compose(ibuf_main, IMSG_SCRIPT, 0, 0, -1, &scr, sizeof(scr)); } void diff --git a/usr.sbin/relayd/control.c b/usr.sbin/relayd/control.c index 33d4dca084a..e9a664735f1 100644 --- a/usr.sbin/relayd/control.c +++ b/usr.sbin/relayd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.16 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: control.c,v 1.17 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -230,12 +230,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_service(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -244,12 +244,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_service(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -258,12 +258,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_table(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -272,12 +272,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_table(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -286,12 +286,12 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_host(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; @@ -300,25 +300,27 @@ control_dispatch_imsg(int fd, short event, void *arg) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_host(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_SHUTDOWN: - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, + 0); break; case IMSG_CTL_RELOAD: if (env->prefork_relay > 0) { - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } - imsg_compose(ibuf_main, IMSG_CTL_RELOAD, 0, 0, NULL, 0); + imsg_compose(ibuf_main, IMSG_CTL_RELOAD, 0, 0, -1, NULL, + 0); /* * we unconditionnaly return a CTL_OK imsg because * we have no choice. @@ -327,13 +329,13 @@ control_dispatch_imsg(int fd, short event, void *arg) * that the reload command has been set, * it doesn't say wether the command succeeded or not. */ - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_CTL_NOTIFY: if (c->flags & CTL_CONN_NOTIFY) { log_debug("control_dispatch_imsg: " "client requested notify more than once"); - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } @@ -358,7 +360,7 @@ control_imsg_forward(struct imsg *imsg) TAILQ_FOREACH(c, &ctl_conns, entry) if (c->flags & CTL_CONN_NOTIFY) imsg_compose(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid, - imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); + -1, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); } void diff --git a/usr.sbin/relayd/hce.c b/usr.sbin/relayd/hce.c index b674886ade9..9e9677a742e 100644 --- a/usr.sbin/relayd/hce.c +++ b/usr.sbin/relayd/hce.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hce.c,v 1.26 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: hce.c,v 1.27 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -220,7 +220,7 @@ hce_launch_checks(int fd, short event, void *arg) /* * notify pfe checks are done and schedule next check */ - imsg_compose(ibuf_pfe, IMSG_SYNC, 0, 0, NULL, 0); + imsg_compose(ibuf_pfe, IMSG_SYNC, 0, 0, -1, NULL, 0); TAILQ_FOREACH(table, env->tables, entry) { TAILQ_FOREACH(host, &table->hosts, entry) { host->flags &= ~(F_CHECK_SENT|F_CHECK_DONE); @@ -295,7 +295,7 @@ hce_notify_done(struct host *host, const char *msg) if (msg) log_debug("hce_notify_done: %s (%s)", host->conf.name, msg); - imsg_compose(ibuf_pfe, IMSG_HOST_STATUS, 0, 0, &st, sizeof(st)); + imsg_compose(ibuf_pfe, IMSG_HOST_STATUS, 0, 0, -1, &st, sizeof(st)); if (host->up != host->last_up) logopt = HOSTSTATED_OPT_LOGUPDATE; else diff --git a/usr.sbin/relayd/imsg.c b/usr.sbin/relayd/imsg.c index 4b21fbe0934..b1a9a9e302f 100644 --- a/usr.sbin/relayd/imsg.c +++ b/usr.sbin/relayd/imsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.c,v 1.6 2007/03/19 10:11:59 henning Exp $ */ +/* $OpenBSD: imsg.c,v 1.7 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -47,10 +47,24 @@ imsg_init(struct imsgbuf *ibuf, int fd, void (*handler)(int, short, void *)) ssize_t imsg_read(struct imsgbuf *ibuf) { + struct msghdr msg; + struct cmsghdr *cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int) * 16)]; + struct iovec iov; ssize_t n; + int fd; + struct imsg_fd *ifd; - if ((n = recv(ibuf->fd, ibuf->r.buf + ibuf->r.wpos, - sizeof(ibuf->r.buf) - ibuf->r.wpos, 0)) == -1) { + bzero(&msg, sizeof(msg)); + + iov.iov_base = ibuf->r.buf + ibuf->r.wpos; + iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { if (errno != EINTR && errno != EAGAIN) { log_warn("imsg_read: pipe read error"); return (-1); @@ -60,6 +74,20 @@ imsg_read(struct imsgbuf *ibuf) ibuf->r.wpos += n; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + fd = (*(int *)CMSG_DATA(cmsg)); + if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) + fatal("imsg_read calloc"); + ifd->fd = fd; + TAILQ_INSERT_TAIL(&ibuf->fds, ifd, entry); + } else + log_warn("imsg_read: got unexpected ctl data level %d " + "type %d", cmsg->cmsg_level, cmsg->cmsg_type); + } + return (n); } @@ -102,7 +130,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) int imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, - pid_t pid, void *data, u_int16_t datalen) + pid_t pid, int fd, void *data, u_int16_t datalen) { struct buf *wbuf; int n; @@ -113,6 +141,8 @@ imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, if (imsg_add(wbuf, data, datalen) == -1) return (-1); + wbuf->fd = fd; + if ((n = imsg_close(ibuf, wbuf)) < 0) return (-1); @@ -181,3 +211,19 @@ imsg_free(struct imsg *imsg) { free(imsg->data); } + +int +imsg_get_fd(struct imsgbuf *ibuf) +{ + int fd; + struct imsg_fd *ifd; + + if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + return (-1); + + fd = ifd->fd; + TAILQ_REMOVE(&ibuf->fds, ifd, entry); + free(ifd); + + return (fd); +} diff --git a/usr.sbin/relayd/pfe.c b/usr.sbin/relayd/pfe.c index 3d2f73cd6c1..b0d4f35bf60 100644 --- a/usr.sbin/relayd/pfe.c +++ b/usr.sbin/relayd/pfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfe.c,v 1.30 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: pfe.c,v 1.31 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -275,7 +275,8 @@ pfe_dispatch_imsg(int fd, short event, void *ptr) /* Forward to relay engine(s) */ for (n = 0; n < env->prefork_relay; n++) imsg_compose(&ibuf_relay[n], - IMSG_HOST_STATUS, 0, 0, &st, sizeof(st)); + IMSG_HOST_STATUS, 0, 0, -1, &st, + sizeof(st)); if ((table = table_find(env, host->conf.tableid)) == NULL) @@ -471,7 +472,7 @@ pfe_dispatch_relay(int fd, short event, void * ptr) if (natlook(env, &cnl) != 0) cnl.in = -1; imsg_compose(&ibuf_relay[cnl.proc], IMSG_NATLOOK, 0, 0, - &cnl, sizeof(cnl)); + -1, &cnl, sizeof(cnl)); break; case IMSG_STATISTICS: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(crs)) @@ -504,45 +505,45 @@ show(struct ctl_conn *c) struct relay *rlay; TAILQ_FOREACH(service, env->services, entry) { - imsg_compose(&c->ibuf, IMSG_CTL_SERVICE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_SERVICE, 0, 0, -1, service, sizeof(*service)); if (service->conf.flags & F_DISABLE) continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1, service->table, sizeof(*service->table)); if (!(service->table->conf.flags & F_DISABLE)) TAILQ_FOREACH(host, &service->table->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, -1, host, sizeof(*host)); if (service->backup->conf.id == EMPTY_TABLE) continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1, service->backup, sizeof(*service->backup)); if (!(service->backup->conf.flags & F_DISABLE)) TAILQ_FOREACH(host, &service->backup->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, -1, host, sizeof(*host)); } TAILQ_FOREACH(rlay, &env->relays, entry) { rlay->stats[env->prefork_relay].id = EMPTY_ID; - imsg_compose(&c->ibuf, IMSG_CTL_RELAY, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_RELAY, 0, 0, -1, rlay, sizeof(*rlay)); - imsg_compose(&c->ibuf, IMSG_CTL_STATISTICS, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_STATISTICS, 0, 0, -1, &rlay->stats, sizeof(rlay->stats)); if (rlay->dsttable == NULL) continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1, rlay->dsttable, sizeof(*rlay->dsttable)); if (!(rlay->dsttable->conf.flags & F_DISABLE)) TAILQ_FOREACH(host, &rlay->dsttable->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, + imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, -1, host, sizeof(*host)); } - imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, NULL, 0); + imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, -1, NULL, 0); } @@ -630,7 +631,7 @@ disable_table(struct ctl_conn *c, struct ctl_id *id) table->up = 0; TAILQ_FOREACH(host, &table->hosts, entry) host->up = HOST_UNKNOWN; - imsg_compose(ibuf_hce, IMSG_TABLE_DISABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_TABLE_DISABLE, 0, 0, -1, &table->conf.id, sizeof(table->conf.id)); log_debug("disable_table: disabled table %d", table->conf.id); pfe_sync(); @@ -662,7 +663,7 @@ enable_table(struct ctl_conn *c, struct ctl_id *id) table->up = 0; TAILQ_FOREACH(host, &table->hosts, entry) host->up = HOST_UNKNOWN; - imsg_compose(ibuf_hce, IMSG_TABLE_ENABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_TABLE_ENABLE, 0, 0, -1, &table->conf.id, sizeof(table->conf.id)); log_debug("enable_table: enabled table %d", table->conf.id); pfe_sync(); @@ -701,12 +702,12 @@ disable_host(struct ctl_conn *c, struct ctl_id *id) host->check_cnt = 0; host->up_cnt = 0; - imsg_compose(ibuf_hce, IMSG_HOST_DISABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_HOST_DISABLE, 0, 0, -1, &host->conf.id, sizeof(host->conf.id)); /* Forward to relay engine(s) */ for (n = 0; n < env->prefork_relay; n++) imsg_compose(&ibuf_relay[n], - IMSG_HOST_DISABLE, 0, 0, + IMSG_HOST_DISABLE, 0, 0, -1, &host->conf.id, sizeof(host->conf.id)); log_debug("disable_host: disabled host %d", host->conf.id); pfe_sync(); @@ -735,12 +736,12 @@ enable_host(struct ctl_conn *c, struct ctl_id *id) host->flags &= ~(F_DEL); host->flags &= ~(F_ADD); - imsg_compose(ibuf_hce, IMSG_HOST_ENABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_HOST_ENABLE, 0, 0, -1, &host->conf.id, sizeof (host->conf.id)); /* Forward to relay engine(s) */ for (n = 0; n < env->prefork_relay; n++) imsg_compose(&ibuf_relay[n], - IMSG_HOST_ENABLE, 0, 0, + IMSG_HOST_ENABLE, 0, 0, -1, &host->conf.id, sizeof(host->conf.id)); log_debug("enable_host: enabled host %d", host->conf.id); pfe_sync(); @@ -831,7 +832,7 @@ pfe_sync(void) demote.level, table->conf.name, table->conf.demote_group); (void)strlcpy(demote.group, table->conf.demote_group, sizeof(demote.group)); - imsg_compose(ibuf_main, IMSG_DEMOTE, 0, 0, + imsg_compose(ibuf_main, IMSG_DEMOTE, 0, 0, -1, &demote, sizeof(demote)); } } diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index cfdd3a8dbc9..0733aaa9cd1 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.33 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: relay.c,v 1.34 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org> @@ -464,7 +464,7 @@ relay_statistics(int fd, short events, void *arg) crs.id = rlay->conf.id; crs.proc = proc_id; - imsg_compose(ibuf_pfe, IMSG_STATISTICS, 0, 0, + imsg_compose(ibuf_pfe, IMSG_STATISTICS, 0, 0, -1, &crs, sizeof(crs)); for (con = TAILQ_FIRST(&rlay->sessions); @@ -1532,7 +1532,8 @@ relay_accept(int fd, short sig, void *arg) cnl->proc = proc_id; bcopy(&con->in.ss, &cnl->src, sizeof(cnl->src)); bcopy(&rlay->conf.ss, &cnl->dst, sizeof(cnl->dst)); - imsg_compose(ibuf_pfe, IMSG_NATLOOK, 0, 0, cnl, sizeof(*cnl)); + imsg_compose(ibuf_pfe, IMSG_NATLOOK, 0, 0, -1, cnl, + sizeof(*cnl)); /* Schedule timeout */ evtimer_set(&con->ev, relay_natlook, con); @@ -1784,7 +1785,7 @@ relay_close(struct session *con, const char *msg) if (con->cnl != NULL) { #if 0 - imsg_compose(ibuf_pfe, IMSG_KILLSTATES, 0, 0, + imsg_compose(ibuf_pfe, IMSG_KILLSTATES, 0, 0, -1, cnl, sizeof(*cnl)); #endif free(con->cnl); diff --git a/usr.sbin/relayd/relayd.c b/usr.sbin/relayd/relayd.c index f5fd78f206d..d348480d098 100644 --- a/usr.sbin/relayd/relayd.c +++ b/usr.sbin/relayd/relayd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.c,v 1.35 2007/06/07 07:19:50 pyr Exp $ */ +/* $OpenBSD: relayd.c,v 1.36 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -328,12 +328,13 @@ send_all(struct hoststated *env, enum imsg_type type, void *buf, u_int16_t len) { int i; - if (imsg_compose(ibuf_pfe, type, 0, 0, buf, len) == -1) + if (imsg_compose(ibuf_pfe, type, 0, 0, -1, buf, len) == -1) return (-1); - if (imsg_compose(ibuf_hce, type, 0, 0, buf, len) == -1) + if (imsg_compose(ibuf_hce, type, 0, 0, -1, buf, len) == -1) return (-1); for (i = 0; i < env->prefork_relay; i++) { - if (imsg_compose(&ibuf_relay[i], type, 0, 0, buf, len) == -1) + if (imsg_compose(&ibuf_relay[i], type, 0, 0, -1, buf, len) + == -1) return (-1); } return (0); @@ -387,40 +388,40 @@ reconfigure(void) /* * first reconfigure pfe */ - imsg_compose(ibuf_pfe, IMSG_RECONF, 0, 0, env, sizeof(*env)); + imsg_compose(ibuf_pfe, IMSG_RECONF, 0, 0, -1, env, sizeof(*env)); TAILQ_FOREACH(table, env->tables, entry) { - imsg_compose(ibuf_pfe, IMSG_RECONF_TABLE, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_TABLE, 0, 0, -1, &table->conf, sizeof(table->conf)); TAILQ_FOREACH(host, &table->hosts, entry) { - imsg_compose(ibuf_pfe, IMSG_RECONF_HOST, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_HOST, 0, 0, -1, &host->conf, sizeof(host->conf)); } } TAILQ_FOREACH(service, env->services, entry) { - imsg_compose(ibuf_pfe, IMSG_RECONF_SERVICE, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_SERVICE, 0, 0, -1, &service->conf, sizeof(service->conf)); TAILQ_FOREACH(virt, &service->virts, entry) - imsg_compose(ibuf_pfe, IMSG_RECONF_VIRT, 0, 0, + imsg_compose(ibuf_pfe, IMSG_RECONF_VIRT, 0, 0, -1, virt, sizeof(*virt)); } - imsg_compose(ibuf_pfe, IMSG_RECONF_END, 0, 0, NULL, 0); + imsg_compose(ibuf_pfe, IMSG_RECONF_END, 0, 0, -1, NULL, 0); /* * then reconfigure hce */ - imsg_compose(ibuf_hce, IMSG_RECONF, 0, 0, env, sizeof(*env)); + imsg_compose(ibuf_hce, IMSG_RECONF, 0, 0, -1, env, sizeof(*env)); TAILQ_FOREACH(table, env->tables, entry) { - imsg_compose(ibuf_hce, IMSG_RECONF_TABLE, 0, 0, + imsg_compose(ibuf_hce, IMSG_RECONF_TABLE, 0, 0, -1, &table->conf, sizeof(table->conf)); if (table->sendbuf != NULL) - imsg_compose(ibuf_hce, IMSG_RECONF_SENDBUF, 0, 0, + imsg_compose(ibuf_hce, IMSG_RECONF_SENDBUF, 0, 0, -1, table->sendbuf, strlen(table->sendbuf) + 1); TAILQ_FOREACH(host, &table->hosts, entry) { - imsg_compose(ibuf_hce, IMSG_RECONF_HOST, 0, 0, + imsg_compose(ibuf_hce, IMSG_RECONF_HOST, 0, 0, -1, &host->conf, sizeof(host->conf)); } } - imsg_compose(ibuf_hce, IMSG_RECONF_END, 0, 0, NULL, 0); + imsg_compose(ibuf_hce, IMSG_RECONF_END, 0, 0, -1, NULL, 0); } void @@ -625,7 +626,7 @@ main_dispatch_hce(int fd, short event, void * ptr) bcopy(imsg.data, &scr, sizeof(scr)); scr.retval = script_exec(env, &scr); imsg_compose(ibuf_hce, IMSG_SCRIPT, - 0, 0, &scr, sizeof(scr)); + 0, 0, -1, &scr, sizeof(scr)); break; default: log_debug("main_dispatch_hce: unexpected imsg %d", diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index cfb5eda0533..d7b4ab7b293 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.51 2007/05/31 03:24:05 pyr Exp $ */ +/* $OpenBSD: relayd.h,v 1.52 2007/06/12 15:16:10 msf Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -62,6 +62,7 @@ struct buf { size_t max; size_t wpos; size_t rpos; + int fd; }; struct msgbuf { @@ -79,6 +80,11 @@ struct buf_read { size_t wpos; }; +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + struct imsgbuf { TAILQ_HEAD(, imsg_fd) fds; struct buf_read r; @@ -645,13 +651,14 @@ void imsg_init(struct imsgbuf *, int, void (*)(int, short, void *)); ssize_t imsg_read(struct imsgbuf *); ssize_t imsg_get(struct imsgbuf *, struct imsg *); int imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, - void *, u_int16_t); + int, void *, u_int16_t); struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, u_int16_t); int imsg_add(struct buf *, void *, u_int16_t); int imsg_close(struct imsgbuf *, struct buf *); void imsg_free(struct imsg *); void imsg_event_add(struct imsgbuf *); /* needs to be provided externally */ +int imsg_get_fd(struct imsgbuf *); /* pfe.c */ pid_t pfe(struct hoststated *, int [2], int [2], int [RELAY_MAXPROC][2], |