diff options
author | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2007-06-07 07:19:51 +0000 |
---|---|---|
committer | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2007-06-07 07:19:51 +0000 |
commit | 0a9bb0d1fab75b6428acbeeb5a42e6ce76467cf6 (patch) | |
tree | a4c324da285797a88895b7543de54beddf214f19 /usr.sbin | |
parent | e0d66f1005b177e1fbe63f0b4833c5557e3fb6ea (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.c | 12 | ||||
-rw-r--r-- | usr.sbin/hoststated/hce.c | 54 | ||||
-rw-r--r-- | usr.sbin/hoststated/hoststated.c | 72 | ||||
-rw-r--r-- | usr.sbin/hoststated/pfe.c | 79 | ||||
-rw-r--r-- | usr.sbin/hoststated/relay.c | 5 | ||||
-rw-r--r-- | usr.sbin/relayd/control.c | 12 | ||||
-rw-r--r-- | usr.sbin/relayd/hce.c | 54 | ||||
-rw-r--r-- | usr.sbin/relayd/pfe.c | 79 | ||||
-rw-r--r-- | usr.sbin/relayd/relay.c | 5 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.c | 72 |
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", |