]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: If connecting to director fails, try connecting to next one.
authorTimo Sirainen <tss@iki.fi>
Wed, 19 May 2010 11:08:33 +0000 (13:08 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 19 May 2010 11:08:33 +0000 (13:08 +0200)
--HG--
branch : HEAD

src/director/director-connection.c
src/director/director-host.h
src/director/director.c

index 1e0f7b020f7aff99885e2e238c5a976ee5e7cb8d..088747ca90079aeb77ad683ff3f577c3a81cc563 100644 (file)
@@ -370,7 +370,7 @@ director_connection_handle_handshake(struct director_connection *conn,
                director_handshake_cmd_done(conn);
                return TRUE;
        }
-       i_error("director(%s): Unknown command (in this state): %s",
+       i_error("director(%s): Invalid handshake command: %s",
                conn->name, cmd);
        return FALSE;
 }
@@ -456,8 +456,15 @@ director_connection_handle_line(struct director_connection *conn,
                i_error("director(%s): Received empty line", conn->name);
                return FALSE;
        }
-       if (!conn->handshake_received)
-               return director_connection_handle_handshake(conn, cmd, args);
+       if (!conn->handshake_received) {
+               if (!director_connection_handle_handshake(conn, cmd, args)) {
+                       /* invalid commands during handshake,
+                          we probably don't want to reconnect here */
+                       conn->host->last_failed = ioloop_time;
+                       return FALSE;
+               }
+               return TRUE;
+       }
 
        if (strcmp(cmd, "USER") == 0)
                return director_cmd_user(conn, args);
@@ -623,13 +630,18 @@ director_connection_init_in(struct director *dir, int fd)
 
 static void director_connection_connected(struct director_connection *conn)
 {
+       struct director *dir = conn->dir;
        string_t *str = t_str_new(1024);
        int err;
 
        if ((err = net_geterror(conn->fd)) != 0) {
+               conn->host->last_failed = ioloop_time;
                i_error("director(%s): connect() failed: %s", conn->name,
                        strerror(err));
                director_connection_deinit(&conn);
+
+               /* try connecting to next server */
+               director_connect(dir);
                return;
        }
        conn->connected = TRUE;
@@ -641,7 +653,7 @@ static void director_connection_connected(struct director_connection *conn)
        director_connection_send_hosts(str);
        director_connection_send(conn, str_c(str));
 
-       conn->user_iter = user_directory_iter_init(conn->dir->users);
+       conn->user_iter = user_directory_iter_init(dir->users);
        (void)director_connection_send_users(conn);
 }
 
index 77c3a4cec830a18ee46e59e5dadd3973c41062a6..fb9015ccfae41893a25b75321f65845885cdd426 100644 (file)
@@ -17,6 +17,9 @@ struct director_host {
           trust the one that has the highest sequence. */
        unsigned int last_seq;
 
+       /* Last time host was detected to be down/broken */
+       time_t last_failed;
+
        /* we are this director */
        unsigned int self:1;
 };
index 00dd700fe3ca91eebae5d726e784142a6da3535f..67ce78a558c062f48aa8795a0fcc9e29ceb927a0 100644 (file)
@@ -10,6 +10,8 @@
 #include "director-connection.h"
 #include "director.h"
 
+#define DIRECTOR_RECONNECT_RETRY_SECS 60
+
 static bool director_is_self_ip_set(struct director *dir)
 {
        struct ip_addr ip;
@@ -90,14 +92,20 @@ int director_connect_host(struct director *dir, struct director_host *host)
 
        i_assert(dir->right == NULL);
 
+       if (host->last_failed + DIRECTOR_RECONNECT_RETRY_SECS > ioloop_time) {
+               /* failed recently, don't try retrying here */
+               return -1;
+       }
+
        fd = net_connect_ip(&host->ip, host->port, NULL);
        if (fd == -1) {
+               host->last_failed = ioloop_time;
                i_error("connect(%s) failed: %m", host->name);
                return -1;
        }
 
        dir->right = director_connection_init_out(dir, fd, host);
-       return 1;
+       return 0;
 }
 
 void director_connect(struct director *dir)
@@ -114,7 +122,7 @@ void director_connect(struct director *dir)
        for (i = 1; i < count; i++) {
                unsigned int idx = (self_idx + i) % count;
 
-               if (director_connect_host(dir, hosts[idx]) > 0)
+               if (director_connect_host(dir, hosts[idx]) == 0)
                        break;
        }
        if (i == count) {