silc_server_config_setlogfiles(server->config);
/* Register all configured ciphers, PKCS and hash functions. */
- silc_server_config_register_ciphers(server->config);
- silc_server_config_register_pkcs(server->config);
- silc_server_config_register_hashfuncs(server->config);
- silc_server_config_register_hmacs(server->config);
+ if (!silc_server_config_register_ciphers(server->config))
+ silc_cipher_register_default();
+ if (!silc_server_config_register_pkcs(server->config))
+ silc_pkcs_register_default();
+ if (!silc_server_config_register_hashfuncs(server->config))
+ silc_hash_register_default();
+ if (!silc_server_config_register_hmacs(server->config))
+ silc_hmac_register_default();
/* Initialize random number generator for the server. */
server->rng = silc_rng_alloc();
{
SILC_LOG_DEBUG(("Running server"));
+ SILC_LOG_INFO(("SILC Server started"));
+
/* Start the scheduler, the heart of the SILC server. When this returns
the program will be terminated. */
silc_schedule();
SILC_REGISTER_CONNECTION_FOR_IO(sock);
/* Run the protocol */
- protocol->execute(server->timeout_queue, 0, protocol, sock, 0, 0);
+ silc_protocol_execute(protocol, server->timeout_queue, 0, 0);
}
/* This function connects to our primary router or if we are a router this
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SilcServerConnection sconn = (SilcServerConnection)ctx->context;
- SilcSocketConnection sock = server->sockets[fd];
+ SilcSocketConnection sock = ctx->sock;
SilcServerConnAuthInternalContext *proto_ctx;
SilcServerConfigSectionServerConnection *conn = NULL;
SILC_TASK_PRI_LOW);
/* Run the protocol */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 0);
}
/* Finalizes the connection to router. Registers a server task to the
later when outgoing data is available. */
SILC_REGISTER_CONNECTION_FOR_IO(sock);
+ SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
+ newsocket->ip));
+
port = server->sockets[fd]->port; /* Listenning port */
/* Check whether this connection is denied to connect to us. */
port);
if (deny) {
/* The connection is denied */
+ SILC_LOG_INFO(("Connection %s (%s) is denied",
+ newsocket->hostname, newsocket->ip));
silc_server_disconnect_remote(server, newsocket, deny->comment ?
deny->comment :
"Server closed connection: "
/* The connection is allowed */
- SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
- newsocket->ip));
-
/* Allocate internal context for key exchange protocol. This is
sent as context for the protocol. */
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
SilcServerKEInternalContext *ctx =
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
- SilcSocketConnection sock = server->sockets[fd];
+ SilcSocketConnection sock = ctx->sock;
SilcServerConnAuthInternalContext *proto_ctx;
SILC_LOG_DEBUG(("Start"));
SILC_LOG_DEBUG(("Success packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
- if (sock->protocol) {
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
- }
+ if (sock->protocol)
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 0);
break;
case SILC_PACKET_FAILURE:
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 100000);
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 100000);
} else {
SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
"protocol active, packet dropped."));
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 0);
} else {
SilcServerKEInternalContext *proto_ctx =
(SilcServerKEInternalContext *)sock->protocol->context;
break;
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock,
- 0, 100000);
+ silc_protocol_execute(sock->protocol, server->timeout_queue,
+ 0, 100000);
}
} else {
SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 0);
} else {
SilcServerKEInternalContext *proto_ctx =
(SilcServerKEInternalContext *)sock->protocol->context;
break;
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock,
- 0, 100000);
+ silc_protocol_execute(sock->protocol, server->timeout_queue,
+ 0, 100000);
}
} else {
SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 0);
} else {
SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
"protocol active, packet dropped."));
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock, 0, 0);
+ silc_protocol_execute(sock->protocol, server->timeout_queue, 0, 0);
} else {
SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
"protocol active, packet dropped."));
sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
"Router"), sock->sock));
+ /* If any protocol is active cancel its execution */
+ if (sock->protocol) {
+ silc_protocol_cancel(sock->protocol, server->timeout_queue);
+ sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute_final(sock->protocol, server->timeout_queue);
+ sock->protocol = NULL;
+ }
+
/* We won't listen for this connection anymore */
silc_schedule_unset_listen_fd(sock->sock);
SilcBuffer args;
/* Send SERVER_SIGNOFF notify to our primary router */
- if (!server->standalone && server->router) {
+ if (!server->standalone && server->router &&
+ server->router != entry) {
args = silc_argument_payload_encode(1, argv, argv_lens,
argv_types);
silc_server_send_notify_args(server,
SilcServer server = (SilcServer)context;
SilcSocketConnection sock = server->sockets[fd];
+ SILC_LOG_DEBUG(("Start"));
+
if (!sock)
return;
+ /* If we have protocol active we must assure that we call the protocol's
+ final callback so that all the memory is freed. */
+ if (sock->protocol) {
+ sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute_final(sock->protocol, server->timeout_queue);
+ return;
+ }
+
if (sock->user_data)
silc_server_free_sock_user_data(server, sock);
- silc_server_disconnect_remote(server, sock,
- "Server closed connection: "
+ silc_server_disconnect_remote(server, sock, "Server closed connection: "
"Connection timeout");
}
SilcIDList id_list,
SilcBuffer *channels,
SilcBuffer *channel_users,
- SilcBuffer *channel_users_modes)
+ SilcBuffer **channel_users_modes,
+ uint32 *channel_users_modes_c,
+ SilcChannelID ***channel_ids)
{
SilcIDCacheList list;
SilcIDCacheEntry id_cache;
uint32 id_len;
uint16 name_len;
int len;
+ int i = *channel_users_modes_c;
SILC_LOG_DEBUG(("Start"));
SILC_STR_END);
silc_buffer_pull(*channels, len);
+ *channel_users_modes = silc_realloc(*channel_users_modes,
+ sizeof(**channel_users_modes) *
+ (i + 1));
+ (*channel_users_modes)[i] = NULL;
+ *channel_ids = silc_realloc(*channel_ids,
+ sizeof(**channel_ids) * (i + 1));
+ (*channel_ids)[i] = NULL;
silc_server_announce_get_channel_users(server, channel,
channel_users,
- channel_users_modes);
-
- silc_free(cid);
+ channel_users_modes[i]);
+ (*channel_ids)[i] = channel->id;
+ i++;
if (!silc_idcache_list_next(list, &id_cache))
break;
}
+
+ *channel_users_modes_c += i;
}
silc_idcache_list_free(list);
void silc_server_announce_channels(SilcServer server)
{
- SilcBuffer channels = NULL, channel_users = NULL, channel_users_modes = NULL;
+ SilcBuffer channels = NULL, channel_users = NULL;
+ SilcBuffer *channel_users_modes = NULL;
+ uint32 channel_users_modes_c = 0;
+ SilcChannelID **channel_ids = NULL;
SILC_LOG_DEBUG(("Announcing channels and channel users"));
/* Get channels and channel users in local list */
silc_server_announce_get_channels(server, server->local_list,
&channels, &channel_users,
- &channel_users_modes);
+ &channel_users_modes,
+ &channel_users_modes_c,
+ &channel_ids);
/* Get channels and channel users in global list */
silc_server_announce_get_channels(server, server->global_list,
&channels, &channel_users,
- &channel_users_modes);
+ &channel_users_modes,
+ &channel_users_modes_c,
+ &channel_ids);
if (channels) {
silc_buffer_push(channels, channels->data - channels->head);
}
if (channel_users_modes) {
- silc_buffer_push(channel_users_modes,
- channel_users_modes->data - channel_users_modes->head);
- SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes->data,
- channel_users_modes->len);
-
- /* Send the packet */
- silc_server_packet_send(server, server->router->connection,
- SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
- channel_users_modes->data,
- channel_users_modes->len,
- FALSE);
-
- silc_buffer_free(channel_users_modes);
+ int i;
+
+ for (i = 0; i < channel_users_modes_c; i++) {
+ silc_buffer_push(channel_users_modes[i],
+ channel_users_modes[i]->data -
+ channel_users_modes[i]->head);
+ SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
+ channel_users_modes[i]->len);
+ silc_server_packet_send_dest(server, server->router->connection,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ channel_ids[i], SILC_ID_CHANNEL,
+ channel_users_modes[i]->data,
+ channel_users_modes[i]->len,
+ FALSE);
+ silc_buffer_free(channel_users_modes[i]);
+ }
+ silc_free(channel_users_modes);
+ silc_free(channel_ids);
}
}
if (f->sock->protocol) {
f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
- f->sock->protocol->execute(f->server->timeout_queue, 0,
- f->sock->protocol, f->sock->sock, 0, 0);
+ silc_protocol_execute(f->sock->protocol, f->server->timeout_queue, 0, 0);
}
silc_free(f);
sock->protocol = protocol;
/* Run the protocol */
- protocol->execute(server->timeout_queue, 0, protocol,
- sock->sock, 0, 0);
+ silc_protocol_execute(protocol, server->timeout_queue, 0, 0);
/* Re-register re-key timeout */
silc_task_register(server->timeout_queue, sock->sock,
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
/* Error occured during protocol */
- silc_protocol_cancel(server->timeout_queue, protocol);
+ silc_protocol_cancel(protocol, server->timeout_queue);
silc_protocol_free(protocol);
sock->protocol = NULL;
if (ctx->packet)