diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-07 14:54:54 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-19 01:58:45 -0400 |
commit | aef30547dc4aa77fc79517a6dcad7712b59af371 (patch) | |
tree | d73ae474b559433a0ff40b0a8930b034478e7df2 /src/or/circuituse.c | |
parent | 20c0581a7935369fecb6c62b7cf5c7c244cdb533 (diff) | |
download | tor-aef30547dc4aa77fc79517a6dcad7712b59af371.tar.gz tor-aef30547dc4aa77fc79517a6dcad7712b59af371.zip |
Add an option to limit the number of non-open client circuits.
This is mainly meant as a way to keep clients from accidentally
DOSing themselves by (e.g.) enabling IsolateDestAddr or
IsolateDestPort on a port that they use for HTTP.
Diffstat (limited to 'src/or/circuituse.c')
-rw-r--r-- | src/or/circuituse.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 93098e527d..dcb6bfa501 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -288,6 +288,27 @@ circuit_get_best(const edge_connection_t *conn, return best; } +/** Return the number of not-yet-open general-purpose origin circuits. */ +static int +count_pending_general_client_circuits(void) +{ + const circuit_t *circ; + + int count = 0; + + for (circ = global_circuitlist; circ; circ = circ->next) { + if (circ->marked_for_close || + circ->state == CIRCUIT_STATE_OPEN || + circ->purpose != CIRCUIT_PURPOSE_C_GENERAL || + !CIRCUIT_IS_ORIGIN(circ)) + continue; + + ++count; + } + + return count; +} + #if 0 /** Check whether, according to the policies in <b>options</b>, the * circuit <b>circ</b> makes sense. */ @@ -1347,6 +1368,20 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, if (!circ) { extend_info_t *extend_info=NULL; uint8_t new_circ_purpose; + const int n_pending = count_pending_general_client_circuits(); + + if (n_pending >= options->MaxClientCircuitsPending) { + static ratelim_t delay_limit = RATELIM_INIT(10*60); + char *m; + if ((m = rate_limit_log(&delay_limit, approx_time()))) { + log_notice(LD_APP, "We'd like to launch a circuit to handle a " + "connection, but we already have %d general-purpose client " + "circuits pending. Waiting until some finish.", + n_pending); + tor_free(m); + } + return 0; + } if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { /* need to pick an intro point */ |