[tor-commits] [tor/release-0.3.2] Fix DNS resolution on busy exit relays

nickm at torproject.org nickm at torproject.org
Sun Nov 5 19:41:59 UTC 2017


commit 98275743081728b1538f70111c891ea573127e85
Author: Sebastian Hahn <sebastian at torproject.org>
Date:   Fri Nov 3 03:06:12 2017 +0100

    Fix DNS resolution on busy exit relays
    
    Thanks to Dhalgren who analyzed this issue two years ago and found a
    solution!
---
 changes/bug21394 |  9 +++++++++
 src/or/dns.c     | 23 ++++++++++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/changes/bug21394 b/changes/bug21394
new file mode 100644
index 000000000..e5452e20b
--- /dev/null
+++ b/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.
diff --git a/src/or/dns.c b/src/or/dns.c
index 0ad4c0f50..c1e3c3256 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1425,14 +1425,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





More information about the tor-commits mailing list