Added statistics updating and statisics dumping with SIGUSR1.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 15 Jun 2002 16:06:53 +0000 (16:06 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 15 Jun 2002 16:06:53 +0000 (16:06 +0000)
CHANGES
TODO
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_internal.h
apps/silcd/server_util.c
apps/silcd/serverconfig.c
apps/silcd/silcd.c

diff --git a/CHANGES b/CHANGES
index 78742aa6de19d2ae6127303cdad3f75848572138..715fed19e6918cd78d4c867f1465b7d89b114f69 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+Sat Jun 15 18:23:39 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+       * Added lots of new statistics updating that was missing from
+         the server and router code.  Affected files in silcd/.
+
+       * Sending SIGUSR1 signal to server now dumps the current
+         server statistics into /tmp directory.  Affected file is
+         silcd/silcd.c.
+
 Sat Jun 15 12:09:14 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Added some better info printing for client during connecting.
diff --git a/TODO b/TODO
index 3ab775e25ee3e5ff350abac419c471fa83b954ca..737c025e68ce61a4b0631b2f5f378c7e6de24fa2 100644 (file)
--- a/TODO
+++ b/TODO
@@ -30,8 +30,6 @@ TODO/bugs In SILC Server
    each JOIN command will create and distribute the new channel key
    to everybody on the channel (Fix this to 0.9.x).
 
- o Lots of statistics updating is missing around the server.
-
  o If client's public key is saved in the server (and doing public key
    authentication) then the hostname and the username information could
    be taken from the public key.  Should be a configuration option!
index 6efee9d02707634c254677a072275c7db0a653ff..168f7bb3e8c7f85bb3637090bcead14592fe9de4 100644 (file)
@@ -3420,6 +3420,13 @@ static void silc_server_command_join_channel(SilcServer server,
                                     clidp->data, clidp->len,
                                     chidp->data, chidp->len);
 
+  /* Update statistics */
+  server->stat.my_chanclients++;
+  if (server->server_type == SILC_ROUTER) {
+    server->stat.cell_chanclients++;
+    server->stat.chanclients++;
+  }
+
   if (!cmd->pending) {
     /* Send JOIN notify packet to our primary router */
     if (!server->standalone)
@@ -3859,6 +3866,22 @@ SILC_SERVER_CMD_FUNC(umode)
       }
     }
 
+    /* Update statistics */
+    if (mask & SILC_UMODE_GONE) {
+      if (!client->mode & SILC_UMODE_GONE)
+       server->stat.my_aways++;
+    } else {
+      if (client->mode & SILC_UMODE_GONE)
+       server->stat.my_aways--;
+    }
+    if (mask & SILC_UMODE_DETACHED) {
+      if (!client->mode & SILC_UMODE_DETACHED)
+       server->stat.my_detached++;
+    } else {
+      if (client->mode & SILC_UMODE_DETACHED)
+       server->stat.my_detached--;
+    }
+
     /* Change the mode */
     client->mode = mask;
 
index 22fe1f1c9b78ac305d8bfde08bdf6efb5f57b80a..a904d3a579ea5abe6085aed211ef9794735b2ab9 100644 (file)
@@ -892,6 +892,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
       goto out;
     }
     server->stat.my_channels++;
+    server->stat.channels++;
   } else {
     /* The entry exists. */
 
index 67454f94e9bd49bf01130f8da8fdf41d6330bc0b..a2a756a0c4bb2ae80ce88950a1c7e6b3c7fa18e3 100644 (file)
@@ -233,6 +233,13 @@ void silc_server_notify(SilcServer server,
     channel->user_count++;
     channel->disabled = FALSE;
 
+    /* Update statistics */
+    if (server->server_type == SILC_ROUTER) {
+      if (sock->type != SILC_SOCKET_TYPE_ROUTER)
+       server->stat.cell_chanclients++;
+      server->stat.chanclients++;
+    }
+
     break;
 
   case SILC_NOTIFY_TYPE_LEAVE:
@@ -1195,7 +1202,9 @@ void silc_server_notify(SilcServer server,
     silc_idlist_del_server(local ? server->local_list :
                           server->global_list, server_entry);
 
-    /* XXX update statistics */
+    /* Update statistics */
+    if (server->server_type == SILC_ROUTER)
+      server->stat.servers--;
 
     break;
 
@@ -1430,6 +1439,24 @@ void silc_server_notify(SilcServer server,
     if (mode & SILC_UMODE_DETACHED)
       client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
 
+    /* Update statistics */
+    if (server->server_type == SILC_ROUTER) {
+      if (mode & SILC_UMODE_GONE) {
+       if (!client->mode & SILC_UMODE_GONE)
+         server->stat.aways++;
+      } else {
+       if (client->mode & SILC_UMODE_GONE)
+         server->stat.aways--;
+      }
+      if (mode & SILC_UMODE_DETACHED) {
+       if (!client->mode & SILC_UMODE_DETACHED)
+         server->stat.detached++;
+      } else {
+       if (client->mode & SILC_UMODE_DETACHED)
+         server->stat.detached--;
+      }
+    }
+
     /* Change the mode */
     client->mode = mode;
 
@@ -2754,12 +2781,6 @@ void silc_server_new_channel(SilcServer server,
       }
       channel->disabled = TRUE;
 
-#if 0
-      /* CMODE change notify is expected */
-      /* Get the mode and set it to the channel */
-      channel->mode = silc_channel_get_mode(payload);
-#endif
-
       /* Send the new channel key to the server */
       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
@@ -2772,7 +2793,6 @@ 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);
-
     } else {
       /* 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.
@@ -2827,6 +2847,10 @@ void silc_server_new_channel(SilcServer server,
 
       silc_free(channel_id);
 
+      /* Update statistics */
+      server->stat.channels++;
+      server->stat.cell_channels++;
+
       /* 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. */
index 40d303e621b84e7c1626a4210268bd0c18a1ce41..512ee42370873ddc32a9922497a821b3c7646e0e 100644 (file)
@@ -50,8 +50,10 @@ int silc_server_packet_send_real(SilcServer server,
 
   /* Send the packet */
   ret = silc_packet_send(sock, force_send);
-  if (ret != -2)
+  if (ret != -2) {
+    server->stat.packets_sent++;
     return ret;
+  }
 
   /* Mark that there is some outgoing data available for this connection. 
      This call sets the connection both for input and output (the input
index bbc25aa115279aedc840ab3f8ce76e185394953a..5cbe0bbcd3574204aafa86378d00c6680c63b520 100644 (file)
@@ -115,12 +115,10 @@ void silc_server_free(SilcServer server)
   }
 }
 
-/* Opens a listening port.
-   XXX This function will become more general and will support multiple
-   listening ports */
+/* Creates a new server listener. */
 
 static bool silc_server_listen(SilcServer server, const char *server_ip,
-                               SilcUInt16 port, int *sock)
+                              SilcUInt16 port, int *sock)
 {
   *sock = silc_net_create_server(port, server_ip);
   if (*sock < 0) {
@@ -2876,7 +2874,14 @@ void silc_server_remove_from_channels(SilcServer server,
       channel->global_users = FALSE;
 
     silc_free(chl);
-    server->stat.my_chanclients--;
+
+    /* Update statistics */
+    if (client->connection)
+      server->stat.my_chanclients--;
+    if (server->server_type == SILC_ROUTER) {
+      server->stat.cell_chanclients--;
+      server->stat.chanclients--;
+    }
 
     /* If there is not at least one local user on the channel then we don't
        need the channel entry anymore, we can remove it safely, unless the
@@ -2966,7 +2971,14 @@ bool silc_server_remove_from_one_channel(SilcServer server,
     channel->global_users = FALSE;
 
   silc_free(chl);
-  server->stat.my_chanclients--;
+
+  /* Update statistics */
+  if (client->connection)
+    server->stat.my_chanclients--;
+  if (server->server_type == SILC_ROUTER) {
+    server->stat.cell_chanclients--;
+    server->stat.chanclients--;
+  }
 
   clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
   if (!clidp)
@@ -3131,9 +3143,11 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server,
   }
 
   server->stat.my_channels++;
-
-  if (server->server_type == SILC_ROUTER)
+  if (server->server_type == SILC_ROUTER) {
+    server->stat.channels++;
+    server->stat.cell_channels++;
     entry->users_resolved = TRUE;
+  }
 
   return entry;
 }
@@ -3214,9 +3228,11 @@ silc_server_create_new_channel_with_id(SilcServer server,
   }
 
   server->stat.my_channels++;
-
-  if (server->server_type == SILC_ROUTER)
+  if (server->server_type == SILC_ROUTER) {
+    server->stat.channels++;
+    server->stat.cell_channels++;
     entry->users_resolved = TRUE;
+  }
 
   return entry;
 }
index 7e773c863d3c37bd492023024b473875eda66096..c435c77622a9a0b46207d8557c643bbdf57ce4a7 100644 (file)
@@ -29,8 +29,9 @@ typedef struct {
   SilcUInt32 my_servers;                 /* Locally connected servers */
   SilcUInt32 my_routers;                 /* Locally connected routers */
   SilcUInt32 my_channels;                /* Locally created channels */
-  SilcUInt32 my_chanclients;     /* Local clients on local channels */
-  SilcUInt32 my_aways;           /* Local clients away (XXX) */
+  SilcUInt32 my_chanclients;             /* Local clients on local channels */
+  SilcUInt32 my_aways;                   /* Local clients away (gone) */
+  SilcUInt32 my_detached;                /* Local clients detached */
   SilcUInt32 my_server_ops;              /* Local server operators */
   SilcUInt32 my_router_ops;              /* Local router operators */
 
@@ -38,12 +39,14 @@ typedef struct {
   SilcUInt32 cell_clients;               /* All clients in cell */
   SilcUInt32 cell_servers;               /* All servers in cell */
   SilcUInt32 cell_channels;              /* All channels in cell */
-  SilcUInt32 cell_chanclients;   /* All clients on cell's channels */
-  SilcUInt32 clients;            /* All clients */
-  SilcUInt32 servers;            /* All servers */
-  SilcUInt32 routers;            /* All routers */
-  SilcUInt32 channels;           /* All channels */
+  SilcUInt32 cell_chanclients;           /* All clients on cell's channels */
+  SilcUInt32 clients;                    /* All clients */
+  SilcUInt32 servers;                    /* All servers */
+  SilcUInt32 routers;                    /* All routers */
+  SilcUInt32 channels;                   /* All channels */
   SilcUInt32 chanclients;                /* All clients on channels */
+  SilcUInt32 aways;                      /* All clients away (gone) */
+  SilcUInt32 detached;                   /* All clients detached */
   SilcUInt32 server_ops;                 /* All server operators */
   SilcUInt32 router_ops;                 /* All router operators */
 
@@ -53,7 +56,7 @@ typedef struct {
   SilcUInt32 auth_attempts;              /* Authentication attempts */
   SilcUInt32 auth_failures;              /* Authentication failures */
   SilcUInt32 packets_sent;               /* Sent packets */
-  SilcUInt32 packets_received;   /* Received packets */
+  SilcUInt32 packets_received;           /* Received packets */
 } SilcServerStatistics;
 
 /*
index 2f815d25254f0e4cb34c92bb18dbb74eec81f0c0..e7bff22110e2b36b0d18a94f4b26379bc2bafd2e 100644 (file)
@@ -73,7 +73,14 @@ static void silc_server_remove_clients_channels(SilcServer server,
       channel->global_users = FALSE;
 
     silc_free(chl);
-    server->stat.my_chanclients--;
+
+    /* Update statistics */
+    if (client->connection)
+      server->stat.my_chanclients--;
+    if (server->server_type == SILC_ROUTER) {
+      server->stat.cell_chanclients--;
+      server->stat.chanclients--;
+    }
 
     /* If there is not at least one local user on the channel then we don't
        need the channel entry anymore, we can remove it safely, unless the
@@ -721,13 +728,25 @@ bool silc_server_channel_delete(SilcServer server,
   if (delchan) {
     SILC_LOG_DEBUG(("Deleting %s channel", channel->channel_name));
 
+    /* Update statistics */
+    if (server->server_type == SILC_ROUTER)
+      server->stat.chanclients -= channel->user_count;
+
     /* Totally delete the channel and all users on the channel. The
        users are deleted automatically in silc_idlist_del_channel. */
     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
-    if (silc_idlist_del_channel(server->local_list, channel))
+    if (silc_idlist_del_channel(server->local_list, channel)) {
       server->stat.my_channels--;
-    else
-      silc_idlist_del_channel(server->global_list, channel);
+      if (server->server_type == SILC_ROUTER) {
+       server->stat.channels--;
+       server->stat.cell_channels--;
+      }
+    } else {
+      if (silc_idlist_del_channel(server->global_list, channel))
+       if (server->server_type == SILC_ROUTER)
+         server->stat.channels--;
+    }
+
     return FALSE;
   }
 
@@ -738,6 +757,15 @@ bool silc_server_channel_delete(SilcServer server,
     silc_hash_table_del(chl->client->channels, channel);
     silc_hash_table_del(channel->user_list, chl->client);
     channel->user_count--;
+
+    /* Update statistics */
+    if (chl->client->connection)
+      server->stat.my_chanclients--;
+    if (server->server_type == SILC_ROUTER) {
+      server->stat.cell_chanclients--;
+      server->stat.chanclients--;
+    }
+
     silc_free(chl);
   }
   silc_hash_table_list_reset(&htl);
index 54425dd675d76e9a4b585da89c72a24195803dbf..d9fe747adb60d02bd2a43f4b5bb194f00c68754c 100644 (file)
@@ -1256,8 +1256,6 @@ SilcServerConfig silc_server_config_alloc(const char *filename)
     return NULL;
   }
 
-  /* XXX are there any other mandatory sections in the config file? */
-
   /* Set default to configuration parameters */
   silc_server_config_set_defaults(config_new);
 
index bb8dc0d44d14b67f3ea8274b25053504e0700f7a..3386f6646ded4c4f7cf95cc70eac8531ee48c8d1 100644 (file)
@@ -245,9 +245,8 @@ static void signal_handler(int sig)
 SILC_TASK_CALLBACK(got_hup)
 {
   /* First, reset all log files (they might have been deleted) */
-  /* XXX this may be redundant with the silc_server_config_setlogfiles() call.
-   * merge these two with the appropriate checking. */
   silc_log_reset_all();
+
   /* Rehash the configuration file */
   silc_server_rehash(silcd);
 }
@@ -259,6 +258,58 @@ SILC_TASK_CALLBACK(stop_server)
   silc_schedule_stop(silcd->schedule);
 }
 
+/* Dump server statistics into a file into /tmp directory */
+
+SILC_TASK_CALLBACK(dump_stats)
+{
+  FILE *fdd;
+  char filename[256];
+
+  memset(filename, 0, sizeof(filename));
+  snprintf(filename, sizeof(filename) - 1, "/tmp/silcd.%d.stats", getpid());
+  fdd = fopen(filename, "w+");
+  if (!fdd)
+    return;
+
+#define STAT_OUTPUT(fmt, stat) fprintf(fdd, fmt "\n", (int)stat);
+
+  fprintf(fdd, "SILC Server %s Statistics\n\n", silcd->server_name);
+  fprintf(fdd, "Local Stats:\n");
+  STAT_OUTPUT("  My clients              : %d", silcd->stat.my_clients);
+  STAT_OUTPUT("  My servers              : %d", silcd->stat.my_servers);
+  STAT_OUTPUT("  My routers              : %d", silcd->stat.my_routers);
+  STAT_OUTPUT("  My channels             : %d", silcd->stat.my_channels);
+  STAT_OUTPUT("  My joined users         : %d", silcd->stat.my_chanclients);
+  STAT_OUTPUT("  My aways                : %d", silcd->stat.my_aways);
+  STAT_OUTPUT("  My detached clients     : %d", silcd->stat.my_detached);
+  STAT_OUTPUT("  My server operators     : %d", silcd->stat.my_server_ops);
+  STAT_OUTPUT("  My router operators     : %d", silcd->stat.my_router_ops);
+  fprintf(fdd, "\nGlobal Stats:\n");
+  STAT_OUTPUT("  Cell clients            : %d", silcd->stat.cell_clients);
+  STAT_OUTPUT("  Cell servers            : %d", silcd->stat.cell_servers);
+  STAT_OUTPUT("  Cell channels           : %d", silcd->stat.cell_channels);
+  STAT_OUTPUT("  Cell joined users       : %d", silcd->stat.cell_chanclients);
+  STAT_OUTPUT("  All clients             : %d", silcd->stat.clients);
+  STAT_OUTPUT("  All servers             : %d", silcd->stat.servers);
+  STAT_OUTPUT("  All routers             : %d", silcd->stat.routers);
+  STAT_OUTPUT("  All channels            : %d", silcd->stat.channels);
+  STAT_OUTPUT("  All joined users        : %d", silcd->stat.chanclients);
+  STAT_OUTPUT("  All aways               : %d", silcd->stat.aways);
+  STAT_OUTPUT("  All detached clients    : %d", silcd->stat.detached);
+  STAT_OUTPUT("  All server operators    : %d", silcd->stat.server_ops);
+  STAT_OUTPUT("  All router operators    : %d", silcd->stat.router_ops);
+  fprintf(fdd, "\nGeneral Stats:\n");
+  STAT_OUTPUT("  Connection attempts     : %d", silcd->stat.conn_attempts);
+  STAT_OUTPUT("  Connection failures     : %d", silcd->stat.conn_failures);
+  STAT_OUTPUT("  Authentication attempts : %d", silcd->stat.auth_attempts);
+  STAT_OUTPUT("  Authentication failures : %d", silcd->stat.auth_failures);
+  STAT_OUTPUT("  Packets sent            : %d", silcd->stat.packets_sent);
+  STAT_OUTPUT("  Packets received        : %d", silcd->stat.packets_received);
+
+  fflush(fdd);
+  fclose(fdd);
+}
+
 /* This function should not be called directly but throught the wrapper
    macro SILC_SERVER_LOG_STDERR() */
 
@@ -398,9 +449,11 @@ int main(int argc, char **argv)
   sigaction(SIGHUP, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);
   sigaction(SIGINT, &sa, NULL);
+  sigaction(SIGUSR1, &sa, NULL);
   silc_schedule_signal_register(silcd->schedule, SIGHUP, got_hup, NULL);
   silc_schedule_signal_register(silcd->schedule, SIGTERM, stop_server, NULL);
   silc_schedule_signal_register(silcd->schedule, SIGINT, stop_server, NULL);
+  silc_schedule_signal_register(silcd->schedule, SIGUSR1, dump_stats, NULL);
 
   if (!foreground) {
     /* Before running the server, fork to background. */