-Fri Mar 30 13:35:27 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+Fri Mar 30 16:35:27 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Fixed the WHOIS and IDENTIFY send reply function to really
check whether to send list or just one entry. Affected file
* Cleaned up the LEAVE command's channel key distribution. The
affected file silcd/command.c.
+ * Changed CMODE_CHANGE's <Client ID> to <ID Payload> as server
+ can enforce the channel mode as well. In that case the ID
+ includes the ID of the server. The code now enforces the
+ mode change if the router have different mode than the server.
+
+ * The notify client operation with CMODE_CHANGE notify can now
+ return NULL client_entry pointer if the CMODE was not changed
+ by client. Application must check for this.
+
+ * Added <Server ID> argument to INFO command to support server
+ info fetching by Server ID.
+
+ * Added silc_server_announce_get_channel_users to get assembled
+ packets of channel users of the specified channel. Affected
+ file silcd/server.[ch].
+
+ * Fixed bug in CHANNEL_CHANGE notify in the server. The new ID
+ was freed underneath the ID Cache.
+
+ * Re-announce clients when the server received CHANNEL_CHANGE
+ notify from the router. Affected file silcd/packet_send.c.
+
Thu Mar 29 19:10:28 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Fixed a fatal bug when client does /join 1 2 3 4 5 6 the server
tmp = silc_client_chmode(tmp_int, channel_entry);
- if (tmp)
- snprintf(message, sizeof(message), "%s changed channel mode to +%s",
- client_entry->nickname, tmp);
- else
- snprintf(message, sizeof(message), "%s removed all channel modes",
- client_entry->nickname);
+ if (tmp) {
+ if (client_entry) {
+ snprintf(message, sizeof(message), "%s changed channel mode to +%s",
+ client_entry->nickname, tmp);
+ } else {
+ snprintf(message, sizeof(message),
+ "channel mode was changed to +%s (forced by router)",
+ tmp);
+ }
+ } else {
+ if (client_entry) {
+ snprintf(message, sizeof(message), "%s removed all channel modes",
+ client_entry->nickname);
+ } else {
+ snprintf(message, sizeof(message),
+ "Removed all channel modes (forced by router)");
+ }
+ }
+
if (app->screen->bottom_line->channel_mode)
silc_free(app->screen->bottom_line->channel_mode);
app->screen->bottom_line->channel_mode = tmp;
return;
case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
+ return;
break;
case SILC_NOTIFY_TYPE_KICKED:
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_SILCOPER, cmd, 1, 2);
+ if (server->server_type == SILC_SERVER)
+ goto out;
+
if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
goto out;
SILC_LOG_DEBUG(("CHANNEL CHANGE"));
+ if (sock->type != SILC_SOCKET_TYPE_ROUTER)
+ break;
+
/* Get the old Channel ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
if (!channel_id2)
goto out;
+ SILC_LOG_DEBUG(("Old Channel ID id(%s)",
+ silc_id_render(channel_id, SILC_ID_CHANNEL)));
+ SILC_LOG_DEBUG(("New Channel ID id(%s)",
+ silc_id_render(channel_id2, SILC_ID_CHANNEL)));
+
/* Replace the Channel ID */
if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
channel_id2))
- silc_idlist_replace_channel_id(server->local_list, channel_id,
- channel_id2);
+ if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
+ channel_id2)) {
+ silc_free(channel_id2);
+ channel_id2 = NULL;
+ }
+
+ if (channel_id2) {
+ SilcBuffer users = NULL;
+
+ /* Re-announce our clients on the channel as the ID has changed now */
+ silc_server_announce_get_channel_users(server, channel, &users);
+ if (users) {
+ silc_buffer_push(users, users->data - users->head);
+ silc_server_packet_send(server, sock,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ users->data, users->len, FALSE);
+ silc_buffer_free(users);
+ }
+ }
silc_free(channel_id);
- silc_free(channel_id2);
break;
cache->id = (void *)server_id;
cache->type = SILC_ID_SERVER;
cache->data = server_name;
+ cache->data_len = strlen(server_name);
silc_idcache_sort_by_data(server->local_list->servers);
/* Distribute the information about new server in the SILC network
unsigned int name_len;
unsigned char *id;
unsigned int id_len;
+ unsigned int mode;
SILC_LOG_DEBUG(("Processing New Channel"));
/* 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.
We also create a new key for the channel. */
+ SilcBuffer users = NULL;
if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
/* They don't match, send CHANNEL_CHANGE notify to the server to
SILC_ID_CHANNEL_LEN);
}
+ /* If the mode is different from what we have then enforce the
+ mode change. */
+ mode = silc_channel_get_mode(payload);
+ if (channel->mode != mode) {
+ SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
+ silc_server_send_notify_cmode(server, sock, FALSE, channel,
+ channel->mode, server->id,
+ SILC_ID_SERVER, SILC_ID_SERVER_LEN,
+ channel->cipher, channel->hmac_name);
+ }
+
/* Create new key for the channel and send it to the server and
everybody else possibly on the channel. */
/* 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_CHANNEL_LEN;
/* Send to the server */
chk = silc_channel_key_payload_encode(id_len, id,
silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
chk->data, chk->len, FALSE);
silc_buffer_free(chk);
+ silc_free(id);
}
silc_free(channel_id);
/* 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. */
- /* XXX TODO **/
+ silc_server_announce_get_channel_users(server, channel, &users);
+ if (users) {
+ silc_buffer_push(users, users->data - users->head);
+ silc_server_packet_send(server, sock,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ users->data, users->len, FALSE);
+ silc_buffer_free(users);
+ }
}
}
+
+ silc_channel_payload_free(payload);
}
/* Received New Channel List packet, list of New Channel List payloads inside
int broadcast,
SilcChannelEntry channel,
unsigned int mode_mask,
- SilcClientID *client_id,
- unsigned int client_id_len,
+ void *id, SilcIdType id_type,
+ unsigned int id_len,
char *cipher, char *hmac)
{
SilcBuffer idp;
unsigned char mode[4];
- idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ idp = silc_id_payload_encode((void *)id, id_type);
SILC_PUT32_MSB(mode_mask, mode);
silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
int broadcast,
SilcChannelEntry channel,
unsigned int mode_mask,
- SilcClientID *client_id,
- unsigned int client_id_len,
+ void *id, SilcIdType id_type,
+ unsigned int id_len,
char *cipher, char *hmac);
void silc_server_send_notify_cumode(SilcServer server,
SilcSocketConnection sock,
SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
sock->hostname, sock->ip, sock->port));
silc_protocol_free(protocol);
- silc_ske_free_key_material(ctx->keymat);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
if (ctx->ske)
SILC_TASK_PRI_NORMAL);
}
+SILC_TASK_CALLBACK(silc_server_close_connection_final)
+{
+ silc_socket_free((SilcSocketConnection)context);
+}
+
/* Closes connection to socket connection */
void silc_server_close_connection(SilcServer server,
/* Close the actual connection */
silc_net_close_connection(sock->sock);
server->sockets[sock->sock] = NULL;
- silc_socket_free(sock);
+
+ silc_task_register(server->timeout_queue, 0,
+ silc_server_close_connection_final,
+ (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
}
/* Sends disconnect message to remote connection and disconnects the
unsigned int tmp_len;
char *cipher;
+ SILC_LOG_DEBUG(("Start"));
+
/* Decode channel key payload */
payload = silc_channel_key_payload_parse(key_payload);
if (!payload) {
return silc_notify_payload_encode(SILC_NOTIFY_TYPE_JOIN, argc, ap);
}
+/* Returns assembled packets for channel users of the `channel'. */
+
+void silc_server_announce_get_channel_users(SilcServer server,
+ SilcChannelEntry channel,
+ SilcBuffer *channel_users)
+{
+ SilcChannelClientEntry chl;
+ SilcBuffer chidp, clidp;
+ SilcBuffer tmp;
+ int len;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ /* Now find all users on the channel */
+ chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+ silc_list_start(channel->user_list);
+ while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
+ clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
+ tmp = silc_server_announce_encode_join(2, clidp->data, clidp->len,
+ chidp->data, chidp->len);
+ len = tmp->len;
+ *channel_users =
+ silc_buffer_realloc(*channel_users,
+ (*channel_users ?
+ (*channel_users)->truelen + len : len));
+ silc_buffer_pull_tail(*channel_users,
+ ((*channel_users)->end -
+ (*channel_users)->data));
+
+ silc_buffer_put(*channel_users, tmp->data, tmp->len);
+ silc_buffer_pull(*channel_users, len);
+ silc_buffer_free(clidp);
+ silc_buffer_free(tmp);
+ }
+ silc_buffer_free(chidp);
+}
+
/* Returns assembled packets for all channels and users on those channels
from the given ID List. The packets are in the form dictated by the
New Channel and New Channel User payloads. */
-static void silc_server_announce_get_channels(SilcServer server,
- SilcIDList id_list,
- SilcBuffer *channels,
- SilcBuffer *channel_users)
+void silc_server_announce_get_channels(SilcServer server,
+ SilcIDList id_list,
+ SilcBuffer *channels,
+ SilcBuffer *channel_users)
{
SilcIDCacheList list;
SilcIDCacheEntry id_cache;
SilcChannelEntry channel;
- SilcChannelClientEntry chl;
- SilcBuffer chidp;
unsigned char *cid;
unsigned short name_len;
int len;
+ SILC_LOG_DEBUG(("Start"));
+
/* Go through all channels in the list */
if (silc_idcache_find_by_id(id_list->channels, SILC_ID_CACHE_ANY,
SILC_ID_CHANNEL, &list)) {
name_len),
SILC_STR_UI_SHORT(SILC_ID_CHANNEL_LEN),
SILC_STR_UI_XNSTRING(cid, SILC_ID_CHANNEL_LEN),
- SILC_STR_UI_INT(0),
+ SILC_STR_UI_INT(channel->mode),
SILC_STR_END);
silc_buffer_pull(*channels, len);
- /* Now find all users on the channel */
- chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- SilcBuffer clidp;
- SilcBuffer tmp;
-
- clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
-
- tmp = silc_server_announce_encode_join(2, clidp->data, clidp->len,
- chidp->data, chidp->len);
- len = tmp->len;
- *channel_users =
- silc_buffer_realloc(*channel_users,
- (*channel_users ?
- (*channel_users)->truelen + len : len));
- silc_buffer_pull_tail(*channel_users,
- ((*channel_users)->end -
- (*channel_users)->data));
-
- silc_buffer_put(*channel_users, tmp->data, tmp->len);
- silc_buffer_pull(*channel_users, len);
- silc_buffer_free(clidp);
- silc_buffer_free(tmp);
- }
- silc_buffer_free(chidp);
+ silc_server_announce_get_channel_users(server, channel,
+ channel_users);
silc_free(cid);
SilcChannelEntry channel);
void silc_server_perform_heartbeat(SilcSocketConnection sock,
void *hb_context);
+void silc_server_announce_get_channel_users(SilcServer server,
+ SilcChannelEntry channel,
+ SilcBuffer *channel_users);
+void silc_server_announce_get_channels(SilcServer server,
+ SilcIDList id_list,
+ SilcBuffer *channels,
+ SilcBuffer *channel_users);
void silc_server_announce_servers(SilcServer server);
void silc_server_announce_clients(SilcServer server);
void silc_server_announce_channels(SilcServer server);
*:silc:silc:passwd:testi
[ServerConnection]
-10.2.1.7:passwd:priikone:1336:1:1
+10.2.1.7:passwd:priikone:1333:1:1
[RouterConnection]
-10.2.1.7:passwd:priikone:1333:1:1:0
+10.2.1.7:passwd:priikone:1335:1:1:0
[DenyConnection]
Sent when an client is invited to a channel. This is also sent
when the invite list of the channel is changed. This notify type
- is sent between routers and if the <Client ID> is argument is
- provided to the client as well. In this case the packet is
- destined to the client.
+ is sent between routers and if an client was invited to the
+ client as well. In this case the packet is destined to the client.
Max Arguments: 5
Arguments: (1) <Channel ID> (2) <channel name>
and the <removing client> is defined in the [SILC1] with
SILC_COMMAND_INVITE command.
- The <adding client> and <removing client> is never sent to the
- client indicated by the <Client ID>.
+ The <adding client> and <removing client> is never sent when the
+ packet is destined to a client.
2 SILC_NOTIFY_TYPE_JOIN