summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-12-20 20:15:44 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-12-20 20:15:44 +0000
commitc678804f02763fbba27fd8cdb0f410f0a5b91b33 (patch)
treea202eab03d6f64e3524fc93df37769c0e078fbb3
parentec7125ff6c5791611f3d901b4bd4d291bf45e23c (diff)
implement statistics for redirections, like the existing statistics
for relays. they can be viewed with the new "relayctl show redirects" command. (uses the previous change to pf_table.c to get the statistics) looks good pyr@
-rw-r--r--usr.sbin/relayctl/parser.c3
-rw-r--r--usr.sbin/relayctl/parser.h3
-rw-r--r--usr.sbin/relayctl/relayctl.810
-rw-r--r--usr.sbin/relayctl/relayctl.c75
-rw-r--r--usr.sbin/relayd/pfe.c67
-rw-r--r--usr.sbin/relayd/pfe_filter.c40
-rw-r--r--usr.sbin/relayd/relayd.h24
7 files changed, 173 insertions, 49 deletions
diff --git a/usr.sbin/relayctl/parser.c b/usr.sbin/relayctl/parser.c
index f3316f2569e..303713537f9 100644
--- a/usr.sbin/relayctl/parser.c
+++ b/usr.sbin/relayctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.19 2007/12/08 20:36:36 pyr Exp $ */
+/* $OpenBSD: parser.c,v 1.20 2007/12/20 20:15:43 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -80,6 +80,7 @@ static const struct token t_main[] = {
static const struct token t_show[] = {
{KEYWORD, "summary", SHOW_SUM, NULL},
{KEYWORD, "hosts", SHOW_HOSTS, NULL},
+ {KEYWORD, "redirects", SHOW_RDRS, NULL},
{KEYWORD, "relays", SHOW_RELAYS, NULL},
{KEYWORD, "sessions", SHOW_SESSIONS, NULL},
{ENDTOKEN, "", NONE, NULL}
diff --git a/usr.sbin/relayctl/parser.h b/usr.sbin/relayctl/parser.h
index 32d9f79baeb..91e3e949671 100644
--- a/usr.sbin/relayctl/parser.h
+++ b/usr.sbin/relayctl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.8 2007/12/08 20:36:36 pyr Exp $ */
+/* $OpenBSD: parser.h,v 1.9 2007/12/20 20:15:43 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -20,6 +20,7 @@ enum actions {
NONE,
SHOW_SUM,
SHOW_HOSTS,
+ SHOW_RDRS,
SHOW_RELAYS,
SHOW_SESSIONS,
RDR_DISABLE,
diff --git a/usr.sbin/relayctl/relayctl.8 b/usr.sbin/relayctl/relayctl.8
index ddf9fe81ad4..08cb980d92d 100644
--- a/usr.sbin/relayctl/relayctl.8
+++ b/usr.sbin/relayctl/relayctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: relayctl.8,v 1.19 2007/12/12 14:55:12 jmc Exp $
+.\" $OpenBSD: relayctl.8,v 1.20 2007/12/20 20:15:43 reyk Exp $
.\"
.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: December 12 2007 $
+.Dd $Mdocdate: December 20 2007 $
.Dt RELAYCTL 8
.Os
.Sh NAME
@@ -59,7 +59,11 @@ the backup table as well.
.It Cm reload
Reload the configuration file.
.It Cm show hosts
-Show detailed status of hosts, tables, and redirections.
+Show detailed status of hosts and tables.
+.It Cm show redirects
+Show detailed status of redirections including the current and average
+access statistics.
+The statistics will be updated every minute.
.It Cm show relays
Show detailed status of relays including the current and average
access statistics.
diff --git a/usr.sbin/relayctl/relayctl.c b/usr.sbin/relayctl/relayctl.c
index 59a1fdd1c30..b0a8c5b1c6e 100644
--- a/usr.sbin/relayctl/relayctl.c
+++ b/usr.sbin/relayctl/relayctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayctl.c,v 1.30 2007/12/08 20:36:36 pyr Exp $ */
+/* $OpenBSD: relayctl.c,v 1.31 2007/12/20 20:15:43 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -51,6 +51,7 @@ char *print_rdr_status(int);
char *print_host_status(int, int);
char *print_table_status(int, int);
char *print_relay_status(int);
+void print_statistics(struct ctl_stats[RELAY_MAXPROC + 1]);
struct imsgname {
int type;
@@ -143,6 +144,7 @@ main(int argc, char *argv[])
/* not reached */
case SHOW_SUM:
case SHOW_HOSTS:
+ case SHOW_RDRS:
case SHOW_RELAYS:
imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
printf("%-4s\t%-8s\t%-24s\t%-7s\tStatus\n",
@@ -207,6 +209,7 @@ main(int argc, char *argv[])
switch (res->action) {
case SHOW_SUM:
case SHOW_HOSTS:
+ case SHOW_RDRS:
case SHOW_RELAYS:
done = show_summary_msg(&imsg, res->action);
break;
@@ -310,12 +313,11 @@ show_summary_msg(struct imsg *imsg, int type)
struct table *table;
struct host *host;
struct relay *rlay;
- struct ctl_stats stats[RELAY_MAXPROC], crs;
- int i;
+ struct ctl_stats stats[RELAY_MAXPROC];
switch (imsg->hdr.type) {
case IMSG_CTL_RDR:
- if (type == SHOW_RELAYS)
+ if (type == SHOW_HOSTS || type == SHOW_RELAYS)
break;
rdr = imsg->data;
printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n",
@@ -323,7 +325,7 @@ show_summary_msg(struct imsg *imsg, int type)
print_rdr_status(rdr->conf.flags));
break;
case IMSG_CTL_TABLE:
- if (type == SHOW_RELAYS)
+ if (type == SHOW_RELAYS || type == SHOW_RDRS)
break;
table = imsg->data;
printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n",
@@ -331,7 +333,7 @@ show_summary_msg(struct imsg *imsg, int type)
print_table_status(table->up, table->conf.flags));
break;
case IMSG_CTL_HOST:
- if (type == SHOW_RELAYS)
+ if (type == SHOW_RELAYS || type == SHOW_RDRS)
break;
host = imsg->data;
printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n",
@@ -347,38 +349,25 @@ show_summary_msg(struct imsg *imsg, int type)
}
break;
case IMSG_CTL_RELAY:
- if (type == SHOW_HOSTS)
+ if (type == SHOW_HOSTS || type == SHOW_RDRS)
break;
rlay = imsg->data;
printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n",
rlay->conf.id, "relay", rlay->conf.name, "",
print_relay_status(rlay->conf.flags));
break;
- case IMSG_CTL_STATISTICS:
+ case IMSG_CTL_RDR_STATS:
+ if (type != SHOW_RDRS)
+ break;
+ bcopy(imsg->data, &stats[0], sizeof(stats[0]));
+ stats[1].id = EMPTY_ID;
+ print_statistics(stats);
+ break;
+ case IMSG_CTL_RELAY_STATS:
if (type != SHOW_RELAYS)
break;
bcopy(imsg->data, &stats, sizeof(stats));
- bzero(&crs, sizeof(crs));
- crs.interval = stats[0].interval;
- for (i = 0; stats[i].id != EMPTY_ID; i++) {
- crs.cnt += stats[i].cnt;
- crs.last += stats[i].last;
- crs.avg += stats[i].avg;
- crs.last_hour += stats[i].last_hour;
- crs.avg_hour += stats[i].avg_hour;
- crs.last_day += stats[i].last_day;
- crs.avg_day += stats[i].avg_day;
- }
- if (crs.cnt == 0)
- break;
- printf("\t%8s\ttotal: %lu sessions\n"
- "\t%8s\tlast: %lu/%us %lu/h %lu/d sessions\n"
- "\t%8s\taverage: %lu/%us %lu/h %lu/d sessions\n",
- "", crs.cnt,
- "", crs.last, crs.interval,
- crs.last_hour, crs.last_day,
- "", crs.avg, crs.interval,
- crs.avg_hour, crs.avg_day);
+ print_statistics(stats);
break;
case IMSG_CTL_END:
return (1);
@@ -497,3 +486,31 @@ print_relay_status(int flags)
return ("active");
}
+void
+print_statistics(struct ctl_stats stats[RELAY_MAXPROC + 1])
+{
+ struct ctl_stats crs;
+ int i;
+
+ bzero(&crs, sizeof(crs));
+ crs.interval = stats[0].interval;
+ for (i = 0; stats[i].id != EMPTY_ID; i++) {
+ crs.cnt += stats[i].cnt;
+ crs.last += stats[i].last;
+ crs.avg += stats[i].avg;
+ crs.last_hour += stats[i].last_hour;
+ crs.avg_hour += stats[i].avg_hour;
+ crs.last_day += stats[i].last_day;
+ crs.avg_day += stats[i].avg_day;
+ }
+ if (crs.cnt == 0)
+ return;
+ printf("\t%8s\ttotal: %llu sessions\n"
+ "\t%8s\tlast: %u/%us %u/h %u/d sessions\n"
+ "\t%8s\taverage: %u/%us %u/h %u/d sessions\n",
+ "", crs.cnt,
+ "", crs.last, crs.interval,
+ crs.last_hour, crs.last_day,
+ "", crs.avg, crs.interval,
+ crs.avg_hour, crs.avg_day);
+}
diff --git a/usr.sbin/relayd/pfe.c b/usr.sbin/relayd/pfe.c
index b4ae7386390..a8d1cf5c31a 100644
--- a/usr.sbin/relayd/pfe.c
+++ b/usr.sbin/relayd/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.45 2007/12/08 20:36:36 pyr Exp $ */
+/* $OpenBSD: pfe.c,v 1.46 2007/12/20 20:15:43 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -42,8 +42,8 @@ void pfe_disable_events(void);
void pfe_dispatch_imsg(int, short, void *);
void pfe_dispatch_parent(int, short, void *);
void pfe_dispatch_relay(int, short, void *);
-
void pfe_sync(void);
+void pfe_statistics(int, short, void *);
static struct relayd *env = NULL;
@@ -181,6 +181,7 @@ pfe_setup_events(void)
{
int i;
struct imsgbuf *ibuf;
+ struct timeval tv;
ibuf_hce->events = EV_READ;
event_set(&ibuf_hce->ev, ibuf_hce->fd, ibuf_hce->events,
@@ -195,6 +196,11 @@ pfe_setup_events(void)
ibuf->handler, ibuf);
event_add(&ibuf->ev, NULL);
}
+
+ /* Schedule statistics timer */
+ evtimer_set(&env->statev, pfe_statistics, NULL);
+ bcopy(&env->statinterval, &tv, sizeof(tv));
+ evtimer_add(&env->statev, &tv);
}
void
@@ -206,6 +212,8 @@ pfe_disable_events(void)
for (i = 0; i < env->prefork_relay; i++)
event_del(&ibuf_relay[i].ev);
+
+ event_del(&env->statev);
}
void
@@ -522,6 +530,9 @@ show(struct ctl_conn *c)
if (rdr->conf.flags & F_DISABLE)
continue;
+ imsg_compose(&c->ibuf, IMSG_CTL_RDR_STATS, 0, 0, -1,
+ &rdr->stats, sizeof(rdr->stats));
+
imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, -1,
rdr->table, sizeof(*rdr->table));
if (!(rdr->table->conf.flags & F_DISABLE))
@@ -545,7 +556,7 @@ relays:
rlay->stats[env->prefork_relay].id = EMPTY_ID;
imsg_compose(&c->ibuf, IMSG_CTL_RELAY, 0, 0, -1,
rlay, sizeof(*rlay));
- imsg_compose(&c->ibuf, IMSG_CTL_STATISTICS, 0, 0, -1,
+ imsg_compose(&c->ibuf, IMSG_CTL_RELAY_STATS, 0, 0, -1,
&rlay->stats, sizeof(rlay->stats));
if (rlay->dsttable == NULL)
@@ -908,3 +919,53 @@ pfe_sync(void)
&demote, sizeof(demote));
}
}
+
+void
+pfe_statistics(int fd, short events, void *arg)
+{
+ struct rdr *rdr;
+ struct ctl_stats *cur;
+ struct timeval tv, tv_now;
+ int resethour, resetday;
+ u_long cnt;
+
+ timerclear(&tv);
+ if (gettimeofday(&tv_now, NULL))
+ fatal("pfe_statistics: gettimeofday");
+
+ TAILQ_FOREACH(rdr, env->rdrs, entry) {
+ cnt = check_table(env, rdr, rdr->table);
+ if (rdr->conf.backup_id != EMPTY_TABLE)
+ cnt += check_table(env, rdr, rdr->backup);
+
+ resethour = resetday = 0;
+
+ cur = &rdr->stats;
+ cur->last = cnt > cur->cnt ? cnt - cur->cnt : 0;
+
+ cur->cnt = cnt;
+ cur->tick++;
+ cur->avg = (cur->last + cur->avg) / 2;
+ cur->last_hour += cur->last;
+ if ((cur->tick % (3600 / env->statinterval.tv_sec)) == 0) {
+ cur->avg_hour = (cur->last_hour + cur->avg_hour) / 2;
+ resethour++;
+ }
+ cur->last_day += cur->last;
+ if ((cur->tick % (86400 / env->statinterval.tv_sec)) == 0) {
+ cur->avg_day = (cur->last_day + cur->avg_day) / 2;
+ resethour++;
+ }
+ if (resethour)
+ cur->last_hour = 0;
+ if (resetday)
+ cur->last_day = 0;
+
+ rdr->stats.interval = env->statinterval.tv_sec;
+ }
+
+ /* Schedule statistics timer */
+ evtimer_set(&env->statev, pfe_statistics, NULL);
+ bcopy(&env->statinterval, &tv, sizeof(tv));
+ evtimer_add(&env->statev, &tv);
+}
diff --git a/usr.sbin/relayd/pfe_filter.c b/usr.sbin/relayd/pfe_filter.c
index 1d01f98bacd..64a0dd18c8e 100644
--- a/usr.sbin/relayd/pfe_filter.c
+++ b/usr.sbin/relayd/pfe_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe_filter.c,v 1.21 2007/12/08 20:36:36 pyr Exp $ */
+/* $OpenBSD: pfe_filter.c,v 1.22 2007/12/20 20:15:43 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -240,7 +240,9 @@ flush_table(struct relayd *env, struct rdr *rdr)
sizeof(io.pfrio_table.pfrt_name))
goto toolong;
if (ioctl(env->pf->dev, DIOCRCLRADDRS, &io) == -1)
- fatal("flush_table: cannot flush table");
+ fatal("flush_table: cannot flush table addresses");
+ if (ioctl(env->pf->dev, DIOCRCLRTSTATS, &io) == -1)
+ fatal("flush_table: cannot flush table stats");
log_debug("flush_table: flushed table %s", rdr->conf.name);
return;
@@ -476,3 +478,37 @@ natlook(struct relayd *env, struct ctl_natlook *cnl)
return (0);
}
+
+u_int64_t
+check_table(struct relayd *env, struct rdr *rdr, struct table *table)
+{
+ struct pfioc_table io;
+ struct pfr_tstats tstats;
+
+ if (table == NULL)
+ return (0);
+
+ bzero(&io, sizeof(io));
+ io.pfrio_esize = sizeof(struct pfr_tstats);
+ io.pfrio_size = 1;
+ io.pfrio_buffer = &tstats;
+ if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
+ sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
+ goto toolong;
+ if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
+ sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
+ goto toolong;
+ if (strlcpy(io.pfrio_table.pfrt_name, rdr->conf.name,
+ sizeof(io.pfrio_table.pfrt_name)) >=
+ sizeof(io.pfrio_table.pfrt_name))
+ goto toolong;
+
+ if (ioctl(env->pf->dev, DIOCRGETTSTATS, &io) == -1)
+ fatal("sync_table: cannot get table stats");
+
+ return (tstats.pfrts_match);
+
+ toolong:
+ fatal("check_table: name too long");
+ return (0);
+}
diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h
index 3791ff97eb1..671bb466264 100644
--- a/usr.sbin/relayd/relayd.h
+++ b/usr.sbin/relayd/relayd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.h,v 1.89 2007/12/08 20:36:36 pyr Exp $ */
+/* $OpenBSD: relayd.h,v 1.90 2007/12/20 20:15:43 reyk Exp $ */
/*
* Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -122,7 +122,8 @@ enum imsg_type {
IMSG_CTL_RELOAD,
IMSG_CTL_POLL,
IMSG_CTL_NOTIFY,
- IMSG_CTL_STATISTICS,
+ IMSG_CTL_RDR_STATS,
+ IMSG_CTL_RELAY_STATS,
IMSG_RDR_ENABLE, /* notifies from pfe to hce */
IMSG_RDR_DISABLE,
IMSG_TABLE_ENABLE,
@@ -271,14 +272,14 @@ struct ctl_stats {
int proc;
u_int interval;
- u_long cnt;
- u_long tick;
- u_long avg;
- u_long last;
- u_long avg_hour;
- u_long last_hour;
- u_long avg_day;
- u_long last_day;
+ u_int64_t cnt;
+ u_int32_t tick;
+ u_int32_t avg;
+ u_int32_t last;
+ u_int32_t avg_hour;
+ u_int32_t last_hour;
+ u_int32_t avg_day;
+ u_int32_t last_day;
};
struct address {
@@ -399,6 +400,7 @@ struct rdr {
struct addresslist virts;
struct table *table;
struct table *backup; /* use this if no host up */
+ struct ctl_stats stats;
};
TAILQ_HEAD(rdrlist, rdr);
@@ -729,6 +731,8 @@ void sync_table(struct relayd *, struct rdr *, struct table *);
void sync_ruleset(struct relayd *, struct rdr *, int);
void flush_rulesets(struct relayd *);
int natlook(struct relayd *, struct ctl_natlook *);
+u_int64_t
+ check_table(struct relayd *, struct rdr *, struct table *);
/* hce.c */
pid_t hce(struct relayd *, int [2], int [2], int [RELAY_MAXPROC][2],