aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@nxc.no>2018-02-02 14:50:53 +0100
committerSergey Poznyakoff <gray@nxc.no>2018-02-02 14:50:53 +0100
commit8a2e9da972cee4714c02f3dd23a3b7fcab9a0476 (patch)
treeee00ab302734161ec756313e8bbede8a82fb86eb /src
parent83919b99e222077a1bb61757403779cc4f456edc (diff)
downloadvarnish-mib-8a2e9da972cee4714c02f3dd23a3b7fcab9a0476.tar.gz
varnish-mib-8a2e9da972cee4714c02f3dd23a3b7fcab9a0476.tar.bz2
Bugfixes
Use consistend debug token names. Make sure configuration settings are honored by opening VSM and doing initial loading after the configuration has been read and processed. Avoid inifinite recursion in dict_load. * src/modconf.c: New file. * src/modconf.h: New file. * src/vclient.h: New file. * src/Makefile.am: Add new files. * src/VARNISH-MIB.txt: Minor changes in descriptions. * src/backend.h (backend_collect_addr): Change prototype. * src/ban.c: Remove configuration management functions. * src/betab.c: Likewise. * src/statdict.c (dict_lookup): Remove debugging kludge. (dict_load): Don't call backend_collect_addr. It is responsibility of the caller. * src/varnish_mib.mib2c: Rearrange includes. Open VSM after parsing configuration. (init_$modulename): Allow loading of one instance only. * src/vcli.c: Rewrite socket support.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/VARNISH-MIB.txt16
-rw-r--r--src/backend.h2
-rw-r--r--src/ban.c45
-rw-r--r--src/betab.c20
-rw-r--r--src/modconf.c123
-rw-r--r--src/modconf.h9
-rw-r--r--src/statdict.c4
-rw-r--r--src/varnish_mib.mib2c88
-rw-r--r--src/vcli.c228
-rw-r--r--src/vclient.h21
11 files changed, 357 insertions, 204 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3b5547b..3ef9fa5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,30 +14,33 @@
# You should have received a copy of the GNU General Public License
# along with varnish-mib. If not, see <http://www.gnu.org/licenses/>.
dlmoddir=@DLMODDIR@
dlmod_LTLIBRARIES = varnish-mib.la
varnish_mib_la_SOURCES = \
auth.c\
ban.c\
backend.h\
belex.l\
betab.c\
+ modconf.h\
+ modconf.c\
sha256.c\
sha256.h\
statdict.c\
varnish_mib.c\
varnish_mib.h\
- vcli.c
+ vcli.c\
+ vclient.h
BUILT_SOURCES = \
varnish_mib.c\
varnish_mib.h
varnish_mib.c varnish_mib.h: varnish_mib.mib2c VARNISH-MIB.txt
.mib2c.c:
MIBDIRS=${top_srcdir}/src:${NET_SNMP_MIBDIRS} MIBS="VARNISH-MIB:${NET_SNMP_MIBS}" \
mib2c -c $< -f $@ varnish
#NET_SNMP_INCLUDES = `$(NET_SNMP_CONFIG) --cflags`
diff --git a/src/VARNISH-MIB.txt b/src/VARNISH-MIB.txt
index 8d60477..6b03f21 100644
--- a/src/VARNISH-MIB.txt
+++ b/src/VARNISH-MIB.txt
@@ -11,32 +11,32 @@ VARNISH-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, enterprises, Counter64, TimeTicks,
Counter32, Integer32
FROM SNMPv2-SMI
TEXTUAL-CONVENTION, DateAndTime
FROM SNMPv2-TC
InetAddressIPv4, InetAddressIPv6, InetPortNumber
FROM INET-ADDRESS-MIB
OBJECT-GROUP, MODULE-COMPLIANCE
FROM SNMPv2-CONF;
varnishMIB MODULE-IDENTITY
- LAST-UPDATED "201802012132Z"
+ LAST-UPDATED "201802020845Z"
ORGANIZATION "Shared Autonomous sYstems"
CONTACT-INFO "Morten Hermanrud <mhe@say.no>
Sergey Poznyakoff <gray@gnu.org>
"
DESCRIPTION
"This MIB module defines objects for Varnish reverse web proxy."
- REVISION "201802012132Z"
+ REVISION "201802020845Z"
DESCRIPTION
"Second revision."
::= { varnish 0 }
varnish OBJECT IDENTIFIER ::= { enterprises 33043 6 1 }
client OBJECT IDENTIFIER ::= { varnish 1 }
backend OBJECT IDENTIFIER ::= { varnish 2 }
total OBJECT IDENTIFIER ::= { varnish 3 }
master OBJECT IDENTIFIER ::= { varnish 4 }
session OBJECT IDENTIFIER ::= { varnish 5 }
threads OBJECT IDENTIFIER ::= { varnish 6 }
bans OBJECT IDENTIFIER ::= { varnish 7 }
@@ -103,33 +103,35 @@ clientRequests400 OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Client requests received, subject to 400 errors."
::= { client 7 }
clientRequests411 OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
- "Client requests received, subject to 411 errors."
+ "Client requests received, subject to 411 errors.
+ This OID is not available in Varnish version 5 and above."
::= { client 8 }
clientRequests413 OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
- "Client requests received, subject to 413 errors."
+ "Client requests received, subject to 413 errors.
+ This OID is not available in Varnish version 5 and above."
::= { client 9 }
clientRequests417 OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Client requests received, subject to 417 errors."
::= { client 10 }
connections OBJECT IDENTIFIER ::= { backend 1 }
@@ -177,25 +179,26 @@ backendConnRecycled OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Backend connections recycles."
::= { connections 6 }
backendConnUnused OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
- "Backend connections unused."
+ "Backend connections unused.
+ This OID is not available in Varnish version 5 and above."
::= { connections 7 }
backendConnRetry OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Backend connections retried."
::= { connections 8 }
backendRequests OBJECT-TYPE
SYNTAX Counter64
@@ -903,25 +906,26 @@ vclDiscard OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of discarded VCLs."
::= { vcl 3 }
vclFail OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
- "Number of VCL failures"
+ "Number of VCL failures.
+ This OID is not available in Varnish 4 and below."
::= { vcl 4 }
--
-- Groups and Compliance
--
varnishConfs OBJECT IDENTIFIER ::= { varnish 100 }
varnishGroups OBJECT IDENTIFIER ::= { varnishConfs 1 }
varnishCompl OBJECT IDENTIFIER ::= { varnishConfs 2 }
--
-- Groups
--
diff --git a/src/backend.h b/src/backend.h
index 0c15e60..d60f613 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -2,15 +2,15 @@ typedef struct be_string {
char const *start;
size_t len;
} be_string_t;
typedef void (*regfun_t)(be_string_t *, be_string_t *, be_string_t *, void *);
void read_defs(const char *str, size_t len, regfun_t regfun, void *d);
void varnish_backend_table_timeout_parser(const char *token, char *line);
struct VSC_point;
void backend_register(char const *name, size_t len, char const *param,
const struct VSC_point *vpt);
void backend_clear(void);
-int backend_collect_addr(void);
+int backend_collect_addr(struct vsm *vsm);
void backend_parser(const char *str, size_t len, regfun_t regfun, void *d);
diff --git a/src/ban.c b/src/ban.c
index 0c354e9..1f4583b 100644
--- a/src/ban.c
+++ b/src/ban.c
@@ -42,71 +42,34 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
{
int rc;
struct vcli_conn conn;
size_t len = requests->requestvb->val_len;
char *expr = malloc(len + 1);
if (!expr) {
snmp_log(LOG_ERR, "out of memory\n");
return SNMP_ERR_GENERR;
}
memcpy(expr, requests->requestvb->val.string, len);
expr[len] = 0;
- DEBUGMSGTL(("varnish_ban", "setting ban %s\n", expr));
+ DEBUGMSGTL(("varnish_mib:ban", "setting ban %s\n", expr));
rc = vcli_connect(vsm, &conn);
if (rc == SNMP_ERR_NOERROR) {
rc = send_ban_cmd(&conn, expr);
vcli_disconnect(&conn);
}
free(expr);
return rc ? SNMP_ERR_GENERR : SNMP_ERR_NOERROR;
}
-unsigned banTable_timeout = 60;
-
-int
-varnish_mib_timeout_parser(const char *token, char *line, unsigned *retval)
-{
- char *p;
- unsigned long n = strtoul(line, &p, 10);
-
- if (*p) {
- if (isspace(*p)) {
- while (*p && isspace(*p))
- ++p;
- if (*p) {
- config_perror("too many arguments");
- return 1;
- }
- } else {
- config_perror("invalid timeout value");
- return 1;
- }
- }
-
- if (n > UINT_MAX) {
- config_perror("timeout value out of allowed range");
- return 1;
- }
-
- *retval = n;
- return 0;
-}
-
-void
-varnish_ban_table_timeout_parser(const char *token, char *line)
-{
- varnish_mib_timeout_parser(token, line, &banTable_timeout);
-}
-
/*
* 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;
@@ -147,25 +110,25 @@ 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 *vsm = varnish_get_vsm_data();
if (!vsm)
return SNMP_ERR_GENERR;
- DEBUGMSGTL(("varnish_ban", "reloading ban table\n"));
+ DEBUGMSGTL(("varnish_mib:ban", "reloading ban table\n"));
rc = vcli_connect(vsm, &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) {
@@ -257,31 +220,31 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
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\n", idx));
+ DEBUGMSGTL(("varnish_mib:ban", "loaded %ld ban entries\n", 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\n"));
+ DEBUGMSGTL(("varnish_mib:ban", "freeing ban table\n"));
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);
}
}
diff --git a/src/betab.c b/src/betab.c
index 388083b..afec48a 100644
--- a/src/betab.c
+++ b/src/betab.c
@@ -127,25 +127,25 @@ backend_register(char const *name, size_t len, char const *param,
dfn->vpt[i] = vpt;
break;
}
}
}
int
backendTable_load(netsnmp_cache *cache, void *vmagic)
{
netsnmp_tdata *table_data = (netsnmp_tdata *) vmagic;
struct backend_dfn *dfn;
- DEBUGMSGTL(("varnish_backend", "loading backend table\n"));
+ DEBUGMSGTL(("varnish_mib:backend", "loading backend table\n"));
VTAILQ_FOREACH(dfn, &backends, list) {
int i;
netsnmp_tdata_row *row;
struct backendTable_entry *ent;
ent = SNMP_MALLOC_TYPEDEF(struct backendTable_entry);
ent->vbeIndex = dfn->vbeIndex;
ent->vbeIdent = malloc(dfn->vbeIdent_len);
memcpy(ent->vbeIdent, dfn->vbeIdent, dfn->vbeIdent_len);
ent->vbeIdent_len = dfn->vbeIdent_len;
@@ -173,40 +173,32 @@ backendTable_load(netsnmp_cache *cache, void *vmagic)
sizeof(ent->vbeIndex));
netsnmp_tdata_add_row(table_data, row);
}
return 0;
}
void
backendTable_free(netsnmp_cache *cache, void *vmagic)
{
netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
netsnmp_tdata_row *row;
- DEBUGMSGTL(("varnish_backend", "freeing backend table\n"));
+ DEBUGMSGTL(("varnish_mib:backend", "freeing backend table\n"));
while ((row = netsnmp_tdata_row_first(table))) {
struct backendTable_entry *entry = row->data;
free(entry->vbeIdent);
SNMP_FREE(entry);
netsnmp_tdata_remove_and_delete_row(table, row);
}
}
-
-unsigned backendTable_timeout = 5;
-
-void
-varnish_backend_table_timeout_parser(const char *token, char *line)
-{
- varnish_mib_timeout_parser(token, line, &backendTable_timeout);
-}
static struct backend_dfn *
dfn_lookup(be_string_t *vclname, be_string_t *label)
{
size_t namelen;
struct backend_dfn *dfn;
namelen = vclname->len + label->len + 1;
VTAILQ_FOREACH(dfn, &backends, list) {
if (dfn->vbeIdent_len == namelen
&& memcmp(dfn->vbeIdent, vclname->start, vclname->len) == 0
&& dfn->vbeIdent[vclname->len] == '.'
@@ -325,37 +317,33 @@ backend_name_add(struct backend_name_list *namelist,
if (name->str.len == len
&& memcmp(name->str.start, str, len) == 0)
return;
}
name = SNMP_MALLOC_TYPEDEF(struct backend_name);
AN(name);
name->str.start = str;
name->str.len = len;
VTAILQ_INSERT_TAIL(namelist, name, list);
}
int
-backend_collect_addr(void)
+backend_collect_addr(struct vsm *vsm)
{
struct backend_dfn *dfn;
struct vcli_conn conn;
- struct vsm *vsm;
int rc;
struct backend_name_list namelist
= VTAILQ_HEAD_INITIALIZER(namelist);
- vsm = varnish_get_vsm_data();
- if (!vsm)
- return SNMP_ERR_GENERR;
- DEBUGMSGTL(("varnish_backend", "getting backend info\n"));
+ DEBUGMSGTL(("varnish_mib:backend", "getting backend info\n"));
rc = vcli_connect(vsm, &conn);
if (rc != SNMP_ERR_NOERROR)
return rc;
/* Select backend names */
VTAILQ_FOREACH(dfn, &backends, list) {
int i;
for (i = 0; i < dfn->vbeIdent_len; i++)
if (dfn->vbeIdent[i] == '.')
break;
if (i == dfn->vbeIdent_len)
diff --git a/src/modconf.c b/src/modconf.c
new file mode 100644
index 0000000..85b2582
--- /dev/null
+++ b/src/modconf.c
@@ -0,0 +1,123 @@
+#include "varnish_mib.h"
+#include <ctype.h>
+
+static int
+timeout_parser(const char *token, char *line, unsigned *retval)
+{
+ char *p;
+ unsigned long n = strtoul(line, &p, 10);
+
+ if (*p) {
+ if (isspace(*p)) {
+ while (*p && isspace(*p))
+ ++p;
+ if (*p) {
+ config_perror("too many arguments");
+ return 1;
+ }
+ } else {
+ config_perror("invalid timeout value");
+ return 1;
+ }
+ }
+
+ if (n > UINT_MAX) {
+ config_perror("timeout value out of allowed range");
+ return 1;
+ }
+
+ *retval = n;
+ return 0;
+}
+
+unsigned banTable_timeout = 60;
+unsigned vcli_timeout = 5;
+unsigned backendTable_timeout = 5;
+vcli_sockaddr_t vcli_sockaddr;
+char *vcli_secret;
+
+static void
+ban_table_timeout_parser(const char *token, char *line)
+{
+ timeout_parser(token, line, &banTable_timeout);
+}
+
+static void
+backend_table_timeout_parser(const char *token, char *line)
+{
+ timeout_parser(token, line, &backendTable_timeout);
+}
+
+static void
+vcli_timeout_parser(const char *token, char *line)
+{
+ timeout_parser(token, line, &vcli_timeout);
+}
+
+static void
+vcli_address_parser(const char *token, char *line)
+{
+ vcli_sockaddr = vcli_parse_sockaddr(line);
+}
+
+static void
+vcli_address_releaser(void)
+{
+ free(vcli_sockaddr);
+}
+
+static void
+vcli_secret_parser(const char *token, char *line)
+{
+ vcli_secret = strdup(line);
+}
+
+static void
+vcli_secret_releaser(void)
+{
+ free(vcli_secret);
+}
+
+struct varnish_mib_config
+{
+ char *token;
+ char *help;
+ void (*parser)(const char *token, char *line);
+ void (*releaser) (void);
+};
+
+static struct varnish_mib_config config[] = {
+ { "varnishBanTableTimeout",
+ "varnishBanTableTimeout SECONDS",
+ ban_table_timeout_parser },
+ { "varnishBackendTableTimeout",
+ "varnishBackendTableTimeout SECONDS",
+ backend_table_timeout_parser },
+ { "varnishCLIPortTimeout",
+ "varnishCLIPortTimeout SECONDS",
+ vcli_timeout_parser },
+ { "varnishCLISocket",
+ "varnishCLISocket ADDRESS[:PORT]",
+ vcli_address_parser,
+ vcli_address_releaser },
+ { "varnishCLISecretFile",
+ "varnishCLISecretFile FILE",
+ vcli_secret_parser,
+ vcli_secret_releaser },
+ { NULL }
+};
+
+void
+varnish_mib_config_init(void)
+{
+ struct varnish_mib_config *cp;
+ for (cp = config; cp->token; cp++) {
+ if (!register_config_handler("snmpd",
+ cp->token,
+ cp->parser,
+ cp->releaser,
+ cp->help))
+ snmp_log(LOG_ERR,"can't register %s config handler\n",
+ cp->token);
+ }
+}
diff --git a/src/modconf.h b/src/modconf.h
new file mode 100644
index 0000000..0a7d8fc
--- /dev/null
+++ b/src/modconf.h
@@ -0,0 +1,9 @@
+extern unsigned banTable_timeout;
+extern unsigned vcli_timeout;
+extern unsigned backendTable_timeout;
+extern vcli_sockaddr_t vcli_sockaddr;
+extern char *vcli_secret;
+
+void varnish_mib_config_init(void);
+
+
diff --git a/src/statdict.c b/src/statdict.c
index e87123b..69b442f 100644
--- a/src/statdict.c
+++ b/src/statdict.c
@@ -104,27 +104,24 @@ lookup(const char *name, int install)
return &dict[i];
rehash();
return lookup(name, install);
}
int
dict_lookup(char const *key, uint64_t *val)
{
struct VSC_point **ent;
ent = lookup(key, 0);
- if (!ent) {
- fprintf(stderr, "%s NOT FOUND\n", key);
- }
if (!ent)
return -1;
*val = *(uint64_t*)(*ent)->ptr;
return 0;
}
void
dict_clear(void)
{
if (dict) {
size_t i;
for (i = 0; i < hash_size[hash_num]; i++)
@@ -159,14 +156,13 @@ load_cb(void *priv, const struct VSC_point *vpt)
}
}
return 0;
}
void
dict_load(struct vsc *vsc)
{
struct vsm_fantom fantom = VSM_FANTOM_NULL;
dict_clear();
backend_clear();
VSC_Iter(vsc, &fantom, load_cb, NULL);
- backend_collect_addr();
}
diff --git a/src/varnish_mib.mib2c b/src/varnish_mib.mib2c
index 6915689..404f511 100644
--- a/src/varnish_mib.mib2c
+++ b/src/varnish_mib.mib2c
@@ -26,36 +26,36 @@
@startperl@
$vars{'varnish_translate_table'} = {
uptime => [ 'DICT', 'MAIN.uptime' ],
clientAcceptedConnections => [ 'DICT', 'MAIN.sess_conn' ],
clientCacheHits => [ 'DICT', 'MAIN.cache_hit' ],
clientCacheHitsPass => [ 'DICT', 'MAIN.cache_hitpass' ],
clientCacheMisses => [ 'DICT', 'MAIN.cache_miss' ],
clientBan => [ 'STRING', '',
{ varnish_set_action => 'varnish_ban' } ],
clientRequestsReceived => [ 'DICT', 'MAIN.client_req' ],
clientRequests400 => [ 'DICT', 'MAIN.client_req_400' ],
- clientRequests411 => [ 'NULL', 'MAIN.client_req_411' ],
- clientRequests413 => [ 'NULL', 'MAIN.client_req_413' ],
+ clientRequests411 => [ 'NULL' ],
+ clientRequests413 => [ 'NULL' ],
clientRequests417 => [ 'DICT', 'MAIN.client_req_417' ],
backendConnSuccess => [ 'DICT', 'MAIN.backend_conn' ],
backendConnNotAttempted => [ 'DICT', 'MAIN.backend_unhealthy' ],
backendConnToMany => [ 'DICT', 'MAIN.backend_busy' ],
backendConnFailures => [ 'DICT', 'MAIN.backend_fail' ],
backendConnReuses => [ 'DICT', 'MAIN.backend_reuse' ],
backendConnRecycled => [ 'DICT', 'MAIN.backend_recycle' ],
- backendConnUnused => [ 'NULL', 'MAIN.backend_toolate' ],
+ backendConnUnused => [ 'NULL' ],
backendConnRetry => [ 'DICT', 'MAIN.backend_retry' ],
backendRequests => [ 'DICT', 'MAIN.backend_req' ],
totalSessions => [ 'DICT', 'MAIN.s_sess' ],
totalRequests => [ 'DICT', 'MAIN.client_req' ],
totalPipe => [ 'DICT', 'MAIN.s_pipe' ],
totalPass => [ 'DICT', 'MAIN.s_pass' ],
totalFetch => [ 'DICT', 'MAIN.s_fetch' ],
totalRequestHeaderBytes => [ 'DICT', 'MAIN.s_req_hdrbytes' ],
totalRequestBodyBytes => [ 'DICT', 'MAIN.s_req_bodybytes' ],
totalResponseHeaderBytes => [ 'DICT', 'MAIN.s_resp_hdrbytes' ],
totalResponseBodyBytes => [ 'DICT', 'MAIN.s_resp_bodybytes' ],
@@ -152,104 +152,106 @@ $vars{'modulename'} =~ s#.*/##;
$vars{'modulename'} =~ s/\.c$//;
#print "$vars{'modulename'}\n";
0;
@endperl@
@open ${modulename}.h@
/* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */
#include <config.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
+#include <errno.h>
#include <vapi/vsc.h>
#include <vapi/vsm.h>
#include <vcli.h>
+#include <vas.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
-typedef struct vcli_conn {
- int fd;
- char *secret;
- int resp;
- char *base;
- size_t bufmax;
- size_t bufsize;
-} vcli_conn_t;
-
-int vcli_write(vcli_conn_t *conn);
-int vcli_read_response(vcli_conn_t *conn);
-int vcli_vasprintf(vcli_conn_t *conn, const char *fmt, va_list ap);
-int vcli_asprintf(vcli_conn_t *conn, const char *fmt, ...);
-void vcli_disconnect(vcli_conn_t *conn);
-int vcli_connect(struct vsm *vsm, vcli_conn_t *conn);
+#include "vclient.h"
+#include "modconf.h"
struct vsm *varnish_get_vsm_data(void);
int varnish_auth_response(const char *file, const char *challenge,
char response[CLI_AUTH_RESPONSE_LEN + 1]);
int varnish_ban(netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests,
struct vsm *vsm);
-int varnish_mib_timeout_parser(const char *token, char *line,
- unsigned *retval);
-
-void varnish_ban_table_timeout_parser(const char *token, char *line);
-void varnish_vcli_timeout_parser(const char *token, char *line);
-
int dict_lookup(char const *key, uint64_t *val);
void dict_install(struct VSC_point const *pt);
void dict_load(struct vsc *vsc);
@open ${name}@
/* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */
#include "varnish_mib.h"
#include "backend.h"
static struct vsm *vd;
static struct vsc *vsc;
-void
-varnish_snmp_init(void)
+int
+post_config(int majorID, int minorID, void *serverarg, void *clientarg)
{
vd = VSM_New();
- if (vd) {
- vsc = VSC_New(vd);
- if (vsc) {
- if (VSM_Attach(vd, 2))
- fprintf(stderr, "%s\n", VSM_Error(vd));
- }
+ if (!vd) {
+ snmp_log(LOG_ERR, "VSM_New: %s\n", strerror(errno));
+ return 1;
+ }
+
+ vsc = VSC_New(vd);
+ if (!vsc) {
+ snmp_log(LOG_ERR, "VSC_New: %s\n", strerror(errno));
+ return 1;
}
+
+ if (VSM_Attach(vd, 2))
+ snmp_log(LOG_ERR, "%s\n", VSM_Error(vd));
+
dict_load(vsc);
+ backend_collect_addr(vd);
+ return 0;
+}
+
+void
+varnish_snmp_init(void)
+{
+ snmp_register_callback(SNMP_CALLBACK_LIBRARY,
+ SNMP_CALLBACK_POST_READ_CONFIG,
+ post_config,
+ NULL);
}
void
varnish_snmp_deinit(void)
{
/* FIXME? */
}
struct vsm *
-varnish_get_vsm_data()
+varnish_get_vsm_data(void)
{
if (vd) {
if (VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED)) {
DEBUGMSGTL(("$modulename", "reopening vd\n"));
dict_load(vsc);
+ backend_collect_addr(vd);
}
}
return vd;
}
/* Variable handlers.
An instance handler only hands us one request at a time, unwrapping
any eventual GETNEXT requests.
*/
@foreach $i scalar@
@@ -579,52 +581,42 @@ initialize_table_$i(void)
/*
netsnmp_inject_handler_before(reg, netsnmp_cache_handler_get(cache),
TABLE_TDATA_NAME);
*/
}
@end@
/** Initializes the $name module */
void
init_$modulename(void)
{
+ if (vd) {
+ snmp_log(LOG_ERR, "%s: can't be loaded twice\n", "$modulename");
+ abort();
+ }
@foreach $i scalar@
@startperl@
&{$vars{'varnish_translate'}}($vars{'i'});
@endperl@
@if $varnish_type ne 'NULL'@
$varnish_if
const oid ${i}_oid[] = { $i.commaoid };
$varnish_endif
@end@
@end@
DEBUGMSGTL(("$modulename", "Initializing\n"));
- if (!register_config_handler("snmpd", "varnishBanTableTimeout",
- varnish_ban_table_timeout_parser,
- NULL,
- "varnishBanTableTimeout SECONDS"))
- snmp_log(LOG_ERR,"can't register config handler\n");
- if (!register_config_handler("snmpd", "varnishBackendTableTimeout",
- varnish_backend_table_timeout_parser,
- NULL,
- "varnishBackendTableTimeout SECONDS"))
- snmp_log(LOG_ERR,"can't register config handler\n");
- if (!register_config_handler("snmpd", "varnishCLIPortTimeout",
- varnish_vcli_timeout_parser,
- NULL,
- "varnishCLIPortTimeout SECONDS"))
- snmp_log(LOG_ERR,"can't register config handler\n");
+ varnish_mib_config_init();
@foreach $i scalar@
@startperl@
&{$vars{'varnish_translate'}}($vars{'i'});
@endperl@
@if $varnish_type ne 'NULL'@
$varnish_if
netsnmp_register_scalar(
netsnmp_create_handler_registration("$i", handle_$i,
${i}_oid, OID_LENGTH(${i}_oid),
@if !$i.settable@
HANDLER_CAN_RONLY
diff --git a/src/vcli.c b/src/vcli.c
index 499c365..2683c9d 100644
--- a/src/vcli.c
+++ b/src/vcli.c
@@ -16,32 +16,85 @@
*/
#include "varnish_mib.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
+struct vcli_sockaddr {
+ socklen_t len;
+ struct sockaddr addr[1];
+};
+
#define ISSPACE(c) ((c)==' '||(c)=='\t'||(c)=='\n')
-static unsigned vcli_timeout = 5;
+vcli_sockaddr_t
+vcli_parse_sockaddr(char const *arg)
+{
+ char *node;
+ size_t n;
+ int rc;
+ struct addrinfo *res;
+ char const *p;
+ vcli_sockaddr_t sa;
+
+ n = strcspn(arg, ": \t");
+ node = malloc(n + 1);
+ if (!node) {
+ snmp_log(LOG_ERR, "out of memory\n");
+ return NULL;
+ }
-void
-varnish_vcli_timeout_parser(const char *token, char *line)
+ memcpy(node, arg, n);
+ node[n] = 0;
+ p = arg + n;
+ if (*p == ':')
+ p++;
+ else
+ while (*p && ISSPACE(*p))
+ p++;
+
+ if (!p)
+ p = "6082";
+
+ rc = getaddrinfo(node, p, NULL, &res);
+ free(node);
+ if (rc) {
+ snmp_log(LOG_ERR, "can't resolve %s\n", arg);
+ return NULL;
+ }
+
+ sa = malloc(sizeof(*sa) - sizeof(sa->addr) + res->ai_addrlen);
+ if (!sa) {
+ snmp_log(LOG_ERR, "out of memory\n");
+ return NULL;
+ }
+ sa->len = res->ai_addrlen;
+ memcpy(sa->addr, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ return sa;
+}
+
+vcli_sockaddr_t
+vcli_sockaddr_dup(vcli_sockaddr_t src)
{
- varnish_mib_timeout_parser(token, line, &vcli_timeout);
+ vcli_sockaddr_t dst;
+ dst = malloc(sizeof(*dst) - sizeof(dst->addr) + src->len);
+ memcpy(dst, src, src->len);
+ return dst;
}
#define VCLI_INIT_ALLOC 16
static int
vcli_alloc(struct vcli_conn *conn, size_t size)
{
char *p;
if (size < conn->bufmax)
return 0;
p = realloc(conn->base, size);
@@ -137,25 +190,25 @@ vcli_read(struct vcli_conn *conn, size_t size)
snmp_log(LOG_ERR, "read: %s\n",
strerror(errno));
ret = -1;
break;
}
}
}
if (ret == 0) {
if (conn->bufsize == 0)
ret = -1;
conn->base[conn->bufsize] = 0;
- DEBUGMSGTL(("varnish_mib:vcli", "<<varnish: %s\n", conn->base));
+ DEBUGMSGTL(("transcript:varnish_mib", "<<varnish: %s\n", conn->base));
}
return ret;
}
static int
vcli_getline(struct vcli_conn *conn)
{
fd_set rd;
time_t start;
struct timeval tv;
long ttl;
@@ -220,25 +273,25 @@ vcli_getline(struct vcli_conn *conn)
}
conn->base[conn->bufsize] = 0;
}
return ret;
}
int
vcli_write(struct vcli_conn *conn)
{
size_t size;
- DEBUGMSGTL(("varnish_mib:vcli", ">>varnish: %s\n", conn->base));
+ DEBUGMSGTL(("transcript:varnish_mib", ">>varnish: %s\n", conn->base));
for (size = 0; size < conn->bufsize; ) {
int n = write(conn->fd, conn->base + size,
conn->bufsize - size);
if (n < 0) {
snmp_log(LOG_ERR, "write error: %s\n",
strerror(errno));
return -1;
}
size += n;
}
return 0;
}
@@ -307,68 +360,78 @@ vcli_vasprintf(struct vcli_conn *conn, const char *fmt, va_list ap)
int
vcli_asprintf(struct vcli_conn *conn, const char *fmt, ...)
{
int rc;
va_list ap;
va_start(ap, fmt);
rc = vcli_vasprintf(conn, fmt, ap);
va_end(ap);
return rc;
}
-
-
+
static int
-open_socket(struct sockaddr_in *sa, const char *connstr)
+open_socket(vcli_sockaddr_t sa)
{
- int fd = socket(sa->sin_family, SOCK_STREAM, 0);
+ int fd;
struct timeval start, connect_tv;
-
+
+ fd = socket(sa->addr->sa_family, SOCK_STREAM, 0);
if (fd == -1) {
snmp_log(LOG_ERR, "socket: %s\n", strerror(errno));
return -1;
}
connect_tv.tv_sec = vcli_timeout;
connect_tv.tv_usec = 0;
gettimeofday(&start, NULL);
for (;;) {
- int rc = connect(fd, sa, sizeof(*sa));
+ int rc = connect(fd, sa->addr, sa->len);
if (rc == 0)
break;
else if (errno == ECONNREFUSED) {
struct timeval tv, now;
fd_set rset, wset, xset;
gettimeofday(&now, NULL);
timersub(&now, &start, &tv);
if (timercmp(&tv, &connect_tv, < )) {
FD_ZERO(&rset);
FD_SET(fd, &rset);
FD_ZERO(&wset);
FD_SET(fd, &wset);
FD_ZERO(&xset);
FD_SET(fd, &xset);
select(fd + 1, &rset, &wset, &xset, &tv);
continue;
}
+ } else {
+ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
+ int ec = errno;
+ if (getnameinfo(sa->addr, sa->len,
+ hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+ NI_NUMERICHOST | NI_NUMERICSERV) == 0)
+ snmp_log(LOG_ERR,
+ "cannot connect to %s:%s: %s\n",
+ hbuf, sbuf, strerror(ec));
+ else
+ snmp_log(LOG_ERR,
+ "cannot connect to varnish: %s\n",
+ strerror(ec));
+ close(fd);
+ return -1;
}
-
- snmp_log(LOG_ERR, "cannot connect to %s: %s\n",
- connstr, strerror(errno));
- close(fd);
- return -1;
}
return fd;
}
<