]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap, pop3: Connection counting fixes.
authorTimo Sirainen <tss@iki.fi>
Tue, 27 Oct 2009 00:11:48 +0000 (20:11 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 27 Oct 2009 00:11:48 +0000 (20:11 -0400)
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
src/lib-master/master-login.c
src/lib-master/master-login.h
src/lib-master/master-service-private.h
src/lib-master/master-service.c
src/pop3/main.c

index 507f328728eac70b4ea7eb4d12e345b699506d41..5526ad3d26526716eac96ccc77030051694e9702 100644 (file)
@@ -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);
        }
index f7d142a23021b98293476260cbc37782fb9a33b2..56138524fba1e7ebdd985336a02f5a58a962d786 100644 (file)
@@ -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)
index 74def20942288fb1ea8ace6cf9a8476a05b42b7f..815f29666b7420ca9fc9249cf520cc39e4b72d90 100644 (file)
@@ -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);
 
index 1bca16959d723f1d545018c9d1109746bf14572f..ff64a00d468fffe76d5f8fa34f17cd5efb2bba99 100644 (file)
@@ -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
index 4c86a89007e62e1383d70883d9c116901de61e6d..a64e4e978a61acc3d7ff902db3a2a26ec7d2e85d 100644 (file)
@@ -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;
 
index ef977043e2dab756fa71f1ceea05f80afb5137db..41a32e753de80c23f01ba64d2936f6f0fd5f778a 100644 (file)
@@ -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);
        }