aboutsummaryrefslogtreecommitdiff
path: root/src/or/circuituse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/circuituse.c')
-rw-r--r--src/or/circuituse.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 51d8716faa..d48449fa81 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -85,10 +85,14 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
}
if (purpose == CIRCUIT_PURPOSE_C_GENERAL ||
- purpose == CIRCUIT_PURPOSE_C_REND_JOINED)
+ purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
if (circ->timestamp_dirty &&
circ->timestamp_dirty+get_options()->MaxCircuitDirtiness <= now)
return 0;
+ }
+
+ if (origin_circ->unusable_for_new_conns)
+ return 0;
/* decide if this circ is suitable for this conn */
@@ -105,6 +109,8 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
return 0;
if (purpose == CIRCUIT_PURPOSE_C_GENERAL) {
+ tor_addr_t addr;
+ const int family = tor_addr_parse(&addr, conn->socks_request->address);
if (!exitnode && !build_state->onehop_tunnel) {
log_debug(LD_CIRC,"Not considering circuit with unknown router.");
return 0; /* this circuit is screwed and doesn't know it yet,
@@ -125,9 +131,7 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
return 0; /* this is a circuit to somewhere else */
if (tor_digest_is_zero(digest)) {
/* we don't know the digest; have to compare addr:port */
- tor_addr_t addr;
- int r = tor_addr_parse(&addr, conn->socks_request->address);
- if (r < 0 ||
+ if (family < 0 ||
!tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
build_state->chosen_exit->port != conn->socks_request->port)
return 0;
@@ -139,6 +143,13 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
return 0;
}
}
+ if (origin_circ->prepend_policy && family != -1) {
+ int r = compare_tor_addr_to_addr_policy(&addr,
+ conn->socks_request->port,
+ origin_circ->prepend_policy);
+ if (r == ADDR_POLICY_REJECTED)
+ return 0;
+ }
if (exitnode && !connection_ap_can_use_exit(conn, exitnode)) {
/* can't exit from this router */
return 0;
@@ -799,9 +810,12 @@ circuit_stream_is_being_handled(entry_connection_t *conn,
circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
(!circ->timestamp_dirty ||
circ->timestamp_dirty + get_options()->MaxCircuitDirtiness > now)) {
- cpath_build_state_t *build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
+ origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
+ cpath_build_state_t *build_state = origin_circ->build_state;
if (build_state->is_internal || build_state->onehop_tunnel)
continue;
+ if (!origin_circ->unusable_for_new_conns)
+ continue;
exitnode = build_state_get_exit_node(build_state);
if (exitnode && (!need_uptime || build_state->need_uptime)) {
@@ -843,6 +857,7 @@ circuit_predict_and_launch_new(void)
/* First, count how many of each type of circuit we have already. */
for (circ=global_circuitlist;circ;circ = circ->next) {
cpath_build_state_t *build_state;
+ origin_circuit_t *origin_circ;
if (!CIRCUIT_IS_ORIGIN(circ))
continue;
if (circ->marked_for_close)
@@ -851,7 +866,10 @@ circuit_predict_and_launch_new(void)
continue; /* only count clean circs */
if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL)
continue; /* only pay attention to general-purpose circs */
- build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
+ origin_circ = TO_ORIGIN_CIRCUIT(circ);
+ if (origin_circ->unusable_for_new_conns)
+ continue;
+ build_state = origin_circ->build_state;
if (build_state->onehop_tunnel)
continue;
num++;
@@ -2275,3 +2293,22 @@ circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
}
}
+/** Mark <b>circ</b> so that no more connections can be attached to it. */
+void
+mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
+{
+ const or_options_t *options = get_options();
+ tor_assert(circ);
+
+ /* XXXX025 This is a kludge; we're only keeping it around in case there's
+ * something that doesn't check unusable_for_new_conns, and to avoid
+ * deeper refactoring of our expiration logic. */
+ if (! circ->base_.timestamp_dirty)
+ circ->base_.timestamp_dirty = approx_time();
+ if (options->MaxCircuitDirtiness >= circ->base_.timestamp_dirty)
+ circ->base_.timestamp_dirty = 1; /* prevent underflow */
+ else
+ circ->base_.timestamp_dirty -= options->MaxCircuitDirtiness;
+
+ circ->unusable_for_new_conns = 1;
+}