Fixed KILLED notify handling in normal server.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 22 Jun 2002 20:53:46 +0000 (20:53 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 22 Jun 2002 20:53:46 +0000 (20:53 +0000)
CHANGES
apps/silcd/idlist.c
apps/silcd/idlist.h
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_internal.h
apps/silcd/server_util.c

diff --git a/CHANGES b/CHANGES
index 8885307aec58f219ceb349a77459cda8a66f2c0f..01fbdc4a4168fea133365bcaec9c0853298022e5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,33 @@
+Sat Jun 22 21:34:59 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+       * Added silc_client_udpate_server function to update changed
+         server info.  Affected file lib/silcclient/idlist.[ch].
+
+       * Added check for server entries that are being resolved when
+         notify is received.  If being resolved, handle the received
+         notify only after it's resolved so that all notifys are
+         handled in same order as received from the server.
+
+         Added similar resolver check to channel entries.  Every
+         notify that cause resolving of any information that affects
+         channel entry marks the channel entry in waiting state.
+         After whatever resolving is over the waiters are signalled
+         and only then the notifys are handled in the same order
+         as delivered from the server.
+
+         Affected files are lib/silcclient/idlist.[ch], and
+         client_notify.c.
+
+       * Fixed KILLED notify handling in normal server.  Affected
+         file silcd/packet_receive.c.
+
+       * Added SILC_IDLIST_STATUS_LOCAL which indicates that entry
+         is locally connected, or was locally connected (but may
+         be detached and connection is not active).  Added also
+         SILC_IS_LOCAL for checking this status.  Affected files
+         silcd/idlist.h, silcd/packet_receive.c, silcd/server_util.c,
+         silcd/server.c and silcd/server_internal.h.
+
 Sat Jun 22 17:06:58 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Don't send or handle TOPIC_SET if topic is already set and
index 3a8eb9d0e2b5d7694af14a79befbe5d3a5048088..c9599deb2ed21ff1236496e9a8007689dc81a23e 100644 (file)
@@ -76,6 +76,14 @@ void silc_idlist_del_data(void *entry)
     silc_hash_free(idata->hash);
   if (idata->public_key)
     silc_pkcs_public_key_free(idata->public_key);
+
+  idata->send_key = NULL;
+  idata->receive_key = NULL;
+  idata->rekey = NULL;
+  idata->hmac_send = NULL;
+  idata->hmac_receive = NULL;
+  idata->hash = NULL;
+  idata->public_key = NULL;
 }
 
 /* Purges ID cache */
index e2acc32919dd88a8b0a52dde01055c67848ab1d4..d7be279188c14c3195cd86e165c9ab2fbbd1b4ee 100644 (file)
@@ -63,6 +63,7 @@ typedef SilcUInt8 SilcIDListStatus;
                                                   with WHOIS or IDENTIFY */
 #define SILC_IDLIST_STATUS_DISABLED     0x08    /* Entry is disabled */
 #define SILC_IDLIST_STATUS_RESUMED      0x10    /* Entry is resumed */
+#define SILC_IDLIST_STATUS_LOCAL        0x20    /* Entry locally connected */
 
 /*
    Generic ID list data structure.
index bf4a1675fe98c1141de8784a75bbd495bac049d5..95486d8f61832a0ccc7b447806fa789847729785 100644 (file)
@@ -1160,6 +1160,13 @@ void silc_server_notify(SilcServer server,
       /* Re-announce our clients on the channel as the ID has changed now */
       silc_server_announce_get_channel_users(server, channel, &modes, &users,
                                             &users_modes);
+      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);
+      }
       if (modes) {
        silc_buffer_push(modes, modes->data - modes->head);
        silc_server_packet_send_dest(server, sock,
@@ -1168,13 +1175,6 @@ void silc_server_notify(SilcServer server,
                                     modes->data, modes->len, FALSE);
        silc_buffer_free(modes);
       }
-      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);
-      }
       if (users_modes) {
        silc_buffer_push(users_modes, users_modes->data - users_modes->head);
        silc_server_packet_send_dest(server, sock,
@@ -1416,10 +1416,10 @@ void silc_server_notify(SilcServer server,
 
       /* If the the client is not in local list we check global list */
       client = silc_idlist_find_client_by_id(server->global_list, 
-                                            client_id, TRUE, NULL);
+                                            client_id, TRUE, &cache);
       if (!client) {
        client = silc_idlist_find_client_by_id(server->local_list, 
-                                              client_id, TRUE, NULL);
+                                              client_id, TRUE, &cache);
        if (!client) {
          silc_free(client_id);
          goto out;
@@ -1463,7 +1463,8 @@ void silc_server_notify(SilcServer server,
          silc_free(client_id);
 
          /* Killer must be router operator */
-         if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
+         if (server->server_type != SILC_SERVER &&
+             !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
            SILC_LOG_DEBUG(("Killing is not allowed"));
            goto out;
          }
@@ -1482,10 +1483,25 @@ void silc_server_notify(SilcServer server,
                                       FALSE);
 
       /* Check if anyone is watching this nickname */
-      if (server->server_type == SILC_ROUTER)
-       silc_server_check_watcher_list(server, client, NULL,
-                                      SILC_NOTIFY_TYPE_KILLED);
+      silc_server_check_watcher_list(server, client, NULL,
+                                    SILC_NOTIFY_TYPE_KILLED);
 
+      /* Update statistics */
+      server->stat.clients--;
+      if (server->stat.cell_clients)
+       server->stat.cell_clients--;
+      SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+      SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
+      if (SILC_IS_LOCAL(client)) {
+       server->stat.my_clients--;
+       silc_schedule_task_del_by_context(server->schedule, client);
+       silc_idlist_del_data(client);
+       client->mode = 0;
+      }
+
+      client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
+      cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
       break;
     }
 
@@ -2956,6 +2972,13 @@ void silc_server_new_channel(SilcServer server,
         users on the channel "joining" the channel. */
       silc_server_announce_get_channel_users(server, channel, &modes, &users,
                                             &users_modes);
+      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);
+      }
       if (modes) {
        silc_buffer_push(modes, modes->data - modes->head);
        silc_server_packet_send_dest(server, sock,
@@ -2964,13 +2987,6 @@ void silc_server_new_channel(SilcServer server,
                                     modes->data, modes->len, FALSE);
        silc_buffer_free(modes);
       }
-      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);
-      }
       if (users_modes) {
        silc_buffer_push(users_modes, users_modes->data - users_modes->head);
        silc_server_packet_send_dest(server, sock,
@@ -3753,6 +3769,7 @@ void silc_server_resume_client(SilcServer server,
                     server->global_list->clients, 
                     detached_client->nickname,
                     detached_client->id, detached_client, FALSE, NULL);
+    detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
 
     /* Change the owner of the client if needed */
     if (detached_client->router != server_entry)
index 18c4011d78832fd33513f9b97a0c66556ccaba15..818ec0f015a3209a108a4fb571c705535f1842f2 100644 (file)
@@ -596,7 +596,8 @@ void silc_server_packet_send_to_channel(SilcServer server,
     goto out;
   }
 
-  SILC_LOG_DEBUG(("Sending packet to channel %s", channel->channel_name));
+  SILC_LOG_DEBUG(("Sending %s packet to channel %s",
+                 silc_get_packet_name(type), channel->channel_name));
 
   routed = silc_calloc(silc_hash_table_count(channel->user_list), 
                       sizeof(*routed));
@@ -636,6 +637,10 @@ void silc_server_packet_send_to_channel(SilcServer server,
        gone = TRUE;
       }
 
+      SILC_LOG_DEBUG(("Sending packet to client %s",
+                     client->nickname ? client->nickname :
+                     (unsigned char *)""));
+
       /* Send the packet */
       silc_server_packet_send_to_channel_real(server, sock, &packetdata,
                                              idata->send_key, 
@@ -661,6 +666,10 @@ void silc_server_packet_send_to_channel(SilcServer server,
     if (!sock || (sender && sock == sender))
       continue;
 
+    SILC_LOG_DEBUG(("Sending packet to client %s",
+                   client->nickname ? client->nickname :
+                   (unsigned char *)""));
+
     /* Send the packet */
     silc_server_packet_send_to_channel_real(server, sock, &packetdata,
                                            idata->send_key, 
index ee5765eeb5fe2143aa5d82c5aae7b88ac033d1cd..b622ed877185d31d0eb2eb623ad63222c8c66ab9 100644 (file)
@@ -1573,6 +1573,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
        server->stat.auth_failures++;
        goto out;
       }
+      entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
 
       /* Statistics */
       server->stat.my_clients++;
@@ -1677,6 +1678,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
        server->stat.auth_failures++;
        goto out;
       }
+      entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
 
       /* Statistics */
       if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER) {
@@ -1875,8 +1877,6 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
     return;
   }
 
-  server->stat.packets_received++;
-
   /* Get keys and stuff from ID entry */
   idata = (SilcIDListData)sock->user_data;
   if (idata) {
@@ -1917,6 +1917,8 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
   SilcIDListData idata = (SilcIDListData)sock->user_data;
   int ret;
 
+  server->stat.packets_received++;
+
   /* Parse the packet */
   if (parse_ctx->normal)
     ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
@@ -2924,7 +2926,7 @@ void silc_server_remove_from_channels(SilcServer server,
     silc_free(chl);
 
     /* Update statistics */
-    if (client->connection)
+    if (SILC_IS_LOCAL(client))
       server->stat.my_chanclients--;
     if (server->server_type == SILC_ROUTER) {
       server->stat.cell_chanclients--;
@@ -3022,7 +3024,7 @@ bool silc_server_remove_from_one_channel(SilcServer server,
   silc_free(chl);
 
   /* Update statistics */
-  if (client->connection)
+  if (SILC_IS_LOCAL(client))
     server->stat.my_chanclients--;
   if (server->server_type == SILC_ROUTER) {
     server->stat.cell_chanclients--;
@@ -3992,6 +3994,20 @@ void silc_server_announce_channels(SilcServer server,
     silc_buffer_free(channels);
   }
 
+  if (channel_users) {
+    silc_buffer_push(channel_users, channel_users->data - channel_users->head);
+    SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
+                    channel_users->len);
+
+    /* Send the packet */
+    silc_server_packet_send(server, remote,
+                           SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+                           channel_users->data, channel_users->len,
+                           FALSE);
+
+    silc_buffer_free(channel_users);
+  }
+
   if (channel_modes) {
     int i;
 
@@ -4014,20 +4030,6 @@ void silc_server_announce_channels(SilcServer server,
     silc_free(channel_modes);
   }
 
-  if (channel_users) {
-    silc_buffer_push(channel_users, channel_users->data - channel_users->head);
-    SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
-                    channel_users->len);
-
-    /* Send the packet */
-    silc_server_packet_send(server, remote,
-                           SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
-                           channel_users->data, channel_users->len,
-                           FALSE);
-
-    silc_buffer_free(channel_users);
-  }
-
   if (channel_users_modes) {
     int i;
 
index f2a141008bffa01ed3d0f5aed4f5d5995cf2dcb1..1d679b0b30a5bbeaa2c127a226614fe654ccaeba 100644 (file)
@@ -55,8 +55,8 @@ typedef struct {
   SilcUInt32 conn_failures;              /* Connection failure */
   SilcUInt32 auth_attempts;              /* Authentication attempts */
   SilcUInt32 auth_failures;              /* Authentication failures */
-  SilcUInt32 packets_sent;               /* Sent packets */
-  SilcUInt32 packets_received;           /* Received packets */
+  SilcUInt32 packets_sent;               /* Sent SILC packets */
+  SilcUInt32 packets_received;           /* Received SILC packets */
 } SilcServerStatistics;
 
 /*
@@ -162,6 +162,11 @@ typedef struct {
 /* Return TRUE if a packet must be broadcasted (router broadcasts) */
 #define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER) 
 
+/* Return TRUE if entry is locally connected or local to us */
+#define SILC_IS_LOCAL(entry)                                           \
+  ((entry)->connection ? TRUE :                                                \
+   (entry)->data.status & SILC_IDLIST_STATUS_LOCAL ? TRUE : FALSE)
+
 /* Registers generic task for file descriptor for reading from network and
    writing to network. As being generic task the actual task is allocated 
    only once and after that the same task applies to all registered fd's. */
@@ -187,7 +192,7 @@ do {                                                                              \
 #define SILC_OPER_STATS_UPDATE(c, type, mod)   \
 do {                                           \
   if ((c)->mode & (mod)) {                     \
-    if ((c)->connection)                       \
+    if (SILC_IS_LOCAL((c)))                    \
       server->stat.my_ ## type ## _ops--;      \
     if (server->server_type == SILC_ROUTER)    \
       server->stat. type ## _ops--;            \
@@ -199,14 +204,14 @@ do {                                              \
 do {                                           \
     if (client->mode & (mod)) {                        \
       if (!(mode & (mod))) {                   \
-       if (client->connection)                 \
+       if (SILC_IS_LOCAL(client))              \
          server->stat.my_ ## oper ## _ops--;   \
         if (server->server_type == SILC_ROUTER)        \
          server->stat. oper ## _ops--;         \
       }                                                \
     } else {                                   \
       if (mode & (mod)) {                      \
-       if (client->connection)                 \
+       if (SILC_IS_LOCAL(client))              \
          server->stat.my_ ## oper ## _ops++;   \
         if (server->server_type == SILC_ROUTER)        \
          server->stat. oper ## _ops++;         \
index 713b8528bd336120251b811259921e49218ab921..6e3056c7e49fae5e9fda99e00f31b6b13f3ae7b3 100644 (file)
@@ -77,7 +77,7 @@ silc_server_remove_clients_channels(SilcServer server,
     silc_free(chl);
 
     /* Update statistics */
-    if (client->connection)
+    if (SILC_IS_LOCAL(client))
       server->stat.my_chanclients--;
     if (server->server_type == SILC_ROUTER) {
       server->stat.cell_chanclients--;
@@ -762,7 +762,7 @@ bool silc_server_channel_delete(SilcServer server,
     channel->user_count--;
 
     /* Update statistics */
-    if (chl->client->connection)
+    if (SILC_IS_LOCAL(chl->client))
       server->stat.my_chanclients--;
     if (server->server_type == SILC_ROUTER) {
       server->stat.cell_chanclients--;
@@ -1307,12 +1307,17 @@ void silc_server_kill_client(SilcServer server,
   } else {
     /* Update statistics */
     server->stat.clients--;
-    server->stat.my_clients--;
     if (server->stat.cell_clients)
       server->stat.cell_clients--;
     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
 
+    if (SILC_IS_LOCAL(remote_client)) {
+      server->stat.my_clients--;
+      silc_schedule_task_del_by_context(server->schedule, remote_client);
+      silc_idlist_del_data(remote_client);
+    }
+
     /* Remove remote client */
     if (!silc_idlist_del_client(server->global_list, remote_client)) {
       /* Remove this client from watcher list if it is */