]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Fix USER-MOVE getting stuck if a director already uses the correct host
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 20 Jan 2017 14:06:48 +0000 (16:06 +0200)
committerGitLab <gitlab@git.dovecot.net>
Fri, 20 Jan 2017 15:46:57 +0000 (17:46 +0200)
src/director/director.c

index 72008ad35b64a9bb2b3469e5c734ea18f092f4fb..c3b8ff6a2f0a86576001fa80413a832eb897dac2 100644 (file)
@@ -1012,16 +1012,18 @@ director_kill_user(struct director *dir, struct director_host *src,
                                   director_user_move_timeout, user);
        ctx->kill_state = USER_KILL_STATE_KILLING;
 
-       if (old_host != NULL) {
+       if (old_host != NULL && old_host != user->host) {
                cmd = t_strdup_printf("proxy\t*\tKICK-DIRECTOR-HASH\t%u",
                                      user->username_hash);
                ctx->callback_pending = TRUE;
                ipc_client_cmd(dir->ipc_proxy, cmd,
                               director_kill_user_callback, ctx);
        } else {
-               /* we didn't even know about the user before now.
+               /* a) we didn't even know about the user before now.
                   don't bother performing a local kick, since it wouldn't
-                  kick anything. */
+                  kick anything.
+                  b) our host was already correct. notify others that we have
+                  killed the user, but don't really do it. */
                director_finish_user_kill(ctx->dir, user,
                                          ctx->kill_is_self_initiated);
        }
@@ -1055,11 +1057,13 @@ void director_move_user(struct director *dir, struct director_host *src,
        if (user == NULL) {
                user = user_directory_add(users, username_hash,
                                          host, ioloop_time);
+       } else if (user->host == host) {
+               /* User is already in the wanted host, but another director
+                  didn't think so. We'll need to finish the move without
+                  killing any of our connections. */
+               old_host = user->host;
+               user->timestamp = ioloop_time;
        } else {
-               if (user->host == host) {
-                       /* user is already in this host */
-                       return;
-               }
                /* user is looked up via the new host's tag, so if it's found
                   the old tag has to be the same. */
                i_assert(user->host->tag == host->tag);