From: Amos Jeffries Date: Sat, 11 Oct 2008 13:59:29 +0000 (+1300) Subject: Bug 2393: DNS requests getting stuck in idns queue X-Git-Tag: SQUID_3_0_STABLE10~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ddd04a744503090686845b7f655e5fa7d921096;p=thirdparty%2Fsquid.git Bug 2393: DNS requests getting stuck in idns queue Port of Squid-2 fix by Henrik Nordstrom There seems to be two problems here. a) On TCP communication failure Squid starts to restransmit the TCP query as fast as it can, with no bounds checking. Keeps doing that until there is a response or Squid is restarted... b) For some reason the retransmit queue seems to halt for you. I have not yet reproduced this issue, but may be related to the first.. --- diff --git a/src/dns_internal.cc b/src/dns_internal.cc index dab4b94c1f..e179173457 100755 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -105,8 +105,8 @@ struct _idns_query int need_vc; struct timeval start_t; - struct timeval sent_t; + struct timeval queue_t; dlink_node lru; IDNSCB *callback; void *callback_data; @@ -824,7 +824,7 @@ idnsSendQuery(idns_query * q) q->nsends++; - q->sent_t = current_time; + q->queue_t = q->sent_t = current_time; if (x < 0) debugs(50, 1, "idnsSendQuery: FD " << DnsSocket << ": sendto: " << xstrerror()); @@ -837,6 +837,7 @@ idnsSendQuery(idns_query * q) } nameservers[ns].nqueries++; + q->queue_t = current_time; dlinkAdd(q, &q->lru, &lru_list); idnsTickleQueue(); } @@ -1102,19 +1103,28 @@ idnsCheckQueue(void *unused) idns_query *q; event_queued = 0; + if (0 == nns) + /* name servers went away; reconfiguring or shutting down */ + return; + for (n = lru_list.tail; n; n = p) { - if (0 == nns) - /* name servers went away; reconfiguring or shutting down */ - break; - q = (idns_query *)n->data; + p = n->prev; + q = static_cast(n->data); - if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * (1 << (q->nsends - 1) % nns)) - break; + /* Anything to process in the queue? */ + if (tvSubDsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit ) + break; - debugs(78, 3, "idnsCheckQueue: ID 0x" << std::hex << std::setfill('0') << std::setw(4) << q->id << "timeout" ); + /* Query timer expired? */ + if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns)) { + dlinkDelete(&q->lru, &lru_list); + q->queue_t = current_time; + dlinkAdd(q, &q->lru, &lru_list); + continue; + } - p = n->prev; + debugs(78, 3, "idnsCheckQueue: ID 0x" << std::hex << std::setfill('0') << std::setw(4) << q->id << "timeout" ); dlinkDelete(&q->lru, &lru_list);