bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 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 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());
4dc8d682c855ca78db8874e04302e885465c1d65Timo Sirainen str_printfa(str, ", %u delayed", director->requests_delayed_count);
d3bae1f9d2448e5c398145ea250849ec12583845Timo Sirainen str_printfa(str, ", %u moving", director->users_moving_count);
5754fa860405e9af20c38981942f6aa97ce3158dTimo Sirainen str_printfa(str, ", %u kicking", director->users_kicking_count);
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen str_printfa(str, ", %"PRIu64"+%"PRIu64" req/s",
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen director->num_incoming_requests - prev_incoming_requests);
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi str_printfa(str, ", %"PRIu64"+%"PRIu64" kB/s",
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi (director->ring_traffic_input - prev_input)/1024,
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi (director->ring_traffic_output - prev_output)/1024);
dd19de9b6382c9a47b65df6b2396789df37a19fbTimo Sirainen prev_incoming_requests = director->num_incoming_requests;
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,
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)
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen master_service_client_connection_accept(conn);
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen notify_connection_init(director, conn->fd, TRUE);
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);
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen master_service_client_connection_accept(conn);
9dd8a75971a2d9e46fb0c80feddc0aaec1181defTimo Sirainen notify_connection_init(director, conn->fd, FALSE);
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)
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);
816d20be0cf95fc4eb1a8aa716639e73b8ba525eMartti Rannanjärvi restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
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. */