summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMathieu Sauve-Frankel <msf@cvs.openbsd.org>2007-06-12 15:16:11 +0000
committerMathieu Sauve-Frankel <msf@cvs.openbsd.org>2007-06-12 15:16:11 +0000
commit02d3a3cfb9a2f15691ac239c00c0dbc365806bd8 (patch)
tree97073def1962bdcdd5bb5d2a121673086b870a69 /usr.sbin
parent2d9ab07ad3aa6f25f68d89c4c70890c3b37fc57e (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.c31
-rw-r--r--usr.sbin/hoststated/check_script.c4
-rw-r--r--usr.sbin/hoststated/control.c40
-rw-r--r--usr.sbin/hoststated/hce.c6
-rw-r--r--usr.sbin/hoststated/hoststated.c33
-rw-r--r--usr.sbin/hoststated/hoststated.h11
-rw-r--r--usr.sbin/hoststated/imsg.c54
-rw-r--r--usr.sbin/hoststated/pfe.c41
-rw-r--r--usr.sbin/hoststated/relay.c9
-rw-r--r--usr.sbin/relayd/buffer.c31
-rw-r--r--usr.sbin/relayd/check_script.c4
-rw-r--r--usr.sbin/relayd/control.c40
-rw-r--r--usr.sbin/relayd/hce.c6
-rw-r--r--usr.sbin/relayd/imsg.c54
-rw-r--r--usr.sbin/relayd/pfe.c41
-rw-r--r--usr.sbin/relayd/relay.c9
-rw-r--r--usr.sbin/relayd/relayd.c33
-rw-r--r--usr.sbin/relayd/relayd.h11
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],