Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9313:34179f0f4d6a HEAD
login proxy: Improvements to "fail immediately if server is down" handling.
Now we use more precise timestamps. Also don't mark server as failed if
another connect had succeeded after we started connecting.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 12 Aug 2009 17:55:14 -0400 |
parents | 00a1d109ecf6 |
children | 68c1d3ab515d |
files | src/login-common/login-proxy-state.h src/login-common/login-proxy.c |
diffstat | 2 files changed, 22 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/login-proxy-state.h Wed Aug 12 17:27:25 2009 -0400 +++ b/src/login-common/login-proxy-state.h Wed Aug 12 17:55:14 2009 -0400 @@ -2,8 +2,8 @@ #define LOGIN_PROXY_STATE_H struct login_proxy_record { - time_t last_failure; - time_t last_success; + struct timeval last_failure; + struct timeval last_success; unsigned int num_waiting_connections; };
--- a/src/login-common/login-proxy.c Wed Aug 12 17:27:25 2009 -0400 +++ b/src/login-common/login-proxy.c Wed Aug 12 17:55:14 2009 -0400 @@ -6,6 +6,7 @@ #include "ostream.h" #include "llist.h" #include "str-sanitize.h" +#include "time-util.h" #include "client-common.h" #include "ssl-proxy.h" #include "login-proxy-state.h" @@ -25,6 +26,7 @@ struct ip_addr ip; struct ssl_proxy *ssl_proxy; + struct timeval created; struct timeout *to; struct login_proxy_record *state_rec; @@ -132,6 +134,19 @@ io_add(proxy->server_fd, IO_READ, proxy_prelogin_input, proxy); } +static void proxy_fail_connect(struct login_proxy *proxy) +{ + if (timeval_cmp(&proxy->created, &proxy->state_rec->last_success) < 0) { + /* there was a successful connection done since we started + connecting. perhaps this is just a temporary one-off + failure. */ + } else { + proxy->state_rec->last_failure = ioloop_timeval; + } + proxy->state_rec->num_waiting_connections--; + proxy->state_rec = NULL; +} + static void proxy_wait_connect(struct login_proxy *proxy) { int err; @@ -140,11 +155,11 @@ if (err != 0) { i_error("proxy: connect(%s, %u) failed: %s", proxy->host, proxy->port, strerror(err)); - proxy->state_rec->last_failure = ioloop_time; + proxy_fail_connect(proxy); login_proxy_free(&proxy); return; } - proxy->state_rec->last_success = ioloop_time; + proxy->state_rec->last_success = ioloop_timeval; proxy->state_rec->num_waiting_connections--; proxy->state_rec = NULL; @@ -166,7 +181,7 @@ static void proxy_connect_timeout(struct login_proxy *proxy) { i_error("proxy: connect(%s, %u) timed out", proxy->host, proxy->port); - proxy->state_rec->last_failure = ioloop_time; + proxy_fail_connect(proxy); login_proxy_free(&proxy); } @@ -194,7 +209,7 @@ } rec = login_proxy_state_get(proxy_state, &ip); - if (rec->last_failure > rec->last_success && + if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 && rec->num_waiting_connections != 0) { /* the server is down. fail immediately */ return NULL; @@ -208,6 +223,7 @@ } proxy = i_new(struct login_proxy, 1); + proxy->created = ioloop_timeval; proxy->host = i_strdup(host); proxy->user = i_strdup(client->virtual_user); proxy->port = port;