+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.
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!
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)
}
}
+ /* 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;
goto out;
}
server->stat.my_channels++;
+ server->stat.channels++;
} else {
/* The entry exists. */
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:
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;
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;
}
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);
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.
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. */
/* 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
}
}
-/* 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) {
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
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)
}
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;
}
}
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;
}
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 */
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 */
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;
/*
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
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;
}
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);
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);
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);
}
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() */
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. */