From 8c2ea8dfdc0d2b66860912e4585aa5307f9e2b23 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 30 Mar 2001 13:56:10 +0000 Subject: [PATCH] updates. --- CHANGES | 24 +++++++- apps/silc/client_ops.c | 26 ++++++-- apps/silcd/command.c | 3 + apps/silcd/packet_receive.c | 58 ++++++++++++++++-- apps/silcd/packet_send.c | 6 +- apps/silcd/packet_send.h | 4 +- apps/silcd/server.c | 93 ++++++++++++++++++----------- apps/silcd/server.h | 7 +++ apps/silcd/testi2.conf | 4 +- doc/draft-riikonen-silc-pp-01.nroff | 9 ++- 10 files changed, 176 insertions(+), 58 deletions(-) diff --git a/CHANGES b/CHANGES index cc2ce970..e8eedcd3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -Fri Mar 30 13:35:27 EEST 2001 Pekka Riikonen +Fri Mar 30 16:35:27 EEST 2001 Pekka Riikonen * Fixed the WHOIS and IDENTIFY send reply function to really check whether to send list or just one entry. Affected file @@ -7,6 +7,28 @@ Fri Mar 30 13:35:27 EEST 2001 Pekka Riikonen * Cleaned up the LEAVE command's channel key distribution. The affected file silcd/command.c. + * Changed CMODE_CHANGE's to 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 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 * Fixed a fatal bug when client does /join 1 2 3 4 5 6 the server diff --git a/apps/silc/client_ops.c b/apps/silc/client_ops.c index dce61eb8..5e3c1332 100644 --- a/apps/silc/client_ops.c +++ b/apps/silc/client_ops.c @@ -208,12 +208,25 @@ void silc_notify(SilcClient client, SilcClientConnection conn, 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; @@ -265,6 +278,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn, return; case SILC_NOTIFY_TYPE_CHANNEL_CHANGE: + return; break; case SILC_NOTIFY_TYPE_KICKED: diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 74426a3b..003f0adf 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -4130,6 +4130,9 @@ SILC_SERVER_CMD_FUNC(silcoper) 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; diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 38b2a86a..0b7b0bfd 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -611,6 +611,9 @@ void silc_server_notify(SilcServer server, 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) @@ -644,14 +647,35 @@ void silc_server_notify(SilcServer server, 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; @@ -1432,6 +1456,7 @@ SilcServerEntry silc_server_new_server(SilcServer server, 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 @@ -1654,6 +1679,7 @@ void silc_server_new_channel(SilcServer server, unsigned int name_len; unsigned char *id; unsigned int id_len; + unsigned int mode; SILC_LOG_DEBUG(("Processing New Channel")); @@ -1738,6 +1764,7 @@ void silc_server_new_channel(SilcServer server, /* 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 @@ -1749,6 +1776,17 @@ void silc_server_new_channel(SilcServer server, 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. */ @@ -1757,6 +1795,8 @@ void silc_server_new_channel(SilcServer server, /* 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, @@ -1769,6 +1809,7 @@ void silc_server_new_channel(SilcServer server, 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); @@ -1776,9 +1817,18 @@ void silc_server_new_channel(SilcServer server, /* 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 diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index e2f5d0e6..3ec4e53c 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -953,14 +953,14 @@ void silc_server_send_notify_cmode(SilcServer server, 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, diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index b3f75baf..22370969 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -126,8 +126,8 @@ void silc_server_send_notify_cmode(SilcServer server, 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, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 0bb81178..6a73c0c1 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -785,7 +785,6 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) 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) @@ -1927,6 +1926,11 @@ void silc_server_create_connection(SilcServer server, 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, @@ -1944,7 +1948,11 @@ 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 @@ -2631,6 +2639,8 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, unsigned int tmp_len; char *cipher; + SILC_LOG_DEBUG(("Start")); + /* Decode channel key payload */ payload = silc_channel_key_payload_parse(key_payload); if (!payload) { @@ -2875,24 +2885,61 @@ silc_server_announce_encode_join(unsigned int argc, ...) 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)) { @@ -2915,36 +2962,12 @@ static void silc_server_announce_get_channels(SilcServer server, 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); diff --git a/apps/silcd/server.h b/apps/silcd/server.h index d02bda75..0cd883a5 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -142,6 +142,13 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, 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); diff --git a/apps/silcd/testi2.conf b/apps/silcd/testi2.conf index 62805382..0dc9377a 100644 --- a/apps/silcd/testi2.conf +++ b/apps/silcd/testi2.conf @@ -50,10 +50,10 @@ errorlogfile:silcd2.log:10000 *: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] diff --git a/doc/draft-riikonen-silc-pp-01.nroff b/doc/draft-riikonen-silc-pp-01.nroff index cd71928a..da02ad43 100644 --- a/doc/draft-riikonen-silc-pp-01.nroff +++ b/doc/draft-riikonen-silc-pp-01.nroff @@ -1125,9 +1125,8 @@ ID's sent in arguments are sent inside ID Payload. 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 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) (2) @@ -1144,8 +1143,8 @@ ID's sent in arguments are sent inside ID Payload. and the is defined in the [SILC1] with SILC_COMMAND_INVITE command. - The and is never sent to the - client indicated by the . + The and is never sent when the + packet is destined to a client. 2 SILC_NOTIFY_TYPE_JOIN -- 2.24.0