updates.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 19 Apr 2001 09:48:04 +0000 (09:48 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 19 Apr 2001 09:48:04 +0000 (09:48 +0000)
CHANGES
TODO
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/idlist.h
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h

diff --git a/CHANGES b/CHANGES
index 98d40d75269935eb100f246a0094d0b49db02ce3..f9f60f10e1438b9a652b37f938ceb3ce76ae9fc2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Thu Apr 19 11:40:20 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Added `sender_entry' argument to the function
+         silc_server_packet_relay_to_channel so that we can check
+         whether some destination actually belongs to the same route
+         the sender belongs (ie, we must not resend the packet to the
+         sender).  Affected file silcd/packet_send.[ch].
+
+       * Added `servername' field to the SilcClientEntry in the server
+         to hold the name of the server where client is from.  Affected
+         file is silcd/idlist.h.
+
 Wed Apr 18 22:19:03 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Moved the channel message encrypting in the router betwen
diff --git a/TODO b/TODO
index ddd804d8caa5ae197add10a75ecf939e2c5645e4..0445423393a3d9de2b6b06566d3a8a3cf5978deb 100644 (file)
--- a/TODO
+++ b/TODO
@@ -73,6 +73,12 @@ TODO/bugs In SILC Libraries
    does not want to register them one by one (if for example SILC client
    is run without config files at all).
 
+ o The ID List must be optimized.  When the lists grow the searching
+   becomes a lot slower and is some cases the lists are searched many
+   times, like with channel messages (twice at least).  Some sort of
+   hash tables should replace the lists.  Thus, the ID cache should be
+   rewritten to use hash tables internally.
+
  o Compression routines are missing.  The protocol supports packet
    compression thus it must be implemented.  SILC Comp API must be
    defined.  zlib package is already included into the lib dir (in CVS,
index e7e0a0822fe6d3569bd112d7526d43deaaf159ff..f2d0f42c2e28a965f6536077f57ca651172cd66d 100644 (file)
@@ -592,10 +592,14 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
     strncat(nh, entry->nickname, strlen(entry->nickname));
     if (!strchr(entry->nickname, '@')) {
       strncat(nh, "@", 1);
-      len = entry->router ? strlen(entry->router->server_name) :
-       strlen(server->server_name);
-      strncat(nh, entry->router ? entry->router->server_name :
-             server->server_name, len);
+      if (entry->servername) {
+       strncat(nh, entry->servername, strlen(entry->servername));
+      } else {
+       len = entry->router ? strlen(entry->router->server_name) :
+         strlen(server->server_name);
+       strncat(nh, entry->router ? entry->router->server_name :
+               server->server_name, len);
+      }
     }
       
     strncat(uh, entry->username, strlen(entry->username));
@@ -1064,10 +1068,14 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd,
     strncat(nh, entry->nickname, strlen(entry->nickname));
     if (!strchr(entry->nickname, '@')) {
       strncat(nh, "@", 1);
-      len = entry->router ? strlen(entry->router->server_name) :
-       strlen(server->server_name);
-      strncat(nh, entry->router ? entry->router->server_name :
-             server->server_name, len);
+      if (entry->servername) {
+       strncat(nh, entry->servername, strlen(entry->servername));
+      } else {
+       len = entry->router ? strlen(entry->router->server_name) :
+         strlen(server->server_name);
+       strncat(nh, entry->router ? entry->router->server_name :
+               server->server_name, len);
+      }
     }
       
     strncat(uh, entry->username, strlen(entry->username));
@@ -1393,10 +1401,14 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
     strncat(nh, entry->nickname, strlen(entry->nickname));
     if (!strchr(entry->nickname, '@')) {
       strncat(nh, "@", 1);
-      len = entry->router ? strlen(entry->router->server_name) :
-       strlen(server->server_name);
-      strncat(nh, entry->router ? entry->router->server_name :
-             server->server_name, len);
+      if (entry->servername) {
+       strncat(nh, entry->servername, strlen(entry->servername));
+      } else {
+       len = entry->router ? strlen(entry->router->server_name) :
+         strlen(server->server_name);
+       strncat(nh, entry->router ? entry->router->server_name :
+               server->server_name, len);
+      }
     }
       
     if (!entry->username) {
index 2bc68693f2f79de17ddeef74b1a0f94e64a8cd0a..eec802895db6798bc068583f0ec960f86613af60 100644 (file)
@@ -129,7 +129,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
 {
   SilcServer server = cmd->server;
   unsigned char *tmp, *id_data;
-  char *nickname, *username, *realname;
+  char *nickname, *username, *realname, *servername = NULL;
   SilcClientID *client_id;
   SilcClientEntry client;
   SilcIDCacheEntry cache = NULL;
@@ -177,7 +177,9 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     if (strchr(nickname, '@')) {
       int len = strcspn(nickname, "@");
       nick = silc_calloc(len + 1, sizeof(char));
+      servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
       memcpy(nick, nickname, len);
+      memcpy(servername, nickname + len + 1, strlen(nickname) - len);
     } else {
       nick = strdup(nickname);
     }
@@ -194,6 +196,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
 
     client->data.registered = TRUE;
     client->mode = mode;
+    client->servername = servername;
   } else {
     /* We have the client already, update the data */
 
@@ -203,7 +206,9 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     if (strchr(nickname, '@')) {
       int len = strcspn(nickname, "@");
       nick = silc_calloc(len + 1, sizeof(char));
+      servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
       memcpy(nick, nickname, len);
+      memcpy(servername, nickname + len + 1, strlen(nickname) - len);
     } else {
       nick = strdup(nickname);
     }
@@ -219,6 +224,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     client->username = strdup(username);
     client->userinfo = strdup(realname);
     client->mode = mode;
+    client->servername = servername;
 
     if (cache) {
       cache->data = nick;
@@ -270,7 +276,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
   SilcServer server = cmd->server;
   uint32 len, id_len;
   unsigned char *id_data;
-  char *nickname, *username, *realname;
+  char *nickname, *username, *realname, *servername = NULL;
   SilcClientID *client_id;
   SilcClientEntry client;
   SilcIDCacheEntry cache = NULL;
@@ -309,7 +315,9 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     if (strchr(nickname, '@')) {
       int len = strcspn(nickname, "@");
       nick = silc_calloc(len + 1, sizeof(char));
+      servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
       memcpy(nick, nickname, len);
+      memcpy(servername, nickname + len + 1, strlen(nickname) - len);
     } else {
       nick = strdup(nickname);
     }
@@ -328,6 +336,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     client = silc_idlist_find_client_by_id(server->global_list, 
                                           client_id, &cache);
     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+    client->servername = servername;
   } else {
     /* We have the client already, update the data */
 
@@ -335,7 +344,9 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     if (strchr(nickname, '@')) {
       int len = strcspn(nickname, "@");
       nick = silc_calloc(len + 1, sizeof(char));
+      servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
       memcpy(nick, nickname, len);
+      memcpy(servername, nickname + len + 1, strlen(nickname) - len);
     } else {
       nick = strdup(nickname);
     }
@@ -347,6 +358,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     
     client->nickname = nick;
     client->username = strdup(username);
+    client->servername = servername;
 
     if (cache) {
       cache->data = nick;
index 6c5d79e7f508b8da8af9a8b62210bbaa4ac8d4a1..dabbacaf3f657a3f765e9441d97f76e7a482226a 100644 (file)
@@ -229,6 +229,14 @@ typedef struct SilcChannelClientEntryStruct {
 
        Generic data structure to hold data common to all ID entries.
 
+   unsigned char *nickname
+
+       The nickname of the client.
+
+   char *servername
+
+       The name of the server where the client is from. MAy be NULL.
+
    char username
 
        Client's usename. This is defined in the following manner:
@@ -307,6 +315,7 @@ struct SilcClientEntryStruct {
   SilcIDListDataStruct data;
 
   unsigned char *nickname;
+  char *servername;
   char *username;
   char *userinfo;
   SilcClientID *id;
index f4d7e14f9816c9359a88444d080a54a4fe0d4ce6..e4c3bd3572061988e8fa33b66e8eaf53fb53b441 100644 (file)
@@ -1148,6 +1148,7 @@ void silc_server_channel_message(SilcServer server,
   SilcChannelClientEntry chl;
   SilcChannelID *id = NULL;
   void *sender = NULL;
+  void *sender_entry = NULL;
 
   SILC_LOG_DEBUG(("Processing channel message"));
 
@@ -1178,12 +1179,13 @@ void silc_server_channel_message(SilcServer server,
                          packet->src_id_type);
   if (!sender)
     goto out;
-  if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
-      packet->src_id_type == SILC_ID_CLIENT) {
+  if (packet->src_id_type == SILC_ID_CLIENT) {
     silc_list_start(channel->user_list);
     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
-      if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
+      if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender)) {
+       sender_entry = chl->client;
        break;
+      }
     }
     if (chl == SILC_LIST_END) {
       SILC_LOG_DEBUG(("Client not on channel"));
@@ -1191,11 +1193,10 @@ void silc_server_channel_message(SilcServer server,
     }
   }
 
-
   /* Distribute the packet to our local clients. This will send the
      packet for further routing as well, if needed. */
   silc_server_packet_relay_to_channel(server, sock, channel, sender,
-                                     packet->src_id_type,
+                                     packet->src_id_type, sender_entry,
                                      packet->buffer->data,
                                      packet->buffer->len, FALSE);
 
@@ -1536,8 +1537,24 @@ static void silc_server_new_id_real(SilcServer server,
   else
     id_list = server->global_list;
 
-  router_sock = sock;
-  router = sock->user_data;
+  /* If the packet is coming from router then use the sender as the
+     origin of the the packet. If it came from router then check the real
+     sender of the packet and use that as he origin. */
+  if (sock->type == SILC_SOCKET_TYPE_SERVER) {
+    router_sock = sock;
+    router = sock->user_data;
+  } else {
+    void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
+                                    packet->src_id_type);
+    router = silc_idlist_find_server_by_id(server->global_list,
+                                          sender_id, NULL);
+    if (!router)
+      router = silc_idlist_find_server_by_id(server->local_list,
+                                            sender_id, NULL);
+    assert(router != NULL);
+    router_sock = sock;
+    silc_free(sender_id);
+  }
 
   switch(id_type) {
   case SILC_ID_CLIENT:
index 6764fb8c23beb88e96b666a8a132b6189e9cc18b..0452a0d2c7af54b97ba428c0252cf3743baa4f19 100644 (file)
@@ -725,6 +725,9 @@ void silc_server_packet_relay_to_channel(SilcServer server,
            memcpy(tmp, data, data_len);
 
            /* Decrypt the channel message (we don't check the MAC) */
+           /* XXX this could be optimized and removed all together by
+              taking a copy of the original data before encrypting it
+              and thus would not required decrypting. */
            if (channel->channel_key &&
                !silc_channel_message_payload_decrypt(tmp, data_len, 
                                                      channel->channel_key,
index c353661b8d8d81703b53196f6dc52c5fc344c1f2..9c984277b585e74823120198b6ad7eeb27ccd36d 100644 (file)
@@ -72,6 +72,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
                                         SilcChannelEntry channel,
                                         void *sender, 
                                         SilcIdType sender_type,
+                                        void *sender_entry,
                                         unsigned char *data,
                                         uint32 data_len,
                                         int force_send);