From 76a24630e7b544c896c6e4e752a702dabc0d1f38 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 27 Sep 2015 22:06:20 +0000 Subject: [PATCH] Added 'hash no server' feature --- client.c | 6 +++++- pen.c | 8 ++++++-- server.c | 10 ++++++++-- server.h | 1 + 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/client.c b/client.c index f6772b3..cbdc327 100644 --- a/client.c +++ b/client.c @@ -83,7 +83,11 @@ int store_client(struct sockaddr_storage *cli) clients[i].last = now; clients[i].addr = *cli; clients[i].connects++; -// clients[i].server = NO_SERVER; + + /* don't remember server */ + if(server_alg & ALG_HASH_NO_SERVER) { + clients[i].server = NO_SERVER; + } DEBUG(2, "Client %s has index %d", pen_ntoa(cli), i); diff --git a/pen.c b/pen.c index b9c70e3..7f66433 100644 --- a/pen.c +++ b/pen.c @@ -848,6 +848,7 @@ static void usage(void) " -T sec tracking time in seconds (0 = forever) [%d]\n" " -H add X-Forwarded-For header in http requests\n" " -U use udp protocol support\n" + " -N use hash for initial server selection without save server\n" " -O option use option in penctl format\n" " -P use poll() rather than select()\n" " -Q use kqueue to manage events (BSD)\n" @@ -2239,9 +2240,9 @@ static int options(int argc, char **argv) char b[1024]; #ifdef HAVE_LIBSSL - char *opt = "B:C:F:O:S:T:b:c:e:i:j:l:m:o:p:q:t:u:w:x:DHPQWXUadfhnrsE:K:G:A:ZRL:"; + char *opt = "B:C:F:O:S:T:b:c:e:i:j:l:m:o:p:q:t:u:w:x:DHNPQWXUadfhnrsE:K:G:A:ZRL:"; #else - char *opt = "B:C:F:O:S:T:b:c:e:i:j:l:m:o:p:q:t:u:w:x:DHPQWXUadfhnrs"; + char *opt = "B:C:F:O:S:T:b:c:e:i:j:l:m:o:p:q:t:u:w:x:DHNPQWXUadfhnrs"; #endif while ((c = getopt(argc, argv, opt)) != -1) { @@ -2414,6 +2415,9 @@ static int options(int argc, char **argv) } break; #endif /* HAVE_LIBSSL */ + case 'N': + server_alg |= ALG_HASH_NO_SERVER; + break; case '?': default: usage(); diff --git a/server.c b/server.c index 8876950..b9c016a 100644 --- a/server.c +++ b/server.c @@ -46,11 +46,17 @@ static int pen_hash(struct sockaddr_storage *a) struct sockaddr_in *si; struct sockaddr_in6 *si6; unsigned char *u; + int hash; switch (a->ss_family) { case AF_INET: si = (struct sockaddr_in *)a; - return si->sin_addr.s_addr % nservers; + hash = (si->sin_addr.s_addr ^ si->sin_port) % nservers; + + DEBUG(2, "Hash: %d", hash); + + return hash; + case AF_INET6: si6 = (struct sockaddr_in6 *)a; u = (unsigned char *)(&si6->sin6_addr); @@ -200,7 +206,7 @@ int initial_server(int conn) } if (server_alg & ALG_PRIO) return server_by_prio(); if (server_alg & ALG_WEIGHT) return server_by_weight(); - if (server_alg & ALG_HASH) return pen_hash(&clients[conns[conn].client].addr); + if (server_alg & ALG_HASH || server_alg & ALG_HASH_NO_SERVER) return pen_hash(&clients[conns[conn].client].addr); return server_by_roundrobin(); } diff --git a/server.h b/server.h index b89d0aa..53a67d8 100644 --- a/server.h +++ b/server.h @@ -11,6 +11,7 @@ #define ALG_PRIO 8 #define ALG_HASH 16 #define ALG_STUBBORN 32 +#define ALG_HASH_NO_SERVER 64 #define EMERGENCY_SERVER (-1) #define ABUSE_SERVER (-2)