From: Pekka Riikonen Date: Wed, 24 Sep 2008 15:18:30 +0000 (+0300) Subject: Merge branch 'topic/mm-fixes' of git://208.110.73.182/silc into silc.1.1.branch X-Git-Tag: silc.server.1.1.13 X-Git-Url: http://git.silc.fi/gitweb/?p=silc.git;a=commitdiff_plain;h=e9374395ec9747bddd3ea0bfd3e5a17717e97b31 Merge branch 'topic/mm-fixes' of git://208.110.73.182/silc into silc.1.1.branch Signed-off-by: Pekka Riikonen --- e9374395ec9747bddd3ea0bfd3e5a17717e97b31 diff --cc lib/silcclient/client.h index ac1116d2,ebe41fe9..d66808dc --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@@ -53,14 -53,16 +53,17 @@@ typedef struct SilcClientEntryInternalS SilcUInt32 key_len; /* Key data length */ SilcClientKeyAgreement ke; /* Current key agreement context or NULL */ ++ SilcAtomic32 refcnt; /* Reference counter */ ++ SilcAtomic32 deleted; /* Flag indicating whether the client object is ++ already scheduled for deletion */ ++ SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */ ++ /* Flags */ unsigned int valid : 1; /* FALSE if this entry is not valid. Entry without nickname is not valid. */ unsigned int generated : 1; /* TRUE if library generated `key' */ unsigned int prv_resp : 1; /* TRUE if we are responder when using private message keys. */ -- SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */ - SilcAtomic8 refcnt; /* Reference counter */ - SilcAtomic32 refcnt; /* Reference counter */ - SilcAtomic32 deleted; /* Flag indicating whether the client object is - already scheduled for deletion.*/ } SilcClientEntryInternal; /* Internal channel entry context */ @@@ -81,13 -83,15 +84,16 @@@ typedef struct SilcChannelEntryInternal SilcHmac hmac; /* Current HMAC */ unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */ ++ SilcAtomic32 refcnt; /* Reference counter */ ++ SilcAtomic32 deleted; /* Flag indicating whether the ++ channel object is already ++ scheduled for deletion */ SilcUInt16 resolve_cmd_ident; /* Channel information resolving identifier. This is used when resolving users, and other stuff that relates to the channel. Not used for the channel resolving itself. */ - SilcAtomic16 refcnt; /* Reference counter */ - SilcAtomic32 refcnt; /* Reference counter */ - SilcAtomic32 deleted; /* Flag indicating whether the channel object is - already scheduled for deletion.*/ } SilcChannelEntryInternal; /* Internal server entry context */ diff --cc lib/silcclient/client_entry.c index 0933c3d4,bdcdd1ca..4664dbaa --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@@ -1008,27 -1010,16 +1010,15 @@@ SilcBool silc_client_del_client(SilcCli if (!client_entry) return FALSE; - if (silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) > 0) - return FALSE; - - SILC_LOG_DEBUG(("Deleting client %p", client_entry)); - - silc_mutex_lock(conn->internal->lock); - ret = silc_idcache_del_by_context(conn->internal->client_cache, - client_entry, NULL); - silc_mutex_unlock(conn->internal->lock); - - if (ret) { - /* Remove from channels */ - silc_client_remove_from_channels(client, conn, client_entry); - if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) - { - SILC_LOG_DEBUG(("** WARNING ** Deleting a client twice %p", client_entry)); -// asm("int3"); - return FALSE; ++ SILC_LOG_DEBUG(("Marking client entry %p deleted")); + - /* Free the client entry data */ - silc_client_del_client_entry(client, conn, client_entry); ++ if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) { ++ SILC_LOG_DEBUG(("Client entry %p already marked deleted")); ++ return FALSE; } - return ret; + silc_client_unref_client(client, conn, client_entry); + return TRUE; - } /* Internal routine used to find client by ID and if not found this creates @@@ -1084,11 -1075,31 +1074,32 @@@ SilcClientEntry silc_client_ref_client( void silc_client_unref_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { -- if (client_entry) { - SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, - silc_atomic_get_int8(&client_entry->internal.refcnt), - silc_atomic_get_int8(&client_entry->internal.refcnt) - 1)); - silc_client_del_client(client, conn, client_entry); - SilcBool ret; ++ SilcBool ret; + - SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, - silc_atomic_get_int32(&client_entry->internal.refcnt), - silc_atomic_get_int32(&client_entry->internal.refcnt) - 1)); ++ if (!client_entry) ++ return; + - if (silc_atomic_sub_int32(&client_entry->internal.refcnt, 1) > 0) - return; - - SILC_LOG_DEBUG(("Deleting client %p (%d)", client_entry, - silc_atomic_get_int32(&client_entry->internal.deleted))); ++ SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, ++ silc_atomic_get_int32(&client_entry->internal.refcnt), ++ silc_atomic_get_int32(&client_entry->internal.refcnt) - 1)); + - silc_mutex_lock(conn->internal->lock); - ret = silc_idcache_del_by_context(conn->internal->client_cache, - client_entry, NULL); - silc_mutex_unlock(conn->internal->lock); ++ if (silc_atomic_sub_int32(&client_entry->internal.refcnt, 1) > 0) ++ return; + - if (ret) { - /* Remove from channels */ - silc_client_remove_from_channels(client, conn, client_entry); ++ SILC_LOG_DEBUG(("Deleting client %p (%d)", client_entry, ++ silc_atomic_get_int32(&client_entry->internal.deleted))); + - /* Free the client entry data */ - silc_client_del_client_entry(client, conn, client_entry); - } ++ silc_mutex_lock(conn->internal->lock); ++ ret = silc_idcache_del_by_context(conn->internal->client_cache, ++ client_entry, NULL); ++ silc_mutex_unlock(conn->internal->lock); ++ ++ if (ret) { ++ /* Remove from channels */ ++ silc_client_remove_from_channels(client, conn, client_entry); ++ ++ /* Free the client entry data */ ++ silc_client_del_client_entry(client, conn, client_entry); } } @@@ -1697,64 -1709,15 +1709,15 @@@ SilcBool silc_client_del_channel(SilcCl if (!channel) return FALSE; - if (silc_atomic_sub_int16(&channel->internal.refcnt, 1) > 0) - return FALSE; - - SILC_LOG_DEBUG(("Deleting channel %p", channel)); - if (silc_atomic_sub_int32(&channel->internal.deleted, 1) > 0) - { - SILC_LOG_DEBUG(("** WARNING ** Deleting a channel twice %p", channel)); -// asm("int3"); ++ SILC_LOG_DEBUG(("Marking channel entry %p deleted")); + - silc_mutex_lock(conn->internal->lock); - if (silc_idcache_find_by_context(conn->internal->channel_cache, channel, - &id_cache)) { - namec = id_cache->name; - ret = silc_idcache_del_by_context(conn->internal->channel_cache, - channel, NULL); - silc_free(namec); - } - silc_mutex_unlock(conn->internal->lock); - - if (!ret) ++ if (silc_atomic_sub_int32(&channel->internal.deleted, 1) != 0) { ++ SILC_LOG_DEBUG(("Channel entry %p already marked deleted")); return FALSE; - - silc_client_empty_channel(client, conn, channel); - silc_client_del_channel_private_keys(client, conn, channel); - silc_hash_table_free(channel->user_list); - silc_free(channel->channel_name); - silc_free(channel->topic); - if (channel->founder_key) - silc_pkcs_public_key_free(channel->founder_key); - if (channel->internal.send_key) - silc_cipher_free(channel->internal.send_key); - if (channel->internal.receive_key) - silc_cipher_free(channel->internal.receive_key); - if (channel->internal.hmac) - silc_hmac_free(channel->internal.hmac); - if (channel->internal.old_channel_keys) { - silc_dlist_start(channel->internal.old_channel_keys); - while ((key = silc_dlist_get(channel->internal.old_channel_keys))) - silc_cipher_free(key); - silc_dlist_uninit(channel->internal.old_channel_keys); } - if (channel->internal.old_hmacs) { - silc_dlist_start(channel->internal.old_hmacs); - while ((hmac = silc_dlist_get(channel->internal.old_hmacs))) - silc_hmac_free(hmac); - silc_dlist_uninit(channel->internal.old_hmacs); - } - if (channel->channel_pubkeys) - silc_argument_list_free(channel->channel_pubkeys, - SILC_ARGUMENT_PUBLIC_KEY); - silc_atomic_uninit16(&channel->internal.refcnt); - silc_rwlock_free(channel->internal.lock); - silc_schedule_task_del_by_context(conn->client->schedule, channel); - silc_free(channel); - return ret; + silc_client_unref_channel(client, conn, channel); + return TRUE; } /* Replaces the channel ID of the `channel' to `new_id'. Returns FALSE @@@ -1818,13 -1781,70 +1781,71 @@@ SilcChannelEntry silc_client_ref_channe void silc_client_unref_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel_entry) { -- if (channel_entry) { - SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, - silc_atomic_get_int16(&channel_entry->internal.refcnt), - silc_atomic_get_int16(&channel_entry->internal.refcnt) - - 1)); - silc_client_del_channel(client, conn, channel_entry); - SilcIDCacheEntry id_cache; - SilcBool ret = TRUE; - SilcCipher key; - SilcHmac hmac; - char *namec; ++ SilcIDCacheEntry id_cache; ++ SilcBool ret = TRUE; ++ SilcCipher key; ++ SilcHmac hmac; ++ char *namec; + - SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, - silc_atomic_get_int32(&channel_entry->internal.refcnt), - silc_atomic_get_int32(&channel_entry->internal.refcnt) - - 1)); ++ if (!channel_entry) ++ return; + - if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0) - return; ++ SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, ++ silc_atomic_get_int32(&channel_entry->internal.refcnt), ++ silc_atomic_get_int32(&channel_entry->internal.refcnt) ++ - 1)); + - SILC_LOG_DEBUG(("Deleting channel %p", channel_entry)); ++ if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0) ++ return; + - silc_mutex_lock(conn->internal->lock); - if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry, ++ SILC_LOG_DEBUG(("Deleting channel %p", channel_entry)); ++ ++ silc_mutex_lock(conn->internal->lock); ++ if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry, + &id_cache)) { - namec = id_cache->name; - ret = silc_idcache_del_by_context(conn->internal->channel_cache, ++ namec = id_cache->name; ++ ret = silc_idcache_del_by_context(conn->internal->channel_cache, + channel_entry, NULL); - silc_free(namec); - } - silc_mutex_unlock(conn->internal->lock); ++ silc_free(namec); + } ++ silc_mutex_unlock(conn->internal->lock); + - if (!ret) - return; ++ if (!ret) ++ return; + - silc_client_empty_channel(client, conn, channel_entry); - silc_client_del_channel_private_keys(client, conn, channel_entry); - silc_hash_table_free(channel_entry->user_list); - silc_free(channel_entry->channel_name); - silc_free(channel_entry->topic); - if (channel_entry->founder_key) - silc_pkcs_public_key_free(channel_entry->founder_key); - if (channel_entry->internal.send_key) - silc_cipher_free(channel_entry->internal.send_key); - if (channel_entry->internal.receive_key) - silc_cipher_free(channel_entry->internal.receive_key); - if (channel_entry->internal.hmac) - silc_hmac_free(channel_entry->internal.hmac); - if (channel_entry->internal.old_channel_keys) { - silc_dlist_start(channel_entry->internal.old_channel_keys); - while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys))) - silc_cipher_free(key); - silc_dlist_uninit(channel_entry->internal.old_channel_keys); - } - if (channel_entry->internal.old_hmacs) { - silc_dlist_start(channel_entry->internal.old_hmacs); - while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs))) - silc_hmac_free(hmac); - silc_dlist_uninit(channel_entry->internal.old_hmacs); - } - if (channel_entry->channel_pubkeys) - silc_argument_list_free(channel_entry->channel_pubkeys, ++ silc_client_empty_channel(client, conn, channel_entry); ++ silc_client_del_channel_private_keys(client, conn, channel_entry); ++ silc_hash_table_free(channel_entry->user_list); ++ silc_free(channel_entry->channel_name); ++ silc_free(channel_entry->topic); ++ if (channel_entry->founder_key) ++ silc_pkcs_public_key_free(channel_entry->founder_key); ++ if (channel_entry->internal.send_key) ++ silc_cipher_free(channel_entry->internal.send_key); ++ if (channel_entry->internal.receive_key) ++ silc_cipher_free(channel_entry->internal.receive_key); ++ if (channel_entry->internal.hmac) ++ silc_hmac_free(channel_entry->internal.hmac); ++ if (channel_entry->internal.old_channel_keys) { ++ silc_dlist_start(channel_entry->internal.old_channel_keys); ++ while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys))) ++ silc_cipher_free(key); ++ silc_dlist_uninit(channel_entry->internal.old_channel_keys); ++ } ++ if (channel_entry->internal.old_hmacs) { ++ silc_dlist_start(channel_entry->internal.old_hmacs); ++ while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs))) ++ silc_hmac_free(hmac); ++ silc_dlist_uninit(channel_entry->internal.old_hmacs); ++ } ++ if (channel_entry->channel_pubkeys) ++ silc_argument_list_free(channel_entry->channel_pubkeys, + SILC_ARGUMENT_PUBLIC_KEY); - silc_atomic_uninit32(&channel_entry->internal.deleted); - silc_atomic_uninit32(&channel_entry->internal.refcnt); - silc_rwlock_free(channel_entry->internal.lock); - silc_schedule_task_del_by_context(conn->client->schedule, channel_entry); - silc_free(channel_entry); - } ++ silc_atomic_uninit32(&channel_entry->internal.deleted); ++ silc_atomic_uninit32(&channel_entry->internal.refcnt); ++ silc_rwlock_free(channel_entry->internal.lock); ++ silc_schedule_task_del_by_context(conn->client->schedule, channel_entry); ++ silc_free(channel_entry); } /* Free channel entry list */ diff --cc lib/silccore/silcpacket.c index 2c01e6dd,85d8b4e6..f552ca6d --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@@ -1323,6 -1324,6 +1324,7 @@@ SilcBool silc_packet_set_ids(SilcPacket { SilcUInt32 len; unsigned char tmp[32]; ++ void *tmp_id; if (!src_id && !dst_id) return FALSE; @@@ -1332,16 -1333,17 +1334,17 @@@ if (src_id) { SILC_LOG_DEBUG(("Setting source ID to packet stream %p", stream)); -- silc_free(stream->src_id); - stream->src_id = NULL; if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) { silc_mutex_unlock(stream->lock); return FALSE; } -- stream->src_id = silc_memdup(tmp, len); -- if (!stream->src_id) { ++ tmp_id = silc_memdup(tmp, len); ++ if (!tmp_id) { silc_mutex_unlock(stream->lock); return FALSE; } ++ silc_free(stream->src_id); ++ stream->src_id = tmp_id; stream->src_id_type = src_id_type; stream->src_id_len = len; } @@@ -1349,16 -1351,17 +1352,17 @@@ if (dst_id) { SILC_LOG_DEBUG(("Setting destination ID to packet stream %p", stream)); -- silc_free(stream->dst_id); - stream->dst_id = NULL; if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) { silc_mutex_unlock(stream->lock); return FALSE; } -- stream->dst_id = silc_memdup(tmp, len); -- if (!stream->dst_id) { ++ tmp_id = silc_memdup(tmp, len); ++ if (!tmp_id) { silc_mutex_unlock(stream->lock); return FALSE; } ++ silc_free(stream->dst_id); ++ stream->dst_id = tmp_id; stream->dst_id_type = dst_id_type; stream->dst_id_len = len; }