diff options
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/VARNISH-MIB.txt | 16 | ||||
-rw-r--r-- | src/backend.h | 2 | ||||
-rw-r--r-- | src/ban.c | 45 | ||||
-rw-r--r-- | src/betab.c | 20 | ||||
-rw-r--r-- | src/modconf.c | 123 | ||||
-rw-r--r-- | src/modconf.h | 9 | ||||
-rw-r--r-- | src/statdict.c | 4 | ||||
-rw-r--r-- | src/varnish_mib.mib2c | 86 | ||||
-rw-r--r-- | src/vcli.c | 196 | ||||
-rw-r--r-- | src/vclient.h | 21 |
11 files changed, 340 insertions, 187 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); @@ -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); @@ -191,14 +191,6 @@ backendTable_free(netsnmp_cache *cache, void *vmagic) } } -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 --- /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 @@ -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@ @@ -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; -void -varnish_vcli_timeout_parser(const char *token, char *line) + n = strcspn(arg, ": \t"); + node = malloc(n + 1); + if (!node) { + snmp_log(LOG_ERR, "out of memory\n"); + return NULL; + } + + 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); @@ -317,13 +370,13 @@ vcli_asprintf(struct vcli_conn *conn, const char *fmt, ...) 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,13 +407,23 @@ open_socket(struct sockaddr_in *sa, const char *connstr) select(fd + 1, &rset, &wset, &xset, &tv); continue; } - } - - snmp_log(LOG_ERR, "cannot connect to %s: %s\n", - connstr, strerror(errno)); + } 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; } + } 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)); - + 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; } - S_arg = VSM_Dup(vsm, "Arg", "-S"); - if (!S_arg) { + 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); - 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); + if (!*addr) 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); - free(T_arg); - free(S_arg); + 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; } - - hp = gethostbyname(T_arg); - if (!hp) { - snmp_log(LOG_ERR, "unknown host name %s\n", T_arg); - free(T_arg); - free(S_arg); + } 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; } - - 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; + DEBUGMSGTL(("varnish_mib:vcli", "-S '%s'\n", S_arg)); + *secret = S_arg; } - - memmove(&vcli_sa.sin_addr, hp->h_addr, 4); - vcli_sa.sin_port = htons(pn); - - conn->fd = open_socket(&vcli_sa, T_arg); - free(T_arg); - if (conn->fd == -1) { - free(S_arg); - return SNMP_ERR_GENERR; + return 0; } - DEBUGMSGTL(("varnish_mib:vcli", "-S '%s'\n", S_arg)); - conn->secret = S_arg; +int +vcli_connect(struct vsm *vsm, struct vcli_conn *conn) +{ + vcli_sockaddr_t addr = NULL; + char *secret = NULL; + int rc; + 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); - return SNMP_ERR_GENERR; + 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); + |