[tor-commits] [tor/master] Add an option to limit the number of non-open client circuits.

nickm at torproject.org nickm at torproject.org
Wed Jul 20 00:44:02 UTC 2011


commit aef30547dc4aa77fc79517a6dcad7712b59af371
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jul 7 14:54:54 2011 -0400

    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.
---
 src/or/circuituse.c |   35 +++++++++++++++++++++++++++++++++++
 src/or/config.c     |   10 ++++++++++
 src/or/or.h         |    5 +++++
 3 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 93098e5..dcb6bfa 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 */
diff --git a/src/or/config.c b/src/or/config.c
index 2ca9c66..14acf59 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -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),
@@ -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;
 
diff --git a/src/or/or.h b/src/or/or.h
index 97418f5..09907c3 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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. */





More information about the tor-commits mailing list