]> git.ipfire.org Git - thirdparty/squid.git/blame - src/client_db.cc
We only need to return IF the callback is made. This should
[thirdparty/squid.git] / src / client_db.cc
CommitLineData
8eb58c9c 1
516350ca 2/*
6f47fbc7 3 * $Id: client_db.cc,v 1.27 1998/03/25 09:23:19 kostas Exp $
516350ca 4 *
f43e2ec2 5 * DEBUG: section 0 Client Database
516350ca 6 * AUTHOR: Duane Wessels
7 *
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * --------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by
14 * the National Science Foundation.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31
c41d4b6d 32#include "squid.h"
33
365e5b34 34static hash_table *client_table = NULL;
f5b8bbc4 35static ClientInfo *clientdbAdd(struct in_addr addr);
c41d4b6d 36
37static ClientInfo *
38clientdbAdd(struct in_addr addr)
39{
40 ClientInfo *c;
59c4d35b 41 c = memAllocate(MEM_CLIENT_INFO);
c41d4b6d 42 c->key = xstrdup(inet_ntoa(addr));
43 c->addr = addr;
44 hash_join(client_table, (hash_link *) c);
c41d4b6d 45 return c;
46}
47
48void
49clientdbInit(void)
50{
19054954 51 if (client_table)
52 return;
aa9e2cab 53 client_table = hash_create((HASHCMP *) strcmp, 467, hash_string);
22f3fd98 54 cachemgrRegister("client_list",
55 "Cache Client List",
56 clientdbDump,
57 0);
c41d4b6d 58}
59
60void
81d0c856 61clientdbUpdate(struct in_addr addr, log_type log_type, protocol_t p, size_t size)
c41d4b6d 62{
429fdbec 63 char *key;
64 ClientInfo *c;
17a0a4ee 65 if (!Config.onoff.client_db)
429fdbec 66 return;
67 key = inet_ntoa(addr);
68 c = (ClientInfo *) hash_lookup(client_table, key);
c41d4b6d 69 if (c == NULL)
70 c = clientdbAdd(addr);
71 if (c == NULL)
72 debug_trap("clientdbUpdate: Failed to add entry");
812ed90c 73 if (p == PROTO_HTTP) {
985b7fb7 74 c->Http.n_requests++;
81d0c856 75 kb_incr(&(c->Http.kbytes_out), size);
985b7fb7 76 c->Http.result_hist[log_type]++;
812ed90c 77 } else if (p == PROTO_ICP) {
985b7fb7 78 c->Icp.n_requests++;
81d0c856 79 kb_incr(&(c->Icp.kbytes_out), size);
985b7fb7 80 c->Icp.result_hist[log_type]++;
81 }
81d0c856 82 switch (log_type) {
83 case LOG_TCP_HIT:
84 case LOG_TCP_REFRESH_HIT:
85 case LOG_TCP_REFRESH_FAIL_HIT:
86 case LOG_TCP_IMS_HIT:
87 case LOG_TCP_NEGATIVE_HIT:
88 case LOG_TCP_MEM_HIT:
89 case LOG_UDP_HIT:
6f47fbc7 90 if (p == PROTO_ICP)
91 kb_incr(&(c->Icp.hit_kbytes_out), size);
81d0c856 92 else
6f47fbc7 93 kb_incr(&(c->Http.hit_kbytes_out), size);
81d0c856 94 break;
95 default:
96 }
c41d4b6d 97}
98
e711a2ff 99#define CUTOFF_SECONDS 3600
c41d4b6d 100int
e711a2ff 101clientdbCutoffDenied(struct in_addr addr)
c41d4b6d 102{
429fdbec 103 char *key;
e711a2ff 104 int NR;
105 int ND;
106 double p;
429fdbec 107 ClientInfo *c;
59c4d35b 108 if (!Config.onoff.client_db)
429fdbec 109 return 0;
110 key = inet_ntoa(addr);
111 c = (ClientInfo *) hash_lookup(client_table, key);
c41d4b6d 112 if (c == NULL)
113 return 0;
e711a2ff 114 /*
115 * If we are in a cutoff window, we don't send a reply
116 */
117 if (squid_curtime - c->cutoff.time < CUTOFF_SECONDS)
118 return 1;
119 /*
120 * Calculate the percent of DENIED replies since the last
121 * cutoff time.
122 */
123 NR = c->Icp.n_requests - c->cutoff.n_req;
124 if (NR < 150)
125 NR = 150;
126 ND = c->Icp.result_hist[LOG_UDP_DENIED] - c->cutoff.n_denied;
127 p = 100.0 * ND / NR;
128 if (p < 95.0)
129 return 0;
59c4d35b 130 debug(1, 0) ("WARNING: Probable misconfigured neighbor at %s\n", key);
131 debug(1, 0) ("WARNING: %d of the last %d ICP replies are DENIED\n", ND, NR);
132 debug(1, 0) ("WARNING: No replies will be sent for the next %d seconds\n",
e711a2ff 133 CUTOFF_SECONDS);
134 c->cutoff.time = squid_curtime;
135 c->cutoff.n_req = c->Icp.n_requests;
136 c->cutoff.n_denied = c->Icp.result_hist[LOG_UDP_DENIED];
137 return 1;
c41d4b6d 138}
139
e711a2ff 140
8eb58c9c 141void
c41d4b6d 142clientdbDump(StoreEntry * sentry)
143{
144 ClientInfo *c;
145 log_type l;
15576b6a 146 storeAppendPrintf(sentry, "Cache Clients:\n");
c41d4b6d 147 c = (ClientInfo *) hash_first(client_table);
148 while (c) {
15576b6a 149 storeAppendPrintf(sentry, "Address: %s\n", c->key);
150 storeAppendPrintf(sentry, "Name: %s\n", fqdnFromAddr(c->addr));
151 storeAppendPrintf(sentry, " ICP Requests %d\n",
985b7fb7 152 c->Icp.n_requests);
9b312a19 153 for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) {
985b7fb7 154 if (c->Icp.result_hist[l] == 0)
155 continue;
156 storeAppendPrintf(sentry,
15576b6a 157 " %-20.20s %7d %3d%%\n",
985b7fb7 158 log_tags[l],
159 c->Icp.result_hist[l],
160 percent(c->Icp.result_hist[l], c->Icp.n_requests));
161 }
15576b6a 162 storeAppendPrintf(sentry, " HTTP Requests %d\n",
985b7fb7 163 c->Http.n_requests);
9b312a19 164 for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) {
985b7fb7 165 if (c->Http.result_hist[l] == 0)
c41d4b6d 166 continue;
167 storeAppendPrintf(sentry,
15576b6a 168 " %-20.20s %7d %3d%%\n",
c41d4b6d 169 log_tags[l],
985b7fb7 170 c->Http.result_hist[l],
171 percent(c->Http.result_hist[l], c->Http.n_requests));
c41d4b6d 172 }
15576b6a 173 storeAppendPrintf(sentry, "\n");
c41d4b6d 174 c = (ClientInfo *) hash_next(client_table);
175 }
c41d4b6d 176}
83394596 177
178void
179clientdbFreeMemory(void)
180{
181 ClientInfo *c;
182 ClientInfo **C;
183 int i = 0;
184 int j;
185 int n = memInUse(MEM_CLIENT_INFO);
186 C = xcalloc(n, sizeof(ClientInfo *));
187 c = (ClientInfo *) hash_first(client_table);
188 while (c && i < n) {
6f47fbc7 189 *(C + i) = c;
190 i++;
191 c = (ClientInfo *) hash_next(client_table);
83394596 192 }
193 for (j = 0; j < i; j++) {
6f47fbc7 194 c = *(C + j);
195 memFree(MEM_CLIENT_INFO, c);
83394596 196 }
197 xfree(C);
198 hashFreeMemory(client_table);
199 client_table = NULL;
200}
81d0c856 201
202#if SQUID_SNMP
6f47fbc7 203int
204meshCtblGetRowFn(oid * New, oid * Oid)
81d0c856 205{
6f47fbc7 206 ClientInfo *c = NULL;
207 static char key[15];
81d0c856 208
6f47fbc7 209 if (!Oid[0] && !Oid[1] && !Oid[2] && !Oid[3])
210 c = (ClientInfo *) hash_first(client_table);
211 else {
212 snprintf(key, 15, "%d.%d.%d.%d", Oid[0], Oid[1], Oid[2], Oid[3]);
213 c = (ClientInfo *) hash_lookup(client_table, key);
214 if (!c)
215 return 0;
216 c = (ClientInfo *) hash_next(client_table);
217 }
218 if (!c)
219 return 0;
220 addr2oid(c->addr, New);
221 return 1;
81d0c856 222}
223
224
225variable_list *
6f47fbc7 226snmp_meshCtblFn(variable_list * Var, snint * ErrP)
81d0c856 227{
228 variable_list *Answer;
229 static char key[15];
230 ClientInfo *c = NULL;
6f47fbc7 231 int aggr = 0;
81d0c856 232#if 0
233 int cnt;
234#endif
235
236 Answer = snmp_var_new(Var->name, Var->name_length);
237 *ErrP = SNMP_ERR_NOERROR;
238
6f47fbc7 239 snprintf(key, 15, "%d.%d.%d.%d", Var->name[11], Var->name[12],
240 Var->name[13], Var->name[14]);
81d0c856 241 debug(49, 5) ("snmp_meshCtblFn: [%s] requested!\n", key);
242 c = (ClientInfo *) hash_lookup(client_table, key);
243#if 0
6f47fbc7 244 c = (ClientInfo *) hash_first(client_table);
81d0c856 245 cnt = Var->name[11];
246 debug(49, 5) ("snmp_meshCtblFn: we want .x.%d\n", Var->name[10]);
247 while (--cnt)
6f47fbc7 248 if (!(c = (ClientInfo *) hash_next(client_table)));
81d0c856 249#endif
250 if (c == NULL) {
6f47fbc7 251 debug(49, 5) ("snmp_meshCtblFn: not found.\n");
252 *ErrP = SNMP_ERR_NOSUCHNAME;
253 snmp_var_free(Answer);
254 return (NULL);
81d0c856 255 }
256 switch (Var->name[10]) {
257 case MESH_CTBL_ADDR:
6f47fbc7 258 Answer->type = SMI_IPADDRESS;
259 Answer->val_len = sizeof(snint);
260 Answer->val.integer = xmalloc(Answer->val_len);
261 *(Answer->val.integer) = (snint) c->addr.s_addr;
262 break;
81d0c856 263 case MESH_CTBL_HTBYTES:
6f47fbc7 264 Answer->val_len = sizeof(snint);
265 Answer->val.integer = xmalloc(Answer->val_len);
266 Answer->type = ASN_INTEGER;
267 *(Answer->val.integer) = (snint) c->Http.kbytes_out.kb;
268 break;
81d0c856 269 case MESH_CTBL_HTREQ:
6f47fbc7 270 Answer->val_len = sizeof(snint);
271 Answer->val.integer = xmalloc(Answer->val_len);
272 Answer->type = ASN_INTEGER;
273 *(Answer->val.integer) = (snint) c->Http.n_requests;
274 break;
81d0c856 275 case MESH_CTBL_HTHITS:
6f47fbc7 276 aggr = c->Http.result_hist[LOG_TCP_HIT] +
277 c->Http.result_hist[LOG_TCP_REFRESH_HIT] +
278 c->Http.result_hist[LOG_TCP_REFRESH_FAIL_HIT] +
279 c->Http.result_hist[LOG_TCP_REFRESH_FAIL_HIT] +
280 c->Http.result_hist[LOG_TCP_IMS_HIT] +
281 c->Http.result_hist[LOG_TCP_NEGATIVE_HIT] +
282 c->Http.result_hist[LOG_TCP_MEM_HIT] +
283 c->Http.result_hist[LOG_UDP_HIT];
284 Answer->val_len = sizeof(snint);
285 Answer->val.integer = xmalloc(Answer->val_len);
286 Answer->type = ASN_INTEGER;
287 *(Answer->val.integer) = (snint) aggr;
288 break;
81d0c856 289 case MESH_CTBL_HTHITBYTES:
6f47fbc7 290 Answer->val_len = sizeof(snint);
291 Answer->val.integer = xmalloc(Answer->val_len);
292 Answer->type = ASN_INTEGER;
293 *(Answer->val.integer) = (snint) c->Http.hit_kbytes_out.kb;
294 break;
81d0c856 295 case MESH_CTBL_ICPBYTES:
6f47fbc7 296 Answer->val_len = sizeof(snint);
297 Answer->val.integer = xmalloc(Answer->val_len);
298 Answer->type = ASN_INTEGER;
299 *(Answer->val.integer) = (snint) c->Icp.kbytes_out.kb;
300 break;
81d0c856 301 case MESH_CTBL_ICPREQ:
6f47fbc7 302 Answer->val_len = sizeof(snint);
303 Answer->val.integer = xmalloc(Answer->val_len);
304 Answer->type = ASN_INTEGER;
305 *(Answer->val.integer) = (snint) c->Icp.n_requests;
306 break;
81d0c856 307 case MESH_CTBL_ICPHITS:
6f47fbc7 308 aggr = c->Icp.result_hist[LOG_TCP_HIT] +
309 c->Icp.result_hist[LOG_TCP_REFRESH_HIT] +
310 c->Icp.result_hist[LOG_TCP_REFRESH_FAIL_HIT] +
311 c->Icp.result_hist[LOG_TCP_REFRESH_FAIL_HIT] +
312 c->Icp.result_hist[LOG_TCP_IMS_HIT] +
313 c->Icp.result_hist[LOG_TCP_NEGATIVE_HIT] +
314 c->Icp.result_hist[LOG_TCP_MEM_HIT] +
315 c->Icp.result_hist[LOG_UDP_HIT];
316 Answer->val_len = sizeof(snint);
317 Answer->val.integer = xmalloc(Answer->val_len);
318 Answer->type = ASN_INTEGER;
319 *(Answer->val.integer) = (snint) aggr;
320 break;
81d0c856 321 case MESH_CTBL_ICPHITBYTES:
6f47fbc7 322 Answer->val_len = sizeof(snint);
323 Answer->val.integer = xmalloc(Answer->val_len);
324 Answer->type = ASN_INTEGER;
325 *(Answer->val.integer) = (snint) c->Icp.hit_kbytes_out.kb;
326 break;
81d0c856 327
328 default:
6f47fbc7 329 *ErrP = SNMP_ERR_NOSUCHNAME;
330 snmp_var_free(Answer);
331 debug(49, 5) ("snmp_meshCtblFn: illegal column.\n");
332 return (NULL);
81d0c856 333 }
334 return Answer;
335}
336
337#endif