SilcServerID *id;
SilcServerEntry id_entry;
SilcIDListPurge purge;
- SilcServerConfigSectionListenPort *listen;
SILC_LOG_DEBUG(("Initializing server"));
assert(server);
assert(server->config);
/* Set public and private keys */
- if (!server->config->server_keys ||
- !server->config->server_keys->public_key ||
- !server->config->server_keys->private_key) {
+ 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;
}
- server->public_key = server->config->server_keys->public_key;
- server->private_key = server->config->server_keys->private_key;
+ server->public_key = server->config->server_info->public_key;
+ server->private_key = server->config->server_info->private_key;
/* XXX After server is made as Silc Server Library this can be given
as argument, for now this is hard coded */
server->params->protocol_timeout = 60;
server->params->require_reverse_mapping = FALSE;
- /* Set log files where log message should be saved. */
- server->config->server = server;
-
/* Register all configured ciphers, PKCS and hash functions. */
- if (!silc_server_config_register_ciphers(server->config))
+ if (!silc_server_config_register_ciphers(server))
silc_cipher_register_default();
- if (!silc_server_config_register_pkcs(server->config))
+ if (!silc_server_config_register_pkcs(server))
silc_pkcs_register_default();
- if (!silc_server_config_register_hashfuncs(server->config))
+ if (!silc_server_config_register_hashfuncs(server))
silc_hash_register_default();
- if (!silc_server_config_register_hmacs(server->config))
+ if (!silc_server_config_register_hmacs(server))
silc_hmac_register_default();
/* Initialize random number generator for the server. */
silc_hash_alloc("md5", &server->md5hash);
silc_hash_alloc("sha1", &server->sha1hash);
- /* Initialize none cipher */
- silc_cipher_alloc("none", &server->none_cipher);
-
/* Allocate PKCS context for local public and private keys */
silc_pkcs_alloc(server->public_key->name, &server->pkcs);
silc_pkcs_public_key_set(server->pkcs, server->public_key);
/* Create a listening server. Note that our server can listen on multiple
ports. All listeners are created here and now. */
sock_count = 0;
- listen = server->config->listen_port;
- while(listen) {
+ while (1) {
int tmp;
- tmp = silc_net_create_server(server->config->listen_port->port,
- server->config->listen_port->listener_ip);
+ tmp = silc_net_create_server(server->config->server_info->port,
+ server->config->server_info->server_ip);
if (tmp < 0) {
- SILC_LOG_ERROR(("Could not create server listener: %s on %d",
- server->config->listen_port->listener_ip,
- server->config->listen_port->port));
+ SILC_LOG_ERROR(("Could not create server listener: %s on %hd",
+ server->config->server_info->server_ip,
+ server->config->server_info->port));
goto err0;
}
sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1));
sock[sock_count] = tmp;
sock_count++;
- listen = listen->next;
+ break;
}
/* Initialize ID caches */
/* 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) {
- SilcServerConfigSectionServerConnection *ptr = server->config->servers;
+ SilcServerConfigSectionServer *ptr = server->config->servers;
server->server_type = SILC_ROUTER;
while (ptr) {
struct group *gr;
char *user, *group;
- if (!server->config->identity || !server->config->identity->user ||
- !server->config->identity->group) {
+ if (!server->config->server_info->user || !server->config->server_info->group) {
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"
}
/* Get the values given for user and group in configuration file */
- user=server->config->identity->user;
- group=server->config->identity->group;
+ user=server->config->server_info->user;
+ group=server->config->server_info->group;
/* Check whether the user/group information is text */
if (atoi(user)!=0 || atoi(group)!=0) {
SilcServerKEInternalContext *proto_ctx;
void *context;
+ /* Cancel any possible retry timeouts */
+ silc_schedule_task_del_by_callback(server->schedule,
+ silc_server_connect_router);
+
/* Set socket options */
silc_net_set_socket_nonblock(sock);
silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
server->router_connect = time(0);
/* Connect to remote host */
- sock = silc_net_create_connection(server->config->listen_port->local_ip,
+ sock = silc_net_create_connection(server->config->server_info->server_ip,
sconn->remote_port,
sconn->remote_host);
if (sock < 0) {
- SILC_LOG_ERROR(("Could not connect to router"));
- silc_schedule_task_add(server->schedule, fd,
- silc_server_connect_to_router_retry,
- context, 0, 1, SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ 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_server_connect_to_router_retry,
+ context, 0, 1, SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
return;
}
{
SilcServer server = (SilcServer)context;
SilcServerConnection sconn;
- SilcServerConfigSectionServerConnection *ptr;
+ SilcServerConfigSectionRouter *ptr;
SILC_LOG_DEBUG(("Connecting to router(s)"));
SilcServerConnection sconn = (SilcServerConnection)ctx->context;
SilcSocketConnection sock = ctx->sock;
SilcServerConnAuthInternalContext *proto_ctx;
- SilcServerConfigSectionServerConnection *conn = NULL;
+ SilcServerConfigSectionRouter *conn = NULL;
SILC_LOG_DEBUG(("Start"));
timeout!! */
hb_context = silc_calloc(1, sizeof(*hb_context));
hb_context->server = server;
- silc_socket_set_heartbeat(sock, 600, hb_context,
+ silc_socket_set_heartbeat(sock, 300, hb_context,
silc_server_perform_heartbeat,
server->schedule);
SilcServer server = (SilcServer)context;
SilcServerKEInternalContext *proto_ctx;
void *cconfig, *sconfig, *rconfig;
- SilcServerConfigSectionDenyConnection *deny;
+ SilcServerConfigSectionDeny *deny;
int port;
SILC_LOG_DEBUG(("Start"));
port = server->sockets[server->sock]->port; /* Listenning port */
/* Check whether this connection is denied to connect to us. */
- deny = silc_server_config_denied_conn(server->config, sock->ip, port);
+ deny = silc_server_config_find_denied(server->config, sock->ip, port);
if (!deny)
- deny = silc_server_config_denied_conn(server->config, sock->hostname,
+ deny = silc_server_config_find_denied(server->config, sock->hostname,
port);
if (deny) {
/* The connection is denied */
SILC_LOG_INFO(("Connection %s (%s) is denied",
sock->hostname, sock->ip));
- silc_server_disconnect_remote(server, sock, deny->comment ?
- deny->comment :
+ silc_server_disconnect_remote(server, sock, deny->reason ?
+ deny->reason :
"Server closed connection: "
"Connection refused");
server->stat.conn_failures++;
/* Check whether we have configred 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_conn(server->config,
+ if (!(cconfig = silc_server_config_find_client(server->config,
sock->ip, port)))
- cconfig = silc_server_config_find_client_conn(server->config,
+ cconfig = silc_server_config_find_client(server->config,
sock->hostname,
port);
if (!(sconfig = silc_server_config_find_server_conn(server->config,
SilcSocketConnection sock = ctx->sock;
SilcServerHBContext hb_context;
SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
- void *id_entry = NULL;
+ void *id_entry;
SILC_LOG_DEBUG(("Start"));
case SILC_SOCKET_TYPE_ROUTER:
{
SilcServerEntry new_server;
- SilcServerConfigSectionServerConnection *conn =
+ /* XXX FIXME: Now server and router has different table, so this is probably broken. */
+ SilcServerConfigSectionRouter *conn =
ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
ctx->sconfig : ctx->rconfig;
break;
}
default:
+ goto out;
break;
}
sock->type = ctx->conn_type;
/* Add the common data structure to the ID entry. */
- if (id_entry)
- silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
-
+ silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
+
/* Add to sockets internal pointer for fast referencing */
silc_free(sock->user_data);
sock->user_data = id_entry;
timeout!! */
hb_context = silc_calloc(1, sizeof(*hb_context));
hb_context->server = server;
- silc_socket_set_heartbeat(sock, 600, hb_context,
+ silc_socket_set_heartbeat(sock, 400, hb_context,
silc_server_perform_heartbeat,
server->schedule);
/* Creates connection to a remote router. */
void silc_server_create_connection(SilcServer server,
- char *remote_host, uint32 port)
+ const char *remote_host, uint32 port)
{
SilcServerConnection sconn;
sconn->server = server;
sconn->remote_host = strdup(remote_host);
sconn->remote_port = port;
+ sconn->no_reconnect = TRUE;
silc_schedule_task_add(server->schedule, 0,
silc_server_connect_router,
silc_server_remove_from_channels(server, NULL, client,
FALSE, NULL, FALSE);
+ /* Update statistics */
+ server->stat.my_clients--;
+ server->stat.clients--;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.cell_clients--;
+ SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+ SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
/* We will not delete the client entry right away. We will take it
into history (for WHOWAS command) for 5 minutes */
i->server = server;
client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
client->router = NULL;
client->connection = NULL;
-
- /* Free the client entry and everything in it */
- server->stat.my_clients--;
- server->stat.clients--;
- if (server->server_type == SILC_ROUTER)
- server->stat.cell_clients--;
+ client->mode = 0;
}
/* Frees user_data pointer from socket connection object. This also sends
silc_hash_table_del(channel->user_list, chl2->client);
silc_free(chl2);
}
+ silc_hash_table_list_reset(&htl2);
continue;
}
if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Re-generate channel key */
if (!silc_server_create_channel_key(server, channel, 0))
- return;
+ goto out;
/* Send the channel key to the channel. The key of course is not sent
to the client who was removed from the channel. */
}
}
+ out:
+ silc_hash_table_list_reset(&htl);
silc_buffer_free(clidp);
}
silc_hash_table_del(channel->user_list, chl2->client);
silc_free(chl2);
}
+ silc_hash_table_list_reset(&htl2);
return FALSE;
}
channel_name = strdup(channel_name);
- /* Create the channel */
+ /* Create the channel ID */
if (!silc_id_create_channel_id(server, router_id, server->rng,
&channel_id)) {
silc_free(channel_name);
silc_hmac_free(newhmac);
return NULL;
}
+
+ /* Create the channel */
entry = silc_idlist_add_channel(server->local_list, channel_name,
SILC_CHANNEL_MODE_NONE, channel_id,
NULL, key, newhmac, 0);
silc_free(channel_name);
silc_cipher_free(key);
silc_hmac_free(newhmac);
+ silc_free(channel_id);
return NULL;
}
/* Now create the actual key material */
if (!silc_server_create_channel_key(server, entry,
silc_cipher_get_key_len(key) / 8)) {
- silc_free(channel_name);
- silc_cipher_free(key);
- silc_hmac_free(newhmac);
- silc_free(entry->cipher);
- silc_free(entry->hmac_name);
+ silc_idlist_del_channel(server->local_list, entry);
return NULL;
}
SILC_CHANNEL_MODE_NONE, channel_id,
NULL, key, newhmac, 0);
if (!entry) {
+ silc_cipher_free(key);
+ silc_hmac_free(newhmac);
silc_free(channel_name);
return NULL;
}
/* Now create the actual key material */
if (!silc_server_create_channel_key(server, entry,
silc_cipher_get_key_len(key) / 8)) {
- silc_free(channel_name);
+ silc_idlist_del_channel(server->local_list, entry);
return NULL;
}
SILC_LOG_DEBUG(("Start"));
/* Decode channel key payload */
- payload = silc_channel_key_payload_parse(key_payload->data,
+ payload = silc_channel_key_payload_parse(key_payload->data,
key_payload->len);
if (!payload) {
SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
if (!channel) {
channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
if (!channel) {
- SILC_LOG_ERROR(("Received key for non-existent channel"));
+ SILC_LOG_ERROR(("Received key for non-existent channel %s",
+ silc_id_render(id, SILC_ID_CHANNEL)));
goto out;
}
}
{
SilcServerHBContext hb = (SilcServerHBContext)hb_context;
- SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname,
- sock->ip));
+ SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
/* Send the heartbeat */
silc_server_send_heartbeat(hb->server, sock);
silc_buffer_free(clidp);
}
+ silc_hash_table_list_reset(&htl);
silc_buffer_free(chidp);
}
int i;
for (i = 0; i < channel_users_modes_c; i++) {
+ if (!channel_users_modes[i])
+ continue;
silc_buffer_push(channel_users_modes[i],
channel_users_modes[i]->data -
channel_users_modes[i]->head);
silc_hash_table_list(channel->user_list, &htl);
while (silc_hash_table_get(&htl, NULL, (void *)&chl))
len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
+ silc_hash_table_list_reset(&htl);
client_id_list = silc_buffer_alloc(len);
client_mode_list =
list_count++;
}
+ silc_hash_table_list_reset(&htl);
silc_buffer_push(client_id_list,
client_id_list->data - client_id_list->head);
silc_buffer_push(client_mode_list,
silc_buffer_pull(buffer, len);
silc_free(cid);
}
+ silc_hash_table_list_reset(&htl);
if (buffer)
silc_buffer_push(buffer, buffer->data - buffer->head);