updates.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 30 Mar 2001 13:56:10 +0000 (13:56 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 30 Mar 2001 13:56:10 +0000 (13:56 +0000)
CHANGES
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/testi2.conf
doc/draft-riikonen-silc-pp-01.nroff

diff --git a/CHANGES b/CHANGES
index cc2ce9707c1a7bd453741000b1a250932eea7e11..e8eedcd38cc53d3131144e2520027d54b625bb83 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-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
@@ -7,6 +7,28 @@ Fri Mar 30 13:35:27 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
        * 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
index dce61eb825a77acb44ec63ee801d5c0324cfd87d..5e3c1332feda4a6454a9475a6fa2fb8c0e000e96 100644 (file)
@@ -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:
index 74426a3b46dbdd37b04a2319c2a0c74fa389809e..003f0adffa1010394acdfde63fd94adab46a5e8a 100644 (file)
@@ -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;
 
index 38b2a86a5b5d2923f10c6854f0b5204f00aa33db..0b7b0bfd98f33fedc931e1d1ef31140585a94b57 100644 (file)
@@ -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
index e2f5d0e636ec5a42eb3a4444f2c28a741bed02d9..3ec4e53ce6edcea32c04994e7948919b3045072a 100644 (file)
@@ -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,
index b3f75baf155252116906b6dc8bd2f2ac192ad2c0..223709693d4c6bbacfaf06944840ddc8103670ec 100644 (file)
@@ -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,
index 0bb81178e249b1020161923619f4660733393768..6a73c0c15322e2974db78cd339b22fc3e6be0bf1 100644 (file)
@@ -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);
 
index d02bda7545b8a748a13b30afb31fc3a38a5dc80e..0cd883a5ec12ca1d05dfdbfe45bd95f8a3fdc7d8 100644 (file)
@@ -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);
index 62805382aff76dfd280177b26594760752d6b1e3..0dc9377a1c3efa0800e8a1616305127c0dabd14f 100644 (file)
@@ -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]
 
index cd71928af7e155ba5ed2581f919e7e83b484b63a..da02ad4392341ae4e90dc9590774951e5f173c2b 100644 (file)
@@ -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 <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>
@@ -1144,8 +1143,8 @@ ID's sent in arguments are sent inside ID Payload.
       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