updates. silc.server.0.7.2
authorPekka Riikonen <priikone@silcnet.org>
Mon, 17 Dec 2001 19:14:55 +0000 (19:14 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 17 Dec 2001 19:14:55 +0000 (19:14 +0000)
13 files changed:
CHANGES
TODO
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-core.c
apps/silcd/command.c
apps/silcd/command.h
apps/silcd/server.c
apps/silcd/server_internal.h
lib/silcclient/client_notify.c
lib/silcclient/command.c
lib/silcclient/idlist.c
lib/silccore/silcchannel.c
lib/silccore/silccommand.c

diff --git a/CHANGES b/CHANGES
index b449fa480e48572f23328f8e48a947afcb33e503..d284fe5e55fb7b4bdc1b8131a7bc4b0908d4bd13 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,33 @@
+Mon Dec 17 18:24:27 EET 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Fixed JOIN command parsing not to crash.  Affected file
+         lib/silcclient/command.c.
+
+       * Fied the NICK_CHANGE notify to add the new client entry
+         even it is resolved.  This removes an <[unknown]> nick
+         thingy bug in the client.  Affected file is 
+         lib/silcclient/client_notify.c.
+
+       * Do not try to allocate 0 bytes (efence does not like it)
+         in lib/silccore/silccomand.c when encoding payload.
+
+       * Do not take IRCNICK as nickname in Irssi SILC client since
+         it is not possible to set nickname before hand connecting
+         the server (TODO has an entry about adding auto-nicking
+         support).
+
+       * Changed the silc_server_command_pending to check whether
+         there already exists an pending entry with the specified
+         command, command identifier and pending callback.  This is
+         to fix IDENTIFY and WHOIS related crashes that may register
+         multiple pending commands with same identifier.  Affected
+         file silcd/command.c.
+
+       * Fixed the server to reconnect to the router even if it
+         was already reconnecting and EOF was received.  This to
+         fix a possibility that the server wouldn't ever try to
+         auto-reconnect to the router.  Affected file silcd/server.c.
+
 Sat Dec 15 20:31:50 EET 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed the server's password authentication to use the
diff --git a/TODO b/TODO
index 757b9c127bc9f5a41b70ac22ea9c2c935e4ca0de..a4d0dbb34ef23e8ad6ebd1909a96d269d51f79ae 100644 (file)
--- a/TODO
+++ b/TODO
@@ -17,6 +17,10 @@ TODO/bugs in Irssi SILC client
    cipher, hash, hmac and pkcs configuration to the Irssi SILC's config
    file.
 
+ o Add auto-nick support to Irssi, so that the user specified nickname
+   would be sent to the server immediately (automatically) after the
+   client is connected to the server.
+
  o Add PERL scripting support from Irssi CVS.
 
  o Extend the /HELP command to support sub commands or something.  So
@@ -35,17 +39,18 @@ TODO/bugs In SILC Client Library
    behaviour and maybe should be removed.  The changer should always
    get the one it wants and not have the formatted nickname.
 
+ o Additions to do after protocol version 1.1:
 
-TODO/bugs In SILC Server
-========================
+       o Fix the NICK_CHANGE notify handling not to create new entry
+         for the changed client, but take the nickname from the notify
+         (removes need for resolving as well).  Protocol TODO entry 3.
 
- o It is possible that IDENTIFy's check_client will register two pending       
-   callbacks for same ident, which must not happen.  Check same for WHOIS
-   as well.
+       o Add support for list of errors in command replies.  Protocol
+         TODO entry 1.
 
- o If auto-reconnecting to router and EOF is received during the
-   connecting phase the server will not try to auto-reconnect anymore
-   after that.  Fix to auto-reconnect.
+
+TODO/bugs In SILC Server
+========================
 
  o Backup router related issues
 
@@ -93,34 +98,45 @@ TODO/bugs In SILC Libraries
 TODO in SILC Protocol
 =====================
 
- o Add "request parameters" or similar to the WHOIS command, which can
-   be used to request various parameters (something not returned by
-   standard WHOIS command) about clients (info that could be fetched
-   even from clients).  Additional specification (or appendix) should 
-   be done to define the payload and the parameters.  It could be used
-   to make the WHOIS command support various search conditions as well.
-   This would be the way to extend the WHOIS command to support various
-   new features without always making the command incompatible to previous
-   version.  To be included in protocol version 1.1.
-
- o Re-define the Status Payload: it is now 16 bits, split it into two
-   8 bits fields.  First field includes status types from 0 - 9 and
-   10 - n *if* it is not an list of errors.  If it is list of errors then
-   the first field includes 1, 2 and/or 3, and the second field includes
-   the error status 10 - n.  This way it is possible to send multiple
-   errors (list of errors) and we have a way to tell the receiver that
-   there will be other errors as well.  The second field is used only
-   if there is list of errors.  If normal status, or normal (single)
-   error status the second field is set to zero, and must be ignored.
-   Hence, the status works same way as now except for list of errors.
-   To be included in protocol version 1.1.
-
- o Define that WHOIS and IDENTIFY commands must send list of errors
-   if multiple Client ID (or Channel ID and Server ID for IDENTIFY) was
-   requested and was not found.  Each unfound entry must cause an error
-   command reply to the sender.  Also define that errors must be sent
-   *after* sending successfully found entries (this way receiver may
-   ignore them).  To be included in protocol version 1.1.
+Current protocol version is 1.0.  However, it is far from being perfect,
+and needs to include additional features.  Following protocol TODO entries
+describe new stuff to be added to protocol versions 1.x.
+
+ 1. Re-define the Status Payload: it is now 16 bits, split it into two
+    8 bits fields.  First field includes status types from 0 - 9 and
+    10 - n *if* it is not an list of errors.  If it is list of errors then
+    the first field includes 1, 2 and/or 3, and the second field includes
+    the error status 10 - n.  This way it is possible to send multiple
+    errors (list of errors) and we have a way to tell the receiver that
+    there will be other errors as well.  The second field is used only
+    if there is list of errors.  If normal status, or normal (single)
+    error status the second field is set to zero, and must be ignored.
+    Hence, the status works same way as now except for list of errors.
+    To be included in protocol version 1.1.
+
+ 2. Define that WHOIS and IDENTIFY commands must send list of errors
+    if multiple Client ID (or Channel ID and Server ID for IDENTIFY) was
+    requested and was not found.  Each unfound entry must cause an error
+    command reply to the sender.  Also define that errors must be sent
+    *after* sending successfully found entries (this way receiver may
+    ignore them).  To be included in protocol version 1.1.
+
+ 3. Define the NICK_CHANGE notify to send the changed nickname as a new
+    third argument.  This will make the NICK_CHANGE notify handling easier
+    in the receiver's end (client primarily) since it removes the
+    requirement that receiver must resolve (using IDENTIFY or WHOIS) the
+    new Client ID received in the notify (because of the new nickname is
+    unknown).  To be included in protocol version 1.1.
+
+ 4. Add "request parameters" or similar to the WHOIS command, which can
+    be used to request various parameters (something not returned by
+    standard WHOIS command) about clients (info that could be fetched
+    even from clients).  Additional specification (or appendix) should 
+    be done to define the payload and the parameters.  It could be used
+    to make the WHOIS command support various search conditions as well.
+    This would be the way to extend the WHOIS command to support various
+    new features without always making the command incompatible to previous
+    version.  To be included in protocol version 1.1.
 
 
 TODO After 1.0
index f6dac8aec0db84efb94381362710eabde81fb464..5fadb888aa505d7905a6fb0788fe1fbc6fdc96f9 100644 (file)
@@ -93,7 +93,8 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
   
   nick = silc_nicklist_find(chanrec, sender);
   if (!nick) {
-    /* We didn't find client but it clearly exists, add it. */
+    /* We didn't find client but it clearly exists, add it. It must be
+       found on the channel->clients list. */
     SilcChannelUser chu;
 
     silc_list_start(channel->clients);
index 3dddc6e44c6a2795acbc4bf33bb045c72a236b8f..f5ea52a34107de8b04d65317fc37919442084ea1 100644 (file)
@@ -120,13 +120,15 @@ static void silc_init_userinfo(void)
     
     user_name = settings_get_str("user_name");
   }
-         
+
   /* nick */
+  /* Actually take SILCUSER or IRCUSER since nickname cannot be set
+     beforehand in SILC (XXX auto-nicking support should be added to Irssi). */
   nick = settings_get_str("nick");
   if (nick == NULL || *nick == '\0') {
-    str = g_getenv("SILCNICK");
+    str = g_getenv("SILCUSER");
     if (!str)
-      str = g_getenv("IRCNICK");
+      str = g_getenv("IRCUSER");
     settings_set_str("nick", str != NULL ? str : user_name);
     
     nick = settings_get_str("nick");
index 38d7a74e2f92a8963800972a92594275d031de55..6ed2dc5ea6fce902900669b1e29c0a4ca1edad0f 100644 (file)
@@ -297,9 +297,11 @@ silc_server_command_dup(SilcServerCommandContext ctx)
    with `context' when reply has been received.  It can be SILC_COMMAND_NONE
    to match any command with the `ident'.  If `ident' is non-zero
    the `callback' will be executed when received reply with command
-   identifier `ident'. */
+   identifier `ident'. If there already exists pending command for the
+   specified command, ident, callback and context this function has no
+   effect. */
 
-void silc_server_command_pending(SilcServer server,
+bool silc_server_command_pending(SilcServer server,
                                 SilcCommand reply_cmd,
                                 uint16 ident,
                                 SilcServerPendingDestructor destructor,
@@ -308,6 +310,16 @@ void silc_server_command_pending(SilcServer server,
 {
   SilcServerCommandPending *reply;
 
+  /* Check whether identical pending already exists for same command,
+     ident, callback and callback context. If it does then it would be
+     error to register it again. */
+  silc_dlist_start(server->pending_commands);
+  while ((reply = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
+    if (reply->reply_cmd == reply_cmd && reply->ident == ident &&
+       reply->callback == callback && reply->context == context)
+      return FALSE;
+  }
+
   reply = silc_calloc(1, sizeof(*reply));
   reply->reply_cmd = reply_cmd;
   reply->ident = ident;
@@ -315,6 +327,8 @@ void silc_server_command_pending(SilcServer server,
   reply->callback = callback;
   reply->destructor = destructor;
   silc_dlist_add(server->pending_commands, reply);
+
+  return TRUE;
 }
 
 /* Deletes pending command by reply command type. */
index da7a3ea737b96775ae255265838a5e3acce104a7..b842e7eec18440b101bcd4d3831f389d48dc4652 100644 (file)
@@ -122,7 +122,7 @@ SilcServerCommandContext silc_server_command_alloc();
 void silc_server_command_free(SilcServerCommandContext ctx);
 SilcServerCommandContext 
 silc_server_command_dup(SilcServerCommandContext ctx);
-void silc_server_command_pending(SilcServer server,
+bool silc_server_command_pending(SilcServer server,
                                 SilcCommand reply_cmd,
                                 uint16 ident,
                                 SilcServerPendingDestructor destructor,
index f90aca67e2ba55daa6568bd6ea54f9dbf4777fd8..d6a4d4e220e7cc229ec04618143537b92a54f083 100644 (file)
@@ -689,6 +689,9 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router)
        sconn->backup_replace_port = ptr->backup_replace_port;
       }
 
+      if (!server->router_conn && !sconn->backup)
+       server->router_conn = sconn;
+
       silc_schedule_task_add(server->schedule, fd, 
                             silc_server_connect_router,
                             (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
@@ -988,6 +991,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
     silc_free(sconn->backup_replace_ip);
     silc_free(sconn);
   }
+  if (sconn == server->router_conn)
+    server->router_conn = NULL;
 
   /* Free the protocol object */
   if (sock->protocol == protocol)
@@ -1556,6 +1561,14 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
 
     if (sock->user_data)
       silc_server_free_sock_user_data(server, sock);
+    else if (server->router_conn && server->router_conn->sock == sock &&
+            !server->router && server->standalone)
+      silc_schedule_task_add(server->schedule, 0, 
+                            silc_server_connect_to_router, 
+                            server, 1, 0,
+                            SILC_TASK_TIMEOUT,
+                            SILC_TASK_PRI_NORMAL);
+
     silc_server_close_connection(server, sock);
     return;
   }
@@ -2365,7 +2378,7 @@ void silc_server_free_sock_user_data(SilcServer server,
        /* Check whether we have a backup router connection */
        if (!backup_router || backup_router == user_data) {
          silc_schedule_task_add(server->schedule, 0, 
-                                silc_server_connect_to_router,
+                                silc_server_connect_to_router, 
                                 server, 1, 0,
                                 SILC_TASK_TIMEOUT,
                                 SILC_TASK_PRI_NORMAL);
index a40adec6a835bb3028befe18935fe658b5d5375d..8001cf382e1c7c1cabcc2ff1cbf32f5be3f528e7 100644 (file)
@@ -80,6 +80,8 @@ struct SilcServerStruct {
   bool backup_router;               /* TRUE if this is backup router */
   bool backup_primary;              /* TRUE if we've switched our primary
                                        router to a backup router. */
+  SilcServerConnection router_conn; /* non-NULL when connecting to the
+                                      primary router, and NULL otherwise. */
 
   /* Current command identifier, 0 not used */
   uint16 cmd_ident;
index 49c315c51fc46e5cddd0c3230447885d822776c4..8b3663b979e5492162b6513cd7e84f13d349dd37 100644 (file)
@@ -41,6 +41,8 @@ static void silc_client_notify_by_server_pending(void *context, void *context2)
   SilcClientCommandReplyContext reply = 
     (SilcClientCommandReplyContext)context2;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (reply) {
     SilcCommandStatus status;
     unsigned char *tmp = silc_argument_get_arg_type(reply->args, 1, NULL);
@@ -472,26 +474,37 @@ void silc_client_notify_by_server(SilcClient client,
     /* Find Client entry and if not found resolve it */
     client_entry2 = silc_client_get_client_by_id(client, conn, client_id);
     if (!client_entry2) {
+      /* Resolve the entry information */
       silc_client_notify_by_server_resolve(client, conn, packet, client_id);
-      goto out;
+
+      /* Add the new entry even though we resolved it. This is because we
+        want to replace the old entry with the new entry here right now. */
+      client_entry2 = 
+       silc_client_add_client(client, conn, NULL, NULL, NULL, 
+                              silc_id_dup(client_id, SILC_ID_CLIENT), 
+                              client_entry->mode);
+
+      /* Replace old ID entry with new one on all channels. */
+      silc_client_replace_from_channels(client, conn, client_entry,
+                                       client_entry2);
     } else {
       if (client_entry2 != conn->local_entry)
        silc_client_nickname_format(client, conn, client_entry2);
-    }
 
-    /* Remove the old from cache */
-    silc_idcache_del_by_context(conn->client_cache, client_entry);
+      /* Remove the old from cache */
+      silc_idcache_del_by_context(conn->client_cache, client_entry);
 
-    /* Replace old ID entry with new one on all channels. */
-    silc_client_replace_from_channels(client, conn, client_entry,
-                                     client_entry2);
+      /* Replace old ID entry with new one on all channels. */
+      silc_client_replace_from_channels(client, conn, client_entry,
+                                       client_entry2);
 
-    /* Notify application */
-    client->internal->ops->notify(client, conn, type, 
-                                 client_entry, client_entry2);
+      /* Notify application */
+      client->internal->ops->notify(client, conn, type, 
+                                   client_entry, client_entry2);
 
-    /* Free data */
-    silc_client_del_client_entry(client, conn, client_entry);
+      /* Free data */
+      silc_client_del_client_entry(client, conn, client_entry);
+    }
     break;
 
   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
index da743a42c2ec70247f970baca10f15d345a0a9bc..37ea4d6fff9744b1a1482f13475d326af447e8ff 100644 (file)
@@ -997,13 +997,13 @@ SILC_CLIENT_CMD_FUNC(join)
   name = cmd->argv[1];
 
   for (i = 2; i < cmd->argc; i++) {
-    if (!strcasecmp(cmd->argv[i], "-cipher") && cmd->argc >= i + 1) {
+    if (!strcasecmp(cmd->argv[i], "-cipher") && cmd->argc > i + 1) {
       cipher = cmd->argv[i + 1];
       i++;
-    } else if (!strcasecmp(cmd->argv[i], "-hmac") && cmd->argc >= i + 1) {
+    } else if (!strcasecmp(cmd->argv[i], "-hmac") && cmd->argc > i + 1) {
       hmac = cmd->argv[i + 1];
       i++;
-    } else if (!strcasecmp(cmd->argv[i], "-founder") && cmd->argc >= i + 1) {
+    } else if (!strcasecmp(cmd->argv[i], "-founder") && cmd->argc > i + 1) {
       if (!strcasecmp(cmd->argv[i + 1], "-pubkey")) {
        auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                  cmd->client->private_key,
index 2c520d148031f9cc3a4611145d4dc9fcad805ec0..d56421c2bfabeb5865546016462cefc707b2aa51 100644 (file)
@@ -747,6 +747,8 @@ SilcChannelEntry silc_client_get_channel(SilcClient client,
 
   entry = (SilcChannelEntry)id_cache->context;
 
+  SILC_LOG_DEBUG(("Found"));
+
   return entry;
 }
 
@@ -769,6 +771,8 @@ SilcChannelEntry silc_client_get_channel_by_id(SilcClient client,
 
   entry = (SilcChannelEntry)id_cache->context;
 
+  SILC_LOG_DEBUG(("Found"));
+
   return entry;
 }
 
index def0d53bdb9eac2e7e5c24de32fd14246d1e6c69..79419968176b334d0a64a13c514d98dcff7f8ec4 100644 (file)
@@ -429,7 +429,7 @@ unsigned char *silc_channel_message_get_data(SilcChannelMessagePayload payload,
 
 /* Return MAC. The caller knows the length of the MAC */
 
-unsigned char *silc_channel_mesage_get_mac(SilcChannelMessagePayload payload)
+unsigned char *silc_channel_message_get_mac(SilcChannelMessagePayload payload)
 {
   return payload->mac;
 }
index e1c2fc2bf1fe3a6a9e6db0677c74be1516ed9799..0d64787d06cd8d3ad778757ae0d3c05864d19562 100644 (file)
@@ -207,31 +207,33 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
                                           uint16 ident, 
                                           uint32 argc, va_list ap)
 {
-  unsigned char **argv;
+  unsigned char **argv = NULL;
   uint32 *argv_lens = NULL, *argv_types = NULL;
   unsigned char *x;
   uint32 x_len;
   uint32 x_type;
   SilcBuffer buffer;
-  int i, k;
-
-  argv = silc_calloc(argc, sizeof(unsigned char *));
-  argv_lens = silc_calloc(argc, sizeof(uint32));
-  argv_types = silc_calloc(argc, sizeof(uint32));
-
-  for (i = 0, k = 0; i < argc; i++) {
-    x_type = va_arg(ap, uint32);
-    x = va_arg(ap, unsigned char *);
-    x_len = va_arg(ap, uint32);
+  int i, k = 0;
 
-    if (!x_type || !x || !x_len)
-      continue;
-
-    argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
-    memcpy(argv[k], x, x_len);
-    argv_lens[k] = x_len;
-    argv_types[k] = x_type;
-    k++;
+  if (argc) {
+    argv = silc_calloc(argc, sizeof(unsigned char *));
+    argv_lens = silc_calloc(argc, sizeof(uint32));
+    argv_types = silc_calloc(argc, sizeof(uint32));
+
+    for (i = 0, k = 0; i < argc; i++) {
+      x_type = va_arg(ap, uint32);
+      x = va_arg(ap, unsigned char *);
+      x_len = va_arg(ap, uint32);
+      
+      if (!x_type || !x || !x_len)
+       continue;
+      
+      argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
+      memcpy(argv[k], x, x_len);
+      argv_lens[k] = x_len;
+      argv_types[k] = x_type;
+      k++;
+    }
   }
 
   buffer = silc_command_payload_encode(cmd, k, argv, argv_lens,