Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9442:562af4a76438 HEAD
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 16 Oct 2009 15:19:54 -0400 |
parents | ebb2a91e6df7 |
children | b5e6de777e52 |
files | src/login-common/login-proxy-state.c src/login-common/login-proxy-state.h src/login-common/login-proxy.c |
diffstat | 3 files changed, 27 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/login-proxy-state.c Fri Oct 16 13:16:07 2009 -0400 +++ b/src/login-common/login-proxy-state.c Fri Oct 16 15:19:54 2009 -0400 @@ -10,18 +10,21 @@ 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 @@ 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 @@ 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; }
--- a/src/login-common/login-proxy-state.h Fri Oct 16 13:16:07 2009 -0400 +++ b/src/login-common/login-proxy-state.h Fri Oct 16 15:19:54 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 @@ 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
--- a/src/login-common/login-proxy.c Fri Oct 16 13:16:07 2009 -0400 +++ b/src/login-common/login-proxy.c Fri Oct 16 15:19:54 2009 -0400 @@ -208,7 +208,7 @@ return NULL; } - rec = login_proxy_state_get(proxy_state, &ip); + rec = login_proxy_state_get(proxy_state, &ip, port); if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 && rec->num_waiting_connections != 0) { /* the server is down. fail immediately */