summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd/hce.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2011-05-19 08:56:50 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2011-05-19 08:56:50 +0000
commit31b1bbafe11da6e0dead1dd433eff2ab64ae8bb6 (patch)
tree911cab636cae40f30bbaab5a11769d79cf7f41b2 /usr.sbin/relayd/hce.c
parent1e687a712e695c6cf93da2be7c3d01ef04f587cb (diff)
Fix reload support in relayd(8) by reimplementing large parts of the
daemon infrastructure. The previous design made it fairly hard to reload the complex data structures, especially relays and protocols. One of the reasons was that the privsep'd relayd processes had two ways of getting their configuration: 1) from memory after forking from the parent process and 2) and (partially) via imsgs after reload. The new implementation first forks the privsep'd children before the parents loads the configuration and sends it via imsgs to them; so it is only like 2) before. It is based on an approach that I first implemented for iked(8) and I also fixed many bugs in the code. Thanks to many testers including dlg@ sthen@ phessler@ ok pyr@ dlg@ sthen@
Diffstat (limited to 'usr.sbin/relayd/hce.c')
-rw-r--r--usr.sbin/relayd/hce.c78
1 files changed, 28 insertions, 50 deletions
diff --git a/usr.sbin/relayd/hce.c b/usr.sbin/relayd/hce.c
index ab80166c4bb..147b272bfde 100644
--- a/usr.sbin/relayd/hce.c
+++ b/usr.sbin/relayd/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.59 2011/05/09 12:08:47 reyk Exp $ */
+/* $OpenBSD: hce.c,v 1.60 2011/05/19 08:56:49 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -72,14 +72,15 @@ hce(struct privsep *ps, struct privsep_proc *p)
void
hce_init(struct privsep *ps, struct privsep_proc *p, void *arg)
{
- purge_config(env, PURGE_RDRS|PURGE_RELAYS|PURGE_PROTOS);
+ if (config_init(ps->ps_env) == -1)
+ fatal("failed to initialize configuration");
env->sc_id = getpid() & 0xffff;
/* Allow maximum available sockets for TCP checks */
socket_rlimit(-1);
- hce_setup_events();
+ snmp_init(env, PROC_PARENT);
}
void
@@ -88,18 +89,17 @@ hce_setup_events(void)
struct timeval tv;
struct table *table;
- snmp_init(env, PROC_PARENT);
-
- if (!TAILQ_EMPTY(env->sc_tables)) {
+ if (!(TAILQ_EMPTY(env->sc_tables) ||
+ event_initialized(&env->sc_ev))) {
evtimer_set(&env->sc_ev, hce_launch_checks, env);
bzero(&tv, sizeof(tv));
evtimer_add(&env->sc_ev, &tv);
}
if (env->sc_flags & F_SSL) {
- ssl_init(env);
TAILQ_FOREACH(table, env->sc_tables, entry) {
- if (!(table->conf.flags & F_SSL))
+ if (!(table->conf.flags & F_SSL) ||
+ table->ssl_ctx != NULL)
continue;
table->ssl_ctx = ssl_ctx_create(env);
}
@@ -116,8 +116,10 @@ hce_disable_events(void)
TAILQ_FOREACH(table, env->sc_tables, entry) {
TAILQ_FOREACH(host, &table->hosts, entry) {
host->he = HCE_ABORT;
- event_del(&host->cte.ev);
- close(host->cte.s);
+ if (event_initialized(&host->cte.ev)) {
+ event_del(&host->cte.ev);
+ close(host->cte.s);
+ }
}
}
if (env->sc_has_icmp) {
@@ -146,7 +148,11 @@ hce_launch_checks(int fd, short event, void *arg)
if ((host->flags & F_CHECK_DONE) == 0)
host->he = HCE_INTERVAL_TIMEOUT;
host->flags &= ~(F_CHECK_SENT|F_CHECK_DONE);
- event_del(&host->cte.ev);
+ if (event_initialized(&host->cte.ev)) {
+ event_del(&host->cte.ev);
+ close(host->cte.s);
+ }
+ host->cte.s = -1;
}
}
@@ -331,9 +337,6 @@ int
hce_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
{
struct ctl_script scr;
- size_t len;
- static struct table *table = NULL;
- struct host *host, *parent;
switch (imsg->hdr.type) {
case IMSG_SCRIPT:
@@ -341,47 +344,22 @@ hce_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
bcopy(imsg->data, &scr, sizeof(scr));
script_done(env, &scr);
break;
- case IMSG_RECONF:
- IMSG_SIZE_CHECK(imsg, env);
- log_debug("%s: reloading configuration", __func__);
- hce_disable_events();
- purge_config(env, PURGE_TABLES);
- merge_config(env, (struct relayd *)imsg->data);
-
- env->sc_tables = calloc(1, sizeof(*env->sc_tables));
- if (env->sc_tables == NULL)
- fatal(NULL);
-
- TAILQ_INIT(env->sc_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->sc_tables, table, entry);
+ case IMSG_CFG_TABLE:
+ config_gettable(env, imsg);
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);
+ case IMSG_CFG_HOST:
+ config_gethost(env, imsg);
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);
- if (host->conf.parentid) {
- parent = host_find(env, host->conf.parentid);
- SLIST_INSERT_HEAD(&parent->children,
- host, child);
- }
+ case IMSG_SNMPSOCK:
+ snmp_getsock(env, imsg);
break;
- case IMSG_RECONF_END:
- log_warnx("%s: configuration reloaded", __func__);
+ case IMSG_CFG_DONE:
+ config_getcfg(env, imsg);
hce_setup_events();
break;
+ case IMSG_CTL_RESET:
+ config_getreset(env, imsg);
+ break;
default:
return (-1);
}