From: Timo Sirainen Date: Mon, 3 May 2021 11:07:44 +0000 (+0300) Subject: login-common: Add client.list_type to better track which linked list client belongs to X-Git-Tag: 2.3.15~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a88734f71ddb2d2f0e90da53655f3196a01edb7d;p=thirdparty%2Fdovecot%2Fcore.git login-common: Add client.list_type to better track which linked list client belongs to Add asserts to make sure the client is always in the expected list. --- diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 1d264d9f75..272de90158 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -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); diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 2c7c6ee036..bee965a4b8 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -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 */