+Fri May 18 11:18:45 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Added new function silc_idcache_del_by_context into the
+ lib/silccore/idcache.[ch].
+
+ * Changed the server's ID list routines to use the new ID Cache
+ interface. Changes around the source tree.
+
Fri May 18 08:35:31 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Added silc_hash_table_del[_by_context]_ext functions in to the
TODO/bugs In SILC Server
========================
+ o Save channel names in the ID Cache always as lowered characters,
+ though allow mixed case characters in the channel entry but the ID
+ cache does not handle loose data searching anymore.
+
o When server quits and all clients of that server are removed from all
channels the channel keys are re-generated for all clients. This is
a bug and should be done only once per channel after all clients of
new_id);
/* Remove old cache entry */
- silc_idcache_del_by_id(server->local_list->clients, SILC_ID_CLIENT,
- client->id);
+ silc_idcache_del_by_id(server->local_list->clients, client->id);
oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
/* Update client cache */
silc_idcache_add(server->local_list->clients, client->nickname,
- strlen(client->nickname), SILC_ID_CLIENT, client->id,
- (void *)client, TRUE, FALSE);
+ strlen(client->nickname), client->id,
+ (void *)client, FALSE);
nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
char *nickname, *username, *realname, *servername = NULL;
SilcClientID *client_id;
SilcClientEntry client;
- SilcIDCacheEntry cache = NULL;
char global = FALSE;
char *nick;
uint32 mode = 0, len, id_len;
/* Check if we have this client cached already. */
- client = silc_idlist_find_client_by_id(server->local_list, client_id,
- &cache);
+ client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
if (!client) {
- client = silc_idlist_find_client_by_id(server->global_list,
- client_id, &cache);
+ client = silc_idlist_find_client_by_id(server->global_list, client_id,
+ NULL);
global = TRUE;
}
client->mode = mode;
client->servername = servername;
- if (cache) {
- cache->data = nick;
- cache->data_len = strlen(nick);
- silc_idcache_sort_by_data(global ? server->global_list->clients :
- server->local_list->clients);
- }
-
+ /* Remove the old cache entry and create a new one */
+ silc_idcache_del_by_context(global ? server->global_list->clients :
+ server->local_list->clients, client);
+ silc_idcache_add(global ? server->global_list->clients :
+ server->local_list->clients, nick, strlen(nick),
+ client->id, client, FALSE);
silc_free(client_id);
}
client->username = strdup(username);
client->servername = servername;
- if (cache) {
- cache->data = nick;
- cache->data_len = strlen(nick);
- silc_idcache_sort_by_data(global ? server->global_list->clients :
- server->local_list->clients);
- }
+ /* Remove the old cache entry and create a new one */
+ silc_idcache_del_by_context(global ? server->global_list->clients :
+ server->local_list->clients, client);
+ silc_idcache_add(global ? server->global_list->clients :
+ server->local_list->clients, nick, strlen(nick),
+ client->id, client, FALSE);
}
silc_free(client_id);
char *nickname, *username;
SilcClientID *client_id;
SilcClientEntry client;
- SilcIDCacheEntry cache = NULL;
char global = FALSE;
char *nick = NULL;
/* Check if we have this client cached already. */
- client = silc_idlist_find_client_by_id(server->local_list, client_id,
- &cache);
+ client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
if (!client) {
- client = silc_idlist_find_client_by_id(server->global_list,
- client_id, &cache);
+ client = silc_idlist_find_client_by_id(server->global_list, client_id,
+ NULL);
global = TRUE;
}
client->username = strdup(username);
}
- if (nickname && cache) {
- cache->data = nick;
- cache->data_len = strlen(nick);
- silc_idcache_sort_by_data(global ? server->global_list->clients :
- server->local_list->clients);
+ /* Remove the old cache entry and create a new one */
+ if (nickname) {
+ silc_idcache_del_by_context(global ? server->global_list->clients :
+ server->local_list->clients, client);
+ silc_idcache_add(global ? server->global_list->clients :
+ server->local_list->clients, nick, strlen(nick),
+ client->id, client, FALSE);
}
-
silc_free(client_id);
}
if (!silc_idcache_add(id_list->servers, server->server_name,
server->server_name ? strlen(server->server_name) : 0,
- SILC_ID_SERVER, (void *)server->id,
- (void *)server, TRUE, FALSE)) {
+ (void *)server->id, (void *)server, FALSE)) {
silc_free(server);
return NULL;
}
SILC_LOG_DEBUG(("Server ID (%s)",
silc_id_render(id, SILC_ID_SERVER)));
- if (!silc_idcache_find_by_id_one(id_list->servers, (void *)id,
- SILC_ID_SERVER, &id_cache))
+ if (!silc_idcache_find_by_id(id_list->servers, (void *)id,
+ &id_cache))
return NULL;
server = (SilcServerEntry)id_cache->context;
SILC_LOG_DEBUG(("Server by name `%s'", name));
- if (!silc_idcache_find_by_data_one(id_list->servers, name, &id_cache))
+ if (!silc_idcache_find_by_data_one(id_list->servers, name, strlen(name),
+ &id_cache))
return NULL;
server = (SilcServerEntry)id_cache->context;
SILC_LOG_DEBUG(("Server by hostname %s and port %d", hostname, port));
- if (!silc_idcache_find_by_id(id_list->servers, SILC_ID_CACHE_ANY,
- SILC_ID_SERVER, &list))
+ if (!silc_idcache_get_all(id_list->servers, &list))
return NULL;
if (!silc_idcache_list_first(list, &id_cache)) {
SILC_LOG_DEBUG(("Replacing Server ID"));
- if (!silc_idcache_find_by_id_one(id_list->servers, (void *)old_id,
- SILC_ID_SERVER, &id_cache))
+ if (!silc_idcache_find_by_id(id_list->servers, (void *)old_id, &id_cache))
return NULL;
server = (SilcServerEntry)id_cache->context;
if (entry) {
/* Remove from cache */
if (entry->id)
- if (!silc_idcache_del_by_id(id_list->servers, SILC_ID_SERVER,
- (void *)entry->id))
+ if (!silc_idcache_del_by_id(id_list->servers, (void *)entry->id))
return FALSE;
/* Free data */
client_list);
if (!silc_idcache_add(id_list->clients, nickname, nickname_len,
- SILC_ID_CLIENT, (void *)client->id,
- (void *)client, TRUE, FALSE)) {
+ (void *)client->id, (void *)client, FALSE)) {
silc_free(client);
return NULL;
}
if (entry) {
/* Remove from cache */
if (entry->id)
- if (!silc_idcache_del_by_id(id_list->clients, SILC_ID_CLIENT,
- (void *)entry->id))
+ if (!silc_idcache_del_by_id(id_list->clients, (void *)entry->id))
return FALSE;
/* Free data */
SILC_LOG_DEBUG(("Start"));
- if (!silc_idcache_find_by_data(id_list->clients, nickname, &list))
+ if (!silc_idcache_find_by_data(id_list->clients, nickname, strlen(nickname),
+ &list))
return FALSE;
*clients = silc_realloc(*clients,
silc_hash_make(md5hash, nickname, strlen(nickname), hash);
- if (!silc_idcache_find_by_data(id_list->clients, hash, &list))
+ if (!silc_idcache_find_by_data(id_list->clients, hash,
+ md5hash->hash->hash_len, &list))
return FALSE;
*clients = silc_realloc(*clients,
SILC_LOG_DEBUG(("Client ID (%s)",
silc_id_render(id, SILC_ID_CLIENT)));
- if (!silc_idcache_find_by_id_one(id_list->clients, (void *)id,
- SILC_ID_CLIENT, &id_cache))
+ if (!silc_idcache_find_by_id(id_list->clients, (void *)id, &id_cache))
return NULL;
client = (SilcClientEntry)id_cache->context;
SILC_LOG_DEBUG(("Replacing Client ID"));
- if (!silc_idcache_find_by_id_one(id_list->clients, (void *)old_id,
- SILC_ID_CLIENT, &id_cache))
+ if (!silc_idcache_find_by_id(id_list->clients, (void *)old_id, &id_cache))
return NULL;
client = (SilcClientEntry)id_cache->context;
client->id = new_id;
id_cache->id = (void *)new_id;
+ /* XXX does not work correctly with the new ID Cache */
+
/* If the old ID Cache data was the hash value of the old Client ID
replace it with the hash of new Client ID */
if (id_cache->data && SILC_ID_COMPARE_HASH(old_id, id_cache->data)) {
silc_free(id_cache->data);
id_cache->data = silc_calloc(sizeof(new_id->hash), sizeof(unsigned char));
memcpy(id_cache->data, new_id->hash, sizeof(new_id->hash));
- silc_idcache_sort_by_data(id_list->clients);
}
SILC_LOG_DEBUG(("Replaced"));
channel_list);
if (!silc_idcache_add(id_list->channels, channel->channel_name,
- channel->channel_name ? strlen(channel->channel_name) :
- 0, SILC_ID_CHANNEL,
- (void *)channel->id, (void *)channel, TRUE, FALSE)) {
+ strlen(channel->channel_name),
+ (void *)channel->id, (void *)channel, FALSE)) {
silc_free(channel);
return NULL;
}
/* Remove from cache */
if (entry->id)
- if (!silc_idcache_del_by_id(id_list->channels, SILC_ID_CHANNEL,
- (void *)entry->id))
+ if (!silc_idcache_del_by_id(id_list->channels, (void *)entry->id))
return FALSE;
/* Free data */
SILC_LOG_DEBUG(("Channel by name"));
- if (!silc_idcache_find_by_data_loose(id_list->channels, name, &list))
+ if (!silc_idcache_find_by_data(id_list->channels, name, strlen(name), &list))
return NULL;
if (!silc_idcache_list_first(list, &id_cache)) {
SILC_LOG_DEBUG(("Channel ID (%s)",
silc_id_render(id, SILC_ID_CHANNEL)));
- if (!silc_idcache_find_by_id_one(id_list->channels, (void *)id,
- SILC_ID_CHANNEL, &id_cache))
+ if (!silc_idcache_find_by_id(id_list->channels, (void *)id, &id_cache))
return NULL;
channel = (SilcChannelEntry)id_cache->context;
SILC_LOG_DEBUG(("Replacing Channel ID"));
- if (!silc_idcache_find_by_id_one(id_list->channels, (void *)old_id,
- SILC_ID_CHANNEL, &id_cache))
+ if (!silc_idcache_find_by_id(id_list->channels, (void *)old_id, &id_cache))
return NULL;
channel = (SilcChannelEntry)id_cache->context;
{
SilcIDCacheList list = NULL;
SilcIDCacheEntry id_cache = NULL;
- SilcChannelEntry *channels;
- int i;
+ SilcChannelEntry *channels = NULL;
+ int i = 0;
SILC_LOG_DEBUG(("Start"));
- if (!silc_idcache_find_by_id(id_list->channels, channel_id ? channel_id :
- SILC_ID_CACHE_ANY, SILC_ID_CHANNEL, &list))
- return NULL;
+ if (!channel_id) {
+ if (!silc_idcache_get_all(id_list->channels, &list))
+ return NULL;
- channels = silc_calloc(silc_idcache_list_count(list), sizeof(*channels));
+ channels = silc_calloc(silc_idcache_list_count(list), sizeof(*channels));
+
+ i = 0;
+ silc_idcache_list_first(list, &id_cache);
+ channels[i++] = (SilcChannelEntry)id_cache->context;
+
+ while (silc_idcache_list_next(list, &id_cache))
+ channels[i++] = (SilcChannelEntry)id_cache->context;
+
+ silc_idcache_list_free(list);
+ } else {
+ if (!silc_idcache_find_by_id(id_list->channels, channel_id, &id_cache))
+ return NULL;
- i = 0;
- silc_idcache_list_first(list, &id_cache);
- channels[i++] = (SilcChannelEntry)id_cache->context;
+ i = 1;
+ channels = silc_calloc(1, sizeof(*channels));
+ channels[0] = (SilcChannelEntry)id_cache->context;
+ }
- while (silc_idcache_list_next(list, &id_cache))
- channels[i++] = (SilcChannelEntry)id_cache->context;
-
- silc_idcache_list_free(list);
-
if (channels_count)
*channels_count = i;
{
SilcBuffer buffer = packet->buffer;
SilcClientEntry client;
- SilcIDCacheEntry cache;
SilcClientID *client_id;
SilcBuffer reply;
SilcIDListData idata;
client = (SilcClientEntry)sock->user_data;
idata = (SilcIDListData)client;
- /* Fetch the old client cache entry so that we can update it. */
- if (!silc_idcache_find_by_context(server->local_list->clients,
- sock->user_data, &cache)) {
- SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
- silc_server_disconnect_remote(server, sock, "Server closed connection: "
- "Unknown client");
- return NULL;
- }
+ /* Remove the old cache entry */
+ silc_idcache_del_by_context(server->local_list->clients, client);
/* Parse incoming packet */
ret = silc_buffer_unformat(buffer,
client->id = client_id;
id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
- /* Update the cache entry */
- cache->id = (void *)client_id;
- cache->type = SILC_ID_CLIENT;
- cache->data = username;
- cache->data_len = strlen(username);
- silc_idcache_sort_by_data(server->local_list->clients);
+ /* Add the client again to the ID cache */
+ silc_idcache_add(server->local_list->clients, client->nickname,
+ strlen(client->nickname), client_id, client, FALSE);
/* Notify our router about new client on the SILC network */
if (!server->standalone)
{
SilcBuffer buffer = packet->buffer;
SilcServerEntry new_server;
- SilcIDCacheEntry cache;
SilcServerID *server_id;
SilcIDListData idata;
unsigned char *server_name, *id_string;
new_server = (SilcServerEntry)sock->user_data;
idata = (SilcIDListData)new_server;
- /* Fetch the old server cache entry so that we can update it. */
- if (!silc_idcache_find_by_context(server->local_list->servers,
- sock->user_data, &cache)) {
- SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
- return NULL;
- }
+ /* Remove the old cache entry */
+ silc_idcache_del_by_context(server->local_list->servers, new_server);
/* Parse the incoming packet */
ret = silc_buffer_unformat(buffer,
}
silc_free(id_string);
- /* Update client entry */
+ /* Update server entry */
idata->registered = TRUE;
new_server->server_name = server_name;
new_server->id = server_id;
- /* Update the cache entry */
- cache->id = (void *)server_id;
- cache->type = SILC_ID_SERVER;
- cache->data = server_name;
- cache->data_len = strlen(server_name);
- silc_idcache_sort_by_data(server->local_list->servers);
+ /* Add again the entry to the ID cache. */
+ silc_idcache_add(server->local_list->servers, server_name,
+ strlen(server_name), server_id, server, FALSE);
/* Distribute the information about new server in the SILC network
to our router. If we are normal server we won't send anything
/* Initialize ID caches */
server->local_list->clients =
- silc_idcache_alloc(0, silc_idlist_client_destructor);
- server->local_list->servers = silc_idcache_alloc(0, NULL);
- server->local_list->channels = silc_idcache_alloc(0, NULL);
+ silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
+ server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
+ server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
/* These are allocated for normal server as well as these hold some
global information that the server has fetched from its router. For
router these are used as they are supposed to be used on router. */
server->global_list->clients =
- silc_idcache_alloc(0, silc_idlist_client_destructor);
- server->global_list->servers = silc_idcache_alloc(0, NULL);
- server->global_list->channels = silc_idcache_alloc(0, NULL);
+ silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
+ server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
+ server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
/* Allocate the entire socket list that is used in server. Eventually
all connections will have entry in this table (it is a table of
silc_buffer_free(idp);
}
- if (silc_idcache_find_by_id(server->local_list->clients,
- SILC_ID_CACHE_ANY, SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(server->local_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
silc_idcache_list_free(list);
}
- if (silc_idcache_find_by_id(server->global_list->clients,
- SILC_ID_CACHE_ANY, SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(server->global_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
SilcBuffer idp;
/* Go through all clients in the list */
- if (silc_idcache_find_by_id(id_list->servers, SILC_ID_CACHE_ANY,
- SILC_ID_SERVER, &list)) {
+ if (silc_idcache_get_all(id_list->servers, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
entry = (SilcServerEntry)id_cache->context;
SilcBuffer idp;
/* Go through all clients in the list */
- if (silc_idcache_find_by_id(id_list->clients, SILC_ID_CACHE_ANY,
- SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(id_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
SILC_LOG_DEBUG(("Start"));
/* Go through all channels in the list */
- if (silc_idcache_find_by_id(id_list->channels, SILC_ID_CACHE_ANY,
- SILC_ID_CHANNEL, &list)) {
+ if (silc_idcache_get_all(id_list->channels, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
channel = (SilcChannelEntry)id_cache->context;
return silc_idcache_del(cache, c);
}
+/* Deletes ID cache entry by context. */
+
+bool silc_idcache_del_by_context(SilcIDCache cache, void *context)
+{
+ SilcIDCacheEntry c;
+
+ if (!silc_hash_table_find(cache->context_table, context, NULL, (void *)&c))
+ return FALSE;
+
+ return silc_idcache_del(cache, c);
+}
+
/* Deletes all ID entries from cache. Free's memory as well. */
bool silc_idcache_del_all(SilcIDCache cache)
uint32 data_len, void *id, void *context, int expire);
bool silc_idcache_del(SilcIDCache cache, SilcIDCacheEntry old);
bool silc_idcache_del_by_id(SilcIDCache cache, void *id);
+bool silc_idcache_del_by_context(SilcIDCache cache, void *context);
bool silc_idcache_del_all(SilcIDCache cache);
bool silc_idcache_purge(SilcIDCache cache);
bool silc_idcache_purge_by_context(SilcIDCache cache, void *context);