updates.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 5 Jul 2001 19:34:42 +0000 (19:34 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 5 Jul 2001 19:34:42 +0000 (19:34 +0000)
CHANGES
TODO
apps/silcd/idlist.c
apps/silcd/protocol.c
apps/silcd/server.c
lib/silcutil/silchashtable.h

diff --git a/CHANGES b/CHANGES
index feb120c54eeb4f0811023cf66707e9127f82c814..e3e718fc513311f4145bb569e0ad19c1c9c00128 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,23 @@
+Thu Jul  5 21:22:32 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Fixed a possible crash in silc_server_remove_clients_by_server
+         in silcd/server.c.  Fixed there also some memory leaks.
+
+       * Fixed the silc_idlist_replace_client_id.  It could replace
+         wrong key in the hash table.  Affected file silcd/idlist.c.
+
+       * Do not check whether there are global users on the channel
+         if the channel->global_users is FALSE.  Affected functions
+         silc_server_remove_from_one_channel and
+         silc_server_remove_from_channels in silcd/server.c.  Also,
+         do not check if the removed client is local as we can be
+         sure that global client was not removed from the channel
+         and checking for global users is not needed.
+
+       * The silc_server_remove_clients_by_server now re-generates
+         the channel keys correctly for those channels that had
+         clients removed from them.  Affected file silcd/server.c.
+
 Tue Jul  3 11:39:20 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Found the reason of random crashes in the server.  We weren't
diff --git a/TODO b/TODO
index 29bda11470fc2eec70384e23c209690fb2b7c057..623f541ad4c227a2753d9e3e43d3c122246030bb 100644 (file)
--- a/TODO
+++ b/TODO
@@ -56,11 +56,6 @@ TODO/bugs In SILC Client Library
 TODO/bugs In SILC Server
 ========================
 
- o When server quits and all clients of that server are removed from all
-   channels the channel keys are re-generated for all clients.  This is
-   a bug and should be done only once per channel after all clients of
-   the server has been removed.
-
  o Incomplete IPv6 support:
 
        o silc_server_get_users_on_channel does not support IPv6 based
index e973a1d6d2bd09d66191b7ba30d410caa877c5a1..abcfb9f12c34e14b5f1594019df606783ce6516d 100644 (file)
@@ -502,7 +502,7 @@ silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id,
 
   /* Remove the old entry and add a new one */
 
-  silc_idcache_del_by_id(id_list->clients, (void *)client->id);
+  silc_idcache_del_by_context(id_list->clients, client);
 
   silc_free(client->id);
   client->id = new_id;
index 76b45942c181af39f42382afa64e5c7cf8eb3920..0a720081d69db1a4275033bc40d6ebf5fd3d3e5d 100644 (file)
@@ -335,7 +335,7 @@ SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
 
   if (maj != maj2)
     status = SILC_SKE_STATUS_BAD_VERSION;
-  if (min < min2)
+  if (min > min2)
     status = SILC_SKE_STATUS_BAD_VERSION;
 
   return status;
index d1d0003cd5cb53c13355494c78bcf59bc6b176ec..8947435ee9a033e8b9189bdbfb0e93e29f50eeb6 100644 (file)
@@ -2304,16 +2304,27 @@ int silc_server_remove_clients_by_server(SilcServer server,
   uint32 clients_c = 0;
   unsigned char **argv = NULL;
   uint32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
+  SilcHashTable servers;
+  SilcChannelClientEntry chl;
+  SilcChannelEntry channel;
+  SilcHashTableList htl;
   int i;
 
   SILC_LOG_DEBUG(("Start"));
 
+  /* Allocate the hash table that holds the channels that require
+     channel key re-generation after we've removed this servers clients
+     from the channels. */
+  servers = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
+                                 NULL, NULL, TRUE);
+
   if (server_signoff) {
     idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
     argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
     argv_lens = silc_realloc(argv_lens,  sizeof(*argv_lens) * (argc + 1));
     argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
-    argv[argc] = idp->data;
+    argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
+    memcpy(argv[argc], idp->data, idp->len);
     argv_lens[argc] = idp->len;
     argv_types[argc] = argc + 1;
     argc++;
@@ -2361,6 +2372,10 @@ int silc_server_remove_clients_by_server(SilcServer server,
          silc_buffer_free(idp);
        }
 
+       silc_hash_table_list(client->channels, &htl);
+       while (silc_hash_table_get(&htl, NULL, (void *)&chl))
+         silc_hash_table_replace(servers, chl->channel, chl->channel);
+
        /* Remove the client entry */
        silc_server_remove_from_channels(server, NULL, client, FALSE, 
                                         NULL, FALSE);
@@ -2414,6 +2429,10 @@ int silc_server_remove_clients_by_server(SilcServer server,
          silc_buffer_free(idp);
        }
 
+       silc_hash_table_list(client->channels, &htl);
+       while (silc_hash_table_get(&htl, NULL, (void *)&chl))
+         silc_hash_table_replace(servers, chl->channel, chl->channel);
+
        /* Remove the client entry */
        silc_server_remove_from_channels(server, NULL, client, FALSE,
                                         NULL, FALSE);
@@ -2455,11 +2474,25 @@ int silc_server_remove_clients_by_server(SilcServer server,
 
     silc_free(clients);
     silc_buffer_free(args);
+    for (i = 0; i < argc; i++)
+      silc_free(argv[i]);
     silc_free(argv);
     silc_free(argv_lens);
     silc_free(argv_types);
   }
 
+  /* We must now re-generate the channel key for all channels that had
+     this server's client(s) on the channel. As they left the channel we
+     must re-generate the channel key. */
+  silc_hash_table_list(servers, &htl);
+  while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
+    silc_server_create_channel_key(server, channel, 0);
+    silc_server_send_channel_key(server, NULL, channel, 
+                                server->server_type == SILC_ROUTER ? 
+                                FALSE : !server->standalone);
+  }
+  silc_hash_table_free(servers);
+
   return TRUE;
 }
 
@@ -2546,9 +2579,9 @@ void silc_server_remove_from_channels(SilcServer server,
     server->stat.my_chanclients--;
 
     /* If there is no global users on the channel anymore mark the channel
-       as local channel. */
-    if (server->server_type == SILC_SERVER &&
-       !silc_server_channel_has_global(channel))
+       as local channel. Do not check if the removed client is local client. */
+    if (server->server_type == SILC_SERVER && channel->global_users && 
+       chl->client->router && !silc_server_channel_has_global(channel))
       channel->global_users = FALSE;
 
     /* If there is not at least one local user on the channel then we don't
@@ -2663,9 +2696,9 @@ int silc_server_remove_from_one_channel(SilcServer server,
   server->stat.my_chanclients--;
   
   /* If there is no global users on the channel anymore mark the channel
-     as local channel. */
-  if (server->server_type == SILC_SERVER &&
-      !silc_server_channel_has_global(channel))
+     as local channel. Do not check if the client is local client. */
+  if (server->server_type == SILC_SERVER && channel->global_users &&
+      chl->client->router && !silc_server_channel_has_global(channel))
     channel->global_users = FALSE;
 
   /* If there is not at least one local user on the channel then we don't
index 9578965b918e1b8d4c3bdb19603f64b0677705ce..fd73e7d0b5c98a0f784c66008debaa68a2465850 100644 (file)
@@ -264,7 +264,7 @@ void silc_hash_table_add(SilcHashTable ht, void *key, void *context);
  * DESCRIPTION
  *
  *    Same as silc_hash_table_add but if the `key' already exists in the
- *    hash table the old key and the old context will be replace with the
+ *    hash table the old key and the old context will be replaced with the
  *    `key' and the `context. The destructor function will be called for the
  *    replaced key and context.
  *
@@ -442,7 +442,7 @@ void silc_hash_table_add_ext(SilcHashTable ht, void *key, void *context,
  * DESCRIPTION
  *
  *    Same as silc_hash_table_add_ext but if the `key' already exists in the
- *    hash table the old key and the old context will be replace with the
+ *    hash table the old key and the old context will be replaced with the
  *    `key' and the `context. The destructor function will be called for the
  *    replaced key and context.
  *