--------------------- PatchSet 12277 Date: 2008/06/27 21:11:33 Author: hno Branch: SQUID_2_6 Tag: (none) Log: Bug #2393: DNS retransmit queue could get hold up DNS queries which has been retried several times could hold up the rest of the DNS retransmit queue. And combined with the earlier TCP retransmit error this could hang the queue indefinitely. Members: src/dns_internal.c:1.61.2.4->1.61.2.5 Index: squid/src/dns_internal.c =================================================================== RCS file: /cvsroot/squid/squid/src/dns_internal.c,v retrieving revision 1.61.2.4 retrieving revision 1.61.2.5 diff -u -r1.61.2.4 -r1.61.2.5 --- squid/src/dns_internal.c 27 Jun 2008 21:11:06 -0000 1.61.2.4 +++ squid/src/dns_internal.c 27 Jun 2008 21:11:33 -0000 1.61.2.5 @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.c,v 1.61.2.4 2008/06/27 21:11:06 hno Exp $ + * $Id: dns_internal.c,v 1.61.2.5 2008/06/27 21:11:33 hno Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -98,6 +98,7 @@ int nsends; struct timeval start_t; struct timeval sent_t; + struct timeval queue_t; dlink_node lru; IDNSCB *callback; void *callback_data; @@ -605,7 +606,7 @@ q->buf, q->sz); q->nsends++; - q->sent_t = current_time; + q->queue_t = q->sent_t = current_time; if (x < 0) { debug(50, 1) ("idnsSendQuery: FD %d: sendto: %s\n", DnsSocket, xstrerror()); @@ -773,6 +774,7 @@ 0, COMM_NONBLOCKING, "DNS TCP Socket"); + q->queue_t = q->sent_t = current_time; dlinkAdd(q, &q->lru, &lru_list); commConnectStart(q->tcp_socket, inet_ntoa(nameservers[ns].S.sin_addr), @@ -932,16 +934,24 @@ dlink_node *p = NULL; 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; + p = n->prev; q = n->data; - if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns)) + /* Anything to process in the queue? */ + if (tvSubDsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit) break; + /* 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; + } debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); - p = n->prev; dlinkDelete(&q->lru, &lru_list); if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) { idnsSendQuery(q);