Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 Pekka Riikonen
+ Copyright (C) 2001 - 2002 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
typedef struct {
SilcServerEntry server;
SilcIDIP ip;
- uint16 port;
+ SilcUInt16 port;
bool local;
} SilcServerBackupEntry;
by backup router. */
typedef struct {
SilcIDIP ip;
- uint16 port;
+ SilcUInt16 port;
SilcServerEntry server; /* Backup router that replaced the primary */
} SilcServerBackupReplaced;
/* Backup context */
struct SilcServerBackupStruct {
SilcServerBackupEntry *servers;
- uint32 servers_count;
+ SilcUInt32 servers_count;
SilcServerBackupReplaced **replaced;
- uint32 replaced_count;
+ SilcUInt32 replaced_count;
};
typedef struct {
- uint8 session;
+ SilcUInt8 session;
bool connected;
SilcServerEntry server_entry;
} SilcServerBackupProtocolSession;
SilcServer server;
SilcSocketConnection sock;
bool responder;
- uint8 type;
- uint8 session;
+ SilcUInt8 type;
+ SilcUInt8 session;
SilcServerBackupProtocolSession *sessions;
- uint32 sessions_count;
+ SilcUInt32 sessions_count;
long start;
} *SilcServerBackupProtocolContext;
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++;
}
return NULL;
for (i = 0; i < server->backup->servers_count; i++) {
- SILC_LOG_HEXDUMP(("IP"), server_id->ip.data, 16);
- SILC_LOG_HEXDUMP(("IP"), server->backup->servers[i].ip.data, 16);
if (server->backup->servers[i].server &&
!memcmp(&server->backup->servers[i].ip, &server_id->ip.data,
sizeof(server_id->ip.data)))
}
/* Deletes the backup server `server_entry'. */
+
void silc_server_backup_del(SilcServer server, SilcServerEntry server_entry)
{
int i;
- SILC_LOG_DEBUG(("Start"));
-
if (!server->backup)
return ;
for (i = 0; i < server->backup->servers_count; i++) {
if (server->backup->servers[i].server == server_entry) {
+ SILC_LOG_DEBUG(("Removing %s as backup router",
+ server_entry->server_name ? server_entry->server_name :
+ ""));
server->backup->servers[i].server = NULL;
- return;
+ memset(server->backup->servers[i].ip.data, 0,
+ sizeof(server->backup->servers[i].ip.data));
}
}
}
SilcServerEntry backup;
SilcSocketConnection sock;
SilcBuffer buffer;
+ const SilcBufferStruct p;
SilcIDListData idata;
int i;
if (!backup || backup->connection == sender ||
server->backup->servers[i].local == FALSE)
continue;
+ if (server->backup->servers[i].server == server->id_entry)
+ continue;
idata = (SilcIDListData)backup;
sock = backup->connection;
- silc_packet_send_prepare(sock, 0, 0, buffer->len);
- silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
+ if (!silc_packet_send_prepare(sock, 0, 0, buffer->len, idata->hmac_send,
+ (const SilcBuffer)&p)) {
+ SILC_LOG_ERROR(("Cannot send packet"));
+ return;
+ }
+ silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
- sock->outbuf, sock->outbuf->len);
+ (SilcBuffer)&p, p.len);
- SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", sock->outbuf->len),
- sock->outbuf->data, sock->outbuf->len);
+ SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", p.len), p.data, p.len);
/* Now actually send the packet */
silc_server_packet_send_real(server, sock, FALSE);
SilcPacketType type,
SilcPacketFlags flags,
unsigned char *data,
- uint32 data_len,
+ SilcUInt32 data_len,
bool force_send,
bool local)
{
if (!server->backup || server->server_type != SILC_ROUTER)
return;
- SILC_LOG_DEBUG(("Start"));
-
for (i = 0; i < server->backup->servers_count; i++) {
backup = server->backup->servers[i].server;
if (!backup)
if (local && server->backup->servers[i].local == FALSE)
continue;
+ if (server->backup->servers[i].server == server->id_entry)
+ continue;
sock = backup->connection;
+
+ SILC_LOG_DEBUG(("Sending %s packet to backup router %s (%s)",
+ silc_get_packet_name(type), sock->hostname, sock->ip));
+
silc_server_packet_send(server, backup->connection, type, flags,
data, data_len, force_send);
}
void *dst_id,
SilcIdType dst_id_type,
unsigned char *data,
- uint32 data_len,
+ SilcUInt32 data_len,
bool force_send,
bool local)
{
if (!server->backup || server->server_type != SILC_ROUTER)
return;
- SILC_LOG_DEBUG(("Start"));
-
for (i = 0; i < server->backup->servers_count; i++) {
backup = server->backup->servers[i].server;
if (!backup)
if (local && server->backup->servers[i].local == FALSE)
continue;
+ if (server->backup->servers[i].server == server->id_entry)
+ continue;
sock = backup->connection;
+
+ SILC_LOG_DEBUG(("Sending %s packet to backup router %s (%s)",
+ silc_get_packet_name(type), sock->hostname, sock->ip));
+
silc_server_packet_send_dest(server, backup->connection, type, flags,
dst_id, dst_id_type, data, data_len,
force_send);
SilcSocketConnection sock,
SilcPacketContext *packet)
{
- uint8 type, session;
+ SilcUInt8 type, session;
SilcServerBackupProtocolContext ctx;
int i, ret;
immediately after we've connected to our primary router. */
if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
- server->router == sock->user_data &&
+ sock && SILC_PRIMARY_ROUTE(server) == sock &&
type == SILC_SERVER_BACKUP_REPLACED) {
/* We have been replaced by an backup router in our cell. We must
mark our primary router connection disabled since we are not allowed
SilcServerConnection sconn = (SilcServerConnection)context;
SilcServer server = sconn->server;
int sock;
+ const char *server_ip;
SILC_LOG_DEBUG(("Connecting to router %s:%d", sconn->remote_host,
sconn->remote_port));
/* Connect to remote host */
- sock = silc_net_create_connection(server->config->listen_port->local_ip,
- sconn->remote_port,
+ server_ip = server->config->server_info->primary == NULL ? NULL :
+ server->config->server_info->primary->server_ip;
+ sock = silc_net_create_connection(server_ip, sconn->remote_port,
sconn->remote_host);
if (sock < 0) {
silc_schedule_task_add(server->schedule, 0,
connection is created. */
void silc_server_backup_reconnect(SilcServer server,
- const char *ip, uint16 port,
+ const char *ip, SilcUInt16 port,
SilcServerConnectRouterCallback callback,
void *context)
{
SILC_PACKET_RESUME_ROUTER:
- <uint8 type> <uint8 Session ID>
+ <SilcUInt8 type> <SilcUInt8 Session ID>
<type> = the protocol opcode
<Session ID> = Identifier for this packet and any subsequent reply
protocol->state++;
} else {
/* Responder of the protocol. */
- SilcServerConfigSectionServerConnection *primary;
+ SilcServerConfigRouter *primary;
/* We should have received START or START_GLOBAL packet */
if (ctx->type != SILC_SERVER_BACKUP_START &&
/* Connect to the primary router that was down that is now supposed
to be back online. We send the CONNECTED packet after we've
established the connection to the primary router. */
- primary = silc_server_config_get_primary_router(server->config);
+ primary = silc_server_config_get_primary_router(server);
if (primary && server->backup_primary) {
silc_server_backup_reconnect(server,
primary->host, primary->port,
to next state. */
if (server->router &&
!(server->router->data.status & SILC_IDLIST_STATUS_DISABLED) &&
- silc_server_config_is_primary_route(server->config)) {
+ silc_server_config_is_primary_route(server)) {
/* We'll wait for RESUMED packet */
protocol->state = SILC_PROTOCOL_STATE_END;
break;
/* 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, TRUE);
silc_server_update_clients_by_server(server, ctx->sock->user_data,
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));
case SILC_PROTOCOL_STATE_END:
{
- SilcIDListData idata;
SilcServerEntry router, backup_router;
/* We should have been received RESUMED packet from our primary
SILC_LOG_DEBUG(("********************************"));
SILC_LOG_DEBUG(("Received RESUMED packet"));
- /* We have now new primary router. All traffic goes there from now on. */
if (server->backup_router)
server->server_type = SILC_BACKUP_ROUTER;
+ /* We have now new primary router. All traffic goes there from now on. */
router = (SilcServerEntry)ctx->sock->user_data;
if (silc_server_backup_replaced_get(server, router->id,
&backup_router)) {
if (backup_router == 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));
- SILC_LOG_DEBUG(("Switching back to primary router %s",
- server->router->server_name));
- idata = (SilcIDListData)server->router;
- idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
+
+ /* 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 {
- SILC_LOG_INFO(("Resuming the use of router %s",
+ /* 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));
- SILC_LOG_DEBUG(("Resuming the use of router %s",
- router->server_name));
- idata = (SilcIDListData)router;
- idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
}
/* Update the client entries of the backup router to the new
router */
- silc_server_update_clients_by_server(server, backup_router,
- router, TRUE, FALSE);
- silc_server_update_servers_by_server(server, backup_router, router);
- silc_server_backup_replaced_del(server, backup_router);
+ silc_server_update_servers_by_server(server, backup_router, router,
+ FALSE);
+ silc_server_update_clients_by_server(server, NULL, router,
+ FALSE, 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 ?
silc_server_announce_channels(server, 0, router->connection);
}
+ /* Send notify about primary router going down to local operators */
+ SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
+ SILC_NOTIFY_TYPE_NONE,
+ ("%s resumed the use of primary router %s",
+ server->server_name,
+ server->router->server_name));
+
/* Protocol has ended, call the final callback */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
SilcIDCacheList list;
SilcIDCacheEntry id_cache;
- SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Backup resuming protocol is ended"));
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
if (sock->protocol == protocol) {
sock->protocol = NULL;
+ SILC_LOG_DEBUG(("***************1 %s:%d",
+ sock->ip, sock->port));
+
if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
}
if (sock->protocol == protocol) {
sock->protocol = NULL;
+ SILC_LOG_DEBUG(("***************2"));
+
if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
}