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 
 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);
 }
  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);
 }
                          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);
                                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
 
 #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;
 
     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;
   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)
     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");
   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.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
   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 20:  New Channel User Payload
 Figure 21:  Replace ID Payload
 Figure 22:  Remove Channel User Payload
+Figure 23:  Set Mode Payload
 
 
 .ti 0
 
 
 .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.
 
           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.
 
 
          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
 
       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
 
 
 9     SILC_NOTIFY_TYPE_MOTD
@@ -2130,6 +2144,89 @@ o Channel ID Data (variable length) - The Channel ID of the channel
 .in 3
 
 
 .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
 
 .ti 0
 2.4 SILC ID Types
index 92ba83273be470f11e85a6dbbb98ca8c1adfbc24..b3c3fc70e52b4226baf276bf2db300e39768526b 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
 
   silcincludes.h
 /*
 
   silcincludes.h
 #include "silcchannel.h"
 #include "silcpacket.h"
 #include "silcnotify.h"
 #include "silcchannel.h"
 #include "silcpacket.h"
 #include "silcnotify.h"
+#include "silcmode.h"
 
 /* TRQ (SilcList API and SilcDList API) */
 #include "silclist.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 \
        silcprotocol.c \
        silcsockconn.c \
        silcpayload.c \
-       silcnotify.c
+       silcnotify.c \
+       silcmode.c
 
 EXTRA_DIST = *.h
 
 
 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;
 
    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,
 /* 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_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 */
 /* #define SILC_PACKET_MAX               255 */
 
 /* Macros */