diff options
Diffstat (limited to 'src/ban.c')
-rw-r--r-- | src/ban.c | 191 |
1 files changed, 189 insertions, 2 deletions
@@ -18,2 +18,3 @@ | |||
18 | #include "varnish_mib.h" | 18 | #include "varnish_mib.h" |
19 | #include <ctype.h> | ||
19 | 20 | ||
@@ -52,3 +53,3 @@ varnish_ban(netsnmp_agent_request_info *reqinfo, | |||
52 | expr[len] = 0; | 53 | expr[len] = 0; |
53 | DEBUGMSGTL(("vcli_mib", "ban %s\n", expr)); | 54 | DEBUGMSGTL(("varnish_ban", "setting ban %s\n", expr)); |
54 | rc = vcli_connect(vd, &conn); | 55 | rc = vcli_connect(vd, &conn); |
@@ -56,3 +57,3 @@ varnish_ban(netsnmp_agent_request_info *reqinfo, | |||
56 | rc = send_ban_cmd(&conn, expr); | 57 | rc = send_ban_cmd(&conn, expr); |
57 | vcli_disconnect(&conn); | 58 | vcli_disconnect(&conn); |
58 | } | 59 | } |
@@ -61,2 +62,188 @@ varnish_ban(netsnmp_agent_request_info *reqinfo, | |||
61 | } | 62 | } |
63 | |||
64 | unsigned banTable_timeout = 60; | ||
62 | 65 | ||
66 | /* | ||
67 | * create a new row in the table | ||
68 | */ | ||
69 | static struct banTable_entry * | ||
70 | create_entry(netsnmp_tdata *table_data, long idx, struct banTable_entry *ent) | ||
71 | { | ||
72 | struct banTable_entry *entry; | ||
73 | netsnmp_tdata_row *row; | ||
74 | |||
75 | entry = SNMP_MALLOC_TYPEDEF(struct banTable_entry); | ||
76 | if (!entry) | ||
77 | return NULL; | ||
78 | |||
79 | row = netsnmp_tdata_create_row(); | ||
80 | if (!row) { | ||
81 | SNMP_FREE(entry); | ||
82 | return NULL; | ||
83 | } | ||
84 | row->data = entry; | ||
85 | *entry = *ent; | ||
86 | |||
87 | entry->banIndex = idx; | ||
88 | netsnmp_tdata_row_add_index(row, ASN_INTEGER, | ||
89 | &entry->banIndex, | ||
90 | sizeof(entry->banIndex)); | ||
91 | if (table_data) | ||
92 | netsnmp_tdata_add_row(table_data, row); | ||
93 | return entry; | ||
94 | } | ||
95 | |||
96 | #define TMSEC(t) (((t)->tm_hour * 60 + (t)->tm_min) * 60 + (t)->tm_sec) | ||
97 | |||
98 | static int | ||
99 | utc_offset (void) | ||
100 | { | ||
101 | time_t t = time (NULL); | ||
102 | struct tm ltm = *localtime (&t); | ||
103 | struct tm gtm = *gmtime (&t); | ||
104 | int d = TMSEC (<m) - TMSEC (>m); | ||
105 | if (!(ltm.tm_year = gtm.tm_year && ltm.tm_mon == gtm.tm_mon)) | ||
106 | d += 86400; | ||
107 | return d / 60; | ||
108 | } | ||
109 | |||
110 | /* Refill the ban table */ | ||
111 | int | ||
112 | banTable_load(netsnmp_cache *cache, void *vmagic) | ||
113 | { | ||
114 | netsnmp_tdata *table = (netsnmp_tdata *) vmagic; | ||
115 | long idx = 0; | ||
116 | int rc; | ||
117 | struct vcli_conn conn; | ||
118 | char *p; | ||
119 | struct VSM_data *vd; | ||
120 | |||
121 | DEBUGMSGTL(("varnish_ban", "reloading ban table")); | ||
122 | vd = varnish_get_vsm_data(); | ||
123 | rc = vcli_connect(vd, &conn); | ||
124 | if (rc != SNMP_ERR_NOERROR) | ||
125 | return rc; | ||
126 | |||
127 | if (vcli_asprintf(&conn, "ban.list\n") || vcli_write(&conn)) | ||
128 | return SNMP_ERR_GENERR; | ||
129 | |||
130 | if (vcli_read_response(&conn)) | ||
131 | return SNMP_ERR_GENERR; | ||
132 | |||
133 | if (conn.resp != CLIS_OK) { | ||
134 | snmp_log(LOG_ERR, "ban.list command rejected: %u %s\n", | ||
135 | conn.resp, conn.base); | ||
136 | return SNMP_ERR_GENERR; | ||
137 | } | ||
138 | |||
139 | p = conn.base; | ||
140 | while (p < conn.base + conn.bufsize) { | ||
141 | char *q; | ||
142 | struct banTable_entry e; | ||
143 | struct tm *tm; | ||
144 | time_t t; | ||
145 | int n; | ||
146 | |||
147 | if (*p == '\n') { | ||
148 | ++p; | ||
149 | continue; | ||
150 | } | ||
151 | e.banIndex = idx; | ||
152 | t = strtoul(p, &q, 10); | ||
153 | if (*q != '.') { | ||
154 | p = strchr(p, '\n'); | ||
155 | if (!p) | ||
156 | break; | ||
157 | continue; | ||
158 | } | ||
159 | ++q; | ||
160 | |||
161 | e.banTime_len = 11; | ||
162 | e.banTime = malloc(e.banTime_len + 1); | ||
163 | if (!e.banTime) { | ||
164 | vcli_disconnect(&conn); | ||
165 | snmp_log(LOG_ERR, "out of memory\n"); | ||
166 | return SNMP_ERR_GENERR; | ||
167 | } | ||
168 | tm = localtime(&t); | ||
169 | /* A date-time specification. | ||
170 | |||
171 | field octets contents range | ||
172 | ----- ------ -------- ----- | ||
173 | 1 1-2 year* 0..65536 | ||
174 | 2 3 month 1..12 | ||
175 | 3 4 day 1..31 | ||
176 | 4 5 hour 0..23 | ||
177 | 5 6 minutes 0..59 | ||
178 | 6 7 seconds 0..60 | ||
179 | (use 60 for leap-second) | ||
180 | 7 8 deci-seconds 0..9 | ||
181 | 8 9 direction from UTC '+' / '-' | ||
182 | 9 10 hours from UTC* 0..13 | ||
183 | 10 11 minutes from UTC 0..59 | ||
184 | |||
185 | * Notes: | ||
186 | - the value of year is in network-byte order | ||
187 | */ | ||
188 | n = tm->tm_year % 100; | ||
189 | e.banTime[0] = n >> 8; | ||
190 | e.banTime[1] = n & 0xff; | ||
191 | e.banTime[2] = tm->tm_mon + 1; | ||
192 | e.banTime[3] = tm->tm_mday; | ||
193 | e.banTime[4] = tm->tm_hour; | ||
194 | e.banTime[5] = tm->tm_min; | ||
195 | e.banTime[6] = tm->tm_sec; | ||
196 | e.banTime[7] = *q - '0'; | ||
197 | n = utc_offset(); | ||
198 | if (n < 0) { | ||
199 | e.banTime[8] = '-'; | ||
200 | n = - n; | ||
201 | } else | ||
202 | e.banTime[8] = '+'; | ||
203 | e.banTime[9] = n / 60; | ||
204 | e.banTime[10] = n % 60; | ||
205 | |||
206 | while (*q && isdigit(*q)) | ||
207 | ++q; | ||
208 | while (*q && isspace(*q)) | ||
209 | ++q; | ||
210 | e.banRefCount = strtoul(q, &q, 10); | ||
211 | |||
212 | while (*q && isspace(*q)) | ||
213 | ++q; | ||
214 | |||
215 | e.banExpression_len = strcspn(q, "\n"); | ||
216 | e.banExpression = malloc(e.banExpression_len); | ||
217 | if (!e.banExpression) { | ||
218 | vcli_disconnect(&conn); | ||
219 | free(e.banTime); | ||
220 | snmp_log(LOG_ERR, "out of memory\n"); | ||
221 | return SNMP_ERR_GENERR; | ||
222 | } | ||
223 | memcpy(e.banExpression, q, e.banExpression_len); | ||
224 | |||
225 | create_entry(table, idx, &e); | ||
226 | ++idx; | ||
227 | q += e.banExpression_len; | ||
228 | p = q; | ||
229 | } | ||
230 | vcli_disconnect(&conn); | ||
231 | DEBUGMSGTL(("varnish_ban", "loaded %ld ban entries", idx)); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | void | ||
236 | banTable_free(netsnmp_cache *cache, void *vmagic) | ||
237 | { | ||
238 | netsnmp_tdata *table = (netsnmp_tdata *) vmagic; | ||
239 | netsnmp_tdata_row *row; | ||
240 | |||
241 | DEBUGMSGTL(("varnish_ban", "freeing ban table")); | ||
242 | while ((row = netsnmp_tdata_row_first(table))) { | ||
243 | struct banTable_entry *entry = row->data; | ||
244 | free(entry->banExpression); | ||
245 | free(entry->banTime); | ||
246 | SNMP_FREE(entry); | ||
247 | netsnmp_tdata_remove_and_delete_row(table, row); | ||
248 | } | ||
249 | } | ||