updates. silc.server.0.7.8
authorPekka Riikonen <priikone@silcnet.org>
Mon, 28 Jan 2002 22:10:36 +0000 (22:10 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 28 Jan 2002 22:10:36 +0000 (22:10 +0000)
CHANGES
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/idlist.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_util.c

diff --git a/CHANGES b/CHANGES
index b33b52813d90b7dbb66920f5e695c5b6f36027e6..5268a3c49925f34c012f5c5c3107116e9ff75857 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,14 @@
+Mon Jan 28 17:49:42 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Check for NULL socket pointer in the function
index ab4d5cd080fe314c0c196812457e87c0df64a13b..62ada13ed4d422259ff453e8d02a59b1119bf01d 100644 (file)
@@ -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;
index 8192b510e43e50623b343352a3adacf422cd494d..0b4ca602d8a4105fdf7f2bf0da8c2132a16f4fff 100644 (file)
@@ -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), 
index 502744eb3e9ad2400e866b0285331dbf7db7e34d..40b9041caaafee09f3b3d36f3e64168429b7972e 100644 (file)
@@ -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;
index e93774ae51d931c0766f9961a19986e9844fd9d1..442dd310a6e4bf9f6efc56b999bee58259aac059 100644 (file)
@@ -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);
index 5cd6168e4ba4c11f72ac20bb4e45ec05e879be5d..0860b68e1ea6c357acca50d1f72e7eac19cf2742 100644 (file)
@@ -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);
index 8e5455ad2e5b6d1fc984808b426aa71e10c9af1a..206f092419d8041afdca76031d9d49abc828c4b3 100644 (file)
@@ -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);
index 88e6afa610357b01bccd8b9687d849d55a1d8a51..ad856b4af076e828ed8b1c7c14a9a561247e261e 100644 (file)
@@ -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. */