Mercurial > dovecot > core-2.2
changeset 20615:dbd3bbba0f49
login-proxy: Fixed assert-crash/hang on connect errors.
The internal BUG would have left the host hanging. "Host is down" or any
immediate connect() error would have assert-crashed with:
Panic: file login-proxy.c: line 470 (login_proxy_disconnect): assertion failed: (proxy->state_rec->num_waiting_connections > 0)
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Wed, 10 Aug 2016 14:05:25 +0300 |
parents | f3b498663de4 |
children | d59ab03e5636 |
files | src/login-common/login-proxy.c |
diffstat | 1 files changed, 17 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/login-proxy.c Wed Aug 10 01:39:39 2016 +0300 +++ b/src/login-common/login-proxy.c Wed Aug 10 14:05:25 2016 +0300 @@ -371,6 +371,20 @@ { struct login_proxy_record *rec = proxy->state_rec; + /* this needs to be done early, since login_proxy_free() shrinks + num_waiting_connections. */ + proxy->num_waiting_connections_updated = FALSE; + rec->num_waiting_connections++; + + if (proxy->ip.family == 0 && + net_addr2ip(proxy->host, &proxy->ip) < 0) { + client_log_err(proxy->client, t_strdup_printf( + "proxy(%s): BUG: host %s is not an IP " + "(auth should have changed it)", + proxy->client->virtual_user, proxy->host)); + return -1; + } + if (rec->last_success.tv_sec == 0) { /* first connect to this IP. don't start immediately failing the check below. */ @@ -383,7 +397,6 @@ client_log_err(proxy->client, t_strdup_printf( "proxy(%s): Host %s:%u is down", proxy->client->virtual_user, proxy->host, proxy->port)); - login_proxy_free(&proxy); return -1; } @@ -392,7 +405,6 @@ &proxy->source_ip); if (proxy->server_fd == -1) { proxy_log_connect_error(proxy); - login_proxy_free(&proxy); return -1; } proxy->server_io = io_add(proxy->server_fd, IO_WRITE, @@ -401,10 +413,6 @@ proxy->to = timeout_add(proxy->connect_timeout_msecs, proxy_connect_timeout, proxy); } - - proxy->num_waiting_connections_updated = FALSE; - proxy->state_rec = rec; - proxy->state_rec->num_waiting_connections++; return 0; } @@ -445,15 +453,9 @@ proxy->port); client_ref(client); - if (set->ip.family == 0 && - net_addr2ip(set->host, &proxy->ip) < 0) { - client_log_err(client, t_strdup_printf( - "proxy(%s): BUG: host %s is not an IP " - "(auth should have changed it)", - client->virtual_user, set->host)); - } else { - if (login_proxy_connect(proxy) < 0) - return -1; + if (login_proxy_connect(proxy) < 0) { + login_proxy_free(&proxy); + return -1; } DLLIST_PREPEND(&login_proxies_pending, proxy);