client_db.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:9k
- /*
- * $Id: client_db.c,v 1.43 1998/12/05 00:54:18 wessels Exp $
- *
- * DEBUG: section 0 Client Database
- * AUTHOR: Duane Wessels
- *
- * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from the
- * Internet community. Development is led by Duane Wessels of the
- * National Laboratory for Applied Network Research and funded by the
- * National Science Foundation. Squid is Copyrighted (C) 1998 by
- * Duane Wessels and the University of California San Diego. Please
- * see the COPYRIGHT file for full details. Squid incorporates
- * software developed and/or copyrighted by other sources. Please see
- * the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
- #include "squid.h"
- static hash_table *client_table = NULL;
- static ClientInfo *clientdbAdd(struct in_addr addr);
- static FREE clientdbFreeItem;
- static ClientInfo *
- clientdbAdd(struct in_addr addr)
- {
- ClientInfo *c;
- c = memAllocate(MEM_CLIENT_INFO);
- c->key = xstrdup(inet_ntoa(addr));
- c->addr = addr;
- hash_join(client_table, (hash_link *) c);
- Counter.client_http.clients++;
- return c;
- }
- void
- clientdbInit(void)
- {
- if (client_table)
- return;
- client_table = hash_create((HASHCMP *) strcmp, 467, hash_string);
- cachemgrRegister("client_list",
- "Cache Client List",
- clientdbDump,
- 0, 1);
- }
- void
- clientdbUpdate(struct in_addr addr, log_type ltype, protocol_t p, size_t size)
- {
- char *key;
- ClientInfo *c;
- if (!Config.onoff.client_db)
- return;
- key = inet_ntoa(addr);
- c = (ClientInfo *) hash_lookup(client_table, key);
- if (c == NULL)
- c = clientdbAdd(addr);
- if (c == NULL)
- debug_trap("clientdbUpdate: Failed to add entry");
- if (p == PROTO_HTTP) {
- c->Http.n_requests++;
- c->Http.result_hist[ltype]++;
- kb_incr(&c->Http.kbytes_out, size);
- if (isTcpHit(ltype))
- kb_incr(&c->Http.hit_kbytes_out, size);
- } else if (p == PROTO_ICP) {
- c->Icp.n_requests++;
- c->Icp.result_hist[ltype]++;
- kb_incr(&c->Icp.kbytes_out, size);
- if (LOG_UDP_HIT == ltype)
- kb_incr(&c->Icp.hit_kbytes_out, size);
- }
- }
- #define CUTOFF_SECONDS 3600
- int
- clientdbCutoffDenied(struct in_addr addr)
- {
- char *key;
- int NR;
- int ND;
- double p;
- ClientInfo *c;
- if (!Config.onoff.client_db)
- return 0;
- key = inet_ntoa(addr);
- c = (ClientInfo *) hash_lookup(client_table, key);
- if (c == NULL)
- return 0;
- /*
- * If we are in a cutoff window, we don't send a reply
- */
- if (squid_curtime - c->cutoff.time < CUTOFF_SECONDS)
- return 1;
- /*
- * Calculate the percent of DENIED replies since the last
- * cutoff time.
- */
- NR = c->Icp.n_requests - c->cutoff.n_req;
- if (NR < 150)
- NR = 150;
- ND = c->Icp.result_hist[LOG_UDP_DENIED] - c->cutoff.n_denied;
- p = 100.0 * ND / NR;
- if (p < 95.0)
- return 0;
- debug(1, 0) ("WARNING: Probable misconfigured neighbor at %sn", key);
- debug(1, 0) ("WARNING: %d of the last %d ICP replies are DENIEDn", ND, NR);
- debug(1, 0) ("WARNING: No replies will be sent for the next %d secondsn",
- CUTOFF_SECONDS);
- c->cutoff.time = squid_curtime;
- c->cutoff.n_req = c->Icp.n_requests;
- c->cutoff.n_denied = c->Icp.result_hist[LOG_UDP_DENIED];
- return 1;
- }
- void
- clientdbDump(StoreEntry * sentry)
- {
- ClientInfo *c;
- log_type l;
- int icp_total = 0;
- int icp_hits = 0;
- int http_total = 0;
- int http_hits = 0;
- storeAppendPrintf(sentry, "Cache Clients:n");
- hash_first(client_table);
- while ((c = (ClientInfo *) hash_next(client_table))) {
- storeAppendPrintf(sentry, "Address: %sn", c->key);
- storeAppendPrintf(sentry, "Name: %sn", fqdnFromAddr(c->addr));
- storeAppendPrintf(sentry, " ICP Requests %dn",
- c->Icp.n_requests);
- for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) {
- if (c->Icp.result_hist[l] == 0)
- continue;
- icp_total += c->Icp.result_hist[l];
- if (LOG_UDP_HIT == l)
- icp_hits += c->Icp.result_hist[l];
- storeAppendPrintf(sentry,
- " %-20.20s %7d %3d%%n",
- log_tags[l],
- c->Icp.result_hist[l],
- percent(c->Icp.result_hist[l], c->Icp.n_requests));
- }
- storeAppendPrintf(sentry, " HTTP Requests %dn",
- c->Http.n_requests);
- for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) {
- if (c->Http.result_hist[l] == 0)
- continue;
- http_total += c->Http.result_hist[l];
- if (isTcpHit(l))
- http_hits += c->Http.result_hist[l];
- storeAppendPrintf(sentry,
- " %-20.20s %7d %3d%%n",
- log_tags[l],
- c->Http.result_hist[l],
- percent(c->Http.result_hist[l], c->Http.n_requests));
- }
- storeAppendPrintf(sentry, "n");
- }
- storeAppendPrintf(sentry, "TOTALSn");
- storeAppendPrintf(sentry, "ICP : %d Queries, %d Hits (%3d%%)n",
- icp_total, icp_hits, percent(icp_hits, icp_total));
- storeAppendPrintf(sentry, "HTTP: %d Requests, %d Hits (%3d%%)n",
- http_total, http_hits, percent(http_hits, http_total));
- }
- static void
- clientdbFreeItem(void *data)
- {
- ClientInfo *c = data;
- safe_free(c->key);
- memFree(c, MEM_CLIENT_INFO);
- }
- void
- clientdbFreeMemory(void)
- {
- hashFreeItems(client_table, clientdbFreeItem);
- hashFreeMemory(client_table);
- client_table = NULL;
- }
- #if SQUID_SNMP
- int
- meshCtblGetRowFn(oid * New, oid * Oid)
- {
- ClientInfo *c = NULL;
- if (!Oid[0] && !Oid[1] && !Oid[2] && !Oid[3]) {
- hash_first(client_table);
- c = (ClientInfo *) hash_next(client_table);
- hash_last(client_table);
- } else {
- char key[15];
- snprintf(key, sizeof(key), "%d.%d.%d.%d", Oid[0], Oid[1], Oid[2], Oid[3]);
- c = (ClientInfo *) hash_lookup(client_table, key);
- if (NULL != c)
- c = c->next;
- }
- if (!c)
- return 0;
- addr2oid(c->addr, New);
- return 1;
- }
- variable_list *
- snmp_meshCtblFn(variable_list * Var, snint * ErrP)
- {
- variable_list *Answer;
- static char key[15];
- ClientInfo *c = NULL;
- int aggr = 0;
- log_type l;
- Answer = snmp_var_new(Var->name, Var->name_length);
- *ErrP = SNMP_ERR_NOERROR;
- snprintf(key, sizeof(key), "%d.%d.%d.%d", Var->name[LEN_SQ_NET + 3], Var->name[LEN_SQ_NET + 4],
- Var->name[LEN_SQ_NET + 5], Var->name[LEN_SQ_NET + 6]);
- debug(49, 5) ("snmp_meshCtblFn: [%s] requested!n", key);
- c = (ClientInfo *) hash_lookup(client_table, key);
- if (c == NULL) {
- debug(49, 5) ("snmp_meshCtblFn: not found.n");
- *ErrP = SNMP_ERR_NOSUCHNAME;
- snmp_var_free(Answer);
- return (NULL);
- }
- switch (Var->name[LEN_SQ_NET + 2]) {
- case MESH_CTBL_ADDR:
- Answer->type = SMI_IPADDRESS;
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- *(Answer->val.integer) = (snint) c->addr.s_addr;
- break;
- case MESH_CTBL_HTBYTES:
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) c->Http.kbytes_out.kb;
- break;
- case MESH_CTBL_HTREQ:
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) c->Http.n_requests;
- break;
- case MESH_CTBL_HTHITS:
- aggr = 0;
- for (l = 0; l < LOG_TYPE_MAX; l++) {
- if (isTcpHit(l))
- aggr += c->Http.result_hist[l];
- }
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) aggr;
- break;
- case MESH_CTBL_HTHITBYTES:
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) c->Http.hit_kbytes_out.kb;
- break;
- case MESH_CTBL_ICPBYTES:
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) c->Icp.kbytes_out.kb;
- break;
- case MESH_CTBL_ICPREQ:
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) c->Icp.n_requests;
- break;
- case MESH_CTBL_ICPHITS:
- aggr = c->Icp.result_hist[LOG_UDP_HIT];
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) aggr;
- break;
- case MESH_CTBL_ICPHITBYTES:
- Answer->val_len = sizeof(snint);
- Answer->val.integer = xmalloc(Answer->val_len);
- Answer->type = SMI_COUNTER32;
- *(Answer->val.integer) = (snint) c->Icp.hit_kbytes_out.kb;
- break;
- default:
- *ErrP = SNMP_ERR_NOSUCHNAME;
- snmp_var_free(Answer);
- debug(49, 5) ("snmp_meshCtblFn: illegal column.n");
- return (NULL);
- }
- return Answer;
- }
- #endif /*SQUID_SNMP */