aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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
@@ -20,18 +20,21 @@ 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
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
@@ -17,20 +17,20 @@ IMPORTS
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 }
@@ -109,21 +109,23 @@ clientRequests400 OBJECT-TYPE
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
@@ -183,13 +185,14 @@ backendConnRecycled OBJECT-TYPE
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
@@ -909,13 +912,14 @@ vclDiscard OBJECT-TYPE
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 }
diff --git a/src/backend.h b/src/backend.h
index 0c15e60..d60f613 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -8,9 +8,9 @@ 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
@@ -48,59 +48,22 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
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)
{
@@ -153,13 +116,13 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
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))
@@ -263,23 +226,23 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
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
@@ -133,13 +133,13 @@ backend_register(char const *name, size_t len, char const *param,
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;
@@ -179,28 +179,20 @@ backendTable_load(netsnmp_cache *cache, void *vmagic)
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;
@@ -331,25 +323,21 @@ backend_name_add(struct backend_name_list *namelist,
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 */
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
@@ -110,15 +110,12 @@ lookup(const char *name, int 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;
}
@@ -165,8 +162,7 @@ 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
@@ -32,24 +32,24 @@ $vars{'varnish_translate_table'} = {
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' ],
@@ -158,52 +158,35 @@ $vars{'modulename'} =~ s/\.c$//;
/* 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. */
@@ -211,39 +194,58 @@ void dict_load(struct vsc *vsc);
#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.
@@ -585,12 +587,16 @@ initialize_table_$i(void)
@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
@@ -598,27 +604,13 @@ $varnish_if
$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'@
diff --git a/src/vcli.c b/src/vcli.c
index 499c365..2683c9d 100644
--- a/src/vcli.c
+++ b/src/vcli.c
@@ -22,20 +22,73 @@
#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)
@@ -143,13 +196,13 @@ vcli_read(struct vcli_conn *conn, size_t size)
}
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
@@ -226,13 +279,13 @@ vcli_getline(struct vcli_conn *conn)
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));
@@ -313,31 +366,31 @@ vcli_asprintf(struct vcli_conn *conn, const char *fmt, ...)
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;
@@ -351,18 +404,28 @@ open_socket(struct sockaddr_in *sa, const char *connstr)
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;
}
void
@@ -420,85 +483,76 @@ vcli_handshake(struct vcli_conn *conn)
return 1;
}
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
--- /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.