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"));
and other information is created after we have received NEW_CLIENT
packet from client. */
client = silc_idlist_add_client(server->local_list,
- NULL, 0, NULL, NULL, NULL, NULL, sock);
+ NULL, NULL, NULL, NULL, NULL, sock);
if (!client) {
SILC_LOG_ERROR(("Could not add new client to cache"));
silc_free(sock->user_data);
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,
int silc_server_channel_has_global(SilcChannelEntry channel)
{
SilcChannelClientEntry chl;
+ SilcHashTableList htl;
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
if (chl->client->router)
return TRUE;
}
int silc_server_channel_has_local(SilcChannelEntry channel)
{
SilcChannelClientEntry chl;
+ SilcHashTableList htl;
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
if (!chl->client->router)
return TRUE;
}
{
SilcChannelEntry channel;
SilcChannelClientEntry chl;
+ SilcHashTableList htl;
SilcBuffer clidp;
SILC_LOG_DEBUG(("Start"));
/* Remove the client from all channels. The client is removed from
the channels' user list. */
- silc_list_start(client->channels);
- while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
+ silc_hash_table_list(client->channels, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
channel = chl->channel;
/* Remove channel from client's channel list */
- silc_list_del(client->channels, chl);
+ silc_hash_table_del(client->channels, channel);
/* Remove channel if there is no users anymore */
if (server->server_type == SILC_ROUTER &&
- silc_list_count(channel->user_list) < 2) {
- server->stat.my_channels--;
-
+ silc_hash_table_count(channel->user_list) < 2) {
if (channel->rekey)
silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
-
- if (channel->founder_key) {
- /* The founder auth data exists, do not remove the channel entry */
- SilcChannelClientEntry chl2;
-
- channel->id = NULL;
-
- silc_list_start(channel->user_list);
- while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- silc_list_del(chl2->client->channels, chl2);
- silc_list_del(channel->user_list, chl2);
- silc_free(chl2);
- }
- continue;
- }
-
if (!silc_idlist_del_channel(server->local_list, channel))
silc_idlist_del_channel(server->global_list, channel);
+ server->stat.my_channels--;
continue;
}
/* Remove client from channel's client list */
- silc_list_del(channel->user_list, chl);
+ silc_hash_table_del(channel->user_list, chl->client);
silc_free(chl);
server->stat.my_chanclients--;
if (channel->founder_key) {
/* The founder auth data exists, do not remove the channel entry */
SilcChannelClientEntry chl2;
+ SilcHashTableList htl2;
channel->id = NULL;
- silc_list_start(channel->user_list);
- while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- silc_list_del(chl2->client->channels, chl2);
- silc_list_del(channel->user_list, chl2);
+ silc_hash_table_list(channel->user_list, &htl2);
+ while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
+ silc_hash_table_del(chl2->client->channels, channel);
+ silc_hash_table_del(channel->user_list, chl2->client);
silc_free(chl2);
}
continue;
}
+ /* Remove the channel entry */
if (!silc_idlist_del_channel(server->local_list, channel))
silc_idlist_del_channel(server->global_list, channel);
server->stat.my_channels--;
SilcClientEntry client,
int notify)
{
- SilcChannelEntry ch;
SilcChannelClientEntry chl;
SilcBuffer clidp;
SILC_LOG_DEBUG(("Start"));
- clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+ /* Get the entry to the channel, if this client is not on the channel
+ then return Ok. */
+ if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
+ return TRUE;
/* Remove the client from the channel. The client is removed from
the channel's user list. */
- silc_list_start(client->channels);
- while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
- if (chl->channel != channel)
- continue;
- ch = chl->channel;
-
- /* Remove channel from client's channel list */
- silc_list_del(client->channels, chl);
-
- /* Remove channel if there is no users anymore */
- if (server->server_type == SILC_ROUTER &&
- silc_list_count(channel->user_list) < 2) {
- if (channel->rekey)
- silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
- if (!silc_idlist_del_channel(server->local_list, channel))
- silc_idlist_del_channel(server->global_list, channel);
- silc_buffer_free(clidp);
- server->stat.my_channels--;
- return FALSE;
- }
-
- /* Remove client from channel's client list */
- silc_list_del(channel->user_list, chl);
- silc_free(chl);
- server->stat.my_chanclients--;
-
- /* If there is no global users on the channel anymore mark the channel
- as local channel. */
- if (server->server_type == SILC_SERVER &&
- !silc_server_channel_has_global(channel))
- channel->global_users = FALSE;
-
- /* If there is not at least one local user on the channel then we don't
- need the channel entry anymore, we can remove it safely. */
- if (server->server_type == SILC_SERVER &&
- !silc_server_channel_has_local(channel)) {
- /* Notify about leaving client if this channel has global users. */
- if (notify && channel->global_users)
- silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
- SILC_NOTIFY_TYPE_LEAVE, 1,
- clidp->data, clidp->len);
+ clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
- silc_buffer_free(clidp);
+ /* Remove channel from client's channel list */
+ silc_hash_table_del(client->channels, chl->channel);
- if (channel->rekey)
- silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
-
- if (channel->founder_key) {
- /* The founder auth data exists, do not remove the channel entry */
- SilcChannelClientEntry chl2;
+ /* Remove channel if there is no users anymore */
+ if (server->server_type == SILC_ROUTER &&
+ silc_hash_table_count(channel->user_list) < 2) {
+ if (channel->rekey)
+ silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
+ if (!silc_idlist_del_channel(server->local_list, channel))
+ silc_idlist_del_channel(server->global_list, channel);
+ silc_buffer_free(clidp);
+ server->stat.my_channels--;
+ return FALSE;
+ }
- channel->id = NULL;
+ /* Remove client from channel's client list */
+ silc_hash_table_del(channel->user_list, chl->client);
+ silc_free(chl);
+ server->stat.my_chanclients--;
+
+ /* If there is no global users on the channel anymore mark the channel
+ as local channel. */
+ if (server->server_type == SILC_SERVER &&
+ !silc_server_channel_has_global(channel))
+ channel->global_users = FALSE;
+
+ /* If there is not at least one local user on the channel then we don't
+ need the channel entry anymore, we can remove it safely. */
+ if (server->server_type == SILC_SERVER &&
+ !silc_server_channel_has_local(channel)) {
+ /* Notify about leaving client if this channel has global users. */
+ if (notify && channel->global_users)
+ silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
+ SILC_NOTIFY_TYPE_LEAVE, 1,
+ clidp->data, clidp->len);
+
+ silc_buffer_free(clidp);
+
+ if (channel->rekey)
+ silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
- silc_list_start(channel->user_list);
- while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- silc_list_del(chl2->client->channels, chl2);
- silc_list_del(channel->user_list, chl2);
- silc_free(chl2);
- }
- return FALSE;
+ if (channel->founder_key) {
+ /* The founder auth data exists, do not remove the channel entry */
+ SilcChannelClientEntry chl2;
+ SilcHashTableList htl2;
+
+ channel->id = NULL;
+
+ silc_hash_table_list(channel->user_list, &htl2);
+ while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
+ silc_hash_table_del(chl2->client->channels, channel);
+ silc_hash_table_del(channel->user_list, chl2->client);
+ silc_free(chl2);
}
-
- if (!silc_idlist_del_channel(server->local_list, channel))
- silc_idlist_del_channel(server->global_list, channel);
- server->stat.my_channels--;
return FALSE;
}
- /* Send notify to channel about client leaving the channel */
- if (notify)
- silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
- SILC_NOTIFY_TYPE_LEAVE, 1,
- clidp->data, clidp->len);
- break;
+ /* Remove the channel entry */
+ if (!silc_idlist_del_channel(server->local_list, channel))
+ silc_idlist_del_channel(server->global_list, channel);
+ server->stat.my_channels--;
+ return FALSE;
}
+ /* Send notify to channel about client leaving the channel */
+ if (notify)
+ silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
+ SILC_NOTIFY_TYPE_LEAVE, 1,
+ clidp->data, clidp->len);
+
silc_buffer_free(clidp);
return TRUE;
}
int silc_server_client_on_channel(SilcClientEntry client,
SilcChannelEntry channel)
{
- SilcChannelClientEntry chl;
-
if (!client || !channel)
return FALSE;
- silc_list_start(client->channels);
- while ((chl = silc_list_get(client->channels)) != SILC_LIST_END)
- if (chl->channel == channel)
- return TRUE;
+ if (silc_hash_table_find(client->channels, channel, NULL, NULL))
+ return TRUE;
return FALSE;
}
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");
}
NULL, key, newhmac);
if (!entry) {
silc_free(channel_name);
+ silc_cipher_free(key);
+ silc_hmac_free(newhmac);
return NULL;
}
SilcBuffer *channel_users_modes)
{
SilcChannelClientEntry chl;
+ SilcHashTableList htl;
SilcBuffer chidp, clidp;
SilcBuffer tmp;
int len;
/* Now find all users on the channel */
chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
/* JOIN Notify */
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);
uint32 *user_count)
{
SilcChannelClientEntry chl;
+ SilcHashTableList htl;
SilcBuffer client_id_list;
SilcBuffer client_mode_list;
SilcBuffer idp;
/* XXX rewrite - this does not support IPv6 based Client ID's. */
- client_id_list = silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) *
- silc_list_count(channel->user_list));
- client_mode_list = silc_buffer_alloc(4 *
- silc_list_count(channel->user_list));
+ client_id_list =
+ silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) *
+ silc_hash_table_count(channel->user_list));
+ client_mode_list =
+ silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
/* Client ID */
idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
silc_buffer_put(client_id_list, idp->data, idp->len);
/* We don't have that client anywhere, add it. The client is added
to global list since server didn't have it in the lists so it must be
global. */
- client = silc_idlist_add_client(server->global_list, NULL, 0, NULL,
- NULL,
+ client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
silc_id_dup(client_id, SILC_ID_CLIENT),
sock->user_data, NULL);
if (!client) {
chl->client = client;
chl->mode = mode;
chl->channel = channel;
- silc_list_add(channel->user_list, chl);
- silc_list_add(client->channels, chl);
+ silc_hash_table_add(channel->user_list, chl->client, chl);
+ silc_hash_table_add(client->channels, chl->channel, chl);
}
}
}
SilcBuffer buffer = NULL;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
+ SilcHashTableList htl;
unsigned char *cid;
uint32 id_len;
uint16 name_len;
int len;
- silc_list_start(client->channels);
- while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
+ silc_hash_table_list(client->channels, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
channel = chl->channel;
if (channel->mode & SILC_CHANNEL_MODE_SECRET)
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)