director-request.c revision 98811ad98a4d673d3f69cac6a4b402cea774ed15
c636315472e4f87313af7be30b7fbcad4b8ca8a4Stephen Gallagher/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
c636315472e4f87313af7be30b7fbcad4b8ca8a4Stephen Gallagher
fd5a4eacd56700ffb08a73121aeacdc806cb0132Sumit Bose#include "lib.h"
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include "ioloop.h"
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include "array.h"
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include "str.h"
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include "mail-host.h"
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include "user-directory.h"
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher#include "director.h"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#include "director-request.h"
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher#define DIRECTOR_REQUEST_TIMEOUT_SECS 30
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#define RING_NOCONN_WARNING_DELAY_MSECS (2*1000)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherenum director_request_delay_reason {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher REQUEST_DELAY_NONE = 0,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher REQUEST_DELAY_RINGNOTHANDSHAKED,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher REQUEST_DELAY_RINGNOTSYNCED,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher REQUEST_DELAY_NOHOSTS,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher REQUEST_DELAY_WEAK,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher REQUEST_DELAY_KILL
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher};
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic const char *delay_reason_strings[] = {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "unknown",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "ring not handshaked",
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher "ring not synced",
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher "no hosts",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "weak user",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "kill waiting"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher};
d921c1eba437662437847279f251a0a5d8f70127Maxim
2cbdd12983eb85eddb90f64cfafb24eae5b448f4Jakub Hrozekstruct director_request {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct director *dir;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher time_t create_time;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int username_hash;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher enum director_request_delay_reason delay_reason;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek director_request_callback *callback;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher void *context;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher};
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher
4b6a0d0b3d42e5fdb457f47d9adfa5e66b160256Stephen Gallagherstatic const char *
70e59ed31c5a9c9ed02d9065ddf92be87c887efbJakub Hrozekdirector_request_get_timeout_error(struct director_request *request,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct user *user, string_t *str)
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher{
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher unsigned int secs;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_truncate(str, 0);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_printfa(str, "Timeout because %s - queued for %u secs (",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher delay_reason_strings[request->delay_reason],
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (unsigned int)(ioloop_time - request->create_time));
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (request->dir->ring_last_sync_time == 0)
be1ef1c62ad13612be5e1f879476c24452a5d6d0Stephen Gallagher str_append(str, "Ring has never been synced");
be1ef1c62ad13612be5e1f879476c24452a5d6d0Stephen Gallagher else {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher secs = ioloop_time - request->dir->ring_last_sync_time;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (request->dir->ring_synced)
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher str_printfa(str, "Ring synced for %u secs", secs);
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher else
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_printfa(str, "Ring not synced for %u secs", secs);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (user != NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (user->weak)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_append(str, ", weak user");
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_printfa(str, ", user refreshed %u secs ago",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (unsigned int)(ioloop_time - user->timestamp));
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_append_c(str, ')');
c737e1444fb186e349e59bfa9dac4995b720b4b1Jan Zeleny return str_c(str);
f1828234a850dd28465425248a83a993f262918fPavel Březina}
f1828234a850dd28465425248a83a993f262918fPavel Březina
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void director_request_timeout(struct director *dir)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct director_request **requestp, *request;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct user *user;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *errormsg;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher string_t *str = t_str_new(128);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher while (array_count(&dir->pending_requests) > 0) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina requestp = array_idx_modifiable(&dir->pending_requests, 0);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina request = *requestp;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (request->create_time +
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DIRECTOR_REQUEST_TIMEOUT_SECS > ioloop_time)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek break;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user = user_directory_lookup(request->dir->users,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->username_hash);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher errormsg = director_request_get_timeout_error(request,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user, str);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher array_delete(&dir->pending_requests, 0, 1);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher T_BEGIN {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->callback(NULL, errormsg, request->context);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } T_END;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_free(request);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (array_count(&dir->pending_requests) == 0 && dir->to_request != NULL)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher timeout_remove(&dir->to_request);
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek}
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher
fe60346714a73ac3987f786731389320633dd245Pavel Březinavoid director_request(struct director *dir, const char *username,
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher director_request_callback *callback, void *context)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct director_request *request;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int username_hash =
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user_directory_get_username_hash(dir->users, username);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request = i_new(struct director_request, 1);
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher request->dir = dir;
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher request->create_time = ioloop_time;
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher request->username_hash = username_hash;
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek request->callback = callback;
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek request->context = context;
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher if (director_request_continue(request))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return;
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* need to queue it */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (dir->to_request == NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher dir->to_request =
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher timeout_add(DIRECTOR_REQUEST_TIMEOUT_SECS * 1000,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher director_request_timeout, dir);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher array_append(&dir->pending_requests, &request, 1);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ring_noconn_warning(struct director *dir)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!dir->ring_handshaked) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_warning("Delaying all requests "
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "until all directors have connected");
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_warning("Delaying new user requests until ring is synced");
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher dir->ring_handshake_warning_sent = TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher timeout_remove(&dir->to_handshake_warning);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozekstatic void ring_log_delayed_warning(struct director *dir)
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek{
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek if (dir->ring_handshake_warning_sent ||
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher dir->to_handshake_warning != NULL)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek dir->to_handshake_warning = timeout_add(RING_NOCONN_WARNING_DELAY_MSECS,
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek ring_noconn_warning, dir);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic bool
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherdirector_request_existing(struct director_request *request, struct user *user)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct director *dir = request->dir;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct mail_host *host;
3b1df539835367cb81cd5ff0f9959947d5642e55Stephen Gallagher
3b1df539835367cb81cd5ff0f9959947d5642e55Stephen Gallagher if (user->kill_state != USER_KILL_STATE_NONE) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* delay processing this user's connections until
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher its existing connections have been killed */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->delay_reason = REQUEST_DELAY_KILL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek if (dir->right == NULL && dir->ring_synced) {
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek /* looks like all the other directors have died. we can do
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher whatever we want without breaking anything. remove the
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user's weakness just in case it was set to TRUE when we
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher had more directors. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user->weak = FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
15b266d9f14dad26da8678a79019749d0f69532eStephen Gallagher if (user->weak) {
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek /* wait for user to become non-weak */
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek request->delay_reason = REQUEST_DELAY_WEAK;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!user_directory_user_is_near_expiring(dir->users, user))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* user is close to being expired. another director may have
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher already expired it. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher host = mail_host_get_by_hash(dir->mail_hosts, user->username_hash);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!dir->ring_synced) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* try again later once ring is synced */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->delay_reason = REQUEST_DELAY_RINGNOTSYNCED;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (user->host == host) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* doesn't matter, other directors would
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher assign the user the same way regardless */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* We have to worry about two separate timepoints in here:
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher a) some directors think the user isn't expiring, and
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher others think the user is near expiring
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher b) some directors think the user is near expiring, and
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher others think the user has already expired
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher What we don't have to worry about is:
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher !c) some directors think the user isn't expiring, and
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher others think the user has already expired
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher If !c) happens, the user might get redirected to different backends.
bfbf5cb0f00c60c0f000f56c282377b13b9a89abSumit Bose We'll use a large enough timeout between a) and b) states, so that
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher !c) should never happen.
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher So what we'll do here is:
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher 1. Send a USER-WEAK notification to all directors with the new host.
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher 2. Each director receiving USER-WEAK refreshes the user's timestamp
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher and host, but marks the user as being weak.
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher 3. Once USER-WEAK has reached all directors, a real USER update is
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher sent, which removes the weak-flag.
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher 4. If a director ever receives a USER update for a weak user, the
0ef783e186ef1c9f60e61a4e8e54c44cb366fdfePavel Březina USER update overrides the host and removes the weak-flag.
2cbdd12983eb85eddb90f64cfafb24eae5b448f4Jakub Hrozek 5. Director doesn't let any weak user log in, until the weak-flag
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher gets removed.
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (dir->ring_min_version < DIRECTOR_VERSION_WEAK_USERS) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* weak users not supported by ring currently */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user->weak = TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher director_update_user_weak(dir, dir->self_host, NULL, user);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->delay_reason = REQUEST_DELAY_WEAK;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherbool director_request_continue(struct director_request *request)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct director *dir = request->dir;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct mail_host *host;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct user *user;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!dir->ring_handshaked) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* delay requests until ring handshaking is complete */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ring_log_delayed_warning(dir);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->delay_reason = REQUEST_DELAY_RINGNOTHANDSHAKED;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user = user_directory_lookup(dir->users, request->username_hash);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (user != NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!director_request_existing(request, user))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user_directory_refresh(dir->users, user);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!dir->ring_synced) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* delay adding new users until ring is again synced */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ring_log_delayed_warning(dir);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->delay_reason = REQUEST_DELAY_RINGNOTSYNCED;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher host = mail_host_get_by_hash(dir->mail_hosts,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->username_hash);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (host == NULL) {
126c9338cf12a3e4404c36bbe4ec14b18f23537cMaxim /* all hosts have been removed */
fe2091327ff44f80d6681c261494e4432404e9baStephen Gallagher request->delay_reason = REQUEST_DELAY_NOHOSTS;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return FALSE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher user = user_directory_add(dir->users, request->username_hash,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher host, ioloop_time);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_assert(!user->weak);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher director_update_user(dir, dir->self_host, user);
2e6087c6cc903d5164b9a1d5e3d791fd046001d9Jakub Hrozek T_BEGIN {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher request->callback(&user->host->ip, NULL, request->context);
126c9338cf12a3e4404c36bbe4ec14b18f23537cMaxim } T_END;
fe2091327ff44f80d6681c261494e4432404e9baStephen Gallagher i_free(request);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return TRUE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher