+Tue Nov 28 11:05:39 EET 2000 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Added silc_server_command_add_to_channel internal routine to add
+ the client to the channel after router has created the channel and
+ sent command reply to the server.
+
+ * Added generic silc_server_send_command to send any command from
+ server.
+
Mon Nov 27 21:39:40 EET 2000 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Fixed a channel user mode bug when joining to a channel server gave
silc_free(idp);
}
+/* Internal routine that is called after router has replied to server's
+ JOIN command it forwarded to the router. The route has joined and possibly
+ creaetd the channel. This function adds the client to the channel's user
+ list. */
+
+SILC_SERVER_CMD_FUNC(add_to_channel)
+{
+ SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+ SilcServer server = cmd->server;
+ SilcClientEntry client;
+ SilcChannelEntry channel;
+ SilcChannelClientEntry chl;
+ char *channel_name;
+
+ /* Get channel name */
+ channel_name = silc_argument_get_arg_type(cmd->args, 1, NULL);
+
+ /* Get client entry */
+ client = (SilcClientEntry)cmd->sock->user_data;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_name(server->local_list, channel_name);
+ if (channel) {
+ /* Join the client to the channel by adding it to channel's user list.
+ Add also the channel to client entry's channels list for fast cross-
+ referencing. */
+ chl = silc_calloc(1, sizeof(*chl));
+ //chl->mode = SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO;
+ chl->client = client;
+ chl->channel = channel;
+ silc_list_add(channel->user_list, chl);
+ silc_list_add(client->channels, chl);
+ }
+
+ silc_server_command_free(cmd);
+}
+
/* Internal routine to join channel. The channel sent to this function
has been either created or resolved from ID lists. This joins the sent
client to the channel. */
reply->data, reply->len, FALSE);
/* Distribute new channel key to local cell and local clients. */
- silc_server_send_channel_key(server, sock, channel, TRUE);
+ silc_server_send_channel_key(server, channel, FALSE);
/* Distribute JOIN notify into the cell for everbody on the channel */
silc_server_send_notify_to_channel(server, channel, FALSE,
/* Send the channel key. Channel key is sent before any other packet
to the channel. */
- silc_server_send_channel_key(server, sock, channel, server->standalone ?
+ silc_server_send_channel_key(server, channel, server->standalone ?
FALSE : TRUE);
/* Send JOIN notify to locally connected clients on the channel */
server->router->connection,
cmd->packet->buffer->data,
cmd->packet->buffer->len, TRUE);
- goto out;
+
+ /* Register handler that will be called after the router has replied
+ to us. We will add the client to the new channel in this callback
+ function. Will be called from JOIN command reply. */
+ silc_server_command_pending(server, SILC_COMMAND_JOIN,
+ ++server->router->data.cmd_ident,
+ silc_server_command_add_to_channel,
+ context);
+ return;
}
/* We are router and the channel does not seem exist so we will check
if (is_op && !is_fo)
return FALSE;
} else {
- if (channel->mode & SILC_CHANNEL_MODE_PRIVATE) {
+ if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
if (is_op && !is_fo)
return FALSE;
}
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
- SilcSocketConnection sock = cmd->sock;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
SilcChannelID *channel_id;
- SilcClientID *client_id;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcBuffer packet, cidp;
unsigned char *tmp, *tmp_id, *tmp_mask;
unsigned int argc, mode_mask, tmp_len, tmp_len2;
- int i;
SILC_LOG_DEBUG(("Start"));
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
- SilcSocketConnection sock = cmd->sock;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
SilcChannelID *channel_id;
SilcClientID *client_id;
SilcClientEntry target_client;
SilcChannelClientEntry chl;
SilcBuffer packet, idp;
- unsigned char *tmp, *tmp_id, *tmp_mask;
+ unsigned char *tmp_id, *tmp_mask;
unsigned int argc, target_mask, sender_mask, tmp_len;
- int i, notify = FALSE;
+ int notify = FALSE;
SILC_LOG_DEBUG(("Start"));
SILC_SERVER_CMD_FUNC(kick)
{
- SilcServerCommandContext cmd = (SilcServerCommandContext)context;
- SilcServer server = cmd->server;
- SilcSocketConnection sock = cmd->sock;
- SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
-
}
SILC_SERVER_CMD_FUNC(restart)
/* Remove old key if exists */
if (channel->key) {
memset(channel->key, 0, channel->key_len);
- silc_free(channel_key);
+ silc_free(channel->key);
silc_cipher_free(channel->channel_key);
exist = TRUE;
}
tmp, tmp_len);
/* Distribute the key to everybody who is on the channel. If we are router
- we will also send it to locally connected servers. If we are normal
- server and old key did not exist then we don't use this function
- as the client is not in our channel user list just yet. We send the
- key after receiveing JOIN notify from router. */
- if (server->server_type == SILC_SERVER && exist)
- silc_server_send_channel_key(server, channel, FALSE);
- if (server->server_type == SILC_ROUTER)
- silc_server_send_channel_key(server, channel, FALSE);
+ we will also send it to locally connected servers. */
+ silc_server_send_channel_key(server, channel, FALSE);
out:
if (id)
switch(id_type) {
case SILC_ID_CLIENT:
- {
- SilcClientEntry idlist;
-
- SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
- silc_id_render(id, SILC_ID_CLIENT),
- sock->type == SILC_SOCKET_TYPE_SERVER ?
- "Server" : "Router", sock->hostname));
-
- /* Add the client to our local list. We are router and we keep
- cell specific local database of all clients in the cell. */
- idlist = silc_idlist_add_client(id_list, NULL, NULL, NULL,
- id, router, router_sock);
- }
+ SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
+ silc_id_render(id, SILC_ID_CLIENT),
+ sock->type == SILC_SOCKET_TYPE_SERVER ?
+ "Server" : "Router", sock->hostname));
+
+ /* Add the client to our local list. We are router and we keep
+ cell specific local database of all clients in the cell. */
+ silc_idlist_add_client(id_list, NULL, NULL, NULL, id, router, router_sock);
break;
case SILC_ID_SERVER:
- {
- SilcServerEntry idlist;
-
- SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
- silc_id_render(id, SILC_ID_SERVER),
- sock->type == SILC_SOCKET_TYPE_SERVER ?
- "Server" : "Router", sock->hostname));
-
- /* Add the server to our local list. We are router and we keep
- cell specific local database of all servers in the cell. */
- idlist = silc_idlist_add_server(id_list, NULL, 0, id, router,
- router_sock);
- }
+ SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
+ silc_id_render(id, SILC_ID_SERVER),
+ sock->type == SILC_SOCKET_TYPE_SERVER ?
+ "Server" : "Router", sock->hostname));
+
+ /* Add the server to our local list. We are router and we keep
+ cell specific local database of all servers in the cell. */
+ silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
break;
case SILC_ID_CHANNEL:
SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
-#if 0
- SILC_LOG_DEBUG(("New channel id(%s) from [%s] %s",
- silc_id_render(id, SILC_ID_CHANNEL),
- sock->type == SILC_SOCKET_TYPE_SERVER ?
- "Server" : "Router", sock->hostname));
-
- /* Add the channel to our local list. We are router and we keep
- cell specific local database of all channels in the cell. */
- silc_idlist_add_channel(id_list, NULL, 0, id, router, NULL);
-#endif
break;
default:
SilcNotifyPayload payload;
SilcNotifyType type;
SilcArgumentPayload args;
- SilcClientID *client_id;
SilcChannelID *channel_id;
- SilcClientEntry client;
SilcChannelEntry channel;
- unsigned char *tmp;
- unsigned int tmp_len;
- int i;
SILC_LOG_DEBUG(("Start"));
switch(type) {
case SILC_NOTIFY_TYPE_JOIN:
- {
- /* Get Client ID */
- tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
- if (!tmp)
- goto out;
-
- client_id = silc_id_payload_parse_id(tmp, tmp_len);
-
- /* Get client entry */
- client = silc_idlist_find_client_by_id(server->local_list, client_id);
- if (!client) {
- silc_free(client_id);
- goto out;
- }
-
- // channel_id = ;
-
- /* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
- if (!channel) {
- silc_free(client_id);
- goto out;
- }
-
- silc_free(client_id);
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+
+ channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
+ if (!channel) {
+ silc_free(channel_id);
+ goto out;
}
+
+ /* Send to channel */
+ silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
+ packet->buffer->data,
+ packet->buffer->len, FALSE);
break;
case SILC_NOTIFY_TYPE_LEAVE:
SilcBuffer clidp;
void *tmpid;
+ SILC_LOG_DEBUG(("Start"));
+
if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
server->server_type != SILC_ROUTER ||
packet->src_id_type != SILC_ID_SERVER)
it is assured that this is sent only to our local clients and locally
connected servers if needed. */
clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
- silc_server_send_notify_to_channel(server, channel, TRUE,
+ silc_server_send_notify_to_channel(server, channel, FALSE,
SILC_NOTIFY_TYPE_JOIN,
1, clidp->data, clidp->len);
silc_buffer_free(clidp);
must not be broadcasted packet. */
void silc_server_send_channel_key(SilcServer server,
- SilcSocketConnection sock,
SilcChannelEntry channel,
unsigned char route)
{
silc_buffer_free(packet);
silc_free(chid);
}
+
+/* Generic function to send any command. The arguments must be sent already
+ encoded into correct form in correct order. */
+
+void silc_server_send_command(SilcServer server,
+ SilcSocketConnection sock,
+ SilcCommand command,
+ unsigned int argc, ...)
+{
+ SilcBuffer packet;
+ va_list ap;
+
+ va_start(ap, argc);
+
+ packet = silc_command_payload_encode_vap(command, 0, argc, ap);
+ silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
+ packet->data, packet->len, TRUE);
+ silc_buffer_free(packet);
+}
void *client_id,
unsigned int client_id_len);
void silc_server_send_channel_key(SilcServer server,
- SilcSocketConnection sock,
SilcChannelEntry channel,
unsigned char route);
+void silc_server_send_command(SilcServer server,
+ SilcSocketConnection sock,
+ SilcCommand command,
+ unsigned int argc, ...);
#endif