updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 8 Oct 2001 19:30:19 +0000 (19:30 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 8 Oct 2001 19:30:19 +0000 (19:30 +0000)
15 files changed:
CHANGES
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/server_backup.c
apps/silcd/server_backup.h
apps/silcd/server_internal.h
apps/silcd/server_util.c
apps/silcd/server_util.h
lib/silccore/silcpacket.c
lib/silccore/silcpacket.h
lib/silcsftp/sftp_client.c
lib/silcsftp/sftp_fs_memory.c
lib/silcsftp/sftp_server.c
lib/silcsftp/sftp_util.c

diff --git a/CHANGES b/CHANGES
index 381095ccae8229d7ae435a9c644d0fd1b081a406..bc91df7a51c8e6d7f1da39068f37f4206d25cad9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Mon Oct  8 16:47:42 EDT 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added --disable-asm configuration option.  Affected files
+         configure.in.pre, lib/silcmath/mpi/configure.in.  A patch
+         by salo.
+
+       * Implemented the backup resuming protocol that is used to
+         resume the primary router position in the cell after the
+         primary router comes back online.  Affected files
+         silcd/server_backup.[ch], silcd/server, silcd/packet_receive.c,
+         and silcd/server_util.[ch].
+
 Sun Oct  7 12:29:25 EDT 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Sleep two (2) seconds after sending QUIT command to server.
index 0bb1ddd3e51740e8b05ddb702bf535e7c1f93b44..9d4730612e5183ecd072b0263ec0b8bf1e56ac57 100644 (file)
@@ -1700,7 +1700,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
     SilcBuffer packet = silc_buffer_alloc(2);
     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
     silc_buffer_format(packet,
-                      SILC_STR_UI_CHAR(20),
+                      SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
                       SILC_STR_UI_CHAR(0),
                       SILC_STR_END);
     silc_server_packet_send(server, sock, 
@@ -1997,6 +1997,7 @@ void silc_server_new_channel(SilcServer server,
   unsigned char *id;
   uint32 id_len;
   uint32 mode;
+  SilcServerEntry server_entry;
   SilcChannelEntry channel;
 
   SILC_LOG_DEBUG(("Processing New Channel"));
@@ -2024,6 +2025,8 @@ void silc_server_new_channel(SilcServer server,
 
   id = silc_channel_get_id(payload, &id_len);
 
+  server_entry = (SilcServerEntry)sock->user_data;
+
   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
     /* Add the channel to global list as it is coming from router. It 
        cannot be our own channel as it is coming from router. */
@@ -2066,7 +2069,8 @@ void silc_server_new_channel(SilcServer server,
         on the router's IP address.  Check whether the ID is based in our
         IP and if it is not then create a new ID and enforce the server
         to switch the ID. */
-      if (!SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
+      if (server_entry->server_type != SILC_BACKUP_ROUTER &&
+         !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
        SilcChannelID *tmp;
        SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
        
index 2e85203df1d7335de7d244086c677cfb91a385b4..05323399eda32a43a8612d13898fbf6f42f15bef 100644 (file)
@@ -912,20 +912,23 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
       server->id_entry->router = id_entry;
       server->router = id_entry;
       server->standalone = FALSE;
-    }
     
-    /* If we are router then announce our possible servers. */
-    if (server->server_type == SILC_ROUTER)
-      silc_server_announce_servers(server, FALSE, 0);
+      /* If we are router then announce our possible servers. */
+      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);
-    silc_server_announce_channels(server, 0);
+      /* 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);
+    }
   } else {
     /* Add this server to be our backup router */
     silc_server_backup_add(server, id_entry, FALSE);
   }
 
+  sock->protocol = NULL;
+
   /* Call the completion callback to indicate that we've connected to
      the router */
   if (sconn->callback)
@@ -939,13 +942,14 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   }
 
   /* Free the protocol object */
+  if (sock->protocol == protocol)
+    sock->protocol = NULL;
   silc_protocol_free(protocol);
   if (ctx->packet)
     silc_packet_context_free(ctx->packet);
   if (ctx->ske)
     silc_ske_free(ctx->ske);
   silc_free(ctx);
-  sock->protocol = NULL;
 }
 
 /* Host lookup callbcak that is called after the incoming connection's
@@ -1343,7 +1347,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
        /* Change it back to SERVER type since that's what it really is. */
        if (conn->backup_local) {
          ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
-         new_server->server_type = SILC_SOCKET_TYPE_SERVER;
+         new_server->server_type = SILC_BACKUP_ROUTER;
        }
       }
 
@@ -1591,10 +1595,6 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
     goto out;
   }
 
-  /* If entry is disabled ignore what we got. */
-  if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED)
-    goto out;
-
   if (ret == 0) {
     /* Parse the packet. Packet type is returned. */
     ret = silc_packet_parse(packet);
@@ -1604,6 +1604,11 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
     ret = silc_packet_parse_special(packet);
   }
 
+  /* If entry is disabled ignore what we got. */
+  if (ret != SILC_PACKET_RESUME_ROUTER &&
+      idata && idata->status & SILC_IDLIST_STATUS_DISABLED)
+    goto out;
+
   if (ret == SILC_PACKET_NONE)
     goto out;
 
@@ -2360,13 +2365,12 @@ void silc_server_free_sock_user_data(SilcServer server,
           router. This also removes the clients that *really* was owned
           by the primary router and went down with the router.  */
        silc_server_update_clients_by_server(server, user_data, backup_router,
-                                            TRUE);
+                                            TRUE, TRUE);
       }
 
       /* Free the server entry */
       silc_server_backup_del(server, user_data);
-      if (user_data->id)
-       silc_server_backup_replaced_del(server, user_data->id);
+      silc_server_backup_replaced_del(server, user_data);
       silc_idlist_del_data(user_data);
       silc_idlist_del_server(server->local_list, user_data);
       server->stat.my_servers--;
@@ -2378,11 +2382,25 @@ void silc_server_free_sock_user_data(SilcServer server,
        /* 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, time(0) - 300);
+         silc_server_announce_servers(server, FALSE, 0,
+                                      server->router->connection);
 
        /* Announce our clients and channels to the router */
-       silc_server_announce_clients(server, time(0) - 300);
-       silc_server_announce_channels(server, time(0) - 300);
+       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);
+
+       /* Announce our clients and channels to the router */
+       silc_server_announce_clients(server, time(0) - 300,
+                                    server->router->connection);
+       silc_server_announce_channels(server, time(0) - 300,
+                                     server->router->connection);
+#endif
       }
       break;
     }
@@ -3076,20 +3094,21 @@ static void silc_server_announce_get_servers(SilcServer server,
    will be announced. */
 
 void silc_server_announce_servers(SilcServer server, bool global,
-                                 unsigned long creation_time)
+                                 unsigned long creation_time,
+                                 SilcSocketConnection remote)
 {
   SilcBuffer servers = NULL;
 
   SILC_LOG_DEBUG(("Announcing servers"));
 
   /* Get servers in local list */
-  silc_server_announce_get_servers(server, server->router,
+  silc_server_announce_get_servers(server, remote->user_data,
                                   server->local_list, &servers,
                                   creation_time);
 
   if (global)
     /* Get servers in global list */
-    silc_server_announce_get_servers(server, server->router,
+    silc_server_announce_get_servers(server, remote->user_data,
                                     server->global_list, &servers,
                                     creation_time);
 
@@ -3098,7 +3117,7 @@ void silc_server_announce_servers(SilcServer server, bool global,
     SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
 
     /* Send the packet */
-    silc_server_packet_send(server, server->router->connection,
+    silc_server_packet_send(server, remote,
                            SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
                            servers->data, servers->len, TRUE);
 
@@ -3157,7 +3176,8 @@ static void silc_server_announce_get_clients(SilcServer server,
    announced. */
 
 void silc_server_announce_clients(SilcServer server,
-                                 unsigned long creation_time)
+                                 unsigned long creation_time,
+                                 SilcSocketConnection remote)
 {
   SilcBuffer clients = NULL;
 
@@ -3177,7 +3197,7 @@ void silc_server_announce_clients(SilcServer server,
     SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
 
     /* Send the packet */
-    silc_server_packet_send(server, server->router->connection,
+    silc_server_packet_send(server, remote,
                            SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
                            clients->data, clients->len, TRUE);
 
@@ -3352,7 +3372,8 @@ void silc_server_announce_get_channels(SilcServer server,
    was provided. */
 
 void silc_server_announce_channels(SilcServer server,
-                                  unsigned long creation_time)
+                                  unsigned long creation_time,
+                                  SilcSocketConnection remote)
 {
   SilcBuffer channels = NULL, channel_users = NULL;
   SilcBuffer *channel_users_modes = NULL;
@@ -3380,7 +3401,7 @@ void silc_server_announce_channels(SilcServer server,
     SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
 
     /* Send the packet */
-    silc_server_packet_send(server, server->router->connection,
+    silc_server_packet_send(server, remote,
                            SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
                            channels->data, channels->len,
                            FALSE);
@@ -3394,7 +3415,7 @@ void silc_server_announce_channels(SilcServer server,
                     channel_users->len);
 
     /* Send the packet */
-    silc_server_packet_send(server, server->router->connection,
+    silc_server_packet_send(server, remote,
                            SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
                            channel_users->data, channel_users->len,
                            FALSE);
@@ -3411,7 +3432,7 @@ void silc_server_announce_channels(SilcServer server,
                       channel_users_modes[i]->head);
       SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data, 
                       channel_users_modes[i]->len);
-      silc_server_packet_send_dest(server, server->router->connection,
+      silc_server_packet_send_dest(server, remote,
                                   SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
                                   channel_ids[i], SILC_ID_CHANNEL,
                                   channel_users_modes[i]->data, 
@@ -3795,7 +3816,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
   SILC_LOG_DEBUG(("Start"));
 
   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
-       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
+      protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
     SILC_LOG_ERROR(("Error occurred during rekey protocol"));
     silc_protocol_cancel(protocol, server->schedule);
index 495bd263dc29bfefce379995039d488bb8994019..d2abd2c92c67195c23c09fb32b1827b24d80a5e4 100644 (file)
@@ -187,11 +187,14 @@ void silc_server_announce_get_channels(SilcServer server,
                                       SilcChannelID ***channel_ids,
                                       unsigned long creation_time);
 void silc_server_announce_servers(SilcServer server, bool global,
-                                 unsigned long creation_time);
+                                 unsigned long creation_time,
+                                 SilcSocketConnection remote);
 void silc_server_announce_clients(SilcServer server,
-                                 unsigned long creationg_time);
+                                 unsigned long creation_time,
+                                 SilcSocketConnection remote);
 void silc_server_announce_channels(SilcServer server,
-                                  unsigned long creationg_time);
+                                  unsigned long creation_time,
+                                  SilcSocketConnection remote);
 void silc_server_get_users_on_channel(SilcServer server,
                                      SilcChannelEntry channel,
                                      SilcBuffer *user_list,
index a3aaf17e888183828e3a862e9c8f3346f737f625..b70bd095966cac93bbc527ece3e9cd8c31794fc9 100644 (file)
@@ -16,6 +16,7 @@
   GNU General Public License for more details.
 
 */
+/* $Id$ */
 
 #include "serverincludes.h"
 #include "server_internal.h"
@@ -62,15 +63,6 @@ typedef struct {
   long start;
 } *SilcServerBackupProtocolContext;
 
-/* Backup resuming protocol types */
-#define SILC_SERVER_BACKUP_START            1
-#define SILC_SERVER_BACKUP_START_GLOBAL     2
-#define SILC_SERVER_BACKUP_CONNECTED        3
-#define SILC_SERVER_BACKUP_ENDING           4
-#define SILC_SERVER_BACKUP_RESUMED          5
-#define SILC_SERVER_BACKUP_RESUMED_GLOBAL   6
-#define SILC_SERVER_BACKUP_REPLACED         20
-
 /* Sets the `backup_server' to be one of our backup router. This can be
    called multiple times to set multiple backup routers. If `local' is
    TRUE then the `backup_server' is in the local cell, if FALSE it is
@@ -81,10 +73,8 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server,
 {
   int i;
 
-  if (!server->backup) {
+  if (!server->backup)
     server->backup = silc_calloc(1, sizeof(*server->backup));
-    server->backup->servers_count++;
-  }
 
   for (i = 0; i < server->backup->servers_count; i++) {
     if (!server->backup->servers[i].server) {
@@ -155,16 +145,17 @@ void silc_server_backup_replaced_add(SilcServer server,
   int i;
   SilcServerBackupReplaced *r = silc_calloc(1, sizeof(*r));;
 
-  if (!server->backup) {
+  if (!server->backup)
     server->backup = silc_calloc(1, sizeof(*server->backup));
-    server->backup->servers_count++;
-  }
   if (!server->backup->replaced) {
     server->backup->replaced = 
       silc_calloc(1, sizeof(*server->backup->replaced));
     server->backup->replaced_count = 1;
   }
 
+  SILC_LOG_DEBUG(("********************************"));
+  SILC_LOG_DEBUG(("Replaced added"));
+
   memcpy(&r->ip, &server_id->ip, sizeof(server_id->ip));
   //r->port = server_id->port;
   r->server = server_entry;
@@ -195,39 +186,44 @@ bool silc_server_backup_replaced_get(SilcServer server,
 {
   int i;
 
+  SILC_LOG_DEBUG(("***********************************************"));
+
   if (!server->backup || !server->backup->replaced)
     return FALSE;
 
-  for (i = 0; i < server->backup->servers_count; i++) {
+  for (i = 0; i < server->backup->replaced_count; i++) {
     if (!server->backup->replaced[i])
       continue;
+    SILC_LOG_HEXDUMP(("IP"), server_id->ip.data, server_id->ip.data_len);
+    SILC_LOG_HEXDUMP(("IP"), server->backup->replaced[i]->ip.data, 
+                    server->backup->replaced[i]->ip.data_len);
     if (!memcmp(&server->backup->replaced[i]->ip, &server_id->ip,
                sizeof(server_id->ip))) {
       if (server_entry)
        *server_entry = server->backup->replaced[i]->server;
+      SILC_LOG_DEBUG(("REPLACED"));
       return TRUE;
     }
   }
 
+  SILC_LOG_DEBUG(("NOT REPLACED"));
   return FALSE;
 }
 
-/* Deletes the IP address and port from the `server_id' from being replaced
-   by an backup router. */
+/* Deletes a replaced host by the set `server_entry. */
 
 void silc_server_backup_replaced_del(SilcServer server,
-                                    SilcServerID *server_id)
+                                    SilcServerEntry server_entry)
 {
   int i;
 
   if (!server->backup || !server->backup->replaced)
     return;
 
-  for (i = 0; i < server->backup->servers_count; i++) {
+  for (i = 0; i < server->backup->replaced_count; i++) {
     if (!server->backup->replaced[i])
       continue;
-    if (!memcmp(&server->backup->replaced[i]->ip, &server_id->ip,
-               sizeof(server_id->ip))) {
+    if (server->backup->replaced[i]->server == server_entry) {
       silc_free(server->backup->replaced[i]);
       server->backup->replaced[i] = NULL;
       return;
@@ -402,12 +398,21 @@ void silc_server_backup_resume_router(SilcServer server,
 
     ctx->type = type;
 
-    for (i = 0; i < ctx->sessions_count; i++) {
-      if (session == ctx->sessions[i].session) {
-       ctx->session = session;
-       silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
-       return;
+    SILC_LOG_DEBUG(("********************************"));
+    SILC_LOG_DEBUG(("Continuing protocol, type %d", type));
+
+    if (type != SILC_SERVER_BACKUP_RESUMED &&
+       type != SILC_SERVER_BACKUP_RESUMED_GLOBAL) {
+      for (i = 0; i < ctx->sessions_count; i++) {
+       if (session == ctx->sessions[i].session) {
+         ctx->session = session;
+         silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
+         return;
+       }
       }
+    } else {
+      silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
+      return;
     }
 
     SILC_LOG_DEBUG(("Bad resume router packet"));
@@ -473,7 +478,7 @@ SILC_TASK_CALLBACK(silc_server_backup_connect_to_router)
   if (sock < 0) {
     silc_schedule_task_add(server->schedule, 0,
                           silc_server_backup_connect_to_router,
-                          context, 0, 2, SILC_TASK_TIMEOUT, 
+                          context, 2, 0, SILC_TASK_TIMEOUT, 
                           SILC_TASK_PRI_NORMAL);
     return;
   }
@@ -563,6 +568,9 @@ static void silc_server_backup_connect_primary(SilcServer server,
     (SilcServerBackupProtocolContext)backup_router->protocol->context;
   SilcBuffer buffer;
 
+  SILC_LOG_DEBUG(("********************************"));
+  SILC_LOG_DEBUG(("Sending CONNECTED packet, session %d", ctx->session));
+
   /* Send the CONNECTED packet back to the backup router. */
   buffer = silc_buffer_alloc(2);
   silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
@@ -575,6 +583,10 @@ static void silc_server_backup_connect_primary(SilcServer server,
                          buffer->data, buffer->len, FALSE);
   silc_buffer_free(buffer);
 
+  /* The primary connection is disabled until it sends the RESUMED packet
+     to us. */
+  idata->status |= SILC_IDLIST_STATUS_DISABLED;
+
   /* Move this protocol context from this backup router connection to
      the primary router connection since it will send the subsequent
      packets in this protocol. We don't talk with backup router 
@@ -582,10 +594,6 @@ static void silc_server_backup_connect_primary(SilcServer server,
   sock->protocol = backup_router->protocol;
   ctx->sock = (SilcSocketConnection)server_entry->connection;
   backup_router->protocol = NULL;
-
-  /* The primary connection is disabled until it sends the RESUMED packet
-     to us. */
-  idata->status |= SILC_IDLIST_STATUS_DISABLED;
 }
 
 /* Resume protocol with RESUME_ROUTER packet: 
@@ -647,7 +655,7 @@ static void silc_server_backup_connect_primary(SilcServer server,
 
 SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
 {
-  SilcProtocol protocol = (SilcProtocol)protocol;
+  SilcProtocol protocol = (SilcProtocol)context;
   SilcServerBackupProtocolContext ctx = protocol->context;
   SilcServer server = ctx->server;
   SilcBuffer packet;
@@ -671,6 +679,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
       packet = silc_buffer_alloc(2);
       silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
 
+      SILC_LOG_DEBUG(("********************************"));
+      SILC_LOG_DEBUG(("Sending START packets"));
+
       /* Send the START packet to primary router and normal servers. */
       if (silc_idcache_get_all(server->local_list->servers, &list)) {
        if (silc_idcache_list_first(list, &id_cache)) {
@@ -691,6 +702,13 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
            ctx->sessions[ctx->sessions_count].connected = FALSE;
            ctx->sessions[ctx->sessions_count].server_entry = server_entry;
 
+           SILC_LOG_DEBUG(("********************************"));
+           SILC_LOG_DEBUG(("START for session %d", ctx->sessions_count));
+
+           /* This connection is performing this protocol too now */
+           ((SilcSocketConnection)server_entry->connection)->protocol =
+             protocol;
+
            if (server_entry->server_type == SILC_ROUTER)
              packet->data[0] = SILC_SERVER_BACKUP_START;
            else
@@ -709,14 +727,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        silc_idcache_list_free(list);
       }
 
-      /* Now, announce all of our information to the primary router */
-      if (server->server_type == SILC_ROUTER)
-       silc_server_announce_servers(server, FALSE, 0);
-      silc_server_announce_clients(server, 0);
-      silc_server_announce_channels(server, 0);
-
       silc_buffer_free(packet);
 
+      /* If we are router then announce our possible servers. */
+      if (server->server_type == SILC_ROUTER)
+       silc_server_announce_servers(server, FALSE, 0, ctx->sock);
+      silc_server_announce_clients(server, 0, ctx->sock);
+      silc_server_announce_channels(server, 0, ctx->sock);
+
       protocol->state++;
     } else {
       /* Responder of the protocol. */
@@ -729,17 +747,50 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        break;
       }
 
+      SILC_LOG_DEBUG(("********************************"));
+      SILC_LOG_DEBUG(("Received START packet, reconnecting to router"));
+
       /* Connect to the primary router that was down that is now supposed
         to be back online. We send the CONNECTED packet after we've
         established the connection to the primary router. */
       primary = silc_server_config_get_primary_router(server->config);
-      if (primary)
+      if (primary) {
        silc_server_backup_reconnect(server,
                                     primary->host, primary->port,
                                     silc_server_backup_connect_primary,
                                     ctx->sock);
+       if (server->server_type == SILC_ROUTER &&
+           (!server->router || 
+            server->router->data.status & SILC_IDLIST_STATUS_DISABLED))
+         protocol->state++;
+       else
+         protocol->state = SILC_PROTOCOL_STATE_END;
+
+      } else {
+       /* Nowhere to connect just return the CONNECTED packet */
+
+       SILC_LOG_DEBUG(("********************************"));
+       SILC_LOG_DEBUG(("Sending CONNECTED packet, session %d", ctx->session));
+       
+       /* Send the CONNECTED packet back to the backup router. */
+       packet = silc_buffer_alloc(2);
+       silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
+       silc_buffer_format(packet,
+                          SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_CONNECTED),
+                          SILC_STR_UI_CHAR(ctx->session),
+                          SILC_STR_END);
+       silc_server_packet_send(server, ctx->sock, 
+                               SILC_PACKET_RESUME_ROUTER, 0, 
+                               packet->data, packet->len, FALSE);
+       silc_buffer_free(packet);
+       protocol->state++;
+      }
 
-      protocol->state++;
+      ctx->sessions = silc_realloc(ctx->sessions,
+                                  sizeof(*ctx->sessions) *
+                                  (ctx->sessions_count + 1));
+      ctx->sessions[ctx->sessions_count].session = ctx->session;
+      ctx->sessions_count++;
     }
     break;
 
@@ -753,17 +804,28 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        break;
       }
 
+      SILC_LOG_DEBUG(("********************************"));
+      SILC_LOG_DEBUG(("Received CONNECTED packet, session %d", ctx->session));
+
       for (i = 0; i < ctx->sessions_count; i++) {
        if (ctx->sessions[i].session == ctx->session) {
          ctx->sessions[i].connected = TRUE;
+         break;
        }
       }
 
       for (i = 0; i < ctx->sessions_count; i++) {
        if (!ctx->sessions[i].connected)
-         break;
+         return;
       }
 
+      SILC_LOG_DEBUG(("********************************"));
+      SILC_LOG_DEBUG(("Sending ENDING packet to primary"));
+
+      for (i = 0; i < ctx->sessions_count; i++)
+       if (ctx->sessions[i].server_entry == ctx->sock->user_data)
+         ctx->session = ctx->sessions[i].session;
+
       /* We've received all the CONNECTED packets and now we'll send the
         ENDING packet to the new primary router. */
       packet = silc_buffer_alloc(2);
@@ -787,17 +849,27 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        break;
       }
 
+      SILC_LOG_DEBUG(("********************************"));
+      SILC_LOG_DEBUG(("Received ENDING packet, sending RESUMED packets"));
+
       /* This state is received by the primary router but also servers
         and perhaps other routers so check that if we are the primary
         router of the cell then start sending RESUMED packets.  If we
         are normal server or one of those other routers then procede
         to next state. */
-      if (!(server->router->data.status & SILC_IDLIST_STATUS_DISABLED)) {
+      if (server->router &&
+         !(server->router->data.status & SILC_IDLIST_STATUS_DISABLED) &&
+         silc_server_config_is_primary_route(server->config)) {
        /* We'll wait for RESUMED packet */
        protocol->state = SILC_PROTOCOL_STATE_END;
        break;
       }
 
+      /* Switch announced informations to our entry instead of using the
+        backup router. */
+      silc_server_update_clients_by_server(server, ctx->sock->user_data,
+                                          server->id_entry, TRUE, FALSE);
+
       packet = silc_buffer_alloc(2);
       silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
 
@@ -814,11 +886,17 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
                continue;
            }
 
+           SILC_LOG_DEBUG(("********************************"));
+           SILC_LOG_DEBUG(("RESUMED packet"));
+
+           /* This connection is performing this protocol too now */
+           ((SilcSocketConnection)server_entry->connection)->protocol =
+             protocol;
+
            if (server_entry->server_type == SILC_ROUTER)
              packet->data[0] = SILC_SERVER_BACKUP_RESUMED;
            else
              packet->data[0] = SILC_SERVER_BACKUP_RESUMED_GLOBAL;
-           packet->data[1] = ctx->sessions_count;
            silc_server_packet_send(server, server_entry->connection,
                                    SILC_PACKET_RESUME_ROUTER, 0, 
                                    packet->data, packet->len, FALSE);
@@ -855,6 +933,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        break;
       }
 
+      SILC_LOG_DEBUG(("********************************"));
+      SILC_LOG_DEBUG(("Received RESUMED packet"));
+
       /* We have now new primary router. All traffic goes there from now on. */
       if (server->backup_router)
        server->server_type = SILC_BACKUP_ROUTER;
@@ -866,21 +947,47 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        if (backup_router == server->router) {
          server->id_entry->router = ctx->sock->user_data;
          server->router = ctx->sock->user_data;
+         SILC_LOG_INFO(("Switching back to primary router %s",
+                        server->router->server_name));
+         SILC_LOG_DEBUG(("********************************"));
          SILC_LOG_DEBUG(("Switching back to primary router %s",
-                       server->router->server_name));
+                         server->router->server_name));
          idata = (SilcIDListData)server->router;
          idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
+
+         /* Update the client entries of the backup router to the new 
+            primary router. */
+         silc_server_update_clients_by_server(server, backup_router,
+                                              primary, TRUE, FALSE);
+         silc_server_backup_replaced_del(server, backup_router);
+         silc_server_backup_add(server, backup_router,
+                                backup_router->server_type != SILC_ROUTER ?
+                                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. */
        if (server->server_type == SILC_ROUTER)
-         silc_server_announce_servers(server, FALSE, ctx->start - 60);
+         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, ctx->start - 60,
+                                      server->router->connection);
        
        /* Announce our clients and channels to the router */
-       silc_server_announce_clients(server, ctx->start - 60);
-       silc_server_announce_channels(server, ctx->start - 60);
+       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 */
@@ -892,9 +999,19 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
     break;
 
   case SILC_PROTOCOL_STATE_ERROR:
+    /* Protocol has ended, call the final callback */
+    if (protocol->final_callback)
+      silc_protocol_execute_final(protocol, server->schedule);
+    else
+      silc_protocol_free(protocol);
     break;
 
   case SILC_PROTOCOL_STATE_FAILURE:
+    /* Protocol has ended, call the final callback */
+    if (protocol->final_callback)
+      silc_protocol_execute_final(protocol, server->schedule);
+    else
+      silc_protocol_free(protocol);
     break;
 
   case SILC_PROTOCOL_STATE_UNKNOWN:
@@ -904,5 +1021,41 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
 
 SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
 {
+  SilcProtocol protocol = (SilcProtocol)context;
+  SilcServerBackupProtocolContext ctx = protocol->context;
+  SilcServer server = ctx->server;
+  SilcServerEntry server_entry;
+  SilcSocketConnection sock;
+  SilcIDCacheList list;
+  SilcIDCacheEntry id_cache;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
+      protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
+    SILC_LOG_ERROR(("Error occurred during backup router resuming protcool"));
+  }
+
+  if (silc_idcache_get_all(server->local_list->servers, &list)) {
+    if (silc_idcache_list_first(list, &id_cache)) {
+      while (id_cache) {
+       server_entry = (SilcServerEntry)id_cache->context;
+       sock = (SilcSocketConnection)server_entry->connection;
+
+       if (sock->protocol && sock->protocol->protocol &&
+           sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP)
+         sock->protocol = NULL;
+       
+       if (!silc_idcache_list_next(list, &id_cache))
+         break;
+      }
+    }
+    silc_idcache_list_free(list);
+  }
 
+  if (ctx->sock->protocol)
+    ctx->sock->protocol = NULL;
+  silc_protocol_free(protocol);
+  silc_free(ctx->sessions);
+  silc_free(ctx);
 }
index 25fe49dbb33dfdd3f7ffb86e8e37128f215e2f38..42df86e28f3a8b9c60a202017f443bfc80cf8758 100644 (file)
 #ifndef SERVER_BACKUP_H
 #define SERVER_BACKUP_H
 
+/* Backup resuming protocol types */
+#define SILC_SERVER_BACKUP_START            1
+#define SILC_SERVER_BACKUP_START_GLOBAL     2
+#define SILC_SERVER_BACKUP_CONNECTED        3
+#define SILC_SERVER_BACKUP_ENDING           4
+#define SILC_SERVER_BACKUP_RESUMED          5
+#define SILC_SERVER_BACKUP_RESUMED_GLOBAL   6
+#define SILC_SERVER_BACKUP_REPLACED         20
+
 /* Adds the `backup_server' to be one of our backup router. This can be
    called multiple times to set multiple backup routers. If `local' is
    TRUE then the `backup_server' is in the local cell, if FALSE it is
@@ -53,10 +62,9 @@ bool silc_server_backup_replaced_get(SilcServer server,
                                     SilcServerID *server_id,
                                     SilcServerEntry *server_entry);
 
-/* Deletes the IP address and port from the `server_id' from being replaced
-   by an backup router. */
+/* Deletes a replaced host by the set `server_entry. */
 void silc_server_backup_replaced_del(SilcServer server,
-                                    SilcServerID *server_id);
+                                    SilcServerEntry server_entry);
 
 /* Broadcast the received packet indicated by `packet' to all of our backup 
    routers. All router wide information is passed using broadcast packets. 
index 9f51174a0652b74f0ef1708c7f447e4a7e0c5abf..5cd0241ecf5ec5074ace09655c2dd0532a6e0bf2 100644 (file)
@@ -73,7 +73,6 @@ struct SilcServerStruct {
                                        does not have connection to network. */
   bool listenning;                  /* TRUE if server is listenning for
                                        incoming connections. */
-
   SilcServerEntry id_entry;         /* Server's own ID entry */
   SilcServerEntry router;           /* Pointer to the primary router */
   unsigned long router_connect;             /* Time when router was connected */
index 398dc52eafcde1bf34ba0d8b89e34d3fc7030152..d4b035f8e3e0ea5f983f1968a291c5cd0fcacdb6 100644 (file)
@@ -365,13 +365,15 @@ silc_server_update_clients_by_real_server(SilcServer server,
    `from' and which are originated from a server that we have connection
    to, when we've acting as backup router. If it is FALSE the `to' will
    be the new source. This function also removes the clients that are
-   *really* originated from `from'. These are clients that the `from'
-   owns, and not just clients that are behind the `from'. */
+   *really* originated from `from' if `remove_from' is TRUE. These are
+   clients that the `from' owns, and not just clients that are behind
+   the `from'. */
 
 void silc_server_update_clients_by_server(SilcServer server, 
                                          SilcServerEntry from,
                                          SilcServerEntry to,
-                                         bool resolve_real_server)
+                                         bool resolve_real_server,
+                                         bool remove_from)
 {
   SilcIDCacheList list = NULL;
   SilcIDCacheEntry id_cache = NULL;
@@ -457,10 +459,11 @@ void silc_server_update_clients_by_server(SilcServer server,
     silc_idcache_list_free(list);
   }
 
-  /* Now remove the clients that are still marked as orignated from the
-     `from'. These are the clients that really was owned by the `from' and
-     not just exist behind the `from'. */
-  silc_server_remove_clients_by_server(server, from, TRUE);
+  if (remove_from)
+    /* Now remove the clients that are still marked as orignated from the
+       `from'. These are the clients that really was owned by the `from' and
+       not just exist behind the `from'. */
+    silc_server_remove_clients_by_server(server, from, TRUE);
 }
 
 /* Checks whether given channel has global users.  If it does this returns
index 283864f3384b1854570633505b182f091c516528..080f9600b3da8b57bd69693d89db1224f21b2eb3 100644 (file)
@@ -35,12 +35,14 @@ bool silc_server_remove_clients_by_server(SilcServer server,
    `from' and which are originated from a server that we have connection
    to, when we've acting as backup router. If it is FALSE the `to' will
    be the new source. This function also removes the clients that are
-   *really* originated from `from'. These are clients that the `from'
-   owns, and not just clients that are behind the `from'. */
+   *really* originated from `from' if `remove_from' is TRUE. These are
+   clients that the `from' owns, and not just clients that are behind
+   the `from'. */
 void silc_server_update_clients_by_server(SilcServer server, 
                                          SilcServerEntry from,
                                          SilcServerEntry to,
-                                         bool resolve_real_server);
+                                         bool resolve_real_server,
+                                         bool remove_from);
 
 /* 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 5c8b51577090dce9cb367a41c987a5e0e5c66f59..ec26ab1dd8cd60f64a0c7dfc529a2b6e61e9bb25 100644 (file)
@@ -671,7 +671,7 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
 
 /* Allocate packet context */
 
-SilcPacketContext *silc_packet_context_alloc()
+SilcPacketContext *silc_packet_context_alloc(void)
 {
   SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
   ctx->users++;
index 1d0338f74fb50456f4548d6fc7904adac4f0734c..a7d5c3ecaab39eee5280f71d3c984281c2c6668d 100644 (file)
@@ -366,23 +366,6 @@ do {                                                                            \
 
 /* Prototypes */
 
-/****f* silccore/SilcPacketAPI/silc_packet_write
- *
- * SYNOPSIS
- *
- *    int silc_packet_write(int sock, SilcBuffer src);
- *
- * DESCRIPTION
- *
- *    Writes data from encrypted buffer to the socket connection. If the
- *    data cannot be written at once, it will be written later with a timeout. 
- *    The data is written from the data section of the buffer, not from head
- *    or tail section. This automatically pulls the data section towards end
- *    after writing the data.
- *
- ***/
-int silc_packet_write(int sock, SilcBuffer src);
-
 /****f* silccore/SilcPacketAPI/silc_packet_send
  *
  * SYNOPSIS
@@ -499,31 +482,6 @@ void silc_packet_send_prepare(SilcSocketConnection sock,
                              uint32 padlen,
                              uint32 data_len);
 
-/****f* silccore/SilcPacketAPI/silc_packet_read
- *
- * SYNOPSIS
- *
- *    int silc_packet_read(int fd, SilcSocketConnection sock);
- *
- * DESCRIPTION
- *
- *    Reads data from the socket connection into the incoming data buffer.
- *    However, this does not parse the packet, it only reads some amount from
- *    the network. If there are more data available that can be read at a time
- *    the rest of the data will be read later with a timeout and only after
- *    that the packet is ready to be parsed. 
- *
- *    The destination buffer sent as argument must be initialized before 
- *    calling this function, and, the data section and the start of the tail
- *    section must be same. Ie. we add the read data to the tail section of
- *    the buffer hence the data section is the start of the buffer.
- *
- *    This returns amount of bytes read or -1 on error or -2 on case where
- *    all of the data could not be read at once.
- *
- ***/
-int silc_packet_read(int fd, SilcSocketConnection sock);
-
 /****f* silccore/SilcPacketAPI/silc_packet_receive
  *
  * SYNOPSIS
@@ -644,7 +602,7 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx);
  *    silc_packet_context_free function.
  *
  ***/
-SilcPacketContext *silc_packet_context_alloc();
+SilcPacketContext *silc_packet_context_alloc(void);
 
 /****f* silccore/SilcPacketAPI/silc_packet_context_dup
  *
index 6835e626f3e7758d025538a5d2872bea0b33eb5b..29ee2076ecd8972852c5e608bb25dce36e7ebf9b 100644 (file)
@@ -16,6 +16,7 @@
   GNU General Public License for more details.
 
 */
+/* $Id$ */
 
 #include "silcincludes.h"
 #include "silcsftp.h"
index 135810f14c46be0fb385ab586b3647143b671bac..9aac497000fbcdfa063b6eeac6822ce47e01967c 100644 (file)
@@ -16,6 +16,7 @@
   GNU General Public License for more details.
 
 */
+/* $Id$ */
 /* XXX TODO Win32 support */
 
 #include "silcincludes.h"
index 2286457fc9f8443472b9cf48ff4d0332dae5a49b..d0030a0cc2f1ffe7799f8ca670b1940f68d1dbd9 100644 (file)
@@ -16,6 +16,7 @@
   GNU General Public License for more details.
 
 */
+/* $Id$ */
 
 #include "silcincludes.h"
 #include "silcsftp.h"
index 349f8a0fdbe5446702478cacf17725d1a67303a7..eb4652accfde62761205aac15da665dca6fd77e5 100644 (file)
@@ -16,6 +16,7 @@
   GNU General Public License for more details.
 
 */
+/* $Id$ */
 
 #include "silcincludes.h"
 #include "silcsftp.h"