From: Timo Sirainen Date: Wed, 1 Nov 2017 20:40:58 +0000 (+0200) Subject: login-common: Destroy all fd proxies at deinit. X-Git-Tag: 2.3.0.rc1~518 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a7efba62b6235e5efc124cbf702ddeb547ca3665;p=thirdparty%2Fdovecot%2Fcore.git login-common: Destroy all fd proxies at deinit. --- diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 136dd7a90c..e099d5ce11 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -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); diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 0307382ee3..2467f20f6c 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -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); diff --git a/src/login-common/main.c b/src/login-common/main.c index 8f1d79e91f..2df7f3b157 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -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();