sconn->remote_host = strdup(ptr->host);
sconn->remote_port = ptr->port;
sconn->backup = ptr->backup_router;
-
+ if (sconn->backup) {
+ sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
+ sconn->backup_replace_port = ptr->backup_replace_port;
+ }
+
silc_schedule_task_add(server->schedule, fd,
silc_server_connect_router,
(void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
SILC_LOG_DEBUG(("New server id(%s)",
silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
- /* Add the connected router to local server list */
- id_entry = silc_idlist_add_server(server->local_list, strdup(sock->hostname),
+ /* Add the connected router to global server list */
+ id_entry = silc_idlist_add_server(server->global_list,
+ strdup(sock->hostname),
SILC_ROUTER, ctx->dest_id, NULL, sock);
if (!id_entry) {
silc_free(ctx->dest_id);
}
} else {
/* Add this server to be our backup router */
- silc_server_backup_add(server, id_entry, FALSE);
+ silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
+ sconn->backup_replace_port, FALSE);
}
sock->protocol = NULL;
/* Free the temporary connection data context */
if (sconn) {
silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
silc_free(sconn);
}
server. We mark ourselves as router for this server if we really
are router. */
new_server =
- silc_idlist_add_server(server->local_list, NULL,
- ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
- SILC_SERVER : SILC_ROUTER, NULL,
- ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
- server->id_entry :
- (conn->backup_router ? server->id_entry :
- NULL), sock);
+ silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
+ server->local_list : (conn->backup_router ?
+ server->local_list :
+ server->global_list)),
+ NULL,
+ (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
+ SILC_SERVER : SILC_ROUTER),
+ NULL,
+ (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
+ server->id_entry : (conn->backup_router ?
+ server->id_entry : NULL)),
+ sock);
if (!new_server) {
SILC_LOG_ERROR(("Could not add new server to cache"));
silc_free(sock->user_data);
/* If the incoming connection is router and marked as backup router
then add it to be one of our backups */
if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && conn->backup_router) {
- silc_server_backup_add(server, new_server, conn->backup_local);
+ silc_server_backup_add(server, new_server, conn->backup_replace_ip,
+ conn->backup_replace_port, conn->backup_local);
/* Change it back to SERVER type since that's what it really is. */
- if (conn->backup_local) {
+ if (conn->backup_local)
ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
- new_server->server_type = SILC_BACKUP_ROUTER;
- }
+
+ new_server->server_type = SILC_BACKUP_ROUTER;
}
/* Check whether this connection is to be our primary router connection
/* If entry is disabled ignore what we got. */
if (ret != SILC_PACKET_RESUME_ROUTER &&
- idata && idata->status & SILC_IDLIST_STATUS_DISABLED)
+ idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
+ SILC_LOG_DEBUG(("Connection is disabled"));
goto out;
+ }
if (ret == SILC_PACKET_NONE)
goto out;
SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
SilcServerEntry backup_router = NULL;
+ if (user_data->id)
+ backup_router = silc_server_backup_get(server, user_data->id);
+
/* If this was our primary router connection then we're lost to
the outside world. */
if (server->router == user_data) {
- backup_router = silc_server_backup_get(server);
-
/* Check whether we have a backup router connection */
if (!backup_router || backup_router == user_data) {
silc_schedule_task_add(server->schedule, 0,
server->id_entry->router = backup_router;
server->router = backup_router;
server->router_connect = time(0);
+ server->backup_primary = TRUE;
if (server->server_type == SILC_BACKUP_ROUTER) {
server->server_type = SILC_ROUTER;
silc_server_backup_replaced_add(server, user_data->id,
backup_router);
}
+ } else if (backup_router) {
+ SILC_LOG_INFO(("Enabling the use of backup router %s",
+ backup_router->server_name));
+ SILC_LOG_DEBUG(("Enabling the use of backup router %s",
+ backup_router->server_name));
+
+ /* Mark this connection as replaced */
+ silc_server_backup_replaced_add(server, user_data->id,
+ backup_router);
}
if (!backup_router) {
silc_server_backup_del(server, user_data);
silc_server_backup_replaced_del(server, user_data);
silc_idlist_del_data(user_data);
- silc_idlist_del_server(server->local_list, user_data);
+ if (!silc_idlist_del_server(server->local_list, user_data))
+ silc_idlist_del_server(server->global_list, user_data);
server->stat.my_servers--;
server->stat.servers--;
if (server->server_type == SILC_ROUTER)
The backup router knows all the other stuff already. */
if (server->server_type == SILC_ROUTER)
silc_server_announce_servers(server, FALSE, time(0) - 300,
- server->router->connection);
+ backup_router->connection);
/* Announce our clients and channels to the router */
silc_server_announce_clients(server, time(0) - 300,
- server->router->connection);
+ backup_router->connection);
silc_server_announce_channels(server, time(0) - 300,
- server->router->connection);
+ backup_router->connection);
}
break;
}
silc_hash_table_count(channel->user_list) < 2) {
if (channel->rekey)
silc_schedule_task_del_by_context(server->schedule, channel->rekey);
- if (!silc_idlist_del_channel(server->local_list, channel))
- silc_idlist_del_channel(server->global_list, channel);
+ if (silc_idlist_del_channel(server->local_list, channel))
server->stat.my_channels--;
+ silc_idlist_del_channel(server->global_list, channel);
continue;
}