From 7ddd04a744503090686845b7f655e5fa7d921096 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Sun, 12 Oct 2008 02:59:29 +1300 Subject: [PATCH] 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.. --- src/dns_internal.cc | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) 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); -- 2.47.2