director.h revision b44033e45e9f48f8a6e1ac5905234fec5de6d6cc
#ifndef DIRECTOR_H
#define DIRECTOR_H
#include "net.h"
#include "director-settings.h"
#define DIRECTOR_VERSION_NAME "director"
#define DIRECTOR_VERSION_MAJOR 1
#define DIRECTOR_VERSION_MINOR 8
/* weak users supported in protocol */
#define DIRECTOR_VERSION_WEAK_USERS 1
/* director ring remove supported */
#define DIRECTOR_VERSION_RING_REMOVE 2
/* quit reason supported */
#define DIRECTOR_VERSION_QUIT 3
/* user-kick supported */
#define DIRECTOR_VERSION_USER_KICK 4
/* options supported in handshake */
#define DIRECTOR_VERSION_OPTIONS 5
/* user tags supported */
#define DIRECTOR_VERSION_TAGS 5
#define DIRECTOR_VERSION_UPDOWN 6
/* user tag version 2 supported */
#define DIRECTOR_VERSION_TAGS_V2 7
/* user-kick-alt supported */
#define DIRECTOR_VERSION_USER_KICK_ALT 8
/* Minimum time between even attempting to communicate with a director that
failed due to a protocol error. */
#define DIRECTOR_PROTOCOL_FAILURE_RETRY_SECS 60
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;
struct ip_addr old_host_ip;
bool kill_is_self_initiated;
bool callback_pending;
enum user_kill_state kill_state;
/* 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: */
struct program_client *pclient;
char *socket_path;
};
struct director {
const struct director_settings *set;
struct director_host *self_host;
/* 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 */
struct timeout *to_reconnect;
struct timeout *to_callback;
/* current mail hosts */
struct mail_host_list *mail_hosts;
/* original mail hosts configured in config file.
this is used only for doveadm lookups */
struct mail_host_list *orig_config_hosts;
/* Number of users currently being moved */
unsigned int users_moving_count;
/* these requests are waiting for directors to be in synced */
struct timeout *to_request;
struct timeout *to_handshake_warning;
/* director hosts are sorted by IP (and port) */
struct timeout *to_remove_dirs;
struct ipc_client *ipc_proxy;
unsigned int sync_seq;
unsigned int ring_change_counter;
unsigned int last_sync_sent_ring_change_counter;
/* the lowest minor version supported by the ring */
unsigned int ring_min_version;
/* director ring handshaking is complete.
director can start serving clients. */
bool ring_handshaked:1;
bool ring_handshake_warning_sent:1;
bool ring_synced:1;
bool sync_frozen:1;
bool sync_pending:1;
};
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 *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);
bool
unsigned int *hash_r);
void directors_init(void);
void directors_deinit(void);
#endif