-/* $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>
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)
-/* $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>
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 {
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 {
-/* $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>
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:
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",
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
-/* $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>
%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
| INTERFACE STRING { $$ = $2; }
;
-host : STRING retry {
+host : STRING retry parent {
struct address *a;
struct addresslist al;
free($1);
$$->conf.id = 0; /* will be set later */
$$->conf.retry = $2;
+ $$->conf.parentid = $3;
+ TAILQ_INIT(&$$->children);
}
;
}
;
+parent : /* nothing */ { $$ = 0; }
+ | PARENT NUMBER {
+ if (($$ = $2) < 0) {
+ yyerror("invalid parent value: %d\n", $2);
+ YYERROR;
+ }
+ }
+ ;
+
timeout : NUMBER
{
if ($1 < 0) {
{ "nodelay", NODELAY },
{ "nothing", NOTHING },
{ "on", ON },
+ { "parent", PARENT },
{ "path", PATH },
{ "port", PORT },
{ "prefork", PREFORK },
{
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 ||
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++;
}
h->conf.tableid = tb->conf.id;
h->tablename = tb->conf.name;
+ TAILQ_INIT(&h->children);
TAILQ_INSERT_TAIL(&tb->hosts, h, entry);
}
-/* $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>
}
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)
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))
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);
}
-.\" $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>
.\" 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
.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;
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:
-/* $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>
struct host_config {
objid_t id;
+ objid_t parentid;
objid_t tableid;
int retry;
char name[MAXHOSTNAMELEN];
struct host {
TAILQ_ENTRY(host) entry;
+ TAILQ_ENTRY(host) child;
+ TAILQ_HEAD(,host) children;
struct host_config conf;
u_int32_t flags;
char *tablename;
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 *);