Browse Source

Merge branch 'bug21394_029' into maint-0.3.2

Nick Mathewson 6 years ago
parent
commit
9f3d9c68ab
2 changed files with 29 additions and 3 deletions
  1. 9 0
      changes/bug21394
  2. 20 3
      src/or/dns.c

+ 9 - 0
changes/bug21394

@@ -0,0 +1,9 @@
+  o Major bugfixes (Exit nodes):
+    - Fix an issue causing high-bandwidth exit nodes to fail a majority
+      or all of their DNS requests, making them basically unsuitable for
+      regular usage in Tor circuits. The problem is related to
+      libevent's DNS handling, but we can work around it in Tor. Fixes
+      bugs 21394 and 18580; bugfix on 0.1.2.2-alpha which introduced
+      eventdns. Credit goes to Dhalgren for identifying and finding a
+      workaround to this bug and to gamambel, arthuredelstein and
+      arma in helping to track it down and analyze it.

+ 20 - 3
src/or/dns.c

@@ -1438,14 +1438,31 @@ configure_nameservers(int force)
 
 #define SET(k,v)  evdns_base_set_option(the_evdns_base, (k), (v))
 
+  // If we only have one nameserver, it does not make sense to back off
+  // from it for a timeout. Unfortunately, the value for max-timeouts is
+  // currently clamped by libevent to 255, but it does not hurt to set
+  // it higher in case libevent gets a patch for this.
+  // Reducing attempts in the case of just one name server too, because
+  // it is very likely to be a local one where a network connectivity
+  // issue should not cause an attempt to fail.
   if (evdns_base_count_nameservers(the_evdns_base) == 1) {
-    SET("max-timeouts:", "16");
-    SET("timeout:", "10");
+    SET("max-timeouts:", "1000000");
+    SET("attempts:", "1");
   } else {
     SET("max-timeouts:", "3");
-    SET("timeout:", "5");
   }
 
+  // Elongate the queue of maximum inflight dns requests, so if a bunch
+  // time out at the resolver (happens commonly with unbound) we won't
+  // stall every other DNS request. This potentially means some wasted
+  // CPU as there's a walk over a linear queue involved, but this is a
+  // much better tradeoff compared to just failing DNS requests because
+  // of a full queue.
+  SET("max-inflight:", "8192");
+
+  // Time out after 5 seconds if no reply.
+  SET("timeout:", "5");
+
   if (options->ServerDNSRandomizeCase)
     SET("randomize-case:", "1");
   else