summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorPierre-Yves Ritschard <pyr@cvs.openbsd.org>2007-06-07 07:19:51 +0000
committerPierre-Yves Ritschard <pyr@cvs.openbsd.org>2007-06-07 07:19:51 +0000
commit0a9bb0d1fab75b6428acbeeb5a42e6ce76467cf6 (patch)
treea4c324da285797a88895b7543de54beddf214f19 /usr.sbin
parente0d66f1005b177e1fbe63f0b4833c5557e3fb6ea (diff)
(finally) Enable reload support for layer 3 configurations.
Hoststated can be reloaded either by sending SIGHUP to the parent process or by using ``hoststatectl reload'' discussed and ok reyk@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/hoststated/control.c12
-rw-r--r--usr.sbin/hoststated/hce.c54
-rw-r--r--usr.sbin/hoststated/hoststated.c72
-rw-r--r--usr.sbin/hoststated/pfe.c79
-rw-r--r--usr.sbin/hoststated/relay.c5
-rw-r--r--usr.sbin/relayd/control.c12
-rw-r--r--usr.sbin/relayd/hce.c54
-rw-r--r--usr.sbin/relayd/pfe.c79
-rw-r--r--usr.sbin/relayd/relay.c5
-rw-r--r--usr.sbin/relayd/relayd.c72
10 files changed, 424 insertions, 20 deletions
diff --git a/usr.sbin/hoststated/control.c b/usr.sbin/hoststated/control.c
index e4f42402748..33d4dca084a 100644
--- a/usr.sbin/hoststated/control.c
+++ b/usr.sbin/hoststated/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.15 2007/05/29 23:19:18 pyr Exp $ */
+/* $OpenBSD: control.c,v 1.16 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -318,8 +318,16 @@ control_dispatch_imsg(int fd, short event, void *arg)
NULL, 0);
break;
}
- imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, NULL, 0);
imsg_compose(ibuf_main, IMSG_CTL_RELOAD, 0, 0, NULL, 0);
+ /*
+ * we unconditionnaly return a CTL_OK imsg because
+ * we have no choice.
+ *
+ * so in this case, the reply hoststatectl gets means
+ * 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);
break;
case IMSG_CTL_NOTIFY:
if (c->flags & CTL_CONN_NOTIFY) {
diff --git a/usr.sbin/hoststated/hce.c b/usr.sbin/hoststated/hce.c
index 35437fd1869..b674886ade9 100644
--- a/usr.sbin/hoststated/hce.c
+++ b/usr.sbin/hoststated/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.25 2007/05/31 05:07:08 pyr Exp $ */
+/* $OpenBSD: hce.c,v 1.26 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -64,6 +64,7 @@ hce_sig_handler(int sig, short event, void *arg)
hce_shutdown();
break;
case SIGHUP:
+ /* nothing */
break;
default:
fatalx("hce_sig_handler: unexpected signal");
@@ -80,6 +81,7 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
int i;
struct event ev_sigint;
struct event ev_sigterm;
+ struct event ev_sighup;
switch (pid = fork()) {
case -1:
@@ -96,10 +98,14 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
if ((pw = getpwnam(HOSTSTATED_USER)) == NULL)
fatal("hce: getpwnam");
+#ifndef DEBUG
if (chroot(pw->pw_dir) == -1)
fatal("hce: chroot");
if (chdir("/") == -1)
fatal("hce: chdir(\"/\")");
+#else
+#warning disabling privilege revocation and chroot in DEBUG mode
+#endif
setproctitle("host check engine");
hoststated_process = PROC_HCE;
@@ -107,10 +113,12 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
/* this is needed for icmp tests */
icmp_init(env);
+#ifndef DEBUG
if (setgroups(1, &pw->pw_gid) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("hce: can't drop privileges");
+#endif
event_init();
@@ -132,8 +140,10 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
signal_set(&ev_sigint, SIGINT, hce_sig_handler, NULL);
signal_set(&ev_sigterm, SIGTERM, hce_sig_handler, NULL);
+ signal_set(&ev_sighup, SIGHUP, hce_sig_handler, NULL);
signal_add(&ev_sigint, NULL);
signal_add(&ev_sigterm, NULL);
+ signal_add(&ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
/* setup pipes */
@@ -403,6 +413,10 @@ hce_dispatch_parent(int fd, short event, void * ptr)
struct imsg imsg;
struct ctl_script scr;
ssize_t n;
+ size_t len;
+
+ static struct table *table = NULL;
+ struct host *host;
ibuf = ptr;
switch (event) {
@@ -436,6 +450,44 @@ hce_dispatch_parent(int fd, short event, void * ptr)
bcopy(imsg.data, &scr, sizeof(scr));
script_done(env, &scr);
break;
+ case IMSG_RECONF:
+ log_debug("hce: reloading configuration");
+ if (imsg.hdr.len !=
+ sizeof(struct hoststated) + IMSG_HEADER_SIZE)
+ fatalx("corrupted reload data");
+ hce_disable_events();
+ purge_config(env, PURGE_TABLES);
+ merge_config(env, (struct hoststated *)imsg.data);
+
+ env->tables = calloc(1, sizeof(*env->tables));
+ if (env->tables == NULL)
+ fatal(NULL);
+
+ TAILQ_INIT(env->tables);
+ break;
+ case IMSG_RECONF_TABLE:
+ if ((table = calloc(1, sizeof(*table))) == NULL)
+ fatal(NULL);
+ memcpy(&table->conf, imsg.data, sizeof(table->conf));
+ TAILQ_INIT(&table->hosts);
+ TAILQ_INSERT_TAIL(env->tables, table, entry);
+ break;
+ case IMSG_RECONF_SENDBUF:
+ len = imsg.hdr.len - IMSG_HEADER_SIZE;
+ table->sendbuf = calloc(1, len);
+ (void)strlcpy(table->sendbuf, (char *)imsg.data, len);
+ break;
+ case IMSG_RECONF_HOST:
+ if ((host = calloc(1, sizeof(*host))) == NULL)
+ fatal(NULL);
+ memcpy(&host->conf, imsg.data, sizeof(host->conf));
+ host->tablename = table->conf.name;
+ TAILQ_INSERT_TAIL(&table->hosts, host, entry);
+ break;
+ case IMSG_RECONF_END:
+ log_warnx("hce: configuration reloaded");
+ hce_setup_events();
+ break;
default:
log_debug("hce_dispatch_parent: unexpected imsg %d",
imsg.hdr.type);
diff --git a/usr.sbin/hoststated/hoststated.c b/usr.sbin/hoststated/hoststated.c
index e9fc8364e16..0858dfe42e2 100644
--- a/usr.sbin/hoststated/hoststated.c
+++ b/usr.sbin/hoststated/hoststated.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hoststated.c,v 1.34 2007/05/31 03:24:05 pyr Exp $ */
+/* $OpenBSD: hoststated.c,v 1.35 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -47,6 +47,7 @@ void main_dispatch_relay(int, short, void *);
int check_child(pid_t, const char *);
int send_all(struct hoststated *, enum imsg_type,
void *, u_int16_t);
+void reconfigure(void);
int pipe_parent2pfe[2];
int pipe_parent2hce[2];
@@ -91,7 +92,7 @@ main_sig_handler(int sig, short event, void *arg)
main_shutdown(env);
break;
case SIGHUP:
- /* reconfigure */
+ reconfigure();
break;
default:
fatalx("unexpected signal");
@@ -363,6 +364,65 @@ merge_config(struct hoststated *env, struct hoststated *new_env)
env->services = new_env->services;
}
+
+void
+reconfigure(void)
+{
+ struct hoststated *env = hoststated_env;
+ struct hoststated *new_env;
+ struct service *service;
+ struct address *virt;
+ struct table *table;
+ struct host *host;
+
+ log_info("reloading configuration");
+ if ((new_env = parse_config(env->confpath, env->opts)) == NULL)
+ exit(1);
+
+ purge_config(env, PURGE_EVERYTHING);
+ merge_config(env, new_env);
+ free(new_env);
+ log_info("configuration merge done");
+
+ /*
+ * first reconfigure pfe
+ */
+ imsg_compose(ibuf_pfe, IMSG_RECONF, 0, 0, env, sizeof(*env));
+ TAILQ_FOREACH(table, env->tables, entry) {
+ imsg_compose(ibuf_pfe, IMSG_RECONF_TABLE, 0, 0,
+ &table->conf, sizeof(table->conf));
+ TAILQ_FOREACH(host, &table->hosts, entry) {
+ imsg_compose(ibuf_pfe, IMSG_RECONF_HOST, 0, 0,
+ &host->conf, sizeof(host->conf));
+ }
+ }
+ TAILQ_FOREACH(service, env->services, entry) {
+ imsg_compose(ibuf_pfe, IMSG_RECONF_SERVICE, 0, 0,
+ &service->conf, sizeof(service->conf));
+ TAILQ_FOREACH(virt, &service->virts, entry)
+ imsg_compose(ibuf_pfe, IMSG_RECONF_VIRT, 0, 0,
+ virt, sizeof(*virt));
+ }
+ imsg_compose(ibuf_pfe, IMSG_RECONF_END, 0, 0, NULL, 0);
+
+ /*
+ * then reconfigure hce
+ */
+ imsg_compose(ibuf_hce, IMSG_RECONF, 0, 0, env, sizeof(*env));
+ TAILQ_FOREACH(table, env->tables, entry) {
+ imsg_compose(ibuf_hce, IMSG_RECONF_TABLE, 0, 0,
+ &table->conf, sizeof(table->conf));
+ if (table->sendbuf != NULL)
+ imsg_compose(ibuf_hce, IMSG_RECONF_SENDBUF, 0, 0,
+ table->sendbuf, strlen(table->sendbuf) + 1);
+ TAILQ_FOREACH(host, &table->hosts, entry) {
+ imsg_compose(ibuf_hce, IMSG_RECONF_HOST, 0, 0,
+ &host->conf, sizeof(host->conf));
+ }
+ }
+ imsg_compose(ibuf_hce, IMSG_RECONF_END, 0, 0, NULL, 0);
+}
+
void
purge_config(struct hoststated *env, u_int8_t what)
{
@@ -375,7 +435,7 @@ purge_config(struct hoststated *env, u_int8_t what)
struct relay *rly;
struct session *sess;
- if (what & PURGE_TABLES) {
+ if (what & PURGE_TABLES && env->tables != NULL) {
while ((table = TAILQ_FIRST(env->tables)) != NULL) {
while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
@@ -392,9 +452,10 @@ purge_config(struct hoststated *env, u_int8_t what)
free(table);
}
free(env->tables);
+ env->tables = NULL;
}
- if (what & PURGE_SERVICES) {
+ if (what & PURGE_SERVICES && env->services != NULL) {
while ((service = TAILQ_FIRST(env->services)) != NULL) {
TAILQ_REMOVE(env->services, service, entry);
while ((virt = TAILQ_FIRST(&service->virts)) != NULL) {
@@ -404,6 +465,7 @@ purge_config(struct hoststated *env, u_int8_t what)
free(service);
}
free(env->services);
+ env->services = NULL;
}
if (what & PURGE_RELAYS) {
@@ -451,7 +513,6 @@ purge_config(struct hoststated *env, u_int8_t what)
free(proto);
}
}
-
}
void
@@ -510,6 +571,7 @@ main_dispatch_pfe(int fd, short event, void *ptr)
/*
* so far we only get here if no L7 (relay) is done.
*/
+ reconfigure();
break;
default:
log_debug("main_dispatch_pfe: unexpected imsg %d",
diff --git a/usr.sbin/hoststated/pfe.c b/usr.sbin/hoststated/pfe.c
index 67e34cb9707..3d2f73cd6c1 100644
--- a/usr.sbin/hoststated/pfe.c
+++ b/usr.sbin/hoststated/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.29 2007/05/31 18:24:02 pyr Exp $ */
+/* $OpenBSD: pfe.c,v 1.30 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -58,6 +58,9 @@ pfe_sig_handler(int sig, short event, void *arg)
case SIGINT:
case SIGTERM:
pfe_shutdown();
+ case SIGHUP:
+ /* nothing */
+ break;
default:
fatalx("pfe_sig_handler: unexpected signal");
}
@@ -72,6 +75,7 @@ pfe(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
struct passwd *pw;
struct event ev_sigint;
struct event ev_sigterm;
+ struct event ev_sighup;
int i;
size_t size;
@@ -101,6 +105,8 @@ pfe(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
fatal("pfe: chroot");
if (chdir("/") == -1)
fatal("pfe: chdir(\"/\")");
+#else
+#warning disabling privilege revocation and chroot in DEBUG mode
#endif
setproctitle("pf update engine");
@@ -117,8 +123,10 @@ pfe(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
signal_set(&ev_sigint, SIGINT, pfe_sig_handler, NULL);
signal_set(&ev_sigterm, SIGTERM, pfe_sig_handler, NULL);
+ signal_set(&ev_sighup, SIGHUP, pfe_sig_handler, NULL);
signal_add(&ev_sigint, NULL);
signal_add(&ev_sigterm, NULL);
+ signal_add(&ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
/* setup pipes */
@@ -316,6 +324,11 @@ pfe_dispatch_parent(int fd, short event, void * ptr)
struct imsg imsg;
ssize_t n;
+ static struct service *service = NULL;
+ static struct table *table = NULL;
+ struct host *host;
+ struct address *virt;
+
ibuf = ptr;
switch (event) {
case EV_READ:
@@ -340,6 +353,70 @@ pfe_dispatch_parent(int fd, short event, void * ptr)
break;
switch (imsg.hdr.type) {
+ case IMSG_RECONF:
+ log_debug("pfe: reloading configuration");
+ if (imsg.hdr.len !=
+ sizeof(struct hoststated) + IMSG_HEADER_SIZE)
+ fatalx("corrupted reload data");
+ pfe_disable_events();
+ purge_config(env, PURGE_EVERYTHING);
+ merge_config(env, (struct hoststated *)imsg.data);
+
+ env->tables = calloc(1, sizeof(*env->tables));
+ env->services = calloc(1, sizeof(*env->services));
+ if (env->tables == NULL || env->services == NULL)
+ fatal(NULL);
+
+ TAILQ_INIT(env->tables);
+ TAILQ_INIT(env->services);
+ break;
+ case IMSG_RECONF_TABLE:
+ if ((table = calloc(1, sizeof(*table))) == NULL)
+ fatal(NULL);
+ memcpy(&table->conf, imsg.data, sizeof(table->conf));
+ TAILQ_INIT(&table->hosts);
+ TAILQ_INSERT_TAIL(env->tables, table, entry);
+ break;
+ case IMSG_RECONF_HOST:
+ if ((host = calloc(1, sizeof(*host))) == NULL)
+ fatal(NULL);
+ memcpy(&host->conf, imsg.data, sizeof(host->conf));
+ host->tablename = table->conf.name;
+ TAILQ_INSERT_TAIL(&table->hosts, host, entry);
+ break;
+ case IMSG_RECONF_SERVICE:
+ if ((service = calloc(1, sizeof(*service))) == NULL)
+ fatal(NULL);
+ memcpy(&service->conf, imsg.data,
+ sizeof(service->conf));
+ service->table = table_find(env,
+ service->conf.table_id);
+ if (service->conf.backup_id == EMPTY_TABLE)
+ service->backup = &env->empty_table;
+ else
+ service->backup = table_find(env,
+ service->conf.backup_id);
+ if (service->table == NULL || service->backup == NULL)
+ fatal("pfe_dispatch_parent:"
+ " corrupted configuration");
+ log_debug("pfe_dispatch_parent: service->table: %s",
+ service->table->conf.name);
+ log_debug("pfe_dispatch_parent: service->backup: %s",
+ service->backup->conf.name);
+ TAILQ_INIT(&service->virts);
+ TAILQ_INSERT_TAIL(env->services, service, entry);
+ break;
+ case IMSG_RECONF_VIRT:
+ if ((virt = calloc(1, sizeof(*virt))) == NULL)
+ fatal(NULL);
+ memcpy(virt, imsg.data, sizeof(*virt));
+ TAILQ_INSERT_TAIL(&service->virts, virt, entry);
+ break;
+ case IMSG_RECONF_END:
+ log_warnx("pfe: configuration reloaded");
+ pfe_setup_events();
+ pfe_sync();
+ break;
default:
log_debug("pfe_dispatch_parent: unexpected imsg %d",
imsg.hdr.type);
diff --git a/usr.sbin/hoststated/relay.c b/usr.sbin/hoststated/relay.c
index 47f44a8c9aa..cfdd3a8dbc9 100644
--- a/usr.sbin/hoststated/relay.c
+++ b/usr.sbin/hoststated/relay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay.c,v 1.32 2007/05/29 00:48:04 pyr Exp $ */
+/* $OpenBSD: relay.c,v 1.33 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -172,6 +172,9 @@ relay(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
fatal("relay: chroot");
if (chdir("/") == -1)
fatal("relay: chdir(\"/\")");
+
+#else
+#warning disabling privilege revocation and chroot in DEBUG mode
#endif
setproctitle("socket relay engine");
diff --git a/usr.sbin/relayd/control.c b/usr.sbin/relayd/control.c
index e4f42402748..33d4dca084a 100644
--- a/usr.sbin/relayd/control.c
+++ b/usr.sbin/relayd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.15 2007/05/29 23:19:18 pyr Exp $ */
+/* $OpenBSD: control.c,v 1.16 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -318,8 +318,16 @@ control_dispatch_imsg(int fd, short event, void *arg)
NULL, 0);
break;
}
- imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, NULL, 0);
imsg_compose(ibuf_main, IMSG_CTL_RELOAD, 0, 0, NULL, 0);
+ /*
+ * we unconditionnaly return a CTL_OK imsg because
+ * we have no choice.
+ *
+ * so in this case, the reply hoststatectl gets means
+ * 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);
break;
case IMSG_CTL_NOTIFY:
if (c->flags & CTL_CONN_NOTIFY) {
diff --git a/usr.sbin/relayd/hce.c b/usr.sbin/relayd/hce.c
index 35437fd1869..b674886ade9 100644
--- a/usr.sbin/relayd/hce.c
+++ b/usr.sbin/relayd/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.25 2007/05/31 05:07:08 pyr Exp $ */
+/* $OpenBSD: hce.c,v 1.26 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -64,6 +64,7 @@ hce_sig_handler(int sig, short event, void *arg)
hce_shutdown();
break;
case SIGHUP:
+ /* nothing */
break;
default:
fatalx("hce_sig_handler: unexpected signal");
@@ -80,6 +81,7 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
int i;
struct event ev_sigint;
struct event ev_sigterm;
+ struct event ev_sighup;
switch (pid = fork()) {
case -1:
@@ -96,10 +98,14 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
if ((pw = getpwnam(HOSTSTATED_USER)) == NULL)
fatal("hce: getpwnam");
+#ifndef DEBUG
if (chroot(pw->pw_dir) == -1)
fatal("hce: chroot");
if (chdir("/") == -1)
fatal("hce: chdir(\"/\")");
+#else
+#warning disabling privilege revocation and chroot in DEBUG mode
+#endif
setproctitle("host check engine");
hoststated_process = PROC_HCE;
@@ -107,10 +113,12 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
/* this is needed for icmp tests */
icmp_init(env);
+#ifndef DEBUG
if (setgroups(1, &pw->pw_gid) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("hce: can't drop privileges");
+#endif
event_init();
@@ -132,8 +140,10 @@ hce(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
signal_set(&ev_sigint, SIGINT, hce_sig_handler, NULL);
signal_set(&ev_sigterm, SIGTERM, hce_sig_handler, NULL);
+ signal_set(&ev_sighup, SIGHUP, hce_sig_handler, NULL);
signal_add(&ev_sigint, NULL);
signal_add(&ev_sigterm, NULL);
+ signal_add(&ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
/* setup pipes */
@@ -403,6 +413,10 @@ hce_dispatch_parent(int fd, short event, void * ptr)
struct imsg imsg;
struct ctl_script scr;
ssize_t n;
+ size_t len;
+
+ static struct table *table = NULL;
+ struct host *host;
ibuf = ptr;
switch (event) {
@@ -436,6 +450,44 @@ hce_dispatch_parent(int fd, short event, void * ptr)
bcopy(imsg.data, &scr, sizeof(scr));
script_done(env, &scr);
break;
+ case IMSG_RECONF:
+ log_debug("hce: reloading configuration");
+ if (imsg.hdr.len !=
+ sizeof(struct hoststated) + IMSG_HEADER_SIZE)
+ fatalx("corrupted reload data");
+ hce_disable_events();
+ purge_config(env, PURGE_TABLES);
+ merge_config(env, (struct hoststated *)imsg.data);
+
+ env->tables = calloc(1, sizeof(*env->tables));
+ if (env->tables == NULL)
+ fatal(NULL);
+
+ TAILQ_INIT(env->tables);
+ break;
+ case IMSG_RECONF_TABLE:
+ if ((table = calloc(1, sizeof(*table))) == NULL)
+ fatal(NULL);
+ memcpy(&table->conf, imsg.data, sizeof(table->conf));
+ TAILQ_INIT(&table->hosts);
+ TAILQ_INSERT_TAIL(env->tables, table, entry);
+ break;
+ case IMSG_RECONF_SENDBUF:
+ len = imsg.hdr.len - IMSG_HEADER_SIZE;
+ table->sendbuf = calloc(1, len);
+ (void)strlcpy(table->sendbuf, (char *)imsg.data, len);
+ break;
+ case IMSG_RECONF_HOST:
+ if ((host = calloc(1, sizeof(*host))) == NULL)
+ fatal(NULL);
+ memcpy(&host->conf, imsg.data, sizeof(host->conf));
+ host->tablename = table->conf.name;
+ TAILQ_INSERT_TAIL(&table->hosts, host, entry);
+ break;
+ case IMSG_RECONF_END:
+ log_warnx("hce: configuration reloaded");
+ hce_setup_events();
+ break;
default:
log_debug("hce_dispatch_parent: unexpected imsg %d",
imsg.hdr.type);
diff --git a/usr.sbin/relayd/pfe.c b/usr.sbin/relayd/pfe.c
index 67e34cb9707..3d2f73cd6c1 100644
--- a/usr.sbin/relayd/pfe.c
+++ b/usr.sbin/relayd/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.29 2007/05/31 18:24:02 pyr Exp $ */
+/* $OpenBSD: pfe.c,v 1.30 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -58,6 +58,9 @@ pfe_sig_handler(int sig, short event, void *arg)
case SIGINT:
case SIGTERM:
pfe_shutdown();
+ case SIGHUP:
+ /* nothing */
+ break;
default:
fatalx("pfe_sig_handler: unexpected signal");
}
@@ -72,6 +75,7 @@ pfe(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
struct passwd *pw;
struct event ev_sigint;
struct event ev_sigterm;
+ struct event ev_sighup;
int i;
size_t size;
@@ -101,6 +105,8 @@ pfe(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
fatal("pfe: chroot");
if (chdir("/") == -1)
fatal("pfe: chdir(\"/\")");
+#else
+#warning disabling privilege revocation and chroot in DEBUG mode
#endif
setproctitle("pf update engine");
@@ -117,8 +123,10 @@ pfe(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
signal_set(&ev_sigint, SIGINT, pfe_sig_handler, NULL);
signal_set(&ev_sigterm, SIGTERM, pfe_sig_handler, NULL);
+ signal_set(&ev_sighup, SIGHUP, pfe_sig_handler, NULL);
signal_add(&ev_sigint, NULL);
signal_add(&ev_sigterm, NULL);
+ signal_add(&ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
/* setup pipes */
@@ -316,6 +324,11 @@ pfe_dispatch_parent(int fd, short event, void * ptr)
struct imsg imsg;
ssize_t n;
+ static struct service *service = NULL;
+ static struct table *table = NULL;
+ struct host *host;
+ struct address *virt;
+
ibuf = ptr;
switch (event) {
case EV_READ:
@@ -340,6 +353,70 @@ pfe_dispatch_parent(int fd, short event, void * ptr)
break;
switch (imsg.hdr.type) {
+ case IMSG_RECONF:
+ log_debug("pfe: reloading configuration");
+ if (imsg.hdr.len !=
+ sizeof(struct hoststated) + IMSG_HEADER_SIZE)
+ fatalx("corrupted reload data");
+ pfe_disable_events();
+ purge_config(env, PURGE_EVERYTHING);
+ merge_config(env, (struct hoststated *)imsg.data);
+
+ env->tables = calloc(1, sizeof(*env->tables));
+ env->services = calloc(1, sizeof(*env->services));
+ if (env->tables == NULL || env->services == NULL)
+ fatal(NULL);
+
+ TAILQ_INIT(env->tables);
+ TAILQ_INIT(env->services);
+ break;
+ case IMSG_RECONF_TABLE:
+ if ((table = calloc(1, sizeof(*table))) == NULL)
+ fatal(NULL);
+ memcpy(&table->conf, imsg.data, sizeof(table->conf));
+ TAILQ_INIT(&table->hosts);
+ TAILQ_INSERT_TAIL(env->tables, table, entry);
+ break;
+ case IMSG_RECONF_HOST:
+ if ((host = calloc(1, sizeof(*host))) == NULL)
+ fatal(NULL);
+ memcpy(&host->conf, imsg.data, sizeof(host->conf));
+ host->tablename = table->conf.name;
+ TAILQ_INSERT_TAIL(&table->hosts, host, entry);
+ break;
+ case IMSG_RECONF_SERVICE:
+ if ((service = calloc(1, sizeof(*service))) == NULL)
+ fatal(NULL);
+ memcpy(&service->conf, imsg.data,
+ sizeof(service->conf));
+ service->table = table_find(env,
+ service->conf.table_id);
+ if (service->conf.backup_id == EMPTY_TABLE)
+ service->backup = &env->empty_table;
+ else
+ service->backup = table_find(env,
+ service->conf.backup_id);
+ if (service->table == NULL || service->backup == NULL)
+ fatal("pfe_dispatch_parent:"
+ " corrupted configuration");
+ log_debug("pfe_dispatch_parent: service->table: %s",
+ service->table->conf.name);
+ log_debug("pfe_dispatch_parent: service->backup: %s",
+ service->backup->conf.name);
+ TAILQ_INIT(&service->virts);
+ TAILQ_INSERT_TAIL(env->services, service, entry);
+ break;
+ case IMSG_RECONF_VIRT:
+ if ((virt = calloc(1, sizeof(*virt))) == NULL)
+ fatal(NULL);
+ memcpy(virt, imsg.data, sizeof(*virt));
+ TAILQ_INSERT_TAIL(&service->virts, virt, entry);
+ break;
+ case IMSG_RECONF_END:
+ log_warnx("pfe: configuration reloaded");
+ pfe_setup_events();
+ pfe_sync();
+ break;
default:
log_debug("pfe_dispatch_parent: unexpected imsg %d",
imsg.hdr.type);
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c
index 47f44a8c9aa..cfdd3a8dbc9 100644
--- a/usr.sbin/relayd/relay.c
+++ b/usr.sbin/relayd/relay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay.c,v 1.32 2007/05/29 00:48:04 pyr Exp $ */
+/* $OpenBSD: relay.c,v 1.33 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -172,6 +172,9 @@ relay(struct hoststated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2],
fatal("relay: chroot");
if (chdir("/") == -1)
fatal("relay: chdir(\"/\")");
+
+#else
+#warning disabling privilege revocation and chroot in DEBUG mode
#endif
setproctitle("socket relay engine");
diff --git a/usr.sbin/relayd/relayd.c b/usr.sbin/relayd/relayd.c
index 8c14cf33528..f5fd78f206d 100644
--- a/usr.sbin/relayd/relayd.c
+++ b/usr.sbin/relayd/relayd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.c,v 1.34 2007/05/31 03:24:05 pyr Exp $ */
+/* $OpenBSD: relayd.c,v 1.35 2007/06/07 07:19:50 pyr Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -47,6 +47,7 @@ void main_dispatch_relay(int, short, void *);
int check_child(pid_t, const char *);
int send_all(struct hoststated *, enum imsg_type,
void *, u_int16_t);
+void reconfigure(void);
int pipe_parent2pfe[2];
int pipe_parent2hce[2];
@@ -91,7 +92,7 @@ main_sig_handler(int sig, short event, void *arg)
main_shutdown(env);
break;
case SIGHUP:
- /* reconfigure */
+ reconfigure();
break;
default:
fatalx("unexpected signal");
@@ -363,6 +364,65 @@ merge_config(struct hoststated *env, struct hoststated *new_env)
env->services = new_env->services;
}
+
+void
+reconfigure(void)
+{
+ struct hoststated *env = hoststated_env;
+ struct hoststated *new_env;
+ struct service *service;
+ struct address *virt;
+ struct table *table;
+ struct host *host;
+
+ log_info("reloading configuration");
+ if ((new_env = parse_config(env->confpath, env->opts)) == NULL)
+ exit(1);
+
+ purge_config(env, PURGE_EVERYTHING);
+ merge_config(env, new_env);
+ free(new_env);
+ log_info("configuration merge done");
+
+ /*
+ * first reconfigure pfe
+ */
+ imsg_compose(ibuf_pfe, IMSG_RECONF, 0, 0, env, sizeof(*env));
+ TAILQ_FOREACH(table, env->tables, entry) {
+ imsg_compose(ibuf_pfe, IMSG_RECONF_TABLE, 0, 0,
+ &table->conf, sizeof(table->conf));
+ TAILQ_FOREACH(host, &table->hosts, entry) {
+ imsg_compose(ibuf_pfe, IMSG_RECONF_HOST, 0, 0,
+ &host->conf, sizeof(host->conf));
+ }
+ }
+ TAILQ_FOREACH(service, env->services, entry) {
+ imsg_compose(ibuf_pfe, IMSG_RECONF_SERVICE, 0, 0,
+ &service->conf, sizeof(service->conf));
+ TAILQ_FOREACH(virt, &service->virts, entry)
+ imsg_compose(ibuf_pfe, IMSG_RECONF_VIRT, 0, 0,
+ virt, sizeof(*virt));
+ }
+ imsg_compose(ibuf_pfe, IMSG_RECONF_END, 0, 0, NULL, 0);
+
+ /*
+ * then reconfigure hce
+ */
+ imsg_compose(ibuf_hce, IMSG_RECONF, 0, 0, env, sizeof(*env));
+ TAILQ_FOREACH(table, env->tables, entry) {
+ imsg_compose(ibuf_hce, IMSG_RECONF_TABLE, 0, 0,
+ &table->conf, sizeof(table->conf));
+ if (table->sendbuf != NULL)
+ imsg_compose(ibuf_hce, IMSG_RECONF_SENDBUF, 0, 0,
+ table->sendbuf, strlen(table->sendbuf) + 1);
+ TAILQ_FOREACH(host, &table->hosts, entry) {
+ imsg_compose(ibuf_hce, IMSG_RECONF_HOST, 0, 0,
+ &host->conf, sizeof(host->conf));
+ }
+ }
+ imsg_compose(ibuf_hce, IMSG_RECONF_END, 0, 0, NULL, 0);
+}
+
void
purge_config(struct hoststated *env, u_int8_t what)
{
@@ -375,7 +435,7 @@ purge_config(struct hoststated *env, u_int8_t what)
struct relay *rly;
struct session *sess;
- if (what & PURGE_TABLES) {
+ if (what & PURGE_TABLES && env->tables != NULL) {
while ((table = TAILQ_FIRST(env->tables)) != NULL) {
while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
@@ -392,9 +452,10 @@ purge_config(struct hoststated *env, u_int8_t what)
free(table);
}
free(env->tables);
+ env->tables = NULL;
}
- if (what & PURGE_SERVICES) {
+ if (what & PURGE_SERVICES && env->services != NULL) {
while ((service = TAILQ_FIRST(env->services)) != NULL) {
TAILQ_REMOVE(env->services, service, entry);
while ((virt = TAILQ_FIRST(&service->virts)) != NULL) {
@@ -404,6 +465,7 @@ purge_config(struct hoststated *env, u_int8_t what)
free(service);
}
free(env->services);
+ env->services = NULL;
}
if (what & PURGE_RELAYS) {
@@ -451,7 +513,6 @@ purge_config(struct hoststated *env, u_int8_t what)
free(proto);
}
}
-
}
void
@@ -510,6 +571,7 @@ main_dispatch_pfe(int fd, short event, void *ptr)
/*
* so far we only get here if no L7 (relay) is done.
*/
+ reconfigure();
break;
default:
log_debug("main_dispatch_pfe: unexpected imsg %d",