Loading src/or/circuituse.c +35 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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 */ Loading src/or/config.c +10 −0 Original line number Diff line number Diff line Loading @@ -315,6 +315,7 @@ static config_var_t _option_vars[] = { VAR("MapAddress", LINELIST, AddressMap, NULL), V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"), V(MaxCircuitDirtiness, INTERVAL, "10 minutes"), V(MaxClientCircuitsPending, UINT, "32"), V(MaxOnionsPending, UINT, "100"), OBSOLETE("MonthlyAccountingStart"), V(MyFamily, STRING, NULL), Loading Loading @@ -3215,6 +3216,15 @@ options_validate(or_options_t *old_options, or_options_t *options, return -1; } if (options->MaxClientCircuitsPending <= 0 || options->MaxClientCircuitsPending > MAX_MAX_CLIENT_CIRCUITS_PENDING) { tor_asprintf(msg, "MaxClientCircuitsPending must be between 1 and %d, but " "was set to %d", MAX_MAX_CLIENT_CIRCUITS_PENDING, options->MaxClientCircuitsPending); return -1; } if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0) return -1; Loading src/or/or.h +5 −0 Original line number Diff line number Diff line Loading @@ -3230,6 +3230,11 @@ typedef struct { /** Should that file be group-readable? */ int ControlPortFileGroupReadable; #define MAX_MAX_CLIENT_CIRCUITS_PENDING 1024 /** Maximum number of non-open general-purpose origin circuits to allow at * once. */ int MaxClientCircuitsPending; } or_options_t; /** Persistent state for an onion router, as saved to disk. */ Loading Loading
src/or/circuituse.c +35 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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 */ Loading
src/or/config.c +10 −0 Original line number Diff line number Diff line Loading @@ -315,6 +315,7 @@ static config_var_t _option_vars[] = { VAR("MapAddress", LINELIST, AddressMap, NULL), V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"), V(MaxCircuitDirtiness, INTERVAL, "10 minutes"), V(MaxClientCircuitsPending, UINT, "32"), V(MaxOnionsPending, UINT, "100"), OBSOLETE("MonthlyAccountingStart"), V(MyFamily, STRING, NULL), Loading Loading @@ -3215,6 +3216,15 @@ options_validate(or_options_t *old_options, or_options_t *options, return -1; } if (options->MaxClientCircuitsPending <= 0 || options->MaxClientCircuitsPending > MAX_MAX_CLIENT_CIRCUITS_PENDING) { tor_asprintf(msg, "MaxClientCircuitsPending must be between 1 and %d, but " "was set to %d", MAX_MAX_CLIENT_CIRCUITS_PENDING, options->MaxClientCircuitsPending); return -1; } if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0) return -1; Loading
src/or/or.h +5 −0 Original line number Diff line number Diff line Loading @@ -3230,6 +3230,11 @@ typedef struct { /** Should that file be group-readable? */ int ControlPortFileGroupReadable; #define MAX_MAX_CLIENT_CIRCUITS_PENDING 1024 /** Maximum number of non-open general-purpose origin circuits to allow at * once. */ int MaxClientCircuitsPending; } or_options_t; /** Persistent state for an onion router, as saved to disk. */ Loading