#ifndef DIRECTOR_H
#define DIRECTOR_H
#include "net.h"
#include "director-settings.h"
/* weak users supported in protocol */
/* director ring remove supported */
/* quit reason supported */
/* user-kick supported */
/* options supported in handshake */
/* user tags supported */
/* user tag version 2 supported */
/* user-kick-alt supported */
/* Users are sent as "U" command in handshake */
/* USER event with timestamp supported */
/* Minimum time between even attempting to communicate with a director that
failed due to a protocol error. */
struct director;
struct mail_host;
struct user;
struct director_user_init;
enum user_kill_state {
/* User isn't being killed */
/* We're still killing the user's connections */
/* Like above, but our left side already announced it was finished
with killing its user connections */
/* We're done killing, but we have to wait for the left side to
finish killing its user connections before sending USER-KILLED to
our right side */
/* We're done killing, but waiting for USER-KILLED-EVERYWHERE
notification until this state gets reset. */
/* Waiting for the flush socket to finish. */
/* Wait for a while for the user connections to actually die. Note that
only at this stage we can be sure that all the directors know about
the user move (although it could be earlier if we added a new
USER-MOVED notification). */
/* NOTE: remember to update also user_kill_state_names[] */
};
/* When a user gets freed, the kill_ctx may still be left alive. It's also
possible for the user to come back, in which case the kill_ctx is usually
NULL, but another kill could have also started. The previous kill_ctx is
valid only if it matches the current user's kill_ctx. */
struct director_kill_context {
unsigned int username_hash;
unsigned int old_host_vhost_count;
bool old_host_down;
bool kill_is_self_initiated;
bool callback_pending;
/* Move timeout to make sure user's connections won't silently hang
indefinitely if there is some trouble moving it. */
/* these are set only for director_flush_socket handling: */
char *socket_path;
};
struct director {
/* left and right connections are set only after they have finished
handshaking. until then they're in the connections list, although
updates are still sent to them during handshaking if the USER list
is long. */
/* all director connections */
/* current mail hosts */
/* original mail hosts configured in config file.
this is used only for doveadm lookups */
/* Number of users currently being moved */
unsigned int users_moving_count;
/* Number of users currently being kicked */
unsigned int users_kicking_count;
/* Number of requests currently delayed */
unsigned int requests_delayed_count;
/* these requests are waiting for directors to be in synced */
/* director hosts are sorted by IP (and port) */
unsigned int sync_seq;
unsigned int ring_change_counter;
unsigned int last_sync_sent_ring_change_counter;
/* Timestamp when the last SYNC was initiated by us */
/* the lowest minor version supported by the ring */
unsigned int ring_min_version;
/* Timestamp when ring became synced or unsynced the last time */
/* How many milliseconds it took for the last SYNC to travel through
the ring. */
unsigned int last_sync_msecs;
/* director ring handshaking is complete.
director can start serving clients. */
};
extern bool director_debug;
/* Create a new director. If listen_ip specifies an actual IP, it's used with
listen_port for finding ourself from the director_servers setting.
listen_port is used regardless by director_host_add_from_string() for hosts
without specified port. */
struct director *
/* Start connecting to other directors */
unsigned int timestamp, unsigned int hosts_hash);
struct director_host *src);
struct director_host *orig_src,
struct director_host *orig_src,
struct director_host *orig_src,
struct director_connection *src_conn,
struct director_host *orig_src,
struct director_host *orig_src,
ATTR_NULL(3);
ATTR_NULL(3);
struct director_host *orig_src,
ATTR_NULL(3);
struct director_host *orig_src,
unsigned int username_hash,
ATTR_NULL(3);
struct director_host *src,
struct director_host *orig_src,
/* Send data to all directors using both left and right connections
(unless they're the same). */
const char *cmd);
struct director_host *src,
unsigned int min_version, const char *cmd);
const char *reason);
bool
unsigned int *hash_r);
void directors_init(void);
void directors_deinit(void);
struct director_user_iter *
#endif