From 3ba9a079592f46e94ce846e5aa80e4d479cd5e41 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 26 Oct 2009 20:11:48 -0400 Subject: [PATCH] imap, pop3: Connection counting fixes. Multiple real connections can come from "login connections". For now don't even try to count login connections. --HG-- branch : HEAD --- src/imap/main.c | 3 ++- src/lib-master/master-login.c | 18 +++++++++++++++++- src/lib-master/master-login.h | 2 +- src/lib-master/master-service-private.h | 5 +++++ src/lib-master/master-service.c | 19 ++++++++++++------- src/pop3/main.c | 3 ++- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/imap/main.c b/src/imap/main.c index 507f328728..5526ad3d26 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -269,6 +269,7 @@ int main(int argc, char *argv[]) service_flags |= MASTER_SERVICE_FLAG_STANDALONE | MASTER_SERVICE_FLAG_STD_CLIENT; } else { + service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; } @@ -297,7 +298,7 @@ int main(int argc, char *argv[]) main_stdio_run(); } T_END; } else { - master_login = master_login_init("auth-master", + master_login = master_login_init(master_service, "auth-master", login_client_connected); io_loop_set_running(current_ioloop); } diff --git a/src/lib-master/master-login.c b/src/lib-master/master-login.c index f7d142a230..56138524fb 100644 --- a/src/lib-master/master-login.c +++ b/src/lib-master/master-login.c @@ -6,6 +6,7 @@ #include "fdpass.h" #include "fd-close-on-exec.h" #include "llist.h" +#include "master-service-private.h" #include "master-login.h" #include "master-login-auth.h" @@ -22,6 +23,7 @@ struct master_login_connection { }; struct master_login { + struct master_service *service; master_login_callback_t *callback; struct master_login_connection *conns; struct master_login_auth *auth; @@ -30,14 +32,16 @@ struct master_login { static void master_login_conn_deinit(struct master_login_connection **_conn); struct master_login * -master_login_init(const char *auth_socket_path, +master_login_init(struct master_service *service, const char *auth_socket_path, master_login_callback_t *callback) { struct master_login *login; login = i_new(struct master_login, 1); + login->service = service; login->callback = callback; login->auth = master_login_auth_init(auth_socket_path); + service->login_connections = TRUE; return login; } @@ -127,6 +131,8 @@ master_login_auth_callback(const char *const *auth_args, void *context) { struct master_login_client *client = context; struct master_auth_reply reply; + struct master_service *service = client->conn->login->service; + bool close_config; memset(&reply, 0, sizeof(reply)); reply.tag = client->auth_req.tag; @@ -142,8 +148,18 @@ master_login_auth_callback(const char *const *auth_args, void *context) return; } + service->master_status.available_count--; + master_status_update(service); + close_config = service->master_status.available_count == 0 && + service->service_count_left == 1; + client->conn->login->callback(client, auth_args[0], auth_args+1); i_free(client); + + if (close_config) { + /* we're dying as soon as this connection closes. */ + master_service_close_config_fd(service); + } } static void master_login_conn_input(struct master_login_connection *conn) diff --git a/src/lib-master/master-login.h b/src/lib-master/master-login.h index 74def20942..815f29666b 100644 --- a/src/lib-master/master-login.h +++ b/src/lib-master/master-login.h @@ -16,7 +16,7 @@ master_login_callback_t(const struct master_login_client *client, const char *username, const char *const *extra_fields); struct master_login * -master_login_init(const char *auth_socket_path, +master_login_init(struct master_service *service, const char *auth_socket_path, master_login_callback_t *callback); void master_login_deinit(struct master_login **login); diff --git a/src/lib-master/master-service-private.h b/src/lib-master/master-service-private.h index 1bca16959d..ff64a00d46 100644 --- a/src/lib-master/master-service-private.h +++ b/src/lib-master/master-service-private.h @@ -53,8 +53,13 @@ struct master_service { unsigned int die_with_master:1; unsigned int call_avail_overflow:1; unsigned int delay_status_updates:1; + /* incoming connections are going to master-login and they're not + counted as real connections */ + unsigned int login_connections:1; }; void master_service_io_listeners_add(struct master_service *service); +void master_status_update(struct master_service *service); +void master_service_close_config_fd(struct master_service *service); #endif diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index 4c86a89007..a64e4e978a 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -40,7 +40,6 @@ struct master_service *master_service; static void master_service_refresh_login_state(struct master_service *service); static void io_listeners_remove(struct master_service *service); -static void master_status_update(struct master_service *service); const char *master_service_getopt_string(void) { @@ -571,7 +570,7 @@ static void master_service_refresh_login_state(struct master_service *service) master_service_set_login_state(service, ret); } -static void master_service_close_config_fd(struct master_service *service) +void master_service_close_config_fd(struct master_service *service) { if (service->config_fd != -1) { if (close(service->config_fd) < 0) @@ -619,6 +618,7 @@ static void master_service_listen(struct master_service_listener *l) { struct master_service *service = l->service; struct master_service_connection conn; + bool close_config; if (service->master_status.available_count == 0) { /* we are full. stop listening for now, unless overflow @@ -660,13 +660,18 @@ static void master_service_listen(struct master_service_listener *l) conn.ssl = l->ssl; net_set_nonblock(conn.fd, TRUE); - service->master_status.available_count--; - master_status_update(service); + if (service->login_connections) + close_config = FALSE; + else { + service->master_status.available_count--; + master_status_update(service); + close_config = service->master_status.available_count == 0 && + service->service_count_left == 1; + } service->callback(&conn); - if (service->master_status.available_count == 0 && - service->service_count_left == 1) { + if (close_config) { /* we're dying as soon as this connection closes. */ master_service_close_config_fd(service); } @@ -731,7 +736,7 @@ static bool master_status_update_is_important(struct master_service *service) return FALSE; } -static void master_status_update(struct master_service *service) +void master_status_update(struct master_service *service) { ssize_t ret; diff --git a/src/pop3/main.c b/src/pop3/main.c index ef977043e2..41a32e753d 100644 --- a/src/pop3/main.c +++ b/src/pop3/main.c @@ -195,6 +195,7 @@ int main(int argc, char *argv[]) service_flags |= MASTER_SERVICE_FLAG_STANDALONE | MASTER_SERVICE_FLAG_STD_CLIENT; } else { + service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; } @@ -219,7 +220,7 @@ int main(int argc, char *argv[]) main_stdio_run(); } T_END; } else { - master_login = master_login_init("auth-master", + master_login = master_login_init(master_service, "auth-master", login_client_connected); io_loop_set_running(current_ioloop); } -- 2.47.3