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;
} 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) {
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);
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);
};
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;
bool auth_waiting:1;
bool notified_auth_ready:1;
bool notified_disconnect:1;
+ bool fd_proxying:1;
/* ... */
};
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);