updates.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 11 Nov 2001 16:48:20 +0000 (16:48 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 11 Nov 2001 16:48:20 +0000 (16:48 +0000)
41 files changed:
CHANGES
TODO
apps/irssi/src/fe-common/silc/module-formats.c
apps/irssi/src/fe-common/silc/module-formats.h
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-core.c
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/protocol.h
apps/silcd/server.c
apps/silcd/server_backup.c
apps/silcd/server_util.c
apps/silcd/server_util.h
apps/silcd/serverid.c
apps/silcd/silcd.c
doc/draft-riikonen-silc-commands-02.nroff
doc/draft-riikonen-silc-pp-04.nroff
lib/silcclient/client.c
lib/silcclient/client_notify.c
lib/silcclient/command.c
lib/silcclient/command_reply.c
lib/silcclient/idlist.c
lib/silcclient/protocol.c
lib/silccore/silcchannel.c
lib/silccore/silcid.h
lib/silccore/silcprivate.c
lib/silccrypt/silchash.c
lib/silcutil/silclog.c
lib/silcutil/silcnet.h
lib/silcutil/silcutil.c
lib/silcutil/silcutil.h
lib/silcutil/unix/silcunixnet.c
lib/silcutil/win32/silcwin32net.c
lib/silcutil/win32/silcwin32util.c
prepare
silc_optimize [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index f65dc8c9e78ccb36208910c7565f4cb6d20ef299..c924468731ab9dbe8e0592c8b5308c4075ee8841 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,82 @@
+Sun Nov 11 10:49:10 EET 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Use ++server->cmd_ident when sending commands in server,
+         instead of random number.  Affected file silcd/command.c.
+
+       * Fixed GETKEY command reply to call actually GETKEY pending
+         command callbacks.  Affected file silcd/command_reply.c.
+
+       * A bit stricter check for nicknames.  Check for same nickname
+         in NICK command also.  Affected file silcd/command.c.
+
+       * Do not call INFO command everytime client ID changes, only
+         during first connecting.  Affected file lib/silcclient/client.c.
+
+       * Set the new nickname only after successful command reply for
+         NICK command is returned by server.  Affected file
+         lib/silcclient/command.c.
+
+       * Remove nicknames from nicklist during server_signoff notify.
+         Should fix /NAMES bit more.  The affected file is
+         irssi/src/silc/core/silc-channels.c.
+
+       * Added `fingerprint' field to the SilcIDListData in the 
+         silcd/idlist.h to hold the fingerprint of the client's
+         public key.
+
+         Send the fingerprint of the client's public key in WHOIS
+         command reply.
+
+         Affected files silcd/command.c, and silcd/idlist.[ch].
+
+       * Added silc_fingerprint into lib/silcutil/silcutil.[ch] to
+         create fingerprint from given data.
+
+       * Show the fingerprint of the client's public key in WHOIS.
+         Affected files irssi/src/module-formats.[ch] and
+         irssi/src/silc/core/client_ops.c.
+
+       * Format the multiple same nicknames also during JOIN and
+         NICK_CHANGE notifys.  Affected file is
+         lib/silcclient/client_notify.c.
+
+       * Do not print error on screen for invalid private message
+         payload since it can come if someone is sending private
+         messages with wrong key.  Affected file
+         lib/silccore/silcprivate.c.
+
+       * Fixed multiple concurrent /PING crash.  Affected file
+         lib/silcclient/command.c.
+
+       * Changed the wrong ID encoding.  All IP addresses must be
+         in MSB first order in encoded format.  They were encoded
+         wrong and was in LSB format.  Affected files are
+         silcd/serverid.c, lib/silcutil/silcutil.c.
+
+       * Remove silc_net_addr2bin_ne from lib/silcutil/silcnet.[ch].
+
+       * Call the `connect' client operation through the scheduler
+         in case of error.  Affected file lib/silcclient/client.c.
+
+       * Call the `failure' client operation even if the error
+         occurred locally during a protocol.  Affected file is
+         lib/silcclient/protocol.c.
+
+       * Added support of sending LIST command to router from normal
+         server.  This way normal server can get list of all channels
+         in the network too.  Fixed the channel list sending in the
+         server too.  Affected files are silcd/command.c, and
+         silcd/command_reply.[ch].
+
+       * Added silc_server_update_channels_by_server and
+         silc_server_remove_channels_by_server.  They are used during
+         disconnection of primary router and in backup router protocol.
+         Affected file silcd/server_util.[ch], silcd/server.c and
+         silcd/server_backup.c.
+
+       * Fixed channel adding to global list in IDENTIFY command
+         reply in server.  Affected file silcd/command_reply.c.
+
 Sat Nov 10 21:39:22 EET 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * If the incoming packet type is REKEY or REKEY_DONE process
diff --git a/TODO b/TODO
index 15baff8534b2ec58e9ac57ba044da2f6af1e59b4..c631c660f2c5af71ed4afd29e5bcbb9c64a819c0 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,9 +1,6 @@
 TODO/bugs in Irssi SILC client
 ==============================
 
- o /NAMES kees showing things wrong after JOIN and after ppl has left
-   channel.
-
  o Add local command to switch the channel's private key when channel has
    several private keys.  Currently sending channel messages with many
    keys is not possible because changing the key is not possible by the
@@ -38,14 +35,6 @@ TODO/bugs in Irssi SILC client
 TODO/bugs In SILC Client Library
 ================================
 
- o key agreement with itself causes the packet sequence numbers go grazy.
-
- o WHOIS shows the formatted nickname wrong in some circumstances.
-
- o Set incrorrect key and /MSG him, screen gets screwed.
-
- o Crashes if lots of concurrent /PING's.
-
  o JOIN command's argument handling is buggy.  See the XXX in the code.
 
 
@@ -90,11 +79,6 @@ TODO/bugs In SILC Server
    If it is, there is no reason to send it to the router, since the server
    knows it best.
 
- o Add support for sending the LIST command to primary router on normal
-   server to receive all the created channels.  Currently the command
-   returns only the channels the server knows about.  The protocol spec
-   does not prohibit of sending the LIST to the router.
-
  o Incomplete IPv6 support:
 
        o silcd/serverid.c and its routines supports only IPv4.
index d2c62f23e3f65cd18962bc6feece623f09181180..690ff07d3bd8deb13e96a344d68a4ed5e3b41ff7 100644 (file)
@@ -52,10 +52,11 @@ FORMAT_REC fecommon_silc_formats[] = {
        { NULL, "Who Queries", 0 },
 
        { "whois", "{nick $0} {nickhost $1@$2}%: nickname : $3 ($4)", 5, { 0, 0, 0, 0, 0 } },
-       { "whois_realname", " realname : $0", 1, { 0 } },
-       { "whois_channels", " channels : $0", 1, { 0 } },
-       { "whois_modes", " modes    : $0", 1, { 0 } },
-       { "whois_idle", " idle     : $0", 1, { 0 } },
+       { "whois_realname",    " realname    : $0", 1, { 0 } },
+       { "whois_channels",    " channels    : $0", 1, { 0 } },
+       { "whois_modes",       " modes       : $0", 1, { 0 } },
+       { "whois_idle",        " idle        : $0", 1, { 0 } },
+       { "whois_fingerprint", " fingerprint : $0", 1, { 0 } },
        { "whowas", "{nick $0} was {nickhost $1} ($2)", 3, { 0, 0, 0 } },
        { "users_header", "Users on {channelhilight $0}", 1, { 0 } },
        { "users", " %|{nick $[!20]0} $[!5]1 $2@$3 {comment {hilight $4}}", 5, { 0, 0, 0, 0, 0 } },
index c1d94a34a9b3c0eedd43053348032dc89314f02c..ce4595c3375fbac59b8867ddb7facf7edbc3b634 100644 (file)
@@ -52,6 +52,7 @@ enum {
   SILCTXT_WHOIS_CHANNELS,
   SILCTXT_WHOIS_MODES,
   SILCTXT_WHOIS_IDLE,
+  SILCTXT_WHOIS_FINGERPRINT,
   SILCTXT_WHOWAS_USERINFO,
   SILCTXT_USERS_HEADER,
   SILCTXT_USERS,
index a3af5d415432661ea65adc3e11c25ecf7691b8c9..4104b4bdf8606d874b97f4a3136a9fcf6659fbc6 100644 (file)
@@ -205,7 +205,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
 
 /* Called to indicate that connection was either successfully established
    or connecting failed.  This is also the first time application receives
-   the SilcClientConnection objecet which it should save somewhere. */
+   the SilcClientConnection object which it should save somewhere. */
 
 void silc_connect(SilcClient client, SilcClientConnection conn, int success)
 {
@@ -401,6 +401,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
   case SILC_COMMAND_WHOIS:
     {
       char buf[1024], *nickname, *username, *realname, *nick;
+      unsigned char *fingerprint;
       uint32 idle, mode;
       SilcBuffer channels;
       SilcClientEntry client_entry;
@@ -426,6 +427,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       channels = va_arg(vp, SilcBuffer);
       mode = va_arg(vp, uint32);
       idle = va_arg(vp, uint32);
+      fingerprint = va_arg(vp, unsigned char *);
       
       silc_parse_userfqdn(nickname, &nick, NULL);
       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
@@ -486,6 +488,13 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                           SILCTXT_WHOIS_IDLE, buf);
       }
+
+      if (fingerprint) {
+       fingerprint = silc_fingerprint(fingerprint, 20);
+       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+                          SILCTXT_WHOIS_FINGERPRINT, fingerprint);
+       silc_free(fingerprint);
+      }
     }
     break;
     
@@ -633,7 +642,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_LIST_HEADER);
 
-      snprintf(users, sizeof(users) - 1, "%d", usercount);
+      if (!usercount)
+       snprintf(users, sizeof(users) - 1, "N/A");
+      else
+       snprintf(users, sizeof(users) - 1, "%d", usercount);
       printformat_module("fe-common/silc", server, NULL,
                         MSGLEVEL_CRAP, SILCTXT_LIST,
                         name, users, topic ? topic : "");
index c02d61d2fc4e9724538a831d38b83fd3221db2ad..da14bcdd5e1aee79c7bca1a41845cfd56c6ff3ec 100644 (file)
@@ -449,6 +449,8 @@ static void event_server_signoff(SILC_SERVER_REC *server, va_list va)
   clients_count = va_arg(va, uint32);
   
   for (i = 0; i < clients_count; i++) {
+    GSList *nicks, *tmp;
+
     memset(userhost, 0, sizeof(userhost));
     if (clients[i]->username)
       snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
@@ -456,6 +458,13 @@ static void event_server_signoff(SILC_SERVER_REC *server, va_list va)
     signal_emit("message quit", 4, server, clients[i]->nickname,
                clients[i]->username ? userhost : "", 
                "server signoff");
+
+    nicks = nicklist_get_same_unique(SERVER(server), clients[i]);
+    for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
+      CHANNEL_REC *channel = tmp->data;
+      NICK_REC *nickrec = tmp->next->data;
+      nicklist_remove(channel, nickrec);
+    }
   }
 }
 
index d66a059584766cd3979753c352d75c5578a65a8f..c5de944d277d58deed15866bd91b1276ad7b08ec 100644 (file)
@@ -195,7 +195,7 @@ void silc_core_init(void)
     { "list-pkcs", 'P', POPT_ARG_NONE, &opt_list_pkcs, 0,
       "List supported PKCSs", NULL },
     { "debug", 'd', POPT_ARG_STRING, &opt_debug, 0,
-      "Enable debugging", NULL },
+      "Enable debugging", "STRING" },
     { "version", 'V', POPT_ARG_NONE, &opt_version, 0,
       "Show version", NULL },
     { NULL, '\0', 0, NULL }
@@ -275,6 +275,11 @@ void silc_core_init_finish(void)
     silc_log_set_debug_string(opt_debug);
     silc_log_set_callbacks(silc_log_info, silc_log_warning,
                           silc_log_error, NULL);
+#ifndef SILC_DEBUG
+    fprintf(stdout, 
+           "Run-time debugging is not enabled. To enable it recompile\n"
+           "the client with --enable-debug configuration option.\n");
+#endif
   }
 
   /* Do some irssi initializing */
index 31fe32bd3b1ad4ca8e3962a70694f8db9a90cbb4..803b0dc9033257d573ecfb920adff7b7339bbee0 100644 (file)
@@ -675,6 +675,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
   uint16 ident = silc_command_get_ident(cmd->payload);
   char nh[256], uh[256];
   unsigned char idle[4], mode[4];
+  unsigned char *fingerprint;
   SilcSocketConnection hsock;
 
   len = 0;
@@ -772,6 +773,11 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
     }
 
     channels = silc_server_get_client_channel_list(server, entry);
+
+    if (entry->data.fingerprint[0] != 0 && entry->data.fingerprint[1] != 0)
+      fingerprint = entry->data.fingerprint;
+    else
+      fingerprint = NULL;
       
     SILC_PUT32_MSB(entry->mode, mode);
 
@@ -779,29 +785,21 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
       SILC_PUT32_MSB((time(NULL) - entry->data.last_receive), idle);
     }
 
-    if (channels)
-      packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
-                                                   status, ident, 7, 
-                                                   2, idp->data, idp->len,
-                                                   3, nh, strlen(nh),
-                                                   4, uh, strlen(uh),
-                                                   5, entry->userinfo, 
-                                                   strlen(entry->userinfo),
-                                                   6, channels->data,
-                                                   channels->len,
-                                                   7, mode, 4,
-                                                   8, idle, 4);
-    else
-      packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
-                                                   status, ident, 6, 
-                                                   2, idp->data, idp->len,
-                                                   3, nh, strlen(nh),
-                                                   4, uh, strlen(uh),
-                                                   5, entry->userinfo, 
-                                                   strlen(entry->userinfo),
-                                                   7, mode, 4,
-                                                   8, idle, 4);
-    
+    packet = 
+      silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
+                                          status, ident, 8, 
+                                          2, idp->data, idp->len,
+                                          3, nh, strlen(nh),
+                                          4, uh, strlen(uh),
+                                          5, entry->userinfo, 
+                                          strlen(entry->userinfo),
+                                          6, channels ? channels->data : NULL,
+                                          channels ? channels->len : 0,
+                                          7, mode, 4,
+                                          8, idle, 4,
+                                          9, fingerprint,
+                                          fingerprint ? 20 : 0);
+
     silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
                            0, packet->data, packet->len, FALSE);
     
@@ -837,7 +835,7 @@ silc_server_command_whois_process(SilcServerCommandContext cmd)
     uint16 old_ident;
 
     old_ident = silc_command_get_ident(cmd->payload);
-    silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+    silc_command_set_ident(cmd->payload, ++server->cmd_ident);
     tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
     /* Send WHOIS command to our router */
@@ -1021,7 +1019,7 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd,
        continue;
       
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
       /* Send WHOWAS command */
@@ -1172,7 +1170,7 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd)
     uint16 old_ident;
 
     old_ident = silc_command_get_ident(cmd->payload);
-    silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+    silc_command_set_ident(cmd->payload, ++server->cmd_ident);
     tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
     /* Send WHOWAS command to our router */
@@ -1857,7 +1855,7 @@ silc_server_command_identify_process(SilcServerCommandContext cmd)
     uint16 old_ident;
 
     old_ident = silc_command_get_ident(cmd->payload);
-    silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+    silc_command_set_ident(cmd->payload, ++server->cmd_ident);
     tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
     /* Send IDENTIFY command to our router */
@@ -1945,6 +1943,14 @@ static int silc_server_command_bad_chars(char *nick)
     if (nick[i] == '?') return TRUE;
     if (nick[i] == ',') return TRUE;
     if (nick[i] == '@') return TRUE;
+    if (nick[i] == ':') return TRUE;
+    if (nick[i] == '/') return TRUE;
+    if (nick[i] == '[') return TRUE;
+    if (nick[i] == '[') return TRUE;
+    if (nick[i] == '(') return TRUE;
+    if (nick[i] == ')') return TRUE;
+    if (nick[i] == '{') return TRUE;
+    if (nick[i] == '}') return TRUE;
   }
 
   return FALSE;
@@ -1959,7 +1965,7 @@ SILC_SERVER_CMD_FUNC(nick)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   SilcServer server = cmd->server;
-  SilcBuffer packet, nidp, oidp;
+  SilcBuffer packet, nidp, oidp = NULL;
   SilcClientID *new_id;
   char *nick;
   uint16 ident = silc_command_get_ident(cmd->payload);
@@ -1981,6 +1987,12 @@ SILC_SERVER_CMD_FUNC(nick)
   if (strlen(nick) > 128)
     nick[128] = '\0';
 
+  /* Check for same nickname */
+  if (!strcmp(client->nickname, nick)) {
+    nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+    goto send_reply;
+  }
+
   /* Create new Client ID */
   while (!silc_id_create_client_id(cmd->server, cmd->server->id, 
                                   cmd->server->rng, 
@@ -2025,6 +2037,7 @@ SILC_SERVER_CMD_FUNC(nick)
                                      oidp->data, oidp->len, 
                                      nidp->data, nidp->len);
 
+ send_reply:
   /* Send the new Client ID as reply command back to client */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK, 
                                                SILC_STATUS_OK, ident, 1, 
@@ -2034,7 +2047,8 @@ SILC_SERVER_CMD_FUNC(nick)
 
   silc_buffer_free(packet);
   silc_buffer_free(nidp);
-  silc_buffer_free(oidp);
+  if (oidp)
+    silc_buffer_free(oidp);
   
  out:
   silc_server_command_free(cmd);
@@ -2079,9 +2093,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd,
     if (i >= 1)
       status = SILC_STATUS_LIST_ITEM;
 
-    if (i == lch_count - 1 && gch_count)
-      break;
-    if (lch_count > 1 && i == lch_count - 1)
+    if (lch_count > 1 && i == lch_count - 1 && !gch_count)
       status = SILC_STATUS_LIST_END;
 
     idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
@@ -2185,7 +2197,33 @@ SILC_SERVER_CMD_FUNC(list)
   SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
   uint32 lch_count = 0, gch_count = 0;
 
-  SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 2);
+  SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1);
+
+  /* If we are normal server, send the command to router, since we
+     want to know all channels in the network. */
+  if (!cmd->pending && server->server_type == SILC_SERVER && 
+      !server->standalone) {
+    SilcBuffer tmpbuf;
+    uint16 old_ident;
+    
+    old_ident = silc_command_get_ident(cmd->payload);
+    silc_command_set_ident(cmd->payload, ++server->cmd_ident);
+    tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+    silc_server_packet_send(server, server->router->connection,
+                           SILC_PACKET_COMMAND, cmd->packet->flags,
+                           tmpbuf->data, tmpbuf->len, TRUE);
+
+    /* Reprocess this packet after received reply from router */
+    silc_server_command_pending(server, SILC_COMMAND_LIST, 
+                               silc_command_get_ident(cmd->payload),
+                               silc_server_command_destructor,
+                               silc_server_command_list, 
+                               silc_server_command_dup(cmd));
+    cmd->pending = TRUE;
+    silc_command_set_ident(cmd->payload, old_ident);
+    silc_buffer_free(tmpbuf);
+    return;
+  }
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
@@ -2202,10 +2240,9 @@ SILC_SERVER_CMD_FUNC(list)
   lchannels = silc_idlist_get_channels(server->local_list, channel_id,
                                       &lch_count);
   
-  /* Get the channels from global list if we are router */
-  if (server->server_type != SILC_SERVER) 
-    gchannels = silc_idlist_get_channels(server->global_list, channel_id,
-                                        &gch_count);
+  /* Get the channels from global list */
+  gchannels = silc_idlist_get_channels(server->global_list, channel_id,
+                                      &gch_count);
 
   /* Send the reply */
   silc_server_command_list_send_reply(cmd, lchannels, lch_count, 
@@ -2823,7 +2860,7 @@ SILC_SERVER_CMD_FUNC(info)
       uint16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
       silc_server_packet_send(server, entry->connection,
@@ -2848,7 +2885,7 @@ SILC_SERVER_CMD_FUNC(info)
       uint16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
       silc_server_packet_send(server, server->router->connection,
@@ -3299,7 +3336,7 @@ SILC_SERVER_CMD_FUNC(join)
            goto out;
          
          old_ident = silc_command_get_ident(cmd->payload);
-         silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+         silc_command_set_ident(cmd->payload, ++server->cmd_ident);
          tmpbuf = silc_command_payload_encode_payload(cmd->payload);
          
          /* Send JOIN command to our router */
@@ -3465,7 +3502,7 @@ SILC_SERVER_CMD_FUNC(motd)
       uint16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
       silc_server_packet_send(server, entry->connection,
@@ -3490,7 +3527,7 @@ SILC_SERVER_CMD_FUNC(motd)
       uint16 old_ident;
 
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
 
       silc_server_packet_send(server, server->router->connection,
@@ -5045,7 +5082,7 @@ SILC_SERVER_CMD_FUNC(users)
        !cmd->pending) {
       SilcBuffer tmpbuf;
       
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
       
       /* Send USERS command */
@@ -5188,7 +5225,7 @@ SILC_SERVER_CMD_FUNC(getkey)
        goto out;
       
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
       
       silc_server_packet_send(server, dest_sock,
@@ -5254,7 +5291,7 @@ SILC_SERVER_CMD_FUNC(getkey)
       uint16 old_ident;
       
       old_ident = silc_command_get_ident(cmd->payload);
-      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      silc_command_set_ident(cmd->payload, ++server->cmd_ident);
       tmpbuf = silc_command_payload_encode_payload(cmd->payload);
       
       silc_server_packet_send(server, server->router->connection,
index cb6c6973793d99e1480b6b5f09b61e7c27232a36..76b641cc3a3db766e4e8c1f5aa2f81ccec2aebb8 100644 (file)
@@ -57,6 +57,7 @@ SilcServerCommandReply silc_command_reply_list[] =
   SILC_SERVER_CMD_REPLY(join, JOIN),
   SILC_SERVER_CMD_REPLY(users, USERS),
   SILC_SERVER_CMD_REPLY(getkey, GETKEY),
+  SILC_SERVER_CMD_REPLY(list, LIST),
 
   { NULL, 0 },
 };
@@ -537,7 +538,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
       /* We don't have that server anywhere, add it. */
       channel = silc_idlist_add_channel(server->global_list, strdup(name),
                                        SILC_CHANNEL_MODE_NONE, channel_id, 
-                                       server->router->connection
+                                       server->router, 
                                        NULL, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -1065,8 +1066,8 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey)
   }
 
  out:
-  SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_USERS);
-  SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_USERS);
+  SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_GETKEY);
+  SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_GETKEY);
   if (idp)
     silc_id_payload_free(idp);
   silc_free(client_id);
@@ -1075,3 +1076,67 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey)
     silc_pkcs_public_key_free(public_key);
   silc_server_command_reply_free(cmd);
 }
+
+SILC_SERVER_CMD_REPLY_FUNC(list)
+{
+  SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
+  SilcServer server = cmd->server;
+  SilcCommandStatus status;
+  SilcChannelID *channel_id = NULL;
+  SilcChannelEntry channel;
+  uint32 len;
+  unsigned char *tmp, *name, *topic;
+  uint32 usercount = 0;
+
+  COMMAND_CHECK_STATUS_LIST;
+
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
+  channel_id = silc_id_payload_parse_id(tmp, len);
+  if (!channel_id)
+    goto out;
+
+  name = silc_argument_get_arg_type(cmd->args, 3, NULL);
+  topic = silc_argument_get_arg_type(cmd->args, 4, NULL);
+  tmp = silc_argument_get_arg_type(cmd->args, 5, NULL);
+  if (tmp)
+    SILC_GET32_MSB(usercount, tmp);
+
+  /* Add the channel entry if we do not have it already */
+  channel = silc_idlist_find_channel_by_id(server->local_list, 
+                                          channel_id, NULL);
+  if (!channel)
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
+                                            channel_id, NULL);
+  if (!channel) {
+    /* If router did not find such Channel ID in its lists then this must
+       be bogus channel or some router in the net is buggy. */
+    if (server->server_type != SILC_SERVER)
+      goto out;
+    
+    channel = silc_idlist_add_channel(server->global_list, strdup(name),
+                                     SILC_CHANNEL_MODE_NONE, channel_id, 
+                                     server->router, 
+                                     NULL, NULL);
+    if (!channel)
+      goto out;
+    channel_id = NULL;
+  }
+
+  if (topic) {
+    silc_free(channel->topic);
+    channel->topic = strdup(topic);
+  }
+
+  /* Pending callbacks are not executed if this was an list entry */
+  if (status != SILC_STATUS_OK &&
+      status != SILC_STATUS_LIST_END) {
+    silc_server_command_reply_free(cmd);
+    return;
+  }
+
+ out:
+  SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_GETKEY);
+  SILC_SERVER_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_GETKEY);
+  silc_free(channel_id);
+  silc_server_command_reply_free(cmd);
+}
index eb5b53d48553b81a5a6718387e3469aa0c9941bb..3b824843c9ef805f64487a86ecea79af0e34cea0 100644 (file)
@@ -75,5 +75,6 @@ SILC_SERVER_CMD_REPLY_FUNC(motd);
 SILC_SERVER_CMD_REPLY_FUNC(join);
 SILC_SERVER_CMD_REPLY_FUNC(users);
 SILC_SERVER_CMD_REPLY_FUNC(getkey);
+SILC_SERVER_CMD_REPLY_FUNC(list);
 
 #endif
index 4a72bcb9f95ce557bbb25a0131e990b9c4b538d3..4dbe844d60badf99b4144a627cecf3f1899e839b 100644 (file)
@@ -42,6 +42,7 @@ void silc_idlist_add_data(void *entry, SilcIDListData idata)
   data->psn_receive = idata->psn_receive;
   data->hash = idata->hash;
   data->public_key = idata->public_key;
+  memcpy(data->fingerprint, idata->fingerprint, sizeof(data->fingerprint));
   data->rekey = idata->rekey;
   data->last_receive = idata->last_receive;
   data->last_sent = idata->last_sent;
index 0436d9a4ed2481969e2cfa6a527e0b0561ef7b21..37d3e9bb55ff85befdae4b59dae1809f6e3ee740 100644 (file)
@@ -93,6 +93,7 @@ typedef struct {
 
   /* Public key */
   SilcPublicKey public_key;
+  unsigned char fingerprint[20];
 
   /* Re-key context */
   SilcServerRekey rekey;
index 061894bec98e8e521b451557971db92be8ab61ff..50caf2403a30142a903c0948733449d92280a6da 100644 (file)
@@ -206,7 +206,8 @@ static void silc_server_protocol_ke_send_packet(SilcSKE ske,
 
 /* Sets the negotiated key material into use for particular connection. */
 
-int silc_server_protocol_ke_set_keys(SilcSKE ske,
+int silc_server_protocol_ke_set_keys(SilcServer server,
+                                    SilcSKE ske,
                                     SilcSocketConnection sock,
                                     SilcSKEKeyMaterial *keymat,
                                     SilcCipher cipher,
@@ -300,6 +301,9 @@ int silc_server_protocol_ke_set_keys(SilcSKE ske,
   /* Save the remote host's public key */
   silc_pkcs_public_key_decode(ske->ke1_payload->pk_data, 
                              ske->ke1_payload->pk_len, &idata->public_key);
+  if (ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL)
+    silc_hash_make(server->sha1hash, ske->ke1_payload->pk_data,
+                  ske->ke1_payload->pk_len, idata->fingerprint);
 
   sock->user_data = (void *)conn_data;
 
index 21c3d193bd987bf00aa024713eae8b88e2a6e439..303fdc930eaf2f0e9c62b26a37d3435bdb432e7a 100644 (file)
@@ -106,7 +106,8 @@ typedef struct {
 /* Prototypes */
 void silc_server_protocols_register(void);
 void silc_server_protocols_unregister(void);
-int silc_server_protocol_ke_set_keys(SilcSKE ske,
+int silc_server_protocol_ke_set_keys(SilcServer server,
+                                    SilcSKE ske,
                                     SilcSocketConnection sock,
                                     SilcSKEKeyMaterial *keymat,
                                     SilcCipher cipher,
index 3a227c50cd058ecd0871ccc805a4037836cf1962..2d76a24a55601af18f326db26893ab2c1f70899c 100644 (file)
@@ -726,7 +726,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
   /* We now have the key material as the result of the key exchange
      protocol. Take the key material into use. Free the raw key material
      as soon as we've set them into use. */
-  if (!silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
+  if (!silc_server_protocol_ke_set_keys(server, ctx->ske, 
+                                       ctx->sock, ctx->keymat,
                                        ctx->ske->prop->cipher,
                                        ctx->ske->prop->pkcs,
                                        ctx->ske->prop->hash,
@@ -1183,7 +1184,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
   /* We now have the key material as the result of the key exchange
      protocol. Take the key material into use. Free the raw key material
      as soon as we've set them into use. */
-  if (!silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
+  if (!silc_server_protocol_ke_set_keys(server, ctx->ske, 
+                                       ctx->sock, ctx->keymat,
                                        ctx->ske->prop->cipher,
                                        ctx->ske->prop->pkcs,
                                        ctx->ske->prop->hash,
@@ -2390,6 +2392,8 @@ void silc_server_free_sock_user_data(SilcServer server,
           become invalid now as well. */
        if (user_data->id)
          silc_server_remove_clients_by_server(server, user_data, TRUE);
+       if (server->server_type == SILC_SERVER)
+         silc_server_remove_channels_by_server(server, user_data);
       } else {
        /* Update the client entries of this server to the new backup
           router. This also removes the clients that *really* was owned
@@ -2397,6 +2401,9 @@ void silc_server_free_sock_user_data(SilcServer server,
        silc_server_update_clients_by_server(server, user_data, backup_router,
                                             TRUE, TRUE);
        silc_server_update_servers_by_server(server, user_data, backup_router);
+       if (server->server_type == SILC_SERVER)
+         silc_server_update_channels_by_server(server, user_data, 
+                                               backup_router);
       }
 
       /* Free the server entry */
@@ -3420,11 +3427,12 @@ void silc_server_announce_channels(SilcServer server,
                                    &channel_ids, creation_time);
 
   /* Get channels and channel users in global list */
-  silc_server_announce_get_channels(server, server->global_list,
-                                   &channels, &channel_users,
-                                   &channel_users_modes,
-                                   &channel_users_modes_c,
-                                   &channel_ids, creation_time);
+  if (server->server_type != SILC_SERVER)
+    silc_server_announce_get_channels(server, server->global_list,
+                                     &channels, &channel_users,
+                                     &channel_users_modes,
+                                     &channel_users_modes_c,
+                                     &channel_ids, creation_time);
 
   if (channels) {
     silc_buffer_push(channels, channels->data - channels->head);
index 423710f9330b299dc48d7ddad3282a0132e39ffa..4bcf0b115f09601b93a695aac91ffa397f0db79b 100644 (file)
@@ -90,8 +90,8 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server,
       server->backup->servers[i].local = local;
       memset(server->backup->servers[i].ip.data, 0,
             sizeof(server->backup->servers[i].ip.data));
-      silc_net_addr2bin_ne(ip, server->backup->servers[i].ip.data,
-                          sizeof(server->backup->servers[i].ip.data));
+      silc_net_addr2bin(ip, server->backup->servers[i].ip.data,
+                       sizeof(server->backup->servers[i].ip.data));
       //server->backup->servers[i].port = port;
       return;
     }
@@ -105,8 +105,8 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server,
   server->backup->servers[i].local = local;
   memset(server->backup->servers[i].ip.data, 0,
         sizeof(server->backup->servers[i].ip.data));
-  silc_net_addr2bin_ne(ip, server->backup->servers[i].ip.data,
-                      sizeof(server->backup->servers[i].ip.data));
+  silc_net_addr2bin(ip, server->backup->servers[i].ip.data,
+                   sizeof(server->backup->servers[i].ip.data));
   //server->backup->servers[i].port = server_id->port;
   server->backup->servers_count++;
 }
@@ -987,6 +987,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
                                           server->router);
       silc_server_update_clients_by_server(server, ctx->sock->user_data,
                                           server->router, TRUE, FALSE);
+      if (server->server_type == SILC_SERVER)
+       silc_server_update_channels_by_server(server, ctx->sock->user_data, 
+                                             server->router);
 
       packet = silc_buffer_alloc(2);
       silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
@@ -1125,7 +1128,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        silc_server_update_servers_by_server(server, backup_router, router);
        silc_server_update_clients_by_server(server, backup_router,
                                             router, TRUE, FALSE);
-       silc_server_backup_replaced_del(server, backup_router);
+       if (server->server_type == SILC_SERVER)
+         silc_server_update_channels_by_server(server, backup_router, router);
+       silc_server_backup_replaced_del(server, backup_router);
        silc_server_backup_add(server, backup_router, 
                               ctx->sock->ip, ctx->sock->port,
                               backup_router->server_type != SILC_ROUTER ?
index d0488095ef5bc64af9752cb4895796b5dedfe707..a29c2fd3757685017be70b928ae0368b528ea117 100644 (file)
@@ -622,6 +622,57 @@ void silc_server_update_servers_by_server(SilcServer server,
   }
 }
 
+/* Removes channels that are from `from. */
+
+void silc_server_remove_channels_by_server(SilcServer server, 
+                                          SilcServerEntry from)
+{
+  SilcIDCacheList list = NULL;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcChannelEntry channel = NULL;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  if (silc_idcache_get_all(server->global_list->channels, &list)) {
+    if (silc_idcache_list_first(list, &id_cache)) {
+      while (id_cache) {
+       channel = (SilcChannelEntry)id_cache->context;
+       if (channel->router == from)
+         silc_idlist_del_channel(server->global_list, channel);
+       if (!silc_idcache_list_next(list, &id_cache))
+         break;
+      }
+    }
+    silc_idcache_list_free(list);
+  }
+}
+
+/* Updates channels that are from `from' to be originated from `to'.  */
+
+void silc_server_update_channels_by_server(SilcServer server, 
+                                          SilcServerEntry from,
+                                          SilcServerEntry to)
+{
+  SilcIDCacheList list = NULL;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcChannelEntry channel = NULL;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  if (silc_idcache_get_all(server->global_list->channels, &list)) {
+    if (silc_idcache_list_first(list, &id_cache)) {
+      while (id_cache) {
+       channel = (SilcChannelEntry)id_cache->context;
+       if (channel->router == from)
+         channel->router = to;
+       if (!silc_idcache_list_next(list, &id_cache))
+         break;
+      }
+    }
+    silc_idcache_list_free(list);
+  }
+}
+
 /* Checks whether given channel has global users.  If it does this returns
    TRUE and FALSE if there is only locally connected clients on the channel. */
 
index 00f740baa6f25a698b07fa1117fe24f6814ad249..8ac40c4522e1ee3ffc7ce3d13a67cdb24270f04a 100644 (file)
@@ -50,6 +50,15 @@ void silc_server_update_servers_by_server(SilcServer server,
                                          SilcServerEntry from,
                                          SilcServerEntry to);
 
+/* Removes channels that are from `from. */
+void silc_server_remove_channels_by_server(SilcServer server, 
+                                          SilcServerEntry from);
+
+/* Updates channels that are from `from' to be originated from `to'.  */
+void silc_server_update_channels_by_server(SilcServer server, 
+                                          SilcServerEntry from,
+                                          SilcServerEntry to);
+
 /* Checks whether given channel has global users.  If it does this returns
    TRUE and FALSE if there is only locally connected clients on the channel. */
 bool silc_server_channel_has_global(SilcChannelEntry channel);
index ff0c551bb0c04f626fa1ab80a8525288f94ad33d..2d153f32f229f0b2b72144669cd0ed2aaf5e7c06 100644 (file)
@@ -46,7 +46,7 @@ void silc_id_create_server_id(int sock, SilcRng rng, SilcServerID **new_id)
 
   /* Create the ID */
   /* XXX Does not support IPv6 */
-  SILC_PUT32_MSB(server.sin_addr.s_addr, (*new_id)->ip.data);
+  memcpy((*new_id)->ip.data, &server.sin_addr.s_addr, 4);
   (*new_id)->ip.data_len = 4;
   (*new_id)->port = server.sin_port;
   (*new_id)->rnd = silc_rng_get_rn16(rng);
index a6f76db1cfad3a09b7d1e7e8c7bfc721f76802e4..bfb50ca7082e2ee95e5fda05e75fee920a528be5 100644 (file)
@@ -127,6 +127,11 @@ int main(int argc, char **argv)
          silc_debug = TRUE;
          silc_debug_hexdump = TRUE;
          silc_log_set_debug_string(optarg);
+#ifndef SILC_DEBUG
+         fprintf(stdout, 
+                 "Run-time debugging is not enabled. To enable it recompile\n"
+                 "the server with --enable-debug configuration option.\n");
+#endif
          break;
        case 'f':
          config_file = strdup(optarg);
index 0d9dd30c2e389d239ef8fe9290e45fb077a16b1e..f9575ad565d5d5372d65a3d91121f009c3474944 100644 (file)
@@ -293,7 +293,7 @@ List of all defined commands in SILC follows.
         binary hash digest of the public key.  The fingerprint MUST NOT
         be sent if the server has not verified the proof of posession of
         the corresponding private key.  Server can do this during the
-        SILC Key Exchange protocol.
+        SILC Key Exchange protocol.  The <fingerprint> is SHA1 digest.
 
         Status messages:
 
index 1b0666c44b984b922c0fdd8181b107aa605f969c..3ea6a3b448734bf178c9970257ec28f45d785165 100644 (file)
@@ -66,7 +66,6 @@ authenticated.
 
 
 
-
 .ti 0
 Table of Contents
 
@@ -79,45 +78,45 @@ Table of Contents
   2.3 SILC Packet Types .........................................  7
       2.3.1 SILC Packet Payloads ................................ 16
       2.3.2 Generic payloads .................................... 16
-            2.3.2.1 ID Payload .................................. 16
-            2.3.2.2 Argument Payload ............................ 17
+            2.3.2.1 ID Payload .................................. 17
+            2.3.2.2 Argument Payload ............................ 18
             2.3.2.3 Channel Payload ............................. 18
             2.3.2.4 Public Key Payload .......................... 19
-      2.3.3 Disconnect Payload .................................. 19
-      2.3.4 Success Payload ..................................... 19
-      2.3.5 Failure Payload ..................................... 20
-      2.3.6 Reject Payload ...................................... 21
+      2.3.3 Disconnect Payload .................................. 20
+      2.3.4 Success Payload ..................................... 21
+      2.3.5 Failure Payload ..................................... 21
+      2.3.6 Reject Payload ...................................... 22
       2.3.7 Notify Payload ...................................... 22
-      2.3.8 Error Payload ....................................... 21
-      2.3.9 Channel Message Payload ............................. 28
-      2.3.10 Channel Key Payload ................................ 31
-      2.3.11 Private Message Payload ............................ 33
-      2.3.12 Private Message Key Payload ........................ 34
-      2.3.13 Command Payload .................................... 36
-      2.3.14 Command Reply Payload .............................. 37
-      2.3.15 Connection Auth Request Payload .................... 37
-      2.3.16 New ID Payload ..................................... 38
-      2.3.17 New Client Payload ................................. 39
-      2.3.18 New Server Payload ................................. 40
-      2.3.19 New Channel Payload ................................ 41
-      2.3.20 Key Agreement Payload .............................. 42
-      2.3.21 Resume Router Payload .............................. 43
-      2.3.22 File Transfer Payload .............................. 43
-  2.4 SILC ID Types ............................................. 44
-  2.5 Packet Encryption And Decryption .......................... 44
-      2.5.1 Normal Packet Encryption And Decryption ............. 45
-      2.5.2 Channel Message Encryption And Decryption ........... 45
-      2.5.3 Private Message Encryption And Decryption ........... 46
-  2.6 Packet MAC Generation ..................................... 47
-  2.7 Packet Padding Generation ................................. 47
-  2.8 Packet Compression ........................................ 48
-  2.9 Packet Sending ............................................ 48
-  2.10 Packet Reception ......................................... 49
-  2.11 Packet Routing ........................................... 49
-  2.12 Packet Broadcasting ...................................... 50
-3 Security Considerations ....................................... 50
-4 References .................................................... 50
-5 Author's Address .............................................. 52
+      2.3.8 Error Payload ....................................... 28
+      2.3.9 Channel Message Payload ............................. 29
+      2.3.10 Channel Key Payload ................................ 32
+      2.3.11 Private Message Payload ............................ 34
+      2.3.12 Private Message Key Payload ........................ 35
+      2.3.13 Command Payload .................................... 37
+      2.3.14 Command Reply Payload .............................. 38
+      2.3.15 Connection Auth Request Payload .................... 38
+      2.3.16 New ID Payload ..................................... 39
+      2.3.17 New Client Payload ................................. 40
+      2.3.18 New Server Payload ................................. 41
+      2.3.19 New Channel Payload ................................ 42
+      2.3.20 Key Agreement Payload .............................. 43
+      2.3.21 Resume Router Payload .............................. 44
+      2.3.22 File Transfer Payload .............................. 44
+  2.4 SILC ID Types ............................................. 46
+  2.5 Packet Encryption And Decryption .......................... 46
+      2.5.1 Normal Packet Encryption And Decryption ............. 46
+      2.5.2 Channel Message Encryption And Decryption ........... 47
+      2.5.3 Private Message Encryption And Decryption ........... 48
+  2.6 Packet MAC Generation ..................................... 48
+  2.7 Packet Padding Generation ................................. 49
+  2.8 Packet Compression ........................................ 50
+  2.9 Packet Sending ............................................ 50
+  2.10 Packet Reception ......................................... 51
+  2.11 Packet Routing ........................................... 51
+  2.12 Packet Broadcasting ...................................... 52
+3 Security Considerations ....................................... 53
+4 References .................................................... 53
+5 Author's Address .............................................. 54
 
 .ti 0
 List of Figures
@@ -569,6 +568,8 @@ List of SILC Packet types are defined as follows.
                                   Payload
 
 
+
+
      13   SILC_PACKET_KEY_EXCHANGE
 
           This packet is used to start SILC Key Exchange Protocol, 
@@ -824,17 +825,6 @@ packet payloads.
 This payload can be used to send an ID.  ID's are variable in length
 thus this payload provides a way to send variable length ID's.
 
-
-
-
-
-
-
-
-
-
-
-
 The following diagram represents the ID Payload.
 
 .in 5
@@ -875,6 +865,12 @@ needs the arguments.  Argument Payloads MUST always reside right after
 the packet payload needing the arguments.  Incorrect amount of argument
 payloads MUST cause rejection of the packet.
 
+
+
+
+
+
+
 The following diagram represents the Argument Payload.
 
 .in 5
@@ -920,6 +916,16 @@ its name, the Channel ID and a mode.
 The following diagram represents the Channel Payload.
 
 
+
+
+
+
+
+
+
+
+
+
 .in 5
 .nf
                      1                   2                   3
@@ -972,6 +978,9 @@ public keys and certificates.
 The following diagram represents the Public Key Payload.
 
 
+
+
+
 .in 5
 .nf
                      1                   2                   3
@@ -1148,6 +1157,9 @@ The payload may only be sent with SILC_PACKET_NOTIFY packet.  It MUST
 not be sent in any other packet type.  The following diagram represents
 the Notify Payload.
 
+
+
+
 .in 5
 .nf
                      1                   2                   3
@@ -1750,6 +1762,12 @@ packet.  It MUST NOT be sent in any other packet type.  The following
 diagram represents the Private Message Payload.
 
 
+
+
+
+
+
+
 .in 5
 .nf
                      1                   2                   3
@@ -2343,6 +2361,8 @@ o Data (variable length) - Arbitrary file transfer data.  The
 .in 3
 
 
+
+
 .ti 0
 2.4 SILC ID Types
 
@@ -2371,6 +2391,10 @@ network.
      this ID in [SILC1].
 .in 3
 
+When encoding different IDs into the ID Payload, all fields are always
+in MSB first order.  The IP address, port, and/or the random number
+are encoded in the MSB first order.
+
 
 .ti 0
 2.5 Packet Encryption And Decryption
index 687341ec03be261d633390be0c0b60943397176e..305e9c7df5fed223785f7a7e3264285b904c0129 100644 (file)
@@ -397,6 +397,19 @@ bool silc_client_start_key_exchange(SilcClient client,
   return TRUE;
 }
 
+/* Callback called when error has occurred during connecting to the server.
+   The `connect' client operation will be called. */
+
+SILC_TASK_CALLBACK(silc_client_connect_failure)
+{
+  SilcClientKEInternalContext *ctx = 
+    (SilcClientKEInternalContext *)context;
+  SilcClient client = (SilcClient)ctx->client;
+
+  client->ops->connect(client, ctx->sock->user_data, FALSE);
+  silc_free(ctx);
+}
+
 /* Start of the connection to the remote server. This is called after
    succesful TCP/IP connection has been established to the remote host. */
 
@@ -485,8 +498,9 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
     silc_socket_free(ctx->sock);
 
     /* Notify application of failure */
-    client->ops->connect(client, ctx->sock->user_data, FALSE);
-    silc_free(ctx);
+    silc_schedule_task_add(client->schedule, ctx->sock->sock,
+                          silc_client_connect_failure, ctx,
+                          0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
     return;
   }
 
@@ -591,8 +605,9 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
     silc_socket_free(ctx->sock);
 
     /* Notify application of failure */
-    client->ops->connect(client, ctx->sock->user_data, FALSE);
-    silc_free(ctx);
+    silc_schedule_task_add(client->schedule, ctx->sock->sock,
+                          silc_client_connect_failure, ctx,
+                          0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
     return;
   }
 
@@ -1408,6 +1423,7 @@ void silc_client_receive_new_id(SilcClient client,
 {
   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
   int connecting = FALSE;
+  SilcClientID *client_id = silc_id_payload_get_id(idp);
   SilcBuffer sidp;
 
   if (!conn->local_entry)
@@ -1415,6 +1431,12 @@ void silc_client_receive_new_id(SilcClient client,
 
   /* Delete old ID from ID cache */
   if (conn->local_id) {
+    /* Check whether they are different */
+    if (SILC_ID_CLIENT_COMPARE(conn->local_id, client_id)) {
+      silc_free(client_id);
+      return;
+    }
+
     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
     silc_free(conn->local_id);
   }
@@ -1424,7 +1446,7 @@ void silc_client_receive_new_id(SilcClient client,
   if (conn->local_id_data)
     silc_free(conn->local_id_data);
 
-  conn->local_id = silc_id_payload_get_id(idp);
+  conn->local_id = client_id;
   conn->local_id_data = silc_id_payload_get_data(idp);
   conn->local_id_data_len = silc_id_payload_get_len(idp);;
 
@@ -1444,17 +1466,18 @@ void silc_client_receive_new_id(SilcClient client,
   silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id, 
                   (void *)conn->local_entry, FALSE);
 
-  /* Issue INFO command to fetch the real server name and server information
-     and other stuff. */
-  sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
-  silc_client_send_command(client, conn, SILC_COMMAND_INFO,
-                          ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
-  silc_buffer_free(sidp);
+  if (connecting) {
+    /* Issue INFO comqmand to fetch the real server name and server information
+       and other stuff. */
+    sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
+    silc_client_send_command(client, conn, SILC_COMMAND_INFO,
+                            ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
+    silc_buffer_free(sidp);
 
-  /* Notify application of successful connection. We do it here now that
-     we've received the Client ID and are allowed to send traffic. */
-  if (connecting)
+    /* Notify application of successful connection. We do it here now that
+       we've received the Client ID and are allowed to send traffic. */
     client->ops->connect(client, conn, TRUE);
+  }
 }
 
 /* Processed received Channel ID for a channel. This is called when client
index 5b508e5c3e6938645aefbd020e5f520b9d9879a4..1b7c39720a131a265c51fe7ad21cbf14af694fa1 100644 (file)
@@ -204,6 +204,9 @@ void silc_client_notify_by_server(SilcClient client,
       client_entry->status |= SILC_CLIENT_STATUS_RESOLVING;
       silc_client_notify_by_server_resolve(client, conn, packet, client_id);
       goto out;
+    } else {
+      if (client_entry != conn->local_entry)
+       silc_client_nickname_format(client, conn, client_entry);
     }
 
     /* Get Channel ID */
@@ -406,6 +409,9 @@ void silc_client_notify_by_server(SilcClient client,
     if (!client_entry2) {
       silc_client_notify_by_server_resolve(client, conn, packet, client_id);
       goto out;
+    } else {
+      if (client_entry2 != conn->local_entry)
+       silc_client_nickname_format(client, conn, client_entry2);
     }
 
     /* Remove the old from cache */
index bdb818f5f0ca2a0997910c70a2ab331288abeec4..0164d7642a3d5e16d9d0f5b96588d7c98b01cddb 100644 (file)
@@ -349,6 +349,29 @@ SILC_CLIENT_CMD_FUNC(identify)
   silc_client_command_free(cmd);
 }
 
+/* Pending callbcak that will be called after the NICK command was
+   replied by the server.  This sets the nickname if there were no
+   errors. */
+
+SILC_CLIENT_CMD_FUNC(nick_change)
+{
+  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+  SilcClientConnection conn = cmd->conn;
+  SilcClientCommandReplyContext reply = 
+    (SilcClientCommandReplyContext)context2;
+  SilcCommandStatus status;
+
+  SILC_GET16_MSB(status, silc_argument_get_arg_type(reply->args, 1, NULL));
+  if (status == SILC_STATUS_OK) {
+    /* Set the nickname */
+    if (conn->nickname)
+      silc_free(conn->nickname);
+    conn->nickname = strdup(cmd->argv[1]);
+  }
+
+  silc_client_command_free(cmd);
+}
+
 /* Command NICK. Shows current nickname/sets new nickname on current
    window. */
 
@@ -392,7 +415,7 @@ SILC_CLIENT_CMD_FUNC(nick)
   if (cmd->argv_lens[1] > 128)
     cmd->argv_lens[1] = 128;
 
-  /* Set new nickname */
+  /* Send the NICK command */
   buffer = silc_command_payload_encode(SILC_COMMAND_NICK, 1,
                                       &cmd->argv[1],
                                       &cmd->argv_lens[1], 
@@ -402,9 +425,15 @@ SILC_CLIENT_CMD_FUNC(nick)
                          SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
                          buffer->data, buffer->len, TRUE);
   silc_buffer_free(buffer);
-  if (conn->nickname)
-    silc_free(conn->nickname);
-  conn->nickname = strdup(cmd->argv[1]);
+
+  /* Register pending callback that will actually set the new nickname
+     if there were no errors returned by the server. */
+  silc_client_command_pending(conn, SILC_COMMAND_NICK, 
+                             cmd->conn->cmd_ident,
+                             silc_client_command_destructor,
+                             silc_client_command_nick_change,
+                             silc_client_command_dup(cmd));
+  cmd->pending = 1;
 
   /* Notify application */
   COMMAND;
@@ -933,7 +962,6 @@ SILC_CLIENT_CMD_FUNC(ping)
       conn->ping[i].start_time = time(NULL);
       conn->ping[i].dest_id = id;
       conn->ping[i].dest_name = strdup(conn->remote_host);
-      conn->ping_count++;
       break;
     }
   }
index b3c3f79180adeed63af1ea1ea10454978b2cbd49..29cfc2bbeecfacc17608466de8086cd54c8b5dba 100644 (file)
@@ -311,7 +311,7 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
   /* Notify application */
   if (!cmd->callback)
     COMMAND_REPLY((ARGS, client_entry, nickname, username, realname, 
-                  channels, mode, idle));
+                  channels, mode, idle, fingerprint));
 
   if (channels)
     silc_buffer_free(channels);
@@ -598,7 +598,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick)
   silc_client_receive_new_id(cmd->client, cmd->sock, idp);
     
   /* Notify application */
+  SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_NICK);
   COMMAND_REPLY((ARGS, conn->local_entry));
+  SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_NICK);
+  silc_client_command_reply_free(cmd);
+  return;
 
  out:
   SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_NICK);
index 3444819810314278c8bb2cb9911f81317fc9ef62..8ec66929aaea090d5f666ae26e1a251d04fbfaef 100644 (file)
@@ -917,7 +917,7 @@ void silc_client_nickname_format(SilcClient client,
 
   len = 0;
   for (i = 0; i < clients_count; i++)
-    if (clients[i]->valid)
+    if (clients[i]->valid && clients[i] != client_entry)
       len++;
   if (!len)
     return;
index 991d86537082ffdd47d4408506cef22b697aaf93..40bffdf826450a9eaf58004961ce7d7e213dd42b 100644 (file)
@@ -244,20 +244,8 @@ static void silc_client_protocol_ke_continue(SilcSKE ske,
   SILC_LOG_DEBUG(("Start"));
 
   if (ske->status != SILC_SKE_STATUS_OK) {
-    if (ske->status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
-      client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
-                      "Received unsupported server %s public key",
-                      ctx->sock->hostname);
-    } else if (ske->status == SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED) {
-      client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
-                      "Remote host did not send its public key, even though "
-                      "it must send it");
-    } else {
-      client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
-                      "Error during key exchange protocol with server %s",
-                      ctx->sock->hostname);
-    }
-    
+    /* Call failure client operation */
+    client->ops->failure(client, conn, protocol, (void *)ske->status);
     protocol->state = SILC_PROTOCOL_STATE_ERROR;
     silc_protocol_execute(protocol, client->schedule, 0, 0);
     return;
index 9ba67a7c56989b0c2da3581a903690842bfdfa67..0a3e2dc30b927e50c4be887ba8d7bd7e3776a26c 100644 (file)
@@ -287,7 +287,7 @@ silc_channel_message_payload_parse(SilcBuffer buffer,
 
   /* Decrypt the payload */
   ret = silc_channel_message_payload_decrypt(buffer->data, buffer->len,
-                                    cipher, hmac);
+                                            cipher, hmac);
   if (ret == FALSE)
     return NULL;
 
index 2397888312e644c8de71143b4d273a3539178115..ae71ecbaa8f880837afebfeac402b7f801088aef 100644 (file)
 typedef uint16 SilcIdType;
 
 /* The SILC ID Types */
-#define SILC_ID_NONE 0
-#define SILC_ID_SERVER 1
-#define SILC_ID_CLIENT 2
-#define SILC_ID_CHANNEL 3
+#define SILC_ID_NONE        0
+#define SILC_ID_SERVER      1
+#define SILC_ID_CLIENT      2
+#define SILC_ID_CHANNEL     3
 /***/
 
 /* The ID Lenghts. These are IPv4 based and should be noted if used directly
index db83587847ee3563aba420dfd66b6be5fbbfefa5..60534f6be8735c332d7ca31d4bb943be5914dd4b 100644 (file)
@@ -64,12 +64,12 @@ silc_private_message_payload_parse(SilcBuffer buffer, SilcCipher cipher)
                                                         &new->message_len),
                             SILC_STR_END);
   if (ret == -1) {
-    SILC_LOG_ERROR(("Incorrect private message payload"));
+    SILC_LOG_DEBUG(("Incorrect private message payload"));
     goto err;
   }
 
   if ((new->message_len < 1 || new->message_len > buffer->len)) {
-    SILC_LOG_ERROR(("Incorrect private message payload in packet, "
+    SILC_LOG_DEBUG(("Incorrect private message payload in packet, "
                    "packet dropped"));
     goto err;
   }
index 4d0d27062d1f0485f4d5f81f5b0b677f2e2b2459..4ec556bcbba3d01420ac9ab752a509970c338033 100644 (file)
@@ -209,34 +209,13 @@ void silc_hash_make(SilcHash hash, const unsigned char *data,
 char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data,
                            uint32 data_len)
 {
-  char fingerprint[64], *cp;
   unsigned char h[32];
-  int i;
 
   if (!hash)
     silc_hash_alloc("sha1", &hash);
 
   silc_hash_make(hash, data, data_len, h);
-  
-  memset(fingerprint, 0, sizeof(fingerprint));
-  cp = fingerprint;
-  for (i = 0; i < hash->hash->hash_len; i++) {
-    snprintf(cp, sizeof(fingerprint), "%02X", h[i]);
-    cp += 2;
-    
-    if ((i + 1) % 2 == 0)
-      snprintf(cp++, sizeof(fingerprint), " ");
-
-    if ((i + 1) % 10 == 0)
-      snprintf(cp++, sizeof(fingerprint), " ");
-  }
-  i--;
-  if ((i + 1) % 2 == 0)
-    cp[-2] = 0;
-  if ((i + 1) % 10 == 0)
-    cp[-1] = 0;
-  
-  return strdup(fingerprint);
+  return silc_fingerprint(h, hash->hash->hash_len);
 }
 
 static const char vo[]= "aeiouy";
index 0ffb369432c31a890c9a75dc6b15e61aad114776..5e3cee08d1b220c7779c9270290be273f2aecc20 100644 (file)
@@ -157,12 +157,11 @@ void silc_log_output_debug(char *file, char *function,
     return;
   }
 
-  if (debug_cb)
-    {
-      (*debug_cb)(file, function, line, string);
-      silc_free(string);
-      return;
-    }
+  if (debug_cb) {
+    (*debug_cb)(file, function, line, string);
+    silc_free(string);
+    return;
+  }
 
   fprintf(stderr, "%s:%d: %s\n", function, line, string);
   fflush(stderr);
@@ -191,12 +190,11 @@ void silc_log_output_hexdump(char *file, char *function,
     return;
   }
 
-  if (debug_hexdump_cb)
-    {
-      (*debug_hexdump_cb)(file, function, line, data_in, len, string);
-      silc_free(string);
-      return;
-    }
+  if (debug_hexdump_cb) {
+    (*debug_hexdump_cb)(file, function, line, data_in, len, string);
+    silc_free(string);
+    return;
+  }
 
   fprintf(stderr, "%s:%d: %s\n", function, line, string);
   silc_free(string);
@@ -316,8 +314,9 @@ void silc_log_reset_debug_callbacks()
 void silc_log_set_debug_string(const char *debug_string)
 {
   silc_free(silc_debug_string);
-  if (strchr(debug_string, '(') &&
-      strchr(debug_string, ')'))
+  if ((strchr(debug_string, '(') &&
+       strchr(debug_string, ')')) ||
+      strchr(debug_string, '$'))
     silc_debug_string = strdup(debug_string);
   else
     silc_debug_string = silc_string_regexify(debug_string);
index 8659cc54f0bf416a9ef7fc740d26d04bdcaf48be..b9978d6e9a16fd093688d756dba194ad0c76c47c 100644 (file)
@@ -200,26 +200,10 @@ bool silc_net_is_ip(const char *addr);
  * DESCRIPTION
  *
  *    Converts the IP number string from numbers-and-dots notation to
- *    binary form.
- *
- ***/
-bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len);
-
-/****f* silcutil/SilcNetAPI/silc_net_addr2bin_ne
- *
- * SYNOPSIS
- *
- *    bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
- *                             uint32 bin_len);
- *
- * DESCRIPTION
- *
- *    Converts the IP number string from numbers-and-dots notation to
  *    binary form in network byte order.
  *
  ***/
-bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
-                         uint32 bin_len);
+bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len);
 
 /****f* silcutil/SilcNetAPI/silc_net_check_host_by_sock
  *
index c61e70ce4836026c38789cdefc2250c1f192ee53..c37ec4e55df810e5c16206f1b94e3254016cc384 100644 (file)
@@ -544,7 +544,7 @@ char *silc_id_render(void *id, uint16 type)
       if (server_id->ip.data_len > 4) {
 
       } else {
-       SILC_GET32_MSB(ipv4.s_addr, server_id->ip.data);
+       memcpy(&ipv4.s_addr, server_id->ip.data, 4);
        strcat(rid, inet_ntoa(ipv4));
       }
 
@@ -565,7 +565,7 @@ char *silc_id_render(void *id, uint16 type)
       if (client_id->ip.data_len > 4) {
 
       } else {
-       SILC_GET32_MSB(ipv4.s_addr, client_id->ip.data);
+       memcpy(&ipv4.s_addr, client_id->ip.data, 4);
        strcat(rid, inet_ntoa(ipv4));
       }
 
@@ -587,7 +587,7 @@ char *silc_id_render(void *id, uint16 type)
       if (channel_id->ip.data_len > 4) {
 
       } else {
-       SILC_GET32_MSB(ipv4.s_addr, channel_id->ip.data);
+       memcpy(&ipv4.s_addr, channel_id->ip.data, 4);
        strcat(rid, inet_ntoa(ipv4));
       }
 
@@ -904,3 +904,31 @@ char *silc_client_chumode_char(uint32 mode)
 
   return strdup(string);
 }
+
+/* Creates fingerprint from data, usually used with SHA1 digests */
+
+char *silc_fingerprint(const unsigned char *data, uint32 data_len)
+{
+  char fingerprint[64], *cp;
+  int i;
+
+  memset(fingerprint, 0, sizeof(fingerprint));
+  cp = fingerprint;
+  for (i = 0; i < data_len; i++) {
+    snprintf(cp, sizeof(fingerprint), "%02X", data[i]);
+    cp += 2;
+    
+    if ((i + 1) % 2 == 0)
+      snprintf(cp++, sizeof(fingerprint), " ");
+
+    if ((i + 1) % 10 == 0)
+      snprintf(cp++, sizeof(fingerprint), " ");
+  }
+  i--;
+  if ((i + 1) % 2 == 0)
+    cp[-2] = 0;
+  if ((i + 1) % 10 == 0)
+    cp[-1] = 0;
+  
+  return strdup(fingerprint);
+}
index 1c467a5661abb04d33028ce36f056d675edd7565..0307119455ad52e0a7ae678f36cca97690701fb3 100644 (file)
@@ -67,5 +67,6 @@ char *silc_client_chmode(uint32 mode, const char *cipher, const char *hmac);
 char *silc_client_chumode(uint32 mode);
 char *silc_client_chumode_char(uint32 mode);
 int silc_gettimeofday(struct timeval *p);
+char *silc_fingerprint(const unsigned char *data, uint32 data_len);
 
 #endif
index 12b28b771b4b7f836c6d52ae042f16463ad20198..72d47641fe8777299ffdc9ca80ba35735d0f5ac9 100644 (file)
@@ -284,22 +284,3 @@ bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len)
   memcpy(bin, (unsigned char *)&tmp.s_addr, 4);
   return ret != 0;
 }
-
-/* Converts the IP number string from numbers-and-dots notation to
-   binary form in network byte order. */
-
-bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
-                         uint32 bin_len)
-{
-  struct in_addr tmp;
-  int ret;
-
-  ret = inet_aton(addr, &tmp);
-
-  if (bin_len < 4)
-    return FALSE;
-
-  SILC_PUT32_MSB(tmp.s_addr, bin);
-
-  return ret != 0;
-}
index 0ff72b33d7cd8ee1917d40135aca819de0ae5dad..ed7818c57ab8f467a44b034d9b9fd6427de8077b 100644 (file)
@@ -235,24 +235,6 @@ bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len);
   return ret != INADDR_NONE;
 }
 
-/* Converts the IP number string from numbers-and-dots notation to
-   binary form in network byte order. */
-
-bool silc_net_addr2bin_ne(const char *addr, unsigned char *bin,
-                         uint32 bin_len)
-{
-  unsigned long ret;
-
-  ret = inet_addr(addr);
-
-  if (bin_len < 4)
-    return FALSE;
-
-  SILC_PUT32_MSB(ret, bin);
-
-  return ret != INADDR_NONE;
-}
-
 /* Set socket to non-blocking mode. */
 
 int silc_net_set_socket_nonblock(int sock)
index afe441ffe9fce4ab6580b5ee6e818d58b4b71489..c8d9c9bf5304c99713640783054c43bd561d9025 100644 (file)
 
 #include "silcincludes.h"
 
+/* XXX GNU regex may work on Win32 too!! */
+char *silc_string_regexify(const char *string)
+{
+  return strdup(string);
+}
+
+char *silc_string_regex_combine(const char *string1, const char *string2)
+{
+  return strdup(string1);
+}
+
+int silc_string_regex_match(const char *regex, const char *string)
+{
+  return TRUE;
+}
+
+int silc_string_match(const char *string1, const char *string2)
+{
+  return TRUE;
+}
+
 #define FILETIME_1970 0x019db1ded53e8000
 const BYTE DWLEN = sizeof(DWORD) * 8;
 
diff --git a/prepare b/prepare
index 8942bf63a9b14518ca8a8d7214ffdb33e1f84715..4d4af2820e9c38fc9d98247d70d46f105863283b 100755 (executable)
--- a/prepare
+++ b/prepare
@@ -37,7 +37,7 @@
 # SILC Distribution versions. Set here or give the version on the command
 # line as argument.
 #
-SILC_VERSION=0.6.1                     # Base version
+SILC_VERSION=0.6.2                     # Base version
 
 
 #############################################################################
diff --git a/silc_optimize b/silc_optimize
new file mode 100644 (file)
index 0000000..655ac71
--- /dev/null
@@ -0,0 +1,70 @@
+SILC Optimizations:
+===================
+
+o Library
+
+       o There is currently three (3) allocations per packet in the
+         silc_packet_receive_process, which is used to process and
+         dispatch all packets in the packet queue to the parser callback
+         function.  First allocation is for parse_ctx, second for the
+         SilcPacketContext, and third for packet->buffer where the actual
+         data is saved.
+
+         The parse_ctx allocation can be removed by adding it as a
+         structure to the SilcPacketContext.  When the SilcPacketContext
+         is allocated there is space for the parse context already.
+
+         The silc_packet_context_alloc should have a free list of
+         packet contexts.  If free packet context is found from the list
+         it is returned instead of allocating a new one.  The library
+         could at first allocate them and save them to the free list
+         until enough contexts for smooth processing exists in the list.
+         This would remove a big allocation since the structure is
+         quite big, and even bigger if it would include the parse_ctx.
+
+         The packet->buffer can be optimized too if the SilcBuffer
+         interface would support free lists as well.  Maybe such could
+         be done in the same way as for SilcPacketContext.  The
+         silc_buffer_alloc would check free list before actually 
+         allocating new memory.  Since the packets in the SILC protocol
+         usually are about the same size (due to padding) it would be
+         easy to find suitable size buffer from the free list very
+         quickly.
+
+         These naturally cause the overal memory consumption to grow
+         but would take away many allocations that can be done several
+         times in a second.
+
+       o Move the actual file descriptor task callback (the callback that
+         handles the incoming data, outgoing data etc, that is implemnted
+         in server and client separately (silc_server_packet_process and
+         silc_client_packet_proces)) to the low level socket connection
+         handling routines, and create an interface where the application
+         can register a callbacks for incoming data, outoing data and EOF
+         receiving and maybe sending too, which the library will call
+         when necessary.  This way we can move the data handling in one 
+         place.
+
+o Server
+
+       o When processing the decrypted and parsed packet we call the
+         silc_server_packet_parse_type function.  This function has a 
+         huge switch statement.  Replace this switch statment with pre-
+         defined table of function pointers where each of the slot
+         in the table represents the packet type (1 for packet type
+         value 1, 2 for value 2 and so on), and call the callback
+         found in the slot.  In this case we can do one-to-one mapping
+         of packet types to correct function.
+
+       o Same optimizations could be done with notify packets which
+         has huge switch statement too.  Same kind of table of notify
+         callbacks would be very easy to do, and achieve one-to-one
+         mapping of notify types.
+
+       o The parser callback in the server will add a timeout task for
+         all packets.  It will require registering and allocating a
+         new task to the SilcSchedule.  Maybe, at least, for server
+         and router packets the parser would be called immediately
+         instead of adding it to the scheduler with 0 timeout.  It
+         should be analyzed too how slow the task registering process
+         actually is, and find out ways to optimize it.