[tor-commits] [tor/master] Add support for 'HiddenServiceMaxStream' to 'ADD_ONION'.

nickm at torproject.org nickm at torproject.org
Thu May 21 14:48:59 UTC 2015


commit 712bf069781d7a6336501aab628f62ada4f4c4d7
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Wed May 20 17:41:27 2015 +0000

    Add support for 'HiddenServiceMaxStream' to 'ADD_ONION'.
    
    Done as a separate commit to ease backporting the tunables to 0.2.6.x.
---
 src/or/control.c     |   21 ++++++++++++++++++++-
 src/or/rendservice.c |   26 +++++++++++++++++++++++++-
 src/or/rendservice.h |    2 ++
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/src/or/control.c b/src/or/control.c
index 4eeb897..746dfff 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -3566,9 +3566,12 @@ handle_control_add_onion(control_connection_t *conn,
   smartlist_t *port_cfgs = smartlist_new();
   int discard_pk = 0;
   int detach = 0;
+  int max_streams = 0;
+  int max_streams_close_circuit = 0;
   for (size_t i = 1; i < arg_len; i++) {
     static const char *port_prefix = "Port=";
     static const char *flags_prefix = "Flags=";
+    static const char *max_s_prefix = "MaxStreams=";
 
     const char *arg = smartlist_get(args, i);
     if (!strcasecmpstart(arg, port_prefix)) {
@@ -3582,15 +3585,27 @@ handle_control_add_onion(control_connection_t *conn,
         goto out;
       }
       smartlist_add(port_cfgs, cfg);
+    } else if (!strcasecmpstart(arg, max_s_prefix)) {
+      /* "MaxStreams=[0..65535]". */
+      const char *max_s_str = arg + strlen(max_s_prefix);
+      int ok = 0;
+      max_streams = (int)tor_parse_long(max_s_str, 10, 0, 65535, &ok, NULL);
+      if (!ok) {
+        connection_printf_to_buf(conn, "512 Invalid MaxStreams\r\n");
+        goto out;
+      }
     } else if (!strcasecmpstart(arg, flags_prefix)) {
       /* "Flags=Flag[,Flag]", where Flag can be:
        *   * 'DiscardPK' - If tor generates the keypair, do not include it in
        *                   the response.
        *   * 'Detach' - Do not tie this onion service to any particular control
        *                connection.
+       *   * 'MaxStreamsCloseCircuit' - Close the circuit if MaxStreams is
+       *                                exceeded.
        */
       static const char *discard_flag = "DiscardPK";
       static const char *detach_flag = "Detach";
+      static const char *max_s_close_flag = "MaxStreamsCloseCircuit";
 
       smartlist_t *flags = smartlist_new();
       int bad = 0;
@@ -3607,6 +3622,8 @@ handle_control_add_onion(control_connection_t *conn,
           discard_pk = 1;
         } else if (!strcasecmp(flag, detach_flag)) {
           detach = 1;
+        } else if (!strcasecmp(flag, max_s_close_flag)) {
+          max_streams_close_circuit = 1;
         } else {
           connection_printf_to_buf(conn,
                                    "512 Invalid 'Flags' argument: %s\r\n",
@@ -3652,7 +3669,9 @@ handle_control_add_onion(control_connection_t *conn,
    * regardless of success/failure.
    */
   char *service_id = NULL;
-  int ret = rend_service_add_ephemeral(pk, port_cfgs, &service_id);
+  int ret = rend_service_add_ephemeral(pk, port_cfgs, max_streams,
+                                       max_streams_close_circuit,
+                                       &service_id);
   port_cfgs = NULL; /* port_cfgs is now owned by the rendservice code. */
   switch (ret) {
   case RSAE_OKAY:
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 5d2225e..0329d70 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -266,6 +266,23 @@ rend_add_service(rend_service_t *service)
 
   service->intro_nodes = smartlist_new();
 
+  if (service->max_streams_per_circuit < 0) {
+    log_warn(LD_CONFIG, "Hidden service (%s) configured with negative max "
+                        "streams per circuit; ignoring.",
+             rend_service_escaped_dir(service));
+    rend_service_free(service);
+    return -1;
+  }
+
+  if (service->max_streams_close_circuit < 0 ||
+      service->max_streams_close_circuit > 1) {
+    log_warn(LD_CONFIG, "Hidden service (%s) configured with invalid "
+                        "max streams handling; ignoring.",
+             rend_service_escaped_dir(service));
+    rend_service_free(service);
+    return -1;
+  }
+
   if (service->auth_type != REND_NO_AUTH &&
       smartlist_len(service->clients) == 0) {
     log_warn(LD_CONFIG, "Hidden service (%s) with client authorization but no "
@@ -792,7 +809,10 @@ rend_config_services(const or_options_t *options, int validate_only)
   return 0;
 }
 
-/** Add the ephemeral service <b>pk</b>/<b>ports</b> if possible.
+/** Add the ephemeral service <b>pk</b>/<b>ports</b> if possible, with
+ * <b>max_streams_per_circuit</b> streams allowed per rendezvous circuit,
+ * and circuit closure on max streams being exceeded set by
+ * <b>max_streams_close_circuit</b>.
  *
  * Regardless of sucess/failure, callers should not touch pk/ports after
  * calling this routine, and may assume that correct cleanup has been done
@@ -803,6 +823,8 @@ rend_config_services(const or_options_t *options, int validate_only)
 rend_service_add_ephemeral_status_t
 rend_service_add_ephemeral(crypto_pk_t *pk,
                            smartlist_t *ports,
+                           int max_streams_per_circuit,
+                           int max_streams_close_circuit,
                            char **service_id_out)
 {
   *service_id_out = NULL;
@@ -816,6 +838,8 @@ rend_service_add_ephemeral(crypto_pk_t *pk,
   s->ports = ports;
   s->intro_period_started = time(NULL);
   s->n_intro_points_wanted = NUM_INTRO_POINTS_DEFAULT;
+  s->max_streams_per_circuit = max_streams_per_circuit;
+  s->max_streams_close_circuit = max_streams_close_circuit;
   if (rend_service_derive_key_digests(s) < 0) {
     rend_service_free(s);
     return RSAE_BADPRIVKEY;
diff --git a/src/or/rendservice.h b/src/or/rendservice.h
index ec783d5..b540d2c 100644
--- a/src/or/rendservice.h
+++ b/src/or/rendservice.h
@@ -117,6 +117,8 @@ typedef enum {
 } rend_service_add_ephemeral_status_t;
 rend_service_add_ephemeral_status_t rend_service_add_ephemeral(crypto_pk_t *pk,
                                smartlist_t *ports,
+                               int max_streams_per_circuit,
+                               int max_streams_close_circuit,
                                char **service_id_out);
 int rend_service_del_ephemeral(const char *service_id);
 





More information about the tor-commits mailing list