diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-12-20 20:15:44 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-12-20 20:15:44 +0000 |
commit | c678804f02763fbba27fd8cdb0f410f0a5b91b33 (patch) | |
tree | a202eab03d6f64e3524fc93df37769c0e078fbb3 | |
parent | ec7125ff6c5791611f3d901b4bd4d291bf45e23c (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.c | 3 | ||||
-rw-r--r-- | usr.sbin/relayctl/parser.h | 3 | ||||
-rw-r--r-- | usr.sbin/relayctl/relayctl.8 | 10 | ||||
-rw-r--r-- | usr.sbin/relayctl/relayctl.c | 75 | ||||
-rw-r--r-- | usr.sbin/relayd/pfe.c | 67 | ||||
-rw-r--r-- | usr.sbin/relayd/pfe_filter.c | 40 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 24 |
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], |