dovecot-2.0-sslstream: imap/pop3 proxy: Track "destination down"...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:55:08 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/b3c3675ba466
changeset: 10088:b3c3675ba466
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Oct 16 15:20:26 2009 -0400
description:
imap/pop3 proxy: Track "destination down" state separately for IP+ports, not just IPs.
In some systems different ports could get redirected to different servers.

diffstat:

3 files changed, 27 insertions(+), 18 deletions(-)
src/login-common/login-proxy-state.c |   36 +++++++++++++++++++---------------
src/login-common/login-proxy-state.h |    7 ++++--
src/login-common/login-proxy.c       |    2 -

diffs (107 lines):

diff -r 9110c752e32e -r b3c3675ba466 src/login-common/login-proxy-state.c
--- a/src/login-common/login-proxy-state.c	Fri Oct 16 13:16:02 2009 -0400
+++ b/src/login-common/login-proxy-state.c	Fri Oct 16 15:20:26 2009 -0400
@@ -10,18 +10,21 @@ struct login_proxy_state {
 	pool_t pool;
 };
 
-static unsigned int ip_addr_hash(const void *p)
+static unsigned int login_proxy_record_hash(const void *p)
 {
-	const struct ip_addr *ip = p;
+	const struct login_proxy_record *rec = p;
 
-	return net_ip_hash(ip);
+	return net_ip_hash(&rec->ip) ^ rec->port;
 }
 
-static int ip_addr_cmp(const void *p1, const void *p2)
+static int login_proxy_record_cmp(const void *p1, const void *p2)
 {
-	const struct ip_addr *ip1 = p1, *ip2 = p2;
+	const struct login_proxy_record *rec1 = p1, *rec2 = p2;
 
-	return net_ip_compare(ip1, ip2) ? 0 : 1;
+	if (!net_ip_compare(&rec1->ip, &rec2->ip))
+		return 1;
+
+	return (int)rec1->port - (int)rec2->port;
 }
 
 struct login_proxy_state *login_proxy_state_init(void)
@@ -31,7 +34,8 @@ struct login_proxy_state *login_proxy_st
 	state = i_new(struct login_proxy_state, 1);
 	state->pool = pool_alloconly_create("login proxy state", 1024);
 	state->hash = hash_table_create(default_pool, state->pool, 0,
-					ip_addr_hash, ip_addr_cmp);
+					login_proxy_record_hash,
+					login_proxy_record_cmp);
 	return state;
 }
 
@@ -47,18 +51,20 @@ void login_proxy_state_deinit(struct log
 
 struct login_proxy_record *
 login_proxy_state_get(struct login_proxy_state *state,
-		      const struct ip_addr *ip)
+		      const struct ip_addr *ip, unsigned int port)
 {
-	struct login_proxy_record *rec;
-	struct ip_addr *new_ip;
+	struct login_proxy_record *rec, key;
 
-	rec = hash_table_lookup(state->hash, ip);
+	memset(&key, 0, sizeof(key));
+	key.ip = *ip;
+	key.port = port;
+
+	rec = hash_table_lookup(state->hash, &key);
 	if (rec == NULL) {
-		new_ip = p_new(state->pool, struct ip_addr, 1);
-		*new_ip = *ip;
-
 		rec = p_new(state->pool, struct login_proxy_record, 1);
-		hash_table_insert(state->hash, new_ip, rec);
+		rec->ip = *ip;
+		rec->port = port;
+		hash_table_insert(state->hash, rec, rec);
 	}
 	return rec;
 }
diff -r 9110c752e32e -r b3c3675ba466 src/login-common/login-proxy-state.h
--- a/src/login-common/login-proxy-state.h	Fri Oct 16 13:16:02 2009 -0400
+++ b/src/login-common/login-proxy-state.h	Fri Oct 16 15:20:26 2009 -0400
@@ -4,9 +4,12 @@
 #include <sys/time.h>
 
 struct login_proxy_record {
+	struct ip_addr ip;
+	unsigned int port;
+	unsigned int num_waiting_connections;
+
 	struct timeval last_failure;
 	struct timeval last_success;
-	unsigned int num_waiting_connections;
 };
 
 struct login_proxy_state *login_proxy_state_init(void);
@@ -14,6 +17,6 @@ void login_proxy_state_deinit(struct log
 
 struct login_proxy_record *
 login_proxy_state_get(struct login_proxy_state *state,
-		      const struct ip_addr *ip);
+		      const struct ip_addr *ip, unsigned int port);
 
 #endif
diff -r 9110c752e32e -r b3c3675ba466 src/login-common/login-proxy.c
--- a/src/login-common/login-proxy.c	Fri Oct 16 13:16:02 2009 -0400
+++ b/src/login-common/login-proxy.c	Fri Oct 16 15:20:26 2009 -0400
@@ -205,7 +205,7 @@ login_proxy_new(struct client *client, c
 		return NULL;
 	}
 
-	rec = login_proxy_state_get(proxy_state, &ip);
+	rec = login_proxy_state_get(proxy_state, &ip, set->port);
 	if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 &&
 	    rec->num_waiting_connections != 0) {
 		/* the server is down. fail immediately */


More information about the dovecot-cvs mailing list