diff options
author | Sebastian Benoit <benno@cvs.openbsd.org> | 2015-12-02 22:12:30 +0000 |
---|---|---|
committer | Sebastian Benoit <benno@cvs.openbsd.org> | 2015-12-02 22:12:30 +0000 |
commit | 7ee4a93a62c620e1b692cf6c06f901330a29d865 (patch) | |
tree | bb7b7bdca8bda608a6d190d0233ad47c656e1f5b | |
parent | 47ed23eaa28387cae449f86d52d3c5d7e7a28ab0 (diff) |
relayd (when running relays) can distribute client sessions over hosts
with a hash generated from different data and calculate modulo
rlt->rlt_nhosts to find the host the session should go to. If this
host is down, the current algorithm simply selects the next host that
is up, obviously not ideal, because this puts heavier load on this
next host.
this changes the algorithm: if the chosen host is not available, the
hash value is recalculated and and retried until a host that is usable
is found or a maximum of retires is reached (in that case the old
method is used).
ok and nice input on my original idea bluhm@
-rw-r--r-- | usr.sbin/relayd/relay.c | 33 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 3 |
2 files changed, 29 insertions, 7 deletions
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index a6ffe040ba5..961c175cccc 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.200 2015/12/02 13:41:27 reyk Exp $ */ +/* $OpenBSD: relay.c,v 1.201 2015/12/02 22:12:29 benno Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -1215,6 +1215,8 @@ relay_from_table(struct rsession *con) struct relay_table *rlt = NULL; struct table *table = NULL; int idx = -1; + int cnt = 0; + int maxtries; u_int64_t p = 0; /* the table is already selected */ @@ -1270,18 +1272,37 @@ relay_from_table(struct rsession *con) /* NOTREACHED */ } if (idx == -1) { + /* handle all hashing algorithms */ p = SipHash24_End(&con->se_siphashctx); /* Reset hash context */ SipHash24_Init(&con->se_siphashctx, &rlay->rl_conf.hashkey.siphashkey); - if ((idx = p % rlt->rlt_nhosts) >= RELAY_MAXHOSTS) - return (-1); + maxtries = (rlt->rlt_nhosts < RELAY_MAX_HASH_RETRIES ? + rlt->rlt_nhosts : RELAY_MAX_HASH_RETRIES); + for (cnt = 0; cnt < maxtries; cnt++) { + if ((idx = p % rlt->rlt_nhosts) >= RELAY_MAXHOSTS) + return (-1); + + host = rlt->rlt_host[idx]; + + DPRINTF("%s: session %d: table %s host %s, " + "p 0x%016llx, idx %d, cnt %d, max %d", + __func__, con->se_id, table->conf.name, + host->conf.name, p, idx, cnt, maxtries); + + if (!table->conf.check || host->up == HOST_UP) + goto found; + p = p >> 1; + } + } else { + /* handle all non-hashing algorithms */ + host = rlt->rlt_host[idx]; + DPRINTF("%s: session %d: table %s host %s, p 0x%016llx, idx %d", + __func__, con->se_id, table->conf.name, host->conf.name, p, idx); } - host = rlt->rlt_host[idx]; - DPRINTF("%s: session %d: table %s host %s, p 0x%016llx, idx %d", - __func__, con->se_id, table->conf.name, host->conf.name, p, idx); + while (host != NULL) { DPRINTF("%s: session %d: host %s", __func__, con->se_id, host->conf.name); diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index 6ff019ecd30..81d90641bc2 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.220 2015/12/02 13:41:27 reyk Exp $ */ +/* $OpenBSD: relayd.h,v 1.221 2015/12/02 22:12:29 benno Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -76,6 +76,7 @@ #define RELAY_BACKLOG 10 #define RELAY_MAXLOOKUPLEVELS 5 #define RELAY_OUTOF_FD_RETRIES 5 +#define RELAY_MAX_HASH_RETRIES 5 #define CONFIG_RELOAD 0x00 #define CONFIG_TABLES 0x01 |