From: Timo Sirainen Date: Tue, 1 Sep 2015 13:25:11 +0000 (+0300) Subject: lib-imap-client: If connect() fails immediately, log an error and retry the next IP. X-Git-Tag: 2.2.19.rc1~139 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5d5b8aab8c7c19e1a8a995ef8fda56b0f281e89;p=thirdparty%2Fdovecot%2Fcore.git lib-imap-client: If connect() fails immediately, log an error and retry the next IP. Only if all IPs fail return a full failure. This is mainly intended to skip IPv6 addresses when IPv6 connectivity doesn't work. --- diff --git a/src/lib-imap-client/imapc-connection.c b/src/lib-imap-client/imapc-connection.c index ecba203618..a018c779fc 100644 --- a/src/lib-imap-client/imapc-connection.c +++ b/src/lib-imap-client/imapc-connection.c @@ -1564,16 +1564,27 @@ static void imapc_connection_reset_idle(struct imapc_connection *conn) static void imapc_connection_connect_next_ip(struct imapc_connection *conn) { const struct ip_addr *ip; + unsigned int i; int fd; i_assert(conn->client->set.max_idle_time > 0); - conn->prev_connect_idx = (conn->prev_connect_idx+1) % conn->ips_count; - ip = &conn->ips[conn->prev_connect_idx]; - fd = net_connect_ip(ip, conn->client->set.port, NULL); - if (fd == -1) { - imapc_connection_set_disconnected(conn); - return; + for (i = 0;;) { + conn->prev_connect_idx = (conn->prev_connect_idx+1) % conn->ips_count; + ip = &conn->ips[conn->prev_connect_idx]; + fd = net_connect_ip(ip, conn->client->set.port, NULL); + if (fd != -1) + break; + + /* failed to connect to one of the IPs immediately + (e.g. IPv6 address without connectivity). try all IPs + before failing completely. */ + i_error("net_connect_ip(%s:%u) failed: %m", + net_ip2addr(ip), conn->client->set.port); + if (++i == conn->ips_count) { + imapc_connection_set_disconnected(conn); + return; + } } conn->fd = fd; conn->input = conn->raw_input = i_stream_create_fd(fd, (size_t)-1, FALSE);