From: Pekka Riikonen Date: Wed, 11 Dec 2002 20:22:57 +0000 (+0000) Subject: Do not call final protocol callback for backup router proto X-Git-Tag: silc.client.0.9.11~39 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=6846cdb0bc129243ffbfc9700e9f0162c9ed01a5 Do not call final protocol callback for backup router proto when closing connection. Backup reconnects to router if resuming fails. --- diff --git a/CHANGES b/CHANGES index 348d2009..77566b3c 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,13 @@ Wed Dec 11 20:20:07 EET 2002 Pekka Riikonen that it is NULL is some odd case. Affected files are lib/silcutil/[unix/win32]/silc[unix/win32]sockconn.c. + * Do not call final protocol callback for backup router + resuming protocol when closing connection. It is closed + by timeout in case of error. Affected file silcd/server.c. + + * Backup reconnect to router if backup resuming protocol + failed. Affected file silcd/server_backup.c. + Wed Dec 11 10:01:26 CET 2002 Pekka Riikonen * Fixed double free in SKE library error hadling when signature diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 1e4f94ad..d7f33838 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -30,7 +30,6 @@ SILC_TASK_CALLBACK(silc_server_rehash_close_connection); SILC_TASK_CALLBACK(silc_server_connect_to_router_retry); SILC_TASK_CALLBACK(silc_server_connect_router); -SILC_TASK_CALLBACK(silc_server_connect_to_router); SILC_TASK_CALLBACK(silc_server_connect_to_router_second); SILC_TASK_CALLBACK(silc_server_connect_to_router_final); SILC_TASK_CALLBACK(silc_server_accept_new_connection); @@ -1005,7 +1004,7 @@ SILC_TASK_CALLBACK(silc_server_connect_router) server to do authentication and key exchange with our router - called from schedule. */ -SILC_TASK_CALLBACK(silc_server_connect_to_router) +SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router) { SilcServer server = (SilcServer)context; SilcServerConnection sconn; @@ -2240,7 +2239,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process) else silc_server_free_sock_user_data(server, sock, NULL); } else if (server->router_conn && server->router_conn->sock == sock && - !server->router && server->standalone) + !server->router && server->standalone) silc_schedule_task_add(server->schedule, 0, silc_server_connect_to_router, server, 1, 0, @@ -2962,7 +2961,8 @@ void silc_server_close_connection(SilcServer server, if (!sock->user_data) { /* If any protocol is active cancel its execution. It will call the final callback which will finalize the disconnection. */ - if (sock->protocol) { + if (sock->protocol && sock->protocol->protocol && + sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) { SILC_LOG_DEBUG(("Cancelling protocol, calling final callback")); silc_protocol_cancel(sock->protocol, server->schedule); sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; @@ -3319,7 +3319,8 @@ void silc_server_free_sock_user_data(SilcServer server, } /* If any protocol is active cancel its execution */ - if (sock->protocol) { + if (sock->protocol && sock->protocol->protocol && + sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) { SILC_LOG_DEBUG(("Cancelling protocol, calling final callback")); silc_protocol_cancel(sock->protocol, server->schedule); sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; @@ -3565,7 +3566,8 @@ SILC_TASK_CALLBACK(silc_server_timeout_remote) /* If we have protocol active we must assure that we call the protocol's final callback so that all the memory is freed. */ - if (sock->protocol) { + if (sock->protocol && sock->protocol->protocol && + sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) { protocol = sock->protocol->protocol->type; silc_protocol_cancel(sock->protocol, server->schedule); sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index b1e61509..548875f0 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -430,6 +430,17 @@ void silc_server_backup_send_dest(SilcServer server, } } +SILC_TASK_CALLBACK(silc_server_backup_timeout) +{ + SilcProtocol protocol = context; + SilcServer server = app_context; + + SILC_LOG_INFO(("Timeout occurred during backup resuming protocol")); + silc_protocol_cancel(protocol, server->schedule); + protocol->state = SILC_PROTOCOL_STATE_ERROR; + silc_protocol_execute_final(protocol, server->schedule); +} + /* Processes incoming RESUME_ROUTER packet. This can give the packet for processing to the protocol handler or allocate new protocol if start command is received. */ @@ -544,6 +555,10 @@ void silc_server_backup_resume_router(SilcServer server, &sock->protocol, proto_ctx, silc_server_protocol_backup_done); silc_protocol_execute(sock->protocol, server->schedule, 0, 0); + silc_schedule_task_add(server->schedule, sock->sock, + silc_server_backup_timeout, + sock->protocol, 30, 0, SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); } } @@ -619,6 +634,11 @@ SILC_TASK_CALLBACK(silc_server_backup_connected_later) &sock->protocol, proto_ctx, silc_server_protocol_backup_done); silc_protocol_execute(sock->protocol, server->schedule, 0, 0); + + silc_schedule_task_add(server->schedule, sock->sock, + silc_server_backup_timeout, + sock->protocol, 30, 0, SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); } /* Called when we've established connection back to our primary router @@ -1199,6 +1219,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) SilcIDCacheList list; SilcIDCacheEntry id_cache; + silc_schedule_task_del_by_context(server->schedule, protocol); + if (protocol->state == SILC_PROTOCOL_STATE_ERROR || protocol->state == SILC_PROTOCOL_STATE_FAILURE) { SILC_LOG_ERROR(("Error occurred during backup router resuming protcool")); @@ -1217,6 +1239,29 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) if (sock->protocol == protocol) { sock->protocol = NULL; + /* Backup closes connection and reconnects if error occurred */ + if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) { + if (protocol->state == SILC_PROTOCOL_STATE_ERROR || + protocol->state == SILC_PROTOCOL_STATE_FAILURE) { + server->backup_noswitch = TRUE; + server->server_type = SILC_BACKUP_ROUTER; + + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_server_close_connection(server, sock); + + silc_schedule_task_add(server->schedule, 0, + silc_server_connect_to_router, + server, 1, 0, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); + + if (!silc_idcache_list_next(list, &id_cache)) + break; + continue; + } + } + if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED) server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; } @@ -1237,6 +1282,29 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) if (sock->protocol == protocol) { sock->protocol = NULL; + /* Backup closes connection and reconnects if error occurred */ + if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) { + if (protocol->state == SILC_PROTOCOL_STATE_ERROR || + protocol->state == SILC_PROTOCOL_STATE_FAILURE) { + server->backup_noswitch = TRUE; + server->server_type = SILC_BACKUP_ROUTER; + + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_server_close_connection(server, sock); + + silc_schedule_task_add(server->schedule, 0, + silc_server_connect_to_router, + server, 1, 0, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); + + if (!silc_idcache_list_next(list, &id_cache)) + break; + continue; + } + } + if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED) server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; } @@ -1248,7 +1316,9 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) silc_idcache_list_free(list); } - SILC_LOG_INFO(("Backup resuming protocol ended successfully")); + if (protocol->state != SILC_PROTOCOL_STATE_ERROR && + protocol->state != SILC_PROTOCOL_STATE_FAILURE) + SILC_LOG_INFO(("Backup resuming protocol ended successfully")); if (ctx->sock->protocol) ctx->sock->protocol = NULL; diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index 406d4338..0f4e14b4 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -232,6 +232,7 @@ do { \ /* Prototypes */ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final); SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_callback); +SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router); void silc_server_watcher_list_destroy(void *key, void *context, void *user_context);