From 785176e97545b2e7fc65bb80cf7aa13c9adc3fc4 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 5 Oct 2016 12:38:03 -0400 Subject: [PATCH 1/2] Clean up and fix exit policy check in connection_exit_connect(). Previously, we would reject even rendezvous connections to IPv6 addresses when IPv6Exit was false. But that doesn't make sense; we don't count that as "exit"ing. I've corrected the logic and tried to make it a lottle more clear. Fixes bug 18357; this code has been wrong since 9016d9e8294a352 in 0.2.4.7-alpha. --- changes/bug18357 | 5 +++++ src/or/connection_edge.c | 22 +++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 changes/bug18357 diff --git a/changes/bug18357 b/changes/bug18357 new file mode 100644 index 0000000000..5f19d1454e --- /dev/null +++ b/changes/bug18357 @@ -0,0 +1,5 @@ + o Minor bugfixes (hidden service): + - Allow hidden services to run on IPv6 addresses even when the + IPv6Exit option is not set. Fixes bug 18357; bugfix on + 0.2.4.7-alpha. + diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 08e4fa5924..a1a0863387 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -3232,14 +3232,22 @@ connection_exit_connect(edge_connection_t *edge_conn) uint16_t port; connection_t *conn = TO_CONN(edge_conn); int socket_error = 0, result; + const char *why_failed_exit_policy = NULL; - if ( (!connection_edge_is_rendezvous_stream(edge_conn) && - router_compare_to_my_exit_policy(&edge_conn->base_.addr, - edge_conn->base_.port)) || - (tor_addr_family(&conn->addr) == AF_INET6 && - ! get_options()->IPv6Exit)) { - log_info(LD_EXIT,"%s:%d failed exit policy. Closing.", - escaped_safe_str_client(conn->address), conn->port); + if (! connection_edge_is_rendezvous_stream(edge_conn)) { + /* only apply exit policy to non-rendezvous connections. */ + if (router_compare_to_my_exit_policy(&edge_conn->base_.addr, + edge_conn->base_.port)) { + why_failed_exit_policy = ""; + } else if (tor_addr_family(&conn->addr) == AF_INET6 && + ! get_options()->IPv6Exit) { + why_failed_exit_policy = " (IPv6 address without IPv6Exit configured)"; + } + } + if (why_failed_exit_policy) { + log_info(LD_EXIT,"%s:%d failed exit policy%s. Closing.", + escaped_safe_str_client(conn->address), conn->port, + why_failed_exit_policy); connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY); circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn); connection_free(conn); From 87865c8aca0cc8c7ad4d4696a75e96b91fdf8734 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 14 Oct 2016 09:08:51 -0400 Subject: [PATCH 2/2] Extract ExitPolicy-and-IPv6Exit check into a new function (I've done this instead of changing the semantics of router_compare_to_my_exit_policy, because dns.c uses router_compare_to_my_exit_policy too, in a slightly weird way.) --- src/or/connection_edge.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index a1a0863387..788b7ee066 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -3218,6 +3218,24 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ) return 0; } +/** Helper: Return true and set *why_rejected to an optional clarifying + * message message iff we do not allow connections to addr:port. + */ +static int +my_exit_policy_rejects(const tor_addr_t *addr, + uint16_t port, + const char **why_rejected) +{ + if (router_compare_to_my_exit_policy(addr, port)) { + *why_rejected = ""; + return 1; + } else if (tor_addr_family(addr) == AF_INET6 && !get_options()->IPv6Exit) { + *why_rejected = " (IPv6 address without IPv6Exit configured)"; + return 1; + } + return 0; +} + /** Connect to conn's specified addr and port. If it worked, conn * has now been added to the connection_array. * @@ -3234,17 +3252,13 @@ connection_exit_connect(edge_connection_t *edge_conn) int socket_error = 0, result; const char *why_failed_exit_policy = NULL; - if (! connection_edge_is_rendezvous_stream(edge_conn)) { - /* only apply exit policy to non-rendezvous connections. */ - if (router_compare_to_my_exit_policy(&edge_conn->base_.addr, - edge_conn->base_.port)) { + /* Apply exit policy to non-rendezvous connections. */ + if (! connection_edge_is_rendezvous_stream(edge_conn) && + my_exit_policy_rejects(&edge_conn->base_.addr, + edge_conn->base_.port, + &why_failed_exit_policy)) { + if (BUG(!why_failed_exit_policy)) why_failed_exit_policy = ""; - } else if (tor_addr_family(&conn->addr) == AF_INET6 && - ! get_options()->IPv6Exit) { - why_failed_exit_policy = " (IPv6 address without IPv6Exit configured)"; - } - } - if (why_failed_exit_policy) { log_info(LD_EXIT,"%s:%d failed exit policy%s. Closing.", escaped_safe_str_client(conn->address), conn->port, why_failed_exit_policy);