Updates.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 28 Jan 2001 21:44:10 +0000 (21:44 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 28 Jan 2001 21:44:10 +0000 (21:44 +0000)
13 files changed:
CHANGES
TODO
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/command_reply.h
apps/silcd/idlist.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server.h
doc/draft-riikonen-silc-pp-01.nroff
lib/silcclient/command.c
lib/silcclient/idlist.c

diff --git a/CHANGES b/CHANGES
index db4eb1551f616cee31d51a40dfa85496e59c9cf2..e2e5fb620f89db6133810f00a9a1ef9e55ba9925 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,52 @@
+Sun Jan 28 16:19:49 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Fixed JOIN command on client library.  Wrong number of arguments
+         used to crash the client.
+
+       * Added silc_server_channel_has_global function to check whether
+         channel has global users or not.
+
+       * Added silc_server_channel_has_local function to check whether channel
+         has locally connected clients on the channel.
+
+       * The silc_server_remove_from_one_channel now checks whether the
+         channel has global users or not after given client was removed from
+         the channel.  It also checks whether the channel has local clients
+         on the channel anymore.  If it does not have then the channel entry
+         is removed as it is not needed anymore.
+
+       * The silc_server_notify now checks on JOIN notify whether the joining
+         client is one of locally connected or global.  If it is global then
+         the channel has now global users on the channel and that is marked
+         to the channel entry.  Also, it now saves the global client to
+         global list who is joining and JOINs it to the channel.  This is
+         for normal server, that is.
+
+         Changed silc_server_send_notify_on_channel, 
+         silc_server_packet_relay_to_channel and 
+         silc_server_packet_send_to_channel check if we are normal server
+         and client has router set (ie. global client) do not send the
+         message to that client, as it is already routed to our router.
+
+       * Implemented LEAVE notify type handling in silc_server_notify 
+         function.
+
+       * Tested LEAVE command in router environment successfully.  Tested
+         with two routers, two servers and two clients.
+
+       * Updated TODO.
+
+       * idlist_find_xxx_by_id routines now dumps the ID on the debug mode.
+
+       * Implemented SIGNOFF notify type handling in silc_server_notify
+         function.
+
+       * silc_server_remove_id now removes the client entry from all channels
+         it has joined and thusly sends SIGNOFF notify type.
+
+       * Rewrote the NAMES list generation in server by removing two excess
+         loops.  The lists are created now inside one loop.
+
 Sat Jan 27 22:34:56 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * silc_server_remove_channel_user checks now also global list
diff --git a/TODO b/TODO
index f4819f5dc5a4755dd0deccb882082ca0da103753..e60dfdc2f2ee69bf7a929c9760d6ae7a11d4e539 100644 (file)
--- a/TODO
+++ b/TODO
@@ -15,6 +15,13 @@ help is really appreciated - and needed.
 New features TODO
 =================
 
+ o Optimization in general.  I have not focused to program optimized code
+   in many circumstances.  It has been more important to get this up and
+   working.  A lot must be optimized especially the ID cache.  Instead of
+   using lists some hash tables should be used.  The searching by ID and
+   such must be made a lot faster.  If someone would like dedicate their
+   efforts purely to generate optimized code I'd be appreaciated.
+
  o We should replace all short, int, long, unsigned short, unsigned int,
    unsigned long with some pre-defined datatypes that really are what
    we want on all platforms.  int16, uint16, int32, uint32 etc. are
index 87eebd88d208b0c19f1714db6ab7c62d226ed6d7..4cdb2ca41f9c2b430521bd5ef8bf3924ab526eeb 100644 (file)
@@ -2829,6 +2829,7 @@ SILC_SERVER_CMD_FUNC(names)
   char *name_list = NULL, *n;
   SilcBuffer client_id_list;
   SilcBuffer client_mode_list;
+  SilcBuffer idp;
 
   SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_NAMES, cmd, 1, 2);
 
@@ -2860,12 +2861,20 @@ SILC_SERVER_CMD_FUNC(names)
     goto out;
   }
 
-  /* Assemble the name list now */
+  /* Assemble the lists now */
+
   name_list = NULL;
-  len = 0;
+  len = i = 0;
+  client_id_list = silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) * 
+                                    silc_list_count(channel->user_list));
+  silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
+  client_mode_list = 
+    silc_buffer_alloc(4 * silc_list_count(channel->user_list));
+  silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
+
   silc_list_start(channel->user_list);
-  i = 0;
   while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+    /* Nickname */
     n = chl->client->nickname;
     if (n) {
       len2 = strlen(n);
@@ -2880,39 +2889,23 @@ SILC_SERVER_CMD_FUNC(names)
       len++;
       i++;
     }
-  }
-  if (!name_list)
-    name_list = "";
-
-  /* Assemble the Client ID list now */
-  client_id_list = silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) * 
-                                    silc_list_count(channel->user_list));
-  silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
-  silc_list_start(channel->user_list);
-  while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
-    SilcBuffer idp;
 
+    /* Client ID */
     idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
-    silc_buffer_format(client_id_list,
-                      SILC_STR_UI_XNSTRING(idp->data, idp->len),
-                      SILC_STR_END);
+    silc_buffer_put(client_id_list, idp->data, idp->len);
     silc_buffer_pull(client_id_list, idp->len);
     silc_buffer_free(idp);
-  }
-  silc_buffer_push(client_id_list, 
-                  client_id_list->data - client_id_list->head);
 
-  /* Assemble mode list */
-  client_mode_list = silc_buffer_alloc(4 * 
-                                      silc_list_count(channel->user_list));
-  silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
-  silc_list_start(channel->user_list);
-  while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+    /* Client's mode on channel */
     SILC_PUT32_MSB(chl->mode, client_mode_list->data);
     silc_buffer_pull(client_mode_list, 4);
   }
+  silc_buffer_push(client_id_list, 
+                  client_id_list->data - client_id_list->head);
   silc_buffer_push(client_mode_list, 
                   client_mode_list->data - client_mode_list->head);
+  if (!name_list)
+    name_list = "";
 
   /* Send reply */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NAMES,
index d248f83e21a88881dd08bdf1c135b983e5916fa6..15ce098c221f79e03a59cfbd08c5278510c7269d 100644 (file)
@@ -51,6 +51,7 @@ SilcServerCommandReply silc_command_reply_list[] =
   SILC_SERVER_CMD_REPLY(join, JOIN),
   SILC_SERVER_CMD_REPLY(whois, WHOIS),
   SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
+  SILC_SERVER_CMD_REPLY(names, NAMES),
 
   { NULL, 0 },
 };
@@ -447,7 +448,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
     /* Add new channel */
 
     SILC_LOG_DEBUG(("Adding new [%s] channel %s id(%s)", 
-                   (created == 0 ? "created" : "existing"), channel_name,
+                   (created == 0 ? "existing" : "created"), channel_name,
                    silc_id_render(id, SILC_ID_CHANNEL)));
 
     /* Add the channel to our local list. */
@@ -486,3 +487,15 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
  out:
   silc_server_command_reply_free(cmd);
 }
+
+SILC_SERVER_CMD_REPLY_FUNC(names)
+{
+  SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
+  SilcServer server = cmd->server;
+  SilcCommandStatus status;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  COMMAND_CHECK_STATUS;
+
+}
index 9b5479e115571172d564be928dfbdabb0a8d55dd..599623df97144a123bbc886f34ef7fb5b00a9aca 100644 (file)
@@ -60,5 +60,6 @@ void silc_server_command_reply_process(SilcServer server,
 SILC_SERVER_CMD_REPLY_FUNC(join);
 SILC_SERVER_CMD_REPLY_FUNC(whois);
 SILC_SERVER_CMD_REPLY_FUNC(identify);
+SILC_SERVER_CMD_REPLY_FUNC(names);
 
 #endif
index cd276491d30fdd9ba1ab98efc127e8e80cb1f966..47ada7d45f70b3371ca3c0dc292c94b15ac2a96c 100644 (file)
@@ -116,7 +116,8 @@ silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id,
   if (!id)
     return NULL;
 
-  SILC_LOG_DEBUG(("Finding server by ID"));
+  SILC_LOG_DEBUG(("Server ID (%s)",
+                 silc_id_render(id, SILC_ID_SERVER)));
 
   if (!silc_idcache_find_by_id_one(id_list->servers, (void *)id, 
                                   SILC_ID_SERVER, &id_cache))
@@ -313,7 +314,7 @@ silc_idlist_find_client_by_nickname(SilcIDList id_list, char *nickname,
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client = NULL;
 
-  SILC_LOG_DEBUG(("Finding client by nickname"));
+  SILC_LOG_DEBUG(("Client by nickname"));
 
   if (server) {
     if (!silc_idcache_find_by_data(id_list->clients, nickname, &list))
@@ -360,7 +361,7 @@ silc_idlist_find_client_by_hash(SilcIDList id_list, char *nickname,
   SilcClientEntry client = NULL;
   unsigned char hash[32];
 
-  SILC_LOG_DEBUG(("Finding client by hash"));
+  SILC_LOG_DEBUG(("Client by hash"));
 
   silc_hash_make(md5hash, nickname, strlen(nickname), hash);
 
@@ -408,7 +409,8 @@ silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id,
   if (!id)
     return NULL;
 
-  SILC_LOG_DEBUG(("Finding client by ID"));
+  SILC_LOG_DEBUG(("Client ID (%s)", 
+                 silc_id_render(id, SILC_ID_CLIENT)));
 
   if (!silc_idcache_find_by_id_one(id_list->clients, (void *)id, 
                                   SILC_ID_CLIENT, &id_cache))
@@ -541,7 +543,7 @@ silc_idlist_find_channel_by_name(SilcIDList id_list, char *name,
   SilcIDCacheEntry id_cache = NULL;
   SilcChannelEntry channel;
 
-  SILC_LOG_DEBUG(("Finding channel by name"));
+  SILC_LOG_DEBUG(("Channel by name"));
 
   if (!silc_idcache_find_by_data_loose(id_list->channels, name, &list))
     return NULL;
@@ -575,7 +577,8 @@ silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id,
   if (!id)
     return NULL;
 
-  SILC_LOG_DEBUG(("Finding channel by ID"));
+  SILC_LOG_DEBUG(("Channel ID (%s)",
+                 silc_id_render(id, SILC_ID_CHANNEL)));
 
   if (!silc_idcache_find_by_id_one(id_list->channels, (void *)id, 
                                   SILC_ID_CHANNEL, &id_cache))
index e3a491d4d6d48b649aae6371a261feb45f26cb77..f7c59125404cf168c98aee397665cc61fe618e99 100644 (file)
@@ -701,7 +701,7 @@ void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
 
 /* Received Remove Channel User packet to remove a user from a channel. 
    Routers notify other routers that user has left a channel. Client must
-   not send this packet.. Normal server may send this packet but must not
+   not send this packet. Normal server may send this packet but must not
    receive it. */
 
 void silc_server_remove_channel_user(SilcServer server,
@@ -766,8 +766,8 @@ void silc_server_remove_channel_user(SilcServer server,
       goto out;
   }
 
-  /* Remove from channel */
-  silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
+  /* Remove user from channel */
+  silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
 
  out:
   if (tmp1)
@@ -838,7 +838,11 @@ void silc_server_notify(SilcServer server,
   SilcNotifyType type;
   SilcArgumentPayload args;
   SilcChannelID *channel_id;
+  SilcClientID *client_id;
   SilcChannelEntry channel;
+  SilcClientEntry client;
+  unsigned char *tmp;
+  unsigned int tmp_len;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -867,6 +871,7 @@ void silc_server_notify(SilcServer server,
     /* 
      * Distribute the notify to local clients on the channel
      */
+    SILC_LOG_DEBUG(("JOIN notify"));
 
     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
     if (!channel_id)
@@ -880,7 +885,40 @@ void silc_server_notify(SilcServer server,
       goto out;
     }
 
-    channel->global_users = TRUE;
+    /* Get client ID */
+    tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+    if (!tmp) {
+      silc_free(channel_id);
+      goto out;
+    }
+    client_id = silc_id_payload_parse_id(tmp, tmp_len);
+
+    /* If the the client is not in local list we check global list (ie. the
+       channel will be global channel) and if it does not exist then create
+       entry for the client. */
+    client = silc_idlist_find_client_by_id(server->local_list, 
+                                          client_id, NULL);
+    if (!client) {
+      SilcChannelClientEntry chl;
+
+      client = silc_idlist_find_client_by_id(server->global_list, 
+                                            client_id, NULL);
+      if (!client)
+       client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
+                                       client_id, sock->user_data, sock);
+
+      /* The channel is global now */
+      channel->global_users = TRUE;
+
+      /* Now actually JOIN the global client to the channel */
+      chl = silc_calloc(1, sizeof(*chl));
+      chl->client = client;
+      chl->channel = channel;
+      silc_list_add(channel->user_list, chl);
+      silc_list_add(client->channels, chl);
+    } else {
+      silc_free(client_id);
+    }
 
     /* Send to channel */
     silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
@@ -889,9 +927,81 @@ void silc_server_notify(SilcServer server,
     break;
 
   case SILC_NOTIFY_TYPE_LEAVE:
+    /* 
+     * Distribute the notify to local clients on the channel
+     */
+    SILC_LOG_DEBUG(("LEAVE notify"));
+
+    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
+    if (!channel_id)
+      goto out;
+
+    /* Get channel entry */
+    channel = silc_idlist_find_channel_by_id(server->local_list, 
+                                            channel_id, NULL);
+    if (!channel) { 
+      silc_free(channel_id);
+      goto out;
+    }
+
+    /* Get client ID */
+    tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+    if (!tmp) {
+      silc_free(channel_id);
+      goto out;
+    }
+    client_id = silc_id_payload_parse_id(tmp, tmp_len);
+
+    /* Send to channel */
+    silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
+                                      packet->buffer->data, 
+                                      packet->buffer->len, FALSE);
+
+    /* Get client entry */
+    client = silc_idlist_find_client_by_id(server->global_list, 
+                                          client_id, NULL);
+    if (!client) {
+      client = silc_idlist_find_client_by_id(server->local_list, 
+                                            client_id, NULL);
+      if (!client) {
+       silc_free(channel_id);
+       goto out;
+      }
+    }
+    silc_free(client_id);
+
+    /* Remove the user from channel */
+    silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
     break;
 
   case SILC_NOTIFY_TYPE_SIGNOFF:
+    /* 
+     * Distribute the notify to local clients on the channel
+     */
+    SILC_LOG_DEBUG(("SIGNOFF notify"));
+
+    /* 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);
+
+    /* Get client entry */
+    client = silc_idlist_find_client_by_id(server->global_list, 
+                                          client_id, NULL);
+    if (!client) {
+      client = silc_idlist_find_client_by_id(server->local_list, 
+                                            client_id, NULL);
+      if (!client)
+       goto out;
+    }
+    silc_free(client_id);
+
+    /* Remove the client from all channels */
+    silc_server_remove_from_channels(server, NULL, client);
+
+    /* Remove the client entry */
+    silc_idlist_del_client(server->global_list, client);
     break;
 
     /* Ignore rest notify types for now */
@@ -1056,6 +1166,8 @@ void silc_server_remove_id(SilcServer server,
   SilcIdType id_type;
   void *id, *id_entry;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
       server->server_type == SILC_SERVER ||
       packet->src_id_type != SILC_ID_SERVER)
@@ -1089,11 +1201,15 @@ void silc_server_remove_id(SilcServer server,
     id_list = server->global_list;
 
   /* Remove the ID */
-  switch(id_type) {
+  switch (id_type) {
   case SILC_ID_CLIENT:
     id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id, 
                                             NULL);
     if (id_entry) {
+      /* Remove from channels */
+      silc_server_remove_from_channels(server, NULL, id_entry);
+
+      /* Remove the client entry */
       silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
 
       SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
index 7c529233bf1a30eaa27eb4067214e4e2bdae2138..bbae2c24bf038fad4d2897c42d2532fd978d9cf4 100644 (file)
@@ -444,6 +444,9 @@ void silc_server_packet_send_to_channel(SilcServer server,
     if (server->server_type == SILC_ROUTER && !route)
       continue;
 
+    if (server->server_type == SILC_SERVER && client->router)
+      continue;
+
     /* Send to locally connected client */
     if (client) {
 
@@ -584,7 +587,8 @@ void silc_server_packet_relay_to_channel(SilcServer server,
        continue;
       }
 
-      /* XXX Check client's mode on the channel. */
+      if (server->server_type == SILC_SERVER && client->router)
+       continue;
 
       /* Get data used in packet header encryption, keys and stuff. */
       sock = (SilcSocketConnection)client->connection;
@@ -884,6 +888,9 @@ void silc_server_send_notify_on_channels(SilcServer server,
        continue;
       }
 
+      if (server->server_type == SILC_SERVER && client->router)
+       continue;
+
       /* Send to locally connected client */
       if (c) {
        
index 1aabffbdb444ca5e38855f2f111c97c5841d6aa2..21b865e26e60545381ea1b3a33fd143a7673045c 100644 (file)
@@ -1665,9 +1665,41 @@ void silc_server_free_sock_user_data(SilcServer server,
   sock->user_data = NULL;
 }
 
-/* Removes client from all channels it has joined. This is used when
-   client connection is disconnected. If the client on a channel
-   is last, the channel is removed as well. */
+/* Checks whether given channel has global users.  If it does this returns
+   TRUE and FALSE if there is only locally connected clients on the channel. */
+
+int silc_server_channel_has_global(SilcChannelEntry channel)
+{
+  SilcChannelClientEntry chl;
+
+  silc_list_start(channel->user_list);
+  while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+    if (chl->client->router)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+/* Checks whether given channel has locally connected users.  If it does this
+   returns TRUE and FALSE if there is not one locally connected client. */
+
+int silc_server_channel_has_local(SilcChannelEntry channel)
+{
+  SilcChannelClientEntry chl;
+
+  silc_list_start(channel->user_list);
+  while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+    if (!chl->client->router)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+/* Removes client from all channels it has joined. This is used when client
+   connection is disconnected. If the client on a channel is last, the
+   channel is removed as well. This sends the SIGNOFF notify types. */
 
 void silc_server_remove_from_channels(SilcServer server, 
                                      SilcSocketConnection sock,
@@ -1703,7 +1735,7 @@ void silc_server_remove_from_channels(SilcServer server,
         channel globally from SILC network, in this case we will
         notify that this client has left the channel. */
       if (channel->global_users)
-       silc_server_send_notify_to_channel(server, channel, TRUE,
+       silc_server_send_notify_to_channel(server, channel, FALSE,
                                           SILC_NOTIFY_TYPE_SIGNOFF, 1,
                                           clidp->data, clidp->len);
       
@@ -1717,7 +1749,7 @@ void silc_server_remove_from_channels(SilcServer server,
 
     /* Send notify to channel about client leaving SILC and thus
        the entire channel. */
-    silc_server_send_notify_to_channel(server, channel, TRUE,
+    silc_server_send_notify_to_channel(server, channel, FALSE,
                                       SILC_NOTIFY_TYPE_SIGNOFF, 1,
                                       clidp->data, clidp->len);
     silc_buffer_free(chidp);
@@ -1761,10 +1793,9 @@ int silc_server_remove_from_one_channel(SilcServer server,
     /* If this client is last one on the channel the channel
        is removed all together. */
     if (silc_list_count(channel->user_list) < 2) {
-      /* Notify about leaving client if this channel has global users,
-        ie. the channel is not created locally. */
+      /* Notify about leaving client if this channel has global users. */
       if (notify && channel->global_users)
-       silc_server_send_notify_to_channel(server, channel, TRUE,
+       silc_server_send_notify_to_channel(server, channel, FALSE,
                                           SILC_NOTIFY_TYPE_LEAVE, 1,
                                           clidp->data, clidp->len);
       
@@ -1777,9 +1808,24 @@ int silc_server_remove_from_one_channel(SilcServer server,
     silc_list_del(channel->user_list, chl);
     silc_free(chl);
 
+    /* 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))
+      channel->global_users = FALSE;
+
+    /* If tehre is not at least one local user on the channel then we don't
+       need the channel entry anymore, we can remove it safely. */
+    if (server->server_type == SILC_SERVER &&
+       !silc_server_channel_has_local(channel)) {
+      silc_idlist_del_channel(server->local_list, channel);
+      silc_buffer_free(clidp);
+      return FALSE;
+    }
+
     /* Send notify to channel about client leaving the channel */
     if (notify)
-      silc_server_send_notify_to_channel(server, channel, TRUE,
+      silc_server_send_notify_to_channel(server, channel, FALSE,
                                         SILC_NOTIFY_TYPE_LEAVE, 1,
                                         clidp->data, clidp->len);
     break;
index 52624050e6551061cec424fa10e9b885d038edbc..53018b434762645828c87d9111f35fb862577444 100644 (file)
@@ -89,6 +89,8 @@ void silc_server_close_connection(SilcServer server,
                                  SilcSocketConnection sock);
 void silc_server_free_sock_user_data(SilcServer server, 
                                     SilcSocketConnection sock);
+int silc_server_channel_has_global(SilcChannelEntry channel);
+int silc_server_channel_has_local(SilcChannelEntry channel);
 void silc_server_remove_from_channels(SilcServer server, 
                                      SilcSocketConnection sock,
                                      SilcClientEntry client);
index 5810c45b66bf66bc0aa64c0103d4fbe46c5f9f1a..4d27be3520c7542861f2977ed44843bf5362eb6e 100644 (file)
@@ -712,10 +712,10 @@ List of SILC Packet types are defined as follows.
           this packet.  This packet maybe sent to entity that is
           indirectly connected to the sender.
 
-          When received and the replaced ID is Client ID the server or
+          When received and the removed ID is Client ID the server or
           router must distribute SILC_NOTIFY_TYPE_SIGNOFF to the
           local clients on the channels (if any) of the client whose
-          ID was changed.  However, the notify type must be sent only
+          ID was removed.  However, the notify type must be sent only
           once per client.
 
           Payload of the packet:  See section 2.3.25 Remove ID Payload
index 29eceb036b15b17c6ff628f4dcfa5c362c5f8a27..f039aac0cdfc715e2031bb213a685a53440fc542 100644 (file)
@@ -670,7 +670,7 @@ SILC_CLIENT_CMD_FUNC(join)
       silc_command_payload_encode_va(SILC_COMMAND_JOIN, 0, 2,
                                     1, cmd->argv[1], cmd->argv_lens[1],
                                     2, idp->data, idp->len);
-  else if (cmd->argc == 4)
+  else if (cmd->argc == 3)
     /* XXX Buggy */
     buffer = 
       silc_command_payload_encode_va(SILC_COMMAND_JOIN, 0, 3,
index edd2df0449943a1ece111c5077317c2c1953a8f4..a14dc63e1c372c094fba0bdfa22a60e580123cc4 100644 (file)
@@ -112,6 +112,9 @@ SilcClientEntry silc_idlist_get_client_by_id(SilcClient client,
 {
   SilcIDCacheEntry id_cache;
 
+  SILC_LOG_DEBUG(("Finding client by ID (%s)", 
+                 silc_id_render(client_id, SILC_ID_CLIENT)));
+
   /* Find ID from cache */
   if (!silc_idcache_find_by_id_one(conn->client_cache, client_id, 
                                   SILC_ID_CLIENT, &id_cache)) {