updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 9 Oct 2001 20:51:54 +0000 (20:51 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 9 Oct 2001 20:51:54 +0000 (20:51 +0000)
CHANGES
TODO
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/server_backup.c
apps/silcd/server_util.c
doc/draft-riikonen-silc-pp-04.nroff
doc/draft-riikonen-silc-spec-04.nroff
lib/silcsftp/sftp_fs_memory.c

diff --git a/CHANGES b/CHANGES
index bc91df7a51c8e6d7f1da39068f37f4206d25cad9..5eb2d3314b65be4f54cba2d4f35f1df23f8ac4ea 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,16 @@
+Tue Oct  9 17:45:43 EDT 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Wrote the definition of the backup resuming protocol to the
+         protocol specification.
+
+       * Removed one redundant channel key generation from normal
+         server during joining procedure.  Removed one redundant
+         channel key sending from server to router during joining
+         procedure.  Affected file silcd/command.c.
+
+       * Made minor bugfixes to the backup router resuming protocol.
+         Affected file silcd/server_backup.c, server.c.
+
 Mon Oct  8 16:47:42 EDT 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Added --disable-asm configuration option.  Affected files
diff --git a/TODO b/TODO
index fc44accbb42a8a7b98236d62f0edf8f5cc247712..feaa084f2cf1a6fe6b2503fdb0c0b2d84ca3f0e9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -57,11 +57,6 @@ TODO/bugs In SILC Server
    each JOIN command will create and distribute the new channel key
    to everybody on the channel.
 
- o Optimize the JOIN command in normal server.  When router returns
-   command reply for JOIN it returns the new channel key.  We however
-   still create new channel key when processing the pending JOIN command.
-   This works ok but is not necessary.
-
  o Optimize the WHOIS and IDENTIFY commands to somehow check whether the
    requested clients are on some channel that the server knows about.  If
    this is the case then the request is not needed to be forwarded to the
index d60bf2c65553fe572b17e0007257b260b9f075b1..3e94f304ae9b70647fad20608be6e8b07f246333 100644 (file)
@@ -2952,7 +2952,8 @@ static void silc_server_command_join_channel(SilcServer server,
                                             SilcServerCommandContext cmd,
                                             SilcChannelEntry channel,
                                             SilcClientID *client_id,
-                                            int created,
+                                            bool created,
+                                            bool create_key,
                                             uint32 umode)
 {
   SilcSocketConnection sock = cmd->sock;
@@ -3080,17 +3081,17 @@ static void silc_server_command_join_channel(SilcServer server,
   }
 
   /* Generate new channel key as protocol dictates */
-  if ((!created && silc_hash_table_count(channel->user_list) > 0) || 
-      !channel->channel_key)
+  if (create_key) {
     if (!silc_server_create_channel_key(server, channel, 0))
       goto out;
 
-  /* Send the channel key. This is broadcasted to the channel but is not
-     sent to the client who is joining to the channel. */
-  if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
-    silc_server_send_channel_key(server, NULL, channel, 
-                                server->server_type == SILC_ROUTER ? 
-                                FALSE : !server->standalone);
+    /* Send the channel key. This is broadcasted to the channel but is not
+       sent to the client who is joining to the channel. */
+    if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
+      silc_server_send_channel_key(server, NULL, channel, 
+                                  server->server_type == SILC_ROUTER ? 
+                                  FALSE : !server->standalone);
+  }
 
   /* Join the client to the channel by adding it to channel's user list.
      Add also the channel to client entry's channels list for fast cross-
@@ -3202,7 +3203,7 @@ SILC_SERVER_CMD_FUNC(join)
   char *tmp, *channel_name = NULL, *cipher, *hmac;
   SilcChannelEntry channel;
   uint32 umode = 0;
-  int created = FALSE;
+  bool created = FALSE, create_key = TRUE;
   SilcClientID *client_id;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_JOIN, cmd, 1, 4);
@@ -3269,13 +3270,14 @@ SILC_SERVER_CMD_FUNC(join)
                                                 hmac, channel_name, TRUE);
        if (!channel) {
          silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
-                                    SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+                                       SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
          goto out;
        }
-
+       
        umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
        created = TRUE;
-
+       create_key = FALSE;
+       
       } else {
 
        /* The channel does not exist on our server. If we are normal server 
@@ -3328,6 +3330,7 @@ SILC_SERVER_CMD_FUNC(join)
 
          umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
          created = TRUE;
+         create_key = FALSE;
        }
       }
     }
@@ -3358,21 +3361,30 @@ SILC_SERVER_CMD_FUNC(join)
 
        umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
        created = TRUE;
+       create_key = FALSE;
       }
     }
   }
 
-  /* If the channel does not have global users and is also empty it means the
-     channel was created globally (by our router) and the client will be the
-     channel founder and operator. */
-  if (!channel->global_users && !silc_hash_table_count(channel->user_list)) {
-    umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
-    created = TRUE;            /* Created globally by our router */
+  /* Check whether the channel was created by our router */
+  if (cmd->pending && context2) {
+    SilcServerCommandReplyContext reply = 
+      (SilcServerCommandReplyContext)context2;
+    if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
+      tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
+      SILC_GET32_MSB(created, tmp);
+      create_key = FALSE;      /* Router returned the key already */
+    }
   }
 
+  /* If the channel does not have global users and is also empty the client
+     will be the channel founder and operator. */
+  if (!channel->global_users && !silc_hash_table_count(channel->user_list))
+    umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
+
   /* Join to the channel */
   silc_server_command_join_channel(server, cmd, channel, client_id,
-                                  created, umode);
+                                  created, create_key, umode);
 
   silc_free(client_id);
 
index 9d4730612e5183ecd072b0263ec0b8bf1e56ac57..a7f07df9b56d2e4fcbe35d04edc9d6541a129e90 100644 (file)
@@ -194,8 +194,10 @@ void silc_server_notify(SilcServer server,
       break;
 
     /* Do not add client to channel if it is there already */
-    if (silc_server_client_on_channel(client, channel))
+    if (silc_server_client_on_channel(client, channel)) {
+      SILC_LOG_DEBUG(("Client already on channel"));
       break;
+    }
 
     /* Send to channel */
     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
index 05323399eda32a43a8612d13898fbf6f42f15bef..4b58bda6bd8980411ede2a44f413020f4a6b6baa 100644 (file)
@@ -1319,7 +1319,9 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
                               ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
                               SILC_SERVER : SILC_ROUTER, NULL, 
                               ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
-                              server->id_entry : NULL, sock);
+                              server->id_entry : 
+                              (conn->backup_router ? server->id_entry : 
+                               NULL), sock);
       if (!new_server) {
        SILC_LOG_ERROR(("Could not add new server to cache"));
        silc_free(sock->user_data);
@@ -1351,14 +1353,6 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
        }
       }
 
-#if 0
-      /* If the incoming connection is normal server and marked as backup
-        server then it will use us as backup router. We'll disable the
-        connection until it is allowed to be used. */
-      if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER && conn->backup_router)
-       SILC_SET_DISABLED(sock);
-#endif
-
       /* Check whether this connection is to be our primary router connection
         if we do not already have the primary route. */
       if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
@@ -2381,16 +2375,6 @@ void silc_server_free_sock_user_data(SilcServer server,
       if (backup_router) {
        /* Announce all of our stuff that was created about 5 minutes ago.
           The backup router knows all the other stuff already. */
-       if (server->server_type == SILC_ROUTER)
-         silc_server_announce_servers(server, FALSE, 0,
-                                      server->router->connection);
-
-       /* Announce our clients and channels to the router */
-       silc_server_announce_clients(server, 0,
-                                    server->router->connection);
-       silc_server_announce_channels(server, 0,
-                                     server->router->connection);
-#if 0
        if (server->server_type == SILC_ROUTER)
          silc_server_announce_servers(server, FALSE, time(0) - 300,
                                       server->router->connection);
@@ -2400,7 +2384,6 @@ void silc_server_free_sock_user_data(SilcServer server,
                                     server->router->connection);
        silc_server_announce_channels(server, time(0) - 300,
                                      server->router->connection);
-#endif
       }
       break;
     }
index b70bd095966cac93bbc527ece3e9cd8c31794fc9..96f9c33f702ee2650f0e6c6e9d99b7e1f8ca1808 100644 (file)
@@ -965,9 +965,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
                                 TRUE : FALSE);
        }
 
-       /* Announce all of our information to the new primary router. We
-          announce all that was updated after the protocol was started since
-          the router knows all the older stuff. */
+       /* Announce all of our information to the new primary router. */
        if (server->server_type == SILC_ROUTER)
          silc_server_announce_servers(server, FALSE, 0,
                                       server->router->connection);
@@ -977,17 +975,6 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
                                     server->router->connection);
        silc_server_announce_channels(server, 0,
                                      server->router->connection);
-#if 0
-       if (server->server_type == SILC_ROUTER)
-         silc_server_announce_servers(server, FALSE, ctx->start - 60,
-                                      server->router->connection);
-       
-       /* Announce our clients and channels to the router */
-       silc_server_announce_clients(server, ctx->start - 60,
-                                    server->router->connection);
-       silc_server_announce_channels(server, ctx->start - 60,
-                                     server->router->connection);
-#endif
       }
 
       /* Protocol has ended, call the final callback */
index d4b035f8e3e0ea5f983f1968a291c5cd0fcacdb6..2d65c43f78bdb701dd1f4287c05925ea29a32942 100644 (file)
@@ -396,7 +396,7 @@ void silc_server_update_clients_by_server(SilcServer server,
          /* Skip clients that are *really* owned by the `from' */
          if (SILC_ID_COMPARE(from->id, client->id, 
                              client->id->ip.data_len)) {
-           SILC_LOG_DEBUG(("Found really owned client, will remove it"));
+           SILC_LOG_DEBUG(("Found really owned client, skip it"));
            if (!silc_idcache_list_next(list, &id_cache))
              break;
            else
@@ -435,7 +435,7 @@ void silc_server_update_clients_by_server(SilcServer server,
          /* Skip clients that are *really* owned by the `from' */
          if (SILC_ID_COMPARE(from->id, client->id, 
                              client->id->ip.data_len)) {
-           SILC_LOG_DEBUG(("Found really owned client, will remove it"));
+           SILC_LOG_DEBUG(("Found really owned client, skip it"));
            if (!silc_idcache_list_next(list, &id_cache))
              break;
            else
index ce081d206c6945f1474d55ce128dd4a43a250eb7..40c8fe34a265019e00c1b29687199d184c65db06 100644 (file)
@@ -2163,7 +2163,9 @@ it is a standalone server and it does not have router connection,
 in this case server acts as router.  Normal server send JOIN command
 to the router (after it has received JOIN command from client) which
 then processes the command and creates the channel.  Client MUST NOT
-send this packet.
+send this packet.  Server may send this packet to a router when it is
+announcing its existing channels to the router after it has connected
+to the router.
 
 The packet uses generic Channel Payload as New Channel Payload.  See
 section 2.3.2.3 for generic Channel Payload.  The Mode Mask field in the
@@ -2252,7 +2254,7 @@ represents the Resume Router Payload.
                      1
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|     Opcode    |  Session ID   |
+|      Type     |  Session ID   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 .in 3
 
@@ -2261,8 +2263,8 @@ Figure 22:  Resume Router Payload
 
 
 .in 6
-o Opcode (1 byte) - Indicates the opcode for the backup resume
-  protocol.
+o Type (1 byte) - Indicates the type of the backup resume
+  protocol packet.  The type values are defined in [SILC1].
 
 o Session ID (1 bytes) - Indicates the session ID for the
   backup resume protocol.  The sender of the packet sets this
@@ -2445,7 +2447,7 @@ It must be noted that this is only when the channel messages are sent
 from router to another router.  In all other cases the channel
 message encryption and decryption is as described above.  This
 different processing of channel messages with router to router
-connection is because channel keys are cell specific.  All cells has
+connection is because channel keys are cell specific.  All cells have
 their own channel keys thus the channel message traveling from one
 cell to another MUST be protected as it would be any normal SILC
 packet.
index c89197edd3705c33ba3fc5091a9bf6b43b333539..22d93d60de2a11f5005fa233118568ab6cee2830 100644 (file)
@@ -1575,28 +1575,102 @@ and it is intended that the original router of the cell will reassume
 its position as primary router when it comes back online.  The backup
 router that is now acting as primary router of the cell must constantly
 try to connect to the original primary router of the cell.  It is
-recommended that it would try to reconnect every 2 minutes to the primary
-router.
-
-When the connection is established to the primary router, the backup 
-router must announce all of its servers, clients, channels and other
-information to the primary router.  It must then send packet
-SILC_PACKET_RESUME_ROUTER to all of the server connections.  This
-packet is used to tell the servers that they must reconnect to the
-original primary router of the cell.  When they have established the
-connection to the router they must send the same packet back to the
-primary router as an indication that they have successfully connected
-back to the primary router.  Then, the primary router will send the
-same packet to the primary router as an indication that it will pass
-over the tasks of being primary router of the cell and will revert back
-as being normal server (but still existing as backup router) in the cell.
-
-When the primary router receives the SILC_PACKET_RESUME_ROUTER packet
-it must announce all of its servers, clients, channels and other information
-to its primary router.
-
-All the connections that were used as primary routes will revert back
-as being passive connections.
+RECOMMENDED that it would try to reconnect in 30 second intervals to
+the primary router.
+
+When the connection is established to the primary router the backup
+resuming protocol is executed.  The protocol is advanced as follows:
+
+  1. Backup router sends SILC_PACKET_RESUME_ROUTER packet with type
+     value 1 the primary router that came back online.  The packet
+     will indicate the primary router has been replaced by the backup
+     router.  After sending the packet the backup router will announce
+     all of its channels, channel users, modes etc. to the primary
+     router.
+
+  2. Backup router sends SILC_PACKET_RESUME_ROUTER packet with type
+     value 2 to its current primary router to indicate that it will
+     resign as being primary router.  Then, backup router sends the
+     SILC_PACKET_RESUME_ROUTER packet with type value 1 to all
+     connected servers to also indicate that it will resign as being
+     primary router.
+
+  3. Backup router also send SILC_PACKET_RESUME_ROUTER packet with
+     type value 2 to the router that is using the backup router
+     currently as its primary router.
+
+  4. Any server and router that receives the SILC_PACKET_RESUME_ROUTER
+     with type value 1 or 2 must reconnect immediately to the
+     primary router of the cell that came back online.  After they
+     have created the connection they MUST NOT use that connection
+     as active primary route but still route all packets to the
+     backup router.  After the connection is created they MUST send
+     SILC_PACKET_RESUME_ROUTER with type value 3 back to the
+     backup router.  The session ID value found in the first packet
+     MUST be set in this packet.
+
+  5. Backup router MUST wait for all packets with type value 3 before
+     it continues with the protocol.  It knows from the session ID values
+     set in the packet when it have received all packets.  The session
+     value should be different in all packets it have send earlier.
+     After the packets is received the backup router sends the
+     SILC_PACKET_RESUME_ROUTER packet with type value 4 to the
+     primary router that came back online.  This packet will indicate 
+     that the backup router is now ready to resign as being primary
+     router.  The session ID value in this packet MUST be the same as
+     in first packet sent to the primary router.  During this time
+     the backup router should still route all packets it is receiving
+     from server connections.
+
+  6. The primary router receives the packet and send the
+     SILC_PACKET_RESUME_ROUTER with type value 5 to all connected servers
+     including the backup router.  It also sends the packet with type
+     value 6 to its primary router, and to the router that is using
+     it as its primary router.  The Session ID value in this packet
+     SHOULD be zero (0).
+
+  7. Any server and router that receives the SILC_PACKET_RESUME_ROUTER
+     with type value 5 or 6 must switch their primary route to the
+     new primary router and remove the route for the backup router, since
+     it is not anymore the primary router of the cell.  They must also
+     update their local database to understand that the clients are
+     not originated from the backup router but from the locally connected
+     servers.  After that they MUST announce their channels, channel
+     users, modes etc. to the primary router.  They must not use the
+     backup router connection after this and the connection is considered
+     to be passive connection.  The implementations SHOULD be able
+     to disable the connection without closing the actual link.
+
+After this protocol is executed the backup router is now again normal
+server in the cell that has the backup link to the primary router.  The
+primary router feeds the router specific data again to the backup router.
+All server connections in the backup router are considered passive
+connections.
+
+When the primary router of the cell comes back online and connects
+to its primary router, the remote primary router must send the 
+SILC_PACKET_RESUME_ROUTER with type value 20 indicating that the
+connection is not allowed since the router has been replaced by an
+backup router.  The session ID value in this packet SHOULD be zero (0).
+When the router receives this packet it must not use the connection
+as active connection but to understand that it cannot act as primary
+router in the cell.  It must wait that the backup router connects to
+it, and the backup resuming protocol is executed.
+
+The following type values has been defined for SILC_PACKET_RESUME_ROUTER
+packet:
+
+  1    SILC_SERVER_BACKUP_START
+  2    SILC_SERVER_BACKUP_START_GLOBAL
+  3    SILC_SERVER_BACKUP_START_CONNECTED
+  4    SILC_SERVER_BACKUP_START_ENDING
+  5    SILC_SERVER_BACKUP_START_RESUMED
+  6    SILC_SERVER_BACKUP_START_GLOBAL
+  20   SILC_SERVER_BACKUP_START_REPLACED
+
+If any other value is found in the type field the packet must be 
+discarded.  The SILC_PACKET_RESUME_ROUTER packet and its payload
+is defined in [SILC2].
 
 
 .ti 0
index 9aac497000fbcdfa063b6eeac6822ce47e01967c..23d032a5ea47a090497e311e09d6f3c75faa5a96 100644 (file)
@@ -730,7 +730,7 @@ void mem_readdir(void *context, SilcSFTP sftp,
     /* Long name format is:
        drwx------   1   324210 Apr  8 08:40 mail/
        1234567890 123 12345678 123456789012 */
-    snprintf(long_name, sizeof(long_name),
+    snprintf(long_name, sizeof(long_name) - 1,
             "%c%c%c%c------ %3d %8lu %12s %s%s",
             (entry->directory ? 'd' : '-'),
             ((entry->perm & SILC_SFTP_FS_PERM_READ) ? 'r' : '-'),