]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap-client: Change server IP only on connect() failures
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 18 May 2017 17:18:24 +0000 (20:18 +0300)
committerGitLab <gitlab@git.dovecot.net>
Fri, 19 May 2017 07:13:55 +0000 (10:13 +0300)
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.

src/lib-imap-client/imapc-client.c
src/lib-imap-client/imapc-connection.c
src/lib-imap-client/imapc-connection.h

index c961d2a66c5e858a5a435297f6a014f08cf85f81..3e4020e7247c1364c46a2863f1740d345c03bde3 100644 (file)
@@ -409,7 +409,7 @@ void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box,
 {
        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)
index db31358dab17ee9ae10e57168a053e058b38f815..835aac616c0c898456147973f27a8bb97aad0152 100644 (file)
@@ -522,9 +522,12 @@ static void imapc_connection_reconnect(struct imapc_connection *conn)
 
 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);
@@ -1544,7 +1547,7 @@ static void imapc_connection_input(struct imapc_connection *conn)
                        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);
 }
@@ -1642,7 +1645,7 @@ static void imapc_connection_connected(struct imapc_connection *conn)
                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);
@@ -1657,12 +1660,14 @@ static void imapc_connection_timeout(struct imapc_connection *conn)
 {
        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",
@@ -1671,7 +1676,7 @@ static void imapc_connection_timeout(struct imapc_connection *conn)
        default:
                i_unreached();
        }
-       imapc_connection_try_reconnect(conn, errstr, 0);
+       imapc_connection_try_reconnect(conn, errstr, 0, connect_error);
 }
 
 static void
@@ -1726,7 +1731,7 @@ static void imapc_connection_connect_next_ip(struct imapc_connection *conn)
                        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;
                }
        }
@@ -1923,7 +1928,7 @@ static void imapc_command_timeout(struct imapc_connection *conn)
        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
index b22e4369fe0fff9a37a134dbb56decb5ffec9be1..8fda69260c0c7923353d4da7ea63cbcadefe9c4d 100644 (file)
@@ -35,7 +35,8 @@ void imapc_connection_disconnect_full(struct imapc_connection *conn,
                                      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);