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);