client->connection = NULL;
silc_server_close_connection(server, sock);
+ /* Mark the client as locally detached. */
+ client->local_detached = TRUE;
+
/*
* Decrement the user count; we'll increment it if the user resumes on our
* server.
this command identifier and handle the process after the resolving
is over.
+ SilcClientEntry resuming_client
+
+ unsigned locally_detached : 1
+
+ Set to indicate that the client is locally owned but detached for
+ purposes of tracking user counts.
+
*/
struct SilcClientEntryStruct {
/* Generic data structure. DO NOT add anything before this! */
/* we need this so nobody can resume more than once at the same time -
* server crashes, really odd behaviour, ... */
SilcClientEntry resuming_client;
+
+ /* Client is locally owned but detached and not counted in the user
+ * count for local clients (server->stat.my_clients). */
+ unsigned local_detached : 1;
};
/*
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
if (SILC_IS_LOCAL(client)) {
- server->stat.my_clients--;
+ if (!client->local_detached)
+ server->stat.my_clients--;
silc_schedule_task_del_by_context(server->schedule, client);
silc_idlist_del_data(client);
client->mode = 0;
server user count as-is (incremented by the current client entry) as
we decremented the count already during detach, thus we'd be undoing
that operation. */
+ detached_client->local_detached = FALSE;
SILC_VERIFY(server->stat.clients > 0);
server->stat.clients--;
if (server->stat.cell_clients)
detached_client, &id_cache))
silc_idcache_move(server->local_list->clients,
server->global_list->clients, id_cache);
- }
+ }
+ /* We don't own this client anymore, if we ever did, as we were just
+ * told that someone else resumed it. Thus, it is most definitely no
+ * a detached client.*/
+ detached_client->local_detached = FALSE;
/* Change the owner of the client */
detached_client->router = server_entry;
}
/* Update statistics */
- server->stat.my_clients--;
+
+ /* Local detached clients aren't counted. */
+ if (!client->local_detached)
+ server->stat.my_clients--;
SILC_VERIFY(server->stat.clients > 0);
server->stat.clients--;
if (server->stat.cell_clients)
}
if (SILC_IS_LOCAL(remote_client)) {
- server->stat.my_clients--;
+ if (!remote_client->local_detached)
+ server->stat.my_clients--;
silc_schedule_task_del_by_context(server->schedule, remote_client);
}