aboutsummaryrefslogtreecommitdiffstats
path: root/src/stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stats.c')
-rw-r--r--src/stats.c249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/stats.c b/src/stats.c
new file mode 100644
index 0000000..800a4cc
--- /dev/null
+++ b/src/stats.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2002 Erik Fears
+ * Copyright (c) 2014-2018 ircd-hybrid development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "setup.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/resource.h> /* getrlimit */
+#include <errno.h>
+
+#include "irc.h"
+#include "log.h"
+#include "misc.h"
+#include "config.h"
+#include "stats.h"
+#include "libopm/src/opm_types.h"
+
+static time_t STATS_UPTIME;
+static unsigned int STATS_CONNECTIONS;
+static unsigned int STATS_DNSBLSENT;
+
+static struct StatsHash STATS_PROXIES[] =
+{
+ { .type = OPM_TYPE_HTTP, .name = "HTTP" },
+ { .type = OPM_TYPE_HTTPPOST, .name = "HTTPPOST" },
+ { .type = OPM_TYPE_HTTPS, .name = "HTTPS" },
+ { .type = OPM_TYPE_HTTPSPOST, .name = "HTTPSPOST" },
+ { .type = OPM_TYPE_SOCKS4, .name = "SOCKS4" },
+ { .type = OPM_TYPE_SOCKS5, .name = "SOCKS5" },
+ { .type = OPM_TYPE_ROUTER, .name = "ROUTER" },
+ { .type = OPM_TYPE_WINGATE, .name = "WINGATE" },
+ { .type = OPM_TYPE_DREAMBOX, .name = "DREAMBOX" },
+ { .type = OPM_TYPE_SSH, .name = "SSH" },
+ { .type = 0 }
+};
+
+
+/* stats_init
+ *
+ * Perform initialization of HOPM stats
+ *
+ * Parameters: NONE
+ * Return: NONE
+ *
+ */
+void
+stats_init(void)
+{
+ time(&STATS_UPTIME);
+}
+
+/* stats_openproxy
+ *
+ * Record open proxy.
+ *
+ *
+ * Parameters: NONE
+ * Return: NONE
+ *
+ */
+void
+stats_openproxy(unsigned int type)
+{
+ for (struct StatsHash *tab = STATS_PROXIES; tab->name; ++tab)
+ {
+ if (tab->type == type)
+ {
+ ++tab->count;
+ break;
+ }
+ }
+}
+
+/* stats_connect
+ *
+ * Record IRC connect.
+ *
+ *
+ * Parameters: NONE
+ * Return: NONE
+ *
+ */
+void
+stats_connect(void)
+{
+ ++STATS_CONNECTIONS;
+}
+
+/* stats_dnsblrecv
+ *
+ * Record that a user was found in the blacklist.
+ *
+ * Parameters: BlacklistConf structure
+ * Return: NONE
+ *
+ */
+void
+stats_dnsblrecv(struct BlacklistConf *bl)
+{
+ ++bl->stats_recv;
+}
+
+/* stats_dnsblsend
+ *
+ * Record a sent report
+ *
+ * Parameters: NONE
+ * Return: NONE
+ *
+ */
+void
+stats_dnsblsend(void)
+{
+ ++STATS_DNSBLSENT;
+}
+
+/* stats_output
+ *
+ * Output stats to target via privmsg
+ *
+ *
+ * Parameters: NONE
+ * Return: NONE
+ *
+ */
+void
+stats_output(const char *target)
+{
+ time_t present;
+ time_t uptime;
+ node_t *p;
+
+ time(&present);
+ uptime = present - STATS_UPTIME;
+
+ irc_send("PRIVMSG %s :Uptime: %s", target, time_dissect(uptime));
+
+ LIST_FOREACH(p, OpmItem.blacklists.head)
+ {
+ const struct BlacklistConf *bl = p->data;
+
+ if (bl->stats_recv)
+ irc_send("PRIVMSG %s :DNSBL: %u successful lookups from %s",
+ target, bl->stats_recv, bl->name);
+ }
+
+ if (STATS_DNSBLSENT)
+ irc_send("PRIVMSG %s :DNSBL: %u reports sent", target,
+ STATS_DNSBLSENT);
+
+ for (const struct StatsHash *tab = STATS_PROXIES; tab->name; ++tab)
+ if (tab->count)
+ irc_send("PRIVMSG %s :Found %u (%s) open.", target,
+ tab->count, tab->name);
+
+ irc_send("PRIVMSG %s :Number of connects: %u (%.2f/minute)",
+ target, STATS_CONNECTIONS, STATS_CONNECTIONS ?
+ (float)STATS_CONNECTIONS / ((float)uptime / 60.0) : 0.0);
+}
+
+/* fdstats_output
+ *
+ * Output file descriptor stats to target via privmsg
+ *
+ *
+ * Parameters: NONE
+ * Return: NONE
+ *
+ */
+void
+fdstats_output(const char *target)
+{
+ struct rlimit rlim;
+ unsigned int total_fd_use = 0;
+
+ /* Get file descriptor ceiling */
+ if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
+ {
+ log_printf("FDSTAT -> getrlimit() error retrieving RLIMIT_NOFILE (%s)", strerror(errno));
+ irc_send("PRIVMSG %s :FDSTAT -> getrlimit() error retrieving RLIMIT_NOFILE (%s)",
+ target, strerror(errno));
+ return;
+ }
+
+ /*
+ * Check which file descriptors are active, based on suggestions from:
+ * http://groups.google.com/groups?th=a48b9fe8ca43947c&rnum=1
+ */
+ for (unsigned int i = 0; i < rlim.rlim_cur; ++i)
+ {
+ int newfd = dup(i);
+
+ if (newfd > -1)
+ {
+ ++total_fd_use;
+ close(newfd);
+ }
+ else
+ {
+ switch (errno)
+ {
+ case EMFILE:
+ /*
+ * We ran out of FDs whilst trying to dup an existing one,
+ * so all fds are open and we can stop checking here.
+ */
+ i = total_fd_use = rlim.rlim_cur;
+ break;
+
+ case EBADF:
+ /* Not an FD in use. */
+ break;
+
+ case EINTR:
+ /* Try again. */
+ --i;
+ break;
+
+ default:
+ /* We don't expect any other errors. */
+ log_printf("fd %u errno = %u (%s)", i, errno, strerror(errno));
+ break;
+ }
+ }
+ }
+
+ irc_send("PRIVMSG %s :Total open FD: %u/%d", target, total_fd_use, rlim.rlim_cur);
+}