]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 2393: DNS requests getting stuck in idns queue
authorAmos Jeffries <squid3@treenet.co.nz>
Sat, 11 Oct 2008 13:59:29 +0000 (02:59 +1300)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 11 Oct 2008 13:59:29 +0000 (02:59 +1300)
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

index dab4b94c1fcb81243e9942ca734084c73b8a8687..e179173457b919aa4f54bb93f35722d896d7fa2c 100755 (executable)
@@ -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<idns_query*>(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);