director.c revision 00e7c3010f7da4a49881a7feb05e413af353af0a
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "lib.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "ioloop.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "array.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "str.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "user-directory.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "mail-host.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director-host.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director-connection.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "director.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen#define DIRECTOR_RECONNECT_RETRY_SECS 60
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic bool director_is_self_ip_set(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_get_ip_any4(&ip);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (net_ip_compare(&dir->self_ip, &ip))
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return FALSE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_get_ip_any6(&ip);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (net_ip_compare(&dir->self_ip, &ip))
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return FALSE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return TRUE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_find_self_ip(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_host *const *hosts;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, count;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen hosts = array_get(&dir->dir_hosts, &count);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < count; i++) {
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen if (net_try_bind(&hosts[i]->ip) == 0) {
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen dir->self_ip = hosts[i]->ip;
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen return;
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen i_fatal("director_servers doesn't list ourself");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_find_self(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->self_host != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
34a45b80c8ed18861c6e343fe40adbe360fc6badTimo Sirainen if (!director_is_self_ip_set(dir))
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_find_self_ip(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->self_host = director_host_lookup(dir, &dir->self_ip,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->self_port);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->self_host == NULL) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("director_servers doesn't list ourself (%s:%u)",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_ip2addr(&dir->self_ip), dir->self_port);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->self_host->self = TRUE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic unsigned int director_find_self_idx(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_host *const *hosts;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, count;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_assert(dir->self_host != NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen hosts = array_get(&dir->dir_hosts, &count);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (hosts[i] == dir->self_host)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return i;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_unreached();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenint director_connect_host(struct director *dir, struct director_host *host)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen unsigned int port;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen int fd;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_assert(dir->right == NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen if (dir->debug) {
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen i_debug("Connecting to %s:%u",
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen net_ip2addr(&host->ip), host->port);
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen }
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen port = dir->test_port != 0 ? dir->test_port : host->port;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen fd = net_connect_ip(&host->ip, port, &dir->self_ip);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (fd == -1) {
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen host->last_failed = ioloop_time;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_error("connect(%s) failed: %m", host->name);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return -1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->right = director_connection_init_out(dir, fd, host);
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen return 0;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_connect(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_host *const *hosts;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, count, self_idx;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_find_self(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen self_idx = director_find_self_idx(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* try to connect to first working server on our right side.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen the left side is supposed to connect to us. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen hosts = array_get(&dir->dir_hosts, &count);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 1; i < count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int idx = (self_idx + i) % count;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen if (hosts[idx]->last_failed +
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen DIRECTOR_RECONNECT_RETRY_SECS > ioloop_time) {
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen /* failed recently, don't try retrying here */
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen continue;
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen }
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen if (director_connect_host(dir, hosts[idx]) == 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen break;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (i == count) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* we're the only one */
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen director_set_ring_handshaked(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainenvoid director_set_ring_handshaked(struct director *dir)
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen{
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen if (dir->ring_handshake_warning_sent) {
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen i_warning("Directors have been connected, "
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen "continuing delayed connections");
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen dir->ring_handshake_warning_sent = FALSE;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen }
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen if (dir->debug)
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen i_debug("Director ring handshaked");
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen dir->ring_handshaked = TRUE;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen director_set_state_changed(dir);
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen}
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_update_host(struct director *dir, struct director_host *src,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_host *host)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_set_state_changed(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_update_send(dir, src, t_strdup_printf(
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "HOST\t%s\t%u\n", net_ip2addr(&host->ip), host->vhost_count));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_remove_host(struct director *dir, struct director_host *src,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_host *host)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_update_send(dir, src, t_strdup_printf(
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "HOST-REMOVE\t%s\n", net_ip2addr(&host->ip)));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen user_directory_remove_host(dir->users, host);
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen mail_host_remove(dir->mail_hosts, host);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainenvoid director_flush_host(struct director *dir, struct director_host *src,
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen struct mail_host *host)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen{
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen director_update_send(dir, src, t_strdup_printf(
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen "HOST-FLUSH\t%s\n", net_ip2addr(&host->ip)));
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen user_directory_remove_host(dir->users, host);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen}
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_update_user(struct director *dir, struct director_host *src,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct user *user)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_update_send(dir, src, t_strdup_printf(
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "USER\t%u\t%s\n", user->username_hash,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_ip2addr(&user->host->ip)));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_set_state_changed(struct director *dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->state_change_callback(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_update_send(struct director *dir, struct director_host *src,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *cmd)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_assert(src != NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->left != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_connection_send_except(dir->left, src, cmd);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->right != NULL && dir->right != dir->left)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_connection_send_except(dir->right, src, cmd);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct director *
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainendirector_init(const struct director_settings *set,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct ip_addr *listen_ip, unsigned int listen_port,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_state_change_callback_t *callback)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director *dir;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir = i_new(struct director, 1);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->set = set;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->self_port = listen_port;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->self_ip = *listen_ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->state_change_callback = callback;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_array_init(&dir->dir_hosts, 16);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_array_init(&dir->pending_requests, 16);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_array_init(&dir->desynced_host_changes, 16);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen dir->users = user_directory_init(set->director_user_expire);
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen dir->mail_hosts = mail_hosts_init();
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return dir;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_deinit(struct director **_dir)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director *dir = *_dir;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_host *const *hostp;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen *_dir = NULL;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->left != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_connection_deinit(&dir->left);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->right != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_connection_deinit(&dir->right);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen user_directory_deinit(&dir->users);
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen mail_hosts_deinit(&dir->mail_hosts);
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen mail_hosts_deinit(&dir->orig_config_hosts);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (dir->to_request != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen timeout_remove(&dir->to_request);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_foreach(&dir->dir_hosts, hostp)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_host_free(*hostp);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_free(&dir->desynced_host_changes);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_free(&dir->pending_requests);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_free(&dir->dir_hosts);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_free(dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}