]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: Added client_disconnect(), which allows explicitly disconnecting the...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Fri, 10 Nov 2017 16:18:28 +0000 (17:18 +0100)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 11 Dec 2017 13:44:18 +0000 (15:44 +0200)
This is sometimes needed to make sure the SSL layer is closed properly before destroying the underlying connection.

src/login-common/client-common.c
src/login-common/client-common.h

index 8e0cdb5bde125be9e323957296dcc1c6518ba4ae..7171a41e716fdd10dfc81d026ad9a3d0d30aec58 100644 (file)
@@ -228,15 +228,11 @@ void client_init(struct client *client, void **other_sets)
        login_refresh_proctitle();
 }
 
-void client_destroy(struct client *client, const char *reason)
+void client_disconnect(struct client *client, const char *reason)
 {
-       i_assert(client->create_finished);
-
-       if (client->destroyed)
+       if (client->disconnected)
                return;
-       client->destroyed = TRUE;
-
-       pool_unref(&client->preproxy_pool);
+       client->disconnected = TRUE;
 
        if (!client->login_success &&
            !client->no_extra_disconnect_reason && reason != NULL) {
@@ -248,10 +244,6 @@ void client_destroy(struct client *client, const char *reason)
        if (reason != NULL)
                client_log(client, reason);
 
-       if (last_client == client)
-               last_client = client->prev;
-       DLLIST_REMOVE(&clients, client);
-
        if (client->output != NULL)
                o_stream_uncork(client->output);
        if (!client->login_success) {
@@ -272,6 +264,23 @@ void client_destroy(struct client *client, const char *reason)
                        client_fd_proxies_count++;
                }
        }
+}
+
+void client_destroy(struct client *client, const char *reason)
+{
+       i_assert(client->create_finished);
+
+       if (client->destroyed)
+               return;
+       client->destroyed = TRUE;
+
+       client_disconnect(client, reason);
+
+       pool_unref(&client->preproxy_pool);
+
+       if (last_client == client)
+               last_client = client->prev;
+       DLLIST_REMOVE(&clients, client);
 
        if (client->master_tag != 0) {
                i_assert(client->auth_request == NULL);
index a947cef35104860a79d54e494ac0b0f376eb6f4b..f1f7c7d14a4845f36ad26eb1b5f8d900b87a9860 100644 (file)
@@ -203,6 +203,7 @@ struct client {
        unsigned int director_username_hash_cache;
 
        bool create_finished:1;
+       bool disconnected:1;
        bool destroyed:1;
        bool input_blocked:1;
        bool login_success:1;
@@ -250,6 +251,7 @@ client_alloc(int fd, pool_t pool,
             const struct login_settings *set,
             const struct master_service_ssl_settings *ssl_set);
 void client_init(struct client *client, void **other_sets);
+void client_disconnect(struct client *client, const char *reason);
 void client_destroy(struct client *client, const char *reason);
 /* Destroy the client after a successful login. Either the client fd was
    sent to the post-login process, or the connection will be proxied. */