summaryrefslogtreecommitdiff
path: root/usr.sbin
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 /usr.sbin
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@
Diffstat (limited to 'usr.sbin')
-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],