mirror of
https://github.com/openbsd/src.git
synced 2025-01-10 06:47:55 -08:00
Support more than one relay backup table. Instead of duplicating the
code for main and backup table all over the place, turn the relay tables into a list attached to the relay. This improves the code and allows some other tricks with multiple tables later.
This commit is contained in:
parent
53cb321c40
commit
416fa9c047
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: config.c,v 1.3 2012/05/08 15:10:15 benno Exp $ */
|
/* $OpenBSD: config.c,v 1.4 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2011 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -793,6 +793,8 @@ int
|
|||||||
config_setrelay(struct relayd *env, struct relay *rlay)
|
config_setrelay(struct relayd *env, struct relay *rlay)
|
||||||
{
|
{
|
||||||
struct privsep *ps = env->sc_ps;
|
struct privsep *ps = env->sc_ps;
|
||||||
|
struct ctl_relaytable crt;
|
||||||
|
struct relay_table *rlt;
|
||||||
int id;
|
int id;
|
||||||
int fd, n, m;
|
int fd, n, m;
|
||||||
struct iovec iov[4];
|
struct iovec iov[4];
|
||||||
@ -840,6 +842,20 @@ config_setrelay(struct relayd *env, struct relay *rlay)
|
|||||||
proc_composev_imsg(ps, id, -1, IMSG_CFG_RELAY, -1,
|
proc_composev_imsg(ps, id, -1, IMSG_CFG_RELAY, -1,
|
||||||
iov, c);
|
iov, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now send the tables associated to this relay */
|
||||||
|
TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
|
||||||
|
crt.id = rlt->rlt_table->conf.id;
|
||||||
|
crt.relayid = rlay->rl_conf.id;
|
||||||
|
crt.mode = rlt->rlt_mode;
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
iov[c].iov_base = &crt;
|
||||||
|
iov[c++].iov_len = sizeof(crt);
|
||||||
|
|
||||||
|
proc_composev_imsg(ps, id, -1,
|
||||||
|
IMSG_CFG_RELAY_TABLE, -1, iov, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(rlay->rl_s);
|
close(rlay->rl_s);
|
||||||
@ -875,21 +891,6 @@ config_getrelay(struct relayd *env, struct imsg *imsg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rlay->rl_conf.dsttable != EMPTY_ID &&
|
|
||||||
(rlay->rl_dsttable = table_find(env,
|
|
||||||
rlay->rl_conf.dsttable)) == NULL) {
|
|
||||||
log_debug("%s: unknown table", __func__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
rlay->rl_backuptable = &env->sc_empty_table;
|
|
||||||
if (rlay->rl_conf.backuptable != EMPTY_ID &&
|
|
||||||
(rlay->rl_backuptable = table_find(env,
|
|
||||||
rlay->rl_conf.backuptable)) == NULL) {
|
|
||||||
log_debug("%s: unknown backup table", __func__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((u_int)(IMSG_DATA_SIZE(imsg) - s) <
|
if ((u_int)(IMSG_DATA_SIZE(imsg) - s) <
|
||||||
(rlay->rl_conf.ssl_cert_len +
|
(rlay->rl_conf.ssl_cert_len +
|
||||||
rlay->rl_conf.ssl_key_len +
|
rlay->rl_conf.ssl_key_len +
|
||||||
@ -917,6 +918,7 @@ config_getrelay(struct relayd *env, struct imsg *imsg)
|
|||||||
s += rlay->rl_conf.ssl_ca_len;
|
s += rlay->rl_conf.ssl_ca_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAILQ_INIT(&rlay->rl_tables);
|
||||||
TAILQ_INSERT_TAIL(env->sc_relays, rlay, rl_entry);
|
TAILQ_INSERT_TAIL(env->sc_relays, rlay, rl_entry);
|
||||||
|
|
||||||
env->sc_relaycount++;
|
env->sc_relaycount++;
|
||||||
@ -938,3 +940,47 @@ config_getrelay(struct relayd *env, struct imsg *imsg)
|
|||||||
free(rlay);
|
free(rlay);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
config_getrelaytable(struct relayd *env, struct imsg *imsg)
|
||||||
|
{
|
||||||
|
struct relay_table *rlt = NULL;
|
||||||
|
struct ctl_relaytable crt;
|
||||||
|
struct relay *rlay;
|
||||||
|
struct table *table;
|
||||||
|
u_int8_t *p = imsg->data;
|
||||||
|
size_t s;
|
||||||
|
|
||||||
|
IMSG_SIZE_CHECK(imsg, &crt);
|
||||||
|
memcpy(&crt, p, sizeof(crt));
|
||||||
|
s = sizeof(crt);
|
||||||
|
|
||||||
|
if ((rlay = relay_find(env, crt.relayid)) == NULL) {
|
||||||
|
log_debug("%s: unknown relay", __func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((table = table_find(env, crt.id)) == NULL) {
|
||||||
|
log_debug("%s: unknown table", __func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rlt = calloc(1, sizeof(*rlt))) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
rlt->rlt_table = table;
|
||||||
|
rlt->rlt_mode = crt.mode;
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry);
|
||||||
|
|
||||||
|
DPRINTF("%s: %s %d received relay table %s for relay %s", __func__,
|
||||||
|
env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance,
|
||||||
|
table->conf.name, rlay->rl_conf.name);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (rlt != NULL)
|
||||||
|
free(rlt);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: parse.y,v 1.164 2012/05/29 23:46:50 benno Exp $ */
|
/* $OpenBSD: parse.y,v 1.165 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2011 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2007-2011 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -108,6 +108,7 @@ static struct router *router = NULL;
|
|||||||
static u_int16_t label = 0;
|
static u_int16_t label = 0;
|
||||||
static in_port_t tableport = 0;
|
static in_port_t tableport = 0;
|
||||||
static int nodedirection;
|
static int nodedirection;
|
||||||
|
static int dstmode;
|
||||||
|
|
||||||
struct address *host_v4(const char *);
|
struct address *host_v4(const char *);
|
||||||
struct address *host_v6(const char *);
|
struct address *host_v6(const char *);
|
||||||
@ -576,6 +577,7 @@ tabledef : TABLE table {
|
|||||||
sizeof(struct timeval));
|
sizeof(struct timeval));
|
||||||
TAILQ_INIT(&tb->hosts);
|
TAILQ_INIT(&tb->hosts);
|
||||||
table = tb;
|
table = tb;
|
||||||
|
dstmode = RELAY_DSTMODE_DEFAULT;
|
||||||
} tabledefopts_l {
|
} tabledefopts_l {
|
||||||
if (TAILQ_EMPTY(&table->hosts)) {
|
if (TAILQ_EMPTY(&table->hosts)) {
|
||||||
yyerror("table %s has no hosts",
|
yyerror("table %s has no hosts",
|
||||||
@ -679,8 +681,7 @@ tableopts : CHECK tablecheck
|
|||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case RELAY_DSTMODE_ROUNDROBIN:
|
case RELAY_DSTMODE_ROUNDROBIN:
|
||||||
if (rlay != NULL)
|
dstmode = $2;
|
||||||
rlay->rl_conf.dstmode = $2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1223,14 +1224,14 @@ relay : RELAY STRING {
|
|||||||
r->rl_conf.timeout.tv_sec = RELAY_TIMEOUT;
|
r->rl_conf.timeout.tv_sec = RELAY_TIMEOUT;
|
||||||
r->rl_proto = NULL;
|
r->rl_proto = NULL;
|
||||||
r->rl_conf.proto = EMPTY_ID;
|
r->rl_conf.proto = EMPTY_ID;
|
||||||
r->rl_conf.dsttable = EMPTY_ID;
|
|
||||||
r->rl_conf.dstmode = RELAY_DSTMODE_DEFAULT;
|
|
||||||
r->rl_conf.dstretry = 0;
|
r->rl_conf.dstretry = 0;
|
||||||
|
TAILQ_INIT(&r->rl_tables);
|
||||||
if (last_relay_id == INT_MAX) {
|
if (last_relay_id == INT_MAX) {
|
||||||
yyerror("too many relays defined");
|
yyerror("too many relays defined");
|
||||||
free(r);
|
free(r);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
|
dstmode = RELAY_DSTMODE_DEFAULT;
|
||||||
rlay = r;
|
rlay = r;
|
||||||
} '{' optnl relayopts_l '}' {
|
} '{' optnl relayopts_l '}' {
|
||||||
struct relay *r;
|
struct relay *r;
|
||||||
@ -1248,16 +1249,11 @@ relay : RELAY STRING {
|
|||||||
}
|
}
|
||||||
if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) == 0 &&
|
if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) == 0 &&
|
||||||
rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
|
rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
|
||||||
rlay->rl_conf.dsttable == EMPTY_ID) {
|
TAILQ_EMPTY(&rlay->rl_tables)) {
|
||||||
yyerror("relay %s has no target, rdr, "
|
yyerror("relay %s has no target, rdr, "
|
||||||
"or table", rlay->rl_conf.name);
|
"or table", rlay->rl_conf.name);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
if (rlay->rl_backuptable == NULL) {
|
|
||||||
rlay->rl_conf.backuptable =
|
|
||||||
conf->sc_empty_table.conf.id;
|
|
||||||
rlay->rl_backuptable = &conf->sc_empty_table;
|
|
||||||
}
|
|
||||||
if (rlay->rl_conf.proto == EMPTY_ID) {
|
if (rlay->rl_conf.proto == EMPTY_ID) {
|
||||||
rlay->rl_proto = &conf->sc_proto_default;
|
rlay->rl_proto = &conf->sc_proto_default;
|
||||||
rlay->rl_conf.proto = conf->sc_proto_default.id;
|
rlay->rl_conf.proto = conf->sc_proto_default.id;
|
||||||
@ -1415,20 +1411,21 @@ forwardspec : STRING port retry {
|
|||||||
rlay->rl_conf.dstretry = $2;
|
rlay->rl_conf.dstretry = $2;
|
||||||
}
|
}
|
||||||
| tablespec {
|
| tablespec {
|
||||||
if (rlay->rl_backuptable) {
|
struct relay_table *rlt;
|
||||||
yyerror("only one backup table is allowed");
|
|
||||||
|
if ((rlt = calloc(1, sizeof(*rlt))) == NULL) {
|
||||||
|
yyerror("failed to allocate table reference");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
if (rlay->rl_dsttable) {
|
|
||||||
rlay->rl_backuptable = $1;
|
rlt->rlt_table = $1;
|
||||||
rlay->rl_backuptable->conf.flags |= F_USED;
|
rlt->rlt_table->conf.flags |= F_USED;
|
||||||
rlay->rl_conf.backuptable = $1->conf.id;
|
rlt->rlt_mode = dstmode;
|
||||||
} else {
|
rlt->rlt_flags = F_USED;
|
||||||
rlay->rl_dsttable = $1;
|
if (!TAILQ_EMPTY(&rlay->rl_tables))
|
||||||
rlay->rl_dsttable->conf.flags |= F_USED;
|
rlt->rlt_flags |= F_BACKUP;
|
||||||
rlay->rl_conf.dsttable = $1->conf.id;
|
|
||||||
rlay->rl_conf.dstport = $1->conf.port;
|
TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2214,6 +2211,7 @@ load_config(const char *filename, struct relayd *x_conf)
|
|||||||
struct sym *sym, *next;
|
struct sym *sym, *next;
|
||||||
struct table *nexttb;
|
struct table *nexttb;
|
||||||
struct host *h, *ph;
|
struct host *h, *ph;
|
||||||
|
struct relay_table *rlt;
|
||||||
|
|
||||||
conf = x_conf;
|
conf = x_conf;
|
||||||
conf->sc_flags = 0;
|
conf->sc_flags = 0;
|
||||||
@ -2266,6 +2264,10 @@ load_config(const char *filename, struct relayd *x_conf)
|
|||||||
/* Cleanup relay list to inherit */
|
/* Cleanup relay list to inherit */
|
||||||
while ((rlay = TAILQ_FIRST(&relays)) != NULL) {
|
while ((rlay = TAILQ_FIRST(&relays)) != NULL) {
|
||||||
TAILQ_REMOVE(&relays, rlay, rl_entry);
|
TAILQ_REMOVE(&relays, rlay, rl_entry);
|
||||||
|
while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
|
||||||
|
TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
|
||||||
|
free(rlt);
|
||||||
|
}
|
||||||
free(rlay);
|
free(rlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2717,6 +2719,7 @@ struct relay *
|
|||||||
relay_inherit(struct relay *ra, struct relay *rb)
|
relay_inherit(struct relay *ra, struct relay *rb)
|
||||||
{
|
{
|
||||||
struct relay_config rc;
|
struct relay_config rc;
|
||||||
|
struct relay_table *rta, *rtb;
|
||||||
|
|
||||||
bcopy(&rb->rl_conf, &rc, sizeof(rc));
|
bcopy(&rb->rl_conf, &rc, sizeof(rc));
|
||||||
bcopy(ra, rb, sizeof(*rb));
|
bcopy(ra, rb, sizeof(*rb));
|
||||||
@ -2725,6 +2728,7 @@ relay_inherit(struct relay *ra, struct relay *rb)
|
|||||||
rb->rl_conf.port = rc.port;
|
rb->rl_conf.port = rc.port;
|
||||||
rb->rl_conf.flags =
|
rb->rl_conf.flags =
|
||||||
(ra->rl_conf.flags & ~F_SSL) | (rc.flags & F_SSL);
|
(ra->rl_conf.flags & ~F_SSL) | (rc.flags & F_SSL);
|
||||||
|
TAILQ_INIT(&rb->rl_tables);
|
||||||
|
|
||||||
rb->rl_conf.id = ++last_relay_id;
|
rb->rl_conf.id = ++last_relay_id;
|
||||||
if (last_relay_id == INT_MAX) {
|
if (last_relay_id == INT_MAX) {
|
||||||
@ -2750,6 +2754,17 @@ relay_inherit(struct relay *ra, struct relay *rb)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAILQ_FOREACH(rta, &ra->rl_tables, rlt_entry) {
|
||||||
|
if ((rtb = calloc(1, sizeof(*rtb))) == NULL) {
|
||||||
|
yyerror("cannot allocate relay table");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
rtb->rlt_table = rta->rlt_table;
|
||||||
|
rtb->rlt_mode = rta->rlt_mode;
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&rb->rl_tables, rtb, rlt_entry);
|
||||||
|
}
|
||||||
|
|
||||||
conf->sc_relaycount++;
|
conf->sc_relaycount++;
|
||||||
SPLAY_INIT(&rlay->rl_sessions);
|
SPLAY_INIT(&rlay->rl_sessions);
|
||||||
TAILQ_INSERT_TAIL(conf->sc_relays, rb, rl_entry);
|
TAILQ_INSERT_TAIL(conf->sc_relays, rb, rl_entry);
|
||||||
@ -2757,6 +2772,10 @@ relay_inherit(struct relay *ra, struct relay *rb)
|
|||||||
return (rb);
|
return (rb);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
while ((rtb = TAILQ_FIRST(&rb->rl_tables))) {
|
||||||
|
TAILQ_REMOVE(&rb->rl_tables, rtb, rlt_entry);
|
||||||
|
free(rtb);
|
||||||
|
}
|
||||||
free(rb);
|
free(rb);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: pfe.c,v 1.72 2012/01/21 13:40:48 camield Exp $ */
|
/* $OpenBSD: pfe.c,v 1.73 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
|
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
|
||||||
@ -199,6 +199,9 @@ pfe_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
|
|||||||
case IMSG_CFG_RELAY:
|
case IMSG_CFG_RELAY:
|
||||||
config_getrelay(env, imsg);
|
config_getrelay(env, imsg);
|
||||||
break;
|
break;
|
||||||
|
case IMSG_CFG_RELAY_TABLE:
|
||||||
|
config_getrelaytable(env, imsg);
|
||||||
|
break;
|
||||||
case IMSG_CFG_DONE:
|
case IMSG_CFG_DONE:
|
||||||
config_getcfg(env, imsg);
|
config_getcfg(env, imsg);
|
||||||
init_filter(env, imsg->fd);
|
init_filter(env, imsg->fd);
|
||||||
@ -296,6 +299,7 @@ show(struct ctl_conn *c)
|
|||||||
struct relay *rlay;
|
struct relay *rlay;
|
||||||
struct router *rt;
|
struct router *rt;
|
||||||
struct netroute *nr;
|
struct netroute *nr;
|
||||||
|
struct relay_table *rlt;
|
||||||
|
|
||||||
if (env->sc_rdrs == NULL)
|
if (env->sc_rdrs == NULL)
|
||||||
goto relays;
|
goto relays;
|
||||||
@ -334,23 +338,16 @@ relays:
|
|||||||
imsg_compose_event(&c->iev, IMSG_CTL_RELAY_STATS, 0, 0, -1,
|
imsg_compose_event(&c->iev, IMSG_CTL_RELAY_STATS, 0, 0, -1,
|
||||||
&rlay->rl_stats, sizeof(rlay->rl_stats));
|
&rlay->rl_stats, sizeof(rlay->rl_stats));
|
||||||
|
|
||||||
if (rlay->rl_dsttable == NULL)
|
TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
|
||||||
continue;
|
|
||||||
imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
|
imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
|
||||||
rlay->rl_dsttable, sizeof(*rlay->rl_dsttable));
|
rlt->rlt_table, sizeof(*rlt->rlt_table));
|
||||||
if (!(rlay->rl_dsttable->conf.flags & F_DISABLE))
|
if (!(rlt->rlt_table->conf.flags & F_DISABLE))
|
||||||
TAILQ_FOREACH(host, &rlay->rl_dsttable->hosts, entry)
|
TAILQ_FOREACH(host,
|
||||||
imsg_compose_event(&c->iev, IMSG_CTL_HOST,
|
&rlt->rlt_table->hosts, entry)
|
||||||
0, 0, -1, host, sizeof(*host));
|
imsg_compose_event(&c->iev,
|
||||||
|
IMSG_CTL_HOST, 0, 0, -1,
|
||||||
if (rlay->rl_conf.backuptable == EMPTY_TABLE)
|
host, sizeof(*host));
|
||||||
continue;
|
}
|
||||||
imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
|
|
||||||
rlay->rl_backuptable, sizeof(*rlay->rl_backuptable));
|
|
||||||
if (!(rlay->rl_backuptable->conf.flags & F_DISABLE))
|
|
||||||
TAILQ_FOREACH(host, &rlay->rl_backuptable->hosts, entry)
|
|
||||||
imsg_compose_event(&c->iev, IMSG_CTL_HOST,
|
|
||||||
0, 0, -1, host, sizeof(*host));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
routers:
|
routers:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: relay.c,v 1.153 2012/09/21 09:56:27 benno Exp $ */
|
/* $OpenBSD: relay.c,v 1.154 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 - 2012 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2006 - 2012 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -377,37 +377,38 @@ relay_launch(void)
|
|||||||
void (*callback)(int, short, void *);
|
void (*callback)(int, short, void *);
|
||||||
struct relay *rlay;
|
struct relay *rlay;
|
||||||
struct host *host;
|
struct host *host;
|
||||||
|
struct relay_table *rlt;
|
||||||
|
|
||||||
TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
|
TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
|
||||||
if ((rlay->rl_conf.flags & (F_SSL|F_SSLCLIENT)) &&
|
if ((rlay->rl_conf.flags & (F_SSL|F_SSLCLIENT)) &&
|
||||||
(rlay->rl_ssl_ctx = relay_ssl_ctx_create(rlay)) == NULL)
|
(rlay->rl_ssl_ctx = relay_ssl_ctx_create(rlay)) == NULL)
|
||||||
fatal("relay_init: failed to create SSL context");
|
fatal("relay_init: failed to create SSL context");
|
||||||
|
|
||||||
if (rlay->rl_dsttable != NULL) {
|
TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
|
||||||
switch (rlay->rl_conf.dstmode) {
|
switch (rlt->rlt_mode) {
|
||||||
case RELAY_DSTMODE_ROUNDROBIN:
|
case RELAY_DSTMODE_ROUNDROBIN:
|
||||||
rlay->rl_dstkey = 0;
|
rlt->rlt_key = 0;
|
||||||
break;
|
break;
|
||||||
case RELAY_DSTMODE_LOADBALANCE:
|
case RELAY_DSTMODE_LOADBALANCE:
|
||||||
case RELAY_DSTMODE_HASH:
|
case RELAY_DSTMODE_HASH:
|
||||||
rlay->rl_dstkey =
|
rlt->rlt_key =
|
||||||
hash32_str(rlay->rl_conf.name, HASHINIT);
|
hash32_str(rlay->rl_conf.name, HASHINIT);
|
||||||
rlay->rl_dstkey =
|
rlt->rlt_key =
|
||||||
hash32_str(rlay->rl_dsttable->conf.name,
|
hash32_str(rlt->rlt_table->conf.name,
|
||||||
rlay->rl_dstkey);
|
rlt->rlt_key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rlay->rl_dstnhosts = 0;
|
rlt->rlt_nhosts = 0;
|
||||||
TAILQ_FOREACH(host, &rlay->rl_dsttable->hosts, entry) {
|
TAILQ_FOREACH(host, &rlt->rlt_table->hosts, entry) {
|
||||||
if (rlay->rl_dstnhosts >= RELAY_MAXHOSTS)
|
if (rlt->rlt_nhosts >= RELAY_MAXHOSTS)
|
||||||
fatal("relay_init: "
|
fatal("relay_init: "
|
||||||
"too many hosts in table");
|
"too many hosts in table");
|
||||||
host->idx = rlay->rl_dstnhosts;
|
host->idx = rlt->rlt_nhosts;
|
||||||
rlay->rl_dsthost[rlay->rl_dstnhosts++] = host;
|
rlt->rlt_host[rlt->rlt_nhosts++] = host;
|
||||||
}
|
}
|
||||||
log_info("adding %d hosts from table %s%s",
|
log_info("adding %d hosts from table %s%s",
|
||||||
rlay->rl_dstnhosts, rlay->rl_dsttable->conf.name,
|
rlt->rlt_nhosts, rlt->rlt_table->conf.name,
|
||||||
rlay->rl_dsttable->conf.check ? "" : " (no check)");
|
rlt->rlt_table->conf.check ? "" : " (no check)");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (rlay->rl_proto->type) {
|
switch (rlay->rl_proto->type) {
|
||||||
@ -976,7 +977,6 @@ relay_accept(int fd, short event, void *arg)
|
|||||||
con->se_id = ++relay_conid;
|
con->se_id = ++relay_conid;
|
||||||
con->se_relayid = rlay->rl_conf.id;
|
con->se_relayid = rlay->rl_conf.id;
|
||||||
con->se_pid = getpid();
|
con->se_pid = getpid();
|
||||||
con->se_hashkey = rlay->rl_dstkey;
|
|
||||||
con->se_in.tree = &proto->request_tree;
|
con->se_in.tree = &proto->request_tree;
|
||||||
con->se_out.tree = &proto->response_tree;
|
con->se_out.tree = &proto->response_tree;
|
||||||
con->se_in.dir = RELAY_DIR_REQUEST;
|
con->se_in.dir = RELAY_DIR_REQUEST;
|
||||||
@ -1104,22 +1104,46 @@ relay_from_table(struct rsession *con)
|
|||||||
{
|
{
|
||||||
struct relay *rlay = (struct relay *)con->se_relay;
|
struct relay *rlay = (struct relay *)con->se_relay;
|
||||||
struct host *host;
|
struct host *host;
|
||||||
struct table *table = rlay->rl_dsttable;
|
struct relay_table *rlt = NULL;
|
||||||
|
struct table *table = NULL;
|
||||||
u_int32_t p = con->se_hashkey;
|
u_int32_t p = con->se_hashkey;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
if (table->conf.check && !table->up && !rlay->rl_backuptable->up) {
|
/* the table is already selected */
|
||||||
log_debug("%s: no active hosts", __func__);
|
if (con->se_table != NULL) {
|
||||||
return (-1);
|
rlt = con->se_table;
|
||||||
} else if (!table->up && rlay->rl_backuptable->up) {
|
table = rlt->rlt_table;
|
||||||
table = rlay->rl_backuptable;
|
if (table->conf.check && !table->up)
|
||||||
|
table = NULL;
|
||||||
|
goto gottable;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (rlay->rl_conf.dstmode) {
|
/* otherwise grep the first active table */
|
||||||
|
TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) {
|
||||||
|
table = rlt->rlt_table;
|
||||||
|
if ((rlt->rlt_flags & F_USED == 0) ||
|
||||||
|
(table->conf.check && !table->up))
|
||||||
|
table = NULL;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gottable:
|
||||||
|
if (table == NULL) {
|
||||||
|
log_debug("%s: session %d: no active hosts",
|
||||||
|
__func__, con->se_id);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (!con->se_hashkeyset) {
|
||||||
|
p = con->se_hashkey = rlt->rlt_key;
|
||||||
|
con->se_hashkeyset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rlt->rlt_mode) {
|
||||||
case RELAY_DSTMODE_ROUNDROBIN:
|
case RELAY_DSTMODE_ROUNDROBIN:
|
||||||
if ((int)rlay->rl_dstkey >= rlay->rl_dstnhosts)
|
if ((int)rlt->rlt_key >= rlt->rlt_nhosts)
|
||||||
rlay->rl_dstkey = 0;
|
rlt->rlt_key = 0;
|
||||||
idx = (int)rlay->rl_dstkey;
|
idx = (int)rlt->rlt_key;
|
||||||
break;
|
break;
|
||||||
case RELAY_DSTMODE_LOADBALANCE:
|
case RELAY_DSTMODE_LOADBALANCE:
|
||||||
p = relay_hash_addr(&con->se_in.ss, p);
|
p = relay_hash_addr(&con->se_in.ss, p);
|
||||||
@ -1128,14 +1152,15 @@ relay_from_table(struct rsession *con)
|
|||||||
p = relay_hash_addr(&rlay->rl_conf.ss, p);
|
p = relay_hash_addr(&rlay->rl_conf.ss, p);
|
||||||
p = hash32_buf(&rlay->rl_conf.port,
|
p = hash32_buf(&rlay->rl_conf.port,
|
||||||
sizeof(rlay->rl_conf.port), p);
|
sizeof(rlay->rl_conf.port), p);
|
||||||
if ((idx = p % rlay->rl_dstnhosts) >= RELAY_MAXHOSTS)
|
if ((idx = p % rlt->rlt_nhosts) >= RELAY_MAXHOSTS)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
host = rlay->rl_dsthost[idx];
|
host = rlt->rlt_host[idx];
|
||||||
DPRINTF("%s: host %s, p 0x%08x, idx %d", __func__,
|
DPRINTF("%s: session %d: table %s host %s, p 0x%08x, idx %d",
|
||||||
host->conf.name, p, idx);
|
__func__, con->se_id, table->conf.name, host->conf.name, p, idx);
|
||||||
while (host != NULL) {
|
while (host != NULL) {
|
||||||
DPRINTF("%s: host %s", __func__, host->conf.name);
|
DPRINTF("%s: session %d: host %s", __func__,
|
||||||
|
con->se_id, host->conf.name);
|
||||||
if (!table->conf.check || host->up == HOST_UP)
|
if (!table->conf.check || host->up == HOST_UP)
|
||||||
goto found;
|
goto found;
|
||||||
host = TAILQ_NEXT(host, entry);
|
host = TAILQ_NEXT(host, entry);
|
||||||
@ -1150,8 +1175,8 @@ relay_from_table(struct rsession *con)
|
|||||||
fatalx("relay_from_table: no active hosts, desynchronized");
|
fatalx("relay_from_table: no active hosts, desynchronized");
|
||||||
|
|
||||||
found:
|
found:
|
||||||
if (rlay->rl_conf.dstmode == RELAY_DSTMODE_ROUNDROBIN)
|
if (rlt->rlt_mode == RELAY_DSTMODE_ROUNDROBIN)
|
||||||
rlay->rl_dstkey = host->idx + 1;
|
rlt->rlt_key = host->idx + 1;
|
||||||
con->se_retry = host->conf.retry;
|
con->se_retry = host->conf.retry;
|
||||||
con->se_out.port = table->conf.port;
|
con->se_out.port = table->conf.port;
|
||||||
bcopy(&host->conf.ss, &con->se_out.ss, sizeof(con->se_out.ss));
|
bcopy(&host->conf.ss, &con->se_out.ss, sizeof(con->se_out.ss));
|
||||||
@ -1171,7 +1196,7 @@ relay_natlook(int fd, short event, void *arg)
|
|||||||
|
|
||||||
if (con->se_out.ss.ss_family == AF_UNSPEC && cnl->in == -1 &&
|
if (con->se_out.ss.ss_family == AF_UNSPEC && cnl->in == -1 &&
|
||||||
rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
|
rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
|
||||||
rlay->rl_dsttable == NULL) {
|
TAILQ_EMPTY(&rlay->rl_tables)) {
|
||||||
relay_close(con, "session NAT lookup failed");
|
relay_close(con, "session NAT lookup failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1355,7 +1380,7 @@ relay_connect(struct rsession *con)
|
|||||||
if (gettimeofday(&con->se_tv_start, NULL) == -1)
|
if (gettimeofday(&con->se_tv_start, NULL) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (rlay->rl_dsttable != NULL) {
|
if (!TAILQ_EMPTY(&rlay->rl_tables)) {
|
||||||
if (relay_from_table(con) != 0)
|
if (relay_from_table(con) != 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
} else if (con->se_out.ss.ss_family == AF_UNSPEC) {
|
} else if (con->se_out.ss.ss_family == AF_UNSPEC) {
|
||||||
@ -1691,6 +1716,9 @@ relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
|
|||||||
case IMSG_CFG_RELAY:
|
case IMSG_CFG_RELAY:
|
||||||
config_getrelay(env, imsg);
|
config_getrelay(env, imsg);
|
||||||
break;
|
break;
|
||||||
|
case IMSG_CFG_RELAY_TABLE:
|
||||||
|
config_getrelaytable(env, imsg);
|
||||||
|
break;
|
||||||
case IMSG_CFG_DONE:
|
case IMSG_CFG_DONE:
|
||||||
config_getcfg(env, imsg);
|
config_getcfg(env, imsg);
|
||||||
break;
|
break;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: relay_udp.c,v 1.24 2011/05/09 12:08:47 reyk Exp $ */
|
/* $OpenBSD: relay_udp.c,v 1.25 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -249,7 +249,6 @@ relay_udp_server(int fd, short sig, void *arg)
|
|||||||
con->se_in.con = con;
|
con->se_in.con = con;
|
||||||
con->se_out.con = con;
|
con->se_out.con = con;
|
||||||
con->se_relay = rlay;
|
con->se_relay = rlay;
|
||||||
con->se_hashkey = rlay->rl_dstkey;
|
|
||||||
con->se_id = ++relay_conid;
|
con->se_id = ++relay_conid;
|
||||||
con->se_in.tree = &proto->request_tree;
|
con->se_in.tree = &proto->request_tree;
|
||||||
con->se_out.tree = &proto->response_tree;
|
con->se_out.tree = &proto->response_tree;
|
||||||
@ -474,7 +473,7 @@ relay_dns_request(struct rsession *con)
|
|||||||
if (gettimeofday(&con->se_tv_start, NULL) == -1)
|
if (gettimeofday(&con->se_tv_start, NULL) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (rlay->rl_dsttable != NULL) {
|
if (!TAILQ_EMPTY(&rlay->rl_tables)) {
|
||||||
if (relay_from_table(con) != 0)
|
if (relay_from_table(con) != 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
} else if (con->se_out.ss.ss_family == AF_UNSPEC) {
|
} else if (con->se_out.ss.ss_family == AF_UNSPEC) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: relayd.c,v 1.109 2012/09/21 09:56:27 benno Exp $ */
|
/* $OpenBSD: relayd.c,v 1.110 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -564,6 +564,7 @@ void
|
|||||||
purge_relay(struct relayd *env, struct relay *rlay)
|
purge_relay(struct relayd *env, struct relay *rlay)
|
||||||
{
|
{
|
||||||
struct rsession *con;
|
struct rsession *con;
|
||||||
|
struct relay_table *rlt;
|
||||||
|
|
||||||
/* shutdown and remove relay */
|
/* shutdown and remove relay */
|
||||||
if (event_initialized(&rlay->rl_ev))
|
if (event_initialized(&rlay->rl_ev))
|
||||||
@ -591,6 +592,11 @@ purge_relay(struct relayd *env, struct relay *rlay)
|
|||||||
if (rlay->rl_ssl_ca != NULL)
|
if (rlay->rl_ssl_ca != NULL)
|
||||||
free(rlay->rl_ssl_ca);
|
free(rlay->rl_ssl_ca);
|
||||||
|
|
||||||
|
while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
|
||||||
|
TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
|
||||||
|
free(rlt);
|
||||||
|
}
|
||||||
|
|
||||||
free(rlay);
|
free(rlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: relayd.conf.5,v 1.129 2012/08/24 20:13:03 jmc Exp $
|
.\" $OpenBSD: relayd.conf.5,v 1.130 2012/10/03 08:33:31 reyk Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
|
.\" Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
|
||||||
.\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@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
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 24 2012 $
|
.Dd $Mdocdate: October 3 2012 $
|
||||||
.Dt RELAYD.CONF 5
|
.Dt RELAYD.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -596,8 +596,9 @@ Like the previous directive, but connect to a host from the specified
|
|||||||
table; see the
|
table; see the
|
||||||
.Sx TABLES
|
.Sx TABLES
|
||||||
section above for information about table options.
|
section above for information about table options.
|
||||||
This directive can be specified twice \(en the second entry will be used
|
This directive can be specified multiple times \(en subsequent entries
|
||||||
as the backup table if all hosts in the main table are down.
|
will be used as the backup table if all hosts in the previous table
|
||||||
|
are down.
|
||||||
At least one entry for the main table is mandatory.
|
At least one entry for the main table is mandatory.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic forward to
|
.Ic forward to
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: relayd.h,v 1.158 2012/09/21 09:56:27 benno Exp $ */
|
/* $OpenBSD: relayd.h,v 1.159 2012/10/03 08:33:31 reyk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 - 2012 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2006 - 2012 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -108,6 +108,12 @@ struct ctl_id {
|
|||||||
char name[MAX_NAME_SIZE];
|
char name[MAX_NAME_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ctl_relaytable {
|
||||||
|
objid_t id;
|
||||||
|
objid_t relayid;
|
||||||
|
int mode;
|
||||||
|
};
|
||||||
|
|
||||||
struct ctl_script {
|
struct ctl_script {
|
||||||
objid_t host;
|
objid_t host;
|
||||||
int retval;
|
int retval;
|
||||||
@ -430,6 +436,8 @@ struct rsession {
|
|||||||
struct ctl_relay_event se_out;
|
struct ctl_relay_event se_out;
|
||||||
void *se_priv;
|
void *se_priv;
|
||||||
u_int32_t se_hashkey;
|
u_int32_t se_hashkey;
|
||||||
|
int se_hashkeyset;
|
||||||
|
struct relay_table *se_table;
|
||||||
struct event se_ev;
|
struct event se_ev;
|
||||||
struct timeval se_timeout;
|
struct timeval se_timeout;
|
||||||
struct timeval se_tv_start;
|
struct timeval se_tv_start;
|
||||||
@ -580,6 +588,17 @@ struct protocol {
|
|||||||
};
|
};
|
||||||
TAILQ_HEAD(protolist, protocol);
|
TAILQ_HEAD(protolist, protocol);
|
||||||
|
|
||||||
|
struct relay_table {
|
||||||
|
struct table *rlt_table;
|
||||||
|
u_int32_t rlt_flags;
|
||||||
|
int rlt_mode;
|
||||||
|
u_int32_t rlt_key;
|
||||||
|
struct host *rlt_host[RELAY_MAXHOSTS];
|
||||||
|
int rlt_nhosts;
|
||||||
|
TAILQ_ENTRY(relay_table) rlt_entry;
|
||||||
|
};
|
||||||
|
TAILQ_HEAD(relaytables, relay_table);
|
||||||
|
|
||||||
struct relay_config {
|
struct relay_config {
|
||||||
objid_t id;
|
objid_t id;
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
@ -588,10 +607,7 @@ struct relay_config {
|
|||||||
char ifname[IFNAMSIZ];
|
char ifname[IFNAMSIZ];
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
in_port_t dstport;
|
in_port_t dstport;
|
||||||
int dstmode;
|
|
||||||
int dstretry;
|
int dstretry;
|
||||||
objid_t dsttable;
|
|
||||||
objid_t backuptable;
|
|
||||||
struct sockaddr_storage ss;
|
struct sockaddr_storage ss;
|
||||||
struct sockaddr_storage dstss;
|
struct sockaddr_storage dstss;
|
||||||
struct sockaddr_storage dstaf;
|
struct sockaddr_storage dstaf;
|
||||||
@ -614,11 +630,7 @@ struct relay {
|
|||||||
int rl_dsts;
|
int rl_dsts;
|
||||||
struct bufferevent *rl_dstbev;
|
struct bufferevent *rl_dstbev;
|
||||||
|
|
||||||
struct table *rl_dsttable;
|
struct relaytables rl_tables;
|
||||||
struct table *rl_backuptable;
|
|
||||||
u_int32_t rl_dstkey;
|
|
||||||
struct host *rl_dsthost[RELAY_MAXHOSTS];
|
|
||||||
int rl_dstnhosts;
|
|
||||||
|
|
||||||
struct event rl_ev;
|
struct event rl_ev;
|
||||||
struct event rl_evt;
|
struct event rl_evt;
|
||||||
@ -789,6 +801,7 @@ enum imsg_type {
|
|||||||
IMSG_CFG_PROTO,
|
IMSG_CFG_PROTO,
|
||||||
IMSG_CFG_PROTONODE,
|
IMSG_CFG_PROTONODE,
|
||||||
IMSG_CFG_RELAY,
|
IMSG_CFG_RELAY,
|
||||||
|
IMSG_CFG_RELAY_TABLE,
|
||||||
IMSG_CFG_DONE
|
IMSG_CFG_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1148,5 +1161,6 @@ int config_setprotonode(struct relayd *, enum privsep_procid,
|
|||||||
int config_getprotonode(struct relayd *, struct imsg *);
|
int config_getprotonode(struct relayd *, struct imsg *);
|
||||||
int config_setrelay(struct relayd *env, struct relay *);
|
int config_setrelay(struct relayd *env, struct relay *);
|
||||||
int config_getrelay(struct relayd *, struct imsg *);
|
int config_getrelay(struct relayd *, struct imsg *);
|
||||||
|
int config_getrelaytable(struct relayd *, struct imsg *);
|
||||||
|
|
||||||
#endif /* _RELAYD_H */
|
#endif /* _RELAYD_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user