Major rewrite of ID Cache system. Support added for the new
authorPekka Riikonen <priikone@silcnet.org>
Wed, 12 Jul 2000 05:59:41 +0000 (05:59 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 12 Jul 2000 05:59:41 +0000 (05:59 +0000)
ID cache system. Major rewrite of ID List stuff on server.  All
SilcXXXList's are now called SilcXXXEntry's and they are pointers
by default. A lot rewritten ID list functions.

12 files changed:
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/command_reply.h
apps/silcd/idlist.c
apps/silcd/idlist.h
apps/silcd/protocol.c
apps/silcd/route.c
apps/silcd/route.h
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/server_internal.h
apps/silcd/silc.conf

index d5661fe24ccdb9ce4cb19b42ec7d7b10afd198e8..fae70a4f7772cc8e1eaf9dcfd8238bd7561897d7 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.9  2000/07/12 05:59:41  priikone
+ *     Major rewrite of ID Cache system. Support added for the new
+ *     ID cache system. Major rewrite of ID List stuff on server.  All
+ *     SilcXXXList's are now called SilcXXXEntry's and they are pointers
+ *     by default. A lot rewritten ID list functions.
+ *
  * Revision 1.8  2000/07/10 05:42:59  priikone
  *     Removed command packet processing from server.c and added it to
  *     command.c.
@@ -120,7 +126,7 @@ static int silc_server_is_registered(SilcServer server,
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     {
-      SilcClientList *client = (SilcClientList *)sock->user_data;
+      SilcClientEntry client = (SilcClientEntry)sock->user_data;
       if (client->registered)
        return TRUE;
       break;
@@ -128,7 +134,7 @@ static int silc_server_is_registered(SilcServer server,
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     {
-      SilcServerList *serv = (SilcServerList *)sock->user_data;
+      SilcServerEntry serv = (SilcServerEntry)sock->user_data;
       if (serv->registered)
        return TRUE;
       break;
@@ -307,9 +313,10 @@ silc_server_command_send_status_data(SilcServerCommandContext cmd,
 SILC_SERVER_CMD_FUNC(whois)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
-  char *tmp, *nick = NULL, *server = NULL;
+  SilcServer server = cmd->server;
+  char *tmp, *nick = NULL, *server_name = NULL;
   unsigned int argc, count = 0, len;
-  SilcClientList *entry;
+  SilcClientEntry entry;
   SilcBuffer packet;
   unsigned char *id_string;
 
@@ -334,8 +341,8 @@ SILC_SERVER_CMD_FUNC(whois)
       len = strcspn(tmp, "@");
       nick = silc_calloc(len + 1, sizeof(char));
       memcpy(nick, tmp, len);
-      server = silc_calloc(strlen(tmp) - len, sizeof(char));
-      memcpy(server, tmp + len + 1, strlen(tmp) - len - 1);
+      server_name = silc_calloc(strlen(tmp) - len, sizeof(char));
+      memcpy(server_name, tmp + len + 1, strlen(tmp) - len - 1);
     } else {
       nick = strdup(tmp);
     }
@@ -353,30 +360,30 @@ SILC_SERVER_CMD_FUNC(whois)
                                            SILC_STATUS_ERR_TOO_MANY_PARAMS);
       if (nick)
        silc_free(nick);
-      if (server)
-       silc_free(server);
+      if (server_name)
+       silc_free(server_name);
       goto out;
     }
     count = atoi(tmp);
   }
 
   /* Then, make the query from our local client list */
-  entry = silc_idlist_find_client_by_nickname(cmd->server->local_list->clients,
-                                             nick, server);
+  entry = silc_idlist_find_client_by_nickname(server->local_list, 
+                                             nick, server_name);
   if (!entry) {
 
     /* If we are normal server and are connected to a router we will
        make global query from the router. */
-    if (cmd->server->server_type == SILC_SERVER && !cmd->server->standalone) {
+    if (server->server_type == SILC_SERVER && !server->standalone) {
 
       goto ok;
     }
     
     /* If we are router then we will check our global list as well. */
-    if (cmd->server->server_type == SILC_ROUTER) {
+    if (server->server_type == SILC_ROUTER) {
       entry =
-       silc_idlist_find_client_by_nickname(cmd->server->global_list->clients,
-                                           nick, server);
+       silc_idlist_find_client_by_nickname(server->global_list,
+                                           nick, server_name);
       if (!entry) {
        silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
                                             SILC_STATUS_ERR_NO_SUCH_NICK,
@@ -410,9 +417,9 @@ SILC_SERVER_CMD_FUNC(whois)
     strncat(nh, entry->nickname, strlen(entry->nickname));
     strncat(nh, "@", 1);
     len = entry->router ? strlen(entry->router->server_name) :
-      strlen(cmd->server->server_name);
+      strlen(server->server_name);
     strncat(nh, entry->router ? entry->router->server_name :
-           cmd->server->server_name, len);
+           server->server_name, len);
 
     strncat(uh, entry->username, strlen(entry->username));
     strncat(uh, "@", 1);
@@ -448,7 +455,7 @@ SILC_SERVER_CMD_FUNC(whois)
                                           strlen(entry->nickname),
                                           4, tmp, strlen(tmp)); /* XXX */
   }
-  silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
+  silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
                          0, packet->data, packet->len, FALSE);
 
   silc_free(id_string);
@@ -465,9 +472,11 @@ SILC_SERVER_CMD_FUNC(whowas)
 SILC_SERVER_CMD_FUNC(identify)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
-  char *tmp, *nick = NULL, *server = NULL;
+  SilcServer server = cmd->server;
+  char *tmp, *nick = NULL, *server_name = NULL;
   unsigned int argc, count = 0, len;
-  SilcClientList *entry;  SilcBuffer packet;
+  SilcClientEntry entry;
+  SilcBuffer packet;
   unsigned char *id_string;
 
   SILC_LOG_DEBUG(("Start"));
@@ -491,8 +500,8 @@ SILC_SERVER_CMD_FUNC(identify)
       len = strcspn(tmp, "@");
       nick = silc_calloc(len + 1, sizeof(char));
       memcpy(nick, tmp, len);
-      server = silc_calloc(strlen(tmp) - len, sizeof(char));
-      memcpy(server, tmp + len + 1, strlen(tmp) - len - 1);
+      server_name = silc_calloc(strlen(tmp) - len, sizeof(char));
+      memcpy(server_name, tmp + len + 1, strlen(tmp) - len - 1);
     } else {
       nick = strdup(tmp);
     }
@@ -514,28 +523,30 @@ SILC_SERVER_CMD_FUNC(identify)
   }
 
   /* Then, make the query from our local client list */
-  entry = silc_idlist_find_client_by_hash(cmd->server->local_list->clients,
-                                         nick, cmd->server->md5hash);
+  entry = silc_idlist_find_client_by_nickname(server->local_list,
+                                             nick, NULL);
   if (!entry) {
 
     /* If we are normal server and are connected to a router we will
        make global query from the router. */
-    if (cmd->server->server_type == SILC_SERVER && !cmd->server->standalone) {
+    if (server->server_type == SILC_SERVER && !server->standalone) {
       SilcBuffer buffer = cmd->packet->buffer;
 
+      SILC_LOG_DEBUG(("Requesting identify from router"));
+
       /* Send IDENTIFY command to our router */
       silc_buffer_push(buffer, buffer->data - buffer->head);
-      silc_server_packet_forward(cmd->server, (SilcSocketConnection)
-                                cmd->server->id_entry->router->connection,
+      silc_server_packet_forward(server, (SilcSocketConnection)
+                                server->id_entry->router->connection,
                                 buffer->data, buffer->len, TRUE);
       goto out;
     }
     
     /* If we are router then we will check our global list as well. */
-    if (cmd->server->server_type == SILC_ROUTER) {
+    if (server->server_type == SILC_ROUTER) {
       entry = 
-       silc_idlist_find_client_by_hash(cmd->server->global_list->clients,
-                                       nick, cmd->server->md5hash);
+       silc_idlist_find_client_by_nickname(server->global_list,
+                                           nick, NULL);
       if (!entry) {
        silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
                                             SILC_STATUS_ERR_NO_SUCH_NICK,
@@ -563,14 +574,14 @@ SILC_SERVER_CMD_FUNC(identify)
 #if 0
   if (cmd->packet->flags & SILC_PACKET_FLAG_FORWARDED) {
     void *id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_type);
-    silc_server_packet_send_dest(cmd->server, cmd->sock, 
+    silc_server_packet_send_dest(server, cmd->sock, 
                                 SILC_PACKET_COMMAND_REPLY, 0,
                                 id, cmd->packet->src_id_type,
                                 packet->data, packet->len, FALSE);
     silc_free(id);
   } else
 #endif
-    silc_server_packet_send(cmd->server, cmd->sock, 
+    silc_server_packet_send(server, cmd->sock, 
                            SILC_PACKET_COMMAND_REPLY, 0, 
                            packet->data, packet->len, FALSE);
 
@@ -580,8 +591,8 @@ SILC_SERVER_CMD_FUNC(identify)
  out:
   if (nick)
     silc_free(nick);
-  if (server)
-    silc_free(server);
+  if (server_name)
+    silc_free(server_name);
   silc_server_command_free(cmd);
 }
 
@@ -608,7 +619,7 @@ static int silc_server_command_bad_chars(char *nick)
 SILC_SERVER_CMD_FUNC(nick)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
-  SilcClientList *id_entry = (SilcClientList *)cmd->sock->user_data;
+  SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
   SilcServer server = cmd->server;
   SilcBuffer packet;
   SilcClientID *new_id;
@@ -617,9 +628,6 @@ SILC_SERVER_CMD_FUNC(nick)
 
   SILC_LOG_DEBUG(("Start"));
 
-#define LCC(x) server->local_list->client_cache[(x) - 32]
-#define LCCC(x) server->local_list->client_cache_count[(x) - 32]
-
   /* Check number of arguments */
   if (silc_command_get_arg_num(cmd->payload) < 1) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
@@ -657,9 +665,8 @@ SILC_SERVER_CMD_FUNC(nick)
                                new_id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
 
   /* Remove old cache entry */
-  silc_idcache_del_by_id(LCC(id_entry->nickname[0]),
-                        LCCC(id_entry->nickname[0]), 
-                        SILC_ID_CLIENT, id_entry->id); 
+  silc_idcache_del_by_id(server->local_list->clients, SILC_ID_CLIENT, 
+                        id_entry->id); 
   
   /* Free old ID */
   if (id_entry->id) {
@@ -675,9 +682,8 @@ SILC_SERVER_CMD_FUNC(nick)
   id_entry->id = new_id;
 
   /* Update client cache */
-  LCCC(nick[0]) = silc_idcache_add(&LCC(nick[0]), LCCC(nick[0]),
-                                  id_entry->nickname, SILC_ID_CLIENT, 
-                                  id_entry->id, (void *)id_entry);
+  silc_idcache_add(server->local_list->clients, id_entry->nickname, 
+                  SILC_ID_CLIENT, id_entry->id, (void *)id_entry, TRUE);
 
   /* Send the new Client ID as reply command back to client */
   id_string = silc_id_id2str(id_entry->id, SILC_ID_CLIENT);
@@ -693,8 +699,6 @@ SILC_SERVER_CMD_FUNC(nick)
 
  out:
   silc_server_command_free(cmd);
-#undef LCC
-#undef LCCC
 }
 
 SILC_SERVER_CMD_FUNC(list)
@@ -712,9 +716,9 @@ SILC_SERVER_CMD_FUNC(invite)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcSocketConnection sock = cmd->sock, dest_sock;
-  SilcClientList *sender, *dest;
+  SilcClientEntry sender, dest;
   SilcClientID *dest_id;
-  SilcChannelList *channel;
+  SilcChannelEntry channel;
   SilcChannelID *channel_id;
   unsigned int argc, len;
   unsigned char *id_string;
@@ -751,8 +755,7 @@ SILC_SERVER_CMD_FUNC(invite)
   channel_id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
 
   /* Check whether the channel exists */
-  channel = silc_idlist_find_channel_by_id(server->local_list->channels, 
-                                          channel_id);
+  channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
   if (!channel) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
                                          SILC_STATUS_ERR_NO_SUCH_CHANNEL);
@@ -760,7 +763,7 @@ SILC_SERVER_CMD_FUNC(invite)
   }
 
   /* Check whether the sender of this command is on the channel. */
-  sender = (SilcClientList *)sock->user_data;
+  sender = (SilcClientEntry )sock->user_data;
   if (!silc_server_client_on_channel(sender, channel)) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
                                          SILC_STATUS_ERR_NOT_ON_CHANNEL);
@@ -773,7 +776,7 @@ SILC_SERVER_CMD_FUNC(invite)
 
   /* Find the connection data for the destination. If it is local we will
      send it directly otherwise we will send it to router for routing. */
-  dest = silc_idlist_find_client_by_id(server->local_list->clients, dest_id);
+  dest = silc_idlist_find_client_by_id(server->local_list, dest_id);
   if (dest)
     dest_sock = (SilcSocketConnection)dest->connection;
   else
@@ -876,7 +879,8 @@ SILC_SERVER_CMD_FUNC(info)
   if (!strncasecmp(dest_server, server->server_name, strlen(dest_server))) {
     /* Send our reply */
     memset(info_string, 0, sizeof(info_string));
-    snprintf(info_string, sizeof(info_string), "%s %s %s <%s>",
+    snprintf(info_string, sizeof(info_string), 
+            "location: %s server: %s admin: %s <%s>",
             server->config->admin_info->location,
             server->config->admin_info->server_type,
             server->config->admin_info->admin_name,
@@ -971,7 +975,7 @@ typedef struct {
   char *nickname;
   char *username;
   char *hostname;
-  SilcChannelList *channel;
+  SilcChannelEntry channel;
   SilcServer server;
 } JoinInternalContext;
 
@@ -998,7 +1002,7 @@ SILC_TASK_CALLBACK(silc_server_command_join_notify)
 
 void silc_server_command_send_names(SilcServer server,
                                    SilcSocketConnection sock,
-                                   SilcChannelList *channel)
+                                   SilcChannelEntry channel)
 {
   SilcServerCommandContext cmd;
   SilcBuffer buffer;
@@ -1031,17 +1035,13 @@ SILC_SERVER_CMD_FUNC(join)
   int argc, i, tmp_len;
   char *tmp, *channel_name = NULL, *cipher = NULL, *id_string = NULL;
   unsigned char *passphrase, mode[4];
-  SilcChannelList *channel;
+  SilcChannelEntry channel;
   SilcServerID *router_id;
-  SilcIDCache *id_cache;
   SilcBuffer packet;
-  SilcClientList *client;
+  SilcClientEntry client;
 
   SILC_LOG_DEBUG(("Start"));
 
-#define LCC(x) server->local_list->channel_cache[(x) - 32]
-#define LCCC(x) server->local_list->channel_cache_count[(x) - 32]
-
   /* Check number of parameters */
   argc = silc_command_get_arg_num(cmd->payload);
   if (argc < 1) {
@@ -1077,10 +1077,10 @@ SILC_SERVER_CMD_FUNC(join)
   cipher = silc_command_get_arg_type(cmd->payload, 3, NULL);
 
   /* See if the channel exists */
-  if (silc_idcache_find_by_data(LCC(channel_name[0]), LCCC(channel_name[0]), 
-                               channel_name, &id_cache) == FALSE) {
+  channel = 
+    silc_idlist_find_channel_by_name(server->local_list, channel_name);
+  if (!channel) {
     /* Channel not found */
-    id_cache = NULL;
 
     /* If we are standalone server we don't have a router, we just create 
        the channel by  ourselves. */
@@ -1088,6 +1088,9 @@ SILC_SERVER_CMD_FUNC(join)
       router_id = server->id;
       channel = silc_server_new_channel(server, router_id, 
                                        cipher, channel_name);
+      if (!channel)
+       goto out;
+
       goto join_channel;
     }
 
@@ -1114,7 +1117,7 @@ SILC_SERVER_CMD_FUNC(join)
 
   /* If we are router and the channel does not exist we will check our
      global list for the channel. */
-  if (!id_cache && server->server_type == SILC_ROUTER) {
+  if (!channel && server->server_type == SILC_ROUTER) {
 
     /* Notify all routers about the new channel in SILC network. */
     if (!server->standalone) {
@@ -1127,18 +1130,16 @@ SILC_SERVER_CMD_FUNC(join)
 
   }
 
-  channel = (SilcChannelList *)id_cache->context;
-
  join_channel:
 
   /* If the JOIN request was forwarded to us we will make a bit slower
      query to get the client pointer. Otherwise, we get the client pointer
      real easy. */
   if (!(cmd->packet->flags & SILC_PACKET_FLAG_FORWARDED)) {
-    client = (SilcClientList *)sock->user_data;
+    client = (SilcClientEntry)sock->user_data;
   } else {
     void *id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_type);
-    client = silc_idlist_find_client_by_id(server->local_list->clients, id);
+    client = silc_idlist_find_client_by_id(server->local_list, id);
     if (!client) {
       /* XXX */
       goto out;
@@ -1264,8 +1265,6 @@ SILC_SERVER_CMD_FUNC(join)
 
  out:
   silc_server_command_free(cmd);
-#undef LCC
-#undef LCCC
 }
 
 /* Server side of command MOTD. Sends servers current "message of the
@@ -1313,9 +1312,9 @@ SILC_SERVER_CMD_FUNC(leave)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcSocketConnection sock = cmd->sock;
-  SilcClientList *id_entry = (SilcClientList *)cmd->sock->user_data;
+  SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
   SilcChannelID *id;
-  SilcChannelList *channel;
+  SilcChannelEntry channel;
   SilcBuffer packet;
   unsigned int i, argc, key_len;
   unsigned char *tmp, channel_key[32];
@@ -1344,7 +1343,7 @@ SILC_SERVER_CMD_FUNC(leave)
   id = silc_id_str2id(tmp, SILC_ID_CHANNEL);
 
   /* Get channel entry */
-  channel = silc_idlist_find_channel_by_id(server->local_list->channels, id);
+  channel = silc_idlist_find_channel_by_id(server->local_list, id);
   if (!channel) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
                                          SILC_STATUS_ERR_NO_SUCH_CHANNEL);
@@ -1419,7 +1418,7 @@ SILC_SERVER_CMD_FUNC(names)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
-  SilcChannelList *channel;
+  SilcChannelEntry channel;
   SilcChannelID *id;
   SilcBuffer packet;
   unsigned int i, len, len2, argc;
@@ -1453,7 +1452,7 @@ SILC_SERVER_CMD_FUNC(names)
   /* Check whether the channel exists. If we are normal server and the
      channel does not exist we will send this same command to our router
      which will know if the channel exists. */
-  channel = silc_idlist_find_channel_by_id(server->local_list->channels, id);
+  channel = silc_idlist_find_channel_by_id(server->local_list, id);
   if (!channel) {
     if (server->server_type == SILC_SERVER && !server->standalone) {
       /* XXX Send names command */
index 9bf7e1c77d1014e5601434386261fc39440951e6..b3054faed7d3e07354912ca511c70ebee2b8f9e5 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.4  2000/07/12 05:59:41  priikone
+ *     Major rewrite of ID Cache system. Support added for the new
+ *     ID cache system. Major rewrite of ID List stuff on server.  All
+ *     SilcXXXList's are now called SilcXXXEntry's and they are pointers
+ *     by default. A lot rewritten ID list functions.
+ *
  * Revision 1.3  2000/07/05 06:14:01  priikone
  *     Global costemic changes.
  *
@@ -41,6 +47,7 @@
 SilcServerCommandReply silc_command_reply_list[] =
 {
   SILC_SERVER_CMD_REPLY(join, JOIN),
+  SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
 
   { NULL, 0 },
 };
@@ -96,13 +103,10 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
   SilcServer server = cmd->server;
   SilcCommandStatus status;
   SilcChannelID *id;
-  SilcChannelList *entry;
+  SilcChannelEntry entry;
   unsigned char *id_string;
   char *channel_name, *tmp;
 
-#define LCC(x) server->local_list->channel_cache[(x) - 32]
-#define LCCC(x) server->local_list->channel_cache_count[(x) - 32]
-
   SILC_LOG_DEBUG(("Start"));
 
   tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
@@ -124,13 +128,12 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
 
   /* Add the channel to our local list. */
   id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
-  silc_idlist_add_channel(&server->local_list->channels, channel_name, 
-                         SILC_CHANNEL_MODE_NONE, id, 
-                         server->id_entry->router, NULL, &entry);
-  LCCC(channel_name[0]) = silc_idcache_add(&LCC(channel_name[0]), 
-                                          LCCC(channel_name[0]),
-                                          channel_name, SILC_ID_CHANNEL, 
-                                          (void *)id, (void *)entry);
+  entry = silc_idlist_add_channel(server->local_list, channel_name, 
+                                 SILC_CHANNEL_MODE_NONE, id, 
+                                 server->id_entry->router, NULL);
+  if (!entry)
+    goto out;
+
   entry->global_users = TRUE;
 
   /* Execute pending JOIN command so that the client who originally
@@ -139,6 +142,61 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
 
  out:
   silc_server_command_reply_free(cmd);
-#undef LCC
-#undef LCCC
+}
+
+/* Received reply for forwarded IDENTIFY command. We have received the
+   requested identify information now and we will cache it. After this we
+   will call the pending command so that the requestee gets the information
+   after all. */
+
+SILC_SERVER_CMD_REPLY_FUNC(identify)
+{
+  SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
+  SilcServer server = cmd->server;
+  SilcCommandStatus status;
+  unsigned char *tmp;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
+  SILC_GET16_MSB(status, tmp);
+  if (status != SILC_STATUS_OK)
+    goto out;
+
+  /* Process one identify reply */
+  if (status == SILC_STATUS_OK) {
+    unsigned char *id_data;
+    char *nickname;
+
+    id_data = silc_command_get_arg_type(cmd->payload, 2, NULL);
+    nickname = silc_command_get_arg_type(cmd->payload, 3, NULL);
+    if (!id_data || !nickname)
+      goto out;
+
+#if 0
+    /* Allocate client entry */
+    client_entry = silc_calloc(1, sizeof(*client_entry));
+    client_entry->id = silc_id_str2id(id_data, SILC_ID_CLIENT);
+    client_entry->nickname = strdup(nickname);
+
+    /* Save received Client ID to ID cache */
+    silc_idcache_add(win->client_cache, client_entry->nickname,
+                    SILC_ID_CLIENT, client_entry->id, client_entry, TRUE);
+#endif
+  }
+
+  if (status == SILC_STATUS_LIST_START) {
+
+  }
+
+  if (status == SILC_STATUS_LIST_END) {
+
+  }
+
+  /* Execute pending IDENTIFY command so that the client who originally
+     requested the identify information will get it after all. */
+  SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_IDENTIFY);
+
+ out:
+  silc_server_command_reply_free(cmd);
 }
index 0e67aa287dbb2dddb0119ca1fe7df8f42d28c6e2..28d95c5b7c4fa026e3c36a0c4f9a40eef03e0205 100644 (file)
@@ -73,5 +73,6 @@ void silc_server_command_reply_process(SilcServer server,
                                       SilcSocketConnection sock,
                                       SilcBuffer buffer);
 SILC_SERVER_CMD_REPLY_FUNC(join);
+SILC_SERVER_CMD_REPLY_FUNC(identify);
 
 #endif
index 863d06be676245defdd32bf381d2b77f59a12284..2bb1636d66811dbcb2fdad00440215a888712b73 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.5  2000/07/12 05:59:41  priikone
+ *     Major rewrite of ID Cache system. Support added for the new
+ *     ID cache system. Major rewrite of ID List stuff on server.  All
+ *     SilcXXXList's are now called SilcXXXEntry's and they are pointers
+ *     by default. A lot rewritten ID list functions.
+ *
  * Revision 1.4  2000/07/06 07:16:13  priikone
  *     Added SilcPublicKey's
  *
 #include "serverincludes.h"
 #include "idlist.h"
 
-/* Adds a new server to the list. The pointer sent as argument is allocated
-   and returned. */
+/******************************************************************************
 
-void silc_idlist_add_server(SilcServerList **list, 
-                           char *server_name, int server_type,
-                           SilcServerID *id, SilcServerList *router,
-                           SilcCipher send_key, SilcCipher receive_key,
-                           SilcPKCS public_key, SilcHmac hmac, 
-                           SilcServerList **new_idlist)
-{
-  SilcServerList *last, *idlist;
+                          Server entry functions
 
-  SILC_LOG_DEBUG(("Adding new server to id list"));
+******************************************************************************/
 
-  idlist = silc_calloc(1, sizeof(*idlist));
-  if (idlist == NULL) {
-    SILC_LOG_ERROR(("Could not allocate new server list object"));
-    *new_idlist = NULL;
-    return;
-  }
+/* Add new server entry. This adds the new server entry to ID cache and
+   returns the allocated entry object or NULL on error. This is called
+   when new server connects to us. We also add ourselves to cache with
+   this function. */
 
-  /* Set the pointers */
-  idlist->server_name = server_name;
-  idlist->server_type = server_type;
-  idlist->id = id;
-  idlist->router = router;
-  idlist->send_key = send_key;
-  idlist->receive_key = receive_key;
-  idlist->pkcs = public_key;
-  idlist->hmac = hmac;
-  idlist->next = idlist;
-  idlist->prev = idlist;
-
-  /* First on the list? */
-  if (!*list) {
-    *list = idlist;
-    *new_idlist = idlist;
-    return;
+SilcServerEntry 
+silc_idlist_add_server(SilcIDList id_list, 
+                      char *server_name, int server_type,
+                      SilcServerID *id, SilcServerEntry router,
+                      SilcCipher send_key, SilcCipher receive_key,
+                      SilcPKCS pkcs, SilcHmac hmac, 
+                      SilcPublicKey public_key, void *connection)
+{
+  SilcServerEntry server;
+
+  SILC_LOG_DEBUG(("Adding new server entry"));
+
+  server = silc_calloc(1, sizeof(*server));
+  server->server_name = server_name;
+  server->server_type = server_type;
+  server->id = id;
+  server->router = router;
+  server->send_key = send_key;
+  server->receive_key = receive_key;
+  server->pkcs = pkcs;
+  server->hmac = hmac;
+  server->public_key = public_key;
+  server->connection = connection;
+
+  if (!silc_idcache_add(id_list->servers, server->server_name, SILC_ID_SERVER,
+                       (void *)server->id, (void *)server, TRUE)) {
+    silc_free(server);
+    return NULL;
   }
 
-  /* Add it to the list */
-  last = (*list)->prev;
-  last->next = idlist;
-  (*list)->prev = idlist;
-  idlist->next = (*list);
-  idlist->prev = last;
-
-  if (new_idlist)
-    *new_idlist = idlist;
+  return server;
 }
 
-/* Adds a new client to the client list. This is called when new client 
-   connection is accepted to the server. This adds all the relevant data 
-   about the client and session with it to the list. This list is 
-   referenced for example when sending message to the client. */
-
-void silc_idlist_add_client(SilcClientList **list, char *nickname,
-                           char *username, char *userinfo,
-                           SilcClientID *id, SilcServerList *router,
-                           SilcCipher send_key, SilcCipher receive_key,
-                           SilcPKCS public_key, SilcHmac hmac, 
-                           SilcClientList **new_idlist)
-{
-  SilcClientList *last, *idlist;
+/******************************************************************************
 
-  SILC_LOG_DEBUG(("Adding new client to id list"));
+                          Client entry functions
 
-  idlist = silc_calloc(1, sizeof(*idlist));
-  if (idlist == NULL) {
-    SILC_LOG_ERROR(("Could not allocate new client list object"));
-    return;
-  }
+******************************************************************************/
 
-  /* Set the pointers */
-  idlist->nickname = nickname;
-  idlist->username = username;
-  idlist->userinfo = userinfo;
-  idlist->id = id;
-  idlist->router = router;
-  idlist->send_key = send_key;
-  idlist->receive_key = receive_key;
-  idlist->pkcs = public_key;
-  idlist->hmac = hmac;
-  idlist->next = idlist;
-  idlist->prev = idlist;
-
-  /* First on the list? */
-  if (!(*list)) {
-    *list = idlist;
-    if (new_idlist)
-      *new_idlist = idlist;
-    return;
-  }
+/* Add new client entry. This adds the client entry to ID cache system
+   and returns the allocated client entry or NULL on error.  This is
+   called when new client connection is accepted to the server. */
 
-  /* Add it to the list */
-  last = (*list)->prev;
-  last->next = idlist;
-  (*list)->prev = idlist;
-  idlist->next = *list;
-  idlist->prev = last;
+SilcClientEntry
+silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
+                      char *userinfo, SilcClientID *id, 
+                      SilcServerEntry router,
+                      SilcCipher send_key, SilcCipher receive_key,
+                      SilcPKCS pkcs, SilcHmac hmac, 
+                      SilcPublicKey public_key, void *connection)
+{
+  SilcClientEntry client;
+
+  SILC_LOG_DEBUG(("Adding new client entry"));
+
+  client = silc_calloc(1, sizeof(*client));
+  client->nickname = nickname;
+  client->username = username;
+  client->userinfo = userinfo;
+  client->id = id;
+  client->router = router;
+  client->send_key = send_key;
+  client->receive_key = receive_key;
+  client->pkcs = pkcs;
+  client->hmac = hmac;
+  client->public_key = public_key;
+  client->connection = connection;
+
+  if (!silc_idcache_add(id_list->clients, client->nickname, SILC_ID_CLIENT,
+                       (void *)client->id, (void *)client, TRUE)) {
+    silc_free(client);
+    return NULL;
+  }
 
-  if (new_idlist)
-    *new_idlist = idlist;
+  return client;
 }
 
-/* Free client entry.  This free's everything. */
+/* Free client entry. This free's everything and removes the entry
+   from ID cache. */
 
-void silc_idlist_del_client(SilcClientList **list, SilcClientList *entry)
+void silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 {
   if (entry) {
+    /* Remove from cache */
+    if (entry->id)
+      silc_idcache_del_by_id(id_list->clients, SILC_ID_CLIENT, 
+                            (void *)entry->id);
+
+    /* Free data */
     if (entry->nickname)
       silc_free(entry->nickname);
     if (entry->username)
@@ -162,211 +158,134 @@ void silc_idlist_del_client(SilcClientList **list, SilcClientList *entry)
       silc_cipher_free(entry->receive_key);
     if (entry->pkcs)
       silc_pkcs_free(entry->pkcs);
+    if (entry->public_key)
+      silc_pkcs_public_key_free(entry->public_key);
     if (entry->hmac)
       silc_hmac_free(entry->hmac);
     if (entry->hmac_key) {
       memset(entry->hmac_key, 0, entry->hmac_key_len);
       silc_free(entry->hmac_key);
     }
-
-    /* Last one in list? */
-    if (*list == entry && entry->next == entry) {
-      *list = NULL;
-      silc_free(entry);
-      return;
-    }
-
-    /* At the start of list? */
-    if (*list == entry && entry->next != entry) {
-      *list = entry->next;
-      entry->next->prev = entry->prev;
-      entry->prev->next = *list;
-      silc_free(entry);
-      return;
-    }
-
-    /* Remove from list */
-    entry->prev->next = entry->next;
-    entry->next->prev = entry->prev;
-    silc_free(entry);
-    return;
   }
 }
 
-SilcClientList *
-silc_idlist_find_client_by_nickname(SilcClientList *list,
-                                   char *nickname,
+/* Finds client entry by nickname. */
+
+SilcClientEntry
+silc_idlist_find_client_by_nickname(SilcIDList id_list, char *nickname,
                                    char *server)
 {
-  SilcClientList *first, *entry;
+  SilcIDCacheList list = NULL;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcClientEntry client = NULL;
 
   SILC_LOG_DEBUG(("Finding client by nickname"));
 
-  if (!list)
-    return NULL;
+  if (server) {
+    if (!silc_idcache_find_by_data(id_list->clients, nickname, &list))
+      return NULL;
 
-  first = entry = list;
-  if (!strcmp(entry->nickname, nickname)) {
-    SILC_LOG_DEBUG(("Found"));
-    return entry;
-  }
-  entry = entry->next;
+#if 0
+    while (silc_idcache_list_next(list, &id_cache)) {
+      client = (SilcClientEntry)id_cache->context;
 
-  while(entry != first) {
-    if (!strcmp(entry->nickname, nickname)) {
-      SILC_LOG_DEBUG(("Found"));
-      return entry;
-    }
-
-    entry = entry->next;
-  }
-
-  return NULL;
-}
-
-SilcClientList *
-silc_idlist_find_client_by_hash(SilcClientList *list,
-                               char *nickname, SilcHash md5hash)
-{
-  SilcClientList *first, *entry;
-  unsigned char hash[16];
-
-  SILC_LOG_DEBUG(("Finding client by nickname hash"));
-
-  if (!list)
-    return NULL;
+      if (!strcmp(server, XXX, strlen(server)))
+       break;
 
-  /* Make hash of the nickname */
-  silc_hash_make(md5hash, nickname, strlen(nickname), hash);
+      client = NULL;
+    }
+#endif
 
-  first = entry = list;
-  if (entry && !SILC_ID_COMPARE_HASH(entry->id, hash)) {
-    SILC_LOG_DEBUG(("Found"));
-    return entry;
-  }
-  entry = entry->next;
+   if (!client)
+     return NULL;
 
-  while(entry != first) {
-    if (entry && !SILC_ID_COMPARE_HASH(entry->id, hash)) {
-      SILC_LOG_DEBUG(("Found"));
-      return entry;
-    }
+   silc_idcache_list_free(list);
+  } else {
+    if (!silc_idcache_find_by_data_one(id_list->clients, nickname, &id_cache))
+      return NULL;
 
-    entry = entry->next;
+    client = (SilcClientEntry)id_cache->context;
   }
 
-  return NULL;
+  return client;
 }
 
-SilcClientList *
-silc_idlist_find_client_by_id(SilcClientList *list, SilcClientID *id)
-{
-  SilcClientList *first, *entry;
-
-  SILC_LOG_DEBUG(("Finding client by Client ID"));
-
-  if (!list)
-    return NULL;
-
-  first = entry = list;
-  if (entry && !SILC_ID_CLIENT_COMPARE(entry->id, id)) {
-    SILC_LOG_DEBUG(("Found"));
-    return entry;
-  }
-  entry = entry->next;
+/* Finds client by nickname hash. */
 
-  while(entry != first) {
-    if (entry && !SILC_ID_CLIENT_COMPARE(entry->id, id)) {
-      SILC_LOG_DEBUG(("Found"));
-      return entry;
-    }
-
-    entry = entry->next;
-  }
+SilcClientEntry
+silc_idlist_find_client_by_hash(SilcIDList id_list, unsigned char *hash,
+                               SilcHash md5hash)
+{
 
   return NULL;
 }
 
-/* Adds new channel to the list. */
+/* Finds client by Client ID */
 
-void silc_idlist_add_channel(SilcChannelList **list, 
-                            char *channel_name, int mode,
-                            SilcChannelID *id, SilcServerList *router,
-                            SilcCipher channel_key,
-                            SilcChannelList **new_idlist)
+SilcClientEntry
+silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id)
 {
-  SilcChannelList *last, *idlist;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcClientEntry client;
 
-  SILC_LOG_DEBUG(("Adding new channel to id list"));
+  if (!id)
+    return NULL;
 
-  idlist = silc_calloc(1, sizeof(*idlist));
-  if (idlist == NULL) {
-    SILC_LOG_ERROR(("Could not allocate new channel list object"));
-    return;
-  }
+  SILC_LOG_DEBUG(("Finding client by ID"));
 
-  /* Set the pointers */
-  idlist->channel_name = channel_name;
-  idlist->mode = mode;
-  idlist->id = id;
-  idlist->router = router;
-  idlist->channel_key = channel_key;
-  idlist->next = idlist;
-  idlist->prev = idlist;
-
-  /* First on the list? */
-  if (!*list) {
-    *list = idlist;
-    if (new_idlist)
-      *new_idlist = idlist;
-    return;
-  }
+  if (!silc_idcache_find_by_id_one(id_list->clients, (void *)id, 
+                                  SILC_ID_CLIENT, &id_cache))
+    return NULL;
 
-  /* Add it to the list */
-  last = (*list)->prev;
-  last->next = idlist;
-  (*list)->prev = idlist;
-  idlist->next = (*list);
-  idlist->prev = last;
+  client = (SilcClientEntry)id_cache->context;
 
-  if (new_idlist)
-    *new_idlist = idlist;
+  return client;
 }
 
-SilcChannelList *
-silc_idlist_find_channel_by_id(SilcChannelList *list, SilcChannelID *id)
-{
-  SilcChannelList *first, *entry;
+/******************************************************************************
 
-  SILC_LOG_DEBUG(("Finding channel by Channel ID"));
+                          Channel entry functions
 
-  if (!list)
-    return NULL;
+******************************************************************************/
 
-  first = entry = list;
-  if (entry && !SILC_ID_CHANNEL_COMPARE(entry->id, id)) {
-    SILC_LOG_DEBUG(("Found"));
-    return entry;
-  }
-  entry = entry->next;
+/* Add new channel entry. This add the new channel entry to the ID cache
+   system and returns the allocated entry or NULL on error. */
 
-  while(entry != first) {
-    if (entry && !SILC_ID_CHANNEL_COMPARE(entry->id, id)) {
-      SILC_LOG_DEBUG(("Found"));
-      return entry;
-    }
-
-    entry = entry->next;
+SilcChannelEntry
+silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
+                       SilcChannelID *id, SilcServerEntry router,
+                       SilcCipher channel_key)
+{
+  SilcChannelEntry channel;
+
+  channel = silc_calloc(1, sizeof(*channel));
+  channel->channel_name = channel_name;
+  channel->mode = mode;
+  channel->id = id;
+  channel->router = router;
+  channel->channel_key = channel_key;
+
+  if (!silc_idcache_add(id_list->channels, channel->channel_name, 
+                       SILC_ID_CHANNEL, (void *)channel->id, 
+                       (void *)channel, TRUE)) {
+    silc_free(channel);
+    return NULL;
   }
 
-  return NULL;
+  return channel;
 }
 
 /* Free channel entry.  This free's everything. */
 
-void silc_idlist_del_channel(SilcChannelList **list, SilcChannelList *entry)
+void silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
 {
   if (entry) {
+    /* Remove from cache */
+    if (entry->id)
+      silc_idcache_del_by_id(id_list->channels, SILC_ID_CHANNEL, 
+                            (void *)entry->id);
+
+    /* Free data */
     if (entry->channel_name)
       silc_free(entry->channel_name);
     if (entry->id)
@@ -383,27 +302,52 @@ void silc_idlist_del_channel(SilcChannelList **list, SilcChannelList *entry)
 
     if (entry->user_list_count)
       silc_free(entry->user_list);
+  }
+}
 
-    /* Last one in list? */
-    if (*list == entry && entry->next == entry) {
-      *list = NULL;
-      silc_free(entry);
-      return;
-    }
+/* Finds channel by channel name. Channel names are unique and they
+   are not case-sensitive. */
 
-    /* At the start of list? */
-    if (*list == entry && entry->next != entry) {
-      *list = entry->next;
-      entry->next->prev = entry->prev;
-      entry->prev->next = *list;
-      silc_free(entry);
-      return;
-    }
+SilcChannelEntry
+silc_idlist_find_channel_by_name(SilcIDList id_list, char *name)
+{
+  SilcIDCacheList list = NULL;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcChannelEntry channel;
 
-    /* Remove from list */
-    entry->prev->next = entry->next;
-    entry->next->prev = entry->prev;
-    silc_free(entry);
-    return;
-  }
+  SILC_LOG_DEBUG(("Finding channel by name"));
+
+  if (!silc_idcache_find_by_data_loose(id_list->channels, name, &list))
+    return NULL;
+  
+  if (!silc_idcache_list_first(list, &id_cache))
+    return NULL;
+
+  channel = (SilcChannelEntry)id_cache->context;
+
+  silc_idcache_list_free(list);
+
+  return channel;
+}
+
+/* Finds channel by Channel ID. */
+
+SilcChannelEntry
+silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id)
+{
+  SilcIDCacheEntry id_cache = NULL;
+  SilcChannelEntry channel;
+
+  if (!id)
+    return NULL;
+
+  SILC_LOG_DEBUG(("Finding channel by ID"));
+
+  if (!silc_idcache_find_by_id_one(id_list->channels, (void *)id, 
+                                  SILC_ID_CHANNEL, &id_cache))
+    return NULL;
+
+  channel = (SilcChannelEntry)id_cache->context;
+
+  return channel;
 }
index c958e26ab82fd8ca124ee87b0f0a5c7ef9409fb7..d9bfe339fa219f416b41eb93c829c078e34bb6ab 100644 (file)
 #define IDLIST_H
 
 /* Forward declarations */
-typedef struct SilcServerListStruct SilcServerList;
-typedef struct SilcClientListStruct SilcClientList;
-typedef struct SilcChannelListStruct SilcChannelList;
+typedef struct SilcServerEntryStruct *SilcServerEntry;
+typedef struct SilcClientEntryStruct *SilcClientEntry;
+typedef struct SilcChannelEntryStruct *SilcChannelEntry;
 
 /* 
-   SILC Server list object.
+   SILC Server entry object.
 
-   This list holds information about servers in SILC network. However, 
-   contents of this list is highly dependent of what kind of server we are 
-   (normal server or router server) and whether the list is used as a local 
-   list or a global list. These factors dictates the contents of this list.
+   This entry holds information about servers in SILC network. However, 
+   contents of this entry is highly dependent of what kind of server we are 
+   (normal server or router server) and whether the entry is used as a local 
+   list or a global list. These factors dictates the contents of this entry.
 
-   This list is defined as follows:
+   This entry is defined as follows:
 
    Server type   List type      Contents
    =======================================================================
@@ -61,7 +61,7 @@ typedef struct SilcChannelListStruct SilcChannelList;
        the server SILC will ever need. These are also the informations
        that is broadcasted between servers and routers in the SILC network.
 
-   struct SilcServerListStruct *router
+   SilcServerEntry router
 
        This is a pointer back to the server list. This is the router server 
        where this server is connected to. If this is the router itself and 
@@ -79,7 +79,7 @@ typedef struct SilcChannelListStruct SilcChannelList;
        list.
    
 */
-struct SilcServerListStruct {
+struct SilcServerEntryStruct {
   char *server_name;
   int server_type;
   SilcServerID *id;
@@ -88,7 +88,7 @@ struct SilcServerListStruct {
   int registered;
 
   /* Pointer to the router */
-  struct SilcServerListStruct *router;
+  SilcServerEntry router;
 
   /* Keys */
   SilcCipher send_key;
@@ -101,19 +101,16 @@ struct SilcServerListStruct {
 
   /* Connection data */
   void *connection;
-
-  struct SilcServerListStruct *next;
-  struct SilcServerListStruct *prev;
 };
 
 /* 
-   SILC Client list object.
+   SILC Client entry object.
 
-   This list holds information about connected clients ie. users in the SILC
-   network. The contents of this list is depended on whether we are normal 
+   This entry holds information about connected clients ie. users in the SILC
+   network. The contents of this entrt is depended on whether we are normal 
    server or router server and whether the list is a local or global list.
 
-   This list is defined as follows:
+   This entry is defined as follows:
 
    Server type   List type      Contents
    =======================================================================
@@ -168,7 +165,7 @@ struct SilcServerListStruct {
        Client's mode.  Client maybe for example server operator or
        router operator (SILC operator).
 
-   SilcServerList *router
+   SilcServerEntry router
 
        This is a pointer to the server list. This is the router server whose 
        cell this client is coming from. This is used to route messages to 
@@ -197,7 +194,7 @@ struct SilcServerListStruct {
        list.
 
 */
-struct SilcClientListStruct {
+struct SilcClientEntryStruct {
   char *nickname;
   char *username;
   char *userinfo;
@@ -208,10 +205,10 @@ struct SilcClientListStruct {
   int registered;
 
   /* Pointer to the router */
-  SilcServerList *router;
+  SilcServerEntry router;
 
   /* Pointers to channels this client has joined */
-  SilcChannelList **channel;
+  SilcChannelEntry *channel;
   unsigned int channel_count;
 
   /* Keys */
@@ -219,24 +216,22 @@ struct SilcClientListStruct {
   SilcCipher receive_key;
   SilcPKCS pkcs;
   SilcHmac hmac;
+  SilcPublicKey public_key;
   unsigned char *hmac_key;
   unsigned int hmac_key_len;
 
   /* Connection data */
   void *connection;
-
-  struct SilcClientListStruct *next;
-  struct SilcClientListStruct *prev;
 };
 
 /* 
-   SILC Channel Client list structure.
+   SILC Channel Client entry structure.
 
-   This list used only by the SilcChannelList object and it holds information 
-   about current clients (ie. users) on channel. Following short description 
-   of the fields:
+   This entry used only by the SilcChannelEntry object and it holds
+   information about current clients (ie. users) on channel. Following
+   short description  of the fields:
 
-   SilcClientList client
+   SilcClientEntry client
 
        Pointer to the client list. This is the client currently on channel.
 
@@ -245,19 +240,19 @@ struct SilcClientListStruct {
        Client's current mode on the channel.
 
 */
-typedef struct SilcChannelClientListStruct {
-  SilcClientList *client;
+typedef struct SilcChannelClientEntryStruct {
+  SilcClientEntry client;
   int mode;
-} SilcChannelClientList;
+} *SilcChannelClientEntry;
 
 /* 
-   SILC Channel list object.
+   SILC Channel entry object.
 
-   This list holds information about channels in SILC network. The contents 
-   of this list is depended on whether we are normal server or router server 
+   This entry holds information about channels in SILC network. The contents 
+   of this entry is depended on whether we are normal server or router server 
    and whether the list is a local or global list.
 
-   This list is defined as follows:
+   This entry is defined as follows:
 
    Server type   List type      Contents
    =======================================================================
@@ -295,19 +290,28 @@ typedef struct SilcChannelClientListStruct {
 
        Current topic of the channel.
 
-   SilcServerList *router
+   SilcServerEntry router
 
        This is a pointer to the server list. This is the router server 
        whose cell this channel belongs to. This is used to route messages 
        to this channel.
 
-   SilcCipher send_key
+   SilcCipher channel_key
 
+       The key of the channel (the cipher actually).
 
-   SilcCipher receive_key
+   unsigned char *key
+   unsigned int key_len
+
+       Raw key data of the channel key.
+
+   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]
+
+       Current initial vector. Initial vector is received always along
+       with the channel packet. By default this is filled with NULL.
 
 */
-struct SilcChannelListStruct {
+struct SilcChannelEntryStruct {
   char *channel_name;
   int mode;
   SilcChannelID *id;
@@ -315,20 +319,17 @@ struct SilcChannelListStruct {
   char *topic;
 
   /* List of users on channel */
-  SilcChannelClientList *user_list;
+  SilcChannelClientEntry user_list;
   unsigned int user_list_count;
 
   /* Pointer to the router */
-  SilcServerList *router;
+  SilcServerEntry router;
 
   /* Channel keys */
   SilcCipher channel_key;
   unsigned char *key;
   unsigned int key_len;
   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
-
-  struct SilcChannelListStruct *next;
-  struct SilcChannelListStruct *prev;
 };
 
 /* 
@@ -336,22 +337,22 @@ struct SilcChannelListStruct {
 
    As for remainder these lists are defined as follows:
 
-   List        Server type   List type      Contents
+   Entry list (cache)  Server type   List type      Contents
    =======================================================================
-   servers     server        local list     Server itself
-   servers     server        global list    NULL
-   servers     router        local list     All servers in cell
-   servers     router        global list    All servers in SILC
+   servers             server        local list     Server itself
+   servers             server        global list    NULL
+   servers             router        local list     All servers in cell
+   servers             router        global list    All servers in SILC
 
-   clients     server        local list     All clients in server
-   clients     server        global list    NULL
-   clients     router        local list     All clients in cell
-   clients     router        global list    All clients in SILC
+   clients             server        local list     All clients in server
+   clients             server        global list    NULL
+   clients             router        local list     All clients in cell
+   clients             router        global list    All clients in SILC
 
-   channels    server        local list     All channels in server
-   channels    server        global list    NULL
-   channels    router        local list     All channels in cell
-   channels    router        global list    All channels in SILC
+   channels            server        local list     All channels in server
+   channels            server        global list    NULL
+   channels            router        local list     All channels in cell
+   channels            router        global list    All channels in SILC
 
    As seen on the list normal server never defines a global list. This is
    because of normal server don't know anything about anything global data,
@@ -359,33 +360,29 @@ struct SilcChannelListStruct {
    other hand, always define local and global lists because routers really
    know all the relevant data in the SILC network.
 
-*/
-typedef struct SilcIDListStruct {
-  SilcServerList *servers;
-  SilcClientList *clients;
-  SilcChannelList *channels;
+   This object is used as local and global list by the server/router.
+   Above table shows how this is defined on different conditions.
 
-  /* ID Caches. Caches are used to perform fast search on the ID's. */
-  SilcIDCache *server_cache[96];
-  unsigned int server_cache_count[96];
-  SilcIDCache *client_cache[96];
-  unsigned int client_cache_count[96];
-  SilcIDCache *channel_cache[96];
-  unsigned int channel_cache_count[96];
-} SilcIDListObject;
+   This object holds pointers to the ID cache system. Every ID cache entry
+   has a specific context pointer to allocated entry (server, client or
+   channel entry).
 
-typedef SilcIDListObject *SilcIDList;
+*/
+typedef struct SilcIDListStruct {
+  SilcIDCache servers;
+  SilcIDCache clients;
+  SilcIDCache channels;
+} *SilcIDList;
 
 /*
-   Temporary ID List object.
+   Temporary ID Entry object.
 
-   This is used during authentication phases where we still don't
-   know what kind of connection remote connection is, hence, we
-   will use this structure instead until we know what type of
-   connection remote end is.
+   This is used during authentication phases where we still don't know 
+   what kind of connection remote connection is, hence, we will use this
+   structure instead until we know what type of connection remote end is.
 
-   This is not in any list. This is always individually allocated
-   and used as such.
+   This is not in any list. This is always individually allocated and
+   used as such.
 
 */
 typedef struct {
@@ -399,38 +396,40 @@ typedef struct {
   unsigned int hmac_key_len;
 
   /* SilcComp comp */
-} SilcIDListUnknown;
+} *SilcUnknownEntry;
 
 /* Prototypes */
-void silc_idlist_add_server(SilcServerList **list, 
-                           char *server_name, int server_type,
-                           SilcServerID *id, SilcServerList *router,
-                           SilcCipher send_key, SilcCipher receive_key,
-                           SilcPKCS public_key, SilcHmac hmac, 
-                           SilcServerList **new_idlist);
-void silc_idlist_add_client(SilcClientList **list, char *nickname,
-                           char *username, char *userinfo,
-                           SilcClientID *id, SilcServerList *router,
-                           SilcCipher send_key, SilcCipher receive_key,
-                           SilcPKCS public_key, SilcHmac hmac, 
-                           SilcClientList **new_idlist);
-void silc_idlist_del_client(SilcClientList **list, SilcClientList *entry);
-SilcClientList *
-silc_idlist_find_client_by_nickname(SilcClientList *list,
-                                   char *nickname,
+SilcServerEntry 
+silc_idlist_add_server(SilcIDList id_list, 
+                      char *server_name, int server_type,
+                      SilcServerID *id, SilcServerEntry router,
+                      SilcCipher send_key, SilcCipher receive_key,
+                      SilcPKCS pkcs, SilcHmac hmac, 
+                      SilcPublicKey public_key, void *connection);
+SilcClientEntry
+silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
+                      char *userinfo, SilcClientID *id, 
+                      SilcServerEntry router,
+                      SilcCipher send_key, SilcCipher receive_key,
+                      SilcPKCS pkcs, SilcHmac hmac, 
+                      SilcPublicKey public_key, void *connection);
+void silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry);
+SilcClientEntry
+silc_idlist_find_client_by_nickname(SilcIDList id_list, char *nickname,
                                    char *server);
-SilcClientList *
-silc_idlist_find_client_by_hash(SilcClientList *list,
-                               char *nickname, SilcHash hash);
-SilcClientList *
-silc_idlist_find_client_by_id(SilcClientList *list, SilcClientID *id);
-void silc_idlist_add_channel(SilcChannelList **list, 
-                            char *channel_name, int mode,
-                            SilcChannelID *id, SilcServerList *router,
-                            SilcCipher channel_key,
-                            SilcChannelList **new_idlist);
-SilcChannelList *
-silc_idlist_find_channel_by_id(SilcChannelList *list, SilcChannelID *id);
-void silc_idlist_del_channel(SilcChannelList **list, SilcChannelList *entry);
+SilcClientEntry
+silc_idlist_find_client_by_hash(SilcIDList id_list, unsigned char *hash,
+                               SilcHash md5hash);
+SilcClientEntry
+silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id);
+SilcChannelEntry
+silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
+                       SilcChannelID *id, SilcServerEntry router,
+                       SilcCipher channel_key);
+void silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry);
+SilcChannelEntry
+silc_idlist_find_channel_by_name(SilcIDList id_list, char *name);
+SilcChannelEntry
+silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id);
 
 #endif
index d6daeba98b1ea3e14ae3fb35d43fe97c35f90689..3c24e91d41e1ede033be466e8530e40ca234570c 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.6  2000/07/12 05:59:41  priikone
+ *     Major rewrite of ID Cache system. Support added for the new
+ *     ID cache system. Major rewrite of ID List stuff on server.  All
+ *     SilcXXXList's are now called SilcXXXEntry's and they are pointers
+ *     by default. A lot rewritten ID list functions.
+ *
  * Revision 1.5  2000/07/10 05:42:14  priikone
  *     Support for public key encoding functions added.
  *
@@ -92,7 +98,7 @@ static void silc_server_protocol_ke_set_keys(SilcSKE ske,
                                             SilcHash hash,
                                             int is_responder)
 {
-  SilcIDListUnknown *conn_data;
+  SilcUnknownEntry conn_data;
   SilcHash nhash;
 
   SILC_LOG_DEBUG(("Setting new key into use"));
index a46ed51fe44e207ec6829b3b38f7521db2038a9a..5edd731512182d2c9a3a1a4d1d4bbf9f759b145d 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.4  2000/07/12 05:59:41  priikone
+ *     Major rewrite of ID Cache system. Support added for the new
+ *     ID cache system. Major rewrite of ID List stuff on server.  All
+ *     SilcXXXList's are now called SilcXXXEntry's and they are pointers
+ *     by default. A lot rewritten ID list functions.
+ *
  * Revision 1.3  2000/07/05 06:14:01  priikone
  *     Global costemic changes.
  *
@@ -49,7 +55,7 @@ SilcServerRouteTable silc_route_cache[SILC_SERVER_ROUTE_SIZE];
    index value generated by silc_server_route_hash. */
 
 void silc_server_route_add(unsigned int index, unsigned int dest,
-                          SilcServerList *router)
+                          SilcServerEntry router)
 {
   silc_route_cache[index].dest = dest;
   silc_route_cache[index].router = router;
@@ -58,7 +64,7 @@ void silc_server_route_add(unsigned int index, unsigned int dest,
 /* Checksk whether destination has a specific router. Returns the
    router data if found, NULL otherwise. */
 
-SilcServerList *silc_server_route_check(unsigned int dest, 
+SilcServerEntry silc_server_route_check(unsigned int dest, 
                                        unsigned short port)
 {
   unsigned int index;
@@ -81,7 +87,7 @@ SilcSocketConnection silc_server_get_route(SilcServer server, void *id,
 {
   unsigned int dest = 0;
   unsigned short port = 0;
-  SilcServerList *router = NULL;
+  SilcServerEntry router = NULL;
 
   if (server->server_type == SILC_SERVER)
     return (SilcSocketConnection)server->id_entry->router->connection;
index bc0249477c4bb51ee5a28d227699fb379c26444f..b04118d798b681f8c186482c20e3ce250046a352 100644 (file)
        Destination IPv4 address.  Can be used to quickly check whether
        the found route entry is what the caller wanted.
 
-   SilcServerList *router
+   SilcServerEntry router
 
        Pointer to the router specific data.
 
 */
 typedef struct {
   unsigned int dest;
-  SilcServerList *router;
+  SilcServerEntry router;
 } SilcServerRouteTable;
 
 /* Route cache hash table */
@@ -70,8 +70,8 @@ unsigned int silc_server_route_hash(unsigned int addr,
 
 /* Prototypes */
 void silc_server_route_add(unsigned int index, unsigned int dest,
-                          SilcServerList *router);
-SilcServerList *silc_server_route_check(unsigned int dest, 
+                          SilcServerEntry router);
+SilcServerEntry silc_server_route_check(unsigned int dest, 
                                        unsigned short port);
 SilcSocketConnection silc_server_get_route(SilcServer server, void *id,
                                           SilcIdType id_type);
index c0836ec73bd90e42b355ba007fa985ba46a35846..691bd524a82fc30d46fed644612a8496565176c6 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.8  2000/07/12 05:59:41  priikone
+ *     Major rewrite of ID Cache system. Support added for the new
+ *     ID cache system. Major rewrite of ID List stuff on server.  All
+ *     SilcXXXList's are now called SilcXXXEntry's and they are pointers
+ *     by default. A lot rewritten ID list functions.
+ *
  * Revision 1.7  2000/07/10 05:43:00  priikone
  *     Removed command packet processing from server.c and added it to
  *     command.c.
@@ -89,27 +95,17 @@ extern char server_version[];
 
 int silc_server_alloc(SilcServer *new_server)
 {
+  SilcServer server;
+
   SILC_LOG_DEBUG(("Allocating new server object"));
 
-  *new_server = silc_calloc(1, sizeof(**new_server));
-  if (*new_server == NULL) {
-    SILC_LOG_ERROR(("Could not allocate new server object"));
-    return FALSE;
-  }
+  server = silc_calloc(1, sizeof(*server));
+  server->server_type = SILC_SERVER;
+  server->standalone = FALSE;
+  server->local_list = silc_calloc(1, sizeof(*server->local_list));
+  server->global_list = silc_calloc(1, sizeof(*server->global_list));
 
-  /* Set default values */
-  (*new_server)->server_name = NULL;
-  (*new_server)->server_type = SILC_SERVER;
-  (*new_server)->standalone = FALSE;
-  (*new_server)->id = NULL;
-  (*new_server)->io_queue = NULL;
-  (*new_server)->timeout_queue = NULL;
-  (*new_server)->local_list = silc_calloc(1, sizeof(SilcIDListObject));
-  (*new_server)->global_list = silc_calloc(1, sizeof(SilcIDListObject));
-  (*new_server)->rng = NULL;
-  (*new_server)->md5hash = NULL;
-  (*new_server)->sha1hash = NULL;
-  /*  (*new_server)->public_key = NULL;*/
+  *new_server = server;
 
   return TRUE;
 }
@@ -143,7 +139,7 @@ int silc_server_init(SilcServer server)
 {
   int *sock = NULL, sock_count = 0, i;
   SilcServerID *id;
-  SilcServerList *id_entry;
+  SilcServerEntry id_entry;
 
   SILC_LOG_DEBUG(("Initializing server"));
   assert(server);
@@ -240,6 +236,17 @@ int silc_server_init(SilcServer server)
     sock_count++;
   }
 
+  /* Initialize ID caches */
+  server->local_list->clients = silc_idcache_alloc(0);
+  server->local_list->servers = silc_idcache_alloc(0);
+  server->local_list->channels = silc_idcache_alloc(0);
+
+  if (server->server_type == SILC_ROUTER) {
+    server->global_list->clients = silc_idcache_alloc(0);
+    server->global_list->servers = silc_idcache_alloc(0);
+    server->global_list->channels = silc_idcache_alloc(0);
+  }
+
   /* Allocate the entire socket list that is used in server. Eventually 
      all connections will have entry in this table (it is a table of 
      pointers to the actual object that is allocated individually 
@@ -268,13 +275,16 @@ int silc_server_init(SilcServer server)
        beacuse we haven't established a route yet. It will be done later. 
        For now, NULL is sent as router. This allocates new entry to
        the ID list. */
-    silc_idlist_add_server(&server->local_list->servers, 
-                          server->config->server_info->server_name,
-                          server->server_type, server->id, NULL,
-                          server->send_key, server->receive_key,
-                          NULL, NULL, &id_entry);
-    if (!id_entry)
+    id_entry = 
+      silc_idlist_add_server(server->local_list,
+                            server->config->server_info->server_name,
+                            server->server_type, server->id, NULL,
+                            server->send_key, server->receive_key,
+                            NULL, NULL, NULL, NULL);
+    if (!id_entry) {
+      SILC_LOG_ERROR(("Could not add ourselves to cache"));
       goto err0;
+    }
     
     /* Add ourselves also to the socket table. The entry allocated above
        is sent as argument for fast referencing in the future. */
@@ -653,8 +663,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
     (SilcServerConnAuthInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
   SilcSocketConnection sock = ctx->sock;
-  SilcServerList *id_entry;
-  SilcIDListUnknown *conn_data;
+  SilcServerEntry id_entry;
+  SilcUnknownEntry conn_data;
   SilcBuffer packet;
   unsigned char *id_string;
 
@@ -715,20 +725,21 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
 
   /* Add the connected router to local server list */
   server->standalone = FALSE;
-  conn_data = (SilcIDListUnknown *)sock->user_data;
-  silc_idlist_add_server(&server->local_list->servers, 
-                        sock->hostname ? sock->hostname : sock->ip,
-                        SILC_ROUTER, ctx->dest_id, NULL,
-                        conn_data->send_key, conn_data->receive_key,
-                        conn_data->pkcs, conn_data->hmac, &id_entry);
-
-  id_entry->hmac_key = conn_data->hmac_key;
-  id_entry->hmac_key_len = conn_data->hmac_key_len;
-  id_entry->connection = sock;
-  sock->user_data = (void *)id_entry;
-  sock->type = SILC_SOCKET_TYPE_ROUTER;
-  server->id_entry->router = id_entry;
-
+  conn_data = (SilcUnknownEntry)sock->user_data;
+  id_entry =
+    silc_idlist_add_server(server->local_list, 
+                          sock->hostname ? sock->hostname : sock->ip,
+                          SILC_ROUTER, ctx->dest_id, NULL,
+                          conn_data->send_key, conn_data->receive_key,
+                          conn_data->pkcs, conn_data->hmac, NULL, sock);
+  if (id_entry) {
+    id_entry->hmac_key = conn_data->hmac_key;
+    id_entry->hmac_key_len = conn_data->hmac_key_len;
+    sock->user_data = (void *)id_entry;
+    sock->type = SILC_SOCKET_TYPE_ROUTER;
+    server->id_entry->router = id_entry;
+  }
+    
   /* Free the temporary connection data context from key exchange */
   silc_free(conn_data);
 
@@ -933,67 +944,74 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     {
-      SilcClientList *id_entry = NULL;
-      SilcIDListUnknown *conn_data = sock->user_data;
+      SilcClientEntry client;
+      SilcUnknownEntry conn_data = (SilcUnknownEntry)sock->user_data;
 
       SILC_LOG_DEBUG(("Remote host is client"));
-
       SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname,
                     sock->ip));
 
-      /* Add the client to the client ID list. We have not created the
-        client ID for the client yet. This is done when client registers
-        itself by sending NEW_CLIENT packet. */
-      silc_idlist_add_client(&server->local_list->clients, 
-                            NULL, NULL, NULL, NULL, NULL,
-                            conn_data->send_key, conn_data->receive_key, 
-                            conn_data->pkcs, conn_data->hmac, &id_entry);
-
-      id_entry->hmac_key = conn_data->hmac_key;
-      id_entry->hmac_key_len = conn_data->hmac_key_len;
-      id_entry->connection = sock;
+      /* Add the client to the client ID cache. The nickname and Client ID
+        and other information is created after we have received NEW_CLIENT
+        packet from client. */
+      client = 
+       silc_idlist_add_client(server->local_list, NULL, NULL, NULL, NULL,
+                              NULL, conn_data->send_key, 
+                              conn_data->receive_key, conn_data->pkcs,
+                              conn_data->hmac, NULL, sock);
+      if (!client) {
+       SILC_LOG_ERROR(("Could not add new client to cache"));
+       silc_free(conn_data);
+       break;
+      }
 
+      client->hmac_key = conn_data->hmac_key;
+      client->hmac_key_len = conn_data->hmac_key_len;
+      
       /* Free the temporary connection data context from key exchange */
       silc_free(conn_data);
 
-      /* Mark the entry to the ID list to the socket connection for
-        fast referencing in the future. */
-      sock->user_data = (void *)id_entry;
+      /* Add to sockets internal pointer for fast referencing */
+      sock->user_data = (void *)client;
       break;
     }
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     {
-      SilcServerList *id_entry;
-      SilcIDListUnknown *conn_data = sock->user_data;
-      
+      SilcServerEntry new_server;
+      SilcUnknownEntry conn_data = (SilcUnknownEntry)sock->user_data;
+
       SILC_LOG_DEBUG(("Remote host is %s", 
                      sock->type == SILC_SOCKET_TYPE_SERVER ? 
                      "server" : "router"));
-      
       SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname,
                     sock->ip, sock->type == SILC_SOCKET_TYPE_SERVER ? 
                     "server" : "router"));
 
-      /* Add the server to the ID list. We don't have the server's ID
-        yet but we will receive it after the server sends NEW_SERVER
-        packet to us. */
-      silc_idlist_add_server(&server->local_list->servers, NULL,
-                            sock->type == SILC_SOCKET_TYPE_SERVER ?
-                            SILC_SERVER : SILC_ROUTER, NULL, NULL,
-                            conn_data->send_key, conn_data->receive_key,
-                            conn_data->pkcs, conn_data->hmac, &id_entry);
-
-      id_entry->hmac_key = conn_data->hmac_key;
-      id_entry->hmac_key_len = conn_data->hmac_key_len;
-      id_entry->connection = sock;
-
-      /* Free the temporary connection data context from key exchange */
+      /* Add the server into server cache. The server name and Server ID
+        is updated after we have received NEW_SERVER packet from the
+        server. */
+      new_server = 
+       silc_idlist_add_server(server->local_list, NULL,
+                              sock->type == SILC_SOCKET_TYPE_SERVER ?
+                              SILC_SERVER : SILC_ROUTER, NULL, NULL,
+                              conn_data->send_key, conn_data->receive_key,
+                              conn_data->pkcs, conn_data->hmac, NULL, sock);
+      if (!new_server) {
+       SILC_LOG_ERROR(("Could not add new server to cache"));
+       silc_free(conn_data);
+       break;
+      }
+      
+      new_server->registered = TRUE;
+      new_server->hmac_key = conn_data->hmac_key;
+      new_server->hmac_key_len = conn_data->hmac_key_len;
+      
+      /* Free the temporary connection data context from protocols */
       silc_free(conn_data);
 
-      /* Mark the entry to the ID list to the socket connection for
-        fast referencing in the future. */
-      sock->user_data = (void *)id_entry;
+      /* Add to sockets internal pointer for fast referencing */
+      sock->user_data = (void *)new_server;
 
       /* There is connection to other server now, if it is router then
         we will have connection to outside world.  If we are router but
@@ -1135,7 +1153,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
 
     /* Decrypt a packet coming from client. */
     if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
-      SilcClientList *clnt = (SilcClientList *)sock->user_data;
+      SilcClientEntry clnt = (SilcClientEntry)sock->user_data;
       SilcServerInternalPacket *packet;
       int mac_len = 0;
       
@@ -1218,7 +1236,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
     /* Decrypt a packet coming from server connection */
     if (sock->type == SILC_SOCKET_TYPE_SERVER ||
        sock->type == SILC_SOCKET_TYPE_ROUTER) {
-      SilcServerList *srvr = (SilcServerList *)sock->user_data;
+      SilcServerEntry srvr = (SilcServerEntry)sock->user_data;
       SilcServerInternalPacket *packet;
       int mac_len = 0;
       
@@ -1309,7 +1327,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
 
     /* Decrypt a packet coming from client. */
     if (sock->type == SILC_SOCKET_TYPE_UNKNOWN) {
-      SilcIDListUnknown *conn_data = (SilcIDListUnknown *)sock->user_data;
+      SilcUnknownEntry conn_data = (SilcUnknownEntry)sock->user_data;
       SilcServerInternalPacket *packet;
       
       SILC_LOG_HEXDUMP(("Incoming packet, len %d", sock->inbuf->len),
@@ -1359,24 +1377,24 @@ static int silc_server_packet_check_mac(SilcServer server,
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     if (sock->user_data) {
-      hmac = ((SilcClientList *)sock->user_data)->hmac;
-      hmac_key = ((SilcClientList *)sock->user_data)->hmac_key;
-      hmac_key_len = ((SilcClientList *)sock->user_data)->hmac_key_len;
+      hmac = ((SilcClientEntry)sock->user_data)->hmac;
+      hmac_key = ((SilcClientEntry)sock->user_data)->hmac_key;
+      hmac_key_len = ((SilcClientEntry)sock->user_data)->hmac_key_len;
     }
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     if (sock->user_data) {
-      hmac = ((SilcServerList *)sock->user_data)->hmac;
-      hmac_key = ((SilcServerList *)sock->user_data)->hmac_key;
-      hmac_key_len = ((SilcServerList *)sock->user_data)->hmac_key_len;
+      hmac = ((SilcServerEntry)sock->user_data)->hmac;
+      hmac_key = ((SilcServerEntry)sock->user_data)->hmac_key;
+      hmac_key_len = ((SilcServerEntry)sock->user_data)->hmac_key_len;
     }
     break;
   default:
     if (sock->user_data) {
-      hmac = ((SilcIDListUnknown *)sock->user_data)->hmac;
-      hmac_key = ((SilcIDListUnknown *)sock->user_data)->hmac_key;
-      hmac_key_len = ((SilcIDListUnknown *)sock->user_data)->hmac_key_len;
+      hmac = ((SilcUnknownEntry)sock->user_data)->hmac;
+      hmac_key = ((SilcUnknownEntry)sock->user_data)->hmac_key;
+      hmac_key_len = ((SilcUnknownEntry)sock->user_data)->hmac_key_len;
     }
   }
 
@@ -1432,21 +1450,21 @@ static int silc_server_packet_decrypt_rest(SilcServer server,
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     if (sock->user_data) {
-      session_key = ((SilcClientList *)sock->user_data)->receive_key;
-      hmac = ((SilcClientList *)sock->user_data)->hmac;
+      session_key = ((SilcClientEntry)sock->user_data)->receive_key;
+      hmac = ((SilcClientEntry)sock->user_data)->hmac;
     }
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     if (sock->user_data) {
-      session_key = ((SilcServerList *)sock->user_data)->receive_key;
-      hmac = ((SilcServerList *)sock->user_data)->hmac;
+      session_key = ((SilcServerEntry)sock->user_data)->receive_key;
+      hmac = ((SilcServerEntry)sock->user_data)->hmac;
     }
     break;
   default:
     if (sock->user_data) {
-      session_key = ((SilcIDListUnknown *)sock->user_data)->receive_key;
-      hmac = ((SilcIDListUnknown *)sock->user_data)->hmac;
+      session_key = ((SilcUnknownEntry)sock->user_data)->receive_key;
+      hmac = ((SilcUnknownEntry)sock->user_data)->hmac;
     }
   }
   
@@ -1494,21 +1512,21 @@ static int silc_server_packet_decrypt_rest_special(SilcServer server,
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     if (sock->user_data) {
-      session_key = ((SilcClientList *)sock->user_data)->receive_key;
-      hmac = ((SilcClientList *)sock->user_data)->hmac;
+      session_key = ((SilcClientEntry)sock->user_data)->receive_key;
+      hmac = ((SilcClientEntry)sock->user_data)->hmac;
     }
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     if (sock->user_data) {
-      session_key = ((SilcServerList *)sock->user_data)->receive_key;
-      hmac = ((SilcServerList *)sock->user_data)->hmac;
+      session_key = ((SilcServerEntry)sock->user_data)->receive_key;
+      hmac = ((SilcServerEntry)sock->user_data)->hmac;
     }
     break;
   default:
     if (sock->user_data) {
-      session_key = ((SilcIDListUnknown *)sock->user_data)->receive_key;
-      hmac = ((SilcIDListUnknown *)sock->user_data)->hmac;
+      session_key = ((SilcUnknownEntry)sock->user_data)->receive_key;
+      hmac = ((SilcUnknownEntry)sock->user_data)->hmac;
     }
   }
   
@@ -1948,15 +1966,15 @@ void silc_server_packet_send(SilcServer server,
   /* Get data used in the packet sending, keys and stuff */
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
-    if (((SilcClientList *)sock->user_data)->id) {
-      dst_id = ((SilcClientList *)sock->user_data)->id;
+    if (((SilcClientEntry)sock->user_data)->id) {
+      dst_id = ((SilcClientEntry)sock->user_data)->id;
       dst_id_type = SILC_ID_CLIENT;
     }
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
-    if (((SilcServerList *)sock->user_data)->id) {
-      dst_id = ((SilcServerList *)sock->user_data)->id;
+    if (((SilcServerEntry)sock->user_data)->id) {
+      dst_id = ((SilcServerEntry)sock->user_data)->id;
       dst_id_type = SILC_ID_SERVER;
     }
     break;
@@ -2001,24 +2019,24 @@ void silc_server_packet_send_dest(SilcServer server,
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     if (sock->user_data) {
-      cipher = ((SilcClientList *)sock->user_data)->send_key;
-      hmac = ((SilcClientList *)sock->user_data)->hmac;
+      cipher = ((SilcClientEntry)sock->user_data)->send_key;
+      hmac = ((SilcClientEntry)sock->user_data)->hmac;
       if (hmac) {
        mac_len = hmac->hash->hash->hash_len;
-       hmac_key = ((SilcClientList *)sock->user_data)->hmac_key;
-       hmac_key_len = ((SilcClientList *)sock->user_data)->hmac_key_len;
+       hmac_key = ((SilcClientEntry)sock->user_data)->hmac_key;
+       hmac_key_len = ((SilcClientEntry)sock->user_data)->hmac_key_len;
       }
     }
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     if (sock->user_data) {
-      cipher = ((SilcServerList *)sock->user_data)->send_key;
-      hmac = ((SilcServerList *)sock->user_data)->hmac;
+      cipher = ((SilcServerEntry)sock->user_data)->send_key;
+      hmac = ((SilcServerEntry)sock->user_data)->hmac;
       if (hmac) {
        mac_len = hmac->hash->hash->hash_len;
-       hmac_key = ((SilcServerList *)sock->user_data)->hmac_key;
-       hmac_key_len = ((SilcServerList *)sock->user_data)->hmac_key_len;
+       hmac_key = ((SilcServerEntry)sock->user_data)->hmac_key;
+       hmac_key_len = ((SilcServerEntry)sock->user_data)->hmac_key_len;
       }
     }
     break;
@@ -2026,12 +2044,12 @@ void silc_server_packet_send_dest(SilcServer server,
     if (sock->user_data) {
       /* We don't know what type of connection this is thus it must
         be in authentication phase. */
-      cipher = ((SilcIDListUnknown *)sock->user_data)->send_key;
-      hmac = ((SilcIDListUnknown *)sock->user_data)->hmac;
+      cipher = ((SilcUnknownEntry)sock->user_data)->send_key;
+      hmac = ((SilcUnknownEntry)sock->user_data)->hmac;
       if (hmac) {
        mac_len = hmac->hash->hash->hash_len;
-       hmac_key = ((SilcIDListUnknown *)sock->user_data)->hmac_key;
-       hmac_key_len = ((SilcIDListUnknown *)sock->user_data)->hmac_key_len;
+       hmac_key = ((SilcUnknownEntry)sock->user_data)->hmac_key;
+       hmac_key_len = ((SilcUnknownEntry)sock->user_data)->hmac_key_len;
       }
     }
     break;
@@ -2128,24 +2146,24 @@ void silc_server_packet_forward(SilcServer server,
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     if (sock->user_data) {
-      cipher = ((SilcClientList *)sock->user_data)->send_key;
-      hmac = ((SilcClientList *)sock->user_data)->hmac;
+      cipher = ((SilcClientEntry )sock->user_data)->send_key;
+      hmac = ((SilcClientEntry )sock->user_data)->hmac;
       if (hmac) {
        mac_len = hmac->hash->hash->hash_len;
-       hmac_key = ((SilcClientList *)sock->user_data)->hmac_key;
-       hmac_key_len = ((SilcClientList *)sock->user_data)->hmac_key_len;
+       hmac_key = ((SilcClientEntry )sock->user_data)->hmac_key;
+       hmac_key_len = ((SilcClientEntry )sock->user_data)->hmac_key_len;
       }
     }
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     if (sock->user_data) {
-      cipher = ((SilcServerList *)sock->user_data)->send_key;
-      hmac = ((SilcServerList *)sock->user_data)->hmac;
+      cipher = ((SilcServerEntry )sock->user_data)->send_key;
+      hmac = ((SilcServerEntry )sock->user_data)->hmac;
       if (hmac) {
        mac_len = hmac->hash->hash->hash_len;
-       hmac_key = ((SilcServerList *)sock->user_data)->hmac_key;
-       hmac_key_len = ((SilcServerList *)sock->user_data)->hmac_key_len;
+       hmac_key = ((SilcServerEntry )sock->user_data)->hmac_key;
+       hmac_key_len = ((SilcServerEntry )sock->user_data)->hmac_key_len;
       }
     }
     break;
@@ -2195,7 +2213,7 @@ void silc_server_packet_forward(SilcServer server,
    channel, things like notify about new user joining to the channel. */
 
 void silc_server_packet_send_to_channel(SilcServer server,
-                                       SilcChannelList *channel,
+                                       SilcChannelEntry channel,
                                        unsigned char *data,
                                        unsigned int data_len,
                                        int force_send)
@@ -2203,8 +2221,8 @@ void silc_server_packet_send_to_channel(SilcServer server,
   int i;
   SilcSocketConnection sock = NULL;
   SilcPacketContext packetdata;
-  SilcClientList *client = NULL;
-  SilcServerList **routed = NULL;
+  SilcClientEntry client = NULL;
+  SilcServerEntry *routed = NULL;
   unsigned int routed_count = 0;
   unsigned char *hmac_key = NULL;
   unsigned int hmac_key_len = 0;
@@ -2251,7 +2269,7 @@ void silc_server_packet_send_to_channel(SilcServer server,
      first to our router for further routing. */
   if (server->server_type == SILC_SERVER && !server->standalone &&
       channel->global_users) {
-    SilcServerList *router;
+    SilcServerEntry router;
 
     /* Get data used in packet header encryption, keys and stuff. */
     router = server->id_entry->router;
@@ -2450,7 +2468,7 @@ void silc_server_packet_send_to_channel(SilcServer server,
 
 void silc_server_packet_relay_to_channel(SilcServer server,
                                         SilcSocketConnection sender_sock,
-                                        SilcChannelList *channel,
+                                        SilcChannelEntry channel,
                                         void *sender, 
                                         SilcIdType sender_type,
                                         unsigned char *data,
@@ -2460,8 +2478,8 @@ void silc_server_packet_relay_to_channel(SilcServer server,
   int i, found = FALSE;
   SilcSocketConnection sock = NULL;
   SilcPacketContext packetdata;
-  SilcClientList *client = NULL;
-  SilcServerList **routed = NULL;
+  SilcClientEntry client = NULL;
+  SilcServerEntry *routed = NULL;
   unsigned int routed_count = 0;
   unsigned char *hmac_key = NULL;
   unsigned int hmac_key_len = 0;
@@ -2492,7 +2510,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
      first to our router for further routing. */
   if (server->server_type == SILC_SERVER && !server->standalone &&
       channel->global_users) {
-    SilcServerList *router;
+    SilcServerEntry router;
 
     router = server->id_entry->router;
 
@@ -2704,7 +2722,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
    the client. */
 
 void silc_server_packet_send_local_channel(SilcServer server,
-                                          SilcChannelList *channel,
+                                          SilcChannelEntry channel,
                                           SilcPacketType type,
                                           SilcPacketFlags flags,
                                           unsigned char *data,
@@ -2712,7 +2730,7 @@ void silc_server_packet_send_local_channel(SilcServer server,
                                           int force_send)
 {
   int i;
-  SilcClientList *client;
+  SilcClientEntry client;
   SilcSocketConnection sock = NULL;
 
   SILC_LOG_DEBUG(("Start"));
@@ -2743,7 +2761,7 @@ void silc_server_packet_relay_command_reply(SilcServer server,
                                            SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
-  SilcClientList *client;
+  SilcClientEntry client;
   SilcClientID *id;
   SilcSocketConnection dst_sock;
   unsigned char mac[32];
@@ -2768,7 +2786,7 @@ void silc_server_packet_relay_command_reply(SilcServer server,
   id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
 
   /* Destination must be one of ours */
-  client = silc_idlist_find_client_by_id(server->local_list->clients, id);
+  client = silc_idlist_find_client_by_id(server->local_list, id);
   if (!client) {
     silc_free(id);
     goto out;
@@ -2871,26 +2889,17 @@ void silc_server_free_sock_user_data(SilcServer server,
 {
   SILC_LOG_DEBUG(("Start"));
 
-#define LCC(x) server->local_list->client_cache[(x) - 32]
-#define LCCC(x) server->local_list->client_cache_count[(x) - 32]
-
   switch(sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     {
-      SilcClientList *user_data = (SilcClientList *)sock->user_data;
+      SilcClientEntry user_data = (SilcClientEntry )sock->user_data;
 
       /* Remove client from all channels */
       silc_server_remove_from_channels(server, sock, user_data);
 
-      /* Clear ID cache */
-      if (user_data->nickname && user_data->id)
-       silc_idcache_del_by_id(LCC(user_data->nickname[0]),
-                              LCCC(user_data->nickname[0]),
-                              SILC_ID_CLIENT, user_data->id);
-
       /* Free the client entry and everything in it */
       /* XXX must take some info to history before freeing */
-      silc_idlist_del_client(&server->local_list->clients, user_data);
+      silc_idlist_del_client(server->local_list, user_data);
       break;
     }
   case SILC_SOCKET_TYPE_SERVER:
@@ -2902,7 +2911,7 @@ void silc_server_free_sock_user_data(SilcServer server,
     break;
   default:
     {
-      SilcIDListUnknown *user_data = (SilcIDListUnknown *)sock->user_data;
+      SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
 
       if (user_data->send_key)
        silc_cipher_free(user_data->send_key);
@@ -2931,13 +2940,10 @@ void silc_server_free_sock_user_data(SilcServer server,
 
 void silc_server_remove_from_channels(SilcServer server, 
                                      SilcSocketConnection sock,
-                                     SilcClientList *client)
+                                     SilcClientEntry client)
 {
   int i, k;
-  SilcChannelList *channel;
-
-#define LCC(x) server->local_list->channel_cache[(x) - 32]
-#define LCCC(x) server->local_list->channel_cache_count[(x) - 32]
+  SilcChannelEntry channel;
 
   /* Remove the client from all channels. The client is removed from
      the channels' user list. */
@@ -2953,10 +2959,7 @@ void silc_server_remove_from_channels(SilcServer server,
        /* If this client is last one on the channel the channel
           is removed all together. */
        if (channel->user_list_count == 1) {
-         silc_idcache_del_by_id(LCC(channel->channel_name[0]),
-                                LCCC(channel->channel_name[0]),
-                                SILC_ID_CHANNEL, channel->id);
-         silc_idlist_del_channel(&server->local_list->channels, channel);
+         silc_idlist_del_channel(server->local_list, channel);
          break;
        }
 
@@ -2975,8 +2978,6 @@ void silc_server_remove_from_channels(SilcServer server,
   if (client->channel_count)
     silc_free(client->channel);
   client->channel = NULL;
-#undef LCC
-#undef LCCC
 }
 
 /* Removes client from one channel. This is used for example when client
@@ -2986,14 +2987,11 @@ void silc_server_remove_from_channels(SilcServer server,
 
 int silc_server_remove_from_one_channel(SilcServer server, 
                                        SilcSocketConnection sock,
-                                       SilcChannelList *channel,
-                                       SilcClientList *client)
+                                       SilcChannelEntry channel,
+                                       SilcClientEntry client)
 {
   int i, k;
-  SilcChannelList *ch;
-
-#define LCC(x) server->local_list->channel_cache[(x) - 32]
-#define LCCC(x) server->local_list->channel_cache_count[(x) - 32]
+  SilcChannelEntry ch;
 
   /* Remove the client from the channel. The client is removed from
      the channel's user list. */
@@ -3012,10 +3010,7 @@ 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 (channel->user_list_count == 1) {
-         silc_idcache_del_by_id(LCC(channel->channel_name[0]),
-                                LCCC(channel->channel_name[0]),
-                                SILC_ID_CHANNEL, channel->id);
-         silc_idlist_del_channel(&server->local_list->channels, channel);
+         silc_idlist_del_channel(server->local_list, channel);
          return FALSE;
        }
        
@@ -3032,8 +3027,6 @@ int silc_server_remove_from_one_channel(SilcServer server,
   }
 
   return TRUE;
-#undef LCC
-#undef LCCC
 }
 
 /* Returns TRUE if the given client is on the channel.  FALSE if not. 
@@ -3042,8 +3035,8 @@ int silc_server_remove_from_one_channel(SilcServer server,
    `client' which is faster than checking the user list from `channel'. */
 /* XXX This really is utility function and should be in eg. serverutil.c */
 
-int silc_server_client_on_channel(SilcClientList *client,
-                                 SilcChannelList *channel)
+int silc_server_client_on_channel(SilcClientEntry client,
+                                 SilcChannelEntry channel)
 {
   int i;
 
@@ -3080,7 +3073,7 @@ SILC_TASK_CALLBACK(silc_server_timeout_remote)
 static void 
 silc_server_private_message_send_internal(SilcServer server,
                                          SilcSocketConnection dst_sock,
-                                         SilcServerList *router,
+                                         SilcServerEntry router,
                                          SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
@@ -3135,7 +3128,7 @@ silc_server_private_message_send_internal(SilcServer server,
 static void
 silc_server_private_message_send_local(SilcServer server,
                                       SilcSocketConnection dst_sock,
-                                      SilcClientList *client,
+                                      SilcClientEntry client,
                                       SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
@@ -3198,9 +3191,9 @@ void silc_server_private_message(SilcServer server,
 {
   SilcBuffer buffer = packet->buffer;
   SilcClientID *id;
-  SilcServerList *router;
+  SilcServerEntry router;
   SilcSocketConnection dst_sock;
-  SilcClientList *client;
+  SilcClientEntry client;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -3222,7 +3215,7 @@ void silc_server_private_message(SilcServer server,
      is so sucky that it cannot be used... it MUST be rewritten! Using
      this search is probably faster than if we'd use here the current
      idcache system. */
-  client = silc_idlist_find_client_by_id(server->local_list->clients, id);
+  client = silc_idlist_find_client_by_id(server->local_list, id);
   if (client) {
     /* It exists, now deliver the message to the destination */
     dst_sock = (SilcSocketConnection)client->connection;
@@ -3270,35 +3263,14 @@ void silc_server_private_message(SilcServer server,
   silc_buffer_free(buffer);
 }
 
-SilcChannelList *silc_find_channel(SilcServer server, SilcChannelID *id)
-{
-  int i;
-  SilcIDCache *id_cache;
-
-#define LCC(x) server->local_list->channel_cache[(x)]
-#define LCCC(x) server->local_list->channel_cache_count[(x)]
-
-  for (i = 0; i < 96; i++) {
-    if (LCC(i) == NULL)
-      continue;
-    if (silc_idcache_find_by_id(LCC(i), LCCC(i), (void *)id, 
-                               SILC_ID_CHANNEL, &id_cache))
-      return (SilcChannelList *)id_cache->context;
-  }
-  
-  return NULL;
-#undef LCC
-#undef LCCC
-}
-
 /* Process received channel message. */
 
 void silc_server_channel_message(SilcServer server,
                                 SilcSocketConnection sock,
                                 SilcPacketContext *packet)
 {
-  SilcChannelList *channel = NULL;
-  SilcClientList *client = NULL;
+  SilcChannelEntry channel = NULL;
+  SilcClientEntry client = NULL;
   SilcChannelID *id = NULL;
   SilcClientID *sender = NULL;
   SilcBuffer buffer = packet->buffer;
@@ -3319,7 +3291,7 @@ void silc_server_channel_message(SilcServer server,
 
   /* Find channel entry */
   id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
-  channel = silc_find_channel(server, id);
+  channel = silc_idlist_find_channel_by_id(server->local_list, id);
   if (!channel) {
     SILC_LOG_DEBUG(("Could not find channel"));
     goto out;
@@ -3362,8 +3334,8 @@ void silc_server_channel_key(SilcServer server,
   SilcBuffer buffer = packet->buffer;
   SilcChannelKeyPayload payload = NULL;
   SilcChannelID *id = NULL;
-  SilcChannelList *channel;
-  SilcClientList *client;
+  SilcChannelEntry channel;
+  SilcClientEntry client;
   unsigned char *key;
   unsigned int key_len;
   char *cipher;
@@ -3377,7 +3349,7 @@ void silc_server_channel_key(SilcServer server,
   payload = silc_channel_key_parse_payload(buffer);
   if (!payload) {
     SILC_LOG_ERROR(("Bad channel key payload, dropped"));
-    SILC_LOG_DEBUG(("Bad channel key payload, dropped"));
+    goto out;
   }
 
   /* Get channel ID */
@@ -3386,10 +3358,9 @@ void silc_server_channel_key(SilcServer server,
     goto out;
 
   /* Get the channel entry */
-  channel = silc_idlist_find_channel_by_id(server->local_list->channels, id);
+  channel = silc_idlist_find_channel_by_id(server->local_list, id);
   if (!channel) {
     SILC_LOG_ERROR(("Received key for non-existent channel"));
-    SILC_LOG_DEBUG(("Received key for non-existent channel"));
     goto out;
   }
 
@@ -3491,7 +3462,7 @@ void silc_server_send_notify_dest(SilcServer server,
    client side. */
 
 void silc_server_send_notify_to_channel(SilcServer server,
-                                       SilcChannelList *channel,
+                                       SilcChannelEntry channel,
                                        const char *fmt, ...)
 {
   va_list ap;
@@ -3589,22 +3560,19 @@ void silc_server_send_replace_id(SilcServer server,
 
 /* Creates new channel. */
 
-SilcChannelList *silc_server_new_channel(SilcServer server, 
+SilcChannelEntry silc_server_new_channel(SilcServer server, 
                                         SilcServerID *router_id,
                                         char *cipher, char *channel_name)
 {
   int i, channel_len, key_len;
   SilcChannelID *channel_id;
-  SilcChannelList *entry;
+  SilcChannelEntry entry;
   SilcCipher key;
   unsigned char channel_key[32], *id_string;
   SilcBuffer packet;
 
   SILC_LOG_DEBUG(("Creating new channel"));
 
-#define LCC(x) server->local_list->channel_cache[(x) - 32]
-#define LCCC(x) server->local_list->channel_cache_count[(x) - 32]
-
   /* Create channel key */
   for (i = 0; i < 32; i++)
     channel_key[i] = silc_rng_get_byte(server->rng);
@@ -3619,13 +3587,16 @@ SilcChannelList *silc_server_new_channel(SilcServer server,
 
   /* Create the channel */
   silc_id_create_channel_id(router_id, server->rng, &channel_id);
-  silc_idlist_add_channel(&server->local_list->channels, channel_name, 
-                         SILC_CHANNEL_MODE_NONE, channel_id, NULL, /*XXX*/
-                         key, &entry);
-  LCCC(channel_name[0]) = silc_idcache_add(&LCC(channel_name[0]), 
-                                          LCCC(channel_name[0]),
-                                          channel_name, SILC_ID_CHANNEL, 
-                                          channel_id, (void *)entry);
+  entry = silc_idlist_add_channel(server->local_list, channel_name, 
+                                 SILC_CHANNEL_MODE_NONE, channel_id, 
+                                 NULL, key);
+  if (!entry)
+    return NULL;
+
+  /* Add to cache */
+  silc_idcache_add(server->local_list->channels, channel_name,
+                  SILC_ID_CHANNEL, channel_id, (void *)entry, TRUE);
+
   entry->key = silc_calloc(key_len, sizeof(*entry->key));
   entry->key_len = key_len * 8;
   memcpy(entry->key, channel_key, key_len);
@@ -3656,60 +3627,71 @@ SilcChannelList *silc_server_new_channel(SilcServer server,
     silc_buffer_free(packet);
   }
 
-#undef LCC
-#undef LCCC
   return entry;
 }
 
 /* Create new client. This processes incoming NEW_CLIENT packet and creates
-   Client ID for the client and adds it to lists and cache. */
+   Client ID for the client. Client becomes registered after calling this
+   functions. */
 
-SilcClientList *silc_server_new_client(SilcServer server,
+SilcClientEntry silc_server_new_client(SilcServer server,
                                       SilcSocketConnection sock,
                                       SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
-  SilcClientList *id_entry;
-  char *username = NULL, *realname = NULL, *id_string;
+  SilcClientEntry client;
+  SilcIDCacheEntry cache;
+  SilcClientID *client_id;
   SilcBuffer reply;
+  char *username = NULL, *realname = NULL, *id_string;
 
   SILC_LOG_DEBUG(("Creating new client"));
 
   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
     return NULL;
 
-#define LCC(x) server->local_list->client_cache[(x) - 32]
-#define LCCC(x) server->local_list->client_cache_count[(x) - 32]
+  /* Take client entry */
+  client = (SilcClientEntry)sock->user_data;
+
+  /* Fetch the old client cache entry so that we can update it. */
+  if (!silc_idcache_find_by_context(server->local_list->clients,
+                                   sock->user_data, &cache)) {
+    SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
+    return NULL;
+  }
 
+  /* Parse incoming packet */
   silc_buffer_unformat(buffer,
                       SILC_STR_UI16_STRING_ALLOC(&username),
                       SILC_STR_UI16_STRING_ALLOC(&realname),
                       SILC_STR_END);
 
-  /* Set the pointers to the client list and create new client ID */
-  id_entry = (SilcClientList *)sock->user_data;
-  id_entry->registered = TRUE;
-  id_entry->nickname = strdup(username);
-  id_entry->username = username;
-  id_entry->userinfo = realname;
+  /* Create Client ID */
   silc_id_create_client_id(server->id, server->rng, server->md5hash,
-                          username, &id_entry->id);
+                          username, &client_id);
 
-  /* Add to client cache */
-  LCCC(username[0]) = silc_idcache_add(&LCC(username[0]), 
-                                      LCCC(username[0]),
-                                      username, SILC_ID_CLIENT, 
-                                      id_entry->id, (void *)id_entry);
+  /* Update client entry */
+  client->registered = TRUE;
+  client->nickname = strdup(username);
+  client->username = username;
+  client->userinfo = realname;
+  client->id = client_id;
+
+  /* Update the cache entry */
+  cache->id = (void *)client_id;
+  cache->type = SILC_ID_CLIENT;
+  cache->data = username;
+  silc_idcache_sort_by_data(server->local_list->clients);
 
   /* Notify our router about new client on the SILC network */
   if (!server->standalone)
     silc_server_send_new_id(server, (SilcSocketConnection) 
                            server->id_entry->router->connection, 
                            server->server_type == SILC_SERVER ? TRUE : FALSE,
-                           id_entry->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
+                           client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
   
   /* Send the new client ID to the client. */
-  id_string = silc_id_id2str(id_entry->id, SILC_ID_CLIENT);
+  id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
   silc_buffer_format(reply,
@@ -3734,17 +3716,15 @@ SilcClientList *silc_server_new_client(SilcServer server,
   silc_server_send_notify(server, sock, 
                          "Your connection is secured with %s cipher, "
                          "key length %d bits",
-                         id_entry->send_key->cipher->name,
-                         id_entry->send_key->cipher->key_len);
+                         client->send_key->cipher->name,
+                         client->send_key->cipher->key_len);
   silc_server_send_notify(server, sock, 
                          "Your current nickname is %s",
-                         id_entry->nickname);
+                         client->nickname);
 
   /* XXX Send motd */
 
-#undef LCC
-#undef LCCC
-  return id_entry;
+  return client;
 }
 
 /* Create new server. This processes incoming NEW_SERVER packet and
@@ -3752,15 +3732,17 @@ SilcClientList *silc_server_new_client(SilcServer server,
    server thus we save all the information and save it to local list. 
    This funtion can be used by both normal server and router server.
    If normal server uses this it means that its router has connected
-   to the server.  If router uses this it means that one of the cell's
+   to the server. If router uses this it means that one of the cell's
    servers is connected to the router. */
 
-SilcServerList *silc_server_new_server(SilcServer server,
+SilcServerEntry silc_server_new_server(SilcServer server,
                                       SilcSocketConnection sock,
                                       SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
-  SilcServerList *id_entry;
+  SilcServerEntry new_server;
+  SilcIDCacheEntry cache;
+  SilcServerID *server_id;
   unsigned char *server_name, *id_string;
 
   SILC_LOG_DEBUG(("Creating new server"));
@@ -3769,40 +3751,46 @@ SilcServerList *silc_server_new_server(SilcServer server,
       sock->type != SILC_SOCKET_TYPE_ROUTER)
     return NULL;
 
-#define LSC(x) server->local_list->server_cache[(x) - 32]
-#define LSCC(x) server->local_list->server_cache_count[(x) - 32]
+  /* Take server entry */
+  new_server = (SilcServerEntry)sock->user_data;
 
+  /* Fetch the old server cache entry so that we can update it. */
+  if (!silc_idcache_find_by_context(server->local_list->servers,
+                                   sock->user_data, &cache)) {
+    SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
+    return NULL;
+  }
+
+  /* Parse the incoming packet */
   silc_buffer_unformat(buffer,
                       SILC_STR_UI16_STRING_ALLOC(&id_string),
                       SILC_STR_UI16_STRING_ALLOC(&server_name),
                       SILC_STR_END);
 
-  /* Save ID and name */
-  id_entry = (SilcServerList *)sock->user_data;
-  id_entry->registered = TRUE;
-  id_entry->id = silc_id_str2id(id_string, SILC_ID_SERVER);
-  id_entry->server_name = server_name;
-  
-  /* Add to server cache */
-  LSCC(server_name[0]) = 
-    silc_idcache_add(&LSC(server_name[0]), 
-                    LSCC(server_name[0]),
-                    server_name, SILC_ID_SERVER, 
-                    id_entry->id, (void *)id_entry);
+  /* Get Server ID */
+  server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
+  silc_free(id_string);
+
+  /* Update client entry */
+  new_server->registered = TRUE;
+  new_server->server_name = server_name;
+  new_server->id = server_id;
+
+  /* Update the cache entry */
+  cache->id = (void *)server_id;
+  cache->type = SILC_ID_SERVER;
+  cache->data = server_name;
+  silc_idcache_sort_by_data(server->local_list->servers);
 
   /* Distribute the information about new server in the SILC network
      to our router. If we are normal server we won't send anything
      since this connection must be our router connection. */
   if (server->server_type == SILC_ROUTER && !server->standalone)
     silc_server_send_new_id(server, server->id_entry->router->connection,
-                           TRUE, id_entry->id, SILC_ID_SERVER, 
+                           TRUE, new_server->id, SILC_ID_SERVER, 
                            SILC_ID_SERVER_LEN);
 
-  silc_free(id_string);
-
-#undef LSC
-#undef LSCC
-  return id_entry;
+  return new_server;
 }
 
 /* Processes incoming New ID Payload. New ID Payload is used to distribute
@@ -3845,35 +3833,33 @@ void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
   switch(id_type) {
   case SILC_ID_CLIENT:
     {
-      SilcClientList *idlist;
+      SilcClientEntry idlist;
 
       /* Add the client to our local list. We are router and we keep
         cell specific local database of all clients in the cell. */
-      silc_idlist_add_client(&server->local_list->clients, NULL, NULL, NULL,
-                            id, sock->user_data, NULL, NULL, 
-                            NULL, NULL, &idlist);
-      idlist->connection = sock;
+      idlist = silc_idlist_add_client(server->local_list, NULL, NULL, NULL,
+                                     id, sock->user_data, NULL, NULL, 
+                                     NULL, NULL, NULL, sock);
     }
     break;
 
   case SILC_ID_SERVER:
     {
-      SilcServerList *idlist;
+      SilcServerEntry idlist;
 
       /* Add the server to our local list. We are router and we keep
         cell specific local database of all servers in the cell. */
-      silc_idlist_add_server(&server->local_list->servers, NULL, 0,
-                            id, server->id_entry, NULL, NULL, 
-                          NULL, NULL, &idlist);
-      idlist->connection = sock;
+      idlist = silc_idlist_add_server(server->local_list, NULL, 0,
+                                     id, server->id_entry, NULL, NULL, 
+                                     NULL, NULL, NULL, sock);
     }
     break;
 
   case SILC_ID_CHANNEL:
     /* Add the channel to our local list. We are router and we keep
        cell specific local database of all channels in the cell. */
-    silc_idlist_add_channel(&server->local_list->channels, NULL, 0,
-                           id, server->id_entry, NULL, NULL);
+    silc_idlist_add_channel(server->local_list, NULL, 0, id, 
+                           server->id_entry, NULL);
     break;
 
   default:
index b2327d4501d1e6b5f0c96da8393b57eac948dc57..a2b68856353e891e850056bd0f76b346926c79a7 100644 (file)
@@ -60,20 +60,20 @@ void silc_server_packet_forward(SilcServer server,
                                unsigned char *data, unsigned int data_len,
                                int force_send);
 void silc_server_packet_send_to_channel(SilcServer server,
-                                       SilcChannelList *channel,
+                                       SilcChannelEntry channel,
                                        unsigned char *data,
                                        unsigned int data_len,
                                        int force_send);
 void silc_server_packet_relay_to_channel(SilcServer server,
                                         SilcSocketConnection sender_sock,
-                                        SilcChannelList *channel,
+                                        SilcChannelEntry channel,
                                         void *sender, 
                                         SilcIdType sender_type,
                                         unsigned char *data,
                                         unsigned int data_len,
                                         int force_send);
 void silc_server_packet_send_local_channel(SilcServer server,
-                                          SilcChannelList *channel,
+                                          SilcChannelEntry channel,
                                           SilcPacketType type,
                                           SilcPacketFlags flags,
                                           unsigned char *data,
@@ -88,13 +88,13 @@ void silc_server_free_sock_user_data(SilcServer server,
                                     SilcSocketConnection sock);
 void silc_server_remove_from_channels(SilcServer server, 
                                      SilcSocketConnection sock,
-                                     SilcClientList *client);
+                                     SilcClientEntry client);
 int silc_server_remove_from_one_channel(SilcServer server, 
                                        SilcSocketConnection sock,
-                                       SilcChannelList *channel,
-                                       SilcClientList *client);
-int silc_server_client_on_channel(SilcClientList *client,
-                                 SilcChannelList *channel);
+                                       SilcChannelEntry channel,
+                                       SilcClientEntry client);
+int silc_server_client_on_channel(SilcClientEntry client,
+                                 SilcChannelEntry channel);
 void silc_server_disconnect_remote(SilcServer server,
                                   SilcSocketConnection sock,
                                   const char *fmt, ...);
@@ -119,7 +119,7 @@ void silc_server_send_notify_dest(SilcServer server,
                                  SilcIdType dest_id_type,
                                  const char *fmt, ...);
 void silc_server_send_notify_to_channel(SilcServer server,
-                                       SilcChannelList *channel,
+                                       SilcChannelEntry channel,
                                        const char *fmt, ...);
 void silc_server_send_new_id(SilcServer server,
                             SilcSocketConnection sock,
@@ -133,13 +133,13 @@ void silc_server_send_replace_id(SilcServer server,
                                 unsigned int old_id_len,
                                 void *new_id, SilcIdType new_id_type,
                                 unsigned int new_id_len);
-SilcChannelList *silc_server_new_channel(SilcServer server, 
+SilcChannelEntry silc_server_new_channel(SilcServer server, 
                                         SilcServerID *router_id,
                                         char *cipher, char *channel_name);
-SilcClientList *silc_server_new_client(SilcServer server,
+SilcClientEntry silc_server_new_client(SilcServer server,
                                       SilcSocketConnection sock,
                                       SilcPacketContext *packet);
-SilcServerList *silc_server_new_server(SilcServer server,
+SilcServerEntry silc_server_new_server(SilcServer server,
                                       SilcSocketConnection sock,
                                       SilcPacketContext *packet);
 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
index 8f4fa5829f39e6fad3f22bf03543f15304b1ae1b..0093ac8429a5ade3e586f515d5a872c2c40fbe9b 100644 (file)
@@ -40,7 +40,7 @@ typedef struct SilcServerObjectStruct {
   int listenning;
   SilcServerID *id;
   SilcIdType id_type;
-  SilcServerList *id_entry;
+  SilcServerEntry id_entry;
 
   /* SILC server task queues */
   SilcTaskQueue io_queue;
index d7d444778c50eb823d67d99f636a01b965ed0d04..515f8ba0d50dea45e71ffea1011e300655f6d429 100644 (file)
@@ -13,26 +13,26 @@ sha1::64:20
 #dss::1024
 
 [AdminInfo]
-Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
+Pohjois-Savo Poly-Technics:SILC Test Server:Pekka Riikonen:priikone@poseidon.pspt.fi
 
 [ServerInfo]
-silc.pspt.fi:193.166.51.47:Kuopio, Finland:1333
+silc.pspt.fi:193.166.51.47:Kuopio, Finland:706
 
 [ListenPort]
-193.166.51.47:193.166.51.47:1333
+193.166.51.47:193.166.51.47:706
 
 [Logging]
 infologfile:silcd.log:10000
-#warninglogfile:/var/log/silcd_warning.log:10000
-#errorlogfile:ERROR.log:10000
-#fatallogfile:/var/log/silcd_error.log:
+warninglogfile:silcd.log:
+errorlogfile:silcd.log:10000
+fatallogfile:silcd.log:
 
 [ConnectionClass]
 1:100:100:100
 2:200:300:400
 
 [ClientConnection]
-:::1333:1
+:::706:1
 
 [AdminConnection]