]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: Destroy all fd proxies at deinit.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 1 Nov 2017 20:40:58 +0000 (22:40 +0200)
committerTimo Sirainen <tss@dovecot.fi>
Mon, 6 Nov 2017 23:09:00 +0000 (01:09 +0200)
src/login-common/client-common.c
src/login-common/client-common.h
src/login-common/main.c

index 136dd7a90cabfd8cecf982bfc4f7d520ddf57753..e099d5ce1189f872149d4c5df4d2fa1a70d0b45e 100644 (file)
@@ -32,6 +32,8 @@ struct client *clients = NULL;
 static struct client *last_client = NULL;
 static unsigned int clients_count = 0;
 
+static struct client *client_fd_proxies = NULL;
+
 struct login_client_module_hooks {
        struct module *module;
        const struct login_client_hooks *hooks;
@@ -264,6 +266,10 @@ void client_destroy(struct client *client, const char *reason)
        } else {
                /* Login was successful. We may now be proxying the connection,
                   so don't disconnect the client until client_unref(). */
+               if (client->iostream_fd_proxy != NULL) {
+                       client->fd_proxying = TRUE;
+                       DLLIST_PREPEND(&client_fd_proxies, client);
+               }
        }
 
        if (client->master_tag != 0) {
@@ -346,6 +352,9 @@ bool client_unref(struct client **_client)
                ssl_proxy_free(&client->ssl_proxy);
        if (client->iostream_fd_proxy != NULL)
                iostream_proxy_unref(&client->iostream_fd_proxy);
+       if (client->fd_proxying) {
+               DLLIST_REMOVE(&client_fd_proxies, client);
+       }
        i_stream_unref(&client->input);
        o_stream_unref(&client->output);
        i_close_fd(&client->fd);
@@ -1017,6 +1026,14 @@ void client_common_init(void)
        i_array_init(&module_hooks, 32);
 }
 
+void client_destroy_fd_proxies(void)
+{
+       while (client_fd_proxies != NULL) {
+               struct client *client = client_fd_proxies;
+               client_unref(&client);
+       }
+}
+
 void client_common_deinit(void)
 {
        array_free(&module_hooks);
index 0307382ee3494e661fd31c3ff0d8f0c27d7be0be..2467f20f6c75e312810f0bd841775274f268c514 100644 (file)
@@ -127,7 +127,12 @@ struct client_vfuncs {
 };
 
 struct client {
+       /* If disconnected=FALSE, the client is in "clients" list.
+          If fd_proxying=TRUE, the client is in "client_fd_proxies" list.
+          Otherwise, either the client will soon be freed or it's only
+          referenced via "login_proxies" which doesn't use these pointers. */
        struct client *prev, *next;
+
        pool_t pool;
        /* this pool gets free'd once proxying starts */
        pool_t preproxy_pool;
@@ -218,6 +223,7 @@ struct client {
        bool auth_waiting:1;
        bool notified_auth_ready:1;
        bool notified_disconnect:1;
+       bool fd_proxying:1;
        /* ... */
 };
 
@@ -306,6 +312,7 @@ void client_destroy_oldest(void);
 void clients_destroy_all(void);
 void clients_destroy_all_reason(const char *reason);
 
+void client_destroy_fd_proxies(void);
 void client_common_init(void);
 void client_common_deinit(void);
 
index 8f1d79e91f4d12820fafcd9b950e7b2e00b1a510..2df7f3b1574ba3aab0d726f108c38b93e0197729 100644 (file)
@@ -412,6 +412,7 @@ static void main_init(const char *login_socket)
 static void main_deinit(void)
 {
        ssl_proxy_deinit();
+       client_destroy_fd_proxies();
        ssl_iostream_context_cache_free();
        login_proxy_deinit();