aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r--src/or/connection_edge.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index b1e952d46..47230da2e 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -2840,9 +2840,13 @@ connection_edge_is_rendezvous_stream(edge_connection_t *conn)
* to exit from it, or 0 if it probably will not allow it.
* (We might be uncertain if conn's destination address has not yet been
* resolved.)
+ *
+ * If <b>excluded_means_no</b> is 1 and Exclude*Nodes is set and excludes
+ * this relay, return 0.
*/
int
-connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
+connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+ int excluded_means_no)
{
tor_assert(conn);
tor_assert(conn->_base.type == CONN_TYPE_AP);
@@ -2889,6 +2893,21 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
if (!conn->chosen_exit_name && policy_is_reject_star(exit->exit_policy))
return 0;
}
+ if (options->_ExcludeExitNodesUnion &&
+ (options->StrictNodes || excluded_means_no) &&
+ routerset_contains_router(options->_ExcludeExitNodesUnion, exit)) {
+ /* If we are trying to avoid this node as exit, and we have StrictNodes
+ * set, then this is not a suitable exit. Refuse it.
+ *
+ * If we don't have StrictNodes set, then this function gets called in
+ * two contexts. First, we've got a circuit open and we want to know
+ * whether we can use it. In that case, we somehow built this circuit
+ * despite having the last hop in ExcludeExitNodes, so we should be
+ * willing to use it. Second, we are evaluating whether this is an
+ * acceptable exit for a new circuit. In that case, skip it. */
+ return 0;
+ }
+
return 1;
}