X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fserver.c;h=0c55b28d0e87f5c411bfdfe62069e4b15dd0deba;hp=c3359196fe887f7dfc30da1aeed9c6a8b751f15c;hb=ecb19b3983b3e74bc4aaa82277abd125c53c3623;hpb=382d15d447b7a95390decfa783836ae4fe255b3d diff --git a/apps/silcd/server.c b/apps/silcd/server.c index c3359196..0c55b28d 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -430,11 +430,7 @@ bool silc_server_init(SilcServer server) timeout. It expires as soon as the caller calls silc_server_run. This task performs authentication protocol and key exchange with our primary router. */ - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - (void *)server, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_server_create_connections(server); /* Add listener task to the scheduler. This task receives new connections to the server. This task remains on the queue until the end of the @@ -695,12 +691,8 @@ bool silc_server_rehash(SilcServer server) } } - /* Go through all configured routers after rehash */ - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - (void *)server, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + /* Create connections after rehash */ + silc_server_create_connections(server); /* Check whether our router status has changed */ if (newconfig->servers) { @@ -1047,7 +1039,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router) server->wait_backup = TRUE; if (ptr->initiator) { - /* Check whether we are connected to this host already */ + /* Check whether we are connecting or connected to this host already */ if (silc_server_num_sockets_by_remote(server, silc_net_is_ip(ptr->host) ? ptr->host : NULL, @@ -1057,6 +1049,15 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router) SILC_LOG_DEBUG(("We are already connected to this router")); continue; } + if (silc_server_num_sockets_by_remote(server, + silc_net_is_ip(ptr->host) ? + ptr->host : NULL, + silc_net_is_ip(ptr->host) ? + NULL : ptr->host, ptr->port, + SILC_SOCKET_TYPE_UNKNOWN)) { + SILC_LOG_DEBUG(("We are already connecting to this router")); + continue; + } /* Allocate connection object for hold connection specific stuff. */ sconn = silc_calloc(1, sizeof(*sconn)); @@ -2239,12 +2240,9 @@ 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) - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + !server->router && server->standalone) { + silc_server_create_connections(server); + } silc_server_close_connection(server, sock); return; @@ -2289,6 +2287,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process) if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) server->backup_noswitch = TRUE; + SILC_SET_DISCONNECTING(sock); if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); @@ -2433,6 +2432,7 @@ bool silc_server_packet_parse(SilcPacketParserContext *parser_context, if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) server->backup_noswitch = TRUE; + SILC_SET_DISCONNECTING(sock); if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); @@ -2501,10 +2501,15 @@ void silc_server_packet_parse_type(SilcServer server, message ? message : "")); silc_free(message); + /* Do not switch to backup in case of error */ + server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE); + /* Handle the disconnection from our end too */ + SILC_SET_DISCONNECTING(sock); if (sock->user_data && SILC_IS_LOCAL(sock->user_data)) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); + server->backup_noswitch = FALSE; } break; @@ -2931,6 +2936,7 @@ void silc_server_close_connection(SilcServer server, if (!server->sockets[sock->sock] && SILC_IS_DISCONNECTED(sock)) { silc_schedule_unset_listen_fd(server->schedule, sock->sock); silc_schedule_task_del_by_fd(server->schedule, sock->sock); + silc_net_close_connection(sock->sock); silc_schedule_task_add(server->schedule, sock->sock, silc_server_close_connection_final, (void *)sock, 0, 1, SILC_TASK_TIMEOUT, @@ -2950,8 +2956,6 @@ void silc_server_close_connection(SilcServer server, /* Unregister all tasks */ silc_schedule_task_del_by_fd(server->schedule, sock->sock); - /* Close the actual connection */ - silc_net_close_connection(sock->sock); server->sockets[sock->sock] = NULL; /* If sock->user_data is NULL then we'll check for active protocols @@ -2971,6 +2975,9 @@ void silc_server_close_connection(SilcServer server, } } + /* Close the actual connection */ + silc_net_close_connection(sock->sock); + /* We won't listen for this connection anymore */ silc_schedule_unset_listen_fd(server->schedule, sock->sock); @@ -2993,8 +3000,13 @@ void silc_server_disconnect_remote(SilcServer server, char *cp; int len; - if (!sock || SILC_IS_DISCONNECTED(sock)) + if (!sock) + return; + + if (SILC_IS_DISCONNECTED(sock)) { + silc_server_close_connection(server, sock); return; + } memset(buf, 0, sizeof(buf)); va_start(ap, status); @@ -3152,12 +3164,7 @@ void silc_server_free_sock_user_data(SilcServer server, if (server->router == user_data) { /* Check whether we have a backup router connection */ if (!backup_router || backup_router == user_data) { - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); - + silc_server_create_connections(server); server->id_entry->router = NULL; server->router = NULL; server->standalone = TRUE; @@ -3205,15 +3212,12 @@ void silc_server_free_sock_user_data(SilcServer server, } else if (server->server_type == SILC_SERVER && sock->type == SILC_SOCKET_TYPE_ROUTER) { /* Reconnect to the router (backup) */ - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_server_create_connections(server); } - SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE, - ("Server %s signoff", user_data->server_name)); + if (user_data->server_name) + SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE, + ("Server %s signoff", user_data->server_name)); if (!backup_router) { /* Remove all servers that are originated from this server, and @@ -3851,7 +3855,12 @@ bool silc_server_create_channel_key(SilcServer server, /* Generate HMAC key from the channel key data and set it */ if (!channel->hmac) - silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac); + if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) { + memset(channel->key, 0, channel->key_len / 8); + silc_free(channel->key); + channel->channel_key = NULL; + return FALSE; + } silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash); silc_hmac_set_key(channel->hmac, hash, silc_hash_len(silc_hmac_get_hash(channel->hmac))); @@ -3962,7 +3971,12 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, /* Generate HMAC key from the channel key data and set it */ if (!channel->hmac) - silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac); + if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) { + memset(channel->key, 0, channel->key_len / 8); + silc_free(channel->key); + channel->channel_key = NULL; + return FALSE; + } silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash); silc_hmac_set_key(channel->hmac, hash, silc_hash_len(silc_hmac_get_hash(channel->hmac))); @@ -5062,8 +5076,8 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final) if (protocol->state == SILC_PROTOCOL_STATE_ERROR || protocol->state == SILC_PROTOCOL_STATE_FAILURE) { /* Error occured during protocol */ - SILC_LOG_ERROR(("Error occurred during rekey protocol with - %s (%s)", sock->hostname, sock->ip)); + SILC_LOG_ERROR(("Error occurred during rekey protocol with " + "%s (%s)", sock->hostname, sock->ip)); silc_protocol_cancel(protocol, server->schedule); silc_protocol_free(protocol); sock->protocol = NULL; @@ -5072,6 +5086,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final) if (ctx->ske) silc_ske_free(ctx->ske); silc_free(ctx); + + /* Reconnect */ + SILC_SET_DISCONNECTING(sock); + server->backup_noswitch = TRUE; + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_server_close_connection(server, sock); + silc_server_create_connections(server); return; }