main.c revision 6468191d64827a2d1481c091ec499874583c834e
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2010-2015 Dovecot authors, see the included COPYING file */
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenstatic ARRAY(enum director_socket_type) listener_socket_types;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainenstatic void director_refresh_proctitle_timeout(void *context ATTR_UNUSED)
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen static uint64_t prev_requests = 0, prev_input = 0, prev_output;
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen str_printfa(str, "[%u users", user_directory_count(director->users));
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)
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenlistener_get_socket_type_fallback(const struct director_settings *set,
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen if (net_getsockname(listen_fd, NULL, &local_port) == 0) {
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen /* TCP/IP connection */
6468191d64827a2d1481c091ec499874583c834eTimo Sirainenstatic void listener_sockets_init(const struct director_settings *set,
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 */
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen type = listener_get_socket_type_fallback(set, 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);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen (void)login_connection_init(director, conn->fd, auth, userdb);
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;
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainen if (!dir->ring_synced || !mail_hosts_have_usable(dir->mail_hosts))
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)
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];
6468191d64827a2d1481c091ec499874583c834eTimo Sirainen listener_sockets_init(set, &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)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct setting_parser_info *set_roots[] = {
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen const enum master_service_flags service_flags =
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int test_port = 0;
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: ");
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen /* we're testing, possibly writing to same log file.
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen make it clear which director we are. */