From: Pekka Riikonen Date: Sun, 4 Feb 2001 19:13:07 +0000 (+0000) Subject: updates. X-Git-Tag: SILC.0.1~261 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=3669e66576d397af788c9ce2013b0a23c43c6854 updates. --- diff --git a/CHANGES b/CHANGES index 6f17e20e..71ebd178 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,19 @@ +Sun Feb 4 13:18:32 EET 2001 Pekka Riikonen + + * Added new packet type SILC_PACKET_SET_MODE that is used to + distribute the information about changed modes (for clients, + channels and clients channel modes) to all routers in the + network. Updated the protocol specification accordingly. + + Added functions into silcd/packet_send.c and + silcd/packet_receive.c: silc_server_send_set_mode, + silc_server_set_mode. + + Added new files silcmode.[ch] into lib/silccore that implements + the encoding and decoding of Set Mode Payload. Added new type + SilcSetModePayload. Moved the definitions of different modes + from lib/silccore/silcchannel.h into lib/silccore/silcmode.h. + Sat Feb 3 15:44:54 EET 2001 Pekka Riikonen * Oops, a little mistake in server's connection authentication diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 337e8c67..a5c24930 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1338,3 +1338,166 @@ void silc_server_remove_id(SilcServer server, out: silc_id_payload_free(idp); } + +/* Processes received SET_MODE packet. The packet is used to distribute + the information about changed channel's or client's channel modes. */ + +void silc_server_set_mode(SilcServer server, + SilcSocketConnection sock, + SilcPacketContext *packet) +{ + SilcSetModePayload payload = NULL; + SilcArgumentPayload args = NULL; + unsigned short mode_type; + unsigned int mode_mask; + unsigned char *tmp, *tmp2; + unsigned int tmp_len, tmp_len2; + unsigned char mode[4]; + SilcClientID *client_id; + SilcChannelID *channel_id = NULL; + SilcClientEntry client; + SilcChannelEntry channel; + SilcChannelClientEntry chl; + + if (sock->type == SILC_SOCKET_TYPE_CLIENT || + packet->src_id_type == SILC_ID_CLIENT) + return; + + SILC_LOG_DEBUG(("Start")); + + /* If we are router and this packet is not already broadcast packet + we will broadcast it. The sending socket really cannot be router or + the router is buggy. If this packet is coming from router then it must + have the broadcast flag set already and we won't do anything. */ + if (!server->standalone && server->server_type == SILC_ROUTER && + sock->type == SILC_SOCKET_TYPE_SERVER && + !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) { + SILC_LOG_DEBUG(("Broadcasting received Set Mode packet")); + silc_server_packet_send(server, server->router->connection, packet->type, + packet->flags | SILC_PACKET_FLAG_BROADCAST, + packet->buffer->data, packet->buffer->len, FALSE); + } + + /* Parse Set Mode payload */ + payload = silc_set_mode_payload_parse(packet->buffer); + if (!payload) + return; + + mode_type = silc_set_mode_get_type(payload); + args = silc_set_mode_get_args(payload); + if (!args) + goto out; + + mode_mask = silc_set_mode_get_mode(payload); + SILC_PUT32_MSB(mode_mask, mode); + + switch (mode_type) { + case SILC_MODE_TYPE_CHANNEL: + /* Get Channel ID */ + tmp = silc_argument_get_arg_type(args, 1, &tmp_len); + if (!tmp) + goto out; + channel_id = silc_id_payload_parse_id(tmp, tmp_len); + if (!channel_id) + goto out; + + /* Get channel entry */ + channel = silc_idlist_find_channel_by_id(server->local_list, + channel_id, NULL); + if (!channel) { + channel = silc_idlist_find_channel_by_id(server->global_list, + channel_id, NULL); + if (!channel) + goto out; + } + + /* Get Client ID payload */ + tmp = silc_argument_get_arg_type(args, 2, &tmp_len); + if (!tmp) + goto out; + + /* Send CMODE_CHANGE notify to local channel */ + silc_server_send_notify_to_channel(server, sock, channel, FALSE, + SILC_NOTIFY_TYPE_CMODE_CHANGE, + 2, tmp, tmp_len, + mode, sizeof(mode)); + + /* Change the mode */ + channel->mode = mode_mask; + break; + + case SILC_MODE_TYPE_UCHANNEL: + /* Get Channel ID */ + tmp = silc_argument_get_arg_type(args, 1, &tmp_len); + if (!tmp) + goto out; + channel_id = silc_id_payload_parse_id(tmp, tmp_len); + if (!channel_id) + goto out; + + /* Get channel entry */ + channel = silc_idlist_find_channel_by_id(server->local_list, + channel_id, NULL); + if (!channel) { + channel = silc_idlist_find_channel_by_id(server->global_list, + channel_id, NULL); + if (!channel) + goto out; + } + + /* Get Client ID payload */ + tmp = silc_argument_get_arg_type(args, 2, &tmp_len); + if (!tmp) + goto out; + + /* Get target Client ID */ + tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2); + if (!tmp2) + goto out; + client_id = silc_id_payload_parse_id(tmp2, tmp_len2); + if (!client_id) + goto out; + + /* Get target client entry */ + client = silc_idlist_find_client_by_id(server->global_list, + client_id, NULL); + if (!client) { + client = silc_idlist_find_client_by_id(server->local_list, + client_id, NULL); + if (!client) { + silc_free(client_id); + goto out; + } + } + silc_free(client_id); + + /* Send CUMODE_CHANGE notify to local channel */ + silc_server_send_notify_to_channel(server, sock, channel, FALSE, + SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2, + tmp, tmp_len, + mode, sizeof(mode), + tmp2, tmp_len2); + + /* Get entry to the channel user list */ + silc_list_start(channel->user_list); + while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) + if (chl->client == client) { + /* Change the mode */ + chl->mode = mode_mask; + break; + } + + break; + + default: + break; + } + + out: + if (channel_id) + silc_free(channel_id); + if (args) + silc_argument_payload_free(args); + if (payload) + silc_set_mode_payload_free(payload); +} diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 23c51d5c..ec26e5d1 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -1177,3 +1177,33 @@ void silc_server_send_remove_id(SilcServer server, idp->data, idp->len, FALSE); silc_buffer_free(idp); } + +/* Function used to send SET_MODE packet. The packet is used to notify routers + that channel's or client's channel mode was changed. If the argument + `broadcast' is TRUE then the packet is sent as broadcast packet. */ + +void silc_server_send_set_mode(SilcServer server, + SilcSocketConnection sock, + int broadcast, + int mode_type, unsigned int mode_mask, + unsigned int argc, ...) +{ + SilcBuffer packet; + va_list ap; + + SILC_LOG_DEBUG(("Start")); + + va_start(ap, argc); + + /* Encode Set Mode payload */ + packet = silc_set_mode_payload_encode(mode_type, mode_mask, argc, ap); + if (!packet) + return; + + /* Send the packet */ + silc_server_packet_send(server, sock, SILC_PACKET_SET_MODE, + broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, + packet->data, packet->len, FALSE); + + silc_buffer_free(packet); +} diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index 30833278..2ce52f17 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -143,5 +143,10 @@ void silc_server_send_remove_id(SilcServer server, int broadcast, void *id, unsigned int id_len, SilcIdType id_type); +void silc_server_send_set_mode(SilcServer server, + SilcSocketConnection sock, + int broadcast, + int mode_type, unsigned int mode_mask, + unsigned int argc, ...); #endif diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 7f9d244d..12094881 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1579,6 +1579,14 @@ void silc_server_packet_parse_type(SilcServer server, silc_server_remove_channel_user(server, sock, packet); break; + case SILC_PACKET_SET_MODE: + /* + * Received packet to set the mode of channel or client's channel mode. + */ + SILC_LOG_DEBUG(("Set Mode packet")); + silc_server_set_mode(server, sock, packet); + break + default: SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type)); break; @@ -1909,6 +1917,9 @@ SILC_TASK_CALLBACK(silc_server_timeout_remote) if (!sock) return; + if (sock->user_data) + silc_server_free_sock_user_data(sconn->server, sock); + silc_server_disconnect_remote(sconn->server, sock, "Server closed connection: " "Connection timeout"); diff --git a/doc/draft-riikonen-silc-pp-01.nroff b/doc/draft-riikonen-silc-pp-01.nroff index 4d27be35..f3860e95 100644 --- a/doc/draft-riikonen-silc-pp-01.nroff +++ b/doc/draft-riikonen-silc-pp-01.nroff @@ -104,6 +104,7 @@ Table of Contents 2.3.24 Replace ID Payload ................................. 36 2.3.25 Remove ID Payload .................................. 37 2.3.26 Remove Channel User Payload ........................ 38 + 2.3.27 Set Mode Payload ................................... XXX 2.4 SILC ID Types ............................................. 39 2.5 Packet Encryption And Decryption .......................... 39 2.5.1 Normal Packet Encryption And Decryption ............. 39 @@ -148,6 +149,7 @@ Figure 19: New Channel Payload Figure 20: New Channel User Payload Figure 21: Replace ID Payload Figure 22: Remove Channel User Payload +Figure 23: Set Mode Payload .ti 0 @@ -751,8 +753,20 @@ List of SILC Packet types are defined as follows. as SILC Key Exchange protocol is executed. This packet does not have a payload. + + 31 SILC_PACKET_SET_MODE - 31 - 199 + This packet is used by servers and routers to inform each + other about changed modes. When channel's and client'c channel + mode is changed this packet is used to distribute the information + to all routers in the network. Server can send this packet but + must not receive it. Router can send and receive this packet. + Client must not send or receive this packet. + + Payload of the packet: See section 2.3.27 Set Mode Payload + + + 32 - 199 Currently undefined commands. @@ -1184,7 +1198,7 @@ ID's sent in arguments are sent inside ID Payload. The is the client who changed the mode. The is the new mode mask of the channel. The is the - client whose mode was changed. + client which mode was changed. 9 SILC_NOTIFY_TYPE_MOTD @@ -2130,6 +2144,89 @@ o Channel ID Data (variable length) - The Channel ID of the channel .in 3 +.ti 0 +2.3.27 Set Mode Payload + +Set Mode Payload is used by servers and routers to distribute to each +other the information about changed modes in the SILC network. The +payload is sent when channel's or client's channel mode is changed. +Server can send this to router which will broadcast it further to other +routers. However, normal server must not reiceve this payload. Client +must not send or receive this payload. + +The payload may only be sent with SILC_PACKET_SET_MODE packet. +It must not be sent in any other packet type. Following diagram +represents the Set Mode Payload. + + + +.in 5 +.nf +.in 5 +.nf + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Mode Type | Payload Length | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Mode Mask | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Argument Nums | ++-+-+-+-+-+-+-+-+ +.in 3 + +.ce +Figure 23: Set Mode Payload + + +.in 6 +o Mode type (2 bytes) - Indicates the type of the mode that was + changed. Every type has arguments associated to the type which + are defined below. The following types are defined: + + 0 SILC_MODE_TYPE_CHANNEL + + Max Arguments: 2 + Arguments: (1) (2) + + The is the channel which mode was set and the + is the client who set it. + + + 1 SILC_MODE_TYPE_UCHANNEL + + Max Arguments: 3 + Arguments: (1) (2) + (3) + + The is the channel where the and + the is on. The is the client + who set the mode. + + + 2 - RESERVED + + Reserved types. + + + 32768 - Private range + + Rest of the types are reserved for private use. + +o Payload Length (2 bytes) - Length of the entire Set Mode Payload + including any associated Argument Payloads. + +o Mode Mask (4 bytes) - Indicates the set mode mask. This is + specified by the mode type. See definitions of SILC_COMMAND_UMODE + for client modes, SILC_COMMAND_CMODE for channel modes and + SILC_COMMAND_CUMODE for client's channel modes in [SILC1]. + +o Argument Nums (2 bytes) - Indicates the number of Argument + Payloads associated to this payload. Mode types may define + arguments to be send along this payload. +.in 3 + + .ti 0 2.4 SILC ID Types diff --git a/includes/silcincludes.h b/includes/silcincludes.h index 92ba8327..b3c3fc70 100644 --- a/includes/silcincludes.h +++ b/includes/silcincludes.h @@ -1,3 +1,4 @@ + /* silcincludes.h @@ -156,6 +157,7 @@ #include "silcchannel.h" #include "silcpacket.h" #include "silcnotify.h" +#include "silcmode.h" /* TRQ (SilcList API and SilcDList API) */ #include "silclist.h" diff --git a/lib/silccore/Makefile.am b/lib/silccore/Makefile.am index 36036ce1..eda260a8 100644 --- a/lib/silccore/Makefile.am +++ b/lib/silccore/Makefile.am @@ -29,7 +29,8 @@ libsilccore_a_SOURCES = \ silcprotocol.c \ silcsockconn.c \ silcpayload.c \ - silcnotify.c + silcnotify.c \ + silcmode.c EXTRA_DIST = *.h diff --git a/lib/silccore/silcchannel.h b/lib/silccore/silcchannel.h index e3382e7b..6169fe9a 100644 --- a/lib/silccore/silcchannel.h +++ b/lib/silccore/silcchannel.h @@ -29,24 +29,6 @@ typedef struct SilcChannelPayloadStruct *SilcChannelPayload; actual structure is defined in source file and is private data. */ typedef struct SilcChannelKeyPayloadStruct *SilcChannelKeyPayload; -/* Channel modes */ -#define SILC_CHANNEL_MODE_NONE 0x0000 -#define SILC_CHANNEL_MODE_PRIVATE 0x0001 /* private channel */ -#define SILC_CHANNEL_MODE_SECRET 0x0002 /* secret channel */ -#define SILC_CHANNEL_MODE_PRIVKEY 0x0004 /* channel has private key */ -#define SILC_CHANNEL_MODE_INVITE 0x0008 /* invite only channel */ -#define SILC_CHANNEL_MODE_TOPIC 0x0010 /* topic setting by operator */ -#define SILC_CHANNEL_MODE_ULIMIT 0x0020 /* user limit set */ -#define SILC_CHANNEL_MODE_PASSPHRASE 0x0040 /* passphrase set */ -#define SILC_CHANNEL_MODE_BAN 0x0080 /* ban list set */ -#define SILC_CHANNEL_MODE_INVITE_LIST 0x0100 /* invite list set */ -#define SILC_CHANNEL_MODE_CIPHER 0x0200 /* sets cipher of channel */ - -/* User modes on channel */ -#define SILC_CHANNEL_UMODE_NONE 0x0000 /* Normal user */ -#define SILC_CHANNEL_UMODE_CHANFO 0x0001 /* channel founder */ -#define SILC_CHANNEL_UMODE_CHANOP 0x0002 /* channel operator */ - /* Prototypes */ SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer); SilcBuffer silc_channel_payload_encode(unsigned short data_len, diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index cf1e8edc..bdd4e4d6 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -222,6 +222,7 @@ typedef void (*SilcPacketParserCallback)(SilcPacketParserContext #define SILC_PACKET_REMOVE_CHANNEL_USER 28 /* Remove user from channel */ #define SILC_PACKET_REKEY 29 #define SILC_PACKET_REKEY_DONE 30 +#define SILC_PACKET_SET_MODE 31 /* Set mode */ /* #define SILC_PACKET_MAX 255 */ /* Macros */