From 1eb298744baad994b2a6cda057c9125e27729e6f Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 28 Jan 2002 22:10:36 +0000 Subject: [PATCH] updates. --- CHANGES | 11 +++++++++++ apps/silcd/command.c | 8 ++++---- apps/silcd/command_reply.c | 8 ++++++-- apps/silcd/idlist.c | 19 +++++++++++-------- apps/silcd/packet_receive.c | 21 ++++++++++++++++----- apps/silcd/packet_send.c | 8 ++++---- apps/silcd/server.c | 23 ++++++++++++----------- apps/silcd/server_util.c | 5 +---- 8 files changed, 65 insertions(+), 38 deletions(-) diff --git a/CHANGES b/CHANGES index b33b5281..5268a3c4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,14 @@ +Mon Jan 28 17:49:42 EET 2002 Pekka Riikonen + + * Fixed memory leaks in silc_server_create_new_channel* + functions. Affected file silcd/server.c. + + * Fixed the CHANNEL_CHANGE notify to re-announce the channel + which ID was changed. This way the router will send the + user list for the channel again, and server won't be in + desync in some rare circumstances. Affected file is + silcd/packet_receive.c. + Sun Jan 27 21:04:19 EET 2002 Pekka Riikonen * Check for NULL socket pointer in the function diff --git a/apps/silcd/command.c b/apps/silcd/command.c index ab4d5cd0..62ada13e 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -3859,22 +3859,22 @@ SILC_SERVER_CMD_FUNC(cmode) /* The mode is removed and we need to generate and distribute new channel key. Clients are not using private channel keys anymore after this. */ - + /* Re-generate channel key */ if (!silc_server_create_channel_key(server, channel, 0)) goto out; - + /* Send the channel key. This sends it to our local clients and if we are normal server to our router as well. */ silc_server_send_channel_key(server, NULL, channel, server->server_type == SILC_ROUTER ? FALSE : !server->standalone); - + cipher = channel->channel_key->cipher->name; hmac = (char *)silc_hmac_get_name(channel->hmac); } } - + if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) { /* User limit is set on channel */ uint32 user_limit; diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 8192b510..0b4ca602 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -823,7 +823,6 @@ SILC_SERVER_CMD_REPLY_FUNC(join) silc_buffer_pull_tail(keyp, SILC_BUFFER_END(keyp)); silc_buffer_put(keyp, tmp, len); } - id = silc_id_payload_parse_id(id_string, id_len); if (!id) goto out; @@ -873,8 +872,13 @@ SILC_SERVER_CMD_REPLY_FUNC(join) local list. */ entry = silc_idlist_find_channel_by_name(server->global_list, channel_name, &cache); - if (entry) + if (entry) { + if (entry->rekey) { + silc_schedule_task_del_by_context(server->schedule, entry->rekey); + SILC_LOG_ERROR(("global_list->channels: entry->rekey != NULL, inform Pekka now!!!")); + } silc_idlist_del_channel(server->global_list, entry); + } /* Add the channel to our local list. */ entry = silc_idlist_add_channel(server->local_list, strdup(channel_name), diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 502744eb..40b9041c 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -605,6 +605,9 @@ static void silc_idlist_del_channel_foreach(void *key, void *context, { SilcChannelClientEntry chl = (SilcChannelClientEntry)context; + SILC_LOG_DEBUG(("Removing client %s from channel %s", + chl->client->nickname, chl->channel->channel_name)); + /* Remove the context from the client's channel hash table as that table and channel's user_list hash table share this same context. */ silc_hash_table_del(chl->client->channels, chl->channel); @@ -623,6 +626,13 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry) if (!silc_idcache_del_by_id(id_list->channels, (void *)entry->id)) return FALSE; + /* Free all client entrys from the users list. The silc_hash_table_free + will free all the entries so they are not freed at the foreach + callback. */ + silc_hash_table_foreach(entry->user_list, silc_idlist_del_channel_foreach, + NULL); + silc_hash_table_free(entry->user_list); + /* Free data */ silc_free(entry->channel_name); silc_free(entry->id); @@ -639,13 +649,6 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry) silc_free(entry->hmac_name); silc_free(entry->rekey); - /* Free all client entrys from the users list. The silc_hash_table_free - will free all the entries so they are not freed at the foreach - callback. */ - silc_hash_table_foreach(entry->user_list, silc_idlist_del_channel_foreach, - NULL); - silc_hash_table_free(entry->user_list); - memset(entry, 'F', sizeof(*entry)); silc_free(entry); return TRUE; @@ -663,7 +666,7 @@ silc_idlist_find_channel_by_name(SilcIDList id_list, char *name, { SilcIDCacheEntry id_cache = NULL; - SILC_LOG_DEBUG(("Channel by name")); + SILC_LOG_DEBUG(("Channel by name %s", name)); if (!silc_idcache_find_by_name_one(id_list->channels, name, &id_cache)) return NULL; diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index e93774ae..442dd310 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -212,6 +212,8 @@ void silc_server_notify(SilcServer server, /* The channel is global now */ channel->global_users = TRUE; + SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name)); + /* JOIN the global client to the channel (local clients (if router created the channel) is joined in the pending JOIN command). */ chl = silc_calloc(1, sizeof(*chl)); @@ -638,6 +640,8 @@ void silc_server_notify(SilcServer server, break; } + SILC_LOG_DEBUG(("Changing the channel user mode")); + /* Change the mode */ chl->mode = mode; if (!(mode & SILC_CHANNEL_UMODE_CHANFO)) @@ -750,10 +754,10 @@ void silc_server_notify(SilcServer server, goto out; /* Get the channel entry */ - channel = silc_idlist_find_channel_by_id(server->global_list, + channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { - channel = silc_idlist_find_channel_by_id(server->local_list, + channel = silc_idlist_find_channel_by_id(server->global_list, channel_id, NULL); if (!channel) { silc_free(channel_id); @@ -780,9 +784,9 @@ void silc_server_notify(SilcServer server, silc_id_render(channel_id2, SILC_ID_CHANNEL))); /* Replace the Channel ID */ - if (!silc_idlist_replace_channel_id(server->global_list, channel_id, + if (!silc_idlist_replace_channel_id(server->local_list, channel_id, channel_id2)) - if (!silc_idlist_replace_channel_id(server->local_list, channel_id, + if (!silc_idlist_replace_channel_id(server->global_list, channel_id, channel_id2)) { silc_free(channel_id2); channel_id2 = NULL; @@ -790,7 +794,14 @@ void silc_server_notify(SilcServer server, if (channel_id2) { SilcBuffer users = NULL, users_modes = NULL; - + + /* Re-announce this channel which ID was changed. */ + silc_server_send_new_channel(server, sock, FALSE, channel->channel_name, + channel->id, + silc_id_get_len(channel->id, + SILC_ID_CHANNEL), + channel->mode); + /* Re-announce our clients on the channel as the ID has changed now */ silc_server_announce_get_channel_users(server, channel, &users, &users_modes); diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 5cd6168e..0860b68e 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -1654,9 +1654,8 @@ void silc_server_send_new_id(SilcServer server, } /* Send New Channel Payload to notify about newly created channel in the - SILC network. Normal server nevers sends this packet. Router uses this - to notify other routers in the network about new channel. This packet - is broadcasted. */ + SILC network. Router uses this to notify other routers in the network + about new channel. This packet is broadcasted by router. */ void silc_server_send_new_channel(SilcServer server, SilcSocketConnection sock, @@ -1686,7 +1685,8 @@ void silc_server_send_new_channel(SilcServer server, /* Send to backup routers if this is being broadcasted to primary router. */ - if (server->router && server->router->connection && + if (server->server_type == SILC_ROUTER && + server->router && server->router->connection && sock == server->router->connection && broadcast) silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0, packet->data, packet->len, FALSE, TRUE); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 8e5455ad..206f0924 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -2815,7 +2815,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, channel_name = strdup(channel_name); - /* Create the channel */ + /* Create the channel ID */ if (!silc_id_create_channel_id(server, router_id, server->rng, &channel_id)) { silc_free(channel_name); @@ -2823,6 +2823,8 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, silc_hmac_free(newhmac); return NULL; } + + /* Create the channel */ entry = silc_idlist_add_channel(server->local_list, channel_name, SILC_CHANNEL_MODE_NONE, channel_id, NULL, key, newhmac, 0); @@ -2830,6 +2832,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, silc_free(channel_name); silc_cipher_free(key); silc_hmac_free(newhmac); + silc_free(channel_id); return NULL; } @@ -2839,11 +2842,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, /* Now create the actual key material */ if (!silc_server_create_channel_key(server, entry, silc_cipher_get_key_len(key) / 8)) { - silc_free(channel_name); - silc_cipher_free(key); - silc_hmac_free(newhmac); - silc_free(entry->cipher); - silc_free(entry->hmac_name); + silc_idlist_del_channel(server->local_list, entry); return NULL; } @@ -2898,6 +2897,8 @@ silc_server_create_new_channel_with_id(SilcServer server, SILC_CHANNEL_MODE_NONE, channel_id, NULL, key, newhmac, 0); if (!entry) { + silc_cipher_free(key); + silc_hmac_free(newhmac); silc_free(channel_name); return NULL; } @@ -2905,7 +2906,7 @@ silc_server_create_new_channel_with_id(SilcServer server, /* Now create the actual key material */ if (!silc_server_create_channel_key(server, entry, silc_cipher_get_key_len(key) / 8)) { - silc_free(channel_name); + silc_idlist_del_channel(server->local_list, entry); return NULL; } @@ -3032,7 +3033,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, SILC_LOG_DEBUG(("Start")); /* Decode channel key payload */ - payload = silc_channel_key_payload_parse(key_payload->data, + payload = silc_channel_key_payload_parse(key_payload->data, key_payload->len); if (!payload) { SILC_LOG_ERROR(("Bad channel key payload received, dropped")); @@ -3055,7 +3056,8 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, if (!channel) { channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL); if (!channel) { - SILC_LOG_ERROR(("Received key for non-existent channel")); + SILC_LOG_ERROR(("Received key for non-existent channel %s", + silc_id_render(id, SILC_ID_CHANNEL))); goto out; } } @@ -3140,8 +3142,7 @@ void silc_server_perform_heartbeat(SilcSocketConnection sock, { SilcServerHBContext hb = (SilcServerHBContext)hb_context; - SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, - sock->ip)); + SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip)); /* Send the heartbeat */ silc_server_send_heartbeat(hb->server, sock); diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 88e6afa6..ad856b4a 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -734,10 +734,7 @@ bool silc_server_client_on_channel(SilcClientEntry client, 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. */ -- 2.24.0