{
if (last_client == NULL)
last_client = client;
+ client->list_type = CLIENT_LIST_TYPE_ACTIVE;
DLLIST_PREPEND(&clients, client);
clients_count++;
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++;
}
/* 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);
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);
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;
};
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 */