]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap-client: If connect() fails immediately, log an error and retry the next IP.
authorTimo Sirainen <tss@iki.fi>
Tue, 1 Sep 2015 13:25:11 +0000 (16:25 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 1 Sep 2015 13:25:11 +0000 (16:25 +0300)
Only if all IPs fail return a full failure. This is mainly intended to skip
IPv6 addresses when IPv6 connectivity doesn't work.

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

index ecba20361806798e57788b8c45f939d5ac221e6e..a018c779fcd0bcd4b821ff57483e7829784b8928 100644 (file)
@@ -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);