main.c revision 5a444fdfabcc0c75708c21e84dc8b87eddab7335
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2010-2017 Dovecot authors, see the included COPYING file */
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenstatic ARRAY(enum director_socket_type) listener_socket_types;
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomistatic unsigned int director_total_users_count(void)
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi unsigned int count = 0;
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi array_foreach(mail_hosts_get_tags(director->mail_hosts), tagp)
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainenstatic void director_refresh_proctitle_timeout(void *context ATTR_UNUSED)
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen static uint64_t prev_requests = 0, prev_input = 0, prev_output;
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi str_printfa(str, "[%u users", director_total_users_count());
d3bae1f9d2448e5c398145ea250849ec12583845Timo Sirainen str_printfa(str, ", %u moving", director->users_moving_count);
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen (unsigned long)(director->num_requests - prev_requests));
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen (unsigned long long)(director->ring_traffic_input - prev_input)/1024,
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen (unsigned long long)(director->ring_traffic_output - prev_output)/1024);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainendirector_socket_type_get_from_name(const char *path)
973c8fc1d7e9f982f7caf6385adb78dfacd9fb80Timo Sirainen if (net_getsockname(listen_fd, NULL, &local_port) == 0 &&
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* TCP/IP connection */
c1d01419ffbeb0e00f86a653db70bfd47110e7fcTimo Sirainenstatic void listener_sockets_init(struct ip_addr *listen_ip_r,
009217abb57a24a4076092e8e4e165545747839eStephan Bosch unsigned int i, socket_count;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen socket_count = master_service_get_socket_count(master_service);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen for (i = 0; i < socket_count; i++) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen name = master_service_get_socket_name(master_service, listen_fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen type = director_socket_type_get_from_name(name);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* mainly for backwards compatibility */
5545acdd3aa90a6e0cca2b665f909ec4c2fb2513Baofeng type = listener_get_socket_type_fallback(listen_fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (type == DIRECTOR_SOCKET_TYPE_RING && *listen_port_r == 0 &&
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen net_getsockname(listen_fd, &ip, &port) == 0 && port > 0) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen array_idx_set(&listener_socket_types, listen_fd, &type);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic int director_client_connected(int fd, const struct ip_addr *ip)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_warning("Connection from %s: Server not listed in "
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "director_servers, dropping", net_ip2addr(ip));
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen (void)director_connection_init_in(director, fd, ip);
db693bf6fcae96d834567f1782257517b7207655Timo Sirainenstatic void client_connected(struct master_service_connection *conn)
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen i_error("Received another proxy-notify connection");
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen master_service_client_connection_accept(conn);
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen notify_conn = notify_connection_init(director, conn->fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen typep = array_idx(&listener_socket_types, conn->listen_fd);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* a) userdb connection, probably for lmtp proxy
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen b) login connection
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen Both of them are handled exactly the same, except for which
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen auth socket they connect to. */
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen userdb = *typep == DIRECTOR_SOCKET_TYPE_USERDB;
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen socket_path = userdb ? AUTH_USERDB_SOCKET_PATH :
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen master_service_client_connection_accept(conn);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen (void)login_connection_init(director, conn->fd, auth,
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen master_service_client_connection_accept(conn);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen (void)login_connection_init(director, conn->fd, NULL,
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (director_client_connected(conn->fd, &conn->remote_ip) == 0)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen master_service_client_connection_accept(conn);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen master_service_client_connection_accept(conn);
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen (void)doveadm_connection_init(director, conn->fd);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_state_changed(struct director *dir)
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct director_request *) new_requests;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* if there are any pending client requests, finish them now */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_foreach(&dir->pending_requests, requestp) {
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen /* a) request for a user being killed
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen b) user is weak */
2efe19d9045768d985a3bd549cff12f65ba40cc8Timo Sirainen array_append_array(&dir->pending_requests, &new_requests);
5b4d189a01d248458496068f838128f1bafdcf2eTimo Sirainen if (dir->to_request != NULL && array_count(&new_requests) == 0)
7ee226c2a66aa4dce7f13e8b17687db285c981bdTimo Sirainenstatic void main_preinit(void)
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen /* make sure we die with master even with shutdown_clients=no.
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen otherwise there will be two director processes and everything is
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen broken. it's only the login processes that need to stay alive. */
958e5ae51a755558b6d022a39b194614726b4225Timo Sirainen master_service_set_die_with_master(master_service, TRUE);
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen if (master_service_settings_get(master_service)->verbose_proctitle) {
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen timeout_add(1000, director_refresh_proctitle_timeout,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen set = master_service_settings_get_others(master_service)[0];
c1d01419ffbeb0e00f86a653db70bfd47110e7fcTimo Sirainen listener_sockets_init(&listen_ip, &listen_port);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (listen_port == 0 && *set->director_servers != '\0') {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("No inet_listeners defined for director service "
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "(for standalone keep director_servers empty)");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director = director_init(set, &listen_ip, listen_port,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_host_add_from_string(director, set->director_servers);
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen if (mail_hosts_parse_and_add(director->mail_hosts,
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen i_fatal("Invalid value for director_mail_servers setting");
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen director->orig_config_hosts = mail_hosts_dup(director->mail_hosts);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void main_deinit(void)
faa01447c2f699b63ceccf129430a9ed46458083Timo Sirainen /* deinit doveadm connections before director, so it can clean up
faa01447c2f699b63ceccf129430a9ed46458083Timo Sirainen its pending work, such as abort user moves. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct setting_parser_info *set_roots[] = {
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen const enum master_service_flags service_flags =
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen master_service = master_service_init("director", service_flags,
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen while ((c = master_getopt(master_service)) > 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (master_service_settings_read_simple(master_service, set_roots,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("Error reading configuration: %s", error);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen master_service_init_log(master_service, "director: ");
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainen director_connect(director, "Initial connection");
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen /* we're testing, possibly writing to same log file.
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen make it clear which director we are. */