3 * $Id: ipcache.cc,v 1.260 2007/05/18 06:41:24 amosjeffries Exp $
5 * DEBUG: section 14 IP Cache
6 * AUTHOR: Harvest Derived
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
39 #include "CacheManager.h"
40 #include "SquidTime.h"
44 typedef struct _ipcache_entry ipcache_entry
;
48 hash_link hash
; /* must be first */
56 struct timeval request_time
;
63 unsigned int negcached
:
66 unsigned int fromhosts
:
84 static dlink_list lru_list
;
86 static FREE ipcacheFreeEntry
;
88 static HLPCB ipcacheHandleReply
;
90 static IDNSCB ipcacheHandleReply
;
92 static IPH dummy_handler
;
93 static int ipcacheExpiredEntry(ipcache_entry
*);
94 static int ipcache_testname(void);
96 static int ipcacheParse(ipcache_entry
*, const char *buf
);
98 static int ipcacheParse(ipcache_entry
*, rfc1035_rr
*, int, const char *error
);
100 static ipcache_entry
*ipcache_get(const char *);
101 static void ipcacheLockEntry(ipcache_entry
*);
102 static void ipcacheStatPrint(ipcache_entry
*, StoreEntry
*);
103 static void ipcacheUnlockEntry(ipcache_entry
*);
104 static void ipcacheRelease(ipcache_entry
*);
106 static ipcache_addrs static_addrs
;
107 static hash_table
*ip_table
= NULL
;
109 static long ipcache_low
= 180;
110 static long ipcache_high
= 200;
112 #if LIBRESOLV_DNS_TTL_HACK
113 extern int _dns_ttl_
;
117 ipcache_testname(void)
120 debugs(14, 1, "Performing DNS Tests...");
122 if ((w
= Config
.dns_testname_list
) == NULL
)
125 for (; w
; w
= w
->next
) {
126 if (gethostbyname(w
->key
) != NULL
)
133 /* removes the given ipcache entry */
135 ipcacheRelease(ipcache_entry
* i
)
137 debugs(14, 3, "ipcacheRelease: Releasing entry for '" << (const char *) i
->hash
.key
<< "'");
139 hash_remove_link(ip_table
, (hash_link
*) i
);
140 dlinkDelete(&i
->lru
, &lru_list
);
144 static ipcache_entry
*
145 ipcache_get(const char *name
)
147 if (ip_table
!= NULL
)
148 return (ipcache_entry
*) hash_lookup(ip_table
, name
);
154 ipcacheExpiredEntry(ipcache_entry
* i
)
156 /* all static entries are locked, so this takes care of them too */
161 if (i
->addrs
.count
== 0)
162 if (0 == i
->flags
.negcached
)
165 if (i
->expires
> squid_curtime
)
172 ipcache_purgelru(void *voidnotused
)
175 dlink_node
*prev
= NULL
;
178 eventAdd("ipcache_purgelru", ipcache_purgelru
, NULL
, 10.0, 1);
180 for (m
= lru_list
.tail
; m
; m
= prev
) {
181 if (memInUse(MEM_IPCACHE_ENTRY
) < ipcache_low
)
186 i
= (ipcache_entry
*)m
->data
;
196 debugs(14, 9, "ipcache_purgelru: removed " << removed
<< " entries");
199 /* purges entries added from /etc/hosts (or whatever). */
201 purge_entries_fromhosts(void)
203 dlink_node
*m
= lru_list
.head
;
204 ipcache_entry
*i
= NULL
, *t
;
207 if (i
!= NULL
) { /* need to delay deletion */
208 ipcacheRelease(i
); /* we just override locks */
212 t
= (ipcache_entry
*)m
->data
;
214 if (t
->flags
.fromhosts
)
224 /* create blank ipcache_entry */
225 static ipcache_entry
*
226 ipcacheCreateEntry(const char *name
)
228 static ipcache_entry
*i
;
229 i
= (ipcache_entry
*)memAllocate(MEM_IPCACHE_ENTRY
);
230 i
->hash
.key
= xstrdup(name
);
231 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
236 ipcacheAddEntry(ipcache_entry
* i
)
238 hash_link
*e
= (hash_link
*)hash_lookup(ip_table
, i
->hash
.key
);
241 /* avoid colission */
242 ipcache_entry
*q
= (ipcache_entry
*) e
;
246 hash_join(ip_table
, &i
->hash
);
247 dlinkAdd(i
, &i
->lru
, &lru_list
);
248 i
->lastref
= squid_curtime
;
251 /* walks down the pending list, calling handlers */
253 ipcacheCallback(ipcache_entry
* i
)
255 IPH
*callback
= i
->handler
;
257 i
->lastref
= squid_curtime
;
264 callback
= i
->handler
;
268 if (cbdataReferenceValidDone(i
->handlerData
, &cbdata
)) {
269 dns_error_message
= i
->error_message
;
270 callback(i
->flags
.negcached
? NULL
: &i
->addrs
, cbdata
);
273 ipcacheUnlockEntry(i
);
278 ipcacheParse(ipcache_entry
*i
, const char *inbuf
)
280 LOCAL_ARRAY(char, buf
, DNS_INBUF_SZ
);
285 const char *name
= (const char *)i
->hash
.key
;
286 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
287 i
->flags
.negcached
= 1;
288 safe_free(i
->addrs
.in_addrs
);
289 safe_free(i
->addrs
.bad_mask
);
290 safe_free(i
->error_message
);
294 debugs(14, 1, "ipcacheParse: Got <NULL> reply");
295 i
->error_message
= xstrdup("Internal Error");
299 xstrncpy(buf
, inbuf
, DNS_INBUF_SZ
);
300 debugs(14, 5, "ipcacheParse: parsing: {" << buf
<< "}");
301 token
= strtok(buf
, w_space
);
304 debugs(14, 1, "ipcacheParse: expecting result, got '" << inbuf
<< "'");
306 i
->error_message
= xstrdup("Internal Error");
310 if (0 == strcmp(token
, "$fail")) {
311 token
= strtok(NULL
, "\n");
312 assert(NULL
!= token
);
313 i
->error_message
= xstrdup(token
);
317 if (0 != strcmp(token
, "$addr")) {
318 debugs(14, 1, "ipcacheParse: expecting '$addr', got '" << inbuf
<< "' in response to '" << name
<< "'");
320 i
->error_message
= xstrdup("Internal Error");
324 token
= strtok(NULL
, w_space
);
327 debugs(14, 1, "ipcacheParse: expecting TTL, got '" << inbuf
<< "' in response to '" << name
<< "'");
329 i
->error_message
= xstrdup("Internal Error");
335 while (NULL
!= (token
= strtok(NULL
, w_space
))) {
345 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(ipcount
, sizeof(struct IN_ADDR
));
346 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(ipcount
, sizeof(unsigned char));
348 for (j
= 0, k
= 0; k
< ipcount
; k
++) {
349 if (safe_inet_addr(A
[k
], &i
->addrs
.in_addrs
[j
]))
352 debugs(14, 1, "ipcacheParse: Invalid IP address '" << A
[k
] << "' in response to '" << name
<< "'");
355 i
->addrs
.count
= (unsigned char) j
;
358 if (i
->addrs
.count
<= 0) {
359 debugs(14, 1, "ipcacheParse: No addresses in response to '" << name
<< "'");
363 if (ttl
== 0 || ttl
> Config
.positiveDnsTtl
)
364 ttl
= Config
.positiveDnsTtl
;
366 if (ttl
< Config
.negativeDnsTtl
)
367 ttl
= Config
.negativeDnsTtl
;
369 i
->expires
= squid_curtime
+ ttl
;
371 i
->flags
.negcached
= 0;
373 return i
->addrs
.count
;
378 ipcacheParse(ipcache_entry
*i
, rfc1035_rr
* answers
, int nr
, const char *error_message
)
384 const char *name
= (const char *)i
->hash
.key
;
385 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
386 i
->flags
.negcached
= 1;
387 safe_free(i
->addrs
.in_addrs
);
388 safe_free(i
->addrs
.bad_mask
);
389 safe_free(i
->error_message
);
393 debugs(14, 3, "ipcacheParse: Lookup failed '" << error_message
<< "' for '" << (const char *)i
->hash
.key
<< "'");
394 i
->error_message
= xstrdup(error_message
);
399 debugs(14, 3, "ipcacheParse: No DNS records in response to '" << name
<< "'");
400 i
->error_message
= xstrdup("No DNS records");
406 for (k
= 0; k
< nr
; k
++) {
407 if (answers
[k
].type
!= RFC1035_TYPE_A
)
410 if (answers
[k
]._class
!= RFC1035_CLASS_IN
)
413 if (answers
[k
].rdlength
!= 4) {
414 debugs(14, 1, "ipcacheParse: Invalid IP address in response to '" << name
<< "'");
422 debugs(14, 1, "ipcacheParse: No Address records in response to '" << name
<< "'");
423 i
->error_message
= xstrdup("No Address records");
427 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(na
, sizeof(struct IN_ADDR
));
428 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(na
, sizeof(unsigned char));
430 for (j
= 0, k
= 0; k
< nr
; k
++) {
431 if (answers
[k
]._class
!= RFC1035_CLASS_IN
)
434 if (answers
[k
].type
== RFC1035_TYPE_A
) {
435 if (answers
[k
].rdlength
!= 4)
438 xmemcpy(&i
->addrs
.in_addrs
[j
++], answers
[k
].rdata
, 4);
440 debugs(14, 3, "ipcacheParse: #" << j
- 1 << " " << inet_ntoa(i
->addrs
.in_addrs
[j
- 1]));
442 } else if (answers
[k
].type
!= RFC1035_TYPE_CNAME
)
445 if (ttl
== 0 || (int) answers
[k
].ttl
< ttl
)
446 ttl
= answers
[k
].ttl
;
453 i
->addrs
.count
= (unsigned char) na
;
455 i
->addrs
.count
= 255;
457 if (ttl
== 0 || ttl
> Config
.positiveDnsTtl
)
458 ttl
= Config
.positiveDnsTtl
;
460 if (ttl
< Config
.negativeDnsTtl
)
461 ttl
= Config
.negativeDnsTtl
;
463 i
->expires
= squid_curtime
+ ttl
;
465 i
->flags
.negcached
= 0;
467 return i
->addrs
.count
;
474 ipcacheHandleReply(void *data
, char *reply
)
476 ipcacheHandleReply(void *data
, rfc1035_rr
* answers
, int na
, const char *error_message
)
480 static_cast<generic_cbdata
*>(data
)->unwrap(&i
);
481 IpcacheStats
.replies
++;
482 statHistCount(&statCounter
.dns
.svc_time
,
483 tvSubMsec(i
->request_time
, current_time
));
486 ipcacheParse(i
, reply
);
489 ipcacheParse(i
, answers
, na
, error_message
);
497 ipcache_nbgethostbyname(const char *name
, IPH
* handler
, void *handlerData
)
499 ipcache_entry
*i
= NULL
;
500 const ipcache_addrs
*addrs
= NULL
;
502 assert(handler
!= NULL
);
503 debugs(14, 4, "ipcache_nbgethostbyname: Name '" << name
<< "'.");
504 IpcacheStats
.requests
++;
506 if (name
== NULL
|| name
[0] == '\0') {
507 debugs(14, 4, "ipcache_nbgethostbyname: Invalid name!");
508 dns_error_message
= "Invalid hostname";
509 handler(NULL
, handlerData
);
513 if ((addrs
= ipcacheCheckNumeric(name
))) {
514 dns_error_message
= NULL
;
515 handler(addrs
, handlerData
);
519 i
= ipcache_get(name
);
524 } else if (ipcacheExpiredEntry(i
)) {
525 /* hit, but expired -- bummer */
530 debugs(14, 4, "ipcache_nbgethostbyname: HIT for '" << name
<< "'");
532 if (i
->flags
.negcached
)
533 IpcacheStats
.negative_hits
++;
537 i
->handler
= handler
;
539 i
->handlerData
= cbdataReference(handlerData
);
546 debugs(14, 5, "ipcache_nbgethostbyname: MISS for '" << name
<< "'");
547 IpcacheStats
.misses
++;
548 i
= ipcacheCreateEntry(name
);
549 i
->handler
= handler
;
550 i
->handlerData
= cbdataReference(handlerData
);
551 i
->request_time
= current_time
;
552 c
= new generic_cbdata(i
);
555 dnsSubmit(hashKeyStr(&i
->hash
), ipcacheHandleReply
, c
);
558 idnsALookup(hashKeyStr(&i
->hash
), ipcacheHandleReply
, c
);
562 /* initialize the ipcache */
567 debugs(14, 3, "Initializing IP Cache...");
568 memset(&IpcacheStats
, '\0', sizeof(IpcacheStats
));
569 memset(&lru_list
, '\0', sizeof(lru_list
));
570 /* test naming lookup */
572 if (!opt_dns_tests
) {
573 debugs(14, 4, "ipcache_init: Skipping DNS name lookup tests.");
574 } else if (!ipcache_testname()) {
575 fatal("ipcache_init: DNS name lookup tests failed.");
577 debugs(14, 1, "Successful DNS name lookup tests...");
580 memset(&static_addrs
, '\0', sizeof(ipcache_addrs
));
582 static_addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(1, sizeof(struct IN_ADDR
));
583 static_addrs
.bad_mask
= (unsigned char *)xcalloc(1, sizeof(unsigned char));
584 ipcache_high
= (long) (((float) Config
.ipcache
.size
*
585 (float) Config
.ipcache
.high
) / (float) 100);
586 ipcache_low
= (long) (((float) Config
.ipcache
.size
*
587 (float) Config
.ipcache
.low
) / (float) 100);
588 n
= hashPrime(ipcache_high
/ 4);
589 ip_table
= hash_create((HASHCMP
*) std::strcmp
, n
, hash4
);
590 memDataInit(MEM_IPCACHE_ENTRY
, "ipcache_entry", sizeof(ipcache_entry
), 0);
594 ipcacheRegisterWithCacheManager(CacheManager
& manager
)
596 manager
.registerAction("ipcache",
597 "IP Cache Stats and Contents",
598 stat_ipcache_get
, 0, 1);
601 const ipcache_addrs
*
602 ipcache_gethostbyname(const char *name
, int flags
)
604 ipcache_entry
*i
= NULL
;
605 ipcache_addrs
*addrs
;
607 debugs(14, 3, "ipcache_gethostbyname: '" << name
<< "', flags=" << std::hex
<< flags
);
608 IpcacheStats
.requests
++;
609 i
= ipcache_get(name
);
613 } else if (ipcacheExpiredEntry(i
)) {
616 } else if (i
->flags
.negcached
) {
617 IpcacheStats
.negative_hits
++;
618 dns_error_message
= i
->error_message
;
622 i
->lastref
= squid_curtime
;
623 dns_error_message
= i
->error_message
;
627 dns_error_message
= NULL
;
629 if ((addrs
= ipcacheCheckNumeric(name
)))
632 IpcacheStats
.misses
++;
634 if (flags
& IP_LOOKUP_IF_MISS
)
635 ipcache_nbgethostbyname(name
, dummy_handler
, NULL
);
641 ipcacheStatPrint(ipcache_entry
* i
, StoreEntry
* sentry
)
644 storeAppendPrintf(sentry
, " %-32.32s %c%c %6d %6d %2d(%2d)",
645 hashKeyStr(&i
->hash
),
646 i
->flags
.fromhosts
? 'H' : ' ',
647 i
->flags
.negcached
? 'N' : ' ',
648 (int) (squid_curtime
- i
->lastref
),
649 (int) ((i
->flags
.fromhosts
? -1 : i
->expires
- squid_curtime
)),
650 (int) i
->addrs
.count
,
651 (int) i
->addrs
.badcount
);
653 for (k
= 0; k
< (int) i
->addrs
.count
; k
++) {
654 storeAppendPrintf(sentry
, " %15s-%3s", inet_ntoa(i
->addrs
.in_addrs
[k
]),
655 i
->addrs
.bad_mask
[k
] ? "BAD" : "OK ");
658 storeAppendPrintf(sentry
, "\n");
661 /* process objects list */
663 stat_ipcache_get(StoreEntry
* sentry
)
666 assert(ip_table
!= NULL
);
667 storeAppendPrintf(sentry
, "IP Cache Statistics:\n");
668 storeAppendPrintf(sentry
, "IPcache Entries: %d\n",
669 memInUse(MEM_IPCACHE_ENTRY
));
670 storeAppendPrintf(sentry
, "IPcache Requests: %d\n",
671 IpcacheStats
.requests
);
672 storeAppendPrintf(sentry
, "IPcache Hits: %d\n",
674 storeAppendPrintf(sentry
, "IPcache Negative Hits: %d\n",
675 IpcacheStats
.negative_hits
);
676 storeAppendPrintf(sentry
, "IPcache Misses: %d\n",
677 IpcacheStats
.misses
);
678 storeAppendPrintf(sentry
, "\n\n");
679 storeAppendPrintf(sentry
, "IP Cache Contents:\n\n");
680 storeAppendPrintf(sentry
, " %-29.29s %3s %6s %6s %1s\n",
687 for (m
= lru_list
.head
; m
; m
= m
->next
)
688 ipcacheStatPrint((ipcache_entry
*)m
->data
, sentry
);
692 dummy_handler(const ipcache_addrs
* addrsnotused
, void *datanotused
)
698 ipcacheInvalidate(const char *name
)
702 if ((i
= ipcache_get(name
)) == NULL
)
705 i
->expires
= squid_curtime
;
708 * NOTE, don't call ipcacheRelease here becuase we might be here due
709 * to a thread started from a callback.
714 ipcacheInvalidateNegative(const char *name
)
718 if ((i
= ipcache_get(name
)) == NULL
)
721 if (i
->flags
.negcached
)
722 i
->expires
= squid_curtime
;
725 * NOTE, don't call ipcacheRelease here becuase we might be here due
726 * to a thread started from a callback.
731 ipcacheCheckNumeric(const char *name
)
735 /* check if it's already a IP address in text form. */
737 if (!safe_inet_addr(name
, &ip
))
740 static_addrs
.count
= 1;
742 static_addrs
.cur
= 0;
744 static_addrs
.in_addrs
[0].s_addr
= ip
.s_addr
;
746 static_addrs
.bad_mask
[0] = FALSE
;
748 static_addrs
.badcount
= 0;
750 return &static_addrs
;
754 ipcacheLockEntry(ipcache_entry
* i
)
756 if (i
->locks
++ == 0) {
757 dlinkDelete(&i
->lru
, &lru_list
);
758 dlinkAdd(i
, &i
->lru
, &lru_list
);
763 ipcacheUnlockEntry(ipcache_entry
* i
)
765 assert(i
->locks
> 0);
768 if (ipcacheExpiredEntry(i
))
773 ipcacheCycleAddr(const char *name
, ipcache_addrs
* ia
)
780 if ((i
= ipcache_get(name
)) == NULL
)
783 if (i
->flags
.negcached
)
789 for (k
= 0; k
< ia
->count
; k
++) {
790 if (++ia
->cur
== ia
->count
)
793 if (!ia
->bad_mask
[ia
->cur
])
797 if (k
== ia
->count
) {
798 /* All bad, reset to All good */
799 debugs(14, 3, "ipcacheCycleAddr: Changing ALL " << name
<< " addrs from BAD to OK");
801 for (k
= 0; k
< ia
->count
; k
++)
809 debugs(14, 3, "ipcacheCycleAddr: " << name
<< " now at " << inet_ntoa(ia
->in_addrs
[ia
->cur
]));
813 * Marks the given address as BAD and calls ipcacheCycleAddr to
814 * advance the current pointer to the next OK address.
818 ipcacheMarkBadAddr(const char *name
, struct IN_ADDR addr
)
824 if ((i
= ipcache_get(name
)) == NULL
)
829 for (k
= 0; k
< (int) ia
->count
; k
++)
831 if (ia
->in_addrs
[k
].s_addr
== addr
.s_addr
)
835 if (k
== (int) ia
->count
) /* not found */
838 if (!ia
->bad_mask
[k
])
840 ia
->bad_mask
[k
] = TRUE
;
842 i
->expires
= XMIN(squid_curtime
+ XMAX((time_t)60, Config
.negativeDnsTtl
), i
->expires
);
843 debugs(14, 2, "ipcacheMarkBadAddr: " << name
<< " [" << inet_ntoa(addr
) << "]");
846 ipcacheCycleAddr(name
, ia
);
851 ipcacheMarkGoodAddr(const char *name
, struct IN_ADDR addr
)
857 if ((i
= ipcache_get(name
)) == NULL
)
862 for (k
= 0; k
< (int) ia
->count
; k
++)
864 if (ia
->in_addrs
[k
].s_addr
== addr
.s_addr
)
868 if (k
== (int) ia
->count
) /* not found */
871 if (!ia
->bad_mask
[k
]) /* already OK */
874 ia
->bad_mask
[k
] = FALSE
;
878 debugs(14, 2, "ipcacheMarkGoodAddr: " << name
<< " [" << inet_ntoa(addr
) << "]");
882 ipcacheFreeEntry(void *data
)
884 ipcache_entry
*i
= (ipcache_entry
*)data
;
885 safe_free(i
->addrs
.in_addrs
);
886 safe_free(i
->addrs
.bad_mask
);
887 safe_free(i
->hash
.key
);
888 safe_free(i
->error_message
);
889 memFree(i
, MEM_IPCACHE_ENTRY
);
893 ipcacheFreeMemory(void)
895 hashFreeItems(ip_table
, ipcacheFreeEntry
);
896 hashFreeMemory(ip_table
);
900 /* Recalculate IP cache size upon reconfigure */
902 ipcache_restart(void)
904 ipcache_high
= (long) (((float) Config
.ipcache
.size
*
905 (float) Config
.ipcache
.high
) / (float) 100);
906 ipcache_low
= (long) (((float) Config
.ipcache
.size
*
907 (float) Config
.ipcache
.low
) / (float) 100);
908 purge_entries_fromhosts();
912 * adds a "static" entry from /etc/hosts.
913 * returns 0 upon success, 1 if the ip address is invalid
916 ipcacheAddEntryFromHosts(const char *name
, const char *ipaddr
)
922 if (!safe_inet_addr(ipaddr
, &ip
)) {
923 if (strchr(ipaddr
, ':') && strspn(ipaddr
, "0123456789abcdefABCDEF:") == strlen(ipaddr
)) {
924 debugs(14, 3, "ipcacheAddEntryFromHosts: Skipping IPv6 address '" << ipaddr
<< "'");
926 debugs(14, 1, "ipcacheAddEntryFromHosts: Bad IP address '" << ipaddr
<< "'");
932 if ((i
= ipcache_get(name
))) {
933 if (1 == i
->flags
.fromhosts
) {
934 ipcacheUnlockEntry(i
);
935 } else if (i
->locks
> 0) {
936 debugs(14, 1, "ipcacheAddEntryFromHosts: can't add static entry for locked name '" << name
<< "'");
943 i
= ipcacheCreateEntry(name
);
946 i
->addrs
.badcount
= 0;
948 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(1, sizeof(struct IN_ADDR
));
949 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(1, sizeof(unsigned char));
950 i
->addrs
.in_addrs
[0].s_addr
= ip
.s_addr
;
951 i
->addrs
.bad_mask
[0] = FALSE
;
952 i
->flags
.fromhosts
= 1;
960 * The function to return the ip cache statistics to via SNMP
964 snmp_netIpFn(variable_list
* Var
, snint
* ErrP
)
966 variable_list
*Answer
= NULL
;
967 debugs(49, 5, "snmp_netIpFn: Processing request:");
968 snmpDebugOid(5, Var
->name
, Var
->name_length
);
969 *ErrP
= SNMP_ERR_NOERROR
;
971 switch (Var
->name
[LEN_SQ_NET
+ 1]) {
974 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
975 memInUse(MEM_IPCACHE_ENTRY
),
980 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
981 IpcacheStats
.requests
,
986 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
992 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
998 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
999 IpcacheStats
.negative_hits
,
1004 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
1005 IpcacheStats
.misses
,
1010 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
1016 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
1022 *ErrP
= SNMP_ERR_NOSUCHNAME
;
1023 snmp_var_free(Answer
);
1030 #endif /*SQUID_SNMP */