]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Fixed handling weak users when there were exactly 2 director servers in...
authorTimo Sirainen <tss@iki.fi>
Wed, 23 Apr 2014 20:26:49 +0000 (23:26 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 23 Apr 2014 20:26:49 +0000 (23:26 +0300)
src/director/director-connection.c
src/director/director-request.c
src/director/director.c
src/director/director.h

index ee9990db6b6068d07c013e93b92bb0eccd47db15..a1018e9359318829dea4e15258fd8a2610ae6f5a 100644 (file)
@@ -799,7 +799,7 @@ director_cmd_user_weak(struct director_connection *conn,
                if (!user->weak)
                        director_update_user(conn->dir, src_host, user);
                else {
-                       director_update_user_weak(conn->dir, src_host,
+                       director_update_user_weak(conn->dir, src_host, conn,
                                                  dir_host, user);
                }
        }
index ec1dca9cce4348c4d287c2c9c72c30a0776074dd..fa6dab30064e15519bc608ec1178309f1605e3e4 100644 (file)
@@ -241,7 +241,7 @@ director_request_existing(struct director_request *request, struct user *user)
                return TRUE;
        } else {
                user->weak = TRUE;
-               director_update_user_weak(dir, dir->self_host, NULL, user);
+               director_update_user_weak(dir, dir->self_host, NULL, NULL, user);
                request->delay_reason = REQUEST_DELAY_WEAK;
                dir_debug("request: %u set to weak", request->username_hash);
                return FALSE;
index 1cba743e5ebe08d536e04e1a31db332a05eb9cfa..9757a8a12195d4b1c0886c8b27c445edb24b9280 100644 (file)
@@ -566,9 +566,12 @@ void director_update_user(struct director *dir, struct director_host *src,
 }
 
 void director_update_user_weak(struct director *dir, struct director_host *src,
+                              struct director_connection *src_conn,
                               struct director_host *orig_src,
                               struct user *user)
 {
+       const char *cmd;
+
        i_assert(src != NULL);
        i_assert(user->weak);
 
@@ -577,10 +580,27 @@ void director_update_user_weak(struct director *dir, struct director_host *src,
                orig_src->last_seq++;
        }
 
-       director_update_send(dir, src, t_strdup_printf(
-               "USER-WEAK\t%s\t%u\t%u\t%u\t%s\n",
+       cmd = t_strdup_printf("USER-WEAK\t%s\t%u\t%u\t%u\t%s\n",
                net_ip2addr(&orig_src->ip), orig_src->port, orig_src->last_seq,
-               user->username_hash, net_ip2addr(&user->host->ip)));
+               user->username_hash, net_ip2addr(&user->host->ip));
+
+       if (src != dir->self_host && dir->left != NULL && dir->right != NULL &&
+           director_connection_get_host(dir->left) ==
+           director_connection_get_host(dir->right)) {
+               /* only two directors in this ring and we're forwarding
+                  USER-WEAK from one director back to itself via another
+                  so it sees we've received it. we can't use
+                  director_update_send() for this, because it doesn't send
+                  data back to the source. */
+               if (dir->right == src_conn)
+                       director_connection_send(dir->left, cmd);
+               else if (dir->left == src_conn)
+                       director_connection_send(dir->right, cmd);
+               else
+                       i_unreached();
+       } else {
+               director_update_send(dir, src, cmd);
+       }
 }
 
 struct director_user_kill_finish_ctx {
index 140ed29269eb16be84ee5dcf6af883d52ce540ff..1b97cbf4b496b686a6b8c7587cb05995b3358375 100644 (file)
@@ -124,6 +124,7 @@ void director_flush_host(struct director *dir, struct director_host *src,
 void director_update_user(struct director *dir, struct director_host *src,
                          struct user *user);
 void director_update_user_weak(struct director *dir, struct director_host *src,
+                              struct director_connection *src_conn,
                               struct director_host *orig_src,
                               struct user *user) ATTR_NULL(3);
 void director_move_user(struct director *dir, struct director_host *src,