3 * $Id: ipcache.cc,v 1.255 2006/05/29 00:15:02 robertc 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.
37 #include "CacheManager.h"
38 #include "SquidTime.h"
42 typedef struct _ipcache_entry ipcache_entry
;
46 hash_link hash
; /* must be first */
54 struct timeval request_time
;
61 unsigned int negcached
:
64 unsigned int fromhosts
:
82 static dlink_list lru_list
;
84 static FREE ipcacheFreeEntry
;
86 static HLPCB ipcacheHandleReply
;
88 static IDNSCB ipcacheHandleReply
;
90 static IPH dummy_handler
;
91 static int ipcacheExpiredEntry(ipcache_entry
*);
92 static int ipcache_testname(void);
94 static int ipcacheParse(ipcache_entry
*, const char *buf
);
96 static int ipcacheParse(ipcache_entry
*, rfc1035_rr
*, int, const char *error
);
98 static ipcache_entry
*ipcache_get(const char *);
99 static void ipcacheLockEntry(ipcache_entry
*);
100 static void ipcacheStatPrint(ipcache_entry
*, StoreEntry
*);
101 static void ipcacheUnlockEntry(ipcache_entry
*);
102 static void ipcacheRelease(ipcache_entry
*);
104 static ipcache_addrs static_addrs
;
105 static hash_table
*ip_table
= NULL
;
107 static long ipcache_low
= 180;
108 static long ipcache_high
= 200;
110 #if LIBRESOLV_DNS_TTL_HACK
111 extern int _dns_ttl_
;
115 ipcache_testname(void)
118 debug(14, 1) ("Performing DNS Tests...\n");
120 if ((w
= Config
.dns_testname_list
) == NULL
)
123 for (; w
; w
= w
->next
) {
124 if (gethostbyname(w
->key
) != NULL
)
131 /* removes the given ipcache entry */
133 ipcacheRelease(ipcache_entry
* i
)
135 debug(14, 3) ("ipcacheRelease: Releasing entry for '%s'\n", (const char *) i
->hash
.key
);
136 hash_remove_link(ip_table
, (hash_link
*) i
);
137 dlinkDelete(&i
->lru
, &lru_list
);
141 static ipcache_entry
*
142 ipcache_get(const char *name
)
144 if (ip_table
!= NULL
)
145 return (ipcache_entry
*) hash_lookup(ip_table
, name
);
151 ipcacheExpiredEntry(ipcache_entry
* i
)
153 /* all static entries are locked, so this takes care of them too */
158 if (i
->addrs
.count
== 0)
159 if (0 == i
->flags
.negcached
)
162 if (i
->expires
> squid_curtime
)
169 ipcache_purgelru(void *voidnotused
)
172 dlink_node
*prev
= NULL
;
175 eventAdd("ipcache_purgelru", ipcache_purgelru
, NULL
, 10.0, 1);
177 for (m
= lru_list
.tail
; m
; m
= prev
) {
178 if (memInUse(MEM_IPCACHE_ENTRY
) < ipcache_low
)
183 i
= (ipcache_entry
*)m
->data
;
193 debug(14, 9) ("ipcache_purgelru: removed %d entries\n", removed
);
196 /* purges entries added from /etc/hosts (or whatever). */
198 purge_entries_fromhosts(void)
200 dlink_node
*m
= lru_list
.head
;
201 ipcache_entry
*i
= NULL
, *t
;
204 if (i
!= NULL
) { /* need to delay deletion */
205 ipcacheRelease(i
); /* we just override locks */
209 t
= (ipcache_entry
*)m
->data
;
211 if (t
->flags
.fromhosts
)
221 /* create blank ipcache_entry */
222 static ipcache_entry
*
223 ipcacheCreateEntry(const char *name
)
225 static ipcache_entry
*i
;
226 i
= (ipcache_entry
*)memAllocate(MEM_IPCACHE_ENTRY
);
227 i
->hash
.key
= xstrdup(name
);
228 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
233 ipcacheAddEntry(ipcache_entry
* i
)
235 hash_link
*e
= (hash_link
*)hash_lookup(ip_table
, i
->hash
.key
);
238 /* avoid colission */
239 ipcache_entry
*q
= (ipcache_entry
*) e
;
243 hash_join(ip_table
, &i
->hash
);
244 dlinkAdd(i
, &i
->lru
, &lru_list
);
245 i
->lastref
= squid_curtime
;
248 /* walks down the pending list, calling handlers */
250 ipcacheCallback(ipcache_entry
* i
)
252 IPH
*callback
= i
->handler
;
254 i
->lastref
= squid_curtime
;
261 callback
= i
->handler
;
265 if (cbdataReferenceValidDone(i
->handlerData
, &cbdata
)) {
266 dns_error_message
= i
->error_message
;
267 callback(i
->flags
.negcached
? NULL
: &i
->addrs
, cbdata
);
270 ipcacheUnlockEntry(i
);
275 ipcacheParse(ipcache_entry
*i
, const char *inbuf
)
277 LOCAL_ARRAY(char, buf
, DNS_INBUF_SZ
);
282 const char *name
= (const char *)i
->hash
.key
;
283 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
284 i
->flags
.negcached
= 1;
285 safe_free(i
->addrs
.in_addrs
);
286 safe_free(i
->addrs
.bad_mask
);
287 safe_free(i
->error_message
);
291 debug(14, 1) ("ipcacheParse: Got <NULL> reply\n");
292 i
->error_message
= xstrdup("Internal Error");
296 xstrncpy(buf
, inbuf
, DNS_INBUF_SZ
);
297 debug(14, 5) ("ipcacheParse: parsing: {%s}\n", buf
);
298 token
= strtok(buf
, w_space
);
301 debug(14, 1) ("ipcacheParse: expecting result, got '%s'\n", inbuf
);
302 i
->error_message
= xstrdup("Internal Error");
306 if (0 == strcmp(token
, "$fail")) {
307 token
= strtok(NULL
, "\n");
308 assert(NULL
!= token
);
309 i
->error_message
= xstrdup(token
);
313 if (0 != strcmp(token
, "$addr")) {
314 debug(14, 1) ("ipcacheParse: expecting '$addr', got '%s' in response to '%s'\n", inbuf
, name
);
315 i
->error_message
= xstrdup("Internal Error");
319 token
= strtok(NULL
, w_space
);
322 debug(14, 1) ("ipcacheParse: expecting TTL, got '%s' in response to '%s'\n", inbuf
, name
);
323 i
->error_message
= xstrdup("Internal Error");
329 while (NULL
!= (token
= strtok(NULL
, w_space
))) {
339 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(ipcount
, sizeof(struct IN_ADDR
));
340 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(ipcount
, sizeof(unsigned char));
342 for (j
= 0, k
= 0; k
< ipcount
; k
++) {
343 if (safe_inet_addr(A
[k
], &i
->addrs
.in_addrs
[j
]))
346 debug(14, 1) ("ipcacheParse: Invalid IP address '%s' in response to '%s'\n", A
[k
], name
);
349 i
->addrs
.count
= (unsigned char) j
;
352 if (i
->addrs
.count
<= 0) {
353 debug(14, 1) ("ipcacheParse: No addresses in response to '%s'\n", name
);
357 if (ttl
== 0 || ttl
> Config
.positiveDnsTtl
)
358 ttl
= Config
.positiveDnsTtl
;
360 if (ttl
< Config
.negativeDnsTtl
)
361 ttl
= Config
.negativeDnsTtl
;
363 i
->expires
= squid_curtime
+ ttl
;
365 i
->flags
.negcached
= 0;
367 return i
->addrs
.count
;
372 ipcacheParse(ipcache_entry
*i
, rfc1035_rr
* answers
, int nr
, const char *error_message
)
378 const char *name
= (const char *)i
->hash
.key
;
379 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
380 i
->flags
.negcached
= 1;
381 safe_free(i
->addrs
.in_addrs
);
382 safe_free(i
->addrs
.bad_mask
);
383 safe_free(i
->error_message
);
387 debug(14, 3) ("ipcacheParse: Lookup failed '%s' for '%s'\n",
388 error_message
, (const char *)i
->hash
.key
);
389 i
->error_message
= xstrdup(error_message
);
394 debug(14, 3) ("ipcacheParse: No DNS records in response to '%s'\n", name
);
395 i
->error_message
= xstrdup("No DNS records");
401 for (k
= 0; k
< nr
; k
++) {
402 if (answers
[k
].type
!= RFC1035_TYPE_A
)
405 if (answers
[k
]._class
!= RFC1035_CLASS_IN
)
408 if (answers
[k
].rdlength
!= 4) {
409 debug(14, 1)("ipcacheParse: Invalid IP address in response to '%s'\n", name
);
417 debug(14, 1) ("ipcacheParse: No Address records in response to '%s'\n", name
);
418 i
->error_message
= xstrdup("No Address records");
422 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(na
, sizeof(struct IN_ADDR
));
423 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(na
, sizeof(unsigned char));
425 for (j
= 0, k
= 0; k
< nr
; k
++) {
426 if (answers
[k
]._class
!= RFC1035_CLASS_IN
)
429 if (answers
[k
].type
== RFC1035_TYPE_A
) {
430 if (answers
[k
].rdlength
!= 4)
433 xmemcpy(&i
->addrs
.in_addrs
[j
++], answers
[k
].rdata
, 4);
435 debug(14, 3) ("ipcacheParse: #%d %s\n",
437 inet_ntoa(i
->addrs
.in_addrs
[j
- 1]));
438 } else if (answers
[k
].type
!= RFC1035_TYPE_CNAME
)
441 if (ttl
== 0 || (int) answers
[k
].ttl
< ttl
)
442 ttl
= answers
[k
].ttl
;
448 i
->addrs
.count
= (unsigned char) na
;
450 if (ttl
== 0 || ttl
> Config
.positiveDnsTtl
)
451 ttl
= Config
.positiveDnsTtl
;
453 if (ttl
< Config
.negativeDnsTtl
)
454 ttl
= Config
.negativeDnsTtl
;
456 i
->expires
= squid_curtime
+ ttl
;
458 i
->flags
.negcached
= 0;
460 return i
->addrs
.count
;
467 ipcacheHandleReply(void *data
, char *reply
)
469 ipcacheHandleReply(void *data
, rfc1035_rr
* answers
, int na
, const char *error_message
)
472 generic_cbdata
*c
= (generic_cbdata
*)data
;
473 ipcache_entry
*i
= (ipcache_entry
*)c
->data
;
476 IpcacheStats
.replies
++;
477 statHistCount(&statCounter
.dns
.svc_time
,
478 tvSubMsec(i
->request_time
, current_time
));
481 ipcacheParse(i
, reply
);
484 ipcacheParse(i
, answers
, na
, error_message
);
492 ipcache_nbgethostbyname(const char *name
, IPH
* handler
, void *handlerData
)
494 ipcache_entry
*i
= NULL
;
495 const ipcache_addrs
*addrs
= NULL
;
497 assert(handler
!= NULL
);
498 debug(14, 4) ("ipcache_nbgethostbyname: Name '%s'.\n", name
);
499 IpcacheStats
.requests
++;
501 if (name
== NULL
|| name
[0] == '\0') {
502 debug(14, 4) ("ipcache_nbgethostbyname: Invalid name!\n");
503 dns_error_message
= "Invalid hostname";
504 handler(NULL
, handlerData
);
508 if ((addrs
= ipcacheCheckNumeric(name
))) {
509 dns_error_message
= NULL
;
510 handler(addrs
, handlerData
);
514 i
= ipcache_get(name
);
519 } else if (ipcacheExpiredEntry(i
)) {
520 /* hit, but expired -- bummer */
525 debug(14, 4) ("ipcache_nbgethostbyname: HIT for '%s'\n", name
);
527 if (i
->flags
.negcached
)
528 IpcacheStats
.negative_hits
++;
532 i
->handler
= handler
;
534 i
->handlerData
= cbdataReference(handlerData
);
541 debug(14, 5) ("ipcache_nbgethostbyname: MISS for '%s'\n", name
);
542 IpcacheStats
.misses
++;
543 i
= ipcacheCreateEntry(name
);
544 i
->handler
= handler
;
545 i
->handlerData
= cbdataReference(handlerData
);
546 i
->request_time
= current_time
;
547 c
= cbdataAlloc(generic_cbdata
);
551 dnsSubmit(hashKeyStr(&i
->hash
), ipcacheHandleReply
, c
);
554 idnsALookup(hashKeyStr(&i
->hash
), ipcacheHandleReply
, c
);
558 /* initialize the ipcache */
563 debug(14, 3) ("Initializing IP Cache...\n");
564 memset(&IpcacheStats
, '\0', sizeof(IpcacheStats
));
565 memset(&lru_list
, '\0', sizeof(lru_list
));
566 /* test naming lookup */
568 if (!opt_dns_tests
) {
569 debug(14, 4) ("ipcache_init: Skipping DNS name lookup tests.\n");
570 } else if (!ipcache_testname()) {
571 fatal("ipcache_init: DNS name lookup tests failed.");
573 debug(14, 1) ("Successful DNS name lookup tests...\n");
576 memset(&static_addrs
, '\0', sizeof(ipcache_addrs
));
578 static_addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(1, sizeof(struct IN_ADDR
));
579 static_addrs
.bad_mask
= (unsigned char *)xcalloc(1, sizeof(unsigned char));
580 ipcache_high
= (long) (((float) Config
.ipcache
.size
*
581 (float) Config
.ipcache
.high
) / (float) 100);
582 ipcache_low
= (long) (((float) Config
.ipcache
.size
*
583 (float) Config
.ipcache
.low
) / (float) 100);
584 n
= hashPrime(ipcache_high
/ 4);
585 ip_table
= hash_create((HASHCMP
*) strcmp
, n
, hash4
);
586 memDataInit(MEM_IPCACHE_ENTRY
, "ipcache_entry", sizeof(ipcache_entry
), 0);
590 ipcacheRegisterWithCacheManager(CacheManager
& manager
)
592 manager
.registerAction("ipcache",
593 "IP Cache Stats and Contents",
594 stat_ipcache_get
, 0, 1);
597 const ipcache_addrs
*
598 ipcache_gethostbyname(const char *name
, int flags
)
600 ipcache_entry
*i
= NULL
;
601 ipcache_addrs
*addrs
;
603 debug(14, 3) ("ipcache_gethostbyname: '%s', flags=%x\n", name
, flags
);
604 IpcacheStats
.requests
++;
605 i
= ipcache_get(name
);
609 } else if (ipcacheExpiredEntry(i
)) {
612 } else if (i
->flags
.negcached
) {
613 IpcacheStats
.negative_hits
++;
614 dns_error_message
= i
->error_message
;
618 i
->lastref
= squid_curtime
;
619 dns_error_message
= i
->error_message
;
623 dns_error_message
= NULL
;
625 if ((addrs
= ipcacheCheckNumeric(name
)))
628 IpcacheStats
.misses
++;
630 if (flags
& IP_LOOKUP_IF_MISS
)
631 ipcache_nbgethostbyname(name
, dummy_handler
, NULL
);
637 ipcacheStatPrint(ipcache_entry
* i
, StoreEntry
* sentry
)
640 storeAppendPrintf(sentry
, " %-32.32s %c%c %6d %6d %2d(%2d)",
641 hashKeyStr(&i
->hash
),
642 i
->flags
.fromhosts
? 'H' : ' ',
643 i
->flags
.negcached
? 'N' : ' ',
644 (int) (squid_curtime
- i
->lastref
),
645 (int) ((i
->flags
.fromhosts
? -1 : i
->expires
- squid_curtime
)),
646 (int) i
->addrs
.count
,
647 (int) i
->addrs
.badcount
);
649 for (k
= 0; k
< (int) i
->addrs
.count
; k
++) {
650 storeAppendPrintf(sentry
, " %15s-%3s", inet_ntoa(i
->addrs
.in_addrs
[k
]),
651 i
->addrs
.bad_mask
[k
] ? "BAD" : "OK ");
654 storeAppendPrintf(sentry
, "\n");
657 /* process objects list */
659 stat_ipcache_get(StoreEntry
* sentry
)
662 assert(ip_table
!= NULL
);
663 storeAppendPrintf(sentry
, "IP Cache Statistics:\n");
664 storeAppendPrintf(sentry
, "IPcache Entries: %d\n",
665 memInUse(MEM_IPCACHE_ENTRY
));
666 storeAppendPrintf(sentry
, "IPcache Requests: %d\n",
667 IpcacheStats
.requests
);
668 storeAppendPrintf(sentry
, "IPcache Hits: %d\n",
670 storeAppendPrintf(sentry
, "IPcache Negative Hits: %d\n",
671 IpcacheStats
.negative_hits
);
672 storeAppendPrintf(sentry
, "IPcache Misses: %d\n",
673 IpcacheStats
.misses
);
674 storeAppendPrintf(sentry
, "\n\n");
675 storeAppendPrintf(sentry
, "IP Cache Contents:\n\n");
676 storeAppendPrintf(sentry
, " %-29.29s %3s %6s %6s %1s\n",
683 for (m
= lru_list
.head
; m
; m
= m
->next
)
684 ipcacheStatPrint((ipcache_entry
*)m
->data
, sentry
);
688 dummy_handler(const ipcache_addrs
* addrsnotused
, void *datanotused
)
694 ipcacheInvalidate(const char *name
)
698 if ((i
= ipcache_get(name
)) == NULL
)
701 i
->expires
= squid_curtime
;
704 * NOTE, don't call ipcacheRelease here becuase we might be here due
705 * to a thread started from a callback.
710 ipcacheInvalidateNegative(const char *name
)
714 if ((i
= ipcache_get(name
)) == NULL
)
717 if (i
->flags
.negcached
)
718 i
->expires
= squid_curtime
;
721 * NOTE, don't call ipcacheRelease here becuase we might be here due
722 * to a thread started from a callback.
727 ipcacheCheckNumeric(const char *name
)
731 /* check if it's already a IP address in text form. */
733 if (!safe_inet_addr(name
, &ip
))
736 static_addrs
.count
= 1;
738 static_addrs
.cur
= 0;
740 static_addrs
.in_addrs
[0].s_addr
= ip
.s_addr
;
742 static_addrs
.bad_mask
[0] = FALSE
;
744 static_addrs
.badcount
= 0;
746 return &static_addrs
;
750 ipcacheLockEntry(ipcache_entry
* i
)
752 if (i
->locks
++ == 0) {
753 dlinkDelete(&i
->lru
, &lru_list
);
754 dlinkAdd(i
, &i
->lru
, &lru_list
);
759 ipcacheUnlockEntry(ipcache_entry
* i
)
761 assert(i
->locks
> 0);
764 if (ipcacheExpiredEntry(i
))
769 ipcacheCycleAddr(const char *name
, ipcache_addrs
* ia
)
776 if ((i
= ipcache_get(name
)) == NULL
)
779 if (i
->flags
.negcached
)
785 for (k
= 0; k
< ia
->count
; k
++) {
786 if (++ia
->cur
== ia
->count
)
789 if (!ia
->bad_mask
[ia
->cur
])
793 if (k
== ia
->count
) {
794 /* All bad, reset to All good */
795 debug(14, 3) ("ipcacheCycleAddr: Changing ALL %s addrs from BAD to OK\n",
798 for (k
= 0; k
< ia
->count
; k
++)
806 debug(14, 3) ("ipcacheCycleAddr: %s now at %s\n", name
,
807 inet_ntoa(ia
->in_addrs
[ia
->cur
]));
811 * Marks the given address as BAD and calls ipcacheCycleAddr to
812 * advance the current pointer to the next OK address.
816 ipcacheMarkBadAddr(const char *name
, struct IN_ADDR addr
)
822 if ((i
= ipcache_get(name
)) == NULL
)
827 for (k
= 0; k
< (int) ia
->count
; k
++)
829 if (ia
->in_addrs
[k
].s_addr
== addr
.s_addr
)
833 if (k
== (int) ia
->count
) /* not found */
836 if (!ia
->bad_mask
[k
])
838 ia
->bad_mask
[k
] = TRUE
;
840 i
->expires
= XMIN(squid_curtime
+ XMAX((time_t)60, Config
.negativeDnsTtl
), i
->expires
);
841 debug(14, 2) ("ipcacheMarkBadAddr: %s [%s]\n", name
, inet_ntoa(addr
));
844 ipcacheCycleAddr(name
, ia
);
849 ipcacheMarkGoodAddr(const char *name
, struct IN_ADDR addr
)
855 if ((i
= ipcache_get(name
)) == NULL
)
860 for (k
= 0; k
< (int) ia
->count
; k
++)
862 if (ia
->in_addrs
[k
].s_addr
== addr
.s_addr
)
866 if (k
== (int) ia
->count
) /* not found */
869 if (!ia
->bad_mask
[k
]) /* already OK */
872 ia
->bad_mask
[k
] = FALSE
;
876 debug(14, 2) ("ipcacheMarkGoodAddr: %s [%s]\n", name
, inet_ntoa(addr
));
880 ipcacheFreeEntry(void *data
)
882 ipcache_entry
*i
= (ipcache_entry
*)data
;
883 safe_free(i
->addrs
.in_addrs
);
884 safe_free(i
->addrs
.bad_mask
);
885 safe_free(i
->hash
.key
);
886 safe_free(i
->error_message
);
887 memFree(i
, MEM_IPCACHE_ENTRY
);
891 ipcacheFreeMemory(void)
893 hashFreeItems(ip_table
, ipcacheFreeEntry
);
894 hashFreeMemory(ip_table
);
898 /* Recalculate IP cache size upon reconfigure */
900 ipcache_restart(void)
902 ipcache_high
= (long) (((float) Config
.ipcache
.size
*
903 (float) Config
.ipcache
.high
) / (float) 100);
904 ipcache_low
= (long) (((float) Config
.ipcache
.size
*
905 (float) Config
.ipcache
.low
) / (float) 100);
906 purge_entries_fromhosts();
910 * adds a "static" entry from /etc/hosts.
911 * returns 0 upon success, 1 if the ip address is invalid
914 ipcacheAddEntryFromHosts(const char *name
, const char *ipaddr
)
920 if (!safe_inet_addr(ipaddr
, &ip
)) {
921 if (strchr(ipaddr
, ':') && strspn(ipaddr
, "0123456789abcdefABCDEF:") == strlen(ipaddr
)) {
922 debug(14, 3) ("ipcacheAddEntryFromHosts: Skipping IPv6 address '%s'\n", ipaddr
);
924 debug(14, 1) ("ipcacheAddEntryFromHosts: Bad IP address '%s'\n",
931 if ((i
= ipcache_get(name
))) {
932 if (1 == i
->flags
.fromhosts
) {
933 ipcacheUnlockEntry(i
);
934 } else if (i
->locks
> 0) {
935 debug(14, 1) ("ipcacheAddEntryFromHosts: can't add static entry"
936 " for locked name '%s'\n", 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 debug(49, 5) ("snmp_netIpFn: Processing request:\n");
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 */