}
SILC_LOG_DEBUG(("Backup router %s will replace %s",
- backup_server->data.sconn->remote_host, ip, port));
+ 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) {
/* 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_packet_free(pc->packet);
silc_free(pc);
}
if (type == SILC_SERVER_BACKUP_RESUMED &&
idata->conn_type == SILC_CONN_ROUTER && !router->backup &&
idata->status & SILC_IDLIST_STATUS_DISABLED) {
- if (silc_server_backup_replaced_get(server, router->id, NULL))
+ 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. */
SilcServer server = app_context;
SilcServerConfigRouter *primary;
+ SILC_LOG_DEBUG(("Reconnecting"));
+
+ if (server->server_shutdown)
+ return;
+
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,
+ silc_server_create_connection(server, TRUE, FALSE,
primary->host, primary->port,
silc_server_backup_connected,
context);
if (!server_entry) {
/* Try again */
+ SILC_LOG_DEBUG(("Connecting failed"));
silc_schedule_task_add_timeout(server->schedule,
silc_server_backup_connected_again,
- context, 0, 1);
+ context, 5, 0);
return;
}
if (primary) {
if (!silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
primary->host, primary->port))
- silc_server_create_connection(server, FALSE, FALSE,
+ silc_server_create_connection(server, TRUE, FALSE,
primary->host, primary->port,
silc_server_backup_connect_primary,
context);
return;
}
- /* Unref */
- silc_packet_stream_unref(backup_router);
-
- if (!router->backup)
- return;
- if (!server_entry->connection)
+ if (!router->backup || !server_entry->connection) {
+ silc_packet_stream_unref(backup_router);
return;
+ }
ctx = router->backup_proto;
sock = server_entry->connection;
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
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,
+ silc_server_create_connection(server, TRUE, FALSE,
primary->host, primary->port,
silc_server_backup_connect_primary,
ctx->sock);
if (sock == ctx->sock)
continue;
- send_to_backup:
+ 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_server_packet_send(server, sock, SILC_PACKET_RESUME_ROUTER, 0,
data, sizeof(data));
}
- silc_packet_engine_free_streams_list(list);
/* Now send the same packet to backup */
if (sock != ctx->sock) {
sleep(1);
sock = ctx->sock;
- goto send_to_backup;
+ 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"));
/* For us this is the end of this protocol. */
silc_schedule_task_add_timeout(server->schedule,
silc_server_protocol_backup_done,
- ctx->sock, 0, 1);
+ ctx, 0, 1);
}
break;
/* Protocol has ended, call the final callback */
silc_schedule_task_add_timeout(server->schedule,
silc_server_protocol_backup_done,
- ctx->sock, 0, 1);
+ ctx, 0, 1);
}
break;
/* Protocol has ended, call the final callback */
silc_schedule_task_add_timeout(server->schedule,
silc_server_protocol_backup_done,
- ctx->sock, 0, 1);
+ ctx, 0, 1);
break;
case 252:
ctx->received_failure = TRUE;
silc_schedule_task_add_timeout(server->schedule,
silc_server_protocol_backup_done,
- ctx->sock, 0, 1);
+ ctx, 0, 1);
break;
default:
SilcServerEntry server_entry;
SilcPacketStream sock;
SilcBool error;
- int i;
silc_schedule_task_del_by_context(server->schedule, ctx);
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_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);
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);
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,
}
}
- if (ctx->sock)
+ 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);
}