+Thu Jul 19 21:44:31 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added `task_max' field to the SilcClientParams to indicate
+ the maximum tasks the scheduler can handle. If set to zero,
+ default values are used. Affected file lib/silcclient/silcapi.h.
+
+ * Fixed memory leaks in silc_client_close_connection. Affected
+ file lib/silcclient/client.c.
+
+ * Added silc_client_del_client_entry to client library to free
+ all memory of given client entry. Affected file is
+ lib/silcclient/idlist.[ch].
+
+ * Added new functions silc_client_del_channel and
+ silc_client_del_server to delete channel and server entries.
+ Affected file lib/silcclient/[silcapi.h/idlist.c].
+
+ * Removed silc_client_del_client_by_id from silcapi.h.
+
+ * Fixed the INFO command to return the server's own info
+ correctly when querying by Server ID. Affected file is
+ silcd/command.c.
+
Thu Jul 19 14:47:30 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
* Removed the non-blocking settings in WIN32 code in the
interface separately or it could just remove the old client unless
it is on some channels.
- o silc_client_close_connection leaks memory. Read the XXX from code.
-
TODO/bugs In SILC Server
========================
}
}
- if ((!dest_server && !server_id) ||
+ if ((!dest_server && !server_id && !entry) || (entry &&
+ entry == server->id_entry) ||
(dest_server && !cmd->pending &&
!strncasecmp(dest_server, server->server_name, strlen(dest_server)))) {
/* Send our reply */
silc_client_protocols_register();
/* Initialize the scheduler */
- client->schedule = silc_schedule_init(200);
+ client->schedule = silc_schedule_init(client->params->task_max ?
+ client->params->task_max : 200);
if (!client->schedule)
return FALSE;
/* Free everything */
if (del && sock->user_data) {
- /* XXX Free all client entries and channel entries. */
+ /* Free all cache entries */
+ SilcIDCacheList list;
+ SilcIDCacheEntry entry;
+ bool ret;
+
+ if (silc_idcache_get_all(conn->client_cache, &list)) {
+ ret = silc_idcache_list_first(list, &entry);
+ while (ret) {
+ silc_client_del_client(client, conn, entry->context);
+ ret = silc_idcache_list_next(list, &entry);
+ }
+ silc_idcache_list_free(list);
+ }
+
+ if (silc_idcache_get_all(conn->channel_cache, &list)) {
+ ret = silc_idcache_list_first(list, &entry);
+ while (ret) {
+ silc_client_del_channel(client, conn, entry->context);
+ ret = silc_idcache_list_next(list, &entry);
+ }
+ silc_idcache_list_free(list);
+ }
+
+ if (silc_idcache_get_all(conn->server_cache, &list)) {
+ ret = silc_idcache_list_first(list, &entry);
+ while (ret) {
+ silc_client_del_server(client, conn, entry->context);
+ ret = silc_idcache_list_next(list, &entry);
+ }
+ silc_idcache_list_free(list);
+ }
/* Clear ID caches */
if (conn->client_cache)
client->ops->notify(client, conn, type, client_entry, tmp);
/* Free data */
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (client_entry->id)
- silc_free(client_entry->id);
- if (client_entry->send_key)
- silc_cipher_free(client_entry->send_key);
- if (client_entry->receive_key)
- silc_cipher_free(client_entry->receive_key);
+ silc_client_del_client_entry(client, client_entry);
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
client->ops->notify(client, conn, type, client_entry, client_entry2);
/* Free data */
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (client_entry->id)
- silc_free(client_entry->id);
- if (client_entry->send_key)
- silc_cipher_free(client_entry->send_key);
- if (client_entry->receive_key)
- silc_cipher_free(client_entry->receive_key);
- silc_free(client_entry);
+ silc_client_del_client_entry(client, client_entry);
break;
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
if (client_entry != conn->local_entry) {
/* Remove client from all channels */
silc_client_remove_from_channels(client, conn, client_entry);
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (client_entry->id)
- silc_free(client_entry->id);
- if (client_entry->send_key)
- silc_cipher_free(client_entry->send_key);
- if (client_entry->receive_key)
- silc_cipher_free(client_entry->receive_key);
- silc_free(client_entry);
+ silc_client_del_client(client, conn, client_entry);
}
break;
continue;
silc_client_remove_from_channels(client, conn, client_entry);
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (client_entry->id)
- silc_free(client_entry->id);
- if (client_entry->send_key)
- silc_cipher_free(client_entry->send_key);
- if (client_entry->receive_key)
- silc_cipher_free(client_entry->receive_key);
- silc_free(client_entry);
+ silc_client_del_client(client, conn, client_entry);
}
silc_free(clients);
if (conn->current_channel == channel)
conn->current_channel = NULL;
- silc_idcache_del_by_id(conn->channel_cache, channel->id);
- silc_free(channel->channel_name);
- silc_free(channel->id);
- silc_free(channel->key);
- silc_cipher_free(channel->channel_key);
- silc_free(channel);
+ silc_client_del_channel(cmd->client, cmd->conn, channel);
out:
silc_client_command_free(cmd);
(void *)i);
}
+/* Deletes the client entry and frees all memory. */
+
+void silc_client_del_client_entry(SilcClient client,
+ SilcClientEntry client_entry)
+{
+ silc_free(client_entry->nickname);
+ silc_free(client_entry->username);
+ silc_free(client_entry->realname);
+ silc_free(client_entry->server);
+ silc_free(client_entry->id);
+ if (client_entry->send_key)
+ silc_cipher_free(client_entry->send_key);
+ if (client_entry->receive_key)
+ silc_cipher_free(client_entry->receive_key);
+ silc_free(client_entry->key);
+ silc_free(client_entry);
+}
+
/* Removes client from the cache by the client entry. */
bool silc_client_del_client(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry)
{
- return silc_idcache_del_by_context(conn->client_cache, client_entry);
+ bool ret = silc_idcache_del_by_context(conn->client_cache, client_entry);
+ silc_client_del_client_entry(client, client_entry);
+ return ret;
}
-/* Removes client from the cache by the client ID. */
+/* Removes channel from the cache by the channel entry. */
-bool silc_client_del_client_by_id(SilcClient client,
- SilcClientConnection conn,
- SilcClientID *client_id)
+bool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
+ SilcChannelEntry channel)
{
- return silc_idcache_del_by_id_ext(conn->client_cache, (void *)client_id,
- NULL, NULL,
- silc_hash_client_id_compare, NULL);
+ bool ret = silc_idcache_del_by_context(conn->channel_cache, channel);
+ silc_free(channel->channel_name);
+ silc_free(channel->id);
+ silc_free(channel->key);
+ if (channel->channel_key)
+ silc_cipher_free(channel->channel_key);
+ if (channel->hmac)
+ silc_hmac_free(channel->hmac);
+ silc_client_del_channel_private_keys(client, conn, channel);
+ silc_free(channel);
+ return ret;
}
/* Finds entry for channel by the channel name. Returns the entry or NULL
return entry;
}
+
+/* Removes server from the cache by the server entry. */
+
+bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
+ SilcServerEntry server)
+{
+ bool ret = silc_idcache_del_by_context(conn->server_cache, server);
+ silc_free(server->server_name);
+ silc_free(server->server_info);
+ silc_free(server->server_id);
+ silc_free(server);
+ return ret;
+}
/* Prototypes. These are used only by the library. Application should not
call these directly. */
+void silc_client_del_client_entry(SilcClient client,
+ SilcClientEntry client_entry);
SilcClientEntry silc_idlist_get_client(SilcClient client,
SilcClientConnection conn,
char *nickname,
* SOURCE
*/
typedef struct {
+ /* Number of maximum tasks the client library's scheduler can handle.
+ If set to zero, the default value will be used (200). For WIN32
+ systems this should be set to 64 as it is the hard limit dictated
+ by the WIN32. */
+ int task_max;
+
/* Rekey timeout in seconds. The client will perform rekey in this
- time interval. If set to zero, default value will be used. */
+ time interval. If set to zero, the default value will be used. */
unsigned int rekey_secs;
} SilcClientParams;
/***/
bool silc_client_del_client(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry);
-/****f* silcclient/SilcClientAPI/silc_client_del_client_by_id
- *
- * SYNOPSIS
- *
- * bool silc_client_del_client_by_id(SilcClient client,
- * SilcClientConnection conn,
- * SilcClientID *client_id);
- *
- * DESCRIPTION
- *
- * Removes client from local cache by the Client ID indicated by
- * the `Client ID'. Returns TRUE if the deletion were successful.
- *
- ***/
-bool silc_client_del_client_by_id(SilcClient client,
- SilcClientConnection conn,
- SilcClientID *client_id);
-
/****f* silcclient/SilcClientAPI/SilcGetChannelCallback
*
* SYNOPSIS
SilcGetChannelCallback completion,
void *context);
+/****f* silcclient/SilcClientAPI/silc_client_del_channel
+ *
+ * SYNOPSIS
+ *
+ * bool silc_client_del_channel(SilcClient client,
+ * SilcClientConnection conn,
+ * SilcChannelEntry channel)
+ *
+ * DESCRIPTION
+ *
+ * Removes channel from local cache by the channel entry indicated by
+ * the `channel'. Returns TRUE if the deletion were successful.
+ *
+ ***/
+bool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
+ SilcChannelEntry channel);
+
/****f* silcclient/SilcClientAPI/silc_client_get_server
*
* SYNOPSIS
SilcClientConnection conn,
SilcServerID *server_id);
+/****f* silcclient/SilcClientAPI/silc_client_get_server_by_id
+ *
+ * SYNOPSIS
+ *
+ * bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
+ * SilcServerEntry server);
+ *
+ * DESCRIPTION
+ *
+ * Removes server from local cache by the server entry indicated by
+ * the `server'. Returns TRUE if the deletion were successful.
+ *
+ ***/
+bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
+ SilcServerEntry server);
/* Command management (command.c) */