tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit f755f9b9e67232d9d39682cbcdf4433ac738e17a
parent 9f650b24e97c69216b0d85d20b8363ce1a2488de
Author: Nick Mathewson <nickm@torproject.org>
Date:   Sun,  5 Nov 2017 14:41:53 -0500

Merge branch 'maint-0.3.2'

Diffstat:
Achanges/bug21394 | 9+++++++++
Mscripts/maint/lintChanges.py | 4++--
Msrc/or/dns.c | 23++++++++++++++++++++---
3 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/changes/bug21394 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/scripts/maint/lintChanges.py b/scripts/maint/lintChanges.py @@ -76,13 +76,13 @@ def lintfile(fname): if isBug and not re.search(r'(\d+)', contents): warn("Ticket marked as bugfix, but does not mention a number.") - elif isBug and not re.search(r'Fixes ([a-z ]*)bug (\d+)', contents): + elif isBug and not re.search(r'Fixes ([a-z ]*)bugs? (\d+)', contents): warn("Ticket marked as bugfix, but does not say 'Fixes bug XXX'") if re.search(r'[bB]ug (\d+)', contents): if not re.search(r'[Bb]ugfix on ', contents): warn("Bugfix does not say 'bugfix on X.Y.Z'") - elif not re.search('[fF]ixes ([a-z ]*)bug (\d+); bugfix on ', + elif not re.search('[fF]ixes ([a-z ]*)bugs? (\d+)((, \d+)* and \d+)?; bugfix on ', contents): warn("Bugfix does not say 'Fixes bug X; bugfix on Y'") elif re.search('tor-([0-9]+)', contents): diff --git a/src/or/dns.c b/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