}
struct client *
-client_create(int fd, bool ssl, pool_t pool,
- const struct master_service_connection *conn,
- const struct login_settings *set,
- const struct master_service_ssl_settings *ssl_set,
- void **other_sets)
+client_alloc(int fd, bool ssl, pool_t pool,
+ const struct master_service_connection *conn,
+ const struct login_settings *set,
+ const struct master_service_ssl_settings *ssl_set)
{
struct client *client;
net_ip_compare(&conn->real_remote_ip, &conn->real_local_ip);
}
client->proxy_ttl = LOGIN_PROXY_TTL;
+ return client;
+}
+void client_init(struct client *client, void **other_sets)
+{
if (last_client == NULL)
last_client = client;
DLLIST_PREPEND(&clients, client);
hook_login_client_allocated(client);
client->v.create(client, other_sets);
+ client->create_finished = TRUE;
if (auth_client_is_connected(auth_client))
client_notify_auth_ready(client);
client_set_auth_waiting(client);
login_refresh_proctitle();
- return client;
}
void client_destroy(struct client *client, const char *reason)
{
+ i_assert(client->create_finished);
+
if (client->destroyed)
return;
client->destroyed = TRUE;
if (--client->refcount > 0)
return TRUE;
+ if (!client->create_finished) {
+ pool_unref(&client->preproxy_pool);
+ pool_unref(&client->pool);
+ return FALSE;
+ }
+
i_assert(client->destroyed);
i_assert(client->login_proxy == NULL);
/* director_username_hash cached, if non-zero */
unsigned int director_username_hash_cache;
+ bool create_finished:1;
bool destroyed:1;
bool input_blocked:1;
bool login_success:1;
void login_client_hooks_remove(const struct login_client_hooks *hooks);
struct client *
-client_create(int fd, bool ssl, pool_t pool,
- const struct master_service_connection *conn,
- const struct login_settings *set,
- const struct master_service_ssl_settings *ssl_set,
- void **other_sets);
+client_alloc(int fd, bool ssl, pool_t pool,
+ const struct master_service_connection *conn,
+ const struct login_settings *set,
+ const struct master_service_ssl_settings *ssl_set);
+void client_init(struct client *client, void **other_sets);
void client_destroy(struct client *client, const char *reason);
void client_destroy_success(struct client *client, const char *reason);
&conn->remote_ip, NULL, &ssl_set, &other_sets);
if (!ssl_connections && !conn->ssl) {
- (void)client_create(conn->fd, FALSE, pool, conn,
- set, ssl_set, other_sets);
+ client = client_alloc(conn->fd, FALSE, pool, conn,
+ set, ssl_set);
+ client_init(client, other_sets);
} else {
fd_ssl = ssl_proxy_alloc(conn->fd, &conn->remote_ip, pool,
set, ssl_set, &proxy);
return;
}
- client = client_create(fd_ssl, TRUE, pool, conn,
- set, ssl_set, other_sets);
+ client = client_alloc(fd_ssl, TRUE, pool, conn,
+ set, ssl_set);
+ client_init(client, other_sets);
client->ssl_proxy = proxy;
ssl_proxy_set_client(proxy, client);
ssl_proxy_start(proxy);