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),
SilcPacketContext *packet)
{
uint8 type, session;
- int ret;
+ SilcServerBackupProtocolContext ctx;
+ int i, ret;
if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
sock->type == SILC_SOCKET_TYPE_UNKNOWN)
SILC_LOG_DEBUG(("Start"));
- SILC_LOG_DEBUG(("********************************"));
ret = silc_buffer_unformat(packet->buffer,
SILC_STR_UI_CHAR(&type),
SILC_STR_UI_CHAR(&session),
if (ret < 0)
return;
- SILC_LOG_DEBUG(("********************************"));
+ /* Activate the protocol for this socket if necessary */
+ if ((type == SILC_SERVER_BACKUP_RESUMED ||
+ type == SILC_SERVER_BACKUP_RESUMED_GLOBAL) &&
+ sock->type == SILC_SOCKET_TYPE_ROUTER && !sock->protocol &&
+ ((SilcIDListData)sock->user_data)->status &
+ SILC_IDLIST_STATUS_DISABLED) {
+ SilcServerEntry backup_router;
+
+ if (silc_server_backup_replaced_get(server,
+ ((SilcServerEntry)sock->
+ user_data)->id,
+ &backup_router)) {
+ SilcSocketConnection bsock =
+ (SilcSocketConnection)backup_router->connection;
+ if (bsock->protocol && bsock->protocol->protocol &&
+ bsock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) {
+ sock->protocol = bsock->protocol;
+ ctx = sock->protocol->context;
+ ctx->sock = sock;
+ }
+ }
+ }
+
/* If the backup resuming protocol is active then process the packet
in the protocol. */
if (sock->protocol && sock->protocol->protocol &&
sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) {
- SilcServerBackupProtocolContext ctx = sock->protocol->context;
- int i;
-
+ ctx = sock->protocol->context;
ctx->type = type;
SILC_LOG_DEBUG(("********************************"));
return;
}
- SILC_LOG_DEBUG(("********************************"));
/* We don't have protocol active. If we are router and the packet is
coming from our primary router then lets check whether it means we've
been replaced by an backup router in my cell. This is usually received
SilcIDListData idata = (SilcIDListData)sock->user_data;
SILC_LOG_INFO(("We are replaced by an backup router in this cell, will "
- "wait untill backup resuming protocol is executed"));
+ "wait until backup resuming protocol is executed"));
SILC_LOG_DEBUG(("We are replaced by an backup router in this cell"));
idata->status |= SILC_IDLIST_STATUS_DISABLED;
return;
}
- SILC_LOG_DEBUG(("********************************"));
if (type == SILC_SERVER_BACKUP_START ||
type == SILC_SERVER_BACKUP_START_GLOBAL) {
/* We have received a start for resuming protocol. */
silc_server_protocol_backup_done);
silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
}
- SILC_LOG_DEBUG(("EEEEEEEEEEEEEEEEEEEEEEEEe"));
}
/* Timeout task callback to connect to remote router */
sconn->remote_port));
/* Connect to remote host */
- sock = silc_net_create_connection(server->config->listen_port->local_ip,
+ sock = silc_net_create_connection(server->config->server_info->server_ip,
sconn->remote_port,
sconn->remote_host);
if (sock < 0) {
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);
protocol->state++;
} else {
/* Responder of the protocol. */
- SilcServerConfigSectionServerConnection *primary;
+ SilcServerConfigSectionRouter *primary;
/* We should have received START or START_GLOBAL packet */
if (ctx->type != SILC_SERVER_BACKUP_START &&
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;
silc_buffer_free(packet);
+ SILC_LOG_INFO(("We are now the primary router of our cell again"));
+
/* For us this is the end of this protocol. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
case SILC_PROTOCOL_STATE_END:
{
SilcIDListData idata;
- SilcServerEntry primary;
- SilcServerEntry backup_router;
+ SilcServerEntry router, backup_router;
/* We should have been received RESUMED packet from our primary
router. */
if (server->backup_router)
server->server_type = SILC_BACKUP_ROUTER;
- primary = (SilcServerEntry)ctx->sock->user_data;
- if (silc_server_backup_replaced_get(server, primary->id,
+ router = (SilcServerEntry)ctx->sock->user_data;
+ if (silc_server_backup_replaced_get(server, router->id,
&backup_router)) {
if (backup_router == server->router) {
- server->id_entry->router = ctx->sock->user_data;
- server->router = ctx->sock->user_data;
+ server->id_entry->router = router;
+ server->router = router;
SILC_LOG_INFO(("Switching back to primary router %s",
server->router->server_name));
- SILC_LOG_DEBUG(("********************************"));
SILC_LOG_DEBUG(("Switching back to primary router %s",
server->router->server_name));
idata = (SilcIDListData)server->router;
idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
-
- /* Update the client entries of the backup router to the new
- primary router. */
- silc_server_update_clients_by_server(server, backup_router,
- primary, TRUE, FALSE);
- silc_server_backup_replaced_del(server, backup_router);
- silc_server_backup_add(server, backup_router,
- ((SilcSocketConnection)primary->
- connection)->ip,
- ((SilcSocketConnection)primary->
- connection)->port,
- backup_router->server_type != SILC_ROUTER ?
- TRUE : FALSE);
+ } 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;
}
- /* Announce all of our information to the new primary 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, 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 ?
+ TRUE : FALSE);
+
+ /* Announce all of our information to the router. */
if (server->server_type == SILC_ROUTER)
- silc_server_announce_servers(server, FALSE, 0,
- server->router->connection);
-
+ silc_server_announce_servers(server, FALSE, 0, router->connection);
+
/* Announce our clients and channels to the router */
- silc_server_announce_clients(server, 0,
- server->router->connection);
- silc_server_announce_channels(server, 0,
- server->router->connection);
+ silc_server_announce_clients(server, 0, router->connection);
+ silc_server_announce_channels(server, 0, router->connection);
}
/* Protocol has ended, call the final callback */
SILC_LOG_ERROR(("Error occurred during backup router resuming protcool"));
}
+ /* Remove this protocol from all server entries that has it */
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;
sock = (SilcSocketConnection)server_entry->connection;
- if (sock->protocol && sock->protocol->protocol &&
- sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP)
+ 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 (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;