X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fserver_backup.c;h=3bde1802a3f00cb405bba34c5fa26c89f50b42f4;hp=db4725eeb3cb96979bba99454cfe733e9c8d9c8f;hb=0f72cea6b2ffd15c42c4829b520711cb003ac4b4;hpb=8ef48975ffcb3daee6167e9766c2b344c73152d1 diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index db4725ee..3bde1802 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -108,7 +108,8 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server, } SILC_LOG_DEBUG(("Backup router %s will replace %s", - backup_server->data.sconn->remote_host, ip, port)); + backup_server->data.sconn ? + backup_server->data.sconn->remote_host : "(me)", ip)); for (i = 0; i < server->backup->servers_count; i++) { if (!server->backup->servers[i].server) { @@ -551,10 +552,10 @@ void silc_server_backup_ping_reply(void *context, void *reply) /* The primary is not down, refuse to serve the server as primary */ SILC_LOG_DEBUG(("PING received, primary is up")); silc_server_backup_send_start_use(pc->server, pc->sock, TRUE); + silc_packet_free(pc->packet); } silc_packet_stream_unref(pc->sock); - silc_packet_free(pc->packet); silc_free(pc); } @@ -711,8 +712,17 @@ void silc_server_backup_resume_router(SilcServer server, if (type == SILC_SERVER_BACKUP_RESUMED && idata->conn_type == SILC_CONN_ROUTER && !router->backup && idata->status & SILC_IDLIST_STATUS_DISABLED) { - if (silc_server_backup_replaced_get(server, router->id, NULL)) + SilcServerEntry backup_router; + + if (silc_server_backup_replaced_get(server, router->id, &backup_router)) { + ctx = backup_router->backup_proto; + if (ctx->sock) + silc_packet_stream_unref(ctx->sock); router->backup = TRUE; + router->backup_proto = ctx; + ctx->sock = sock; + silc_packet_stream_ref(sock); + } } /* Call the resuming protocol if the protocol is active. */ @@ -776,6 +786,9 @@ SILC_TASK_CALLBACK(silc_server_backup_connected_again) SilcServer server = app_context; SilcServerConfigRouter *primary; + if (server->server_shutdown) + return; + primary = silc_server_config_get_primary_router(server); if (primary) { if (!silc_server_find_socket_by_host(server, SILC_CONN_ROUTER, @@ -802,7 +815,7 @@ void silc_server_backup_connected(SilcServer server, /* Try again */ silc_schedule_task_add_timeout(server->schedule, silc_server_backup_connected_again, - context, 0, 1); + context, 5, 0); return; } @@ -861,13 +874,10 @@ static void silc_server_backup_connect_primary(SilcServer server, return; } - /* Unref */ - silc_packet_stream_unref(backup_router); - - if (!router->backup) - return; - if (!server_entry->connection) + if (!router->backup || !server_entry->connection) { + silc_packet_stream_unref(backup_router); return; + } ctx = router->backup_proto; sock = server_entry->connection; @@ -891,10 +901,17 @@ static void silc_server_backup_connect_primary(SilcServer server, the primary router connection since it will send the subsequent packets in this protocol. We don't talk with backup router anymore. */ + if (ctx->sock) + silc_packet_stream_unref(ctx->sock); + ctx->sock = sock; + silc_packet_stream_ref(sock); server_entry->backup = TRUE; server_entry->backup_proto = ctx; router->backup = FALSE; router->backup_proto = NULL; + + /* Unref */ + silc_packet_stream_unref(backup_router); } /* Timeout callback used by the backup router to send the ENDING packet @@ -1146,7 +1163,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) if (sock == ctx->sock) continue; - send_to_backup: + server_entry = silc_packet_get_context(sock); server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; SILC_LOG_DEBUG(("Sending RESUMED to %s", server_entry->server_name)); @@ -1161,14 +1178,27 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) silc_server_packet_send(server, sock, SILC_PACKET_RESUME_ROUTER, 0, data, sizeof(data)); } - silc_packet_engine_free_streams_list(list); /* Now send the same packet to backup */ if (sock != ctx->sock) { sleep(1); sock = ctx->sock; - goto send_to_backup; + server_entry = silc_packet_get_context(sock); + server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; + + SILC_LOG_DEBUG(("Sending RESUMED to %s", server_entry->server_name)); + SILC_LOG_INFO(("Sending RESUMED to %s", server_entry->server_name)); + + /* This connection is performing this protocol too now */ + server_entry->backup = TRUE; + server_entry->backup_proto = ctx; + + data[0] = SILC_SERVER_BACKUP_RESUMED; + data[1] = 0; + silc_server_packet_send(server, sock, SILC_PACKET_RESUME_ROUTER, 0, + data, sizeof(data)); } + silc_packet_engine_free_streams_list(list); /* We are now resumed and are back as primary router in the cell. */ SILC_LOG_INFO(("We are now the primary router of our cell again")); @@ -1183,7 +1213,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) /* For us this is the end of this protocol. */ silc_schedule_task_add_timeout(server->schedule, silc_server_protocol_backup_done, - ctx->sock, 0, 1); + ctx, 0, 1); } break; @@ -1249,7 +1279,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) /* Protocol has ended, call the final callback */ silc_schedule_task_add_timeout(server->schedule, silc_server_protocol_backup_done, - ctx->sock, 0, 1); + ctx, 0, 1); } break; @@ -1257,7 +1287,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) /* Protocol has ended, call the final callback */ silc_schedule_task_add_timeout(server->schedule, silc_server_protocol_backup_done, - ctx->sock, 0, 1); + ctx, 0, 1); break; case 252: @@ -1266,7 +1296,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) ctx->received_failure = TRUE; silc_schedule_task_add_timeout(server->schedule, silc_server_protocol_backup_done, - ctx->sock, 0, 1); + ctx, 0, 1); break; default: @@ -1284,7 +1314,6 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) SilcServerEntry server_entry; SilcPacketStream sock; SilcBool error; - int i; silc_schedule_task_del_by_context(server->schedule, ctx); @@ -1341,6 +1370,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) proto_ctx->type = SILC_SERVER_BACKUP_START; proto_ctx->start = time(0); proto_ctx->initiator_restart = ctx->initiator_restart + 1; + silc_packet_stream_ref(sock); /* Start through scheduler */ silc_schedule_task_add_timeout(server->schedule, @@ -1364,6 +1394,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) silc_server_announce_channels(server, 0, sock); /* Announce WATCH list a little later */ + silc_packet_stream_ref(sock); silc_schedule_task_add_timeout(server->schedule, silc_server_backup_announce_watches, sock, 5, 0); @@ -1392,6 +1423,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) silc_server_announce_channels(server, 0, server->router->connection); /* Announce WATCH list a little later */ + silc_packet_stream_ref(server->router->connection); silc_schedule_task_add_timeout(server->schedule, silc_server_backup_announce_watches, server->router->connection, 4, 0); @@ -1409,14 +1441,17 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) FALSE); /* Check couple of times same START_USE just in case. */ + silc_packet_stream_ref(server->router->connection); silc_schedule_task_add_timeout(server->schedule, silc_server_backup_check_status, server->router->connection, 5, 1); + silc_packet_stream_ref(server->router->connection); silc_schedule_task_add_timeout(server->schedule, silc_server_backup_check_status, server->router->connection, 20, 1); + silc_packet_stream_ref(server->router->connection); silc_schedule_task_add_timeout(server->schedule, silc_server_backup_check_status, server->router->connection, @@ -1425,8 +1460,14 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) } } - if (ctx->sock) + if (ctx->sock) { + SilcServerEntry r = silc_packet_get_context(ctx->sock); + if (r) { + r->backup = FALSE; + r->backup_proto = NULL; + } silc_packet_stream_unref(ctx->sock); + } silc_free(ctx->sessions); silc_free(ctx); }