From 33b943ac6034b92fcc5c09802f9fe9add12a51c9 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 8 Oct 2001 19:30:19 +0000 Subject: [PATCH] updates. --- CHANGES | 12 ++ apps/silcd/packet_receive.c | 8 +- apps/silcd/server.c | 81 +++++++---- apps/silcd/server.h | 9 +- apps/silcd/server_backup.c | 249 +++++++++++++++++++++++++++------- apps/silcd/server_backup.h | 14 +- apps/silcd/server_internal.h | 1 - apps/silcd/server_util.c | 17 ++- apps/silcd/server_util.h | 8 +- lib/silccore/silcpacket.c | 2 +- lib/silccore/silcpacket.h | 44 +----- lib/silcsftp/sftp_client.c | 1 + lib/silcsftp/sftp_fs_memory.c | 1 + lib/silcsftp/sftp_server.c | 1 + lib/silcsftp/sftp_util.c | 1 + 15 files changed, 308 insertions(+), 141 deletions(-) diff --git a/CHANGES b/CHANGES index 381095cc..bc91df7a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,15 @@ +Mon Oct 8 16:47:42 EDT 2001 Pekka Riikonen + + * Added --disable-asm configuration option. Affected files + configure.in.pre, lib/silcmath/mpi/configure.in. A patch + by salo. + + * Implemented the backup resuming protocol that is used to + resume the primary router position in the cell after the + primary router comes back online. Affected files + silcd/server_backup.[ch], silcd/server, silcd/packet_receive.c, + and silcd/server_util.[ch]. + Sun Oct 7 12:29:25 EDT 2001 Pekka Riikonen * Sleep two (2) seconds after sending QUIT command to server. diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 0bb1ddd3..9d473061 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1700,7 +1700,7 @@ SilcServerEntry silc_server_new_server(SilcServer server, SilcBuffer packet = silc_buffer_alloc(2); silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet)); silc_buffer_format(packet, - SILC_STR_UI_CHAR(20), + SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED), SILC_STR_UI_CHAR(0), SILC_STR_END); silc_server_packet_send(server, sock, @@ -1997,6 +1997,7 @@ void silc_server_new_channel(SilcServer server, unsigned char *id; uint32 id_len; uint32 mode; + SilcServerEntry server_entry; SilcChannelEntry channel; SILC_LOG_DEBUG(("Processing New Channel")); @@ -2024,6 +2025,8 @@ void silc_server_new_channel(SilcServer server, id = silc_channel_get_id(payload, &id_len); + server_entry = (SilcServerEntry)sock->user_data; + if (sock->type == SILC_SOCKET_TYPE_ROUTER) { /* Add the channel to global list as it is coming from router. It cannot be our own channel as it is coming from router. */ @@ -2066,7 +2069,8 @@ void silc_server_new_channel(SilcServer server, on the router's IP address. Check whether the ID is based in our IP and if it is not then create a new ID and enforce the server to switch the ID. */ - if (!SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) { + if (server_entry->server_type != SILC_BACKUP_ROUTER && + !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) { SilcChannelID *tmp; SILC_LOG_DEBUG(("Forcing the server to change Channel ID")); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 2e85203d..05323399 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -912,20 +912,23 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) server->id_entry->router = id_entry; server->router = id_entry; server->standalone = FALSE; - } - /* If we are router then announce our possible servers. */ - if (server->server_type == SILC_ROUTER) - silc_server_announce_servers(server, FALSE, 0); + /* If we are router then announce our possible servers. */ + if (server->server_type == SILC_ROUTER) + silc_server_announce_servers(server, FALSE, 0, + server->router->connection); - /* Announce our clients and channels to the router */ - silc_server_announce_clients(server, 0); - silc_server_announce_channels(server, 0); + /* 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); + } } else { /* Add this server to be our backup router */ silc_server_backup_add(server, id_entry, FALSE); } + sock->protocol = NULL; + /* Call the completion callback to indicate that we've connected to the router */ if (sconn->callback) @@ -939,13 +942,14 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) } /* Free the protocol object */ + if (sock->protocol == protocol) + sock->protocol = NULL; silc_protocol_free(protocol); if (ctx->packet) silc_packet_context_free(ctx->packet); if (ctx->ske) silc_ske_free(ctx->ske); silc_free(ctx); - sock->protocol = NULL; } /* Host lookup callbcak that is called after the incoming connection's @@ -1343,7 +1347,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) /* Change it back to SERVER type since that's what it really is. */ if (conn->backup_local) { ctx->conn_type = SILC_SOCKET_TYPE_SERVER; - new_server->server_type = SILC_SOCKET_TYPE_SERVER; + new_server->server_type = SILC_BACKUP_ROUTER; } } @@ -1591,10 +1595,6 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) goto out; } - /* If entry is disabled ignore what we got. */ - if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED) - goto out; - if (ret == 0) { /* Parse the packet. Packet type is returned. */ ret = silc_packet_parse(packet); @@ -1604,6 +1604,11 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) ret = silc_packet_parse_special(packet); } + /* If entry is disabled ignore what we got. */ + if (ret != SILC_PACKET_RESUME_ROUTER && + idata && idata->status & SILC_IDLIST_STATUS_DISABLED) + goto out; + if (ret == SILC_PACKET_NONE) goto out; @@ -2360,13 +2365,12 @@ void silc_server_free_sock_user_data(SilcServer server, router. This also removes the clients that *really* was owned by the primary router and went down with the router. */ silc_server_update_clients_by_server(server, user_data, backup_router, - TRUE); + TRUE, TRUE); } /* Free the server entry */ silc_server_backup_del(server, user_data); - if (user_data->id) - silc_server_backup_replaced_del(server, user_data->id); + silc_server_backup_replaced_del(server, user_data); silc_idlist_del_data(user_data); silc_idlist_del_server(server->local_list, user_data); server->stat.my_servers--; @@ -2378,11 +2382,25 @@ void silc_server_free_sock_user_data(SilcServer server, /* Announce all of our stuff that was created about 5 minutes ago. The backup router knows all the other stuff already. */ if (server->server_type == SILC_ROUTER) - silc_server_announce_servers(server, FALSE, time(0) - 300); + silc_server_announce_servers(server, FALSE, 0, + server->router->connection); /* Announce our clients and channels to the router */ - silc_server_announce_clients(server, time(0) - 300); - silc_server_announce_channels(server, time(0) - 300); + silc_server_announce_clients(server, 0, + server->router->connection); + silc_server_announce_channels(server, 0, + server->router->connection); +#if 0 + if (server->server_type == SILC_ROUTER) + silc_server_announce_servers(server, FALSE, time(0) - 300, + server->router->connection); + + /* Announce our clients and channels to the router */ + silc_server_announce_clients(server, time(0) - 300, + server->router->connection); + silc_server_announce_channels(server, time(0) - 300, + server->router->connection); +#endif } break; } @@ -3076,20 +3094,21 @@ static void silc_server_announce_get_servers(SilcServer server, will be announced. */ void silc_server_announce_servers(SilcServer server, bool global, - unsigned long creation_time) + unsigned long creation_time, + SilcSocketConnection remote) { SilcBuffer servers = NULL; SILC_LOG_DEBUG(("Announcing servers")); /* Get servers in local list */ - silc_server_announce_get_servers(server, server->router, + silc_server_announce_get_servers(server, remote->user_data, server->local_list, &servers, creation_time); if (global) /* Get servers in global list */ - silc_server_announce_get_servers(server, server->router, + silc_server_announce_get_servers(server, remote->user_data, server->global_list, &servers, creation_time); @@ -3098,7 +3117,7 @@ void silc_server_announce_servers(SilcServer server, bool global, SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len); /* Send the packet */ - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, remote, SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST, servers->data, servers->len, TRUE); @@ -3157,7 +3176,8 @@ static void silc_server_announce_get_clients(SilcServer server, announced. */ void silc_server_announce_clients(SilcServer server, - unsigned long creation_time) + unsigned long creation_time, + SilcSocketConnection remote) { SilcBuffer clients = NULL; @@ -3177,7 +3197,7 @@ void silc_server_announce_clients(SilcServer server, SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len); /* Send the packet */ - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, remote, SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST, clients->data, clients->len, TRUE); @@ -3352,7 +3372,8 @@ void silc_server_announce_get_channels(SilcServer server, was provided. */ void silc_server_announce_channels(SilcServer server, - unsigned long creation_time) + unsigned long creation_time, + SilcSocketConnection remote) { SilcBuffer channels = NULL, channel_users = NULL; SilcBuffer *channel_users_modes = NULL; @@ -3380,7 +3401,7 @@ void silc_server_announce_channels(SilcServer server, SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len); /* Send the packet */ - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, remote, SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST, channels->data, channels->len, FALSE); @@ -3394,7 +3415,7 @@ void silc_server_announce_channels(SilcServer server, channel_users->len); /* Send the packet */ - silc_server_packet_send(server, server->router->connection, + silc_server_packet_send(server, remote, SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, channel_users->data, channel_users->len, FALSE); @@ -3411,7 +3432,7 @@ void silc_server_announce_channels(SilcServer server, channel_users_modes[i]->head); SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data, channel_users_modes[i]->len); - silc_server_packet_send_dest(server, server->router->connection, + silc_server_packet_send_dest(server, remote, SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, channel_ids[i], SILC_ID_CHANNEL, channel_users_modes[i]->data, @@ -3795,7 +3816,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final) SILC_LOG_DEBUG(("Start")); if (protocol->state == SILC_PROTOCOL_STATE_ERROR || - protocol->state == SILC_PROTOCOL_STATE_FAILURE) { + protocol->state == SILC_PROTOCOL_STATE_FAILURE) { /* Error occured during protocol */ SILC_LOG_ERROR(("Error occurred during rekey protocol")); silc_protocol_cancel(protocol, server->schedule); diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 495bd263..d2abd2c9 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -187,11 +187,14 @@ void silc_server_announce_get_channels(SilcServer server, SilcChannelID ***channel_ids, unsigned long creation_time); void silc_server_announce_servers(SilcServer server, bool global, - unsigned long creation_time); + unsigned long creation_time, + SilcSocketConnection remote); void silc_server_announce_clients(SilcServer server, - unsigned long creationg_time); + unsigned long creation_time, + SilcSocketConnection remote); void silc_server_announce_channels(SilcServer server, - unsigned long creationg_time); + unsigned long creation_time, + SilcSocketConnection remote); void silc_server_get_users_on_channel(SilcServer server, SilcChannelEntry channel, SilcBuffer *user_list, diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index a3aaf17e..b70bd095 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -16,6 +16,7 @@ GNU General Public License for more details. */ +/* $Id$ */ #include "serverincludes.h" #include "server_internal.h" @@ -62,15 +63,6 @@ typedef struct { long start; } *SilcServerBackupProtocolContext; -/* Backup resuming protocol types */ -#define SILC_SERVER_BACKUP_START 1 -#define SILC_SERVER_BACKUP_START_GLOBAL 2 -#define SILC_SERVER_BACKUP_CONNECTED 3 -#define SILC_SERVER_BACKUP_ENDING 4 -#define SILC_SERVER_BACKUP_RESUMED 5 -#define SILC_SERVER_BACKUP_RESUMED_GLOBAL 6 -#define SILC_SERVER_BACKUP_REPLACED 20 - /* Sets the `backup_server' to be one of our backup router. This can be called multiple times to set multiple backup routers. If `local' is TRUE then the `backup_server' is in the local cell, if FALSE it is @@ -81,10 +73,8 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server, { int i; - if (!server->backup) { + if (!server->backup) server->backup = silc_calloc(1, sizeof(*server->backup)); - server->backup->servers_count++; - } for (i = 0; i < server->backup->servers_count; i++) { if (!server->backup->servers[i].server) { @@ -155,16 +145,17 @@ void silc_server_backup_replaced_add(SilcServer server, int i; SilcServerBackupReplaced *r = silc_calloc(1, sizeof(*r));; - if (!server->backup) { + if (!server->backup) server->backup = silc_calloc(1, sizeof(*server->backup)); - server->backup->servers_count++; - } if (!server->backup->replaced) { server->backup->replaced = silc_calloc(1, sizeof(*server->backup->replaced)); server->backup->replaced_count = 1; } + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Replaced added")); + memcpy(&r->ip, &server_id->ip, sizeof(server_id->ip)); //r->port = server_id->port; r->server = server_entry; @@ -195,39 +186,44 @@ bool silc_server_backup_replaced_get(SilcServer server, { int i; + SILC_LOG_DEBUG(("***********************************************")); + if (!server->backup || !server->backup->replaced) return FALSE; - for (i = 0; i < server->backup->servers_count; i++) { + for (i = 0; i < server->backup->replaced_count; i++) { if (!server->backup->replaced[i]) continue; + SILC_LOG_HEXDUMP(("IP"), server_id->ip.data, server_id->ip.data_len); + SILC_LOG_HEXDUMP(("IP"), server->backup->replaced[i]->ip.data, + server->backup->replaced[i]->ip.data_len); if (!memcmp(&server->backup->replaced[i]->ip, &server_id->ip, sizeof(server_id->ip))) { if (server_entry) *server_entry = server->backup->replaced[i]->server; + SILC_LOG_DEBUG(("REPLACED")); return TRUE; } } + SILC_LOG_DEBUG(("NOT REPLACED")); return FALSE; } -/* Deletes the IP address and port from the `server_id' from being replaced - by an backup router. */ +/* Deletes a replaced host by the set `server_entry. */ void silc_server_backup_replaced_del(SilcServer server, - SilcServerID *server_id) + SilcServerEntry server_entry) { int i; if (!server->backup || !server->backup->replaced) return; - for (i = 0; i < server->backup->servers_count; i++) { + for (i = 0; i < server->backup->replaced_count; i++) { if (!server->backup->replaced[i]) continue; - if (!memcmp(&server->backup->replaced[i]->ip, &server_id->ip, - sizeof(server_id->ip))) { + if (server->backup->replaced[i]->server == server_entry) { silc_free(server->backup->replaced[i]); server->backup->replaced[i] = NULL; return; @@ -402,12 +398,21 @@ void silc_server_backup_resume_router(SilcServer server, ctx->type = type; - for (i = 0; i < ctx->sessions_count; i++) { - if (session == ctx->sessions[i].session) { - ctx->session = session; - silc_protocol_execute(sock->protocol, server->schedule, 0, 0); - return; + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Continuing protocol, type %d", type)); + + if (type != SILC_SERVER_BACKUP_RESUMED && + type != SILC_SERVER_BACKUP_RESUMED_GLOBAL) { + for (i = 0; i < ctx->sessions_count; i++) { + if (session == ctx->sessions[i].session) { + ctx->session = session; + silc_protocol_execute(sock->protocol, server->schedule, 0, 0); + return; + } } + } else { + silc_protocol_execute(sock->protocol, server->schedule, 0, 0); + return; } SILC_LOG_DEBUG(("Bad resume router packet")); @@ -473,7 +478,7 @@ SILC_TASK_CALLBACK(silc_server_backup_connect_to_router) if (sock < 0) { silc_schedule_task_add(server->schedule, 0, silc_server_backup_connect_to_router, - context, 0, 2, SILC_TASK_TIMEOUT, + context, 2, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); return; } @@ -563,6 +568,9 @@ static void silc_server_backup_connect_primary(SilcServer server, (SilcServerBackupProtocolContext)backup_router->protocol->context; SilcBuffer buffer; + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Sending CONNECTED packet, session %d", ctx->session)); + /* Send the CONNECTED packet back to the backup router. */ buffer = silc_buffer_alloc(2); silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); @@ -575,6 +583,10 @@ static void silc_server_backup_connect_primary(SilcServer server, buffer->data, buffer->len, FALSE); silc_buffer_free(buffer); + /* The primary connection is disabled until it sends the RESUMED packet + to us. */ + idata->status |= SILC_IDLIST_STATUS_DISABLED; + /* Move this protocol context from this backup router connection to the primary router connection since it will send the subsequent packets in this protocol. We don't talk with backup router @@ -582,10 +594,6 @@ static void silc_server_backup_connect_primary(SilcServer server, sock->protocol = backup_router->protocol; ctx->sock = (SilcSocketConnection)server_entry->connection; backup_router->protocol = NULL; - - /* The primary connection is disabled until it sends the RESUMED packet - to us. */ - idata->status |= SILC_IDLIST_STATUS_DISABLED; } /* Resume protocol with RESUME_ROUTER packet: @@ -647,7 +655,7 @@ static void silc_server_backup_connect_primary(SilcServer server, SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) { - SilcProtocol protocol = (SilcProtocol)protocol; + SilcProtocol protocol = (SilcProtocol)context; SilcServerBackupProtocolContext ctx = protocol->context; SilcServer server = ctx->server; SilcBuffer packet; @@ -671,6 +679,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) packet = silc_buffer_alloc(2); silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet)); + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Sending START packets")); + /* Send the START packet to primary router and normal servers. */ if (silc_idcache_get_all(server->local_list->servers, &list)) { if (silc_idcache_list_first(list, &id_cache)) { @@ -691,6 +702,13 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) ctx->sessions[ctx->sessions_count].connected = FALSE; ctx->sessions[ctx->sessions_count].server_entry = server_entry; + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("START 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 @@ -709,14 +727,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) silc_idcache_list_free(list); } - /* Now, announce all of our information to the primary router */ - if (server->server_type == SILC_ROUTER) - silc_server_announce_servers(server, FALSE, 0); - silc_server_announce_clients(server, 0); - silc_server_announce_channels(server, 0); - 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); + silc_server_announce_clients(server, 0, ctx->sock); + silc_server_announce_channels(server, 0, ctx->sock); + protocol->state++; } else { /* Responder of the protocol. */ @@ -729,17 +747,50 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) break; } + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Received START packet, reconnecting to router")); + /* 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); - if (primary) + if (primary) { silc_server_backup_reconnect(server, primary->host, primary->port, silc_server_backup_connect_primary, ctx->sock); + if (server->server_type == SILC_ROUTER && + (!server->router || + server->router->data.status & SILC_IDLIST_STATUS_DISABLED)) + protocol->state++; + else + protocol->state = SILC_PROTOCOL_STATE_END; + + } else { + /* Nowhere to connect just return the CONNECTED packet */ + + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Sending CONNECTED packet, session %d", ctx->session)); + + /* Send the CONNECTED packet back to the backup 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_CONNECTED), + 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++; + } - protocol->state++; + ctx->sessions = silc_realloc(ctx->sessions, + sizeof(*ctx->sessions) * + (ctx->sessions_count + 1)); + ctx->sessions[ctx->sessions_count].session = ctx->session; + ctx->sessions_count++; } break; @@ -753,17 +804,28 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) break; } + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Received CONNECTED packet, session %d", ctx->session)); + for (i = 0; i < ctx->sessions_count; i++) { if (ctx->sessions[i].session == ctx->session) { ctx->sessions[i].connected = TRUE; + break; } } for (i = 0; i < ctx->sessions_count; i++) { if (!ctx->sessions[i].connected) - break; + return; } + 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); @@ -787,17 +849,27 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) break; } + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("Received ENDING packet, sending RESUMED packets")); + /* This state is received by the primary router but also servers and perhaps other routers so check that if we are the primary router of the cell then start sending RESUMED packets. If we are normal server or one of those other routers then procede to next state. */ - if (!(server->router->data.status & SILC_IDLIST_STATUS_DISABLED)) { + if (server->router && + !(server->router->data.status & SILC_IDLIST_STATUS_DISABLED) && + silc_server_config_is_primary_route(server->config)) { /* We'll wait for RESUMED packet */ protocol->state = SILC_PROTOCOL_STATE_END; break; } + /* Switch announced informations to our entry instead of using the + backup router. */ + silc_server_update_clients_by_server(server, ctx->sock->user_data, + server->id_entry, TRUE, FALSE); + packet = silc_buffer_alloc(2); silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet)); @@ -814,11 +886,17 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) continue; } + SILC_LOG_DEBUG(("********************************")); + SILC_LOG_DEBUG(("RESUMED packet")); + + /* 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; - packet->data[1] = ctx->sessions_count; silc_server_packet_send(server, server_entry->connection, SILC_PACKET_RESUME_ROUTER, 0, packet->data, packet->len, FALSE); @@ -855,6 +933,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) break; } + 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; @@ -866,21 +947,47 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) if (backup_router == server->router) { server->id_entry->router = ctx->sock->user_data; server->router = ctx->sock->user_data; + 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)); + 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, + backup_router->server_type != SILC_ROUTER ? + TRUE : FALSE); } /* Announce all of our information to the new primary router. We announce all that was updated after the protocol was started since the router knows all the older stuff. */ if (server->server_type == SILC_ROUTER) - silc_server_announce_servers(server, FALSE, ctx->start - 60); + silc_server_announce_servers(server, FALSE, 0, + server->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); +#if 0 + if (server->server_type == SILC_ROUTER) + silc_server_announce_servers(server, FALSE, ctx->start - 60, + server->router->connection); /* Announce our clients and channels to the router */ - silc_server_announce_clients(server, ctx->start - 60); - silc_server_announce_channels(server, ctx->start - 60); + silc_server_announce_clients(server, ctx->start - 60, + server->router->connection); + silc_server_announce_channels(server, ctx->start - 60, + server->router->connection); +#endif } /* Protocol has ended, call the final callback */ @@ -892,9 +999,19 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) break; case SILC_PROTOCOL_STATE_ERROR: + /* Protocol has ended, call the final callback */ + if (protocol->final_callback) + silc_protocol_execute_final(protocol, server->schedule); + else + silc_protocol_free(protocol); break; case SILC_PROTOCOL_STATE_FAILURE: + /* Protocol has ended, call the final callback */ + if (protocol->final_callback) + silc_protocol_execute_final(protocol, server->schedule); + else + silc_protocol_free(protocol); break; case SILC_PROTOCOL_STATE_UNKNOWN: @@ -904,5 +1021,41 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) SILC_TASK_CALLBACK(silc_server_protocol_backup_done) { + SilcProtocol protocol = (SilcProtocol)context; + SilcServerBackupProtocolContext ctx = protocol->context; + SilcServer server = ctx->server; + SilcServerEntry server_entry; + SilcSocketConnection sock; + SilcIDCacheList list; + SilcIDCacheEntry id_cache; + + SILC_LOG_DEBUG(("Start")); + + if (protocol->state == SILC_PROTOCOL_STATE_ERROR || + protocol->state == SILC_PROTOCOL_STATE_FAILURE) { + SILC_LOG_ERROR(("Error occurred during backup router resuming protcool")); + } + + 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) + sock->protocol = NULL; + + 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); + silc_free(ctx->sessions); + silc_free(ctx); } diff --git a/apps/silcd/server_backup.h b/apps/silcd/server_backup.h index 25fe49db..42df86e2 100644 --- a/apps/silcd/server_backup.h +++ b/apps/silcd/server_backup.h @@ -20,6 +20,15 @@ #ifndef SERVER_BACKUP_H #define SERVER_BACKUP_H +/* Backup resuming protocol types */ +#define SILC_SERVER_BACKUP_START 1 +#define SILC_SERVER_BACKUP_START_GLOBAL 2 +#define SILC_SERVER_BACKUP_CONNECTED 3 +#define SILC_SERVER_BACKUP_ENDING 4 +#define SILC_SERVER_BACKUP_RESUMED 5 +#define SILC_SERVER_BACKUP_RESUMED_GLOBAL 6 +#define SILC_SERVER_BACKUP_REPLACED 20 + /* Adds the `backup_server' to be one of our backup router. This can be called multiple times to set multiple backup routers. If `local' is TRUE then the `backup_server' is in the local cell, if FALSE it is @@ -53,10 +62,9 @@ bool silc_server_backup_replaced_get(SilcServer server, SilcServerID *server_id, SilcServerEntry *server_entry); -/* Deletes the IP address and port from the `server_id' from being replaced - by an backup router. */ +/* Deletes a replaced host by the set `server_entry. */ void silc_server_backup_replaced_del(SilcServer server, - SilcServerID *server_id); + SilcServerEntry server_entry); /* Broadcast the received packet indicated by `packet' to all of our backup routers. All router wide information is passed using broadcast packets. diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index 9f51174a..5cd0241e 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -73,7 +73,6 @@ struct SilcServerStruct { does not have connection to network. */ bool listenning; /* TRUE if server is listenning for incoming connections. */ - SilcServerEntry id_entry; /* Server's own ID entry */ SilcServerEntry router; /* Pointer to the primary router */ unsigned long router_connect; /* Time when router was connected */ diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 398dc52e..d4b035f8 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -365,13 +365,15 @@ silc_server_update_clients_by_real_server(SilcServer server, `from' and which are originated from a server that we have connection to, when we've acting as backup router. If it is FALSE the `to' will be the new source. This function also removes the clients that are - *really* originated from `from'. These are clients that the `from' - owns, and not just clients that are behind the `from'. */ + *really* originated from `from' if `remove_from' is TRUE. These are + clients that the `from' owns, and not just clients that are behind + the `from'. */ void silc_server_update_clients_by_server(SilcServer server, SilcServerEntry from, SilcServerEntry to, - bool resolve_real_server) + bool resolve_real_server, + bool remove_from) { SilcIDCacheList list = NULL; SilcIDCacheEntry id_cache = NULL; @@ -457,10 +459,11 @@ void silc_server_update_clients_by_server(SilcServer server, silc_idcache_list_free(list); } - /* Now remove the clients that are still marked as orignated from the - `from'. These are the clients that really was owned by the `from' and - not just exist behind the `from'. */ - silc_server_remove_clients_by_server(server, from, TRUE); + if (remove_from) + /* Now remove the clients that are still marked as orignated from the + `from'. These are the clients that really was owned by the `from' and + not just exist behind the `from'. */ + silc_server_remove_clients_by_server(server, from, TRUE); } /* Checks whether given channel has global users. If it does this returns diff --git a/apps/silcd/server_util.h b/apps/silcd/server_util.h index 283864f3..080f9600 100644 --- a/apps/silcd/server_util.h +++ b/apps/silcd/server_util.h @@ -35,12 +35,14 @@ bool silc_server_remove_clients_by_server(SilcServer server, `from' and which are originated from a server that we have connection to, when we've acting as backup router. If it is FALSE the `to' will be the new source. This function also removes the clients that are - *really* originated from `from'. These are clients that the `from' - owns, and not just clients that are behind the `from'. */ + *really* originated from `from' if `remove_from' is TRUE. These are + clients that the `from' owns, and not just clients that are behind + the `from'. */ void silc_server_update_clients_by_server(SilcServer server, SilcServerEntry from, SilcServerEntry to, - bool resolve_real_server); + bool resolve_real_server, + bool remove_from); /* Checks whether given channel has global users. If it does this returns TRUE and FALSE if there is only locally connected clients on the channel. */ diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 5c8b5157..ec26ab1d 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -671,7 +671,7 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx) /* Allocate packet context */ -SilcPacketContext *silc_packet_context_alloc() +SilcPacketContext *silc_packet_context_alloc(void) { SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx)); ctx->users++; diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index 1d0338f7..a7d5c3ec 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -366,23 +366,6 @@ do { \ /* Prototypes */ -/****f* silccore/SilcPacketAPI/silc_packet_write - * - * SYNOPSIS - * - * int silc_packet_write(int sock, SilcBuffer src); - * - * DESCRIPTION - * - * Writes data from encrypted buffer to the socket connection. If the - * data cannot be written at once, it will be written later with a timeout. - * The data is written from the data section of the buffer, not from head - * or tail section. This automatically pulls the data section towards end - * after writing the data. - * - ***/ -int silc_packet_write(int sock, SilcBuffer src); - /****f* silccore/SilcPacketAPI/silc_packet_send * * SYNOPSIS @@ -499,31 +482,6 @@ void silc_packet_send_prepare(SilcSocketConnection sock, uint32 padlen, uint32 data_len); -/****f* silccore/SilcPacketAPI/silc_packet_read - * - * SYNOPSIS - * - * int silc_packet_read(int fd, SilcSocketConnection sock); - * - * DESCRIPTION - * - * Reads data from the socket connection into the incoming data buffer. - * However, this does not parse the packet, it only reads some amount from - * the network. If there are more data available that can be read at a time - * the rest of the data will be read later with a timeout and only after - * that the packet is ready to be parsed. - * - * The destination buffer sent as argument must be initialized before - * calling this function, and, the data section and the start of the tail - * section must be same. Ie. we add the read data to the tail section of - * the buffer hence the data section is the start of the buffer. - * - * This returns amount of bytes read or -1 on error or -2 on case where - * all of the data could not be read at once. - * - ***/ -int silc_packet_read(int fd, SilcSocketConnection sock); - /****f* silccore/SilcPacketAPI/silc_packet_receive * * SYNOPSIS @@ -644,7 +602,7 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx); * silc_packet_context_free function. * ***/ -SilcPacketContext *silc_packet_context_alloc(); +SilcPacketContext *silc_packet_context_alloc(void); /****f* silccore/SilcPacketAPI/silc_packet_context_dup * diff --git a/lib/silcsftp/sftp_client.c b/lib/silcsftp/sftp_client.c index 6835e626..29ee2076 100644 --- a/lib/silcsftp/sftp_client.c +++ b/lib/silcsftp/sftp_client.c @@ -16,6 +16,7 @@ GNU General Public License for more details. */ +/* $Id$ */ #include "silcincludes.h" #include "silcsftp.h" diff --git a/lib/silcsftp/sftp_fs_memory.c b/lib/silcsftp/sftp_fs_memory.c index 135810f1..9aac4970 100644 --- a/lib/silcsftp/sftp_fs_memory.c +++ b/lib/silcsftp/sftp_fs_memory.c @@ -16,6 +16,7 @@ GNU General Public License for more details. */ +/* $Id$ */ /* XXX TODO Win32 support */ #include "silcincludes.h" diff --git a/lib/silcsftp/sftp_server.c b/lib/silcsftp/sftp_server.c index 2286457f..d0030a0c 100644 --- a/lib/silcsftp/sftp_server.c +++ b/lib/silcsftp/sftp_server.c @@ -16,6 +16,7 @@ GNU General Public License for more details. */ +/* $Id$ */ #include "silcincludes.h" #include "silcsftp.h" diff --git a/lib/silcsftp/sftp_util.c b/lib/silcsftp/sftp_util.c index 349f8a0f..eb4652ac 100644 --- a/lib/silcsftp/sftp_util.c +++ b/lib/silcsftp/sftp_util.c @@ -16,6 +16,7 @@ GNU General Public License for more details. */ +/* $Id$ */ #include "silcincludes.h" #include "silcsftp.h" -- 2.24.0