From a89852636cec9c2037b6dde8f0dffea61f2cda5c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 17 Dec 2008 13:14:54 +0000 Subject: [PATCH] Backport r17139: Fix another case of refusing to use a chosen exit node because we think it will reject _mostly_ everything. Based on patch from rovv. See bug 752. svn:r17640 --- ChangeLog | 3 +++ doc/TODO.020 | 2 +- src/or/circuituse.c | 43 ++++++++++++++++++++++++++++++++----------- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37c68561d..3d8e10434 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,9 @@ Changes in version 0.2.0.33 - 200?-??-?? - When we're choosing an exit node for a circuit, and we have no pending streams, choose a good general exit rather than one that supports "all the pending streams". Bugfix on 0.1.1.x. (Fix by rovv.) + - Fix another case of assuming, when a specific exit is requested, + that we know more than the user about what hosts it allows. + Fixes one case of bug 752. Patch from rovv. o Minor features: - Report the case where all signatures in a detached set are rejected diff --git a/doc/TODO.020 b/doc/TODO.020 index fcbd39a20..f532f9161 100644 --- a/doc/TODO.020 +++ b/doc/TODO.020 @@ -18,7 +18,7 @@ Backport for 0.2.0 once better tested: o ... and r17184. - r17137: send END cell in response to connect to nonexistent hidserv port. - r17138: reject *:* servers should never do DNS lookups. - - r17139: Fix another case of overriding .exit choices. + o r17139: Fix another case of overriding .exit choices. - r17162 and r17164: fix another case of not checking cpath_layer. - r17208,r17209,r7211,r17212,r17214: Avoid gotterdammerung when an authority has an expired certificate. diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 96a7e21ef..ea8224140 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1015,17 +1015,38 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, /* Do we need to check exit policy? */ if (check_exit_policy) { - struct in_addr in; - uint32_t addr = 0; - if (tor_inet_aton(conn->socks_request->address, &in)) - addr = ntohl(in.s_addr); - if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port, - need_uptime)) { - log_notice(LD_APP, - "No Tor server exists that allows exit to %s:%d. Rejecting.", - safe_str(conn->socks_request->address), - conn->socks_request->port); - return -1; + if (!conn->chosen_exit_name) { + struct in_addr in; + uint32_t addr = 0; + if (tor_inet_aton(conn->socks_request->address, &in)) + addr = ntohl(in.s_addr); + if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port, + need_uptime)) { + log_notice(LD_APP, + "No Tor server exists that allows exit to %s:%d. Rejecting.", + safe_str(conn->socks_request->address), + conn->socks_request->port); + return -1; + } + } else { + /* XXXX021 Duplicates checks in connection_ap_handshake_attach_circuit + * XXXX021 Fix this, then backport it? */ + routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1); + int opt = conn->_base.chosen_exit_optional; + if (router && !connection_ap_can_use_exit(conn, router)) { + log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP, + "Requested exit point '%s' would refuse request. %s.", + conn->chosen_exit_name, opt ? "Trying others" : "Closing"); + if (opt) { + conn->_base.chosen_exit_optional = 0; + tor_free(conn->chosen_exit_name); + /* Try again. */ + return circuit_get_open_circ_or_launch(conn, + desired_circuit_purpose, + circp); + } + return -1; + } } }