Created SILC Runtime Toolkit git repository Part I.
[runtime.git] / apps / silcd / server_backup.c
diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c
deleted file mode 100644 (file)
index e460c95..0000000
+++ /dev/null
@@ -1,1479 +0,0 @@
-/*
-
-  server_backup.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2001 - 2007 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-/* $Id$ */
-
-#include "serverincludes.h"
-#include "server_internal.h"
-
-SILC_TASK_CALLBACK(silc_server_protocol_backup_done);
-SILC_TASK_CALLBACK(silc_server_backup_announce_watches);
-
-static void silc_server_backup_connect_primary(SilcServer server,
-                                              SilcServerEntry server_entry,
-                                              void *context);
-
-
-/************************** Types and Definitions ***************************/
-
-/* Backup router */
-typedef struct {
-  SilcServerEntry server;
-  SilcIDIP ip;
-  SilcUInt16 port;
-  SilcBool local;
-} SilcServerBackupEntry;
-
-/* Holds IP address and port of the primary router that was replaced
-   by backup router. */
-typedef struct {
-  SilcIDIP ip;
-  SilcUInt16 port;
-  SilcServerEntry server;      /* Backup router that replaced the primary */
-} SilcServerBackupReplaced;
-
-/* Backup context */
-struct SilcServerBackupStruct {
-  SilcServerBackupEntry *servers;
-  SilcUInt32 servers_count;
-  SilcServerBackupReplaced **replaced;
-  SilcUInt32 replaced_count;
-};
-
-typedef struct {
-  SilcUInt8 session;
-  SilcBool connected;
-  SilcServerEntry server_entry;
-} SilcServerBackupProtocolSession;
-
-/* Backup resuming protocol context  */
-typedef struct {
-  SilcServer server;
-  SilcPacketStream sock;
-  SilcUInt8 type;
-  SilcUInt8 session;
-  SilcServerBackupProtocolSession *sessions;
-  SilcUInt32 sessions_count;
-  SilcUInt32 initiator_restart;
-  long start;
-  int state;
-  unsigned int responder        : 1;
-  unsigned int received_failure : 1;
-  unsigned int timeout          : 1;
-  unsigned int error            : 1;
-} *SilcServerBackupProtocolContext;
-
-
-/********************* Backup Configuration Routines ************************/
-
-/* Adds the `backup_server' to be one of our backup router. This can be
-   called multiple times to set multiple backup routers. The `ip' and `port'
-   is the IP and port that the `backup_router' will replace if the `ip'
-   will become unresponsive. If `local' is TRUE then the `backup_server' is
-   in the local cell, if FALSE it is in some other cell. */
-
-void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server,
-                           const char *ip, int port, SilcBool local)
-{
-  int i;
-
-  if (!ip)
-    return;
-
-  if (!server->backup) {
-    server->backup = silc_calloc(1, sizeof(*server->backup));
-    if (!server->backup)
-      return;
-  }
-
-  /* See if already added */
-  for (i = 0; i < server->backup->servers_count; i++) {
-    if (server->backup->servers[i].server == backup_server)
-      return;
-  }
-
-  SILC_LOG_DEBUG(("Backup router %s will replace %s",
-                 backup_server->data.sconn ?
-                 backup_server->data.sconn->remote_host : "(me)", ip));
-
-  for (i = 0; i < server->backup->servers_count; i++) {
-    if (!server->backup->servers[i].server) {
-      server->backup->servers[i].server = backup_server;
-      server->backup->servers[i].local = local;
-      server->backup->servers[i].port = SILC_SWAB_16(port);
-      memset(server->backup->servers[i].ip.data, 0,
-            sizeof(server->backup->servers[i].ip.data));
-      silc_net_addr2bin(ip, server->backup->servers[i].ip.data,
-                       sizeof(server->backup->servers[i].ip.data));
-      return;
-    }
-  }
-
-  i = server->backup->servers_count;
-  server->backup->servers = silc_realloc(server->backup->servers,
-                                        sizeof(*server->backup->servers) *
-                                        (i + 1));
-  server->backup->servers[i].server = backup_server;
-  server->backup->servers[i].local = local;
-  server->backup->servers[i].port = SILC_SWAB_16(port);
-  memset(server->backup->servers[i].ip.data, 0,
-        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_count++;
-}
-
-/* Returns backup router for IP and port in `server_id' or NULL if there
-   does not exist backup router. */
-
-SilcServerEntry silc_server_backup_get(SilcServer server,
-                                      SilcServerID *server_id)
-{
-  int i;
-
-  if (!server->backup)
-    return NULL;
-
-  for (i = 0; i < server->backup->servers_count; i++) {
-    if (server->backup->servers[i].server &&
-       server->backup->servers[i].port == server_id->port &&
-       !memcmp(server->backup->servers[i].ip.data, server_id->ip.data,
-               sizeof(server_id->ip.data))) {
-      SILC_LOG_DEBUG(("Found backup router %s for %s",
-                     server->backup->servers[i].server->server_name,
-                     silc_id_render(server_id, SILC_ID_SERVER)));
-      return server->backup->servers[i].server;
-    }
-  }
-
-  return NULL;
-}
-
-/* Deletes the backup server `server_entry'. */
-
-void silc_server_backup_del(SilcServer server, SilcServerEntry server_entry)
-{
-  int i;
-
-  if (!server->backup)
-    return;
-
-  for (i = 0; i < server->backup->servers_count; i++) {
-    if (server->backup->servers[i].server == server_entry) {
-      SILC_LOG_DEBUG(("Removing %s as backup router",
-                     silc_id_render(server->backup->servers[i].server->id,
-                                    SILC_ID_SERVER)));
-      server->backup->servers[i].server = NULL;
-      memset(server->backup->servers[i].ip.data, 0,
-            sizeof(server->backup->servers[i].ip.data));
-    }
-  }
-}
-
-/* Frees all data allocated for backup routers.  Call this after deleting
-   all backup routers and when new routers are added no more, for example
-   when shutting down the server. */
-
-void silc_server_backup_free(SilcServer server)
-{
-  int i;
-
-  if (!server->backup)
-    return;
-
-  /* Delete existing servers if caller didn't do it */
-  for (i = 0; i < server->backup->servers_count; i++) {
-    if (server->backup->servers[i].server)
-      silc_server_backup_del(server, server->backup->servers[i].server);
-  }
-
-  silc_free(server->backup->servers);
-  silc_free(server->backup);
-  server->backup = NULL;
-}
-
-/* Marks the IP address and port from the `server_id' as  being replaced
-   by backup router indicated by the `server'. If the router connects at
-   a later time we can check whether it has been replaced by an backup
-   router. */
-
-void silc_server_backup_replaced_add(SilcServer server,
-                                    SilcServerID *server_id,
-                                    SilcServerEntry server_entry)
-{
-  int i;
-  SilcServerBackupReplaced *r = silc_calloc(1, sizeof(*r));;
-
-  if (!server->backup)
-    server->backup = silc_calloc(1, sizeof(*server->backup));
-  if (!server->backup->replaced) {
-    server->backup->replaced =
-      silc_calloc(1, sizeof(*server->backup->replaced));
-    server->backup->replaced_count = 1;
-  }
-
-  SILC_LOG_DEBUG(("Replacing router %s with %s",
-                 silc_id_render(server_id, SILC_ID_SERVER),
-                 server_entry->server_name));
-
-  memcpy(&r->ip, &server_id->ip, sizeof(server_id->ip));
-  r->server = server_entry;
-
-  for (i = 0; i < server->backup->replaced_count; i++) {
-    if (!server->backup->replaced[i]) {
-      server->backup->replaced[i] = r;
-      return;
-    }
-  }
-
-  i = server->backup->replaced_count;
-  server->backup->replaced = silc_realloc(server->backup->replaced,
-                                         sizeof(*server->backup->replaced) *
-                                         (i + 1));
-  server->backup->replaced[i] = r;
-  server->backup->replaced_count++;
-}
-
-/* Checks whether the IP address and port from the `server_id' has been
-   replaced by an backup router. If it has been then this returns TRUE
-   and the bacup router entry to the `server' pointer if non-NULL. Returns
-   FALSE if the router is not replaced by backup router. */
-
-SilcBool silc_server_backup_replaced_get(SilcServer server,
-                                        SilcServerID *server_id,
-                                        SilcServerEntry *server_entry)
-{
-  int i;
-
-  if (!server->backup || !server->backup->replaced)
-    return FALSE;
-
-  for (i = 0; i < server->backup->replaced_count; i++) {
-    if (!server->backup->replaced[i])
-      continue;
-    if (!memcmp(server->backup->replaced[i]->ip.data, server_id->ip.data,
-               sizeof(server_id->ip.data))) {
-      if (server_entry)
-       *server_entry = server->backup->replaced[i]->server;
-      SILC_LOG_DEBUG(("Router %s is replaced by %s",
-                     silc_id_render(server_id, SILC_ID_SERVER),
-                     server->backup->replaced[i]->server->server_name));
-      return TRUE;
-    }
-  }
-
-  SILC_LOG_DEBUG(("Router %s is not replaced by backup router",
-                 silc_id_render(server_id, SILC_ID_SERVER)));
-  return FALSE;
-}
-
-/* Deletes a replaced host by the set `server_entry. */
-
-void silc_server_backup_replaced_del(SilcServer server,
-                                    SilcServerEntry server_entry)
-{
-  int i;
-
-  if (!server->backup || !server->backup->replaced)
-    return;
-
-  for (i = 0; i < server->backup->replaced_count; i++) {
-    if (!server->backup->replaced[i])
-      continue;
-    if (server->backup->replaced[i]->server == server_entry) {
-      silc_free(server->backup->replaced[i]);
-      server->backup->replaced[i] = NULL;
-    }
-  }
-}
-
-/* Broadcast the received packet indicated by `packet' to all of our backup
-   routers. All router wide information is passed using broadcast packets.
-   That is why all backup routers need to get this data too. It is expected
-   that the caller already knows that the `packet' is broadcast packet. */
-
-void silc_server_backup_broadcast(SilcServer server,
-                                 SilcPacketStream sender,
-                                 SilcPacket packet)
-{
-  SilcServerEntry backup;
-  SilcPacketStream sock;
-  int i;
-
-  if (!server->backup || server->server_type != SILC_ROUTER)
-    return;
-
-  SILC_LOG_DEBUG(("Broadcasting received packet to backup routers"));
-
-  for (i = 0; i < server->backup->servers_count; i++) {
-    backup = server->backup->servers[i].server;
-
-    if (!backup || backup->connection == sender ||
-       server->backup->servers[i].local == FALSE)
-      continue;
-    if (server->backup->servers[i].server == server->id_entry)
-      continue;
-
-    sock = backup->connection;
-    silc_server_packet_route(server, sock, packet);
-  }
-}
-
-/* A generic routine to send data to all backup routers. If the `sender'
-   is provided it will indicate the original sender of the packet and the
-   packet won't be resent to that entity. The `data' is the data that will
-   be assembled to packet context before sending. The packet will be
-   encrypted this function. If the `force_send' is TRUE the data is sent
-   immediately and not put to queue. If `local' is TRUE then the packet
-   will be sent only to local backup routers inside the cell. If false the
-   packet can go from one cell to the other. This function has no effect
-   if there are no any backup routers. */
-
-void silc_server_backup_send(SilcServer server,
-                            SilcServerEntry sender,
-                            SilcPacketType type,
-                            SilcPacketFlags flags,
-                            unsigned char *data,
-                            SilcUInt32 data_len,
-                            SilcBool force_send,
-                            SilcBool local)
-{
-  SilcServerEntry backup;
-  SilcPacketStream sock;
-  int i;
-
-  if (!server->backup || server->server_type != SILC_ROUTER)
-    return;
-
-  for (i = 0; i < server->backup->servers_count; i++) {
-    backup = server->backup->servers[i].server;
-    if (!backup || sender == backup)
-      continue;
-    if (local && server->backup->servers[i].local == FALSE)
-      continue;
-    if (server->backup->servers[i].server == server->id_entry)
-      continue;
-
-    sock = backup->connection;
-
-    silc_server_packet_send(server, backup->connection, type, flags,
-                           data, data_len);
-  }
-}
-
-/* Same as silc_server_backup_send but sets a specific Destination ID to
-   the packet. The Destination ID is indicated by the `dst_id' and the
-   ID type `dst_id_type'. For example, packets destined to channels must
-   be sent using this function. */
-
-void silc_server_backup_send_dest(SilcServer server,
-                                 SilcServerEntry sender,
-                                 SilcPacketType type,
-                                 SilcPacketFlags flags,
-                                 void *dst_id,
-                                 SilcIdType dst_id_type,
-                                 unsigned char *data,
-                                 SilcUInt32 data_len,
-                                 SilcBool force_send,
-                                 SilcBool local)
-{
-  SilcServerEntry backup;
-  SilcPacketStream sock;
-  int i;
-
-  if (!server->backup || server->server_type != SILC_ROUTER)
-    return;
-
-  for (i = 0; i < server->backup->servers_count; i++) {
-    backup = server->backup->servers[i].server;
-    if (!backup || sender == backup)
-      continue;
-    if (local && server->backup->servers[i].local == FALSE)
-      continue;
-    if (server->backup->servers[i].server == server->id_entry)
-      continue;
-
-    sock = backup->connection;
-
-    silc_server_packet_send_dest(server, backup->connection, type, flags,
-                                dst_id, dst_id_type, data, data_len);
-  }
-}
-
-/* Send the START_USE indication to remote connection.  If `failure' is
-   TRUE then this sends SILC_PACKET_FAILURE.  Otherwise it sends
-   SILC_PACKET_RESUME_ROUTER. */
-
-void silc_server_backup_send_start_use(SilcServer server,
-                                      SilcPacketStream sock,
-                                      SilcBool failure)
-{
-  unsigned char data[4];
-
-  SILC_LOG_DEBUG(("Sending START_USE (%s)",
-                 failure ? "failure" : "success"));
-
-  if (failure) {
-    SILC_PUT32_MSB(SILC_SERVER_BACKUP_START_USE, data);
-    silc_server_packet_send(server, sock, SILC_PACKET_FAILURE, 0,
-                           data, 4);
-  } else {
-    data[0] = SILC_SERVER_BACKUP_START_USE;
-    data[1] = 0;
-    silc_server_packet_send(server, sock,
-                           SILC_PACKET_RESUME_ROUTER, 0,
-                           data, 2);
-  }
-}
-
-/* Send the REPLACED indication to remote router.  This is send by the
-   primary router (remote router) of the primary router that came back
-   online.  This is not sent by backup router or any other server. */
-
-void silc_server_backup_send_replaced(SilcServer server,
-                                     SilcPacketStream sock)
-{
-  unsigned char data[4];
-
-  SILC_LOG_DEBUG(("Sending REPLACED"));
-
-  data[0] = SILC_SERVER_BACKUP_REPLACED;
-  data[1] = 0;
-  silc_server_packet_send(server, sock,
-                         SILC_PACKET_RESUME_ROUTER, 0,
-                         data, 2);
-}
-
-
-/************************ Backup Resuming Protocol **************************/
-
-/* Timeout callback for protocol */
-
-SILC_TASK_CALLBACK(silc_server_backup_timeout)
-{
-  SilcServerBackupProtocolContext ctx = context;
-  SilcServer server = app_context;
-
-  SILC_LOG_INFO(("Timeout occurred during backup resuming protocol"));
-  ctx->timeout = TRUE;
-  ctx->error = TRUE;
-  silc_schedule_task_add_timeout(server->schedule,
-                                silc_server_protocol_backup_done, context,
-                                0, 0);
-}
-
-/* Callback to start the protocol as responder */
-
-SILC_TASK_CALLBACK(silc_server_backup_responder_start)
-{
-  SilcServerBackupProtocolContext proto_ctx = context;
-  SilcPacketStream sock = proto_ctx->sock;
-  SilcIDListData idata = silc_packet_get_context(sock);
-  SilcServer server = app_context;
-
-  /* If other protocol is executing at the same time, start with timeout. */
-  if (idata->sconn->op) {
-    SILC_LOG_DEBUG(("Other protocol is executing, wait for it to finish"));
-    silc_schedule_task_add_timeout(server->schedule,
-                                  silc_server_backup_responder_start,
-                                  proto_ctx, 2, 0);
-    return;
-  }
-
-  /* Register protocol timeout */
-  silc_schedule_task_add_timeout(server->schedule,
-                                silc_server_backup_timeout,
-                                proto_ctx, 30, 0);
-
-  /* Run the backup resuming protocol */
-  silc_schedule_task_add_timeout(server->schedule,
-                                silc_server_protocol_backup,
-                                proto_ctx, 0, 0);
-}
-
-/* Callback to send START_USE to backup to check whether using backup
-   is ok. */
-
-SILC_TASK_CALLBACK(silc_server_backup_check_status)
-{
-  SilcPacketStream sock = context;
-  SilcServer server = app_context;
-
-  /* Check whether we are still using backup */
-  if (!server->backup_primary)
-    return;
-
-  silc_server_backup_send_start_use(server, sock, FALSE);
-  silc_packet_stream_unref(sock);
-}
-
-typedef struct {
-  SilcServer server;
-  SilcPacketStream sock;
-  SilcPacket packet;
-} *SilcServerBackupPing;
-
-/* PING command reply callback */
-
-void silc_server_backup_ping_reply(void *context, void *reply)
-{
-  SilcServerBackupPing pc = context;
-  SilcServerCommandReplyContext cmdr = reply;
-
-  if (cmdr && !silc_command_get_status(cmdr->payload, NULL, NULL)) {
-    /* Timeout error occurred, the primary is really down. */
-    SilcPacketStream primary = SILC_PRIMARY_ROUTE(pc->server);
-
-    SILC_LOG_DEBUG(("PING timeout, primary is down"));
-
-    if (primary) {
-      silc_server_free_sock_user_data(pc->server, primary, NULL);
-      silc_server_close_connection(pc->server, primary);
-    }
-
-    /* Reprocess the RESUME_ROUTER packet */
-    silc_server_backup_resume_router(pc->server, pc->sock, pc->packet);
-  } else {
-    /* The primary is not down, refuse to serve the server as primary */
-    SILC_LOG_DEBUG(("PING received, primary is up"));
-    silc_server_backup_send_start_use(pc->server, pc->sock, TRUE);
-    silc_packet_free(pc->packet);
-  }
-
-  silc_packet_stream_unref(pc->sock);
-  silc_free(pc);
-}
-
-/* Processes incoming RESUME_ROUTER packet. This can give the packet
-   for processing to the protocol handler or allocate new protocol if
-   start command is received. */
-
-void silc_server_backup_resume_router(SilcServer server,
-                                     SilcPacketStream sock,
-                                     SilcPacket packet)
-{
-  SilcIDListData idata = silc_packet_get_context(sock);
-  SilcServerEntry router = (SilcServerEntry)idata;
-  SilcUInt8 type, session;
-  SilcServerBackupProtocolContext ctx;
-  int i, ret;
-
-  SILC_LOG_DEBUG(("Received RESUME_ROUTER packet"));
-
-  if (idata->conn_type == SILC_CONN_CLIENT ||
-      idata->conn_type == SILC_CONN_UNKNOWN) {
-    SILC_LOG_DEBUG(("Bad packet received"));
-    silc_packet_free(packet);
-    return;
-  }
-
-  ret = silc_buffer_unformat(&packet->buffer,
-                            SILC_STR_UI_CHAR(&type),
-                            SILC_STR_UI_CHAR(&session),
-                            SILC_STR_END);
-  if (ret < 0) {
-    SILC_LOG_ERROR(("Malformed resume router packet received"));
-    silc_packet_free(packet);
-    return;
-  }
-
-  /* Check whether this packet is used to tell us that server will start
-     using us as primary router. */
-  if (type == SILC_SERVER_BACKUP_START_USE) {
-    SilcBuffer idp;
-    SilcServerBackupPing pc;
-
-    /* If we are normal server then backup router has sent us back
-       this reply and we use the backup as primary router now. */
-    if (server->server_type == SILC_SERVER) {
-      /* Nothing to do here actually, since we have switched already. */
-      SILC_LOG_DEBUG(("Received successful START_USE from backup router"));
-      silc_packet_free(packet);
-      return;
-    }
-
-    /* Backup router following. */
-
-    /* If we are marked as router then the primary is down and we send
-       success START_USE back to the server. */
-    if (server->server_type == SILC_ROUTER) {
-      SILC_LOG_DEBUG(("Sending success START_USE back"));
-      silc_server_backup_send_start_use(server, sock, FALSE);
-      silc_packet_free(packet);
-      return;
-    }
-
-    /* We have just lost primary, send success START_USE back */
-    if (server->standalone) {
-      SILC_LOG_DEBUG(("We are stanalone, sending success START_USE back"));
-      silc_server_backup_send_start_use(server, sock, FALSE);
-      silc_packet_free(packet);
-      return;
-    }
-
-    /* We are backup router. This server claims that our primary is down.
-       We will check this ourselves by sending PING command to the primary. */
-    SILC_LOG_DEBUG(("Sending PING to detect status of primary router"));
-    idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
-    silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
-                            SILC_COMMAND_PING, ++server->cmd_ident, 1,
-                            1, idp->data, silc_buffer_len(idp));
-    silc_buffer_free(idp);
-
-    /* Reprocess this packet after received reply from router */
-    pc = silc_calloc(1, sizeof(*pc));
-    pc->server = server;
-    pc->sock = sock;
-    pc->packet = packet;
-    silc_packet_stream_ref(sock);
-    silc_server_command_pending_timed(server, SILC_COMMAND_PING,
-                                     server->cmd_ident,
-                                     silc_server_backup_ping_reply, pc, 15);
-    return;
-  }
-
-  /* Start the resuming protocol if requested. */
-  if (type == SILC_SERVER_BACKUP_START) {
-    /* We have received a start for resuming protocol.  We are either
-       primary router that came back online or normal server. */
-    SilcServerBackupProtocolContext proto_ctx;
-
-    /* If backup had closed the connection earlier we won't allow resuming
-       since we (primary router) have never gone away. */
-    if (server->server_type == SILC_ROUTER && !server->backup_router &&
-       server->backup_closed) {
-      unsigned char data[4];
-      SILC_LOG_DEBUG(("Backup resuming not allowed since we are still "
-                     "primary router"));
-      SILC_LOG_INFO(("Backup resuming not allowed since we are still "
-                    "primary router"));
-      SILC_PUT32_MSB(SILC_SERVER_BACKUP_START, data);
-      silc_server_packet_send(server, sock, SILC_PACKET_FAILURE, 0,
-                             data, 4);
-      server->backup_closed = FALSE;
-      silc_packet_free(packet);
-      return;
-    }
-
-    proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
-    proto_ctx->server = server;
-    proto_ctx->sock = sock;
-    proto_ctx->responder = TRUE;
-    proto_ctx->type = type;
-    proto_ctx->session = session;
-    proto_ctx->start = time(0);
-    silc_packet_stream_ref(sock);
-    router->backup = TRUE;
-    router->backup_proto = proto_ctx;
-
-    SILC_LOG_DEBUG(("Starting backup resuming protocol as responder"));
-    SILC_LOG_INFO(("Starting backup resuming protocol"));
-
-    /* Start protocol immediately */
-    silc_schedule_task_add_timeout(server->schedule,
-                                  silc_server_backup_responder_start,
-                                  proto_ctx, 0, 1);
-    return;
-  }
-
-  /* If we are router and the packet is coming from our primary router
-     then it means we have been replaced by an backup router in our cell. */
-  if (type == SILC_SERVER_BACKUP_REPLACED &&
-      server->server_type == SILC_ROUTER &&
-      idata->conn_type == SILC_CONN_ROUTER &&
-      SILC_PRIMARY_ROUTE(server) == sock) {
-    /* We have been replaced by an backup router in our cell. We must
-       mark our primary router connection disabled since we are not allowed
-       to use it at this moment. */
-    SILC_LOG_INFO(("We are replaced by an backup router in this cell, will "
-                  "wait until backup resuming protocol is executed"));
-    idata->status |= SILC_IDLIST_STATUS_DISABLED;
-    silc_packet_free(packet);
-    return;
-  }
-
-  /* Activate the shared protocol context for this socket connection
-     if necessary */
-  if (type == SILC_SERVER_BACKUP_RESUMED &&
-      idata->conn_type == SILC_CONN_ROUTER && !router->backup &&
-      idata->status & SILC_IDLIST_STATUS_DISABLED) {
-    SilcServerEntry backup_router;
-
-    if (silc_server_backup_replaced_get(server, router->id, &backup_router)) {
-      ctx = backup_router->backup_proto;
-      if (ctx->sock)
-       silc_packet_stream_unref(ctx->sock);
-      router->backup = TRUE;
-      router->backup_proto = ctx;
-      ctx->sock = sock;
-      silc_packet_stream_ref(sock);
-    }
-  }
-
-  /* Call the resuming protocol if the protocol is active. */
-  if (router->backup) {
-    ctx = router->backup_proto;
-    ctx->type = type;
-
-    for (i = 0; i < ctx->sessions_count; i++) {
-      if (session == ctx->sessions[i].session) {
-       ctx->session = session;
-       silc_schedule_task_add_timeout(server->schedule,
-                                      silc_server_protocol_backup,
-                                      ctx, 0, 1);
-       silc_packet_free(packet);
-       return;
-      }
-    }
-
-    /* If RESUMED received the session ID is zero, execute the protocol. */
-    if (type == SILC_SERVER_BACKUP_RESUMED) {
-      silc_schedule_task_add_timeout(server->schedule,
-                                    silc_server_protocol_backup,
-                                    ctx, 0, 1);
-      silc_packet_free(packet);
-      return;
-    }
-
-    SILC_LOG_ERROR(("Unknown backup resuming session %d", session));
-    silc_packet_free(packet);
-    return;
-  }
-
-  silc_packet_free(packet);
-}
-
-/* Task that is called after backup router has connected back to
-   primary router and we are starting the resuming protocol */
-
-SILC_TASK_CALLBACK(silc_server_backup_connected_later)
-{
-  SilcServerBackupProtocolContext proto_ctx =
-    (SilcServerBackupProtocolContext)context;
-  SilcServer server = proto_ctx->server;
-
-  SILC_LOG_DEBUG(("Starting backup resuming protocol as initiator"));
-  SILC_LOG_INFO(("Starting backup resuming protocol"));
-
-  /* Register protocol timeout */
-  silc_schedule_task_add_timeout(server->schedule,
-                                silc_server_backup_timeout,
-                                proto_ctx, 30, 0);
-
-  /* Run the backup resuming protocol */
-  silc_schedule_task_add_timeout(server->schedule,
-                                silc_server_protocol_backup,
-                                proto_ctx, 0, 0);
-}
-
-SILC_TASK_CALLBACK(silc_server_backup_connected_again)
-{
-  SilcServer server = app_context;
-  SilcServerConfigRouter *primary;
-
-  primary = silc_server_config_get_primary_router(server);
-  if (primary) {
-    if (!silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
-                                        primary->host, primary->port))
-      silc_server_create_connection(server, FALSE, FALSE,
-                                   primary->host, primary->port,
-                                   silc_server_backup_connected,
-                                   context);
-  }
-}
-
-/* Called when we've established connection back to our primary router
-   when we've acting as backup router and have replaced the primary router
-   in the cell. This function will start the backup resuming protocol. */
-
-void silc_server_backup_connected(SilcServer server,
-                                 SilcServerEntry server_entry,
-                                 void *context)
-{
-  SilcServerBackupProtocolContext proto_ctx;
-  SilcPacketStream sock;
-
-  if (!server_entry) {
-    /* Try again */
-    silc_schedule_task_add_timeout(server->schedule,
-                                  silc_server_backup_connected_again,
-                                  context, 5, 0);
-    return;
-  }
-
-  sock = server_entry->connection;
-  proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
-  proto_ctx->server = server;
-  proto_ctx->sock = sock;
-  proto_ctx->responder = FALSE;
-  proto_ctx->type = SILC_SERVER_BACKUP_START;
-  proto_ctx->start = time(0);
-  silc_packet_stream_ref(sock);
-
-  /* Start through scheduler */
-  silc_schedule_task_add_timeout(server->schedule,
-                                silc_server_backup_connected_later,
-                                proto_ctx, 0, 1);
-}
-
-SILC_TASK_CALLBACK(silc_server_backup_connect_primary_again)
-{
-  SilcServer server = app_context;
-  SilcServerConfigRouter *primary;
-
-  primary = silc_server_config_get_primary_router(server);
-  if (primary) {
-    if (!silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
-                                        primary->host, primary->port))
-      silc_server_create_connection(server, FALSE, FALSE,
-                                   primary->host, primary->port,
-                                   silc_server_backup_connect_primary,
-                                   context);
-  }
-}
-
-/* Called when normal server has connected to its primary router after
-   backup router has sent the START packet in reusming protocol. We will
-   move the protocol context from the backup router connection to the
-   primary router. */
-
-static void silc_server_backup_connect_primary(SilcServer server,
-                                              SilcServerEntry server_entry,
-                                              void *context)
-{
-  SilcPacketStream backup_router = context;
-  SilcIDListData idata = silc_packet_get_context(backup_router);
-  SilcServerEntry router = (SilcServerEntry)idata;
-  SilcServerBackupProtocolContext ctx;
-  SilcPacketStream sock;
-  unsigned char data[2];
-
-  if (!server_entry) {
-    /* Try again */
-    silc_schedule_task_add_timeout(server->schedule,
-                                  silc_server_backup_connect_primary_again,
-                                  context, 0, 0);
-    return;
-  }
-
-  if (!router->backup || !server_entry->connection) {
-    silc_packet_stream_unref(backup_router);
-    return;
-  }
-
-  ctx = router->backup_proto;
-  sock = server_entry->connection;
-  idata = (SilcIDListData)server_entry;
-
-  SILC_LOG_DEBUG(("Sending CONNECTED packet (session %d)", ctx->session));
-  SILC_LOG_INFO(("Sending CONNECTED (session %d) to backup router",
-               ctx->session));
-
-  /* Send the CONNECTED packet back to the backup router. */
-  data[0] = SILC_SERVER_BACKUP_CONNECTED;
-  data[1] = ctx->session;
-  silc_server_packet_send(server, backup_router,
-                         SILC_PACKET_RESUME_ROUTER, 0, data, 2);
-
-  /* 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
-     anymore. */
-  if (ctx->sock)
-    silc_packet_stream_unref(ctx->sock);
-  ctx->sock = sock;
-  silc_packet_stream_ref(sock);
-  server_entry->backup = TRUE;
-  server_entry->backup_proto = ctx;
-  router->backup = FALSE;
-  router->backup_proto = NULL;
-
-  /* Unref */
-  silc_packet_stream_unref(backup_router);
-}
-
-/* Timeout callback used by the backup router to send the ENDING packet
-   to primary router to indicate that it can now resume as being primary
-   router. All CONNECTED packets has been received when we reach this. */
-
-SILC_TASK_CALLBACK(silc_server_backup_send_resumed)
-{
-  SilcServerBackupProtocolContext ctx = context;
-  SilcServer server = ctx->server;
-  unsigned char data[2];
-  int i;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  for (i = 0; i < ctx->sessions_count; i++)
-    if (ctx->sessions[i].server_entry == silc_packet_get_context(ctx->sock))
-      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. */
-  data[0] = SILC_SERVER_BACKUP_ENDING;
-  data[1] = ctx->session;
-  silc_server_packet_send(server, ctx->sock, SILC_PACKET_RESUME_ROUTER, 0,
-                         data, sizeof(data));
-
-  /* The protocol will go to END state. */
-  ctx->state = 250;
-}
-
-/* Backup resuming protocol. This protocol is executed when the primary
-   router wants to resume its position as being primary router. */
-
-SILC_TASK_CALLBACK(silc_server_protocol_backup)
-{
-  SilcServerBackupProtocolContext ctx = context;
-  SilcServer server = ctx->server;
-  SilcServerEntry server_entry = NULL;
-  SilcPacketStream sock = NULL;
-  unsigned char data[2];
-  SilcDList list;
-  int i;
-
-  if (!ctx->state)
-    ctx->state = 1;
-
-  switch(ctx->state) {
-  case 1:
-    if (ctx->responder == FALSE) {
-      /*
-       * Initiator (backup router)
-       */
-
-      /* Send the START packet to primary router and normal servers. The
-        packet will indicate to the primary router that it has been replaced
-        by us.  For normal servers it means that we will be resigning as
-        being primary router shortly. */
-      list = silc_packet_engine_get_streams(server->packet_engine);
-      if (!list)
-       return;
-
-      silc_dlist_start(list);
-      while ((sock = silc_dlist_get(list))) {
-       server_entry = silc_packet_get_context(sock);
-
-       if (!server_entry || server_entry == server->id_entry ||
-           (server_entry->data.conn_type != SILC_CONN_ROUTER &&
-            server_entry->data.conn_type != SILC_CONN_SERVER))
-         continue;
-
-       if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
-         continue;
-
-       ctx->sessions = silc_realloc(ctx->sessions,
-                                    sizeof(*ctx->sessions) *
-                                    (ctx->sessions_count + 1));
-       ctx->sessions[ctx->sessions_count].session = ctx->sessions_count;
-       ctx->sessions[ctx->sessions_count].connected = FALSE;
-       ctx->sessions[ctx->sessions_count].server_entry = server_entry;
-
-       SILC_LOG_DEBUG(("Sending START to %s (session %d)",
-                       server_entry->server_name, ctx->sessions_count));
-       SILC_LOG_INFO(("Expecting CONNECTED from %s (session %d)",
-                      server_entry->server_name, ctx->sessions_count));
-
-       /* This connection is performing this protocol too now */
-       server_entry->backup = TRUE;
-       server_entry->backup_proto = ctx;
-
-       data[0] = SILC_SERVER_BACKUP_START;
-       data[1] = ctx->sessions_count;
-       silc_server_packet_send(server, sock, SILC_PACKET_RESUME_ROUTER, 0,
-                               data, sizeof(data));
-       ctx->sessions_count++;
-      }
-      silc_packet_engine_free_streams_list(list);
-
-      /* Announce data to the new primary to be. */
-      silc_server_announce_servers(server, TRUE, 0, ctx->sock);
-      silc_server_announce_clients(server, 0, ctx->sock);
-      silc_server_announce_channels(server, 0, ctx->sock);
-
-      ctx->state++;
-
-    } else {
-      /*
-       * Responder (all servers and routers)
-       */
-      SilcServerConfigRouter *primary;
-
-      /* We should have received START packet */
-      if (ctx->type != SILC_SERVER_BACKUP_START) {
-       SILC_LOG_ERROR(("Bad resume router packet START %d", ctx->type));
-       break;
-      }
-
-      /* 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);
-      if (primary && server->backup_primary &&
-         !silc_server_num_sockets_by_remote(server,
-                                            silc_net_is_ip(primary->host) ?
-                                            primary->host : NULL,
-                                            silc_net_is_ip(primary->host) ?
-                                            NULL : primary->host,
-                                            primary->port,
-                                            SILC_CONN_ROUTER)) {
-       SILC_LOG_DEBUG(("Received START (session %d), reconnect to router",
-                       ctx->session));
-       silc_packet_stream_ref(ctx->sock);
-       silc_server_create_connection(server, FALSE, FALSE,
-                                     primary->host, primary->port,
-                                     silc_server_backup_connect_primary,
-                                     ctx->sock);
-      } else {
-       /* Nowhere to connect just return the CONNECTED packet */
-       SILC_LOG_DEBUG(("Received START (session %d), send CONNECTED back",
-                       ctx->session));
-       SILC_LOG_INFO(("Sending CONNECTED (session %d) to backup router",
-                     ctx->session));
-
-       /* Send the CONNECTED packet back to the backup router. */
-       data[0] = SILC_SERVER_BACKUP_CONNECTED;
-       data[1] = ctx->session;
-       silc_server_packet_send(server, ctx->sock,
-                               SILC_PACKET_RESUME_ROUTER, 0,
-                               data, sizeof(data));
-      }
-
-      /* Add this resuming session */
-      ctx->sessions = silc_realloc(ctx->sessions,
-                                  sizeof(*ctx->sessions) *
-                                  (ctx->sessions_count + 1));
-      ctx->sessions[ctx->sessions_count].session = ctx->session;
-      ctx->sessions_count++;
-
-      /* Normal server goes directly to the END state. */
-      if (server->server_type == SILC_ROUTER &&
-         (!server->router ||
-          server->router->data.status & SILC_IDLIST_STATUS_DISABLED))
-       ctx->state++;
-      else
-       ctx->state = 250;
-    }
-    break;
-
-  case 2:
-    if (ctx->responder == FALSE) {
-      /*
-       * Initiator (backup router)
-       */
-
-      /* We should have received CONNECTED packet */
-      if (ctx->type != SILC_SERVER_BACKUP_CONNECTED) {
-       SILC_LOG_ERROR(("Bad resume router packet CONNECTED %d", ctx->type));
-       break;
-      }
-
-      for (i = 0; i < ctx->sessions_count; i++) {
-       if (ctx->sessions[i].session == ctx->session) {
-         ctx->sessions[i].connected = TRUE;
-         SILC_LOG_INFO(("Received CONNECTED from %s (session %d)",
-                        ctx->sessions[i].server_entry->server_name,
-                        ctx->session));
-         SILC_LOG_DEBUG(("Received CONNECTED (session %d)", ctx->session));
-         break;
-       }
-      }
-
-      /* See if all returned CONNECTED, if not, then continue waiting. */
-      for (i = 0; i < ctx->sessions_count; i++) {
-       if (!ctx->sessions[i].connected)
-         return;
-      }
-
-      SILC_LOG_INFO(("All sessions have returned CONNECTED packets, "
-                    "continuing"));
-      SILC_LOG_DEBUG(("Sending ENDING packet to primary router"));
-
-      /* The ENDING is sent with timeout, and then we continue to the
-        END state in the protocol. */
-      silc_schedule_task_add_timeout(server->schedule,
-                                    silc_server_backup_send_resumed,
-                                    ctx, 1, 0);
-      return;
-
-    } else {
-      /*
-       * Responder (primary router)
-       */
-
-      /* We should have been received ENDING packet */
-      if (ctx->type != SILC_SERVER_BACKUP_ENDING) {
-       SILC_LOG_ERROR(("Bad resume router packet ENDING %d", ctx->type));
-       break;
-      }
-
-      SILC_LOG_DEBUG(("Received ENDING packet, we are going to resume now"));
-
-      /* Switch announced informations to our primary router of using the
-        backup router. */
-      silc_server_local_servers_toggle_enabled(server, TRUE);
-      silc_server_update_servers_by_server(server,
-                                          silc_packet_get_context(ctx->sock),
-                                          server->router);
-      silc_server_update_clients_by_server(server,
-                                          silc_packet_get_context(ctx->sock),
-                                          server->router, TRUE);
-
-      /* We as primary router now must send RESUMED packets to all servers
-        and routers so that they know we are back.   For backup router we
-        send the packet last so that we give the backup as much time as
-        possible to deal with message routing at this critical moment. */
-      list = silc_packet_engine_get_streams(server->packet_engine);
-      if (!list)
-       return;
-
-      silc_dlist_start(list);
-      while ((sock = silc_dlist_get(list))) {
-       server_entry = silc_packet_get_context(sock);
-
-       if (!server_entry || server_entry == server->id_entry ||
-           (server_entry->data.conn_type != SILC_CONN_ROUTER &&
-            server_entry->data.conn_type != SILC_CONN_SERVER))
-         continue;
-
-       /* Send to backup last */
-       if (sock == ctx->sock)
-         continue;
-
-       server_entry = silc_packet_get_context(sock);
-       server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
-
-       SILC_LOG_DEBUG(("Sending RESUMED to %s", server_entry->server_name));
-       SILC_LOG_INFO(("Sending RESUMED to %s", server_entry->server_name));
-
-       /* This connection is performing this protocol too now */
-       server_entry->backup = TRUE;
-       server_entry->backup_proto = ctx;
-
-       data[0] = SILC_SERVER_BACKUP_RESUMED;
-       data[1] = 0;
-       silc_server_packet_send(server, sock, SILC_PACKET_RESUME_ROUTER, 0,
-                               data, sizeof(data));
-      }
-
-      /* Now send the same packet to backup */
-      if (sock != ctx->sock) {
-       sleep(1);
-       sock = ctx->sock;
-       server_entry = silc_packet_get_context(sock);
-       server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
-
-       SILC_LOG_DEBUG(("Sending RESUMED to %s", server_entry->server_name));
-       SILC_LOG_INFO(("Sending RESUMED to %s", server_entry->server_name));
-
-       /* This connection is performing this protocol too now */
-       server_entry->backup = TRUE;
-       server_entry->backup_proto = ctx;
-
-       data[0] = SILC_SERVER_BACKUP_RESUMED;
-       data[1] = 0;
-       silc_server_packet_send(server, sock, SILC_PACKET_RESUME_ROUTER, 0,
-                               data, sizeof(data));
-      }
-      silc_packet_engine_free_streams_list(list);
-
-      /* We are now resumed and are back as primary router in the cell. */
-      SILC_LOG_INFO(("We are now the primary router of our cell again"));
-      server->wait_backup = FALSE;
-
-      /* Announce WATCH list a little later */
-      silc_packet_stream_ref(ctx->sock);
-      silc_schedule_task_add_timeout(server->schedule,
-                                    silc_server_backup_announce_watches,
-                                    ctx->sock, 4, 0);
-
-      /* For us this is the end of this protocol. */
-      silc_schedule_task_add_timeout(server->schedule,
-                                    silc_server_protocol_backup_done,
-                                    ctx, 0, 1);
-    }
-    break;
-
-  case 250:
-    {
-      /*
-       * Responder (backup router, servers, and remote router)
-       */
-      SilcServerEntry router, backup_router;
-
-      /* We should have been received RESUMED from our primary router. */
-      if (ctx->type != SILC_SERVER_BACKUP_RESUMED) {
-       SILC_LOG_ERROR(("Bad resume router packet RESUMED %d", ctx->type));
-       break;
-      }
-
-      SILC_LOG_INFO(("Received RESUMED from new primary router"));
-
-      /* If we are the backup router, mark that we are no longer primary
-        but are back to backup router status. */
-      if (server->backup_router)
-       server->server_type = SILC_BACKUP_ROUTER;
-
-      /* We have now new primary router. All traffic goes there from now on. */
-      router = silc_packet_get_context(ctx->sock);
-      if (silc_server_backup_replaced_get(server, router->id,
-                                         &backup_router)) {
-
-       if (backup_router == server->router) {
-         /* We have new primary router now */
-         server->id_entry->router = router;
-         server->router = router;
-         SILC_LOG_INFO(("Switching back to primary router %s",
-                        server->router->server_name));
-       } else {
-         /* We are connected to new primary and now continue using it */
-         SILC_LOG_INFO(("Resuming the use of primary router %s",
-                        router->server_name));
-       }
-       server->backup_primary = FALSE;
-       sock = router->connection;
-
-       /* Update the client entries of the backup router to the new
-          router */
-       silc_server_local_servers_toggle_enabled(server, FALSE);
-       router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
-       silc_server_update_servers_by_server(server, backup_router, router);
-       silc_server_update_clients_by_server(
-                                  server, NULL, router,
-                                  server->server_type == SILC_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);
-      }
-
-      /* Send notify about primary router going down to local operators */
-      SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
-                            SILC_NOTIFY_TYPE_NONE,
-                            ("%s resumed the use of primary router %s",
-                             server->server_name,
-                             server->router->server_name));
-
-      /* Protocol has ended, call the final callback */
-      silc_schedule_task_add_timeout(server->schedule,
-                                    silc_server_protocol_backup_done,
-                                    ctx, 0, 1);
-    }
-    break;
-
-  case 251:
-    /* Protocol has ended, call the final callback */
-    silc_schedule_task_add_timeout(server->schedule,
-                                  silc_server_protocol_backup_done,
-                                  ctx, 0, 1);
-    break;
-
-  case 252:
-    /* Protocol has ended, call the final callback */
-    SILC_LOG_ERROR(("Error during backup resume: received Failure"));
-    ctx->received_failure = TRUE;
-    silc_schedule_task_add_timeout(server->schedule,
-                                  silc_server_protocol_backup_done,
-                                  ctx, 0, 1);
-    break;
-
-  default:
-    break;
-  }
-}
-
-/* Final resuming protocol completion callback */
-
-SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
-{
-  SilcServerBackupProtocolContext ctx = context;
-  SilcServer server = ctx->server;
-  SilcDList list;
-  SilcServerEntry server_entry;
-  SilcPacketStream sock;
-  SilcBool error;
-
-  silc_schedule_task_del_by_context(server->schedule, ctx);
-
-  error = ctx->error;
-
-  if (error)
-    SILC_LOG_ERROR(("Error occurred during backup router resuming protcool"));
-
-  if (server->server_shutdown)
-    return;
-
-  /* Remove this protocol from all server entries that has it */
-  list = silc_packet_engine_get_streams(server->packet_engine);
-  if (!list)
-    return;
-
-  silc_dlist_start(list);
-  while ((sock = silc_dlist_get(list))) {
-    server_entry = silc_packet_get_context(sock);
-    if (!server_entry)
-      continue;
-
-    if (server_entry->data.conn_type != SILC_CONN_ROUTER &&
-       server_entry->data.conn_type != SILC_CONN_SERVER)
-      continue;
-
-    if (server_entry->backup_proto == ctx) {
-      if (error) {
-
-       if (server->server_type == SILC_SERVER &&
-           server_entry->server_type == SILC_ROUTER)
-         continue;
-
-       /* Backup router */
-       if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) {
-         if (ctx->sock == sock) {
-           silc_packet_stream_unref(sock);
-           ctx->sock = NULL;
-         }
-
-         /* If failed after 10 attempts, it won't work, give up */
-         if (ctx->initiator_restart > 10)
-           ctx->received_failure = TRUE;
-
-         if (!ctx->received_failure) {
-           /* Protocol error, probably timeout. Just restart the protocol. */
-           SilcServerBackupProtocolContext proto_ctx;
-
-           /* Restart the protocol. */
-           proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
-           proto_ctx->server = server;
-           proto_ctx->sock = sock;
-           proto_ctx->responder = FALSE;
-           proto_ctx->type = SILC_SERVER_BACKUP_START;
-           proto_ctx->start = time(0);
-           proto_ctx->initiator_restart = ctx->initiator_restart + 1;
-           silc_packet_stream_ref(sock);
-
-           /* Start through scheduler */
-           silc_schedule_task_add_timeout(server->schedule,
-                                          silc_server_backup_connected_later,
-                                          proto_ctx, 5, 0);
-         } else {
-           /* If failure was received, switch back to normal backup router.
-              For some reason primary wouldn't accept that we were supposed
-              to perfom resuming protocol. */
-           server->server_type = SILC_BACKUP_ROUTER;
-           silc_server_local_servers_toggle_enabled(server, FALSE);
-           server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
-           silc_server_update_servers_by_server(server, server->id_entry,
-                                                silc_packet_get_context(sock));
-           silc_server_update_clients_by_server(server, NULL,
-                                                silc_packet_get_context(sock),
-                                                TRUE);
-
-           /* Announce our clients and channels to the router */
-           silc_server_announce_clients(server, 0, sock);
-           silc_server_announce_channels(server, 0, sock);
-
-           /* Announce WATCH list a little later */
-           silc_packet_stream_ref(sock);
-           silc_schedule_task_add_timeout(server->schedule,
-                                          silc_server_backup_announce_watches,
-                                          sock, 5, 0);
-         }
-
-         continue;
-       }
-      }
-
-      server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
-    }
-  }
-  silc_packet_engine_free_streams_list(list);
-
-  if (!error) {
-    SILC_LOG_INFO(("Backup resuming protocol ended successfully"));
-
-    if (ctx->type == SILC_SERVER_BACKUP_RESUMED && server->router) {
-      /* Announce all of our information to the router. */
-      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);
-
-      /* Announce WATCH list a little later */
-      silc_packet_stream_ref(server->router->connection);
-      silc_schedule_task_add_timeout(server->schedule,
-                                    silc_server_backup_announce_watches,
-                                    server->router->connection, 4, 0);
-    }
-  } else {
-    /* Error */
-
-    if (server->server_type == SILC_SERVER) {
-      /* If we are still using backup router Send confirmation to backup
-        that using it is still ok and continue sending traffic there.
-        The backup will reply with error if it's not ok. */
-      if (server->router && server->backup_primary) {
-       /* Send START_USE just in case using backup wouldn't be ok. */
-       silc_server_backup_send_start_use(server, server->router->connection,
-                                         FALSE);
-
-       /* Check couple of times same START_USE just in case. */
-       silc_packet_stream_ref(server->router->connection);
-       silc_schedule_task_add_timeout(server->schedule,
-                                      silc_server_backup_check_status,
-                                      server->router->connection,
-                                      5, 1);
-       silc_packet_stream_ref(server->router->connection);
-       silc_schedule_task_add_timeout(server->schedule,
-                                      silc_server_backup_check_status,
-                                      server->router->connection,
-                                      20, 1);
-       silc_packet_stream_ref(server->router->connection);
-       silc_schedule_task_add_timeout(server->schedule,
-                                      silc_server_backup_check_status,
-                                      server->router->connection,
-                                      60, 1);
-      }
-    }
-  }
-
-  if (ctx->sock) {
-    SilcServerEntry r = silc_packet_get_context(ctx->sock);
-    if (r) {
-      r->backup = FALSE;
-      r->backup_proto = NULL;
-    }
-    silc_packet_stream_unref(ctx->sock);
-  }
-  silc_free(ctx->sessions);
-  silc_free(ctx);
-}
-
-SILC_TASK_CALLBACK(silc_server_backup_announce_watches)
-{
-  SilcPacketStream sock = context;
-  SilcServer server = app_context;
-  if (silc_packet_stream_is_valid(sock))
-    silc_server_announce_watches(server, sock);
-  silc_packet_stream_unref(sock);
-}