Added preliminary backup router support for standalone routers.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 23 Jun 2002 19:18:50 +0000 (19:18 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 23 Jun 2002 19:18:50 +0000 (19:18 +0000)
CHANGES
TODO
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/server_backup.c
apps/silcd/server_util.c
apps/silcd/server_util.h
doc/draft-riikonen-silc-spec-06.nroff
lib/silcutil/silcutil.c

diff --git a/CHANGES b/CHANGES
index b2f1792419ad4c337f9df1d932f26b96a9ba842e..837f2525820846c0ee77abcd3088f0c7b1808271 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,26 @@ Sun Jun 23 17:32:31 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
          and on some it's not.  Fallback encoding is used instead.
          Affected file lib/silcutil/silcstrutil.c.
 
+       * Fixed statistics updating for incoming server connection
+         which could cause problems when re-connecting.  Affected
+         file silcd/server.c.
+
+       * Preliminary backup router support for standalone router
+         added.  Affected files in silcd/.
+
+       * Mark server connections in backup router disabled before
+         and after backup protocol.  Affected file is
+         silcd/server_backup.c.
+
+       * Added support for reconnecting to remote server connection
+         even if the protocol fails, and if the configuration wants
+         us to keep trying to connect anyway.
+
+         Server connection is not allowed to backup router if
+         backup router does not have connection to primary router yet.
+
+         Affected file is silcd/server.c.
+
 Sat Jun 22 21:34:59 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Added silc_client_udpate_server function to update changed
diff --git a/TODO b/TODO
index 6748473e9cb70694fde6aef779484e508351baa4..85336542a5fc5c94ede7ff05cb21da02f35e0650 100644 (file)
--- a/TODO
+++ b/TODO
@@ -25,8 +25,19 @@ TODO/bugs In SILC Server
 
  o Backup router related issues (Fix this to 0.9.x):
 
-       o Channel user mode changes are notified unnecessarely when
-         switching to backup router on router crash.
+       o Complete backup router support with standalone router
+
+       o Make the backup router work even if not all servers in the
+         cell use it.  When primary goes down, also those that are
+         not using it (are not connected locally) are signoffed.
+
+       o Configure use of backup router on normal server using HUP.
+
+       o Configure use of backup router on router using HUP.
+
+       o Rewrite SILC_LOG_DEBUG's in silcd/server_backup.c.
+
+       o Testing
 
  o Add a timeout to handling incoming JOIN commands.  It should be 
    enforced that JOIN command is executed only once in a second or two
index 95486d8f61832a0ccc7b447806fa789847729785..a9f3f267f9300271910401ba816adc04f05c9224 100644 (file)
@@ -218,10 +218,17 @@ void silc_server_notify(SilcServer server,
     chl->client = client;
     chl->channel = channel;
 
-    /* If this is the first one on the channel then it is the founder of
-       the channel. */
-    if (!silc_hash_table_count(channel->user_list))
-      chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
+    if (server->server_type != SILC_ROUTER ||
+       sock->type == SILC_SOCKET_TYPE_ROUTER) {
+      /* If this is the first one on the channel then it is the founder of
+        the channel. This is done on normal server and on router if this
+        notify is coming from router */
+      if (!silc_hash_table_count(channel->user_list)) {
+       SILC_LOG_DEBUG(("Client %s is founder on channel",
+                       silc_id_render(chl->client->id, SILC_ID_CLIENT)));
+       chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
+      }
+    }
 
     silc_hash_table_add(channel->user_list, client, chl);
     silc_hash_table_add(client->channels, channel, chl);
@@ -915,17 +922,17 @@ void silc_server_notify(SilcServer server,
           is set on the channel now check whether this is the client that
           originally set the mode. */
 
-       /* Get public key that must be present in notify */
-       tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
-       if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
-                                                &founder_key)) {
-         chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
-         silc_server_force_cumode_change(server, sock, channel, chl, mode);
-         notify_sent = TRUE;
-         break;
-       }
-
        if (channel->founder_key) {
+         /* Get public key that must be present in notify */
+         tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
+         if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
+                                                  &founder_key)) {
+           chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+           silc_server_force_cumode_change(server, sock, channel, chl, mode);
+           notify_sent = TRUE;
+           break;
+         }
+
          /* Now match the public key we have cached and public key sent.
             They must match. */
          if (client && client->data.public_key && 
@@ -1287,9 +1294,14 @@ void silc_server_notify(SilcServer server,
     }
     silc_free(server_id);
 
+    /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
+    if (SILC_IS_LOCAL(server_entry))
+      break;
+
     /* Free all client entries that this server owns as they will
        become invalid now as well. */
     silc_server_remove_clients_by_server(server, server_entry, TRUE);
+    silc_server_backup_del(server, server_entry);
 
     /* Remove the server entry */
     silc_idlist_del_server(local ? server->local_list :
@@ -2484,6 +2496,12 @@ SilcServerEntry silc_server_new_server(SilcServer server,
       silc_server_announce_clients(server, 0, sock);
       silc_server_announce_channels(server, 0, sock);
     }
+
+    /* By default the servers connected to backup router are disabled
+       until backup router has become the primary */
+    if (server->server_type == SILC_BACKUP_ROUTER &&
+       sock->type == SILC_SOCKET_TYPE_SERVER)
+      idata->status |= SILC_IDLIST_STATUS_DISABLED;
   }
 
   return new_server;
index b622ed877185d31d0eb2eb623ad63222c8c66ab9..fb135c4cfc66765513e938bd0d7894ef65837298 100644 (file)
@@ -892,14 +892,23 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
       silc_ske_free(ctx->ske);
     silc_free(ctx->dest_id);
     silc_free(ctx);
-    silc_server_config_unref(&sconn->conn);
-    silc_free(sconn->remote_host);
-    silc_free(sconn->backup_replace_ip);
-    silc_free(sconn);
     silc_schedule_task_del_by_callback(server->schedule,
                                       silc_server_failure_callback);
     silc_server_disconnect_remote(server, sock, 
                                  SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
+
+    /* Try reconnecting if configuration wants it */
+    if (!sconn->no_reconnect) {
+      silc_schedule_task_add(server->schedule, 0,
+                            silc_server_connect_to_router_retry,
+                            sconn, 0, 1, SILC_TASK_TIMEOUT,
+                            SILC_TASK_PRI_NORMAL);
+      return;
+    }
+    silc_server_config_unref(&sconn->conn);
+    silc_free(sconn->remote_host);
+    silc_free(sconn->backup_replace_ip);
+    silc_free(sconn);
     return;
   }
 
@@ -923,14 +932,23 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
       silc_ske_free(ctx->ske);
     silc_free(ctx->dest_id);
     silc_free(ctx);
-    silc_server_config_unref(&sconn->conn);
-    silc_free(sconn->remote_host);
-    silc_free(sconn->backup_replace_ip);
-    silc_free(sconn);
     silc_schedule_task_del_by_callback(server->schedule,
                                       silc_server_failure_callback);
     silc_server_disconnect_remote(server, sock, 
                                  SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
+
+    /* Try reconnecting if configuration wants it */
+    if (!sconn->no_reconnect) {
+      silc_schedule_task_add(server->schedule, 0,
+                            silc_server_connect_to_router_retry,
+                            sconn, 0, 1, SILC_TASK_TIMEOUT,
+                            SILC_TASK_PRI_NORMAL);
+      return;
+    }
+    silc_server_config_unref(&sconn->conn);
+    silc_free(sconn->remote_host);
+    silc_free(sconn->backup_replace_ip);
+    silc_free(sconn);
     return;
   }
   silc_ske_free_key_material(ctx->keymat);
@@ -1049,6 +1067,16 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
     silc_free(ctx->dest_id);
     silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED,
                                  NULL);
+
+    /* Try reconnecting if configuration wants it */
+    if (!sconn->no_reconnect) {
+      silc_schedule_task_add(server->schedule, 0,
+                            silc_server_connect_to_router_retry,
+                            sconn, 0, 1, SILC_TASK_TIMEOUT,
+                            SILC_TASK_PRI_NORMAL);
+      goto out2;
+    }
+
     goto out;
   }
 
@@ -1156,12 +1184,10 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
       silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
       silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
 
-#ifdef BACKUP_SINGLE_ROUTER
       /* If we are backup router then this primary router is whom we are
         backing up. */
       if (server->server_type == SILC_BACKUP_ROUTER)
        silc_server_backup_add(server, server->id_entry, sock->ip, 0, TRUE);
-#endif /* BACKUP_SINGLE_ROUTER */
     }
   } else {
     /* Add this server to be our backup router */
@@ -1187,6 +1213,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   if (sconn == server->router_conn)
     server->router_conn = NULL;
 
+ out2:
   /* Free the protocol object */
   if (sock->protocol == protocol)
     sock->protocol = NULL;
@@ -1601,12 +1628,30 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
       SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
       SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
 
+      /* If we are backup router and this is incoming server connection
+        and we do not have connection to primary router, do not allow
+        the connection. */
+      if (server->server_type == SILC_BACKUP_ROUTER &&
+         ctx->conn_type == SILC_SOCKET_TYPE_SERVER &&
+         !SILC_PRIMARY_ROUTE(server)) {
+       SILC_LOG_INFO(("Will not accept server connection because we do "
+                      "not have primary router connection established"));
+       silc_server_disconnect_remote(server, sock, 
+                                     SILC_STATUS_ERR_PERM_DENIED,
+                                     "We do not have connection to primary "
+                                     "router established, try later");
+       silc_free(sock->user_data);
+       server->stat.auth_failures++;
+       goto out;
+      }
+
       if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
        /* Verify whether this connection is after all allowed to connect */
        if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
                                            &server->config->param,
                                            rconn ? rconn->param : NULL,
                                            ctx->ske)) {
+         silc_free(sock->user_data);
          server->stat.auth_failures++;
          goto out;
        }
@@ -1631,6 +1676,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
                                            &server->config->param,
                                            sconn ? sconn->param : NULL,
                                            ctx->ske)) {
+         silc_free(sock->user_data);
          server->stat.auth_failures++;
          goto out;
        }
@@ -1680,15 +1726,6 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
       }
       entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
 
-      /* Statistics */
-      if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
-       server->stat.my_servers++;
-      } else {
-       server->stat.my_routers++;
-       server->stat.routers++;
-      }
-      server->stat.servers++;
-
       id_entry = (void *)new_server;
 
       /* If the incoming connection is router and marked as backup router
@@ -1704,6 +1741,15 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
        new_server->server_type = SILC_BACKUP_ROUTER;
       }
 
+      /* Statistics */
+      if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
+       server->stat.my_servers++;
+      } else {
+       server->stat.my_routers++;
+       server->stat.routers++;
+      }
+      server->stat.servers++;
+
       /* Check whether this connection is to be our primary router connection
         if we do not already have the primary route. */
       if (!backup_router &&
@@ -2089,10 +2135,10 @@ void silc_server_packet_parse_type(SilcServer server,
        message = silc_memdup(packet->buffer->data + 1,
                              packet->buffer->len - 1);
 
-      SILC_LOG_ERROR(("Disconnected by %s (%s): %s (%d) %s", 
-                     sock->ip, sock->hostname,
-                     silc_get_status_message(status), status,
-                     message ? message : ""));
+      SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s", 
+                    sock->ip, sock->hostname,
+                    silc_get_status_message(status), status,
+                    message ? message : ""));
       silc_free(message);
     }
     break;
@@ -2515,7 +2561,7 @@ void silc_server_create_connection(SilcServer server,
 
 SILC_TASK_CALLBACK(silc_server_close_connection_final)
 {
-  silc_socket_free((SilcSocketConnection)context);
+  silc_socket_free(context);
 }
 
 /* Closes connection to socket connection */
@@ -2751,24 +2797,25 @@ void silc_server_free_sock_user_data(SilcServer server,
          server->standalone = TRUE;
          backup_router = NULL;
        } else {
-         SILC_LOG_INFO(("New primary router is backup router %s",
-                        backup_router->server_name));
-         SILC_LOG_DEBUG(("New primary router is backup router %s",
-                         backup_router->server_name));
-#ifdef BACKUP_SINGLE_ROUTER
+         if (server->id_entry == backup_router) {
+           SILC_LOG_INFO(("We are now new router in this cell"));
+           SILC_LOG_DEBUG(("We are now new router in this cell"));
+         } else {
+           SILC_LOG_INFO(("New primary router is backup router %s",
+                          backup_router->server_name));
+           SILC_LOG_DEBUG(("New primary router is backup router %s",
+                           backup_router->server_name));
+         }
          if (server->id_entry != backup_router) {
-#endif /* BACKUP_SINGLE_ROUTER */
            server->id_entry->router = backup_router;
            server->router = backup_router;
            server->router_connect = time(0);
            server->backup_primary = TRUE;
-#ifdef BACKUP_SINGLE_ROUTER
          } else {
            server->id_entry->router = NULL;
            server->router = NULL;
            server->standalone = TRUE;
          }
-#endif /* BACKUP_SINGLE_ROUTER */
 
          if (server->server_type == SILC_BACKUP_ROUTER) {
            server->server_type = SILC_ROUTER;
@@ -2796,19 +2843,25 @@ void silc_server_free_sock_user_data(SilcServer server,
       }
 
       if (!backup_router) {
-       /* Free all client entries that this server owns as they will
-          become invalid now as well. */
-       if (user_data->id)
+       /* As router, remove clients and channels always.  As normal server
+          remove only if it is our primary router.  Other connections
+          may be backup routers and these normal server don't handle here. */
+       if (server->server_type != SILC_SERVER ||
+           server->standalone || sock == SILC_PRIMARY_ROUTE(server)) {
+         /* Free all client entries that this server owns as they will
+            become invalid now as well. */
          silc_server_remove_clients_by_server(server, user_data, TRUE);
-       if (server->server_type == SILC_SERVER)
-         silc_server_remove_channels_by_server(server, user_data);
+         if (server->server_type == SILC_SERVER)
+           silc_server_remove_channels_by_server(server, user_data);
+       }
       } else {
        /* Update the client entries of this server to the new backup
           router. This also removes the clients that *really* was owned
           by the primary router and went down with the router.  */
        silc_server_update_clients_by_server(server, user_data, backup_router,
                                             TRUE, TRUE);
-       silc_server_update_servers_by_server(server, user_data, backup_router);
+       silc_server_update_servers_by_server(server, user_data, backup_router,
+                                            TRUE);
        if (server->server_type == SILC_SERVER)
          silc_server_update_channels_by_server(server, user_data,
                                                backup_router);
@@ -2830,7 +2883,7 @@ void silc_server_free_sock_user_data(SilcServer server,
       if (server->server_type == SILC_ROUTER)
        server->stat.cell_servers--;
 
-      if (backup_router) {
+      if (backup_router && backup_router != server->id_entry) {
        /* 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)
@@ -3652,9 +3705,10 @@ static void silc_server_announce_get_clients(SilcServer server,
        silc_buffer_pull(*clients, idp->len);
 
        SILC_PUT32_MSB(client->mode, mode);
-       tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
-                                                2, idp->data, idp->len,
-                                                mode, 4);
+       tmp =
+         silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
+                                            2, idp->data, idp->len,
+                                            mode, 4);
        *umodes = silc_buffer_realloc(*umodes,
                                      (*umodes ?
                                       (*umodes)->truelen + tmp->len :
index 70322dd93b4ebfff4de2af22809369cf73f82cd1..299f1eee1b681e8700a27aaf2d3338f0d6b64786 100644 (file)
@@ -125,8 +125,6 @@ SilcServerEntry silc_server_backup_get(SilcServer server,
     return NULL;
 
   for (i = 0; i < server->backup->servers_count; i++) {
-    SILC_LOG_HEXDUMP(("IP"), server_id->ip.data, 16);
-    SILC_LOG_HEXDUMP(("IP"), server->backup->servers[i].ip.data, 16);
     if (server->backup->servers[i].server &&
        !memcmp(&server->backup->servers[i].ip, &server_id->ip.data,
                sizeof(server_id->ip.data)))
@@ -137,19 +135,22 @@ SilcServerEntry silc_server_backup_get(SilcServer server,
 }
 
 /* Deletes the backup server `server_entry'. */
+
 void silc_server_backup_del(SilcServer server, SilcServerEntry server_entry)
 {
   int i;
 
-  SILC_LOG_DEBUG(("Start"));
-
   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",
+                     server_entry->server_name ? server_entry->server_name :
+                     ""));
       server->backup->servers[i].server = NULL;
-      return;
+      memset(server->backup->servers[i].ip.data, 0,
+            sizeof(server->backup->servers[i].ip.data));
     }
   }
 }
@@ -288,6 +289,8 @@ void silc_server_backup_broadcast(SilcServer server,
     if (!backup || backup->connection == sender || 
        server->backup->servers[i].local == FALSE)
       continue;
+    if (server->backup->servers[i].server == server->id_entry)
+      continue;
 
     idata = (SilcIDListData)backup;
     sock = backup->connection;
@@ -334,8 +337,6 @@ void silc_server_backup_send(SilcServer server,
   if (!server->backup || server->server_type != SILC_ROUTER)
     return;
 
-  SILC_LOG_DEBUG(("Start"));
-
   for (i = 0; i < server->backup->servers_count; i++) {
     backup = server->backup->servers[i].server;
     if (!backup)
@@ -346,8 +347,14 @@ void silc_server_backup_send(SilcServer server,
 
     if (local && server->backup->servers[i].local == FALSE)
       continue;
+    if (server->backup->servers[i].server == server->id_entry)
+      continue;
 
     sock = backup->connection;
+
+    SILC_LOG_DEBUG(("Sending %s packet to backup router %s (%s)",
+                   silc_get_packet_name(type), sock->hostname, sock->ip));
+
     silc_server_packet_send(server, backup->connection, type, flags, 
                            data, data_len, force_send);
   }
@@ -376,8 +383,6 @@ void silc_server_backup_send_dest(SilcServer server,
   if (!server->backup || server->server_type != SILC_ROUTER)
     return;
 
-  SILC_LOG_DEBUG(("Start"));
-
   for (i = 0; i < server->backup->servers_count; i++) {
     backup = server->backup->servers[i].server;
     if (!backup)
@@ -388,8 +393,14 @@ void silc_server_backup_send_dest(SilcServer server,
 
     if (local && server->backup->servers[i].local == FALSE)
       continue;
+    if (server->backup->servers[i].server == server->id_entry)
+      continue;
 
     sock = backup->connection;
+
+    SILC_LOG_DEBUG(("Sending %s packet to backup router %s (%s)",
+                   silc_get_packet_name(type), sock->hostname, sock->ip));
+
     silc_server_packet_send_dest(server, backup->connection, type, flags, 
                                 dst_id, dst_id_type, data, data_len, 
                                 force_send);
@@ -478,7 +489,7 @@ void silc_server_backup_resume_router(SilcServer server,
      immediately after we've connected to our primary router. */
 
   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
-      server->router == sock->user_data &&
+      sock && SILC_PRIMARY_ROUTE(server) == sock &&
       type == SILC_SERVER_BACKUP_REPLACED) {
     /* We have been replaced by an backup router in our cell. We must
        mark our primary router connection disabled since we are not allowed
@@ -990,7 +1001,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
       /* Switch announced informations to our primary router of using the
         backup router. */
       silc_server_update_servers_by_server(server, ctx->sock->user_data, 
-                                          server->router);
+                                          server->router, TRUE);
       silc_server_update_clients_by_server(server, ctx->sock->user_data,
                                           server->router, TRUE, FALSE);
       if (server->server_type == SILC_SERVER)
@@ -1089,7 +1100,6 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
 
   case SILC_PROTOCOL_STATE_END:
     {
-      SilcIDListData idata;
       SilcServerEntry router, backup_router;
 
       /* We should have been received RESUMED packet from our primary
@@ -1103,35 +1113,37 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
       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;
 
+      /* We have now new primary router. All traffic goes there from now on. */
       router = (SilcServerEntry)ctx->sock->user_data;
       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;
+         server->router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+
          SILC_LOG_INFO(("Switching back to primary router %s",
                         server->router->server_name));
-         SILC_LOG_DEBUG(("Switching back to primary router %s",
-                         server->router->server_name));
-         idata = (SilcIDListData)server->router;
-         idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
+
+         /* We cannot talk to backup router connection anymore, it's
+            enabled again if primary goes down. */
+         backup_router->data.status |= SILC_IDLIST_STATUS_DISABLED;
        } else {
-         SILC_LOG_INFO(("Resuming the use of router %s",
+         /* We are connected to new primary and now continue using it */
+         router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+         SILC_LOG_INFO(("Resuming the use of primary router %s",
                         router->server_name));
-         SILC_LOG_DEBUG(("Resuming the use of router %s",
-                         router->server_name));
-         idata = (SilcIDListData)router;
-         idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
        }
 
        /* Update the client entries of the backup router to the new 
           router */
-       silc_server_update_servers_by_server(server, backup_router, router);
+       silc_server_update_servers_by_server(server, backup_router, router,
+                                            FALSE);
        silc_server_update_clients_by_server(server, backup_router,
                                             router, TRUE, FALSE);
        if (server->server_type == SILC_SERVER)
@@ -1190,7 +1202,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
   SilcIDCacheList list;
   SilcIDCacheEntry id_cache;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Backup resuming protocol is ended"));
 
   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
@@ -1207,6 +1219,9 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
        if (sock->protocol == protocol) {
          sock->protocol = NULL;
 
+         SILC_LOG_DEBUG(("***************1 %s:%d",
+                         sock->ip, sock->port));
+
          if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
            server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
        }
@@ -1227,6 +1242,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
        if (sock->protocol == protocol) {
          sock->protocol = NULL;
 
+         SILC_LOG_DEBUG(("***************2"));
+
          if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
            server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
        }
index 6e3056c7e49fae5e9fda99e00f31b6b13f3ae7b3..a09a9d90e120013d1010c3eda7775b31dd686854 100644 (file)
@@ -287,6 +287,9 @@ bool silc_server_remove_clients_by_server(SilcServer server,
   if (server_signoff) {
     SilcBuffer args, not;
 
+    SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %d clients",
+                   argc - 1));
+
     /* Send SERVER_SIGNOFF notify to our primary router */
     if (server->router != entry) {
       args = silc_argument_payload_encode(1, argv, argv_lens,
@@ -474,18 +477,23 @@ void silc_server_update_clients_by_server(SilcServer server,
 
   SILC_LOG_DEBUG(("Start"));
 
-  SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
-                                               SILC_ID_SERVER)));
-  SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
-                                         SILC_ID_SERVER)));
-
+  if (from)
+    SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
+                                                 SILC_ID_SERVER)));
+  if (to)
+    SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
+                                           SILC_ID_SERVER)));
 
   local = FALSE;
   if (silc_idcache_get_all(server->global_list->clients, &list)) {
     if (silc_idcache_list_first(list, &id_cache)) {
       while (id_cache) {
        client = (SilcClientEntry)id_cache->context;
-       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
+
+       /* If entry is disabled skip it.  If entry is local to us, do not
+          switch it to anyone else, it is ours so skip it. */
+       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
+           SILC_IS_LOCAL(client)) {
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -532,7 +540,11 @@ void silc_server_update_clients_by_server(SilcServer server,
     if (silc_idcache_list_first(list, &id_cache)) {
       while (id_cache) {
        client = (SilcClientEntry)id_cache->context;
-       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
+
+       /* If entry is disabled skip it.  If entry is local to us, do not
+          switch it to anyone else, it is ours so skip it. */
+       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
+           SILC_IS_LOCAL(client)) {
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -582,26 +594,48 @@ void silc_server_update_clients_by_server(SilcServer server,
 }
 
 /* Updates servers that are from `from' to be originated from `to'.  This
-   will also update the server's connection to `to's connection. */
+   will also update the server's connection to `to's connection. If
+   `local_toggle_enabled' is TRUE then local server's connections are
+   enabled, if FALSE they are disabled. */
 
 void silc_server_update_servers_by_server(SilcServer server, 
                                          SilcServerEntry from,
-                                         SilcServerEntry to)
+                                         SilcServerEntry to,
+                                         bool local_toggle_enabled)
 {
   SilcIDCacheList list = NULL;
   SilcIDCacheEntry id_cache = NULL;
   SilcServerEntry server_entry = NULL;
 
-  SILC_LOG_DEBUG(("Start"));
-
   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;
+
+       if (SILC_IS_LOCAL(server_entry)) {
+         if (server_entry != server->id_entry) {
+           if (local_toggle_enabled)
+             server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+           else
+             server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
+         }
+
+         /* If entry is local to us, do not switch it to any oneelse,
+            it is ours. */
+         if (!silc_idcache_list_next(list, &id_cache))
+           break;
+         else
+           continue;
+       }
+
        if (server_entry->router == from) {
+         SILC_LOG_DEBUG(("Updating server (local) %s",
+                         server_entry->server_name ? 
+                         server_entry->server_name : ""));
          server_entry->router = to;
          server_entry->connection = to->connection;
        }
+
        if (!silc_idcache_list_next(list, &id_cache))
          break;
       }
@@ -613,10 +647,31 @@ void silc_server_update_servers_by_server(SilcServer server,
     if (silc_idcache_list_first(list, &id_cache)) {
       while (id_cache) {
        server_entry = (SilcServerEntry)id_cache->context;
+
+       if (SILC_IS_LOCAL(server_entry)) {
+         if (server_entry != server->id_entry) {
+           if (local_toggle_enabled)
+             server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+           else
+             server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
+         }
+
+         /* If entry is local to us, do not switch it to anyone else,
+            it is ours. */
+         if (!silc_idcache_list_next(list, &id_cache))
+           break;
+         else
+           continue;
+       }
+
        if (server_entry->router == from) {
+         SILC_LOG_DEBUG(("Updating server (global) %s",
+                         server_entry->server_name ? 
+                         server_entry->server_name : ""));
          server_entry->router = to;
          server_entry->connection = to->connection;
        }
+
        if (!silc_idcache_list_next(list, &id_cache))
          break;
       }
@@ -948,6 +1003,8 @@ bool silc_server_connection_allowed(SilcServer server,
   SilcUInt32 r_software_version, l_software_version;
   char *r_vendor_version = NULL, *l_vendor_version;
 
+  SILC_LOG_DEBUG(("Checking whether connection is allowed"));
+
   /* Check version */
 
   l_protocol_version = 
index 84ef07838ca90d204d8187ff949487f7eb9bb533..6f67e25c5669fc32fba37e7cd11e5f5b6e88c498 100644 (file)
@@ -45,10 +45,13 @@ void silc_server_update_clients_by_server(SilcServer server,
                                          bool remove_from);
 
 /* Updates servers that are from `from' to be originated from `to'.  This
-   will also update the server's connection to `to's connection. */
+   will also update the server's connection to `to's connection. If
+   `local_toggle_enabled' is TRUE then local server's connections are
+   enabled, if FALSE they are disabled. */
 void silc_server_update_servers_by_server(SilcServer server, 
                                          SilcServerEntry from,
-                                         SilcServerEntry to);
+                                         SilcServerEntry to,
+                                         bool local_toggle_enabled);
 
 /* Removes channels that are from `from. */
 void silc_server_remove_channels_by_server(SilcServer server, 
index 45cd9476b10c6433de38385c52d1cfe9f6f3ad34..ec1bb6cbce92d73814df4ba5e5e428a787fdbc28 100644 (file)
@@ -1630,14 +1630,14 @@ resuming protocol is executed.  The protocol is advanced as follows:
   5. Backup router MUST wait for all packets with type value 3 before
      it continues with the protocol.  It knows from the session ID values
      set in the packet when it have received all packets.  The session
-     value should be different in all packets it have send earlier.
+     value should be different in all packets it have sent earlier.
      After the packets is received the backup router sends the
      SILC_PACKET_RESUME_ROUTER packet with type value 4 to the
      primary router that came back online.  This packet will indicate 
      that the backup router is now ready to resign as being primary
      router.  The session ID value in this packet MUST be the same as
      in first packet sent to the primary router.  During this time
-     the backup router should still route all packets it is receiving
+     the backup router must still route all packets it is receiving
      from server connections.
 
   6. The primary router receives the packet and send the
@@ -1683,7 +1683,7 @@ packet:
   3    SILC_SERVER_BACKUP_START_CONNECTED
   4    SILC_SERVER_BACKUP_START_ENDING
   5    SILC_SERVER_BACKUP_START_RESUMED
-  6    SILC_SERVER_BACKUP_START_GLOBAL
+  6    SILC_SERVER_BACKUP_START_RESUMED_GLOBAL
   20   SILC_SERVER_BACKUP_START_REPLACED
 
 If any other value is found in the type field the packet must be 
index bcfa80de03b279316b99b9e36063a3a99b0c84cb..57931f7e649d4ae8f78bb810011f31927659ce54 100644 (file)
@@ -995,7 +995,7 @@ static const SilcStatusMessage silc_status_messages[] = {
   { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
   { STAT(TOO_MANY_PARAMS),   "Too many parameters" },
   { STAT(PERM_DENIED),       "Permission denied" },
-  { STAT(BANNED_FROM_SERVER),"You are banned from this server" },
+  { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
   { STAT(BAD_PASSWORD),      "Cannot join channel. Incorrect password" },
   { STAT(CHANNEL_IS_FULL),   "Cannot join channel. Channel is full" },
   { STAT(NOT_INVITED),     "Cannot join channel. You have not been invited" },