silc_dlist_uninit(server->sim);
#endif
+ silc_server_config_unref(&server->config_ref);
if (server->rng)
silc_rng_free(server->rng);
if (server->pkcs)
silc_pkcs_free(server->pkcs);
+ if (server->public_key)
+ silc_pkcs_public_key_free(server->public_key);
+ if (server->private_key)
+ silc_pkcs_private_key_free(server->private_key);
if (server->pending_commands)
silc_dlist_uninit(server->pending_commands);
if (server->id_entry)
}
}
+/* Opens a listening port.
+ XXX This function will become more general and will support multiple
+ listening ports */
+
+static bool silc_server_listen(SilcServer server, int *sock)
+{
+
+ *sock = silc_net_create_server(server->config->server_info->port,
+ server->config->server_info->server_ip);
+ if (*sock < 0) {
+ SILC_LOG_ERROR(("Could not create server listener: %s on %hu",
+ server->config->server_info->server_ip,
+ server->config->server_info->port));
+ return FALSE;
+ }
+ return TRUE;
+}
+
/* Initializes the entire SILC server. This is called always before running
the server. This is called only once at the initialization of the program.
This binds the server to its listenning port. After this function returns
when everything is ok to run the server. Configuration file must be
read and parsed before calling this. */
-int silc_server_init(SilcServer server)
+bool silc_server_init(SilcServer server)
{
int sock;
SilcServerID *id;
SilcServerEntry id_entry;
SilcIDListPurge purge;
+ SilcSocketConnection newsocket = NULL;
SILC_LOG_DEBUG(("Initializing server"));
assert(server);
assert(server->config);
+ silc_server_config_ref(&server->config_ref, server->config,
+ server->config);
+
/* Set public and private keys */
if (!server->config->server_info ||
!server->config->server_info->public_key ||
SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
return FALSE;
}
+
+ /* Steal public and private key from the config object */
server->public_key = server->config->server_info->public_key;
server->private_key = server->config->server_info->private_key;
-
- /* Set default to configuration parameters */
- silc_server_config_set_defaults(server);
+ server->config->server_info->public_key = NULL;
+ server->config->server_info->private_key = NULL;
/* Register all configured ciphers, PKCS and hash functions. */
if (!silc_server_config_register_ciphers(server))
silc_hash_alloc("sha1", &server->sha1hash);
/* Allocate PKCS context for local public and private keys */
- silc_pkcs_alloc(server->public_key->name, &server->pkcs);
+ if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
+ goto err;
silc_pkcs_public_key_set(server->pkcs, server->public_key);
silc_pkcs_private_key_set(server->pkcs, server->private_key);
- /* Create a listening server */
- sock = silc_net_create_server(server->config->server_info->port,
- server->config->server_info->server_ip);
- if (sock < 0) {
- SILC_LOG_ERROR(("Could not create server listener: %s on %hu",
- server->config->server_info->server_ip,
- server->config->server_info->port));
+ /* Initialize the scheduler */
+ server->schedule = silc_schedule_init(server->config->param.connections_max);
+ if (!server->schedule)
goto err;
- }
+
+ /* First, register log files configuration for error output */
+ silc_server_config_setlogfiles(server);
/* Initialize ID caches */
server->local_list->clients =
server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
+ /* Create a listening server */
+ if (!silc_server_listen(server, &sock))
+ goto err;
+
+ /* Set socket to non-blocking mode */
+ silc_net_set_socket_nonblock(sock);
+ server->sock = sock;
+
/* Allocate the entire socket list that is used in server. Eventually
all connections will have entry in this table (it is a table of
pointers to the actual object that is allocated individually
later). */
server->sockets = silc_calloc(server->config->param.connections_max,
sizeof(*server->sockets));
+ if (!server->sockets)
+ goto err;
- do {
- SilcSocketConnection newsocket = NULL;
-
- /* Set socket to non-blocking mode */
- silc_net_set_socket_nonblock(sock);
- server->sock = sock;
-
- /* Add ourselves also to the socket table. The entry allocated above
- is sent as argument for fast referencing in the future. */
- silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
- server->sockets[sock] = newsocket;
-
- /* Perform name and address lookups to resolve the listenning address
- and port. */
- if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
- &newsocket->ip)) {
- if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
- !newsocket->ip) {
- SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
- newsocket->hostname ? newsocket->hostname :
- newsocket->ip ? newsocket->ip : ""));
- server->stat.conn_failures++;
- goto err;
- }
- if (!newsocket->hostname)
- newsocket->hostname = strdup(newsocket->ip);
- }
- newsocket->port = silc_net_get_local_port(sock);
-
- /* Create a Server ID for the server. */
- silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
- if (!id)
- goto err;
+ /* Add ourselves also to the socket table. The entry allocated above
+ is sent as argument for fast referencing in the future. */
+ silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
+ server->sockets[sock] = newsocket;
- server->id = id;
- server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
- server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
- server->id_type = SILC_ID_SERVER;
- server->server_name = server->config->server_info->server_name;
-
- /* Add ourselves to the server list. We don't have a router yet
- beacuse we haven't established a route yet. It will be done later.
- For now, NULL is sent as router. This allocates new entry to
- the ID list. */
- id_entry =
- silc_idlist_add_server(server->local_list, strdup(server->server_name),
- server->server_type, server->id, NULL, NULL);
- if (!id_entry) {
- SILC_LOG_ERROR(("Could not add ourselves to cache"));
+ /* Perform name and address lookups to resolve the listenning address
+ and port. */
+ if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
+ &newsocket->ip)) {
+ if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
+ !newsocket->ip) {
+ SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
+ newsocket->hostname ? newsocket->hostname :
+ newsocket->ip ? newsocket->ip : ""));
+ server->stat.conn_failures++;
goto err;
}
- id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
+ if (!newsocket->hostname)
+ newsocket->hostname = strdup(newsocket->ip);
+ }
+ newsocket->port = silc_net_get_local_port(sock);
+
+ /* Create a Server ID for the server. */
+ silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
+ if (!id)
+ goto err;
- /* Put the allocated socket pointer also to the entry allocated above
- for fast back-referencing to the socket list. */
- newsocket->user_data = (void *)id_entry;
- id_entry->connection = (void *)newsocket;
- server->id_entry = id_entry;
- } while (0);
+ server->id = id;
+ server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
+ server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
+ server->id_type = SILC_ID_SERVER;
+ server->server_name = server->config->server_info->server_name;
+ server->config->server_info->server_name = NULL;
+
+ /* Add ourselves to the server list. We don't have a router yet
+ beacuse we haven't established a route yet. It will be done later.
+ For now, NULL is sent as router. This allocates new entry to
+ the ID list. */
+ id_entry =
+ silc_idlist_add_server(server->local_list, strdup(server->server_name),
+ server->server_type, server->id, NULL, NULL);
+ if (!id_entry) {
+ SILC_LOG_ERROR(("Could not add ourselves to cache"));
+ goto err;
+ }
+ id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
+
+ /* Put the allocated socket pointer also to the entry allocated above
+ for fast back-referencing to the socket list. */
+ newsocket->user_data = (void *)id_entry;
+ id_entry->connection = (void *)newsocket;
+ server->id_entry = id_entry;
/* Register protocols */
silc_server_protocols_register();
- /* Initialize the scheduler. */
- server->schedule = silc_schedule_init(server->config->param.connections_max);
- if (!server->schedule)
- goto err;
-
/* Add the first task to the scheduler. This is task that is executed by
timeout. It expires as soon as the caller calls silc_server_run. This
task performs authentication protocol and key exchange with our
SILC_TASK_PRI_NORMAL);
server->listenning = TRUE;
- /* Send log file configuration */
- silc_server_config_setlogfiles(server);
-
/* If server connections has been configured then we must be router as
normal server cannot have server connections, only router connections. */
if (server->config->servers) {
return FALSE;
}
-/* Fork server to background */
+/* This function basically reads the config file again and switches the config
+ object pointed by the server object. After that, we have to fix various
+ things such as the server_name and the listening ports.
+ Keep in mind that we no longer have the root privileges at this point. */
-void silc_server_daemonise(SilcServer server)
+bool silc_server_rehash(SilcServer server)
{
- int i;
+ SilcServerConfig newconfig;
+
+ /* Our old config is gone now. We'll unreference our reference made in
+ silc_server_init and then destroy it since we are destroying it
+ underneath the application (layer which called silc_server_init). */
+ silc_server_config_unref(&server->config_ref);
+ silc_server_config_destroy(server->config);
+
+ /* Reset the logging system */
+ silc_log_quick = TRUE;
+ silc_log_flush_all();
+
+ /* Start the main rehash phase (read again the config file) */
+ SILC_LOG_INFO(("Rehashing server"));
+ newconfig = silc_server_config_alloc(server->config_file);
+ if (!newconfig) {
+ SILC_LOG_ERROR(("Rehash FAILED."));
+ return FALSE;
+ }
- SILC_LOG_DEBUG(("Forking SILC server to background"));
+ /* Take new config context */
+ server->config = newconfig;
+ silc_server_config_ref(&server->config_ref, server->config, server->config);
- i = fork();
+ /* Set public and private keys */
+ if (!server->config->server_info ||
+ !server->config->server_info->public_key ||
+ !server->config->server_info->private_key) {
+ SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
+ return FALSE;
+ }
- if (i < 0) {
- SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
- exit(1);
+ /* Fix the server_name field */
+ if (!strcmp(server->server_name, newconfig->server_info->server_name)) {
+ /* We don't need any update */
+ silc_free(newconfig->server_info->server_name);
+ newconfig->server_info->server_name = NULL;
+ } else {
+ silc_free(server->server_name);
+ server->server_name = newconfig->server_info->server_name;
+ newconfig->server_info->server_name = NULL;
+
+ /* Update the idcache list with a fresh pointer */
+ silc_free(server->id_entry->server_name);
+ server->id_entry->server_name = strdup(server->server_name);
+ silc_idcache_del_by_context(server->local_list->servers, server->id_entry);
+ silc_idcache_add(server->local_list->servers,
+ server->id_entry->server_name,
+ server->id_entry->id, server->id_entry, 0, NULL);
}
- else if (i) {
- if (geteuid())
- SILC_LOG_DEBUG(("Server started as user"));
- else
- SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
- exit(0);
+
+ silc_server_config_setlogfiles(server);
+
+ /* Change new key pair if necessary */
+ if (server->config->server_info->public_key &&
+ !silc_pkcs_public_key_compare(server->public_key,
+ server->config->server_info->public_key)) {
+ silc_pkcs_public_key_free(server->public_key);
+ silc_pkcs_private_key_free(server->private_key);
+ server->public_key = server->config->server_info->public_key;
+ server->private_key = server->config->server_info->private_key;
+ server->config->server_info->public_key = NULL;
+ server->config->server_info->private_key = NULL;
+
+ /* Allocate PKCS context for local public and private keys */
+ silc_pkcs_free(server->pkcs);
+ if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
+ return FALSE;
+ silc_pkcs_public_key_set(server->pkcs, server->public_key);
+ silc_pkcs_private_key_set(server->pkcs, server->private_key);
}
- setsid();
+
+ return TRUE;
}
-/* Drop root privligies. If this cannot be done, die. */
+/* Drop root privileges. If some system call fails, die. */
void silc_server_drop(SilcServer server)
{
/* Are we executing silcd as root or a regular user? */
- if (!geteuid()) {
+ if (geteuid()) {
+ SILC_LOG_DEBUG(("Server started as user"));
+ }
+ else {
struct passwd *pw;
struct group *gr;
char *user, *group;
+ SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
+
/* Get the values given for user and group in configuration file */
user = server->config->server_info->user;
group = server->config->server_info->group;
if (!user || !group) {
- fprintf(stderr, "Error:" /* XXX update this error message */
+ fprintf(stderr, "Error:"
"\tSILC server must not be run as root. For the security of your\n"
"\tsystem it is strongly suggested that you run SILC under dedicated\n"
- "\tuser account. Modify the [Identity] configuration section to run\n"
+ "\tuser account. Modify the ServerInfo configuration section to run\n"
"\tthe server as non-root user.\n");
exit(1);
}
fprintf(stderr, "Error:"
"\tSILC server must not be run as root. For the security of your\n"
"\tsystem it is strongly suggested that you run SILC under dedicated\n"
- "\tuser account. Modify the [Identity] configuration section to run\n"
+ "\tuser account. Modify the ServerInfo configuration section to run\n"
"\tthe server as non-root user.\n");
exit(1);
}
}
}
+/* Fork server to background */
+
+void silc_server_daemonise(SilcServer server)
+{
+ int i;
+
+ SILC_LOG_DEBUG(("Forking SILC server to background"));
+
+ if ((i = fork()) < 0) {
+ fprintf(stderr, "Error: fork() failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (i) /* Kill the parent */
+ exit(0);
+
+ server->background = TRUE;
+ setsid();
+
+ /* XXX close stdin, stdout, stderr -- before this, check that all writes
+ to stderr are changed to SILC_SERVER_LOG_ERROR() */
+}
+
/* The heart of the server. This runs the scheduler thus runs the server.
When this returns the server has been stopped and the program will
be terminated. */
void silc_server_run(SilcServer server)
{
- SILC_LOG_DEBUG(("Running server"));
-
SILC_LOG_INFO(("SILC Server started"));
/* Start the scheduler, the heart of the SILC server. When this returns
SilcSocketConnection newsocket;
SilcProtocol protocol;
SilcServerKEInternalContext *proto_ctx;
- SilcServerConfigRouter *conn = sconn->conn;
+ SilcServerConfigRouter *conn =
+ (SilcServerConfigRouter *) sconn->conn.ref_ptr;
void *context;
/* Cancel any possible retry timeouts */
{
SilcServerConnection sconn = (SilcServerConnection)context;
SilcServer server = sconn->server;
+ SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
SilcServerConfigConnParams *param =
- (sconn->param ? sconn->param : &server->config->param);
+ (conn->param ? conn->param : &server->config->param);
SILC_LOG_INFO(("Retrying connecting to a router"));
silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
/* If we've reached max retry count, give up. */
- if (sconn->retry_count > param->reconnect_count &&
- param->reconnect_keep_trying == FALSE) {
+ if ((sconn->retry_count > param->reconnect_count) &&
+ !param->reconnect_keep_trying) {
SILC_LOG_ERROR(("Could not connect to router, giving up"));
+ silc_server_config_unref(&sconn->conn);
silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
silc_free(sconn);
return;
}
+ /* We will lookup a fresh pointer later */
+ silc_server_config_unref(&sconn->conn);
+
/* Wait one before retrying */
- silc_schedule_task_add(server->schedule, fd, silc_server_connect_router,
+ silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
context, sconn->retry_timeout, 0,
SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
{
SilcServerConnection sconn = (SilcServerConnection)context;
SilcServer server = sconn->server;
+ SilcServerConfigRouter *rconn;
int sock;
SILC_LOG_INFO(("Connecting to the %s %s on port %d",
sconn->remote_host, sconn->remote_port));
server->router_connect = time(NULL);
+ rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
+ sconn->remote_port);
+ if (!rconn) {
+ SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
+ (sconn->backup ? "backup router" : "router"),
+ sconn->remote_host, sconn->remote_port));
+ silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
+ silc_free(sconn);
+ return;
+ }
+ silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
/* Connect to remote host */
sock = silc_net_create_connection(server->config->server_info->server_ip,
SILC_LOG_ERROR(("Could not connect to router %s:%d",
sconn->remote_host, sconn->remote_port));
if (!sconn->no_reconnect)
- silc_schedule_task_add(server->schedule, fd,
+ silc_schedule_task_add(server->schedule, 0,
silc_server_connect_to_router_retry,
context, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
+ else
+ silc_server_config_unref(&sconn->conn);
return;
}
SILC_LOG_DEBUG(("We are backup router/normal server"));
}
+ if (!server->config->routers) {
+ /* There wasn't a configured router, we will continue but we don't
+ have a connection to outside world. We will be standalone server. */
+ SILC_LOG_DEBUG(("No router(s), server will be standalone"));
+ server->standalone = TRUE;
+ return;
+ }
+
/* Create the connections to all our routes */
- ptr = server->config->routers;
- while (ptr) {
+ for (ptr = server->config->routers; ptr; ptr = ptr->next) {
SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
ptr->backup_router ? "Backup router" : "Router",
if (!server->router_conn && !sconn->backup)
server->router_conn = sconn;
- sconn->conn = ptr;
- sconn->param = ptr->param;
-
silc_schedule_task_add(server->schedule, fd,
silc_server_connect_router,
(void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
}
-
- if (!ptr->next)
- return;
-
- ptr = ptr->next;
}
-
- SILC_LOG_DEBUG(("No router(s), server will be standalone"));
-
- /* There wasn't a configured router, we will continue but we don't
- have a connection to outside world. We will be standalone server. */
- server->standalone = TRUE;
}
/* Second part of connecting to router(s). Key exchange protocol has been
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
+ silc_server_config_unref(&sconn->conn);
+ silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
+ silc_free(sconn);
silc_schedule_task_del_by_callback(server->schedule,
silc_server_failure_callback);
silc_server_disconnect_remote(server, sock, "Server closed connection: "
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
+ silc_server_config_unref(&sconn->conn);
+ silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
+ silc_free(sconn);
silc_schedule_task_del_by_callback(server->schedule,
silc_server_failure_callback);
silc_server_disconnect_remote(server, sock, "Server closed connection: "
/* Resolve the authentication method used in this connection. Check if
we find a match from user configured connections */
- if (!sconn->conn)
+ if (!sconn->conn.ref_ptr)
conn = silc_server_config_find_router_conn(server, sock->hostname,
sock->port);
else
- conn = sconn->conn;
+ conn = sconn->conn.ref_ptr;
if (conn) {
/* Match found. Use the configured authentication method. Take only
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
+ silc_server_config_unref(&sconn->conn);
+ silc_free(sconn->remote_host);
+ silc_free(sconn->backup_replace_ip);
+ silc_free(sconn);
silc_schedule_task_del_by_callback(server->schedule,
silc_server_failure_callback);
silc_server_disconnect_remote(server, sock, "Server closed connection: "
unsigned char *id_string;
SilcUInt32 id_len;
SilcIDListData idata;
- SilcServerConfigConnParams *param;
+ SilcServerConfigRouter *conn = NULL;
+ SilcServerConfigConnParams *param = NULL;
SILC_LOG_DEBUG(("Start"));
idata = (SilcIDListData)sock->user_data;
idata->status |= SILC_IDLIST_STATUS_REGISTERED;
- param = (sconn->param ? sconn->param : &server->config->param);
+ conn = sconn->conn.ref_ptr;
+ param = &server->config->param;
+ if (conn && conn->param)
+ param = conn->param;
/* Perform keepalive. The `hb_context' will be freed automatically
when finally calling the silc_socket_free function. */
out:
/* Free the temporary connection data context */
if (sconn) {
+ silc_server_config_unref(&sconn->conn);
silc_free(sconn->remote_host);
silc_free(sconn->backup_replace_ip);
silc_free(sconn);
silc_free(ctx);
}
-/* Host lookup callbcak that is called after the incoming connection's
+/* Host lookup callback that is called after the incoming connection's
IP and FQDN lookup is performed. This will actually check the acceptance
of the incoming connection and will register the key exchange protocol
for this connection. */
if (deny) {
/* The connection is denied */
SILC_LOG_INFO(("Connection %s (%s) is denied",
- sock->hostname, sock->ip));
+ sock->hostname, sock->ip));
silc_server_disconnect_remote(server, sock, deny->reason ?
deny->reason :
"Server closed connection: "
return;
}
- /* Check whether we have configred this sort of connection at all. We
+ /* Check whether we have configured this sort of connection at all. We
have to check all configurations since we don't know what type of
connection this is. */
if (!(cconfig = silc_server_config_find_client(server, sock->ip)))
proto_ctx->sock = sock;
proto_ctx->rng = server->rng;
proto_ctx->responder = TRUE;
- proto_ctx->cconfig = cconfig;
- proto_ctx->sconfig = sconfig;
- proto_ctx->rconfig = rconfig;
+ silc_server_config_ref(&proto_ctx->cconfig, server->config, cconfig);
+ silc_server_config_ref(&proto_ctx->sconfig, server->config, sconfig);
+ silc_server_config_ref(&proto_ctx->rconfig, server->config, rconfig);
/* Take flags for key exchange. Since we do not know what type of connection
- this is, we go through all found configuratios and use the global ones
+ this is, we go through all found configurations and use the global ones
as well. This will result always into strictest key exchange flags. */
SILC_GET_SKE_FLAGS(cconfig, proto_ctx);
SILC_GET_SKE_FLAGS(sconfig, proto_ctx);
/* Check for maximum allowed connections */
if (sock > server->config->param.connections_max) {
- SILC_LOG_ERROR(("Refusing connection, server is full, try again later"));
+ SILC_LOG_ERROR(("Refusing connection, server is full"));
server->stat.conn_failures++;
+ silc_net_close_connection(sock);
return;
}
SILC_LOG_DEBUG(("Start"));
- if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
- protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
+ if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
+ (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
/* Error occured during protocol */
silc_protocol_free(protocol);
sock->protocol = NULL;
if (ctx->ske)
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
+ silc_server_config_unref(&ctx->cconfig);
+ silc_server_config_unref(&ctx->sconfig);
+ silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
silc_schedule_task_del_by_callback(server->schedule,
silc_server_failure_callback);
if (ctx->ske)
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
+ silc_server_config_unref(&ctx->cconfig);
+ silc_server_config_unref(&ctx->sconfig);
+ silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
silc_schedule_task_del_by_callback(server->schedule,
silc_server_failure_callback);
if (ctx->ske)
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
+ silc_server_config_unref(&ctx->cconfig);
+ silc_server_config_unref(&ctx->sconfig);
+ silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
silc_schedule_task_del_by_callback(server->schedule,
silc_server_failure_callback);
case SILC_SOCKET_TYPE_CLIENT:
{
SilcClientEntry client;
- SilcServerConfigClient *conn = ctx->cconfig;
+ SilcServerConfigClient *conn = ctx->cconfig.ref_ptr;
/* Verify whether this connection is after all allowed to connect */
if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
bool backup_router = FALSE;
char *backup_replace_ip = NULL;
SilcUInt16 backup_replace_port = 0;
- SilcServerConfigServer *sconn = ctx->sconfig;
- SilcServerConfigRouter *rconn = ctx->rconfig;
+ SilcServerConfigServer *sconn = ctx->sconfig.ref_ptr;
+ SilcServerConfigRouter *rconn = ctx->rconfig.ref_ptr;
if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
/* Verify whether this connection is after all allowed to connect */
if (ctx->ske)
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
+ silc_server_config_unref(&ctx->cconfig);
+ silc_server_config_unref(&ctx->sconfig);
+ silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
sock->protocol = NULL;
}
if (sock->protocol && sock->protocol->protocol &&
sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
-
SilcServerKEInternalContext *proto_ctx =
(SilcServerKEInternalContext *)sock->protocol->context;
sconn->remote_host = strdup(remote_host);
sconn->remote_port = port;
sconn->no_reconnect = TRUE;
- sconn->param = &server->config->param;
silc_schedule_task_add(server->schedule, 0,
silc_server_connect_router,