updates.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 4 Feb 2001 19:13:07 +0000 (19:13 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 4 Feb 2001 19:13:07 +0000 (19:13 +0000)
CHANGES
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/server.c
doc/draft-riikonen-silc-pp-01.nroff
includes/silcincludes.h
lib/silccore/Makefile.am
lib/silccore/silcchannel.h
lib/silccore/silcpacket.h

diff --git a/CHANGES b/CHANGES
index 6f17e20e6081112fc945c03fe9d72996fe9f0f2b..71ebd178d5d1d5d9704c7bc119302a2fe6c2933e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,19 @@
+Sun Feb  4 13:18:32 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * 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 <priikone@poseidon.pspt.fi>
 
        * Oops, a little mistake in server's connection authentication 
index 337e8c67462b95c762e3c7c82d116b260cc65063..a5c2493012bb6476f403860d20a85fdf4a4d40c2 100644 (file)
@@ -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);
+}
index 23c51d5c38543cf53b0c1dc3df8de8d883de2efb..ec26e5d16fb0d82eb940f4ea98ef0632c4875d23 100644 (file)
@@ -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);
+}
index 30833278003c81bd1ff5255080d7b75d664c3cac..2ce52f17563310b0cf4937a56b95583fb4b40974 100644 (file)
@@ -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
index 7f9d244d1adb2f1d40f73c80e5d16e0f9d8b6927..1209488123d0353edc95f63a6e546c3db135a892 100644 (file)
@@ -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");
index 4d27be3520c7542861f2977ed44843bf5362eb6e..f3860e95170b1c4ba5ee62ab6f53a823227f76af 100644 (file)
@@ -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 <Client ID> is the client who changed the mode.  The <mode mask>
       is the new mode mask of the channel.  The <Target Client ID> 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) <Channel ID>  (2) <Client ID>
+
+           The <Channel ID> is the channel which mode was set and the
+           <Client ID> is the client who set it.
+
+
+  1        SILC_MODE_TYPE_UCHANNEL
+
+           Max Arguments:  3
+               Arguments:  (1) <Channel ID>        (2) <Client ID>  
+                           (3) <Target Client ID>
+
+           The <Channel ID> is the channel where the <Client ID> and
+           the <Target Client ID> is on.  The <Client ID> is the client
+           who set the <Target Client ID> 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
index 92ba83273be470f11e85a6dbbb98ca8c1adfbc24..b3c3fc70e52b4226baf276bf2db300e39768526b 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
 
   silcincludes.h
 #include "silcchannel.h"
 #include "silcpacket.h"
 #include "silcnotify.h"
+#include "silcmode.h"
 
 /* TRQ (SilcList API and SilcDList API) */
 #include "silclist.h"
index 36036ce139bbbb851a175a56e49c2b515577bfe0..eda260a808785c507f83956afa4e669a575207d6 100644 (file)
@@ -29,7 +29,8 @@ libsilccore_a_SOURCES = \
        silcprotocol.c \
        silcsockconn.c \
        silcpayload.c \
-       silcnotify.c
+       silcnotify.c \
+       silcmode.c
 
 EXTRA_DIST = *.h
 
index e3382e7b8361db8b04184811835942f59a0a964a..6169fe9a2662c423c5fdbecca158b608d9fa5150 100644 (file)
@@ -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,
index cf1e8edc323fced42c033db0c138013223bb621b..bdd4e4d676b3e15e69bbb927a6ca66d966017297 100644 (file)
@@ -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 */