SilcClientEntry client = NULL, client2 = NULL;
SilcServerEntry server_entry = NULL;
SilcChannelClientEntry chl;
- SilcIDCacheEntry cache;
+ SilcIDCacheEntry cache = NULL;
SilcHashTableList htl;
SilcUInt32 mode;
unsigned char *tmp;
*/
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)
entry for the client. */
client = silc_idlist_find_client_by_id(server->global_list,
client_id, server->server_type,
- NULL);
+ &cache);
if (!client) {
client = silc_idlist_find_client_by_id(server->local_list,
client_id, server->server_type,
- NULL);
+ &cache);
if (!client) {
/* If router did not find the client the it is bogus */
- if (server->server_type != SILC_SERVER)
+ if (server->server_type != SILC_SERVER) {
+ silc_free(client_id);
goto out;
+ }
client =
silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
}
}
+ silc_free(client_id);
/* Do not process the notify if the client is not registered */
if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
silc_hash_table_add(channel->user_list, client, chl);
silc_hash_table_add(client->channels, channel, chl);
- silc_free(client_id);
channel->user_count++;
channel->disabled = FALSE;
+ /* Make sure we don't expire clients that are on channel */
+ if (cache)
+ cache->expire = 0;
+
/* Update statistics */
if (server->server_type == SILC_ROUTER) {
if (sock->type != SILC_SOCKET_TYPE_ROUTER)
}
}
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(channel_id);
if (channel->topic && !strcmp(channel->topic, tmp)) {
SILC_LOG_DEBUG(("Topic is already set and same"));
silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
- silc_free(channel_id);
break;
case SILC_NOTIFY_TYPE_NICK_CHANGE:
if (!id2)
goto out;
client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
- if (!client_id2)
+ if (!client_id2) {
+ silc_free(client_id);
goto out;
+ }
SILC_LOG_DEBUG(("Old Client ID id(%s)",
silc_id_render(client_id, SILC_ID_CLIENT)));
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,
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 (!server_id)
goto out;
+ /* If the ID is mine, this notify is not allowed. */
+ if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
+ SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
+ break;
+ }
+
/* Get server entry */
server_entry = silc_idlist_find_server_by_id(server->global_list,
server_id, TRUE, NULL);
- local = TRUE;
+ local = FALSE;
if (!server_entry) {
server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, TRUE, NULL);
silc_server_del_from_watcher_list(server, client);
/* Remove the client */
+ silc_idlist_del_data(client);
silc_idlist_del_client(local ? server->local_list :
server->global_list, client);
}
server->stat.detached--;
}
}
+ SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
+ SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
/* Change the mode */
client->mode = mode;
if (client) {
silc_server_remove_from_channels(server, NULL, client, TRUE,
NULL, TRUE);
+ silc_idlist_del_data(client);
silc_idlist_del_client(server->global_list, client);
}
silc_free(client_id);
SILC_LOG_DEBUG(("Start"));
- /* Source must be server or router */
- if (packet->src_id_type != SILC_ID_SERVER &&
- sock->type != SILC_SOCKET_TYPE_ROUTER)
- return;
-
if (packet->dst_id_type == SILC_ID_CHANNEL)
return;
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;
snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
}
+ /* If client marked as anonymous, scramble the username and hostname */
+ if (client->mode & SILC_UMODE_ANONYMOUS) {
+ char *scramble;
+
+ if (strlen(username) >= 2) {
+ username[0] = silc_rng_get_byte_fast(server->rng);
+ username[1] = silc_rng_get_byte_fast(server->rng);
+ }
+
+ scramble = silc_hash_babbleprint(server->sha1hash, username,
+ strlen(username));
+ scramble[5] = '@';
+ scramble[11] = '.';
+ memcpy(&scramble[16], ".silc", 5);
+ scramble[21] = '\0';
+ silc_free(username);
+ username = scramble;
+ }
+
/* Update client entry */
idata->status |= SILC_IDLIST_STATUS_REGISTERED;
client->nickname = nickname;
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_server_free_sock_user_data(server, sock, NULL);
goto out;
}
+
+ client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
}
/* Reprocess the packet */
SilcHashTableList htl;
SilcChannelClientEntry chl;
SilcServerResumeResolve r;
+ const char *cipher;
ret = silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING(&id_string, &id_len),
idata = (SilcIDListData)client;
/* Get entry to the client, and resolve it if we don't have it. */
- detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
- &resolved);
+ detached_client = silc_server_query_client(server, client_id, FALSE,
+ &resolved);
if (!detached_client) {
if (resolved) {
/* The client info is being resolved. Reprocess this packet after
resolve = TRUE;
if (!detached_client->nickname)
resolve = TRUE;
+ if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
+ resolve = FALSE;
if (resolve) {
if (server->server_type == SILC_SERVER && !server->standalone) {
/* The client info is being resolved. Reprocess this packet after
receiving the reply to the query. */
SILC_LOG_DEBUG(("Resolving client info"));
- silc_server_get_client_resolve(server, client_id, TRUE, NULL);
+ silc_server_query_client(server, client_id, TRUE, NULL);
r = silc_calloc(1, sizeof(*r));
if (!r)
return;
silc_idlist_add_data(detached_client, idata);
detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
+ detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
detached_client->mode &= ~SILC_UMODE_DETACHED;
server->stat.my_detached--;
}
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);
/* Get server entry */
server_entry = silc_idlist_find_server_by_id(server->global_list,
server_id, TRUE, NULL);
- local = TRUE;
+ local = FALSE;
if (!server_entry) {
server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, TRUE, NULL);
- local = FALSE;
+ local = TRUE;
if (!server_entry) {
silc_free(server_id);
silc_free(client_id);