From cf9d67e4a9bfee31cf3be05244555d51a3d1b9fe Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 20 May 2010 12:23:55 +0200 Subject: [PATCH] director: Code cleanup - keep mail hosts in a struct rather than in static variables. --HG-- branch : HEAD --- src/director/director-connection.c | 14 ++-- src/director/director-request.c | 3 +- src/director/director.c | 4 +- src/director/director.h | 1 + src/director/doveadm-connection.c | 13 ++-- src/director/mail-host.c | 115 ++++++++++++++++------------- src/director/mail-host.h | 27 ++++--- src/director/main.c | 10 +-- 8 files changed, 106 insertions(+), 81 deletions(-) diff --git a/src/director/director-connection.c b/src/director/director-connection.c index 8789791c3d..a416c98cf4 100644 --- a/src/director/director-connection.c +++ b/src/director/director-connection.c @@ -199,7 +199,7 @@ director_handshake_cmd_user(struct director_connection *conn, 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]); @@ -249,7 +249,7 @@ director_cmd_host_hand_start(struct director_connection *conn, 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); @@ -281,9 +281,9 @@ director_cmd_host(struct director_connection *conn, const char *const *args) 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; @@ -311,7 +311,7 @@ director_cmd_host_remove(struct director_connection *conn, 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; @@ -432,7 +432,7 @@ director_cmd_user(struct director_connection *conn, const char *const *args) 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; @@ -583,7 +583,7 @@ director_connection_send_hosts(struct director_connection *conn, string_t *str) 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); } diff --git a/src/director/director-request.c b/src/director/director-request.c index e3c92827ed..1ff32c7ddd 100644 --- a/src/director/director-request.c +++ b/src/director/director-request.c @@ -90,7 +90,8 @@ bool director_request_continue(struct director_request *request) /* 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; diff --git a/src/director/director.c b/src/director/director.c index ca0a6f22de..b9dd4251b0 100644 --- a/src/director/director.c +++ b/src/director/director.c @@ -147,7 +147,7 @@ void director_remove_host(struct director *dir, struct director_host *src, 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, @@ -190,6 +190,7 @@ director_init(const struct director_settings *set, 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; } @@ -206,6 +207,7 @@ void director_deinit(struct director **_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) diff --git a/src/director/director.h b/src/director/director.h index 65890e822f..59a5033d79 100644 --- a/src/director/director.h +++ b/src/director/director.h @@ -30,6 +30,7 @@ struct director { struct director_host *self_host; struct director_connection *left, *right; + struct mail_host_list *mail_hosts; /* temporary user -> host associations */ struct user_directory *users; diff --git a/src/director/doveadm-connection.c b/src/director/doveadm-connection.c index e1de4edec9..75fadbea0c 100644 --- a/src/director/doveadm-connection.c +++ b/src/director/doveadm-connection.c @@ -43,7 +43,7 @@ static void doveadm_cmd_host_list(struct doveadm_connection *conn) 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); @@ -68,6 +68,7 @@ static void doveadm_cmd_director_list(struct doveadm_connection *conn) 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; @@ -84,12 +85,12 @@ doveadm_cmd_host_set(struct doveadm_connection *conn, const char *line) 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; @@ -105,7 +106,7 @@ doveadm_cmd_host_remove(struct doveadm_connection *conn, const char *line) 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 { diff --git a/src/director/mail-host.c b/src/director/mail-host.c index 0cbe0f5985..521fd31401 100644 --- a/src/director/mail-host.c +++ b/src/director/mail-host.c @@ -6,9 +6,11 @@ #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) @@ -16,36 +18,37 @@ 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; @@ -54,11 +57,12 @@ static int mail_host_add(const char *host) 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; @@ -76,26 +80,27 @@ static int mail_hosts_add_range(const char *host1, const char *host2) 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 @@ -105,78 +110,88 @@ int mail_hosts_parse_and_add(const char *hosts_list) 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); } diff --git a/src/director/mail-host.h b/src/director/mail-host.h index 1ad10138a0..84395f929b 100644 --- a/src/director/mail-host.h +++ b/src/director/mail-host.h @@ -3,6 +3,8 @@ #include "network.h" +struct mail_host_list; + struct mail_host { unsigned int user_count; unsigned int vhost_count; @@ -11,18 +13,23 @@ struct mail_host { }; 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 diff --git a/src/director/main.c b/src/director/main.c index c7ad0396e2..efba776ed6 100644 --- a/src/director/main.c +++ b/src/director/main.c @@ -108,7 +108,7 @@ static void director_state_changed(struct director *dir) 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 */ @@ -133,10 +133,6 @@ static void main_init(void) 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 " @@ -146,6 +142,9 @@ static void main_init(void) 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); } @@ -158,7 +157,6 @@ static void main_deinit(void) doveadm_connections_deinit(); login_connections_deinit(); auth_connections_deinit(); - mail_hosts_deinit(); i_free(auth_socket_path); } -- 2.47.3