diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-11-26 07:34:42 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-11-26 07:59:50 +0200 |
commit | 50813ca9aa276c72e6f766a5ecd23c1170273528 (patch) | |
tree | 61a3246051156b10f14f35481368ba589b8b5b4f /src/ban.c | |
parent | 2301256beda8480560c6e8053dc209989c8afeb8 (diff) | |
download | varnish-mib-50813ca9aa276c72e6f766a5ecd23c1170273528.tar.gz varnish-mib-50813ca9aa276c72e6f766a5ecd23c1170273528.tar.bz2 |
Implement table of bans
* src/varnish_mib.h: Removed; from now on it is generated
from varnish_mib.mib2c in pair with varnish_mib.c
* src/.gitignore: Add varnish_mib.h
* src/Makefile.am: Change rules accordingly.
* src/VARNISH-MIB.txt: Define table of bans.
* src/ban.c: Implement table of bans.
* src/varnish_mib.mib2c: Implement table support.
Diffstat (limited to 'src/ban.c')
-rw-r--r-- | src/ban.c | 189 |
1 files changed, 188 insertions, 1 deletions
@@ -18,2 +18,3 @@ #include "varnish_mib.h" +#include <ctype.h> @@ -52,3 +53,3 @@ varnish_ban(netsnmp_agent_request_info *reqinfo, expr[len] = 0; - DEBUGMSGTL(("vcli_mib", "ban %s\n", expr)); + DEBUGMSGTL(("varnish_ban", "setting ban %s\n", expr)); rc = vcli_connect(vd, &conn); @@ -62 +63,187 @@ varnish_ban(netsnmp_agent_request_info *reqinfo, +unsigned banTable_timeout = 60; + +/* + * create a new row in the table + */ +static struct banTable_entry * +create_entry(netsnmp_tdata *table_data, long idx, struct banTable_entry *ent) +{ + struct banTable_entry *entry; + netsnmp_tdata_row *row; + + entry = SNMP_MALLOC_TYPEDEF(struct banTable_entry); + if (!entry) + return NULL; + + row = netsnmp_tdata_create_row(); + if (!row) { + SNMP_FREE(entry); + return NULL; + } + row->data = entry; + *entry = *ent; + + entry->banIndex = idx; + netsnmp_tdata_row_add_index(row, ASN_INTEGER, + &entry->banIndex, + sizeof(entry->banIndex)); + if (table_data) + netsnmp_tdata_add_row(table_data, row); + return entry; +} + +#define TMSEC(t) (((t)->tm_hour * 60 + (t)->tm_min) * 60 + (t)->tm_sec) + +static int +utc_offset (void) +{ + time_t t = time (NULL); + struct tm ltm = *localtime (&t); + struct tm gtm = *gmtime (&t); + int d = TMSEC (<m) - TMSEC (>m); + if (!(ltm.tm_year = gtm.tm_year && ltm.tm_mon == gtm.tm_mon)) + d += 86400; + return d / 60; +} + +/* Refill the ban table */ +int +banTable_load(netsnmp_cache *cache, void *vmagic) +{ + netsnmp_tdata *table = (netsnmp_tdata *) vmagic; + long idx = 0; + int rc; + struct vcli_conn conn; + char *p; + struct VSM_data *vd; + + DEBUGMSGTL(("varnish_ban", "reloading ban table")); + vd = varnish_get_vsm_data(); + rc = vcli_connect(vd, &conn); + if (rc != SNMP_ERR_NOERROR) + return rc; + + if (vcli_asprintf(&conn, "ban.list\n") || vcli_write(&conn)) + return SNMP_ERR_GENERR; + + if (vcli_read_response(&conn)) + return SNMP_ERR_GENERR; + + if (conn.resp != CLIS_OK) { + snmp_log(LOG_ERR, "ban.list command rejected: %u %s\n", + conn.resp, conn.base); + return SNMP_ERR_GENERR; + } + + p = conn.base; + while (p < conn.base + conn.bufsize) { + char *q; + struct banTable_entry e; + struct tm *tm; + time_t t; + int n; + + if (*p == '\n') { + ++p; + continue; + } + e.banIndex = idx; + t = strtoul(p, &q, 10); + if (*q != '.') { + p = strchr(p, '\n'); + if (!p) + break; + continue; + } + ++q; + + e.banTime_len = 11; + e.banTime = malloc(e.banTime_len + 1); + if (!e.banTime) { + vcli_disconnect(&conn); + snmp_log(LOG_ERR, "out of memory\n"); + return SNMP_ERR_GENERR; + } + tm = localtime(&t); + /* A date-time specification. + + field octets contents range + ----- ------ -------- ----- + 1 1-2 year* 0..65536 + 2 3 month 1..12 + 3 4 day 1..31 + 4 5 hour 0..23 + 5 6 minutes 0..59 + 6 7 seconds 0..60 + (use 60 for leap-second) + 7 8 deci-seconds 0..9 + 8 9 direction from UTC '+' / '-' + 9 10 hours from UTC* 0..13 + 10 11 minutes from UTC 0..59 + + * Notes: + - the value of year is in network-byte order + */ + n = tm->tm_year % 100; + e.banTime[0] = n >> 8; + e.banTime[1] = n & 0xff; + e.banTime[2] = tm->tm_mon + 1; + e.banTime[3] = tm->tm_mday; + e.banTime[4] = tm->tm_hour; + e.banTime[5] = tm->tm_min; + e.banTime[6] = tm->tm_sec; + e.banTime[7] = *q - '0'; + n = utc_offset(); + if (n < 0) { + e.banTime[8] = '-'; + n = - n; + } else + e.banTime[8] = '+'; + e.banTime[9] = n / 60; + e.banTime[10] = n % 60; + + while (*q && isdigit(*q)) + ++q; + while (*q && isspace(*q)) + ++q; + e.banRefCount = strtoul(q, &q, 10); + + while (*q && isspace(*q)) + ++q; + + e.banExpression_len = strcspn(q, "\n"); + e.banExpression = malloc(e.banExpression_len); + if (!e.banExpression) { + vcli_disconnect(&conn); + free(e.banTime); + snmp_log(LOG_ERR, "out of memory\n"); + return SNMP_ERR_GENERR; + } + memcpy(e.banExpression, q, e.banExpression_len); + + create_entry(table, idx, &e); + ++idx; + q += e.banExpression_len; + p = q; + } + vcli_disconnect(&conn); + DEBUGMSGTL(("varnish_ban", "loaded %ld ban entries", idx)); + return 0; +} + +void +banTable_free(netsnmp_cache *cache, void *vmagic) +{ + netsnmp_tdata *table = (netsnmp_tdata *) vmagic; + netsnmp_tdata_row *row; + + DEBUGMSGTL(("varnish_ban", "freeing ban table")); + while ((row = netsnmp_tdata_row_first(table))) { + struct banTable_entry *entry = row->data; + free(entry->banExpression); + free(entry->banTime); + SNMP_FREE(entry); + netsnmp_tdata_remove_and_delete_row(table, row); + } +} |