diff options
-rw-r--r-- | changes/bug21394 | 9 | ||||
-rw-r--r-- | changes/bug23318 | 7 | ||||
-rw-r--r-- | changes/ticket21031 | 7 | ||||
-rw-r--r-- | doc/tor.1.txt | 17 | ||||
-rwxr-xr-x | scripts/maint/lintChanges.py | 4 | ||||
-rw-r--r-- | src/or/config.c | 18 | ||||
-rw-r--r-- | src/or/connection_edge.c | 2 | ||||
-rw-r--r-- | src/or/dns.c | 23 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/relay.c | 6 | ||||
-rw-r--r-- | src/or/routerlist.c | 2 | ||||
-rw-r--r-- | src/or/scheduler.c | 2 | ||||
-rw-r--r-- | src/test/test_options.c | 5 | ||||
-rw-r--r-- | src/test/test_relaycell.c | 4 |
14 files changed, 77 insertions, 31 deletions
diff --git a/changes/bug21394 b/changes/bug21394 new file mode 100644 index 0000000000..e5452e20ba --- /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/changes/bug23318 b/changes/bug23318 new file mode 100644 index 0000000000..32c85eb194 --- /dev/null +++ b/changes/bug23318 @@ -0,0 +1,7 @@ + o Minor bugfixes (path selection): + - When selecting relays by bandwidth, avoid a rounding error that + could sometimes cause load to be imbalanced incorrectly. Previously, + we would always round upwards; now, we round towards the nearest + integer. This had the biggest effect when a relay's weight adjustments + should have given it weight 0, but it got weight 1 instead. + Fixes bug 23318; bugfix on 0.2.4.3-alpha. diff --git a/changes/ticket21031 b/changes/ticket21031 new file mode 100644 index 0000000000..b081fb018f --- /dev/null +++ b/changes/ticket21031 @@ -0,0 +1,7 @@ + o Minor features (removed deprecations): + - The ClientDNSRejectInternalAddresses flag can once again be set in + non-testing Tor networks, so long as they do not use the default + directory authorities. + This change also removes the deprecation of this + flag in 0.2.9.2-alpha. Closes ticket 21031. + diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 86999667a5..f052464332 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -1440,9 +1440,15 @@ The following options are useful only for clients (that is, if addresses/ports. See SocksPort for an explanation of isolation flags. (Default: 0) +[[ClientDNSRejectInternalAddresses]] **ClientDNSRejectInternalAddresses** **0**|**1**:: + If true, Tor does not believe any anonymously retrieved DNS answer that + tells it that an address resolves to an internal address (like 127.0.0.1 or + 192.168.0.1). This option prevents certain browser-based attacks; it + is not allowed to be set on the default network. (Default: 1) + [[ClientRejectInternalAddresses]] **ClientRejectInternalAddresses** **0**|**1**:: If true, Tor does not try to fulfill requests to connect to an internal - address (like 127.0.0.1 or 192.168.0.1) __unless a exit node is + address (like 127.0.0.1 or 192.168.0.1) __unless an exit node is specifically requested__ (for example, via a .exit hostname, or a controller request). If true, multicast DNS hostnames for machines on the local network (of the form *.local) are also rejected. (Default: 1) @@ -2507,7 +2513,7 @@ The following options are used for running a testing Tor network. 4 (for 40 seconds), 8, 16, 32, 60 ClientBootstrapConsensusMaxDownloadTries 80 ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries 80 - TestingClientDNSRejectInternalAddresses 0 + ClientDNSRejectInternalAddresses 0 ClientRejectInternalAddresses 0 CountPrivateBandwidth 1 ExitPolicyRejectPrivate 0 @@ -2718,13 +2724,6 @@ The following options are used for running a testing Tor network. we replace it and issue a new key? (Default: 3 hours for link and auth; 1 day for signing.) -[[ClientDNSRejectInternalAddresses]] [[TestingClientDNSRejectInternalAddresses]] **TestingClientDNSRejectInternalAddresses** **0**|**1**:: - If true, Tor does not believe any anonymously retrieved DNS answer that - tells it that an address resolves to an internal address (like 127.0.0.1 or - 192.168.0.1). This option prevents certain browser-based attacks; don't - turn it off unless you know what you're doing. (Default: 1) - - NON-PERSISTENT OPTIONS ---------------------- diff --git a/scripts/maint/lintChanges.py b/scripts/maint/lintChanges.py index c2dda6dc81..d5b8fcae5c 100755 --- 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/config.c b/src/or/config.c index e7fe3a5470..d6e1abaa10 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -169,8 +169,6 @@ static config_abbrev_t option_abbrevs_[] = { { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0}, { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0}, { "VirtualAddrNetwork", "VirtualAddrNetworkIPv4", 0, 0}, - { "ClientDNSRejectInternalAddresses", - "TestingClientDNSRejectInternalAddresses", 0, 1, }, { NULL, NULL, 0, 0}, }; @@ -262,7 +260,7 @@ static config_var_t option_vars_[] = { V(CircuitsAvailableTimeout, INTERVAL, "0"), V(CircuitStreamTimeout, INTERVAL, "0"), V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/ - V(TestingClientDNSRejectInternalAddresses, BOOL,"1"), + V(ClientDNSRejectInternalAddresses, BOOL,"1"), V(ClientOnly, BOOL, "0"), V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"), V(ClientPreferIPv6DirPort, AUTOBOOL, "auto"), @@ -648,7 +646,7 @@ static const config_var_t testing_tor_network_defaults[] = { "0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"), V(ClientBootstrapConsensusMaxDownloadTries, UINT, "80"), V(ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries, UINT, "80"), - V(TestingClientDNSRejectInternalAddresses, BOOL,"0"), + V(ClientDNSRejectInternalAddresses, BOOL,"0"), V(ClientRejectInternalAddresses, BOOL, "0"), V(CountPrivateBandwidth, BOOL, "1"), V(ExitPolicyRejectPrivate, BOOL, "0"), @@ -693,7 +691,12 @@ static const config_var_t testing_tor_network_defaults[] = { #undef OBSOLETE static const config_deprecation_t option_deprecation_notes_[] = { - /* Deprecated since 0.3.2.1-alpha. */ + /* Deprecated since 0.2.9.2-alpha... */ + { "AllowDotExit", "Unrestricted use of the .exit notation can be used for " + "a wide variety of application-level attacks." }, + /* End of options deprecated since 0.2.9.2-alpha. */ + + /* Deprecated since 0.3.2.0-alpha. */ { "HTTPProxy", "It only applies to direct unencrypted HTTP connections " "to your directory server, which your Tor probably wasn't using." }, { "HTTPProxyAuthenticator", "HTTPProxy is deprecated in favor of HTTPSProxy " @@ -4211,9 +4214,12 @@ options_validate(or_options_t *old_options, or_options_t *options, CHECK_DEFAULT(TestingSigningKeySlop); CHECK_DEFAULT(TestingAuthKeySlop); CHECK_DEFAULT(TestingLinkKeySlop); - CHECK_DEFAULT(TestingClientDNSRejectInternalAddresses); #undef CHECK_DEFAULT + if (!options->ClientDNSRejectInternalAddresses && + !(options->DirAuthorities || + (options->AlternateDirAuthority && options->AlternateBridgeAuthority))) + REJECT("ClientDNSRejectInternalAddresses used for default network."); if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2) REJECT("SigningKeyLifetime is too short."); if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index b9d8eeaff6..f178917f0b 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1344,7 +1344,7 @@ connection_ap_handshake_rewrite(entry_connection_t *conn, /* Hang on, did we find an answer saying that this is a reverse lookup for * an internal address? If so, we should reject it if we're configured to * do so. */ - if (options->TestingClientDNSRejectInternalAddresses) { + if (options->ClientDNSRejectInternalAddresses) { /* Don't let clients try to do a reverse lookup on 10.0.0.1. */ tor_addr_t addr; int ok; diff --git a/src/or/dns.c b/src/or/dns.c index 078bde3ef2..4194a29a6b 100644 --- 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 diff --git a/src/or/or.h b/src/or/or.h index d9ab815cbc..809714b5e2 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4204,7 +4204,7 @@ typedef struct { /** If true, do not believe anybody who tells us that a domain resolves * to an internal address, or that an internal address has a PTR mapping. * Helps avoid some cross-site attacks. */ - int TestingClientDNSRejectInternalAddresses; + int ClientDNSRejectInternalAddresses; /** If true, do not accept any requests to connect to internal addresses * over randomly chosen exits. */ diff --git a/src/or/relay.c b/src/or/relay.c index 48c1dd6f8d..09f70793d3 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -949,7 +949,7 @@ connection_ap_process_end_not_open( connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); return 0; } - if (get_options()->TestingClientDNSRejectInternalAddresses && + if (get_options()->ClientDNSRejectInternalAddresses && tor_addr_is_internal(&addr, 0)) { log_info(LD_APP,"Address '%s' resolved to internal. Closing,", safe_str(conn->socks_request->address)); @@ -1366,7 +1366,7 @@ connection_edge_process_resolved_cell(edge_connection_t *conn, goto done; } - if (get_options()->TestingClientDNSRejectInternalAddresses) { + if (get_options()->ClientDNSRejectInternalAddresses) { int orig_len = smartlist_len(resolved_addresses); SMARTLIST_FOREACH_BEGIN(resolved_addresses, address_ttl_t *, addr) { if (addr->hostname == NULL && tor_addr_is_internal(&addr->addr, 0)) { @@ -1459,7 +1459,7 @@ connection_edge_process_relay_cell_not_open( if (tor_addr_family(&addr) != AF_UNSPEC) { const sa_family_t family = tor_addr_family(&addr); if (tor_addr_is_null(&addr) || - (get_options()->TestingClientDNSRejectInternalAddresses && + (get_options()->ClientDNSRejectInternalAddresses && tor_addr_is_internal(&addr, 0))) { log_info(LD_APP, "...but it claims the IP address was %s. Closing.", fmt_addr(&addr)); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index c7c1092539..f0bd343f45 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2706,7 +2706,7 @@ compute_weighted_bandwidths(const smartlist_t *sl, final_weight = weight*this_bw; } - bandwidths[node_sl_idx] = final_weight + 0.5; + bandwidths[node_sl_idx] = final_weight; } SMARTLIST_FOREACH_END(node); log_debug(LD_CIRC, "Generated weighted bandwidths for rule %s based " diff --git a/src/or/scheduler.c b/src/or/scheduler.c index 97b6d40b1e..1438dc60f6 100644 --- a/src/or/scheduler.c +++ b/src/or/scheduler.c @@ -687,7 +687,7 @@ scheduler_bug_occurred(const channel_t *chan) chan->global_identifier, channel_state_to_string(chan->state), chan->scheduler_state, circuitmux_num_cells(chan->cmux), - outbuf_len); + (unsigned long)outbuf_len); } { diff --git a/src/test/test_options.c b/src/test/test_options.c index c55be35845..62732cabf7 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -398,11 +398,12 @@ fixed_get_uname(void) "V3AuthVoteDelay 20\n" \ "V3AuthDistDelay 20\n" \ "V3AuthNIntervalsValid 3\n" \ - "ClientUseIPv4 1\n" \ + "ClientUseIPv4 1\n" \ "VirtualAddrNetworkIPv4 127.192.0.0/10\n" \ "VirtualAddrNetworkIPv6 [FE80::]/10\n" \ "UseEntryGuards 1\n" \ - "Schedulers Vanilla\n" + "Schedulers Vanilla\n" \ + "ClientDNSRejectInternalAddresses 1\n" typedef struct { or_options_t *old_opt; diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c index 9c010deece..eea1f5dc80 100644 --- a/src/test/test_relaycell.c +++ b/src/test/test_relaycell.c @@ -112,7 +112,7 @@ test_relaycell_resolved(void *arg) MOCK(connection_mark_unattached_ap_, mark_unattached_mock); MOCK(connection_ap_handshake_socks_resolved, socks_resolved_mock); - options->TestingClientDNSRejectInternalAddresses = 0; + options->ClientDNSRejectInternalAddresses = 0; SET_CELL(/* IPv4: 127.0.1.2, ttl 256 */ "\x04\x04\x7f\x00\x01\x02\x00\x00\x01\x00" @@ -151,7 +151,7 @@ test_relaycell_resolved(void *arg) /* But we may be discarding private answers. */ MOCK_RESET(); - options->TestingClientDNSRejectInternalAddresses = 1; + options->ClientDNSRejectInternalAddresses = 1; r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh); tt_int_op(r, OP_EQ, 0); ASSERT_MARK_CALLED(END_STREAM_REASON_DONE| |