Commit Diff


commit - 08348b86d5ce0ac714bc087317428d464f7d2128
commit + 17acabee04364fc3733815f102d0dbcef8a2937a
blob - f16e9bd3d61e93ec7fb0977016fa0f75ef287538
blob + c022077f936affd858c491481daacf78d88f55c4
--- check_icmp.c
+++ check_icmp.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: check_icmp.c,v 1.23 2008/01/31 09:33:39 reyk Exp $	*/
+/*	$OpenBSD: check_icmp.c,v 1.24 2008/07/19 10:52:32 reyk Exp $	*/
 
 /*
  * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -197,7 +197,8 @@ send_icmp(int s, short event, void *arg)
 		    table->conf.flags & F_DISABLE)
 			continue;
 		TAILQ_FOREACH(host, &table->hosts, entry) {
-			if (host->flags & (F_DISABLE | F_CHECK_SENT))
+			if (host->flags & (F_DISABLE | F_CHECK_SENT) ||
+			    host->conf.parentid)
 				continue;
 			if (((struct sockaddr *)&host->conf.ss)->sa_family !=
 			    cie->af)
blob - d0c7258fe7db6ee50b978eaa9ccb898a96b0d8dc
blob + 67be0a1a7be61bf815f27f3750bf2a8b57e276f8
--- control.c
+++ control.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: control.c,v 1.25 2008/01/31 09:33:39 reyk Exp $	*/
+/*	$OpenBSD: control.c,v 1.26 2008/07/19 10:52:32 reyk Exp $	*/
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -293,7 +293,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
 				fatalx("invalid imsg header len");
 			memcpy(&id, imsg.data, sizeof(id));
-			if (disable_host(c, &id))
+			if (disable_host(c, &id, NULL))
 				imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1,
 				    NULL, 0);
 			else {
@@ -307,7 +307,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
 				fatalx("invalid imsg header len");
 			memcpy(&id, imsg.data, sizeof(id));
-			if (enable_host(c, &id))
+			if (enable_host(c, &id, NULL))
 				imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1,
 				    NULL, 0);
 			else {
blob - f0cd92cfb47453d254596488e4b7a610cc9b9f82
blob + 262f7f646c9c94c952edfeb6e9780c4a02269be0
--- hce.c
+++ hce.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: hce.c,v 1.41 2008/03/12 10:50:44 pyr Exp $	*/
+/*	$OpenBSD: hce.c,v 1.42 2008/07/19 10:52:32 reyk Exp $	*/
 
 /*
  * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -240,7 +240,7 @@ hce_launch_checks(int fd, short event, void *arg)
 			fatalx("hce_launch_checks: unknown check type");
 
 		TAILQ_FOREACH(host, &table->hosts, entry) {
-			if (host->flags & F_DISABLE)
+			if (host->flags & F_DISABLE || host->conf.parentid)
 				continue;
 			switch (table->conf.check) {
 			case CHECK_ICMP:
@@ -276,7 +276,11 @@ hce_notify_done(struct host *host, const char *msg)
 	struct timeval		 tv_now, tv_dur;
 	u_long			 duration;
 	u_int			 logopt;
+	struct host		*h;
+	int			 hostup;
 
+	hostup = host->up;
+
 	if (host->up == HOST_DOWN && host->retry_cnt) {
 		log_debug("hce_notify_done: host %s retry %d",
 		    host->conf.name, host->retry_cnt);
@@ -327,6 +331,15 @@ hce_notify_done(struct host *host, const char *msg)
 		snmp_hosttrap(table, host);
 
 	host->last_up = host->up;
+
+	if (TAILQ_EMPTY(&host->children))
+		return;
+
+	/* Notify for all other hosts that inherit the state from this one */
+	TAILQ_FOREACH(h, &host->children, child) {
+		h->up = hostup;		
+		hce_notify_done(h, msg);
+	}
 }
 
 void
blob - 3c7cb2b61a7c0070fae8647d77287e9692ccd913
blob + 9a881ed0f2a6d8e5432f0b9d0801a73ccfe9815f
--- parse.y
+++ parse.y
@@ -1,4 +1,4 @@
-/*	$OpenBSD: parse.y,v 1.119 2008/07/17 16:41:06 reyk Exp $	*/
+/*	$OpenBSD: parse.y,v 1.120 2008/07/19 10:52:32 reyk Exp $	*/
 
 /*
  * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
@@ -130,11 +130,11 @@ typedef struct {
 %token	ON PATH PORT PREFORK PROTO QUERYSTR REAL REDIRECT RELAY REMOVE TRAP
 %token	REQUEST RESPONSE RETRY RETURN ROUNDROBIN SACK SCRIPT SEND SESSION
 %token	SOCKET SSL STICKYADDR STYLE TABLE TAG TCP TIMEOUT TO UPDATES URL
-%token	VIRTUAL WITH ERROR ROUTE TRANSPARENT
+%token	VIRTUAL WITH ERROR ROUTE TRANSPARENT PARENT
 %token	<v.string>	STRING
 %token  <v.number>	NUMBER
 %type	<v.string>	interface hostname table
-%type	<v.number>	port http_type loglevel sslcache optssl mark
+%type	<v.number>	port http_type loglevel sslcache optssl mark parent
 %type	<v.number>	proto_type dstmode retry log flag direction forwardmode
 %type	<v.host>	host
 %type	<v.tv>		timeout
@@ -1238,7 +1238,7 @@ interface	: /*empty*/		{ $$ = NULL; }
 		| INTERFACE STRING	{ $$ = $2; }
 		;
 
-host		: STRING retry		{
+host		: STRING retry parent	{
 			struct address *a;
 			struct addresslist al;
 
@@ -1266,6 +1266,8 @@ host		: STRING retry		{
 			free($1);
 			$$->conf.id = 0; /* will be set later */
 			$$->conf.retry = $2;
+			$$->conf.parentid = $3;
+			TAILQ_INIT(&$$->children);
 		}
 		;
 
@@ -1278,6 +1280,15 @@ retry		: /* nothing */		{ $$ = 0; }
 		}
 		;
 
+parent		: /* nothing */		{ $$ = 0; }
+		| PARENT NUMBER		{
+			if (($$ = $2) < 0) {
+				yyerror("invalid parent value: %d\n", $2);
+				YYERROR;
+			}
+		}
+		;
+
 timeout		: NUMBER
 		{
 			if ($1 < 0) {
@@ -1378,6 +1389,7 @@ lookup(char *s)
 		{ "nodelay",		NODELAY },
 		{ "nothing",		NOTHING },
 		{ "on",			ON },
+		{ "parent",		PARENT },
 		{ "path",		PATH },
 		{ "port",		PORT },
 		{ "prefork",		PREFORK },
@@ -1729,7 +1741,7 @@ parse_config(const char *filename, int opts)
 {
 	struct sym	*sym, *next;
 	struct table	*nexttb;
-	struct host	*h;
+	struct host	*h, *ph;
 
 	if ((conf = calloc(1, sizeof(*conf))) == NULL ||
 	    (conf->sc_tables = calloc(1, sizeof(*conf->sc_tables))) == NULL ||
@@ -1833,6 +1845,26 @@ parse_config(const char *filename, int opts)
 			free(table);
 			continue;
 		}
+
+		TAILQ_FOREACH(h, &table->hosts, entry) {
+			if (h->conf.parentid) {
+				ph = host_find(conf, h->conf.parentid);
+
+				/* Validate the parent id */
+				if (h->conf.id == h->conf.parentid ||
+				    ph == NULL || ph->conf.parentid)
+					ph = NULL;
+
+				if (ph == NULL) {
+					log_warnx("host parent id %d invalid",
+					    h->conf.parentid);
+					errors++;
+				} else
+					TAILQ_INSERT_TAIL(&ph->children,
+					    h, child);
+			}
+		}
+
 		if (!(table->conf.flags & F_USED)) {
 			log_warnx("unused table: %s", table->conf.name);
 			errors++;
@@ -2135,6 +2167,7 @@ table_inherit(struct table *tb)
 		}
 		h->conf.tableid = tb->conf.id;
 		h->tablename = tb->conf.name;
+		TAILQ_INIT(&h->children);
 		TAILQ_INSERT_TAIL(&tb->hosts, h, entry);
 	}
 
blob - f905f4f85d94afdbddb851bb472608d973847afb
blob + f06432a6b6b516e6c6ba3f380aa115d31250e400
--- pfe.c
+++ pfe.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: pfe.c,v 1.48 2008/01/31 09:56:28 reyk Exp $	*/
+/*	$OpenBSD: pfe.c,v 1.49 2008/07/19 10:52:32 reyk Exp $	*/
 
 /*
  * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -749,18 +749,20 @@ enable_table(struct ctl_conn *c, struct ctl_id *id)
 }
 
 int
-disable_host(struct ctl_conn *c, struct ctl_id *id)
+disable_host(struct ctl_conn *c, struct ctl_id *id, struct host *host)
 {
-	struct host	*host;
+	struct host	*h;
 	struct table	*table;
 	int		 n;
 
-	if (id->id == EMPTY_ID)
-		host = host_findbyname(env, id->name);
-	else
-		host = host_find(env, id->id);
-	if (host == NULL)
-		return (-1);
+	if (host == NULL) {
+		if (id->id == EMPTY_ID)
+			host = host_findbyname(env, id->name);
+		else
+			host = host_find(env, id->id);
+		if (host == NULL || host->conf.parentid)
+			return (-1);
+	}
 	id->id = host->conf.id;
 
 	if (host->flags & F_DISABLE)
@@ -788,22 +790,30 @@ disable_host(struct ctl_conn *c, struct ctl_id *id)
 		    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();
+
+	/* Disable all children */
+	TAILQ_FOREACH(h, &host->children, child)
+		disable_host(c, id, h);
+
+	if (!host->conf.parentid)
+		pfe_sync();
 	return (0);
 }
 
 int
-enable_host(struct ctl_conn *c, struct ctl_id *id)
+enable_host(struct ctl_conn *c, struct ctl_id *id, struct host *host)
 {
-	struct host	*host;
+	struct host	*h;
 	int		 n;
 
-	if (id->id == EMPTY_ID)
-		host = host_findbyname(env, id->name);
-	else
-		host = host_find(env, id->id);
-	if (host == NULL)
-		return (-1);
+	if (host == NULL) {
+		if (id->id == EMPTY_ID)
+			host = host_findbyname(env, id->name);
+		else
+			host = host_find(env, id->id);
+		if (host == NULL || host->conf.parentid)
+			return (-1);
+	}
 	id->id = host->conf.id;
 
 	if (!(host->flags & F_DISABLE))
@@ -822,7 +832,13 @@ enable_host(struct ctl_conn *c, struct ctl_id *id)
 		    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();
+
+	/* Enable all children */
+	TAILQ_FOREACH(h, &host->children, child)
+		enable_host(c, id, h);
+
+	if (!host->conf.parentid)
+		pfe_sync();
 	return (0);
 }
 
blob - 16c609b0f6968a4aad2fc68a3ccbb0cca8c804ef
blob + 2611a531000b26edb0da153a1c77ceba342821bc
--- relayd.conf.5
+++ relayd.conf.5
@@ -1,4 +1,4 @@
-.\"	$OpenBSD: relayd.conf.5,v 1.88 2008/06/11 18:21:20 reyk Exp $
+.\"	$OpenBSD: relayd.conf.5,v 1.89 2008/07/19 10:52:32 reyk Exp $
 .\"
 .\" Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
 .\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: June 11 2008 $
+.Dd $Mdocdate: July 19 2008 $
 .Dt RELAYD.CONF 5
 .Os
 .Sh NAME
@@ -183,7 +183,7 @@ The table can be later enabled through
 .El
 Each table must contain at least one host;
 multiple hosts are separated by newline, comma, or whitespace.
-Host entries may be defined with the following attribute:
+Host entries may be defined with the following attributes:
 .Bl -tag -width retry
 .It Ic retry Ar number
 The optional retry option adds a tolerance for failed host checks;
@@ -192,6 +192,17 @@ the check will be retried for
 more times before setting the host state to down.
 If this table is used by a relay, it will also specify the number of
 retries for outgoing connection attempts.
+.It Ic parent Ar number
+The optional parent option allows to inherit the state from a parent
+host with the specified identifier.
+The check will be skipped for this host and copied from the parent host.
+This can be used to prevent multiple checks on hosts with multiple IP
+addresses for the same service.
+The host identifiers are sequentially assigned to the configured hosts
+starting with 1; it can be figured out with the
+.Xr relayctl 8
+.Ic show summary
+commands.
 .El
 .Pp
 For example:
blob - 1979e4285fa11a32c3e5843095a6a2fe9db72669
blob + 763a4f5870900c3c26f186c4b13accb7fcb82369
--- relayd.h
+++ relayd.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: relayd.h,v 1.106 2008/07/09 17:16:51 reyk Exp $	*/
+/*	$OpenBSD: relayd.h,v 1.107 2008/07/19 10:52:32 reyk Exp $	*/
 
 /*
  * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -345,6 +345,7 @@ enum forwardmode {
 
 struct host_config {
 	objid_t			 id;
+	objid_t			 parentid;
 	objid_t			 tableid;
 	int			 retry;
 	char			 name[MAXHOSTNAMELEN];
@@ -353,6 +354,8 @@ struct host_config {
 
 struct host {
 	TAILQ_ENTRY(host)	 entry;
+	TAILQ_ENTRY(host)	 child;
+	TAILQ_HEAD(,host)	 children;
 	struct host_config	 conf;
 	u_int32_t		 flags;
 	char			*tablename;
@@ -766,10 +769,10 @@ void	 show(struct ctl_conn *);
 void	 show_sessions(struct ctl_conn *);
 int	 enable_rdr(struct ctl_conn *, struct ctl_id *);
 int	 enable_table(struct ctl_conn *, struct ctl_id *);
-int	 enable_host(struct ctl_conn *, struct ctl_id *);
+int	 enable_host(struct ctl_conn *, struct ctl_id *, struct host *);
 int	 disable_rdr(struct ctl_conn *, struct ctl_id *);
 int	 disable_table(struct ctl_conn *, struct ctl_id *);
-int	 disable_host(struct ctl_conn *, struct ctl_id *);
+int	 disable_host(struct ctl_conn *, struct ctl_id *, struct host *);
 
 /* pfe_filter.c */
 void	 init_filter(struct relayd *);