SilcUInt32 tmp_len;
bool local;
- SILC_LOG_DEBUG(("Start"));
-
if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
- packet->src_id_type != SILC_ID_SERVER)
- return;
-
- if (!packet->dst_id)
+ packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
+ SILC_LOG_DEBUG(("Bad notify packet received"));
return;
+ }
/* If the packet is destined directly to a client then relay the packet
before processing it. */
goto out;
if (!server->standalone)
- silc_server_packet_send_dest(server, server->router->connection,
+ silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
packet->type, packet->flags |
SILC_PACKET_FLAG_BROADCAST,
channel_id, SILC_ID_CHANNEL,
} else {
/* Packet is destined to client or server */
if (!server->standalone)
- silc_server_packet_send(server, server->router->connection,
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
packet->buffer->data, packet->buffer->len,
server->stat.cell_clients--;
SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+ silc_schedule_task_del_by_context(server->schedule, client);
/* Remove the client from all channels. */
silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
silc_server_check_watcher_list(server, client, NULL,
SILC_NOTIFY_TYPE_SIGNOFF);
+ /* Remove this client from watcher list if it is */
+ silc_server_del_from_watcher_list(server, client);
+
client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
break;
SILC_GET32_MSB(mode, tmp);
/* Check if mode changed */
- if (channel->mode == mode)
+ if (channel->mode == mode) {
+ SILC_LOG_DEBUG(("Mode is changed already"));
break;
+ }
/* Get user's channel entry and check that mode change is allowed */
if (client) {
}
}
- /* Send the same notify to the channel */
- silc_server_packet_send_to_channel(server, sock, channel, packet->type,
- FALSE, packet->buffer->data,
- packet->buffer->len, FALSE);
-
/* If the channel had private keys set and the mode was removed then
we must re-generate and re-distribute a new channel key */
if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
channel->passphrase, NULL);
}
+ /* Send the same notify to the channel */
+ silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
+ FALSE, packet->buffer->data,
+ packet->buffer->len, FALSE);
+
/* Change mode */
channel->mode = mode;
silc_hash_table_list(channel->user_list, &htl);
while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
- mode &= ~SILC_CHANNEL_UMODE_CHANFO;
- silc_server_force_cumode_change(server, sock, channel,
- chl, mode);
- notify_sent = TRUE;
+ /* If the founder on the channel is not the one whom has set
+ the founder mode, then it's possible that this CUMODE_CHANGE
+ is correct. Due to netsplits it's possible that this
+ situation happens. */
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
+ (channel->founder_key && chl2->client->data.public_key &&
+ silc_pkcs_public_key_compare(
+ channel->founder_key,
+ chl2->client->data.public_key))) {
+ mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, sock, channel,
+ chl, mode);
+ notify_sent = TRUE;
+ }
break;
}
silc_hash_table_list_reset(&htl);
silc_pkcs_public_key_free(founder_key);
}
- if (server->server_type == SILC_ROUTER && chl->mode == mode) {
+ if (chl->mode == mode) {
SILC_LOG_DEBUG(("Mode is changed already"));
break;
}
/* Send the same notify to the channel */
if (!notify_sent)
- silc_server_packet_send_to_channel(server, sock, channel,
+ silc_server_packet_send_to_channel(server, NULL, channel,
packet->type,
FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
client_id, client, 0, NULL);
/* Notify our router about new client on the SILC network */
- if (!server->standalone)
- silc_server_send_new_id(server, (SilcSocketConnection)
- server->router->connection,
- server->server_type == SILC_ROUTER ? TRUE : FALSE,
- client->id, SILC_ID_CLIENT, id_len);
+ silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), client->id,
+ SILC_ID_CLIENT, id_len);
/* Distribute to backup routers */
if (server->server_type == SILC_ROUTER) {
to our router. If we are normal server we won't send anything
since this connection must be our router connection. */
if (server->server_type == SILC_ROUTER && !server->standalone &&
- server->router->connection != sock)
- silc_server_send_new_id(server, server->router->connection,
+ SILC_PRIMARY_ROUTE(server) != sock)
+ silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
TRUE, new_server->id, SILC_ID_SERVER,
silc_id_get_len(server_id, SILC_ID_SERVER));
id_type == SILC_ID_SERVER &&
server->id_entry->server_type != SILC_BACKUP_ROUTER) {
id_list = server->global_list;
- router_sock = server->router ? server->router->connection : sock;
+ router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
}
} else {
void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
sock->type == SILC_SOCKET_TYPE_SERVER &&
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
- if (!server->standalone)
- silc_server_packet_send(server, server->router->connection,
- packet->type,
- packet->flags | SILC_PACKET_FLAG_BROADCAST,
- buffer->data, buffer->len, FALSE);
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
+ packet->type,
+ packet->flags | SILC_PACKET_FLAG_BROADCAST,
+ buffer->data, buffer->len, FALSE);
silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
sock->type == SILC_SOCKET_TYPE_SERVER &&
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
- if (!server->standalone)
- silc_server_packet_send(server, server->router->connection,
- packet->type,
- packet->flags | SILC_PACKET_FLAG_BROADCAST,
- packet->buffer->data,
- packet->buffer->len, FALSE);
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
+ packet->type,
+ packet->flags | SILC_PACKET_FLAG_BROADCAST,
+ packet->buffer->data,
+ packet->buffer->len, FALSE);
silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
sock->type == SILC_SOCKET_TYPE_SERVER &&
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
- if (!server->standalone)
- silc_server_packet_send(server, server->router->connection,
- packet->type,
- packet->flags | SILC_PACKET_FLAG_BROADCAST,
- packet->buffer->data,
- packet->buffer->len, FALSE);
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
+ packet->type,
+ packet->flags | SILC_PACKET_FLAG_BROADCAST,
+ packet->buffer->data,
+ packet->buffer->len, FALSE);
silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
goto out;
}
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
goto out;
}
}
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
goto out;
}
}
SilcChannelClientEntry chl;
SilcServerResumeResolve r;
- SILC_LOG_DEBUG(("Start"));
-
ret = silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING(&id_string, &id_len),
SILC_STR_END);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_free(client_id);
return;
}
r->server = server;
r->sock = silc_socket_dup(sock);
r->packet = silc_packet_context_dup(packet);
- r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
+ r->data = client_id;
silc_server_command_pending(server, SILC_COMMAND_WHOIS,
server->cmd_ident,
silc_server_command_resume_resolve, r);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_free(client_id);
}
return;
}
r->server = server;
r->sock = silc_socket_dup(sock);
r->packet = silc_packet_context_dup(packet);
- r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
+ r->data = client_id;
silc_server_command_pending(server, SILC_COMMAND_WHOIS,
server->cmd_ident,
silc_server_command_resume_resolve, r);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_free(client_id);
return;
}
}
resolve it first. */
if (!detached_client->data.public_key) {
if (server->server_type == SILC_SERVER && server->standalone) {
+ SILC_LOG_ERROR(("Detached client's public key not present, "
+ "closing connection"));
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_free(client_id);
} else {
/* We must retrieve the detached client's public key by sending
GETKEY command. Reprocess this packet after receiving the key */
SILC_LOG_DEBUG(("Resolving client public key"));
silc_server_send_command(server, dest_sock ? dest_sock :
- server->router->connection,
+ SILC_PRIMARY_ROUTE(server),
SILC_COMMAND_GETKEY, ++server->cmd_ident,
1, 1, idp->data, idp->len);
r = silc_calloc(1, sizeof(*r));
- if (!r)
+ if (!r) {
+ silc_free(client_id);
return;
+ }
r->server = server;
r->sock = silc_socket_dup(sock);
silc_buffer_free(idp);
}
+ silc_free(client_id);
return;
} else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
idata->public_key)) {
/* We require that the connection and resuming authentication data
must be using same key pair. */
+ SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
+ "closing connection"));
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_free(client_id);
return;
}
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
"Resuming not possible");
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_free(client_id);
return;
}
SILC_STR_END);
/* Send to primary router */
- if (!server->standalone)
- silc_server_packet_send(server, server->router->connection,
- SILC_PACKET_RESUME_CLIENT, 0,
- buf->data, buf->len, TRUE);
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
+ SILC_PACKET_RESUME_CLIENT, 0,
+ buf->data, buf->len, TRUE);
/* As router we must deliver this packet directly to the original
server whom this client was earlier. */
/* If the ID is not based in our ID then change it */
if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
+ silc_free(client_id);
while (!silc_id_create_client_id(server, server->id, server->rng,
server->md5hash, client->nickname,
&client_id)) {
if (nickfail > 9) {
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_BAD_NICKNAME, NULL);
+ if (sock->user_data)
+ silc_server_free_sock_user_data(server, sock, NULL);
return;
}
snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
if (nick_change) {
/* Notify about Client ID change, nickname doesn't actually change. */
- if (!server->standalone)
- silc_server_send_notify_nick_change(server, server->router->connection,
- FALSE, client->id, client_id,
- client->nickname);
+ silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server),
+ client->id, client_id,
+ client->nickname);
}
/* Resolve users on those channels that client has joined but we
SILC_LOG_DEBUG(("Resolving users for %s channel",
channel->channel_name));
if (channel->disabled || !channel->users_resolved) {
- silc_server_send_command(server, server->router->connection,
+ silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
SILC_COMMAND_USERS, ++server->cmd_ident,
1, 2, channel->channel_name,
strlen(channel->channel_name));
silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
keyp->data, keyp->len, FALSE);
- if (created && server->server_type == SILC_SERVER &&
- !server->standalone)
- silc_server_packet_send(server, server->router->connection,
+ if (created && server->server_type == SILC_SERVER)
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_CHANNEL_KEY, 0,
keyp->data, keyp->len, FALSE);
SilcServerEntry server_entry;
SilcServerID *server_id;
- if (!client_id)
+ if (!client_id) {
+ SILC_LOG_DEBUG(("Malformed resuming packet"));
return;
+ }
/* Get entry to the client, and resolve it if we don't have it. */
detached_client = silc_idlist_find_client_by_id(server->local_list,
if (!detached_client) {
detached_client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
- if (!detached_client)
+ if (!detached_client) {
+ SILC_LOG_DEBUG(("Resuming client is unknown"));
+ silc_free(client_id);
return;
+ }
}
/* Check that the client has not been resumed already because it is
/* The client is clearly attempting to resume more than once and
perhaps playing around by resuming from several different places
at the same time. */
+ SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
silc_server_kill_client(server, detached_client, NULL,
server->id, SILC_ID_SERVER);
+ silc_free(client_id);
return;
}
/* Check whether client is detached at all */
- if (!(detached_client->mode & SILC_UMODE_DETACHED))
+ if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
+ SILC_LOG_DEBUG(("Client is not detached"));
+ silc_free(client_id);
return;
+ }
/* Client is detached, and now it is resumed. Remove the detached
mode and mark that it is resumed. */
/* Get the new owner of the resumed client */
server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
packet->src_id_type);
- if (!server_id)
+ if (!server_id) {
+ silc_free(client_id);
return;
+ }
/* Get server entry */
server_entry = silc_idlist_find_server_by_id(server->global_list,
local = FALSE;
if (!server_entry) {
silc_free(server_id);
+ silc_free(client_id);
return;
}
}
sock->type == SILC_SOCKET_TYPE_SERVER &&
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
- if (!server->standalone)
- silc_server_packet_send(server, server->router->connection,
- packet->type,
- packet->flags | SILC_PACKET_FLAG_BROADCAST,
- buffer->data, buffer->len, FALSE);
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
+ packet->type,
+ packet->flags | SILC_PACKET_FLAG_BROADCAST,
+ buffer->data, buffer->len, FALSE);
silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,