channel_id, SILC_ID_CHANNEL,
packet->buffer->data,
packet->buffer->len, FALSE);
- silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send_dest(server, sock->user_data,
packet->type, packet->flags,
channel_id, SILC_ID_CHANNEL,
packet->buffer->data, packet->buffer->len,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
packet->buffer->data, packet->buffer->len,
FALSE);
- silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
/* Do not add client to channel if it is there already */
if (silc_server_client_on_channel(client, channel, NULL)) {
- SILC_LOG_DEBUG(("Client already on channel"));
+ SILC_LOG_DEBUG(("Client already on channel %s",
+ channel->channel_name));
break;
}
chl->client = client;
chl->channel = channel;
- /* If this is the first one on the channel then it is the founder of
- the channel. */
- if (!silc_hash_table_count(channel->user_list))
- chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
+ if (server->server_type != SILC_ROUTER ||
+ sock->type == SILC_SOCKET_TYPE_ROUTER) {
+ /* If this is the first one on the channel then it is the founder of
+ the channel. This is done on normal server and on router if this
+ notify is coming from router */
+ if (!silc_hash_table_count(channel->user_list)) {
+ SILC_LOG_DEBUG(("Client %s is founder on channel",
+ silc_id_render(chl->client->id, SILC_ID_CLIENT)));
+ chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
+ }
+ }
silc_hash_table_add(channel->user_list, client, chl);
silc_hash_table_add(client->channels, channel, chl);
if (server->server_type == SILC_SERVER &&
sock == SILC_PRIMARY_ROUTE(server) &&
mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
- SILC_LOG_DEBUG(("Founder public key received from primary router"));
+ SILC_LOG_DEBUG(("Founder public key received from router"));
tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
if (!tmp)
break;
is set on the channel now check whether this is the client that
originally set the mode. */
- /* Get public key that must be present in notify */
- tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
- if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
- &founder_key)) {
- chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
- silc_server_force_cumode_change(server, sock, channel, chl, mode);
- notify_sent = TRUE;
- break;
- }
-
if (channel->founder_key) {
+ /* Get public key that must be present in notify */
+ tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
+ if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
+ &founder_key)) {
+ chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, sock, channel, chl, mode);
+ notify_sent = TRUE;
+ break;
+ }
+
/* Now match the public key we have cached and public key sent.
They must match. */
if (client && client->data.public_key &&
/* Send the same notify to the channel */
if (!notify_sent)
- silc_server_packet_send_to_channel(server, NULL, channel,
- packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, NULL, channel,
+ packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
silc_free(channel_id);
}
silc_free(server_id);
- /* Free all client entries that this server owns as they will
- become invalid now as well. */
- silc_server_remove_clients_by_server(server, server_entry, TRUE);
+ /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
+ if (SILC_IS_LOCAL(server_entry))
+ break;
+
+ /* Remove all servers that are originated from this server, and
+ remove the clients of those servers too. */
+ silc_server_remove_servers_by_server(server, server_entry, TRUE);
+
+ /* Remove the clients that this server owns as they will become
+ invalid now too. */
+ silc_server_remove_clients_by_server(server, server_entry->router,
+ server_entry, TRUE);
+ silc_server_backup_del(server, server_entry);
/* Remove the server entry */
silc_idlist_del_server(local ? server->local_list :
goto out;
SILC_GET32_MSB(mode, tmp);
- /* Check that mode changing is allowed. */
- if (!silc_server_check_umode_rights(server, client, mode)) {
- SILC_LOG_DEBUG(("UMODE change is not allowed"));
- goto out;
- }
-
/* Remove internal resumed flag if client is marked detached now */
if (mode & SILC_UMODE_DETACHED)
client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
if (server->server_type != SILC_BACKUP_ROUTER) {
/* Distribute to local cell backup routers. */
- silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
SILC_PACKET_CHANNEL_KEY, 0,
buffer->data, buffer->len, FALSE, TRUE);
}
/* Distribute to backup routers */
if (server->server_type == SILC_ROUTER) {
SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
- silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
+ silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
idp->data, idp->len, FALSE, TRUE);
silc_buffer_free(idp);
}
if (server->server_type == SILC_ROUTER) {
/* Distribute to backup routers */
SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
- silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
+ silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
idp->data, idp->len, FALSE, TRUE);
silc_buffer_free(idp);
silc_server_announce_clients(server, 0, sock);
silc_server_announce_channels(server, 0, sock);
}
+
+ /* By default the servers connected to backup router are disabled
+ until backup router has become the primary */
+ if (server->server_type == SILC_BACKUP_ROUTER &&
+ sock->type == SILC_SOCKET_TYPE_SERVER)
+ idata->status |= SILC_IDLIST_STATUS_DISABLED;
}
return new_server;
packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
buffer->data, buffer->len, FALSE);
- silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
packet->flags | SILC_PACKET_FLAG_BROADCAST,
packet->buffer->data,
packet->buffer->len, FALSE);
- silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
return;
}
channel->disabled = TRUE;
- channel->mode = silc_channel_get_mode(payload);
+ if (server_entry->server_type != SILC_BACKUP_ROUTER)
+ channel->mode = silc_channel_get_mode(payload);
/* Send the new channel key to the server */
id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
/* Create new key for the channel and send it to the server and
everybody else possibly on the channel. */
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
- if (!silc_server_create_channel_key(server, channel, 0))
- return;
-
- /* Send to the channel */
- silc_server_send_channel_key(server, sock, channel, FALSE);
- id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
- id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
+
+ if (silc_hash_table_count(channel->user_list)) {
+ if (!silc_server_create_channel_key(server, channel, 0))
+ return;
+
+ /* Send to the channel */
+ silc_server_send_channel_key(server, sock, channel, FALSE);
+ }
/* Send to the server */
+ id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+ id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
chk = silc_channel_key_payload_encode(id_len, id,
strlen(channel->channel_key->
cipher->name),
packet->flags | SILC_PACKET_FLAG_BROADCAST,
packet->buffer->data,
packet->buffer->len, FALSE);
- silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
buffer->data, buffer->len, FALSE);
- silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
packet->buffer->data, packet->buffer->len,
FALSE, TRUE);