return FALSE;
}
- host = mail_host_lookup(&ip);
+ host = mail_host_lookup(conn->dir->mail_hosts, &ip);
if (host == NULL) {
i_error("director(%s): USER used unknown host %s in handshake",
conn->name, args[1]);
if (remote_ring_completed && !conn->dir->ring_handshaked) {
/* clear everything we have and use only what remote sends us */
- hosts = mail_hosts_get();
+ hosts = mail_hosts_get(conn->dir->mail_hosts);
while (array_count(hosts) > 0) {
hostp = array_idx(hosts, 0);
director_remove_host(conn->dir, conn->host, *hostp);
return TRUE;
}
- host = mail_host_lookup(&ip);
+ host = mail_host_lookup(conn->dir->mail_hosts, &ip);
if (host == NULL) {
- host = mail_host_add_ip(&ip);
+ host = mail_host_add_ip(conn->dir->mail_hosts, &ip);
update = TRUE;
} else {
update = host->vhost_count != vhost_count;
return FALSE;
}
- host = mail_host_lookup(&ip);
+ host = mail_host_lookup(conn->dir->mail_hosts, &ip);
if (host != NULL)
director_remove_host(conn->dir, conn->host, host);
return TRUE;
return FALSE;
}
- host = mail_host_lookup(&ip);
+ host = mail_host_lookup(conn->dir->mail_hosts, &ip);
if (host == NULL) {
/* we probably just removed this host. */
return TRUE;
struct mail_host *const *hostp;
str_printfa(str, "HOST-HAND-START\t%u\n", conn->dir->ring_handshaked);
- array_foreach(mail_hosts_get(), hostp) {
+ array_foreach(mail_hosts_get(conn->dir->mail_hosts), hostp) {
str_printfa(str, "HOST\t%s\t%u\n",
net_ip2addr(&(*hostp)->ip), (*hostp)->vhost_count);
}
/* delay adding new users until ring is again synced */
return FALSE;
}
- host = mail_host_get_by_hash(request->username_hash);
+ host = mail_host_get_by_hash(dir->mail_hosts,
+ request->username_hash);
if (host == NULL) {
/* all hosts have been removed */
return FALSE;
director_update_send(dir, src, t_strdup_printf(
"HOST-REMOVE\t%s\n", net_ip2addr(&host->ip)));
user_directory_remove_host(dir->users, host);
- mail_host_remove(host);
+ mail_host_remove(dir->mail_hosts, host);
}
void director_update_user(struct director *dir, struct director_host *src,
i_array_init(&dir->pending_requests, 16);
i_array_init(&dir->desynced_host_changes, 16);
dir->users = user_directory_init(set->director_user_expire);
+ dir->mail_hosts = mail_hosts_init();
return dir;
}
director_connection_deinit(&dir->right);
user_directory_deinit(&dir->users);
+ mail_hosts_deinit(&dir->mail_hosts);
if (dir->to_request != NULL)
timeout_remove(&dir->to_request);
array_foreach(&dir->dir_hosts, hostp)
struct director_host *self_host;
struct director_connection *left, *right;
+ struct mail_host_list *mail_hosts;
/* temporary user -> host associations */
struct user_directory *users;
struct mail_host *const *hostp;
string_t *str = t_str_new(1024);
- array_foreach(mail_hosts_get(), hostp) {
+ array_foreach(mail_hosts_get(conn->dir->mail_hosts), hostp) {
str_printfa(str, "%s\t%u\t%u\n",
net_ip2addr(&(*hostp)->ip), (*hostp)->vhost_count,
(*hostp)->user_count);
static bool
doveadm_cmd_host_set(struct doveadm_connection *conn, const char *line)
{
+ struct director *dir = conn->dir;
const char *const *args;
struct mail_host *host;
struct ip_addr ip;
o_stream_send_str(conn->output, "vhost count too large\n");
return TRUE;
}
- host = mail_host_lookup(&ip);
+ host = mail_host_lookup(dir->mail_hosts, &ip);
if (host == NULL)
- host = mail_host_add_ip(&ip);
+ host = mail_host_add_ip(dir->mail_hosts, &ip);
if (vhost_count != -1U)
- mail_host_set_vhost_count(host, vhost_count);
- director_update_host(conn->dir, conn->dir->self_host, host);
+ mail_host_set_vhost_count(dir->mail_hosts, host, vhost_count);
+ director_update_host(dir, dir->self_host, host);
o_stream_send(conn->output, "OK\n", 3);
return TRUE;
i_error("doveadm sent invalid HOST-SET parameters");
return FALSE;
}
- host = mail_host_lookup(&ip);
+ host = mail_host_lookup(conn->dir->mail_hosts, &ip);
if (host == NULL)
o_stream_send_str(conn->output, "NOTFOUND\n");
else {
#define VHOST_MULTIPLIER 100
-static ARRAY_TYPE(mail_host) hosts;
-static ARRAY_DEFINE(vhosts, struct mail_host *);
-static bool hosts_unsorted;
+struct mail_host_list {
+ ARRAY_TYPE(mail_host) hosts;
+ ARRAY_DEFINE(vhosts, struct mail_host *);
+ bool hosts_unsorted;
+};
static int
mail_host_cmp(struct mail_host *const *h1, struct mail_host *const *h2)
return net_ip_cmp(&(*h1)->ip, &(*h2)->ip);
}
-static void mail_hosts_sort(void)
+static void mail_hosts_sort(struct mail_host_list *list)
{
struct mail_host *const *hostp;
unsigned int i;
- array_sort(&hosts, mail_host_cmp);
+ array_sort(&list->hosts, mail_host_cmp);
/* rebuild vhosts */
- array_clear(&vhosts);
- array_foreach(&hosts, hostp) {
+ array_clear(&list->vhosts);
+ array_foreach(&list->hosts, hostp) {
for (i = 0; i < (*hostp)->vhost_count; i++)
- array_append(&vhosts, hostp, 1);
+ array_append(&list->vhosts, hostp, 1);
}
- hosts_unsorted = FALSE;
+ list->hosts_unsorted = FALSE;
}
-struct mail_host *mail_host_add_ip(const struct ip_addr *ip)
+struct mail_host *
+mail_host_add_ip(struct mail_host_list *list, const struct ip_addr *ip)
{
struct mail_host *host;
host = i_new(struct mail_host, 1);
host->vhost_count = VHOST_MULTIPLIER;
host->ip = *ip;
- array_append(&hosts, &host, 1);
+ array_append(&list->hosts, &host, 1);
- hosts_unsorted = TRUE;
+ list->hosts_unsorted = TRUE;
return host;
}
-static int mail_host_add(const char *host)
+static int mail_host_add(struct mail_host_list *list, const char *host)
{
struct ip_addr ip;
return -1;
}
- mail_host_add_ip(&ip);
+ mail_host_add_ip(list, &ip);
return 0;
}
-static int mail_hosts_add_range(const char *host1, const char *host2)
+static int
+mail_hosts_add_range(struct mail_host_list *list, const char *host1, const char *host2)
{
struct ip_addr ip1, ip2;
return 0;
}
-int mail_hosts_parse_and_add(const char *hosts_list)
+int mail_hosts_parse_and_add(struct mail_host_list *list,
+ const char *hosts_string)
{
int ret = 0;
T_BEGIN {
const char *const *tmp, *p;
- tmp = t_strsplit_spaces(hosts_list, " ");
+ tmp = t_strsplit_spaces(hosts_string, " ");
for (; *tmp != NULL; tmp++) {
p = strchr(*tmp, '-');
if (p == NULL) {
- if (mail_host_add(*tmp) < 0)
+ if (mail_host_add(list, *tmp) < 0)
ret = -1;
- } else if (mail_hosts_add_range(t_strdup_until(*tmp, p),
+ } else if (mail_hosts_add_range(list, t_strdup_until(*tmp, p),
p + 1) < 0)
ret = -1;
}
} T_END;
- if (array_count(&hosts) == 0) {
+ if (array_count(&list->hosts) == 0) {
if (ret < 0)
i_error("No valid servers specified");
else
return ret;
}
-void mail_host_set_vhost_count(struct mail_host *host,
- unsigned int vhost_count)
+void mail_host_set_vhost_count(struct mail_host_list *list,
+ struct mail_host *host, unsigned int vhost_count)
{
host->vhost_count = vhost_count;
- mail_hosts_sort();
+ mail_hosts_sort(list);
}
-void mail_host_remove(struct mail_host *host)
+void mail_host_remove(struct mail_host_list *list, struct mail_host *host)
{
- struct mail_host *const *h;
+ struct mail_host *const *hosts;
unsigned int i, count;
- h = array_get(&hosts, &count);
+ hosts = array_get(&list->hosts, &count);
for (i = 0; i < count; i++) {
- if (h[i] == host) {
- array_delete(&hosts, i, 1);
+ if (hosts[i] == host) {
+ array_delete(&list->hosts, i, 1);
break;
}
}
i_free(host);
- mail_hosts_sort();
+ mail_hosts_sort(list);
}
-struct mail_host *mail_host_lookup(const struct ip_addr *ip)
+struct mail_host *
+mail_host_lookup(struct mail_host_list *list, const struct ip_addr *ip)
{
struct mail_host *const *hostp;
- if (hosts_unsorted)
- mail_hosts_sort();
+ if (list->hosts_unsorted)
+ mail_hosts_sort(list);
- array_foreach(&hosts, hostp) {
+ array_foreach(&list->hosts, hostp) {
if (net_ip_compare(&(*hostp)->ip, ip))
return *hostp;
}
return NULL;
}
-struct mail_host *mail_host_get_by_hash(unsigned int hash)
+struct mail_host *
+mail_host_get_by_hash(struct mail_host_list *list, unsigned int hash)
{
- struct mail_host *const *v;
+ struct mail_host *const *vhosts;
unsigned int count;
- if (hosts_unsorted)
- mail_hosts_sort();
+ if (list->hosts_unsorted)
+ mail_hosts_sort(list);
- v = array_get(&vhosts, &count);
+ vhosts = array_get(&list->vhosts, &count);
if (count == 0)
return NULL;
- return v[hash % count];
+ return vhosts[hash % count];
}
-const ARRAY_TYPE(mail_host) *mail_hosts_get(void)
+const ARRAY_TYPE(mail_host) *mail_hosts_get(struct mail_host_list *list)
{
- if (hosts_unsorted)
- mail_hosts_sort();
- return &hosts;
+ if (list->hosts_unsorted)
+ mail_hosts_sort(list);
+ return &list->hosts;
}
-void mail_hosts_init(void)
+struct mail_host_list *mail_hosts_init(void)
{
- i_array_init(&hosts, 16);
- i_array_init(&vhosts, 16*VHOST_MULTIPLIER);
+ struct mail_host_list *list;
+
+ list = i_new(struct mail_host_list, 1);
+ i_array_init(&list->hosts, 16);
+ i_array_init(&list->vhosts, 16*VHOST_MULTIPLIER);
+ return list;
}
-void mail_hosts_deinit(void)
+void mail_hosts_deinit(struct mail_host_list **_list)
{
+ struct mail_host_list *list = *_list;
struct mail_host **hostp;
- array_foreach_modifiable(&hosts, hostp)
+ *_list = NULL;
+
+ array_foreach_modifiable(&list->hosts, hostp)
i_free(*hostp);
- array_free(&hosts);
- array_free(&vhosts);
+ array_free(&list->hosts);
+ array_free(&list->vhosts);
+ i_free(list);
}
#include "network.h"
+struct mail_host_list;
+
struct mail_host {
unsigned int user_count;
unsigned int vhost_count;
};
ARRAY_DEFINE_TYPE(mail_host, struct mail_host *);
-struct mail_host *mail_host_add_ip(const struct ip_addr *ip);
-struct mail_host *mail_host_lookup(const struct ip_addr *ip);
-struct mail_host *mail_host_get_by_hash(unsigned int hash);
-
-int mail_hosts_parse_and_add(const char *hosts_list);
-void mail_host_set_vhost_count(struct mail_host *host,
+struct mail_host *
+mail_host_add_ip(struct mail_host_list *list, const struct ip_addr *ip);
+struct mail_host *
+mail_host_lookup(struct mail_host_list *list, const struct ip_addr *ip);
+struct mail_host *
+mail_host_get_by_hash(struct mail_host_list *list, unsigned int hash);
+
+int mail_hosts_parse_and_add(struct mail_host_list *list,
+ const char *hosts_string);
+void mail_host_set_vhost_count(struct mail_host_list *list,
+ struct mail_host *host,
unsigned int vhost_count);
-void mail_host_remove(struct mail_host *host);
+void mail_host_remove(struct mail_host_list *list, struct mail_host *host);
-const ARRAY_TYPE(mail_host) *mail_hosts_get(void);
+const ARRAY_TYPE(mail_host) *mail_hosts_get(struct mail_host_list *list);
-void mail_hosts_init(void);
-void mail_hosts_deinit(void);
+struct mail_host_list *mail_hosts_init(void);
+void mail_hosts_deinit(struct mail_host_list **list);
#endif
if (!dir->ring_handshaked ||
array_count(&dir->desynced_host_changes) != 0 ||
- mail_host_get_by_hash(0) == NULL)
+ mail_host_get_by_hash(dir->mail_hosts, 0) == NULL)
return;
/* if there are any pending client requests, finish them now */
auth_socket_path = i_strconcat(set->base_dir,
"/"AUTH_SOCKET_PATH, NULL);
- mail_hosts_init();
- if (mail_hosts_parse_and_add(set->director_mail_servers) < 0)
- i_fatal("Invalid value for director_mail_servers setting");
-
listen_port = find_inet_listener_port(&listen_ip);
if (listen_port == 0 && *set->director_servers != '\0') {
i_fatal("No inet_listeners defined for director service "
director = director_init(set, &listen_ip, listen_port,
director_state_changed);
director_host_add_from_string(director, set->director_servers);
+ if (mail_hosts_parse_and_add(director->mail_hosts,
+ set->director_mail_servers) < 0)
+ i_fatal("Invalid value for director_mail_servers setting");
director_connect(director);
}
doveadm_connections_deinit();
login_connections_deinit();
auth_connections_deinit();
- mail_hosts_deinit();
i_free(auth_socket_path);
}