summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@nxc.no>2018-02-02 13:50:53 (GMT)
committer Sergey Poznyakoff <gray@nxc.no>2018-02-02 13:50:53 (GMT)
commit8a2e9da972cee4714c02f3dd23a3b7fcab9a0476 (patch) (side-by-side diff)
treeee00ab302734161ec756313e8bbede8a82fb86eb
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 (more/less context) (ignore whitespace changes)
-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
@@ -23,12 +23,15 @@ varnish_mib_la_SOURCES = \
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\
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
@@ -20,14 +20,14 @@ IMPORTS
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 }
@@ -112,7 +112,8 @@ clientRequests411 OBJECT-TYPE
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
@@ -120,7 +121,8 @@ clientRequests413 OBJECT-TYPE
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
@@ -186,7 +188,8 @@ backendConnUnused OBJECT-TYPE
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
@@ -912,7 +915,8 @@ vclFail OBJECT-TYPE
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 }
--
diff --git a/src/backend.h b/src/backend.h
index 0c15e60..d60f613 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -11,6 +11,6 @@ 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
@@ -51,7 +51,7 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
}
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);
@@ -61,43 +61,6 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
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
*/
@@ -156,7 +119,7 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
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)
@@ -266,7 +229,7 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
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;
}
@@ -276,7 +239,7 @@ 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);
diff --git a/src/betab.c b/src/betab.c
index 388083b..afec48a 100644
--- a/src/betab.c
+++ b/src/betab.c
@@ -136,7 +136,7 @@ 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;
@@ -182,7 +182,7 @@ 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);
@@ -190,14 +190,6 @@ backendTable_free(netsnmp_cache *cache, void *vmagic)
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)
@@ -334,19 +326,15 @@ backend_name_add(struct backend_name_list *namelist,
}
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)
diff --git a/src/modconf.c b/src/modconf.c
new file mode 100644
index 0000000..85b2582
--- a/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
--- a/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
@@ -113,9 +113,6 @@ 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;
@@ -168,5 +165,4 @@ dict_load(struct vsc *vsc)
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
@@ -35,8 +35,8 @@ $vars{'varnish_translate_table'} = {
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' ],
@@ -46,7 +46,7 @@ $vars{'varnish_translate_table'} = {
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' ],
@@ -161,30 +161,19 @@ $vars{'modulename'} =~ s/\.c$//;
#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);
@@ -195,12 +184,6 @@ 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);
@@ -214,18 +197,36 @@ void dict_load(struct vsc *vsc);
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
@@ -235,12 +236,13 @@ varnish_snmp_deinit(void)
}
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;
@@ -588,6 +590,10 @@ initialize_table_$i(void)
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'});
@@ -601,21 +607,7 @@ $varnish_endif
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@
diff --git a/src/vcli.c b/src/vcli.c
index 499c365..2683c9d 100644
--- a/src/vcli.c
+++ b/src/vcli.c
@@ -25,14 +25,67 @@
#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
@@ -146,7 +199,7 @@ vcli_read(struct vcli_conn *conn, size_t size)
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;
@@ -229,7 +282,7 @@ 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);
@@ -316,14 +369,14 @@ vcli_asprintf(struct vcli_conn *conn, const char *fmt, ...)
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;
@@ -334,7 +387,7 @@ open_socket(struct sockaddr_in *sa, const char *connstr)
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) {
@@ -354,12 +407,22 @@ open_socket(struct sockaddr_in *sa, const char *connstr)
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;
@@ -423,82 +486,73 @@ vcli_handshake(struct vcli_conn *conn)
return 0;
}
-int
-vcli_connect(struct vsm *vsm, struct vcli_conn *conn)
+static int
+parse_connection(struct vsm *vsm, vcli_sockaddr_t *addr, char **secret)
{
- struct sockaddr_in vcli_sa;
- char *portstr, *p;
- unsigned long n;
- short pn;
- struct hostent *hp;
- char *T_arg = NULL, *S_arg = NULL;
- memset(conn, 0, sizeof(*conn));
-
- T_arg = VSM_Dup(vsm, "Arg", "-T");
- if (!T_arg) {
- snmp_log(LOG_ERR, "no -T arg in shared memory\n");
- return SNMP_ERR_GENERR;
- }
- S_arg = VSM_Dup(vsm, "Arg", "-S");
- if (!S_arg) {
- free(T_arg);
- snmp_log(LOG_ERR, "no -S arg in shared memory\n");
- return SNMP_ERR_GENERR;
- }
-
- DEBUGMSGTL(("varnish_mib:vcli", "-T '%s'\n", (char*) T_arg));
-
- for (portstr = T_arg; !ISSPACE(*portstr); portstr++)
- ;
- if (!*portstr) {
- snmp_log(LOG_ERR, "unrecognized -T arg: %s\n", T_arg);
- free(T_arg);
- free(S_arg);
- return SNMP_ERR_GENERR;
- }
- for (*portstr++ = 0; ISSPACE(*portstr); portstr++)
- ;
-
- n = pn = strtoul(portstr, &p, 0);
- if (n != pn || (*p && !ISSPACE(*p))) {
- snmp_log(LOG_ERR, "unrecognized -T arg: %s\n", T_arg);
+ if (vcli_sockaddr) {
+ DEBUGMSGTL(("varnish_mib:vcli",
+ "using configured sockaddr\n"));
+ *addr = vcli_sockaddr_dup(vcli_sockaddr);
+ } else {
+ char *T_arg, *p;
+ T_arg = VSM_Dup(vsm, "Arg", "-T");
+ if (!T_arg) {
+ snmp_log(LOG_ERR, "no -T arg in shared memory\n");
+ return SNMP_ERR_GENERR;
+ }
+ p = T_arg + strlen(T_arg) - 1;
+ if (*p == '\n')
+ *p = 0;
+ DEBUGMSGTL(("varnish_mib:vcli", "-T '%s'\n", T_arg));
+ *addr = vcli_parse_sockaddr(T_arg);
free(T_arg);
- free(S_arg);
- return SNMP_ERR_GENERR;
}
-
- hp = gethostbyname(T_arg);
- if (!hp) {
- snmp_log(LOG_ERR, "unknown host name %s\n", T_arg);
- free(T_arg);
- free(S_arg);
+ if (!*addr)
return SNMP_ERR_GENERR;
- }
- vcli_sa.sin_family = hp->h_addrtype;
- if (vcli_sa.sin_family != AF_INET) {
- snmp_log(LOG_ERR, "unknown host name %s\n", T_arg);
- free(T_arg);
- free(S_arg);
- return SNMP_ERR_GENERR;
- }
-
- memmove(&vcli_sa.sin_addr, hp->h_addr, 4);
- vcli_sa.sin_port = htons(pn);
+ if (vcli_secret) {
+ DEBUGMSGTL(("varnish_mib:vcli",
+ "using configured secret\n"));
+ *secret = strdup(vcli_secret);
+ if (!*secret) {
+ snmp_log(LOG_ERR, "out of memory");
+ return SNMP_ERR_GENERR;
+ }
+ } else {
+ char *S_arg = VSM_Dup(vsm, "Arg", "-S");
+ if (!S_arg) {
+ snmp_log(LOG_ERR, "no -S arg in shared memory\n");
+ return SNMP_ERR_GENERR;
+ }
+ DEBUGMSGTL(("varnish_mib:vcli", "-S '%s'\n", S_arg));
+ *secret = S_arg;
+ }
+ return 0;
+}
- conn->fd = open_socket(&vcli_sa, T_arg);
- free(T_arg);
- if (conn->fd == -1) {
- free(S_arg);
- return SNMP_ERR_GENERR;
- }
+int
+vcli_connect(struct vsm *vsm, struct vcli_conn *conn)
+{
+ vcli_sockaddr_t addr = NULL;
+ char *secret = NULL;
+ int rc;
- DEBUGMSGTL(("varnish_mib:vcli", "-S '%s'\n", S_arg));
- conn->secret = S_arg;
-
- if (vcli_handshake(conn)) {
- vcli_disconnect(conn);
- return SNMP_ERR_GENERR;
+ rc = parse_connection(vsm, &addr, &secret);
+ if (rc == 0) {
+ memset(conn, 0, sizeof(*conn));
+ conn->fd = open_socket(addr);
+ if (conn->fd == -1)
+ rc = SNMP_ERR_GENERR;
+ else {
+ conn->secret = secret;
+ secret = NULL;
+ if (vcli_handshake(conn)) {
+ vcli_disconnect(conn);
+ rc = SNMP_ERR_GENERR;
+ }
+ }
}
- return SNMP_ERR_NOERROR;
+ free(addr);
+ free(secret);
+ return rc;
}
diff --git a/src/vclient.h b/src/vclient.h
new file mode 100644
index 0000000..8bb3cdf
--- a/dev/null
+++ b/src/vclient.h
@@ -0,0 +1,21 @@
+struct vcli_sockaddr;
+typedef struct vcli_sockaddr *vcli_sockaddr_t;
+
+vcli_sockaddr_t vcli_parse_sockaddr(char const *arg);
+
+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);
+

Return to:

Send suggestions and report system problems to the System administrator.