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
}
}
- /* 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) {
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,
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));
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;
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);
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);
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;
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,
/* 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
}
}
+ /* 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);
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);
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;
} 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
/* 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)));
/* 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)));
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;
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;
}