do { \
SilcUInt32 _argc; \
\
- SILC_LOG_DEBUG(("Start")); \
- \
if (silc_server_command_pending_error_check(cmd, context2, command)) { \
+ SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \
silc_server_command_free(cmd); \
return; \
} \
\
_argc = silc_argument_get_arg_num(cmd->args); \
if (_argc < min) { \
+ SILC_LOG_DEBUG(("Not enough parameters in command")); \
silc_server_command_send_status_reply(cmd, command, \
SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
0); \
return; \
} \
if (_argc > max) { \
+ SILC_LOG_DEBUG(("Too many parameters in command")); \
silc_server_command_send_status_reply(cmd, command, \
SILC_STATUS_ERR_TOO_MANY_PARAMS, \
0); \
SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
if (!client) {
+ SILC_LOG_DEBUG(("Client entry is invalid"));
silc_server_command_free(timeout->ctx);
silc_free(timeout);
}
/* Update access time */
client->last_command = time(NULL);
- if (!(timeout->cmd->flags & SILC_CF_REG))
+ if (!(timeout->cmd->flags & SILC_CF_REG)) {
+ SILC_LOG_DEBUG(("Calling %s command",
+ silc_get_command_name(timeout->cmd->cmd)));
timeout->cmd->cb(timeout->ctx, NULL);
- else if (silc_server_is_registered(timeout->ctx->server,
- timeout->ctx->sock,
- timeout->ctx,
- timeout->cmd->cmd))
+ } else if (silc_server_is_registered(timeout->ctx->server,
+ timeout->ctx->sock,
+ timeout->ctx,
+ timeout->cmd->cmd)) {
+ SILC_LOG_DEBUG(("Calling %s command",
+ silc_get_command_name(timeout->cmd->cmd)));
timeout->cmd->cb(timeout->ctx, NULL);
- else
+ } else {
+ SILC_LOG_DEBUG(("Client is not registered"));
silc_server_command_free(timeout->ctx);
+ }
silc_free(timeout);
}
packet->buffer->len);
if (!ctx->payload) {
SILC_LOG_ERROR(("Bad command payload, packet dropped"));
- silc_buffer_free(packet->buffer);
silc_packet_context_free(packet);
silc_socket_free(ctx->sock);
silc_free(ctx);
break;
if (!cmd || !cmd->cb) {
+ SILC_LOG_DEBUG(("Unknown command %d", command));
silc_server_command_send_status_reply(ctx, command,
SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
silc_server_command_free(ctx);
/* Execute for server */
- if (!(cmd->flags & SILC_CF_REG))
+ if (!(cmd->flags & SILC_CF_REG)) {
+ SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
cmd->cb(ctx, NULL);
- else if (silc_server_is_registered(server, sock, ctx, cmd->cmd))
+ } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) {
+ SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
cmd->cb(ctx, NULL);
- else
+ } else {
+ SILC_LOG_DEBUG(("Server is not registered"));
silc_server_command_free(ctx);
+ }
}
/* Allocate Command Context */
/* Send WHOIS command to our router */
silc_server_packet_send(server, (SilcSocketConnection)
- server->router->connection,
+ SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
/* Send WHOWAS command to our router */
- silc_server_packet_send(server, (SilcSocketConnection)
- server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
/* Send IDENTIFY command to our router */
silc_server_packet_send(server, (SilcSocketConnection)
- server->router->connection,
+ SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
/* Send notify about nickname change to our router. We send the new
ID and ask to replace it with the old one. If we are router the
packet is broadcasted. Send NICK_CHANGE notify. */
- if (!server->standalone)
- silc_server_send_notify_nick_change(server, server->router->connection,
- server->server_type == SILC_SERVER ?
- FALSE : TRUE, client->id,
- new_id, nick);
+ silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), client->id,
+ new_id, nick);
/* Check if anyone is watching the old nickname */
if (server->server_type == SILC_ROUTER)
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
goto out;
}
- /* Set the topic for channel */
- silc_free(channel->topic);
- channel->topic = strdup(tmp);
+ if (!channel->topic || strcmp(channel->topic, tmp)) {
+ /* Set the topic for channel */
+ silc_free(channel->topic);
+ channel->topic = strdup(tmp);
- /* Send TOPIC_SET notify type to the network */
- if (!server->standalone)
- silc_server_send_notify_topic_set(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
+ /* Send TOPIC_SET notify type to the network */
+ silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
client->id, SILC_ID_CLIENT,
channel->topic);
- idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
-
- /* Send notify about topic change to all clients on the channel */
- silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
- SILC_NOTIFY_TYPE_TOPIC_SET, 2,
- idp->data, idp->len,
- channel->topic, strlen(channel->topic));
- silc_buffer_free(idp);
+ /* Send notify about topic change to all clients on the channel */
+ idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+ silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
+ SILC_NOTIFY_TYPE_TOPIC_SET, 2,
+ idp->data, idp->len,
+ channel->topic,
+ strlen(channel->topic));
+ silc_buffer_free(idp);
+ }
}
/* Send the topic to client as reply packet */
}
/* Send notify to the primary router */
- if (!server->standalone)
- silc_server_send_notify_invite(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- sender->id, add, del);
+ silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
+ sender->id, add, del);
/* Send command reply */
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
++server->cmd_ident, 1,
1, idp->data, idp->len);
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, 0, packet->data,
packet->len, FALSE);
char check[512], check2[512];
bool founder = FALSE;
bool resolve;
+ unsigned char *fkey = NULL;
+ SilcUInt32 fkey_len = 0;
- SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Joining client to channel"));
if (!channel)
return;
*/
if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
SilcIDListData idata = (SilcIDListData)client;
+ SilcChannelClientEntry chl2;
+ SilcHashTableList htl;
if (channel->founder_key && idata->public_key &&
silc_pkcs_public_key_compare(channel->founder_key,
if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
channel->founder_key, 0, server->sha1hash,
client->id, SILC_ID_CLIENT)) {
+
+ /* There cannot be anyone else as founder on the channel now. This
+ client is definitely the founder due to this authentication */
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+ if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, NULL, channel, chl2,
+ chl2->mode);
+ break;
+ }
+ silc_hash_table_list_reset(&htl);
+
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
founder = TRUE;
}
silc_free(tmp);
}
+ if (channel->founder_key)
+ fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
+
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
- SILC_STATUS_OK, 0, ident, 13,
+ SILC_STATUS_OK, 0, ident, 14,
2, channel->channel_name,
strlen(channel->channel_name),
3, chidp->data, chidp->len,
12, tmp3, 4,
13, user_list->data, user_list->len,
14, mode_list->data,
- mode_list->len);
+ mode_list->len,
+ 15, fkey, fkey_len);
/* Send command reply */
silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
we'll ignore it (in packet_receive.c) so we must send it here. If
we are router then this will send it to local clients and local
servers. */
+ SILC_LOG_DEBUG(("Send JOIN notify to channel"));
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
SILC_NOTIFY_TYPE_JOIN, 2,
clidp->data, clidp->len,
chidp->data, chidp->len);
+ /* Update statistics */
+ server->stat.my_chanclients++;
+ if (server->server_type == SILC_ROUTER) {
+ server->stat.cell_chanclients++;
+ server->stat.chanclients++;
+ }
+
if (!cmd->pending) {
/* Send JOIN notify packet to our primary router */
- if (!server->standalone)
- silc_server_send_notify_join(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, client->id);
+ silc_server_send_notify_join(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel, client->id);
if (keyp)
/* Distribute the channel key to all backup routers. */
notify the mode change to the channel. */
if (founder) {
SILC_PUT32_MSB(chl->mode, mode);
- tmp = silc_pkcs_public_key_encode(channel->founder_key, &tmp_len);
+ SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
clidp->data, clidp->len,
mode, 4, clidp->data, clidp->len,
- tmp, tmp_len);
- silc_free(tmp);
-
- /* Set CUMODE notify type to network */
- if (!server->standalone)
- silc_server_send_notify_cumode(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- chl->mode, client->id, SILC_ID_CLIENT,
- client->id, channel->founder_key);
+ fkey, fkey_len);
}
}
+ /* Set CUMODE notify type to network */
+ if (founder)
+ silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
+ chl->mode, client->id, SILC_ID_CLIENT,
+ client->id, channel->founder_key);
+
silc_buffer_free(reply);
silc_buffer_free(clidp);
silc_buffer_free(chidp);
silc_buffer_free(keyp);
silc_buffer_free(user_list);
silc_buffer_free(mode_list);
+ silc_free(fkey);
out:
silc_free(passphrase);
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
+ silc_free(client_id);
client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
if (!channel ||
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
0);
+ silc_free(client_id);
goto out;
}
/* If this is pending command callback then we've resolved
it and it didn't work, return since we've notified the
client already in the command reply callback. */
- if (cmd->pending)
+ if (cmd->pending) {
+ silc_free(client_id);
goto out;
+ }
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
/* Send JOIN command to our router */
silc_server_packet_send(server, (SilcSocketConnection)
- server->router->connection,
+ SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
cmd->pending = TRUE;
silc_command_set_ident(cmd->payload, old_ident);
silc_buffer_free(tmpbuf);
+ silc_free(client_id);
goto out;
}
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
+ silc_free(client_id);
goto out;
}
something went wrong with the joining as the channel was not found.
We can't do anything else but ignore this. */
if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
- server->server_type != SILC_ROUTER)
+ server->server_type != SILC_ROUTER) {
+ silc_free(client_id);
goto out;
+ }
/* We are router and the channel does not seem exist so we will check
our global list as well for the channel. */
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
+ silc_free(client_id);
goto out;
}
SILC_GET32_MSB(created, tmp);
if (silc_argument_get_arg_type(reply->args, 7, NULL))
create_key = FALSE; /* Router returned the key already */
+
+ if (silc_command_get_status(reply->payload, NULL, NULL) &&
+ channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
+ /* Save channel passphrase, if user provided it successfully */
+ unsigned char *pa;
+ SilcUInt32 pa_len;
+ pa = silc_argument_get_arg_type(reply->args, 3, &pa_len);
+ if (pa) {
+ silc_free(channel->passphrase);
+ channel->passphrase = silc_memdup(pa, pa_len);
+ }
+ }
}
if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
- !silc_hash_table_count(channel->user_list))
+ !channel->disabled && !silc_hash_table_count(channel->user_list))
created = TRUE;
}
if (server->config && server->config->server_info &&
server->config->server_info->motd_file) {
/* Send motd */
- motd = silc_file_readfile(server->config->server_info->motd_file, &motd_len);
+ motd = silc_file_readfile(server->config->server_info->motd_file,
+ &motd_len);
if (!motd)
goto out;
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
}
}
+ /* Update statistics */
+ if (mask & SILC_UMODE_GONE) {
+ if (!(client->mode & SILC_UMODE_GONE))
+ server->stat.my_aways++;
+ } else {
+ if (client->mode & SILC_UMODE_GONE)
+ server->stat.my_aways--;
+ }
+
/* Change the mode */
client->mode = mask;
/* Send UMODE change to primary router */
- if (!server->standalone)
- silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, client->mode);
+ silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), client->id,
+ client->mode);
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
/* Check that client has rights to change any requested channel modes */
if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
mode_mask)) {
+ SILC_LOG_DEBUG(("Client does not have rights to change mode"));
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_CMODE,
(!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
/* Save the public key */
channel->founder_key = silc_pkcs_public_key_copy(idata->public_key);
+ if (!channel->founder_key) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
+ goto out;
+ }
+
founder_key = channel->founder_key;
fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
+ if (!fkey) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
+ goto out;
+ }
}
}
} else {
fkey, fkey_len);
/* Set CMODE notify type to network */
- if (!server->standalone)
- silc_server_send_notify_cmode(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- mode_mask, client->id, SILC_ID_CLIENT,
- cipher, hmac, passphrase, founder_key);
+ silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
+ mode_mask, client->id, SILC_ID_CLIENT,
+ cipher, hmac, passphrase, founder_key);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
3, tmp_mask, 4);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
-
+
silc_buffer_free(packet);
silc_buffer_free(cidp);
/* The client tries to claim the founder rights. */
unsigned char *tmp_auth;
SilcUInt32 tmp_auth_len;
+ SilcChannelClientEntry chl2;
+ SilcHashTableList htl;
if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
!channel->founder_key || !idata->public_key ||
goto out;
}
- sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
notify = TRUE;
founder_key = channel->founder_key;
fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
+ if (!fkey) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
+ goto out;
+ }
+
+ /* There cannot be anyone else as founder on the channel now. This
+ client is definitely the founder due to this authentication */
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+ if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, NULL, channel, chl2,
+ chl2->mode);
+ break;
+ }
+ silc_hash_table_list_reset(&htl);
+
+ sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
}
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
/* Promote to operator */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
- if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
- !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV,
- 0);
- goto out;
+ if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+ 0);
+ goto out;
}
chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
- !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV,
- 0);
- goto out;
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+ 0);
+ goto out;
}
-
+
/* Demote to normal user */
chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
notify = TRUE;
}
}
+ if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
+ if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
+ if (client == target_client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
+ }
+ chl->mode |= SILC_CHANNEL_UMODE_QUIET;
+ notify = TRUE;
+ }
+ } else {
+ if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
+ if (client == target_client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
+ }
+ chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
+ notify = TRUE;
+ }
+ }
+
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
fkey, fkey_len);
/* Set CUMODE notify type to network */
- if (!server->standalone)
- silc_server_send_notify_cumode(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- target_mask, client->id,
- SILC_ID_CLIENT,
- target_client->id, founder_key);
+ silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
+ target_mask, client->id, SILC_ID_CLIENT,
+ target_client->id, founder_key);
}
/* Send command reply to sender */
idp->data, idp->len);
silc_buffer_free(idp);
+ /* Send KICKED notify to primary route */
+ silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
+ target_client->id, client->id, comment);
+
/* Remove the client from the channel. If the channel does not exist
after removing the client then the client kicked itself off the channel
and we don't have to send anything after that. */
target_client, FALSE))
goto out;
- /* Send KICKED notify to primary route */
- if (!server->standalone)
- silc_server_send_notify_kicked(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- target_client->id, client->id, comment);
-
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Re-generate channel key */
if (!silc_server_create_channel_key(server, channel, 0))
server->stat.server_ops++;
/* Send UMODE change to primary router */
- if (!server->standalone)
- silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, client->mode);
+ silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), client->id,
+ client->mode);
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
SILC_TASK_CALLBACK(silc_server_command_detach_cb)
{
QuitInternal q = (QuitInternal)context;
- SilcClientEntry client = (SilcClientEntry)q->sock->user_data;
+ SilcClientID *client_id = (SilcClientID *)q->sock;
+ SilcClientEntry client;
+ SilcSocketConnection sock;
- /* If there is pending outgoing data for the client then purge it
- to the network before closing connection. */
- silc_server_packet_queue_purge(q->server, q->sock);
+ client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
+ TRUE, NULL);
+ if (client && client->connection) {
+ sock = client->connection;
- /* Close the connection on our side */
- client->router = NULL;
- client->connection = NULL;
- q->sock->user_data = NULL;
- silc_server_close_connection(q->server, q->sock);
+ /* If there is pending outgoing data for the client then purge it
+ to the network before closing connection. */
+ silc_server_packet_queue_purge(q->server, sock);
+ /* Close the connection on our side */
+ client->router = NULL;
+ client->connection = NULL;
+ sock->user_data = NULL;
+ silc_server_close_connection(q->server, sock);
+ }
+
+ silc_free(client_id);
silc_free(q);
}
SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
{
QuitInternal q = (QuitInternal)context;
- SilcClientEntry client = (SilcClientEntry)q->sock;
-
- SILC_LOG_DEBUG(("Start"));
+ SilcClientID *client_id = (SilcClientID *)q->sock;
+ SilcClientEntry client;
- if (client->mode & SILC_UMODE_DETACHED)
+ client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
+ TRUE, NULL);
+ if (client && client->mode & SILC_UMODE_DETACHED) {
+ SILC_LOG_DEBUG(("Detach timeout"));
silc_server_free_client_data(q->server, NULL, client, TRUE,
"Detach timeout");
+ }
+
+ silc_free(client_id);
silc_free(q);
}
if (server->config->detach_disabled) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
- SILC_STATUS_ERR_UNKNOWN_COMMAND,
- 0);
+ SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
goto out;
}
client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
client->last_command = 0;
client->fast_command = 0;
- if (!server->standalone)
- silc_server_send_notify_umode(server, server->router->connection,
- server->server_type == SILC_SERVER ?
- FALSE : TRUE, client->id, client->mode);
+ silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), client->id,
+ client->mode);
+ server->stat.my_detached++;
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
q = silc_calloc(1, sizeof(*q));
q->server = server;
- q->sock = cmd->sock;
+ q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
if (server->config->detach_timeout) {
q = silc_calloc(1, sizeof(*q));
q->server = server;
- q->sock = (void *)client;
+ q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
silc_schedule_task_add(server->schedule, 0,
silc_server_command_detach_timeout,
q, server->config->detach_timeout * 60,
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
silc_free(tmp);
}
+ /* Distribute the watch list to backup routers too */
+ if (server->backup) {
+ SilcBuffer tmpbuf;
+ silc_command_set_ident(cmd->payload, ++server->cmd_ident);
+ tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+ silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
+ cmd->packet->flags, tmpbuf->data, tmpbuf->len,
+ FALSE, TRUE);
+ silc_buffer_free(tmpbuf);
+ }
+
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
SILC_STATUS_OK, 0);
server->stat.router_ops++;
/* Send UMODE change to primary router */
- if (!server->standalone)
- silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, client->mode);
+ silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), client->id,
+ client->mode);
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
}
/* Send the BAN notify type to our primary router. */
- if (!server->standalone && (add || del))
- silc_server_send_notify_ban(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, add, del);
+ if (add || del)
+ silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel, add, del);
/* Send the reply back to the client */
packet =
/* Notify routers that they should remove this client from their list
of clients on the channel. Send LEAVE notify type. */
- if (!server->standalone)
- silc_server_send_notify_leave(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, id_entry->id);
+ silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel, id_entry->id);
silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
SILC_STATUS_OK, 0, 2, tmp, len);
channel = silc_idlist_find_channel_by_name(server->local_list,
channel_name, NULL);
- if (!channel || channel->disabled || !channel->users_resolved) {
+ if (!channel || (!server->standalone && (channel->disabled ||
+ !channel->users_resolved))) {
if (server->server_type != SILC_ROUTER && !server->standalone &&
!cmd->pending) {
SilcBuffer tmpbuf;
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
/* Send USERS command */
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);
}
/* Get the users list */
- silc_server_get_users_on_channel(server, channel, &client_id_list,
- &client_mode_list, &list_count);
+ if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
+ &client_mode_list, &list_count)) {
+ list_count = 0;
+ client_id_list = NULL;
+ client_mode_list = NULL;
+ }
/* List count */
SILC_PUT32_MSB(list_count, lc);
SILC_STATUS_OK, 0, ident, 4,
2, idp->data, idp->len,
3, lc, 4,
- 4, client_id_list->data,
- client_id_list->len,
- 5, client_mode_list->data,
- client_mode_list->len);
+ 4, client_id_list ?
+ client_id_list->data : NULL,
+ client_id_list ?
+ client_id_list->len : 0,
+ 5, client_mode_list ?
+ client_mode_list->data : NULL,
+ client_mode_list ?
+ client_mode_list->len : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(idp);
silc_buffer_free(packet);
- silc_buffer_free(client_id_list);
- silc_buffer_free(client_mode_list);
+ if (client_id_list)
+ silc_buffer_free(client_id_list);
+ if (client_mode_list)
+ silc_buffer_free(client_mode_list);
silc_free(id);
out:
SilcIdType id_type;
SilcPublicKey public_key;
- SILC_LOG_DEBUG(("Start"));
-
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_COMMAND, cmd->packet->flags,
tmpbuf->data, tmpbuf->len, TRUE);