- /* Notify application. The channel entry is sent last as this notify
- is for channel but application don't know it from the arguments
- sent by server. */
- client->ops->notify(client, conn, type, client_entry, channel);
- break;
-
- case SILC_NOTIFY_TYPE_SIGNOFF:
- /*
- * Someone left SILC. We'll remove it from all channels and from cache.
- */
-
- /* Get Client ID */
- tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
- if (!tmp)
- goto out;
-
- client_id = silc_id_payload_parse_id(tmp, tmp_len);
- if (!client_id)
- goto out;
-
- /* Find Client entry */
- client_entry =
- silc_idlist_get_client_by_id(client, conn, client_id);
- if (!client_entry)
- goto out;
-
- /* Remove from all channels */
- silc_client_remove_from_channels(client, conn, client_entry);
-
- /* Remove from cache */
- silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT,
- client_entry->id);
-
- /* Get signoff message */
- tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
- if (tmp_len > 128)
- tmp = NULL;
-
- /* Notify application */
- 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);
- break;
-
- case SILC_NOTIFY_TYPE_TOPIC_SET:
- /*
- * Someone set the topic on a channel.
- */
-
- /* Get Client ID */
- tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
- if (!tmp)
- goto out;
-
- client_id = silc_id_payload_parse_id(tmp, tmp_len);
- if (!client_id)
- goto out;
-
- /* Find Client entry */
- client_entry =
- silc_idlist_get_client_by_id(client, conn, client_id);
- if (!client_entry)
- goto out;
-
- /* Get topic */
- tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
- if (!tmp)
- goto out;
-
- /* Get channel entry */
- channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
- SILC_ID_CHANNEL);
- if (!channel_id)
- goto out;
- if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
- SILC_ID_CHANNEL, &id_cache))
- break;
-
- channel = (SilcChannelEntry)id_cache->context;
-
- /* Notify application. The channel entry is sent last as this notify
- is for channel but application don't know it from the arguments
- sent by server. */
- client->ops->notify(client, conn, type, client_entry, tmp, channel);
- break;
+ /* Free ID caches */
+ if (conn->internal->client_cache)
+ silc_idcache_free(conn->internal->client_cache);
+ if (conn->internal->channel_cache)
+ silc_idcache_free(conn->internal->channel_cache);
+ if (conn->internal->server_cache)
+ silc_idcache_free(conn->internal->server_cache);
+
+ /* Free thread pool */
+ silc_list_start(conn->internal->thread_pool);
+ while ((thread = silc_list_get(conn->internal->thread_pool)))
+ silc_fsm_free(thread);
+
+ silc_free(conn->remote_host);
+ silc_buffer_free(conn->internal->local_idp);
+ silc_buffer_free(conn->internal->remote_idp);
+ silc_mutex_free(conn->internal->lock);
+ if (conn->internal->hash)
+ silc_hash_free(conn->internal->hash);
+ if (conn->internal->sha1hash)
+ silc_hash_free(conn->internal->sha1hash);
+ silc_atomic_uninit16(&conn->internal->cmd_ident);
+ silc_free(conn->internal->away_message);
+ if (conn->internal->rekey)
+ silc_ske_free_rekey_material(conn->internal->rekey);
+ if (conn->internal->cop)
+ silc_async_free(conn->internal->cop);
+
+ silc_free(conn->internal);
+ memset(conn, 'F', sizeof(*conn));
+ silc_free(conn);
+}