[or-cvs] [tor/master 2/8] Allow "EXTENDCIRCUIT 0" to omit a path.

nickm at torproject.org nickm at torproject.org
Sat Feb 20 23:35:28 UTC 2010


Author: Mike Perry <mikeperry-git at fscked.org>
Date: Tue, 29 Dec 2009 04:17:12 +0100
Subject: Allow "EXTENDCIRCUIT 0" to omit a path.
Commit: ac68704f07c2b70321b72e3b8665cb6d12da7e6b

---
 doc/spec/control-spec.txt |   19 ++++++++++------
 src/or/control.c          |   53 +++++++++++++++++++++++++++++++++++---------
 2 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/doc/spec/control-spec.txt b/doc/spec/control-spec.txt
index 4057ffa..7d3312a 100644
--- a/doc/spec/control-spec.txt
+++ b/doc/spec/control-spec.txt
@@ -606,15 +606,20 @@
 3.10. EXTENDCIRCUIT
 
   Sent from the client to the server.  The format is:
-      "EXTENDCIRCUIT" SP CircuitID SP
-                      ServerSpec *("," ServerSpec)
-                      [SP "purpose=" Purpose] CRLF
+      "EXTENDCIRCUIT" SP CircuitID
+                      [SP ServerSpec *("," ServerSpec)
+                       SP "purpose=" Purpose] CRLF
 
   This request takes one of two forms: either the CircuitID is zero, in
-  which case it is a request for the server to build a new circuit according
-  to the specified path, or the CircuitID is nonzero, in which case it is a
-  request for the server to extend an existing circuit with that ID according
-  to the specified path.
+  which case it is a request for the server to build a new circuit,
+  or the CircuitID is nonzero, in which case it is a request for the
+  server to extend an existing circuit with that ID according to the
+  specified path.
+
+  If the CircuitID is 0, the controller has the option of providing
+  a path for Tor to use to build the circuit. If it does not provide
+  a path, Tor will select one automatically from high capacity nodes
+  according to path-spec.txt.
 
   If CircuitID is 0 and "purpose=" is specified, then the circuit's
   purpose is set. Two choices are recognized: "general" and
diff --git a/src/or/control.c b/src/or/control.c
index c34848d..a7e60d5 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -2055,27 +2055,58 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
 
   router_nicknames = smartlist_create();
 
-  args = getargs_helper("EXTENDCIRCUIT", conn, body, 2, -1);
+  args = getargs_helper("EXTENDCIRCUIT", conn, body, 1, -1);
   if (!args)
     goto done;
 
   zero_circ = !strcmp("0", (char*)smartlist_get(args,0));
+
+  if (zero_circ) {
+    char *purp = NULL;
+    if (smartlist_len(args) == 2) {
+      // "EXTENDCIRCUIT 0 PURPOSE=foo"
+      purp = smartlist_get(args,1);
+    } else if (smartlist_len(args) == 3) {
+      // "EXTENDCIRCUIT 0 router1,router2 PURPOSE=foo"
+      purp = smartlist_get(args,2);
+    }
+
+    if (purp && strcmpstart(purp, "purpose=") != 0)
+      purp = NULL;
+
+    if (purp) {
+      intended_purpose = circuit_purpose_from_string(purp);
+      if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) {
+        connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
+        SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+        smartlist_free(args);
+      }
+    }
+
+    if ((smartlist_len(args) == 1) || (purp && (smartlist_len(args) == 2))) {
+        // "EXTENDCIRCUIT 0" || EXTENDCIRCUIT 0 PURPOSE=foo"
+        circ = circuit_launch_by_router(intended_purpose, NULL,
+                CIRCLAUNCH_NEED_CAPACITY);
+        if (!circ) {
+          connection_write_str_to_buf("551 Couldn't start circuit\r\n", conn);
+        } else {
+          connection_printf_to_buf(conn, "250 EXTENDED %lu\r\n",
+                    (unsigned long)circ->global_identifier);
+        }
+        goto done;
+    }
+    // "EXTENDCIRCUIT 0 router1,router2" ||
+    // "EXTENDCIRCUIT 0 router1,router2 PURPOSE=foo"
+  }
+
   if (!zero_circ && !(circ = get_circ(smartlist_get(args,0)))) {
     connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
                              (char*)smartlist_get(args, 0));
+    goto done;
   }
+
   smartlist_split_string(router_nicknames, smartlist_get(args,1), ",", 0, 0);
 
-  if (zero_circ && smartlist_len(args)>2) {
-    char *purp = smartlist_get(args,2);
-    intended_purpose = circuit_purpose_from_string(purp);
-    if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) {
-      connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
-      SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
-      smartlist_free(args);
-      goto done;
-    }
-  }
   SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
   smartlist_free(args);
   if (!zero_circ && !circ) {
-- 
1.6.5




More information about the tor-commits mailing list