#include "server_internal.h"
SILC_TASK_CALLBACK(silc_server_protocol_backup_done);
+static void silc_server_backup_connect_primary(SilcServer server,
+ SilcServerEntry server_entry,
+ void *context);
/* Backup router */
typedef struct {
server->backup->replaced_count = 1;
}
- SILC_LOG_DEBUG(("Replacing router %s with %s backup",
+ SILC_LOG_DEBUG(("Replacing router %s with %s",
silc_id_render(server_id, SILC_ID_SERVER),
server_entry->server_name));
for (i = 0; i < server->backup->servers_count; i++) {
backup = server->backup->servers[i].server;
- if (!backup)
- continue;
-
- if (sender == backup)
+ if (!backup || sender == backup)
continue;
-
if (local && server->backup->servers[i].local == FALSE)
continue;
if (server->backup->servers[i].server == server->id_entry)
for (i = 0; i < server->backup->servers_count; i++) {
backup = server->backup->servers[i].server;
- if (!backup)
- continue;
-
- if (sender == backup)
+ if (!backup || sender == backup)
continue;
-
if (local && server->backup->servers[i].local == FALSE)
continue;
if (server->backup->servers[i].server == server->id_entry)
/* Connect to remote host */
server_ip = server->config->server_info->primary == NULL ? NULL :
- server->config->server_info->primary->server_ip;
+ server->config->server_info->primary->server_ip;
sock = silc_net_create_connection(server_ip, sconn->remote_port,
sconn->remote_host);
if (sock < 0) {
sconn->remote_port = port;
sconn->callback = callback;
sconn->callback_context = context;
+ sconn->no_reconnect = TRUE;
silc_schedule_task_add(server->schedule, 0,
silc_server_backup_connect_to_router,
sconn, 1, 0, SILC_TASK_TIMEOUT,
void *context)
{
SilcServerBackupProtocolContext proto_ctx;
- SilcSocketConnection sock = (SilcSocketConnection)server_entry->connection;
+ SilcSocketConnection sock;
+
+ if (!server_entry) {
+ /* Try again */
+ SilcServerConfigRouter *primary;
+ primary = silc_server_config_get_primary_router(server);
+ if (primary)
+ silc_server_backup_reconnect(server,
+ primary->host, primary->port,
+ silc_server_backup_connected,
+ context);
+ return;
+ }
+ sock = (SilcSocketConnection)server_entry->connection;
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
proto_ctx->server = server;
proto_ctx->sock = sock;
void *context)
{
SilcSocketConnection backup_router = (SilcSocketConnection)context;
- SilcSocketConnection sock = (SilcSocketConnection)server_entry->connection;
- SilcIDListData idata = (SilcIDListData)server_entry;
- SilcServerBackupProtocolContext ctx =
- (SilcServerBackupProtocolContext)backup_router->protocol->context;
+ SilcServerBackupProtocolContext ctx;
+ SilcSocketConnection sock;
+ SilcIDListData idata;
SilcBuffer buffer;
+ if (!server_entry) {
+ /* Try again */
+ SilcServerConfigRouter *primary;
+ primary = silc_server_config_get_primary_router(server);
+ if (primary)
+ silc_server_backup_reconnect(server,
+ primary->host, primary->port,
+ silc_server_backup_connect_primary,
+ context);
+ return;
+ }
+
+ ctx = (SilcServerBackupProtocolContext)backup_router->protocol->context;
+ sock = (SilcSocketConnection)server_entry->connection;
+ idata = (SilcIDListData)server_entry;
+
SILC_LOG_DEBUG(("Sending CONNECTED packet (session %d)", ctx->session));
/* Send the CONNECTED packet back to the backup router. */
silc_buffer_free(packet);
- /* Announce all of our information */
- 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);
+ /* If we are not standalone and our primary is not the one we've
+ talking to now, then announce our information to it since we
+ haven't done that yet. Standalone backup router announces
+ these during connecting to the primary. */
+ if (!server->standalone && SILC_PRIMARY_ROUTE(server) != ctx->sock) {
+ 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);
+ }
protocol->state++;
} else {
/* 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, ctx->sock->user_data,
- server->router, TRUE);
+ server->router);
silc_server_update_clients_by_server(server, ctx->sock->user_data,
- server->router, TRUE, FALSE);
+ server->router, TRUE);
if (server->server_type == SILC_SERVER)
silc_server_update_channels_by_server(server, ctx->sock->user_data,
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));
-
- /* 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 {
/* 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));
}
/* Update the client entries of the backup router to the new
router */
- silc_server_update_servers_by_server(server, backup_router, router,
- FALSE);
- silc_server_update_clients_by_server(server, NULL, router,
- FALSE, FALSE);
+ 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, FALSE);
if (server->server_type == SILC_SERVER)
silc_server_update_channels_by_server(server, backup_router, router);
silc_server_backup_replaced_del(server, backup_router);
/* Announce all of our information to the router. */
if (server->server_type == SILC_ROUTER)
- silc_server_announce_servers(server, FALSE, 0, router->connection);
+ silc_server_announce_servers(server, FALSE, ctx->start,
+ router->connection);
/* Announce our clients and channels to the router */
- silc_server_announce_clients(server, 0, router->connection);
- silc_server_announce_channels(server, 0, router->connection);
+ silc_server_announce_clients(server, ctx->start,
+ router->connection);
+ silc_server_announce_channels(server, ctx->start,
+ router->connection);
}
/* Send notify about primary router going down to local operators */