Allow "EXTENDCIRCUIT 0" to omit a path.

This commit is contained in:
Mike Perry 2009-12-29 04:17:12 +01:00
parent 8512e33773
commit ac68704f07
2 changed files with 54 additions and 18 deletions

View File

@ -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

View File

@ -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) {