*/
SILC_LOG_DEBUG(("JOIN notify"));
+ if (channel_id)
+ silc_free(channel_id);
+
/* Get Channel ID */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
if (!tmp)
}
}
silc_free(client_id);
+ silc_free(channel_id);
/* Check if on channel */
if (!silc_server_client_on_channel(client, channel, NULL))
goto out;
}
}
- silc_free(client_id);
}
+ silc_free(client_id);
if (!channel_id) {
channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
if (channel->founder_key)
silc_pkcs_public_key_free(channel->founder_key);
channel->founder_key = NULL;
- silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+ silc_pkcs_public_key_payload_decode(tmp, tmp_len,
+ &channel->founder_key);
}
break;
if (channel->founder_key)
silc_pkcs_public_key_free(channel->founder_key);
channel->founder_key = NULL;
- silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+ silc_pkcs_public_key_payload_decode(tmp, tmp_len, &channel->founder_key);
if (!channel->founder_key ||
(client && client->data.public_key &&
goto out;
}
}
- silc_free(client_id);
}
+ silc_free(client_id);
if (!channel_id) {
channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
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)) {
+ if (!tmp || !silc_pkcs_public_key_payload_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;
/* Now match the public key we have cached and public key sent.
They must match. */
+#if 0 /* The key may be other than the client's in 1.2 */
if (client && client->data.public_key &&
!silc_pkcs_public_key_compare(channel->founder_key,
client->data.public_key)) {
notify_sent = TRUE;
break;
}
+#endif
if (!silc_pkcs_public_key_compare(channel->founder_key,
founder_key)) {
chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
SilcChannelEntry channel;
if (packet->src_id_type != SILC_ID_SERVER ||
- (server->server_type == SILC_ROUTER &&
+ (server->server_type == SILC_ROUTER && !server->backup_router &&
sock->type == SILC_SOCKET_TYPE_ROUTER))
return;
idata->status |= SILC_IDLIST_STATUS_REGISTERED;
client->nickname = nickname;
client->username = username;
- client->userinfo = realname ? realname : strdup(" ");
+ client->userinfo = realname ? realname : strdup(username);
client->id = client_id;
id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
char *channel_name;
SilcUInt32 name_len;
unsigned char *id;
- SilcUInt32 id_len;
+ SilcUInt32 id_len, cipher_len;
SilcServerEntry server_entry;
SilcChannelEntry channel;
+ const char *cipher;
if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
packet->src_id_type != SILC_ID_SERVER ||
channel =
silc_idlist_add_channel(server->global_list, strdup(channel_name),
0, channel_id, sock->user_data, NULL, NULL, 0);
- if (!channel)
+ if (!channel) {
+ silc_channel_payload_free(payload);
+ silc_free(channel_id);
return;
+ }
channel->disabled = TRUE; /* Disabled until someone JOINs */
server->stat.channels++;
if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
silc_server_send_notify_channel_change(server, sock, FALSE,
channel_id, tmp);
+ silc_channel_payload_free(payload);
silc_free(channel_id);
silc_free(tmp);
}
/* Send the new channel key to the server */
id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
+ cipher = silc_cipher_get_name(channel->channel_key);
+ cipher_len = strlen(cipher);
chk = silc_channel_key_payload_encode(id_len, id,
- strlen(channel->channel_key->
- cipher->name),
- channel->channel_key->cipher->name,
+ cipher_len, cipher,
channel->key_len / 8,
channel->key);
silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
chk->data, chk->len, FALSE);
silc_buffer_free(chk);
+ silc_free(id);
} else {
/* The channel exist by that name, check whether the ID's match.
If they don't then we'll force the server to use the ID we have.
SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
silc_server_send_notify_channel_change(server, sock, FALSE,
channel_id, channel->id);
+ silc_channel_payload_free(payload);
+ silc_free(channel_id);
/* Wait that server re-announces this channel */
return;
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
if (silc_hash_table_count(channel->user_list)) {
- if (!silc_server_create_channel_key(server, channel, 0))
+ if (!silc_server_create_channel_key(server, channel, 0)) {
+ silc_channel_payload_free(payload);
+ silc_free(channel_id);
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);
+ cipher = silc_cipher_get_name(channel->channel_key);
+ cipher_len = strlen(cipher);
chk = silc_channel_key_payload_encode(id_len, id,
- strlen(channel->channel_key->
- cipher->name),
- channel->channel_key->
- cipher->name,
+ cipher_len, cipher,
channel->key_len / 8,
channel->key);
silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
silc_free(channel_id);
- /* Update statistics */
- server->stat.channels++;
- server->stat.cell_channels++;
-
/* Since the channel is coming from server and we also know about it
then send the JOIN notify to the server so that it see's our
users on the channel "joining" the channel. */
SilcHashTableList htl;
SilcChannelClientEntry chl;
SilcServerResumeResolve r;
+ const char *cipher;
ret = silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING(&id_string, &id_len),
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
SILC_PACKET_RESUME_CLIENT, 0,
buf->data, buf->len, TRUE);
+ silc_server_backup_send(server, detached_client->router,
+ SILC_PACKET_RESUME_CLIENT, 0,
+ buf->data, buf->len, TRUE, TRUE);
/* As router we must deliver this packet directly to the original
server whom this client was earlier. */
if (!silc_idlist_del_client(server->local_list, client))
silc_idlist_del_client(server->global_list, client);
client = detached_client;
+ silc_free(client->servername);
+ client->servername = strdup(server->server_name);
/* 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)) {
}
id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+ cipher = silc_cipher_get_name(channel->channel_key);
keyp =
silc_channel_key_payload_encode(silc_id_get_len(channel->id,
SILC_ID_CHANNEL),
id_string,
- strlen(channel->channel_key->
- cipher->name),
- channel->channel_key->cipher->name,
+ strlen(cipher), cipher,
channel->key_len / 8, channel->key);
silc_free(id_string);
- /* Send the key packet to client */
+ /* Send the channel key to the client */
silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
keyp->data, keyp->len, FALSE);
- 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);
+ /* Distribute the channel key to channel */
+ if (created) {
+ silc_server_send_channel_key(server, NULL, channel,
+ server->server_type == SILC_ROUTER ?
+ FALSE : !server->standalone);
+ silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
+ keyp->data, keyp->len, FALSE, TRUE);
+ }
silc_buffer_free(keyp);
}
detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
id_cache->expire = 0;
- /* Update channel information regarding global clients on channel. */
- if (server->server_type == SILC_SERVER) {
- silc_hash_table_list(detached_client->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void **)&chl))
- chl->channel->global_users =
- silc_server_channel_has_global(chl->channel);
- silc_hash_table_list_reset(&htl);
- }
-
silc_schedule_task_del_by_context(server->schedule, detached_client);
/* Get the new owner of the resumed client */
}
if (server->server_type == SILC_ROUTER &&
- sock->type == SILC_SOCKET_TYPE_ROUTER &&
+ sock->type == SILC_SOCKET_TYPE_ROUTER &&
server_entry->server_type == SILC_ROUTER)
local = FALSE;
detached_client))
silc_idcache_del_by_context(server->global_list->clients,
detached_client);
- silc_idcache_add(local && server->server_type == SILC_ROUTER ?
- server->local_list->clients :
- server->global_list->clients,
+ silc_idcache_add(local && server->server_type == SILC_ROUTER ?
+ server->local_list->clients :
+ server->global_list->clients,
detached_client->nickname,
detached_client->id, detached_client, FALSE, NULL);
/* Change the owner of the client */
detached_client->router = server_entry;
+ /* Update channel information regarding global clients on channel. */
+ if (server->server_type != SILC_ROUTER) {
+ silc_hash_table_list(detached_client->channels, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void **)&chl))
+ chl->channel->global_users =
+ silc_server_channel_has_global(chl->channel);
+ silc_hash_table_list_reset(&htl);
+ }
+
silc_free(server_id);
}