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);
}
SilcServerCommand *cmd;
SilcCommand command;
- SILC_LOG_DEBUG(("Start"));
-
/* Allocate command context. This must be free'd by the
command routine receiving it. */
ctx = silc_server_command_alloc();
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);
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;
}
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,
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);
+ 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,
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,
- chl->mode, client->id, SILC_ID_CLIENT,
- client->id, channel->founder_key);
}
}
+ /* 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);
/* 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);
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_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);
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) ?
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);
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 */
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);
+ silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel,
+ target_client->id, client->id, comment);
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Re-generate channel key */
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);
}
SilcClientID *client_id = (SilcClientID *)q->sock;
SilcClientEntry client;
- SILC_LOG_DEBUG(("Start"));
-
client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
- FALSE, NULL);
-
- if (client && client->mode & SILC_UMODE_DETACHED)
+ 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);
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 */
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);
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);
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);
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);
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);