summaryrefslogtreecommitdiffabout
path: root/src
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) (unidiff)
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') (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 = \
23 backend.h\ 23 backend.h\
24 belex.l\ 24 belex.l\
25 betab.c\ 25 betab.c\
26 modconf.h\
27 modconf.c\
26 sha256.c\ 28 sha256.c\
27 sha256.h\ 29 sha256.h\
28 statdict.c\ 30 statdict.c\
29 varnish_mib.c\ 31 varnish_mib.c\
30 varnish_mib.h\ 32 varnish_mib.h\
31 vcli.c 33 vcli.c\
34 vclient.h
32 35
33BUILT_SOURCES = \ 36BUILT_SOURCES = \
34 varnish_mib.c\ 37 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
20 FROM SNMPv2-CONF; 20 FROM SNMPv2-CONF;
21 21
22varnishMIB MODULE-IDENTITY 22varnishMIB MODULE-IDENTITY
23 LAST-UPDATED "201802012132Z" 23 LAST-UPDATED "201802020845Z"
24 ORGANIZATION "Shared Autonomous sYstems" 24 ORGANIZATION "Shared Autonomous sYstems"
25 CONTACT-INFO "Morten Hermanrud <mhe@say.no> 25 CONTACT-INFO "Morten Hermanrud <mhe@say.no>
26 Sergey Poznyakoff <gray@gnu.org> 26 Sergey Poznyakoff <gray@gnu.org>
27 " 27 "
28 DESCRIPTION 28 DESCRIPTION
29 "This MIB module defines objects for Varnish reverse web proxy." 29 "This MIB module defines objects for Varnish reverse web proxy."
30 REVISION "201802012132Z" 30 REVISION "201802020845Z"
31 DESCRIPTION 31 DESCRIPTION
32 "Second revision." 32 "Second revision."
33 ::= { varnish 0 } 33 ::= { varnish 0 }
@@ -112,7 +112,8 @@ clientRequests411 OBJECT-TYPE
112 MAX-ACCESS read-only 112 MAX-ACCESS read-only
113 STATUS current 113 STATUS current
114 DESCRIPTION 114 DESCRIPTION
115 "Client requests received, subject to 411 errors." 115 "Client requests received, subject to 411 errors.
116 This OID is not available in Varnish version 5 and above."
116 ::= { client 8 } 117 ::= { client 8 }
117 118
118clientRequests413 OBJECT-TYPE 119clientRequests413 OBJECT-TYPE
@@ -120,7 +121,8 @@ clientRequests413 OBJECT-TYPE
120 MAX-ACCESS read-only 121 MAX-ACCESS read-only
121 STATUS current 122 STATUS current
122 DESCRIPTION 123 DESCRIPTION
123 "Client requests received, subject to 413 errors." 124 "Client requests received, subject to 413 errors.
125 This OID is not available in Varnish version 5 and above."
124 ::= { client 9 } 126 ::= { client 9 }
125 127
126clientRequests417 OBJECT-TYPE 128clientRequests417 OBJECT-TYPE
@@ -186,7 +188,8 @@ backendConnUnused OBJECT-TYPE
186 MAX-ACCESS read-only 188 MAX-ACCESS read-only
187 STATUS current 189 STATUS current
188 DESCRIPTION 190 DESCRIPTION
189 "Backend connections unused." 191 "Backend connections unused.
192 This OID is not available in Varnish version 5 and above."
190 ::= { connections 7 } 193 ::= { connections 7 }
191 194
192backendConnRetry OBJECT-TYPE 195backendConnRetry OBJECT-TYPE
@@ -912,7 +915,8 @@ vclFail OBJECT-TYPE
912 MAX-ACCESS read-only 915 MAX-ACCESS read-only
913 STATUS current 916 STATUS current
914 DESCRIPTION 917 DESCRIPTION
915 "Number of VCL failures" 918 "Number of VCL failures.
919 This OID is not available in Varnish 4 and below."
916 ::= { vcl 4 } 920 ::= { vcl 4 }
917 921
918-- 922--
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;
11void backend_register(char const *name, size_t len, char const *param, 11void backend_register(char const *name, size_t len, char const *param,
12 const struct VSC_point *vpt); 12 const struct VSC_point *vpt);
13void backend_clear(void); 13void backend_clear(void);
14int backend_collect_addr(void); 14int backend_collect_addr(struct vsm *vsm);
15void backend_parser(const char *str, size_t len, regfun_t regfun, void *d); 15void backend_parser(const char *str, size_t len, regfun_t regfun, void *d);
16 16
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,
51 } 51 }
52 memcpy(expr, requests->requestvb->val.string, len); 52 memcpy(expr, requests->requestvb->val.string, len);
53 expr[len] = 0; 53 expr[len] = 0;
54 DEBUGMSGTL(("varnish_ban", "setting ban %s\n", expr)); 54 DEBUGMSGTL(("varnish_mib:ban", "setting ban %s\n", expr));
55 rc = vcli_connect(vsm, &conn); 55 rc = vcli_connect(vsm, &conn);
56 if (rc == SNMP_ERR_NOERROR) { 56 if (rc == SNMP_ERR_NOERROR) {
57 rc = send_ban_cmd(&conn, expr); 57 rc = send_ban_cmd(&conn, expr);
@@ -61,43 +61,6 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
61 return rc ? SNMP_ERR_GENERR : SNMP_ERR_NOERROR; 61 return rc ? SNMP_ERR_GENERR : SNMP_ERR_NOERROR;
62} 62}
63 63
64unsigned banTable_timeout = 60;
65
66int
67varnish_mib_timeout_parser(const char *token, char *line, unsigned *retval)
68{
69 char *p;
70 unsigned long n = strtoul(line, &p, 10);
71
72 if (*p) {
73 if (isspace(*p)) {
74 while (*p && isspace(*p))
75 ++p;
76 if (*p) {
77 config_perror("too many arguments");
78 return 1;
79 }
80 } else {
81 config_perror("invalid timeout value");
82 return 1;
83 }
84 }
85
86 if (n > UINT_MAX) {
87 config_perror("timeout value out of allowed range");
88 return 1;
89 }
90
91 *retval = n;
92 return 0;
93}
94
95void
96varnish_ban_table_timeout_parser(const char *token, char *line)
97{
98 varnish_mib_timeout_parser(token, line, &banTable_timeout);
99}
100
101/* 64/*
102 * create a new row in the table 65 * create a new row in the table
103 */ 66 */
@@ -156,7 +119,7 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
156 if (!vsm) 119 if (!vsm)
157 return SNMP_ERR_GENERR; 120 return SNMP_ERR_GENERR;
158 121
159 DEBUGMSGTL(("varnish_ban", "reloading ban table\n")); 122 DEBUGMSGTL(("varnish_mib:ban", "reloading ban table\n"));
160 rc = vcli_connect(vsm, &conn); 123 rc = vcli_connect(vsm, &conn);
161 124
162 if (rc != SNMP_ERR_NOERROR) 125 if (rc != SNMP_ERR_NOERROR)
@@ -266,7 +229,7 @@ banTable_load(netsnmp_cache *cache, void *vmagic)
266 p = q; 229 p = q;
267 } 230 }
268 vcli_disconnect(&conn); 231 vcli_disconnect(&conn);
269 DEBUGMSGTL(("varnish_ban", "loaded %ld ban entries\n", idx)); 232 DEBUGMSGTL(("varnish_mib:ban", "loaded %ld ban entries\n", idx));
270 return 0; 233 return 0;
271} 234}
272 235
@@ -276,7 +239,7 @@ banTable_free(netsnmp_cache *cache, void *vmagic)
276 netsnmp_tdata *table = (netsnmp_tdata *) vmagic; 239 netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
277 netsnmp_tdata_row *row; 240 netsnmp_tdata_row *row;
278 241
279 DEBUGMSGTL(("varnish_ban", "freeing ban table\n")); 242 DEBUGMSGTL(("varnish_mib:ban", "freeing ban table\n"));
280 while ((row = netsnmp_tdata_row_first(table))) { 243 while ((row = netsnmp_tdata_row_first(table))) {
281 struct banTable_entry *entry = row->data; 244 struct banTable_entry *entry = row->data;
282 free(entry->banExpression); 245 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)
136 netsnmp_tdata *table_data = (netsnmp_tdata *) vmagic; 136 netsnmp_tdata *table_data = (netsnmp_tdata *) vmagic;
137 struct backend_dfn *dfn; 137 struct backend_dfn *dfn;
138 138
139 DEBUGMSGTL(("varnish_backend", "loading backend table\n")); 139 DEBUGMSGTL(("varnish_mib:backend", "loading backend table\n"));
140 140
141 VTAILQ_FOREACH(dfn, &backends, list) { 141 VTAILQ_FOREACH(dfn, &backends, list) {
142 int i; 142 int i;
@@ -182,7 +182,7 @@ backendTable_free(netsnmp_cache *cache, void *vmagic)
182 netsnmp_tdata *table = (netsnmp_tdata *) vmagic; 182 netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
183 netsnmp_tdata_row *row; 183 netsnmp_tdata_row *row;
184 184
185 DEBUGMSGTL(("varnish_backend", "freeing backend table\n")); 185 DEBUGMSGTL(("varnish_mib:backend", "freeing backend table\n"));
186 while ((row = netsnmp_tdata_row_first(table))) { 186 while ((row = netsnmp_tdata_row_first(table))) {
187 struct backendTable_entry *entry = row->data; 187 struct backendTable_entry *entry = row->data;
188 free(entry->vbeIdent); 188 free(entry->vbeIdent);
@@ -190,14 +190,6 @@ backendTable_free(netsnmp_cache *cache, void *vmagic)
190 netsnmp_tdata_remove_and_delete_row(table, row); 190 netsnmp_tdata_remove_and_delete_row(table, row);
191 } 191 }
192} 192}
193
194unsigned backendTable_timeout = 5;
195
196void
197varnish_backend_table_timeout_parser(const char *token, char *line)
198{
199 varnish_mib_timeout_parser(token, line, &backendTable_timeout);
200}
201 193
202static struct backend_dfn * 194static struct backend_dfn *
203dfn_lookup(be_string_t *vclname, be_string_t *label) 195dfn_lookup(be_string_t *vclname, be_string_t *label)
@@ -334,19 +326,15 @@ backend_name_add(struct backend_name_list *namelist,
334} 326}
335 327
336int 328int
337backend_collect_addr(void) 329backend_collect_addr(struct vsm *vsm)
338{ 330{
339 struct backend_dfn *dfn; 331 struct backend_dfn *dfn;
340 struct vcli_conn conn; 332 struct vcli_conn conn;
341 struct vsm *vsm;
342 int rc; 333 int rc;
343 struct backend_name_list namelist 334 struct backend_name_list namelist
344 = VTAILQ_HEAD_INITIALIZER(namelist); 335 = VTAILQ_HEAD_INITIALIZER(namelist);
345 336
346 vsm = varnish_get_vsm_data(); 337 DEBUGMSGTL(("varnish_mib:backend", "getting backend info\n"));
347 if (!vsm)
348 return SNMP_ERR_GENERR;
349 DEBUGMSGTL(("varnish_backend", "getting backend info\n"));
350 338
351 rc = vcli_connect(vsm, &conn); 339 rc = vcli_connect(vsm, &conn);
352 if (rc != SNMP_ERR_NOERROR) 340 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 @@
1#include "varnish_mib.h"
2#include <ctype.h>
3
4static int
5timeout_parser(const char *token, char *line, unsigned *retval)
6{
7 char *p;
8 unsigned long n = strtoul(line, &p, 10);
9
10 if (*p) {
11 if (isspace(*p)) {
12 while (*p && isspace(*p))
13 ++p;
14 if (*p) {
15 config_perror("too many arguments");
16 return 1;
17 }
18 } else {
19 config_perror("invalid timeout value");
20 return 1;
21 }
22 }
23
24 if (n > UINT_MAX) {
25 config_perror("timeout value out of allowed range");
26 return 1;
27 }
28
29 *retval = n;
30 return 0;
31}
32
33unsigned banTable_timeout = 60;
34unsigned vcli_timeout = 5;
35unsigned backendTable_timeout = 5;
36vcli_sockaddr_t vcli_sockaddr;
37char *vcli_secret;
38
39static void
40ban_table_timeout_parser(const char *token, char *line)
41{
42 timeout_parser(token, line, &banTable_timeout);
43}
44
45static void
46backend_table_timeout_parser(const char *token, char *line)
47{
48 timeout_parser(token, line, &backendTable_timeout);
49}
50
51static void
52vcli_timeout_parser(const char *token, char *line)
53{
54 timeout_parser(token, line, &vcli_timeout);
55}
56
57static void
58vcli_address_parser(const char *token, char *line)
59{
60 vcli_sockaddr = vcli_parse_sockaddr(line);
61}
62
63static void
64vcli_address_releaser(void)
65{
66 free(vcli_sockaddr);
67}
68
69static void
70vcli_secret_parser(const char *token, char *line)
71{
72 vcli_secret = strdup(line);
73}
74
75static void
76vcli_secret_releaser(void)
77{
78 free(vcli_secret);
79}
80
81struct varnish_mib_config
82{
83 char *token;
84 char *help;
85 void (*parser)(const char *token, char *line);
86 void (*releaser) (void);
87};
88
89static struct varnish_mib_config config[] = {
90 { "varnishBanTableTimeout",
91 "varnishBanTableTimeout SECONDS",
92 ban_table_timeout_parser },
93 { "varnishBackendTableTimeout",
94 "varnishBackendTableTimeout SECONDS",
95 backend_table_timeout_parser },
96 { "varnishCLIPortTimeout",
97 "varnishCLIPortTimeout SECONDS",
98 vcli_timeout_parser },
99 { "varnishCLISocket",
100 "varnishCLISocket ADDRESS[:PORT]",
101 vcli_address_parser,
102 vcli_address_releaser },
103 { "varnishCLISecretFile",
104 "varnishCLISecretFile FILE",
105 vcli_secret_parser,
106 vcli_secret_releaser },
107 { NULL }
108};
109
110void
111varnish_mib_config_init(void)
112{
113 struct varnish_mib_config *cp;
114 for (cp = config; cp->token; cp++) {
115 if (!register_config_handler("snmpd",
116 cp->token,
117 cp->parser,
118 cp->releaser,
119 cp->help))
120 snmp_log(LOG_ERR,"can't register %s config handler\n",
121 cp->token);
122 }
123}
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 @@
1extern unsigned banTable_timeout;
2extern unsigned vcli_timeout;
3extern unsigned backendTable_timeout;
4extern vcli_sockaddr_t vcli_sockaddr;
5extern char *vcli_secret;
6
7void varnish_mib_config_init(void);
8
9
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)
113 struct VSC_point **ent; 113 struct VSC_point **ent;
114 114
115 ent = lookup(key, 0); 115 ent = lookup(key, 0);
116 if (!ent) {
117 fprintf(stderr, "%s NOT FOUND\n", key);
118 }
119 if (!ent) 116 if (!ent)
120 return -1; 117 return -1;
121 *val = *(uint64_t*)(*ent)->ptr; 118 *val = *(uint64_t*)(*ent)->ptr;
@@ -168,5 +165,4 @@ dict_load(struct vsc *vsc)
168 dict_clear(); 165 dict_clear();
169 backend_clear(); 166 backend_clear();
170 VSC_Iter(vsc, &fantom, load_cb, NULL); 167 VSC_Iter(vsc, &fantom, load_cb, NULL);
171 backend_collect_addr();
172} 168}
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'} = {
35 35
36 clientRequestsReceived => [ 'DICT', 'MAIN.client_req' ], 36 clientRequestsReceived => [ 'DICT', 'MAIN.client_req' ],
37 clientRequests400 => [ 'DICT', 'MAIN.client_req_400' ], 37 clientRequests400 => [ 'DICT', 'MAIN.client_req_400' ],
38 clientRequests411 => [ 'NULL', 'MAIN.client_req_411' ], 38 clientRequests411 => [ 'NULL' ],
39 clientRequests413 => [ 'NULL', 'MAIN.client_req_413' ], 39 clientRequests413 => [ 'NULL' ],
40 clientRequests417 => [ 'DICT', 'MAIN.client_req_417' ], 40 clientRequests417 => [ 'DICT', 'MAIN.client_req_417' ],
41 41
42 42
@@ -46,7 +46,7 @@ $vars{'varnish_translate_table'} = {
46 backendConnFailures => [ 'DICT', 'MAIN.backend_fail' ], 46 backendConnFailures => [ 'DICT', 'MAIN.backend_fail' ],
47 backendConnReuses => [ 'DICT', 'MAIN.backend_reuse' ], 47 backendConnReuses => [ 'DICT', 'MAIN.backend_reuse' ],
48 backendConnRecycled => [ 'DICT', 'MAIN.backend_recycle' ], 48 backendConnRecycled => [ 'DICT', 'MAIN.backend_recycle' ],
49 backendConnUnused => [ 'NULL', 'MAIN.backend_toolate' ], 49 backendConnUnused => [ 'NULL' ],
50 backendConnRetry => [ 'DICT', 'MAIN.backend_retry' ], 50 backendConnRetry => [ 'DICT', 'MAIN.backend_retry' ],
51 backendRequests => [ 'DICT', 'MAIN.backend_req' ], 51 backendRequests => [ 'DICT', 'MAIN.backend_req' ],
52 52
@@ -161,30 +161,19 @@ $vars{'modulename'} =~ s/\.c$//;
161#include <stdlib.h> 161#include <stdlib.h>
162#include <stdint.h> 162#include <stdint.h>
163#include <limits.h> 163#include <limits.h>
164#include <errno.h>
164 165
165#include <vapi/vsc.h> 166#include <vapi/vsc.h>
166#include <vapi/vsm.h> 167#include <vapi/vsm.h>
167#include <vcli.h> 168#include <vcli.h>
169#include <vas.h>
168 170
169#include <net-snmp/net-snmp-config.h> 171#include <net-snmp/net-snmp-config.h>
170#include <net-snmp/net-snmp-includes.h> 172#include <net-snmp/net-snmp-includes.h>
171#include <net-snmp/agent/net-snmp-agent-includes.h> 173#include <net-snmp/agent/net-snmp-agent-includes.h>
172 174
173typedef struct vcli_conn { 175#include "vclient.h"
174 int fd; 176#include "modconf.h"
175 char *secret;
176 int resp;
177 char *base;
178 size_t bufmax;
179 size_t bufsize;
180} vcli_conn_t;
181
182int vcli_write(vcli_conn_t *conn);
183int vcli_read_response(vcli_conn_t *conn);
184int vcli_vasprintf(vcli_conn_t *conn, const char *fmt, va_list ap);
185int vcli_asprintf(vcli_conn_t *conn, const char *fmt, ...);
186void vcli_disconnect(vcli_conn_t *conn);
187int vcli_connect(struct vsm *vsm, vcli_conn_t *conn);
188 177
189struct vsm *varnish_get_vsm_data(void); 178struct vsm *varnish_get_vsm_data(void);
190 179
@@ -195,12 +184,6 @@ int varnish_ban(netsnmp_agent_request_info *reqinfo,
195 netsnmp_request_info *requests, 184 netsnmp_request_info *requests,
196 struct vsm *vsm); 185 struct vsm *vsm);
197 186
198int varnish_mib_timeout_parser(const char *token, char *line,
199 unsigned *retval);
200
201void varnish_ban_table_timeout_parser(const char *token, char *line);
202void varnish_vcli_timeout_parser(const char *token, char *line);
203
204int dict_lookup(char const *key, uint64_t *val); 187int dict_lookup(char const *key, uint64_t *val);
205void dict_install(struct VSC_point const *pt); 188void dict_install(struct VSC_point const *pt);
206void dict_load(struct vsc *vsc); 189void dict_load(struct vsc *vsc);
@@ -214,18 +197,36 @@ void dict_load(struct vsc *vsc);
214static struct vsm *vd; 197static struct vsm *vd;
215static struct vsc *vsc; 198static struct vsc *vsc;
216 199
217void 200int
218varnish_snmp_init(void) 201post_config(int majorID, int minorID, void *serverarg, void *clientarg)
219{ 202{
220 vd = VSM_New(); 203 vd = VSM_New();
221 if (vd) { 204 if (!vd) {
222 vsc = VSC_New(vd); 205 snmp_log(LOG_ERR, "VSM_New: %s\n", strerror(errno));
223 if (vsc) { 206 return 1;
224 if (VSM_Attach(vd, 2)) 207 }
225 fprintf(stderr, "%s\n", VSM_Error(vd)); 208
226 } 209 vsc = VSC_New(vd);
210 if (!vsc) {
211 snmp_log(LOG_ERR, "VSC_New: %s\n", strerror(errno));
212 return 1;
227 } 213 }
214
215 if (VSM_Attach(vd, 2))
216 snmp_log(LOG_ERR, "%s\n", VSM_Error(vd));
217
228 dict_load(vsc); 218 dict_load(vsc);
219 backend_collect_addr(vd);
220 return 0;
221}
222
223void
224varnish_snmp_init(void)
225{
226 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
227 SNMP_CALLBACK_POST_READ_CONFIG,
228 post_config,
229 NULL);
229} 230}
230 231
231void 232void
@@ -235,12 +236,13 @@ varnish_snmp_deinit(void)
235} 236}
236 237
237struct vsm * 238struct vsm *
238varnish_get_vsm_data() 239varnish_get_vsm_data(void)
239{ 240{
240 if (vd) { 241 if (vd) {
241 if (VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED)) { 242 if (VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED)) {
242 DEBUGMSGTL(("$modulename", "reopening vd\n")); 243 DEBUGMSGTL(("$modulename", "reopening vd\n"));
243 dict_load(vsc); 244 dict_load(vsc);
245 backend_collect_addr(vd);
244 } 246 }
245 } 247 }
246 return vd; 248 return vd;
@@ -588,6 +590,10 @@ initialize_table_$i(void)
588void 590void
589init_$modulename(void) 591init_$modulename(void)
590{ 592{
593 if (vd) {
594 snmp_log(LOG_ERR, "%s: can't be loaded twice\n", "$modulename");
595 abort();
596 }
591 @foreach $i scalar@ 597 @foreach $i scalar@
592 @startperl@ 598 @startperl@
593 &{$vars{'varnish_translate'}}($vars{'i'}); 599 &{$vars{'varnish_translate'}}($vars{'i'});
@@ -601,21 +607,7 @@ $varnish_endif
601 607
602 DEBUGMSGTL(("$modulename", "Initializing\n")); 608 DEBUGMSGTL(("$modulename", "Initializing\n"));
603 609
604 if (!register_config_handler("snmpd", "varnishBanTableTimeout", 610 varnish_mib_config_init();
605 varnish_ban_table_timeout_parser,
606 NULL,
607 "varnishBanTableTimeout SECONDS"))
608 snmp_log(LOG_ERR,"can't register config handler\n");
609 if (!register_config_handler("snmpd", "varnishBackendTableTimeout",
610 varnish_backend_table_timeout_parser,
611 NULL,
612 "varnishBackendTableTimeout SECONDS"))
613 snmp_log(LOG_ERR,"can't register config handler\n");
614 if (!register_config_handler("snmpd", "varnishCLIPortTimeout",
615 varnish_vcli_timeout_parser,
616 NULL,
617 "varnishCLIPortTimeout SECONDS"))
618 snmp_log(LOG_ERR,"can't register config handler\n");
619 611
620 @foreach $i scalar@ 612 @foreach $i scalar@
621 @startperl@ 613 @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 @@
25#include <arpa/inet.h> 25#include <arpa/inet.h>
26#include <errno.h> 26#include <errno.h>
27 27
28struct vcli_sockaddr {
29 socklen_t len;
30 struct sockaddr addr[1];
31};
32
28#define ISSPACE(c) ((c)==' '||(c)=='\t'||(c)=='\n') 33#define ISSPACE(c) ((c)==' '||(c)=='\t'||(c)=='\n')
29 34
30static unsigned vcli_timeout = 5; 35vcli_sockaddr_t
36vcli_parse_sockaddr(char const *arg)
37{
38 char *node;
39 size_t n;
40 int rc;
41 struct addrinfo *res;
42 char const *p;
43 vcli_sockaddr_t sa;
44
45 n = strcspn(arg, ": \t");
46 node = malloc(n + 1);
47 if (!node) {
48 snmp_log(LOG_ERR, "out of memory\n");
49 return NULL;
50 }
31 51
32void 52 memcpy(node, arg, n);
33varnish_vcli_timeout_parser(const char *token, char *line) 53 node[n] = 0;
54 p = arg + n;
55 if (*p == ':')
56 p++;
57 else
58 while (*p && ISSPACE(*p))
59 p++;
60
61 if (!p)
62 p = "6082";
63
64 rc = getaddrinfo(node, p, NULL, &res);
65 free(node);
66 if (rc) {
67 snmp_log(LOG_ERR, "can't resolve %s\n", arg);
68 return NULL;
69 }
70
71 sa = malloc(sizeof(*sa) - sizeof(sa->addr) + res->ai_addrlen);
72 if (!sa) {
73 snmp_log(LOG_ERR, "out of memory\n");
74 return NULL;
75 }
76 sa->len = res->ai_addrlen;
77 memcpy(sa->addr, res->ai_addr, res->ai_addrlen);
78 freeaddrinfo(res);
79 return sa;
80}
81
82vcli_sockaddr_t
83vcli_sockaddr_dup(vcli_sockaddr_t src)
34{ 84{
35 varnish_mib_timeout_parser(token, line, &vcli_timeout); 85 vcli_sockaddr_t dst;
86 dst = malloc(sizeof(*dst) - sizeof(dst->addr) + src->len);
87 memcpy(dst, src, src->len);
88 return dst;
36} 89}
37 90
38#define VCLI_INIT_ALLOC 16 91#define VCLI_INIT_ALLOC 16
@@ -146,7 +199,7 @@ vcli_read(struct vcli_conn *conn, size_t size)
146 if (conn->bufsize == 0) 199 if (conn->bufsize == 0)
147 ret = -1; 200 ret = -1;
148 conn->base[conn->bufsize] = 0; 201 conn->base[conn->bufsize] = 0;
149 DEBUGMSGTL(("varnish_mib:vcli", "<<varnish: %s\n", conn->base)); 202 DEBUGMSGTL(("transcript:varnish_mib", "<<varnish: %s\n", conn->base));
150 } 203 }
151 204
152 return ret; 205 return ret;
@@ -229,7 +282,7 @@ vcli_write(struct vcli_conn *conn)
229{ 282{
230 size_t size; 283 size_t size;
231 284
232 DEBUGMSGTL(("varnish_mib:vcli", ">>varnish: %s\n", conn->base)); 285 DEBUGMSGTL(("transcript:varnish_mib", ">>varnish: %s\n", conn->base));
233 for (size = 0; size < conn->bufsize; ) { 286 for (size = 0; size < conn->bufsize; ) {
234 int n = write(conn->fd, conn->base + size, 287 int n = write(conn->fd, conn->base + size,
235 conn->bufsize - size); 288 conn->bufsize - size);
@@ -316,14 +369,14 @@ vcli_asprintf(struct vcli_conn *conn, const char *fmt, ...)
316 va_end(ap); 369 va_end(ap);
317 return rc; 370 return rc;
318} 371}
319 372
320
321static int 373static int
322open_socket(struct sockaddr_in *sa, const char *connstr) 374open_socket(vcli_sockaddr_t sa)
323{ 375{
324 int fd = socket(sa->sin_family, SOCK_STREAM, 0); 376 int fd;
325 struct timeval start, connect_tv; 377 struct timeval start, connect_tv;
326 378
379 fd = socket(sa->addr->sa_family, SOCK_STREAM, 0);
327 if (fd == -1) { 380 if (fd == -1) {
328 snmp_log(LOG_ERR, "socket: %s\n", strerror(errno)); 381 snmp_log(LOG_ERR, "socket: %s\n", strerror(errno));
329 return -1; 382 return -1;
@@ -334,7 +387,7 @@ open_socket(struct sockaddr_in *sa, const char *connstr)
334 387
335 gettimeofday(&start, NULL); 388 gettimeofday(&start, NULL);
336 for (;;) { 389 for (;;) {
337 int rc = connect(fd, sa, sizeof(*sa)); 390 int rc = connect(fd, sa->addr, sa->len);
338 if (rc == 0) 391 if (rc == 0)
339 break; 392 break;
340 else if (errno == ECONNREFUSED) { 393 else if (errno == ECONNREFUSED) {
@@ -354,12 +407,22 @@ open_socket(struct sockaddr_in *sa, const char *connstr)
354 select(fd + 1, &rset, &wset, &xset, &tv); 407 select(fd + 1, &rset, &wset, &xset, &tv);
355 continue; 408 continue;
356 } 409 }
410 } else {
411 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
412 int ec = errno;
413 if (getnameinfo(sa->addr, sa->len,
414 hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
415 NI_NUMERICHOST | NI_NUMERICSERV) == 0)
416 snmp_log(LOG_ERR,
417 "cannot connect to %s:%s: %s\n",
418 hbuf, sbuf, strerror(ec));
419 else
420 snmp_log(LOG_ERR,
421 "cannot connect to varnish: %s\n",
422 strerror(ec));
423 close(fd);
424 return -1;
357 } 425 }
358
359 snmp_log(LOG_ERR, "cannot connect to %s: %s\n",
360 connstr, strerror(errno));
361 close(fd);
362 return -1;
363 } 426 }
364 427
365 return fd; 428 return fd;
@@ -423,82 +486,73 @@ vcli_handshake(struct vcli_conn *conn)
423 return 0; 486 return 0;
424} 487}
425 488
426int 489static int
427vcli_connect(struct vsm *vsm, struct vcli_conn *conn) 490parse_connection(struct vsm *vsm, vcli_sockaddr_t *addr, char **secret)
428{ 491{
429 struct sockaddr_in vcli_sa; 492 if (vcli_sockaddr) {
430 char *portstr, *p; 493 DEBUGMSGTL(("varnish_mib:vcli",
431 unsigned long n; 494 "using configured sockaddr\n"));
432 short pn; 495 *addr = vcli_sockaddr_dup(vcli_sockaddr);
433 struct hostent *hp; 496 } else {
434 char *T_arg = NULL, *S_arg = NULL; 497 char *T_arg, *p;
435 memset(conn, 0, sizeof(*conn)); 498 T_arg = VSM_Dup(vsm, "Arg", "-T");
436 499 if (!T_arg) {
437 T_arg = VSM_Dup(vsm, "Arg", "-T"); 500 snmp_log(LOG_ERR, "no -T arg in shared memory\n");
438 if (!T_arg) { 501 return SNMP_ERR_GENERR;
439 snmp_log(LOG_ERR, "no -T arg in shared memory\n"); 502 }
440 return SNMP_ERR_GENERR; 503 p = T_arg + strlen(T_arg) - 1;
441 } 504 if (*p == '\n')
442 S_arg = VSM_Dup(vsm, "Arg", "-S"); 505 *p = 0;
443 if (!S_arg) { 506 DEBUGMSGTL(("varnish_mib:vcli", "-T '%s'\n", T_arg));
444 free(T_arg); 507 *addr = vcli_parse_sockaddr(T_arg);
445 snmp_log(LOG_ERR, "no -S arg in shared memory\n");
446 return SNMP_ERR_GENERR;
447 }
448
449 DEBUGMSGTL(("varnish_mib:vcli", "-T '%s'\n", (char*) T_arg));
450
451 for (portstr = T_arg; !ISSPACE(*portstr); portstr++)
452 ;
453 if (!*portstr) {
454 snmp_log(LOG_ERR, "unrecognized -T arg: %s\n", T_arg);
455 free(T_arg);
456 free(S_arg);
457 return SNMP_ERR_GENERR;
458 }
459 for (*portstr++ = 0; ISSPACE(*portstr); portstr++)
460 ;
461
462 n = pn = strtoul(portstr, &p, 0);
463 if (n != pn || (*p && !ISSPACE(*p))) {
464 snmp_log(LOG_ERR, "unrecognized -T arg: %s\n", T_arg);
465 free(T_arg); 508 free(T_arg);
466 free(S_arg);
467 return SNMP_ERR_GENERR;
468 } 509 }
469 510 if (!*addr)
470 hp = gethostbyname(T_arg);
471 if (!hp) {
472 snmp_log(LOG_ERR, "unknown host name %s\n", T_arg);
473 free(T_arg);
474 free(S_arg);
475 return SNMP_ERR_GENERR; 511 return SNMP_ERR_GENERR;
476 }
477 512
478 vcli_sa.sin_family = hp->h_addrtype; 513 if (vcli_secret) {
479 if (vcli_sa.sin_family != AF_INET) { 514 DEBUGMSGTL(("varnish_mib:vcli",
480 snmp_log(LOG_ERR, "unknown host name %s\n", T_arg); 515 "using configured secret\n"));
481 free(T_arg); 516 *secret = strdup(vcli_secret);
482 free(S_arg); 517 if (!*secret) {
483 return SNMP_ERR_GENERR; 518 snmp_log(LOG_ERR, "out of memory");
484 } 519 return SNMP_ERR_GENERR;
485 520 }
486 memmove(&vcli_sa.sin_addr, hp->h_addr, 4); 521 } else {
487 vcli_sa.sin_port = htons(pn); 522 char *S_arg = VSM_Dup(vsm, "Arg", "-S");
523 if (!S_arg) {
524 snmp_log(LOG_ERR, "no -S arg in shared memory\n");
525 return SNMP_ERR_GENERR;
526 }
527 DEBUGMSGTL(("varnish_mib:vcli", "-S '%s'\n", S_arg));
528 *secret = S_arg;
529 }
530 return 0;
531}
488 532
489 conn->fd = open_socket(&vcli_sa, T_arg); 533int
490 free(T_arg); 534vcli_connect(struct vsm *vsm, struct vcli_conn *conn)
491 if (conn->fd == -1) { 535{
492 free(S_arg); 536 vcli_sockaddr_t addr = NULL;
493 return SNMP_ERR_GENERR; 537 char *secret = NULL;
494 } 538 int rc;
495 539
496 DEBUGMSGTL(("varnish_mib:vcli", "-S '%s'\n", S_arg)); 540 rc = parse_connection(vsm, &addr, &secret);
497 conn->secret = S_arg; 541 if (rc == 0) {
498 542 memset(conn, 0, sizeof(*conn));
499 if (vcli_handshake(conn)) { 543 conn->fd = open_socket(addr);
500 vcli_disconnect(conn); 544 if (conn->fd == -1)
501 return SNMP_ERR_GENERR; 545 rc = SNMP_ERR_GENERR;
546 else {
547 conn->secret = secret;
548 secret = NULL;
549 if (vcli_handshake(conn)) {
550 vcli_disconnect(conn);
551 rc = SNMP_ERR_GENERR;
552 }
553 }
502 } 554 }
503 return SNMP_ERR_NOERROR; 555 free(addr);
556 free(secret);
557 return rc;
504} 558}
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 @@
1struct vcli_sockaddr;
2typedef struct vcli_sockaddr *vcli_sockaddr_t;
3
4vcli_sockaddr_t vcli_parse_sockaddr(char const *arg);
5
6typedef struct vcli_conn {
7 int fd;
8 char *secret;
9 int resp;
10 char *base;
11 size_t bufmax;
12 size_t bufsize;
13} vcli_conn_t;
14
15int vcli_write(vcli_conn_t *conn);
16int vcli_read_response(vcli_conn_t *conn);
17int vcli_vasprintf(vcli_conn_t *conn, const char *fmt, va_list ap);
18int vcli_asprintf(vcli_conn_t *conn, const char *fmt, ...);
19void vcli_disconnect(vcli_conn_t *conn);
20int vcli_connect(struct vsm *vsm, vcli_conn_t *conn);
21

Return to:

Send suggestions and report system problems to the System administrator.