From: hno <> Date: Sun, 24 Jun 2007 03:08:39 +0000 (+0000) Subject: Author: Manu Garg X-Git-Tag: SQUID_3_0_PRE7~203 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e7412b1c930f60835e9c32332fda96d6704cf22c;p=thirdparty%2Fsquid.git Author: Manu Garg Bug #1968: Squid hangs occasionally when using DNS search paths Squid 2.6 (tested with squid 2.6.1 and 2.6.5) hangs after running for some time (could be from 5 min to 40 min on a busy server). Squid becomes unresponsive and CPU usage becomes 90-100%. ltrace shows that it's continuously comparing strings in an infinite loop: strcmp("thumbnail.videoegg.com", "i12.ebaystatic.com") = -1 strcmp("thumbnail.videoegg.com", "i12.ebaystatic.com") = -1 strcmp("thumbnail.videoegg.com", "i12.ebaystatic.com") = -1 The problem seems to be in the way squid's internal DNS system (dns_internal.c) keeps record of looked up but not yet answered DNS queries. This bug is hit specifically when multiple search paths are used in /etc/resolv.conf. Squid caches all dns queries before sending them to avoid duplicate queries for the same name. (look at: idnsCacheQuery(q) and hash_table *idns_lookup_hash, in dns_internal.c). This mechanism works well unless multiple search paths are defined in /etc/resolv.conf. When multiple dns search paths are defined, same query object is modified and next search path is concatenated to it's name. This query is cached again and resent. Problem is that the query is not unlinked before being cached and thus linked again. Only the key of hash object (that's actually name) changes this time; object itself remains same. This corrupts the hash table of looked up queries. --- diff --git a/src/dns_internal.cc b/src/dns_internal.cc index b65a959c6b..f927147477 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.100 2007/05/29 13:31:39 amosjeffries Exp $ + * $Id: dns_internal.cc,v 1.101 2007/06/23 21:08:39 hno Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -967,6 +967,10 @@ idnsGrokReply(const char *buf, size_t sz) } rfc1035MessageDestroy(message); + if (q->hash.key) { + hash_remove_link(idns_lookup_hash, &q->hash); + q->hash.key = NULL; + } q->start_t = current_time; q->id = idnsQueryID(); rfc1035SetQueryID(q->buf, q->id);