/* Remove the client from all channels. The client is removed from
the channels' user list. */
silc_hash_table_list(client->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
channel = chl->channel;
/* Remove channel from client's channel list */
/* Remove client from channel's client list */
silc_hash_table_del(channel->user_list, chl->client);
+ channel->user_count--;
/* If there is no global users on the channel anymore mark the channel
as local channel. Do not check if the removed client is local client. */
channel->disabled = TRUE;
silc_hash_table_list(channel->user_list, &htl2);
- while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
+ while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
silc_hash_table_del(chl2->client->channels, channel);
silc_hash_table_del(channel->user_list, chl2->client);
+ channel->user_count--;
silc_free(chl2);
}
+ silc_hash_table_list_reset(&htl2);
continue;
}
if (!silc_hash_table_find(channels, channel, NULL, NULL))
silc_hash_table_add(channels, channel, channel);
}
+ silc_hash_table_list_reset(&htl);
silc_buffer_free(clidp);
}
SilcClientEntry client = NULL;
SilcBuffer idp;
SilcClientEntry *clients = NULL;
- uint32 clients_c = 0;
+ SilcUInt32 clients_c = 0;
unsigned char **argv = NULL;
- uint32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
+ SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
SilcHashTableList htl;
SilcChannelEntry channel;
SilcHashTable channels;
silc_buffer_free(idp);
}
- /* Remove the client entry */
- silc_server_remove_clients_channels(server, NULL, client, channels);
- client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
- id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+ /* Update statistics */
server->stat.clients--;
if (server->server_type == SILC_ROUTER)
server->stat.cell_clients--;
+ SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+ SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
+ /* Remove the client entry */
+ silc_server_remove_clients_channels(server, NULL, client, channels);
+ if (!server_signoff) {
+ client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
+ id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+ } else {
+ silc_idlist_del_client(server->local_list, client);
+ }
if (!silc_idcache_list_next(list, &id_cache))
break;
silc_buffer_free(idp);
}
- /* Remove the client entry */
- silc_server_remove_clients_channels(server, NULL, client, channels);
- client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
- id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+ /* Update statistics */
server->stat.clients--;
if (server->server_type == SILC_ROUTER)
server->stat.cell_clients--;
+ SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+ SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
+ /* Remove the client entry */
+ silc_server_remove_clients_channels(server, NULL, client, channels);
+ if (!server_signoff) {
+ client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
+ id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+ } else {
+ silc_idlist_del_client(server->global_list, client);
+ }
if (!silc_idcache_list_next(list, &id_cache))
break;
this server's client(s) on the channel. As they left the channel we
must re-generate the channel key. */
silc_hash_table_list(channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
- if (!silc_server_create_channel_key(server, channel, 0))
+ while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
+ if (!silc_server_create_channel_key(server, channel, 0)) {
+ silc_hash_table_list_reset(&htl);
+ silc_hash_table_free(channels);
return FALSE;
+ }
/* Do not send the channel key if private channel key mode is set */
if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
server->server_type == SILC_ROUTER ?
FALSE : !server->standalone);
}
+ silc_hash_table_list_reset(&htl);
silc_hash_table_free(channels);
return TRUE;
SilcHashTableList htl;
silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
- if (chl->client->router)
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
+ if (chl->client->router) {
+ silc_hash_table_list_reset(&htl);
return TRUE;
+ }
}
+ silc_hash_table_list_reset(&htl);
return FALSE;
}
SilcHashTableList htl;
silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
- if (!chl->client->router)
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
+ if (!chl->client->router) {
+ silc_hash_table_list_reset(&htl);
return TRUE;
+ }
}
+ silc_hash_table_list_reset(&htl);
return FALSE;
}
if (!client || !channel)
return FALSE;
- if (silc_hash_table_find(client->channels, channel, NULL, NULL))
- return TRUE;
-
- return FALSE;
+ return silc_hash_table_find(client->channels, channel, NULL, NULL);
}
/* Checks string for bad characters and returns TRUE if they are found. */
-bool silc_server_name_bad_chars(const char *name, uint32 name_len)
+bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
{
int i;
/* Modifies the `name' if it includes bad characters and returns new
allocated name that does not include bad characters. */
-char *silc_server_name_modify_bad(const char *name, uint32 name_len)
+char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
{
int i;
char *newname = strdup(name);
return newname;
}
+
+/* Find number of sockets by IP address indicated by `ip'. Returns 0 if
+ socket connections with the IP address does not exist. */
+
+SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
+ SilcSocketType type)
+{
+ int i, count;
+
+ for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
+ if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
+ server->sockets[i]->type == type)
+ count++;
+ }
+
+ return count;
+}
+
+/* Finds locally cached public key by the public key received in the SKE.
+ If we have it locally cached then we trust it and will use it in the
+ authentication protocol. Returns the locally cached public key or NULL
+ if we do not find the public key. */
+
+SilcPublicKey silc_server_find_public_key(SilcServer server,
+ SilcHashTable local_public_keys,
+ SilcPublicKey remote_public_key)
+{
+ SilcPublicKey cached_key;
+
+ SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
+ silc_hash_table_count(local_public_keys)));
+
+ if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
+ (void **)&cached_key, NULL,
+ silc_hash_public_key, NULL,
+ silc_hash_public_key_compare, NULL)) {
+ SILC_LOG_ERROR(("Public key not found"));
+ return NULL;
+ }
+
+ SILC_LOG_DEBUG(("Found public key"));
+
+ return cached_key;
+}
+
+/* This returns the first public key from the table of public keys. This
+ is used only in cases where single public key exists in the table and
+ we want to get a pointer to it. For public key tables that has multiple
+ keys in it the silc_server_find_public_key must be used. */
+
+SilcPublicKey silc_server_get_public_key(SilcServer server,
+ SilcHashTable local_public_keys)
+{
+ SilcPublicKey cached_key;
+ SilcHashTableList htl;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ assert(silc_hash_table_count(local_public_keys) < 2);
+
+ silc_hash_table_list(local_public_keys, &htl);
+ if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
+ return NULL;
+ silc_hash_table_list_reset(&htl);
+
+ return cached_key;
+}