server->backup->servers[i].local = local;
memset(server->backup->servers[i].ip.data, 0,
sizeof(server->backup->servers[i].ip.data));
- silc_net_addr2bin_ne(ip, server->backup->servers[i].ip.data,
- 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[i].port = port;
return;
}
server->backup->servers[i].local = local;
memset(server->backup->servers[i].ip.data, 0,
sizeof(server->backup->servers[i].ip.data));
- silc_net_addr2bin_ne(ip, server->backup->servers[i].ip.data,
- 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[i].port = server_id->port;
server->backup->servers_count++;
}
silc_packet_send_prepare(sock, 0, 0, buffer->len);
silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
- silc_packet_encrypt(idata->send_key, idata->hmac_send,
+ silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
sock->outbuf, sock->outbuf->len);
SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", sock->outbuf->len),
backup_router->protocol = NULL;
}
+SILC_TASK_CALLBACK(silc_server_backup_send_resumed)
+{
+ SilcProtocol protocol = (SilcProtocol)context;
+ SilcServerBackupProtocolContext ctx = protocol->context;
+ SilcServer server = ctx->server;
+ SilcBuffer packet;
+ int i;
+
+ for (i = 0; i < ctx->sessions_count; i++)
+ if (ctx->sessions[i].server_entry == ctx->sock->user_data)
+ 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. */
+ packet = silc_buffer_alloc(2);
+ silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
+ silc_buffer_format(packet,
+ SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_ENDING),
+ SILC_STR_UI_CHAR(ctx->session),
+ SILC_STR_END);
+ silc_server_packet_send(server, ctx->sock,
+ SILC_PACKET_RESUME_ROUTER, 0,
+ packet->data, packet->len, FALSE);
+ silc_buffer_free(packet);
+
+ protocol->state = SILC_PROTOCOL_STATE_END;
+}
+
/* Resume protocol with RESUME_ROUTER packet:
SILC_PACKET_RESUME_ROUTER:
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if ((server_entry == server->id_entry) ||
- !server_entry->connection) {
+ if (!server_entry || (server_entry == server->id_entry) ||
+ !server_entry->connection || !server_entry->data.send_key ||
+ (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)) {
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ else
+ 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(("********************************"));
+ SILC_LOG_DEBUG(("START (local) for session %d",
+ ctx->sessions_count));
+
+ /* This connection is performing this protocol too now */
+ ((SilcSocketConnection)server_entry->connection)->protocol =
+ protocol;
+
+ if (server_entry->server_type == SILC_ROUTER)
+ packet->data[0] = SILC_SERVER_BACKUP_START;
+ else
+ packet->data[0] = SILC_SERVER_BACKUP_START_GLOBAL;
+ packet->data[1] = ctx->sessions_count;
+ silc_server_packet_send(server, server_entry->connection,
+ SILC_PACKET_RESUME_ROUTER, 0,
+ packet->data, packet->len, FALSE);
+ ctx->sessions_count++;
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+ }
+
+ silc_idcache_list_free(list);
+ }
+
+ if (silc_idcache_get_all(server->global_list->servers, &list)) {
+ if (silc_idcache_list_first(list, &id_cache)) {
+ while (id_cache) {
+ server_entry = (SilcServerEntry)id_cache->context;
+ if (!server_entry || (server_entry == server->id_entry) ||
+ !server_entry->connection || !server_entry->data.send_key ||
+ (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)) {
if (!silc_idcache_list_next(list, &id_cache))
break;
else
ctx->sessions[ctx->sessions_count].server_entry = server_entry;
SILC_LOG_DEBUG(("********************************"));
- SILC_LOG_DEBUG(("START for session %d", ctx->sessions_count));
+ SILC_LOG_DEBUG(("START (global) for session %d",
+ ctx->sessions_count));
/* This connection is performing this protocol too now */
((SilcSocketConnection)server_entry->connection)->protocol =
silc_buffer_free(packet);
- /* If we are router then announce our possible servers. */
- if (server->server_type == SILC_ROUTER)
- silc_server_announce_servers(server, FALSE, 0, ctx->sock);
+ /* 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);
SILC_LOG_DEBUG(("********************************"));
SILC_LOG_DEBUG(("Sending ENDING packet to primary"));
- for (i = 0; i < ctx->sessions_count; i++)
- if (ctx->sessions[i].server_entry == ctx->sock->user_data)
- 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. */
- packet = silc_buffer_alloc(2);
- silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
- silc_buffer_format(packet,
- SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_ENDING),
- SILC_STR_UI_CHAR(ctx->session),
- SILC_STR_END);
- silc_server_packet_send(server, ctx->sock,
- SILC_PACKET_RESUME_ROUTER, 0,
- packet->data, packet->len, FALSE);
- silc_buffer_free(packet);
-
- protocol->state = SILC_PROTOCOL_STATE_END;
+ /* Send with a timeout */
+ silc_schedule_task_add(server->schedule, 0,
+ silc_server_backup_send_resumed,
+ protocol, 1, 0, SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
+ return;
} else {
/* Responder */
break;
}
- /* Switch announced informations to our entry instead of using the
+ /* 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);
silc_server_update_clients_by_server(server, ctx->sock->user_data,
- server->id_entry, TRUE, FALSE);
+ server->router, TRUE, FALSE);
+ if (server->server_type == SILC_SERVER)
+ silc_server_update_channels_by_server(server, ctx->sock->user_data,
+ server->router);
packet = silc_buffer_alloc(2);
silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if ((server_entry == server->id_entry) ||
- !server_entry->connection) {
+ if (!server_entry || (server_entry == server->id_entry) ||
+ !server_entry->connection || !server_entry->data.send_key) {
if (!silc_idcache_list_next(list, &id_cache))
break;
else
}
SILC_LOG_DEBUG(("********************************"));
- SILC_LOG_DEBUG(("RESUMED packet"));
+ SILC_LOG_DEBUG(("RESUMED packet (local)"));
+
+ server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+
+ /* This connection is performing this protocol too now */
+ ((SilcSocketConnection)server_entry->connection)->protocol =
+ protocol;
+
+ if (server_entry->server_type == SILC_ROUTER)
+ packet->data[0] = SILC_SERVER_BACKUP_RESUMED;
+ else
+ packet->data[0] = SILC_SERVER_BACKUP_RESUMED_GLOBAL;
+ silc_server_packet_send(server, server_entry->connection,
+ SILC_PACKET_RESUME_ROUTER, 0,
+ packet->data, packet->len, FALSE);
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+ }
+
+ silc_idcache_list_free(list);
+ }
+
+ if (silc_idcache_get_all(server->global_list->servers, &list)) {
+ if (silc_idcache_list_first(list, &id_cache)) {
+ while (id_cache) {
+ server_entry = (SilcServerEntry)id_cache->context;
+ if (!server_entry || (server_entry == server->id_entry) ||
+ !server_entry->connection || !server_entry->data.send_key) {
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ else
+ continue;
+ }
+
+ SILC_LOG_DEBUG(("********************************"));
+ SILC_LOG_DEBUG(("RESUMED packet (global)"));
server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
&backup_router)) {
if (backup_router == server->router) {
+ server->id_entry->router = router;
+ server->router = router;
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));
- server->id_entry->router = router;
- server->router = router;
+ idata = (SilcIDListData)server->router;
+ idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
} else {
SILC_LOG_INFO(("Resuming the use of 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;
}
- idata = (SilcIDListData)server->router;
- idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
-
- /* Update the client entries of the backup router to the new router */
+ /* 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_clients_by_server(server, backup_router,
- router, FALSE, FALSE);
- silc_server_backup_replaced_del(server, backup_router);
+ router, TRUE, 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);
silc_server_backup_add(server, backup_router,
ctx->sock->ip, ctx->sock->port,
backup_router->server_type != SILC_ROUTER ?
/* Announce all of our information to the router. */
if (server->server_type == SILC_ROUTER)
silc_server_announce_servers(server, FALSE, 0, 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_idcache_list_free(list);
}
+ if (silc_idcache_get_all(server->global_list->servers, &list)) {
+ if (silc_idcache_list_first(list, &id_cache)) {
+ while (id_cache) {
+ server_entry = (SilcServerEntry)id_cache->context;
+ sock = (SilcSocketConnection)server_entry->connection;
+
+ if (sock->protocol == protocol) {
+ sock->protocol = NULL;
+
+ if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
+ server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
+ }
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+ }
+ silc_idcache_list_free(list);
+ }
+
if (ctx->sock->protocol)
ctx->sock->protocol = NULL;
silc_protocol_free(protocol);