From 3a3d66b6f490a0b5e972b6208935d34a2a7b632e Mon Sep 17 00:00:00 2001 From: Bron Gondwana Date: Sat, 31 Jan 2009 16:04:19 +1100 Subject: [PATCH] traffic count Add traffic counters in prot_read/prot_write to allow accurate byte counts to be logged per session. --- imap/imapd.c | 15 ++++++++++++--- imap/pop3d.c | 15 ++++++++++++++- lib/prot.c | 12 ++++++++++++ lib/prot.h | 15 ++++++++++++--- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/imap/imapd.c b/imap/imapd.c index e291cb3..4f2b430 100644 --- a/imap/imapd.c +++ b/imap/imapd.c @@ -521,6 +521,8 @@ int mlookup(const char *tag, const char *ext_name, static void imapd_reset(void) { int i; + int bytes_in = 0; + int bytes_out = 0; proc_cleanup(); @@ -551,16 +553,18 @@ static void imapd_reset(void) /* Flush the incoming buffer */ prot_NONBLOCK(imapd_in); prot_fill(imapd_in); - + bytes_in = prot_bytes_in(imapd_in); prot_free(imapd_in); } if (imapd_out) { /* Flush the outgoing buffer */ prot_flush(imapd_out); - + bytes_out = prot_bytes_out(imapd_out); prot_free(imapd_out); } + + syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); imapd_in = imapd_out = NULL; @@ -856,6 +860,8 @@ void shut_down(int code) __attribute__((noreturn)); void shut_down(int code) { int i; + int bytes_in = 0; + int bytes_out = 0; proc_cleanup(); @@ -894,19 +900,22 @@ void shut_down(int code) /* Flush the incoming buffer */ prot_NONBLOCK(imapd_in); prot_fill(imapd_in); - + bytes_in = prot_bytes_in(imapd_in); prot_free(imapd_in); } if (imapd_out) { /* Flush the outgoing buffer */ prot_flush(imapd_out); + bytes_out = prot_bytes_out(imapd_out); prot_free(imapd_out); /* one less active connection */ snmp_increment(ACTIVE_CONNECTIONS, -1); } + syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); + if (protin) protgroup_free(protin); #ifdef HAVE_SSL diff --git a/imap/pop3d.c b/imap/pop3d.c index c597c03..ed5008e 100644 --- a/imap/pop3d.c +++ b/imap/pop3d.c @@ -317,6 +317,9 @@ static struct sasl_callback mysasl_cb[] = { static void popd_reset(void) { + int bytes_in = 0; + int bytes_out = 0; + proc_cleanup(); syslog(LOG_NOTICE, "counts: retr=<%d> top=<%d> dele=<%d>", @@ -341,14 +344,17 @@ static void popd_reset(void) if (popd_in) { prot_NONBLOCK(popd_in); prot_fill(popd_in); - + bytes_in = prot_bytes_in(popd_in); prot_free(popd_in); } if (popd_out) { prot_flush(popd_out); + bytes_out = prot_bytes_out(popd_out); prot_free(popd_out); } + + syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); popd_in = popd_out = NULL; @@ -604,6 +610,9 @@ void usage(void) */ void shut_down(int code) { + int bytes_in = 0; + int bytes_out = 0; + proc_cleanup(); /* close local mailbox */ @@ -633,14 +642,18 @@ void shut_down(int code) if (popd_in) { prot_NONBLOCK(popd_in); prot_fill(popd_in); + bytes_in = prot_bytes_in(popd_in); prot_free(popd_in); } if (popd_out) { prot_flush(popd_out); + bytes_out = prot_bytes_out(popd_out); prot_free(popd_out); } + syslog(LOG_NOTICE, "traffic: in=%d out=%d", bytes_in, bytes_out); + #ifdef HAVE_SSL tls_shutdown_serverengine(); #endif diff --git a/lib/prot.c b/lib/prot.c index 6eb285d..c31c725 100644 --- a/lib/prot.c +++ b/lib/prot.c @@ -103,6 +103,9 @@ int write; if(write) newstream->cnt = PROT_BUFSIZE; + newstream->bytes_in = 0; + newstream->bytes_out = 0; + return newstream; } @@ -488,6 +491,7 @@ int prot_rewind(struct protstream *s) s->cnt = 0; s->error = 0; s->eof = 0; + s->bytes_in = 0; return 0; } @@ -698,6 +702,7 @@ int prot_fill(struct protstream *s) } s->cnt--; /* we return the first char */ + s->bytes_in++; return *s->ptr++; } } while (1); @@ -1097,6 +1102,7 @@ int prot_write(struct protstream *s, const char *buf, unsigned len) memcpy(s->ptr, buf, len); s->ptr += len; s->cnt -= len; + s->bytes_out += len; if (s->error || s->eof) return EOF; assert(s->cnt > 0); @@ -1223,6 +1229,7 @@ int prot_read(struct protstream *s, char *buf, unsigned size) memcpy(buf, s->ptr, size); s->ptr += size; s->cnt -= size; + s->bytes_in += size; return size; } @@ -1233,6 +1240,7 @@ int prot_read(struct protstream *s, char *buf, unsigned size) memcpy(buf+1, s->ptr, size); s->ptr += size; s->cnt -= size; + s->bytes_in += size; /* prot_fill added the 1 already */ return size+1; } @@ -1414,6 +1422,7 @@ char *prot_fgets(char *buf, unsigned size, struct protstream *s) while (size && (c = prot_getc(s)) != EOF) { size--; *p++ = c; + s->bytes_in++; if (c == '\n') break; } if (p == buf) return 0; @@ -1530,6 +1539,7 @@ int prot_getc(struct protstream *s) if (s->cnt > 0) { --s->cnt; + s->bytes_in++; return *(s->ptr)++; } else { return prot_fill(s); @@ -1541,6 +1551,7 @@ int prot_ungetc(int c, struct protstream *s) assert(!s->write); s->cnt++; + s->bytes_in--; *--(s->ptr) = c; return c; @@ -1552,6 +1563,7 @@ int prot_putc(int c, struct protstream *s) assert(s->cnt > 0); *s->ptr++ = c; + s->bytes_out++; if (--s->cnt == 0) { return prot_flush_internal(s,0); } else { diff --git a/lib/prot.h b/lib/prot.h index 3b8ad75..17109f3 100644 --- a/lib/prot.h +++ b/lib/prot.h @@ -121,6 +121,9 @@ struct protstream { time_t timeout_mark; struct protstream *flushonread; + int bytes_in; + int bytes_out; + /* Events */ prot_readcallback_t *readcallback_proc; void *readcallback_rock; @@ -152,9 +155,9 @@ extern int prot_getc(struct protstream *s); extern int prot_ungetc(int c, struct protstream *s); extern int prot_putc(int c, struct protstream *s); -#define prot_getc(s) ((s)->cnt > 0 ? (--(s)->cnt, (int)*(s)->ptr++) : prot_fill(s)) -#define prot_ungetc(c, s) ((s)->cnt++, (*--(s)->ptr = (c))) -#define prot_putc(c, s) ((*(s)->ptr++ = (c)), --(s)->cnt == 0 ? prot_flush_internal(s,0) : 0) +#define prot_getc(s) ((s)->cnt > 0 ? (--(s)->cnt, ++(s)->bytes_in, (int)*(s)->ptr++) : prot_fill(s)) +#define prot_ungetc(c, s) ((s)->cnt++, --(s)->bytes_in, (*--(s)->ptr = (c))) +#define prot_putc(c, s) ((*(s)->ptr++ = (c)), ++(s)->bytes_out, --(s)->cnt == 0 ? prot_flush_internal(s,0) : 0) /* The following two macros control the blocking nature of * the protstream. @@ -184,6 +187,12 @@ extern int prot_free(struct protstream *s); /* Set the telemetry logfile for a given protstream */ extern int prot_setlog(struct protstream *s, int fd); +/* Get traffic counts */ +extern int prot_bytes_in(struct protstream *s); +extern int prot_bytes_out(struct protstream *s); +#define prot_bytes_in(s) ((s)->bytes_in) +#define prot_bytes_out(s) ((s)->bytes_out) + /* Set the SASL options for a protstream (requires authentication to * be complete for the given sasl_conn_t */ extern int prot_setsasl(struct protstream *s, sasl_conn_t *conn); -- 1.5.6.5