]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: Add client.list_type to better track which linked list client belongs to
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 3 May 2021 11:07:44 +0000 (14:07 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 May 2021 06:19:16 +0000 (09:19 +0300)
Add asserts to make sure the client is always in the expected list.

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

index 1d264d9f75210ce12fad35efa9286d198b1f09de..272de90158c78a44dc262c8904ec1d39bcbf64aa 100644 (file)
@@ -233,6 +233,7 @@ void client_init(struct client *client, void **other_sets)
 {
        if (last_client == NULL)
                last_client = client;
+       client->list_type = CLIENT_LIST_TYPE_ACTIVE;
        DLLIST_PREPEND(&clients, client);
        clients_count++;
 
@@ -291,7 +292,9 @@ void client_disconnect(struct client *client, const char *reason,
                if (client->iostream_fd_proxy != NULL) {
                        i_assert(!client->fd_proxying);
                        client->fd_proxying = TRUE;
+                       i_assert(client->list_type == CLIENT_LIST_TYPE_DESTROYED);
                        DLLIST_REMOVE(&destroyed_clients, client);
+                       client->list_type = CLIENT_LIST_TYPE_FD_PROXY;
                        DLLIST_PREPEND(&client_fd_proxies, client);
                        client_fd_proxies_count++;
                }
@@ -311,7 +314,9 @@ void client_destroy(struct client *client, const char *reason)
        /* move to destroyed_clients linked list before it's potentially
           added to client_fd_proxies. */
        i_assert(!client->fd_proxying);
+       i_assert(client->list_type == CLIENT_LIST_TYPE_ACTIVE);
        DLLIST_REMOVE(&clients, client);
+       client->list_type = CLIENT_LIST_TYPE_DESTROYED;
        DLLIST_PREPEND(&destroyed_clients, client);
 
        client_disconnect(client, reason, !client->login_success);
@@ -408,12 +413,15 @@ bool client_unref(struct client **_client)
        ssl_iostream_destroy(&client->ssl_iostream);
        iostream_proxy_unref(&client->iostream_fd_proxy);
        if (client->fd_proxying) {
+               i_assert(client->list_type == CLIENT_LIST_TYPE_FD_PROXY);
                DLLIST_REMOVE(&client_fd_proxies, client);
                i_assert(client_fd_proxies_count > 0);
                client_fd_proxies_count--;
        } else {
+               i_assert(client->list_type == CLIENT_LIST_TYPE_DESTROYED);
                DLLIST_REMOVE(&destroyed_clients, client);
        }
+       client->list_type = CLIENT_LIST_TYPE_NONE;
        i_stream_unref(&client->input);
        o_stream_unref(&client->output);
        i_close_fd(&client->fd);
index 2c7c6ee036834b16347c94e1877b90fd9a40613d..bee965a4b88fb3dd92d8e95b771be2588d8e76b4 100644 (file)
@@ -81,6 +81,18 @@ enum client_auth_result {
        CLIENT_AUTH_RESULT_ANONYMOUS_DENIED
 };
 
+enum client_list_type {
+       CLIENT_LIST_TYPE_NONE = 0,
+       /* clients (disconnected=FALSE, fd_proxying=FALSE, destroyed=FALSE) */
+       CLIENT_LIST_TYPE_ACTIVE,
+       /* destroyed_clients (destroyed=TRUE, fd_proxying=FALSE). Either the
+          client will soon be freed or it's only referenced via
+          "login_proxies". */
+       CLIENT_LIST_TYPE_DESTROYED,
+       /* client_fd_proxies (fd_proxying=TRUE) */
+       CLIENT_LIST_TYPE_FD_PROXY,
+};
+
 struct client_auth_reply {
        const char *master_user, *reason;
        enum client_auth_fail_code fail_code;
@@ -139,11 +151,9 @@ 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;
+       /* Specifies which linked list the client is in */
+       enum client_list_type list_type;
 
        pool_t pool;
        /* this pool gets free'd once proxying starts */