changeset 22052:c641778fda28

lib-imap-client: Change server IP only on connect() failures Also log an warning-level message about it. This is mainly useful to see that a slow connection could be caused by a connect() timeout. Since more IPs are still available, it's not yet an error.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 18 May 2017 20:18:24 +0300
parents a70a741f0ae8
children 7ecd91f06169
files src/lib-imap-client/imapc-client.c src/lib-imap-client/imapc-connection.c src/lib-imap-client/imapc-connection.h
diffstat 3 files changed, 15 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap-client/imapc-client.c	Thu May 18 19:42:03 2017 +0300
+++ b/src/lib-imap-client/imapc-client.c	Thu May 18 20:18:24 2017 +0300
@@ -409,7 +409,7 @@
 {
 	i_assert(!box->reconnecting);
 
-	imapc_connection_try_reconnect(box->conn, errmsg, 0);
+	imapc_connection_try_reconnect(box->conn, errmsg, 0, FALSE);
 }
 
 void imapc_client_mailbox_close(struct imapc_client_mailbox **_box)
--- a/src/lib-imap-client/imapc-connection.c	Thu May 18 19:42:03 2017 +0300
+++ b/src/lib-imap-client/imapc-connection.c	Thu May 18 20:18:24 2017 +0300
@@ -522,9 +522,12 @@
 
 void imapc_connection_try_reconnect(struct imapc_connection *conn,
 				    const char *errstr,
-				    unsigned int delay_msecs)
+				    unsigned int delay_msecs,
+				    bool connect_error)
 {
-	if (conn->prev_connect_idx + 1 < conn->ips_count) {
+	/* Try the next IP address only for connect() problems. */
+	if (conn->prev_connect_idx + 1 < conn->ips_count && connect_error) {
+		i_warning("imapc(%s): %s - trying the next IP", conn->name, errstr);
 		conn->reconnect_ok = TRUE;
 		imapc_connection_disconnect_full(conn, TRUE);
 		imapc_connection_connect(conn);
@@ -1546,7 +1549,7 @@
 			str_printfa(str, "Server disconnected unexpectedly: %s",
 				    errstr);
 		}
-		imapc_connection_try_reconnect(conn, str_c(str), 0);
+		imapc_connection_try_reconnect(conn, str_c(str), 0, FALSE);
 	}
 	imapc_connection_unref(&conn);
 }
@@ -1644,7 +1647,7 @@
 		imapc_connection_try_reconnect(conn, t_strdup_printf(
 			"connect(%s, %u) failed: %s",
 			net_ip2addr(ip), conn->client->set.port,
-			strerror(err)), conn->client->set.connect_retry_interval_msecs);
+			strerror(err)), conn->client->set.connect_retry_interval_msecs, TRUE);
 		return;
 	}
 	conn->io = io_add(conn->fd, IO_READ, imapc_connection_input, conn);
@@ -1659,12 +1662,14 @@
 {
 	const struct ip_addr *ip = &conn->ips[conn->prev_connect_idx];
 	const char *errstr;
+	bool connect_error = FALSE;
 
 	switch (conn->state) {
 	case IMAPC_CONNECTION_STATE_CONNECTING:
 		errstr = t_strdup_printf("connect(%s, %u) timed out after %u seconds",
 			net_ip2addr(ip), conn->client->set.port,
 			conn->client->set.connect_timeout_msecs/1000);
+		connect_error = TRUE;
 		break;
 	case IMAPC_CONNECTION_STATE_AUTHENTICATING:
 		errstr = t_strdup_printf("Authentication timed out after %u seconds",
@@ -1673,7 +1678,7 @@
 	default:
 		i_unreached();
 	}
-	imapc_connection_try_reconnect(conn, errstr, 0);
+	imapc_connection_try_reconnect(conn, errstr, 0, connect_error);
 }
 
 static void
@@ -1728,7 +1733,7 @@
 			net_ip2addr(ip), conn->client->set.port);
 		if (conn->prev_connect_idx+1 == conn->ips_count) {
 			imapc_connection_try_reconnect(conn, "No more IP address(es) to try",
-				conn->client->set.connect_retry_interval_msecs);
+				conn->client->set.connect_retry_interval_msecs, TRUE);
 			return;
 		}
 	}
@@ -1925,7 +1930,7 @@
 	i_assert(count > 0);
 
 	imapc_connection_try_reconnect(conn, t_strdup_printf(
-		"Command '%s' timed out", imapc_command_get_readable(cmds[0])), 0);
+		"Command '%s' timed out", imapc_command_get_readable(cmds[0])), 0, FALSE);
 }
 
 static bool
--- a/src/lib-imap-client/imapc-connection.h	Thu May 18 19:42:03 2017 +0300
+++ b/src/lib-imap-client/imapc-connection.h	Thu May 18 20:18:24 2017 +0300
@@ -35,7 +35,8 @@
 				      bool reconnecting);
 void imapc_connection_try_reconnect(struct imapc_connection *conn,
 				    const char *errstr,
-				    unsigned int delay_msecs);
+				    unsigned int delay_msecs,
+				    bool connect_error);
 void imapc_connection_abort_commands(struct imapc_connection *conn,
 				     struct imapc_client_mailbox *only_box,
 				     bool keep_retriable) ATTR_NULL(2);