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();
/* Initialize ID caches */
server->local_list->clients =
- silc_idcache_alloc(0, silc_idlist_client_destructor);
- server->local_list->servers = silc_idcache_alloc(0, NULL);
- server->local_list->channels = silc_idcache_alloc(0, NULL);
+ silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
+ server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
+ server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
/* These are allocated for normal server as well as these hold some
global information that the server has fetched from its router. For
router these are used as they are supposed to be used on router. */
server->global_list->clients =
- silc_idcache_alloc(0, silc_idlist_client_destructor);
- server->global_list->servers = silc_idcache_alloc(0, NULL);
- server->global_list->channels = silc_idcache_alloc(0, NULL);
+ silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
+ server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
+ server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
/* Allocate the entire socket list that is used in server. Eventually
all connections will have entry in this table (it is a table of
{
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);
silc_buffer_free(idp);
}
- if (silc_idcache_find_by_id(server->local_list->clients,
- SILC_ID_CACHE_ANY, SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(server->local_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
silc_idcache_list_free(list);
}
- if (silc_idcache_find_by_id(server->global_list->clients,
- SILC_ID_CACHE_ANY, SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(server->global_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
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 idp;
/* Go through all clients in the list */
- if (silc_idcache_find_by_id(id_list->servers, SILC_ID_CACHE_ANY,
- SILC_ID_SERVER, &list)) {
+ if (silc_idcache_get_all(id_list->servers, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
entry = (SilcServerEntry)id_cache->context;
SilcBuffer idp;
/* Go through all clients in the list */
- if (silc_idcache_find_by_id(id_list->clients, SILC_ID_CACHE_ANY,
- SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(id_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
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"));
/* Go through all channels in the list */
- if (silc_idcache_find_by_id(id_list->channels, SILC_ID_CACHE_ANY,
- SILC_ID_CHANNEL, &list)) {
+ if (silc_idcache_get_all(id_list->channels, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
channel = (SilcChannelEntry)id_cache->context;
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)