summaryrefslogtreecommitdiff
path: root/src/or/control.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2006-02-23 06:51:09 +0000
committerRoger Dingledine <arma@torproject.org>2006-02-23 06:51:09 +0000
commit329af979e0aaa5759d157c883e498ac552f48af8 (patch)
tree097686979d64b63ead3e9c487cb5401aecb1697e /src/or/control.c
parent2bfd2a2400e05992208f4152deea0aaf3d39eaa9 (diff)
downloadtor-329af979e0aaa5759d157c883e498ac552f48af8.tar.gz
tor-329af979e0aaa5759d157c883e498ac552f48af8.zip
Add a new circuit purpose 'controller' to let the controller
ask for a circuit that Tor won't try to use. Extend the EXTENDCIRCUIT controller command to let you specify the purpose if you're starting a new circuit. Add a new SETCIRCUITPURPOSE controller command to let you change a circuit's purpose after it's been created. svn:r6075
Diffstat (limited to 'src/or/control.c')
-rw-r--r--src/or/control.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/src/or/control.c b/src/or/control.c
index a843b98152..bd845bb04e 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -169,6 +169,8 @@ static int handle_control_getinfo(connection_t *conn, uint32_t len,
const char *body);
static int handle_control_extendcircuit(connection_t *conn, uint32_t len,
const char *body);
+static int handle_control_setcircuitpurpose(connection_t *conn, uint32_t len,
+ const char *body);
static int handle_control_attachstream(connection_t *conn, uint32_t len,
const char *body);
static int handle_control_postdescriptor(connection_t *conn, uint32_t len,
@@ -1541,6 +1543,25 @@ handle_control_getinfo(connection_t *conn, uint32_t len, const char *body)
return 0;
}
+/** If <b>string</b> contains a recognized circuit purpose,
+ * possibly prefaced with the string "purpose=", then assign it
+ * and return 0. Otherwise return -1. */
+static int
+get_purpose(char *string, uint8_t *purpose)
+{
+ if (!strcmpstart(string, "purpose="))
+ string += strlen("purpose=");
+
+ if (!strcmp(string, "general"))
+ *purpose = CIRCUIT_PURPOSE_C_GENERAL;
+ else if (!strcmp(string, "controller"))
+ *purpose = CIRCUIT_PURPOSE_CONTROLLER;
+ else { /* not a recognized purpose */
+ return -1;
+ }
+ return 0;
+}
+
/** Called when we get an EXTENDCIRCUIT message. Try to extend the listed
* circuit, and report success or failure. */
static int
@@ -1552,6 +1573,7 @@ handle_control_extendcircuit(connection_t *conn, uint32_t len,
circuit_t *circ = NULL;
int zero_circ, v0;
char reply[4];
+ uint8_t intended_purpose = CIRCUIT_PURPOSE_C_GENERAL;
v0 = STATE_IS_V0(conn->state);
router_nicknames = smartlist_create();
@@ -1600,6 +1622,13 @@ handle_control_extendcircuit(connection_t *conn, uint32_t len,
if (!zero_circ && !circ) {
goto done;
}
+ if (zero_circ && smartlist_len(args)>2) {
+ if (get_purpose(smartlist_get(args,2), &intended_purpose) < 0) {
+ connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n",
+ (char *)smartlist_get(args,2));
+ goto done;
+ }
+ }
}
routers = smartlist_create();
@@ -1625,7 +1654,7 @@ handle_control_extendcircuit(connection_t *conn, uint32_t len,
if (zero_circ) {
/* start a new circuit */
- circ = circuit_init(CIRCUIT_PURPOSE_C_GENERAL, 0, 0, 0);
+ circ = circuit_init(intended_purpose, 0, 0, 0);
}
/* now circ refers to something that is ready to be extended */
@@ -1677,6 +1706,44 @@ handle_control_extendcircuit(connection_t *conn, uint32_t len,
return 0;
}
+/** Called when we get a SETCIRCUITPURPOSE message. If we can find
+ * the circuit and it's a valid purpose, change it. */
+static int
+handle_control_setcircuitpurpose(connection_t *conn, uint32_t len,
+ const char *body)
+{
+ circuit_t *circ;
+ uint8_t new_purpose;
+ smartlist_t *args = smartlist_create();
+ smartlist_split_string(args, body, " ",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (smartlist_len(args)<2) {
+ connection_printf_to_buf(conn,
+ "512 Missing argument to SETCIRCUITPURPOSE\r\n");
+ goto done;
+ }
+
+ if (!(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;
+ }
+
+ if (get_purpose(smartlist_get(args,1), &new_purpose) < 0) {
+ connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n",
+ (char *)smartlist_get(args,1));
+ goto done;
+ }
+
+ circ->purpose = new_purpose;
+ connection_write_str_to_buf("250 OK\r\n", conn);
+
+done:
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+ smartlist_free(args);
+ return 0;
+}
+
/** Called when we get an ATTACHSTREAM message. Try to attach the requested
* stream, and report success or failure. */
static int
@@ -2187,6 +2254,9 @@ connection_control_process_inbuf_v1(connection_t *conn)
} else if (!strcasecmp(conn->incoming_cmd, "EXTENDCIRCUIT")) {
if (handle_control_extendcircuit(conn, data_len, args))
return -1;
+ } else if (!strcasecmp(conn->incoming_cmd, "SETCIRCUITPURPOSE")) {
+ if (handle_control_setcircuitpurpose(conn, data_len, args))
+ return -1;
} else if (!strcasecmp(conn->incoming_cmd, "ATTACHSTREAM")) {
if (handle_control_attachstream(conn, data_len, args))
return -1;