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 3.10. EXTENDCIRCUIT
Sent from the client to the server. The format is: Sent from the client to the server. The format is:
"EXTENDCIRCUIT" SP CircuitID SP "EXTENDCIRCUIT" SP CircuitID
ServerSpec *("," ServerSpec) [SP ServerSpec *("," ServerSpec)
[SP "purpose=" Purpose] CRLF SP "purpose=" Purpose] CRLF
This request takes one of two forms: either the CircuitID is zero, in 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 which case it is a request for the server to build a new circuit,
to the specified path, or the CircuitID is nonzero, in which case it is a or the CircuitID is nonzero, in which case it is a request for the
request for the server to extend an existing circuit with that ID according server to extend an existing circuit with that ID according to the
to the specified path. 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 If CircuitID is 0 and "purpose=" is specified, then the circuit's
purpose is set. Two choices are recognized: "general" and 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(); router_nicknames = smartlist_create();
args = getargs_helper("EXTENDCIRCUIT", conn, body, 2, -1); args = getargs_helper("EXTENDCIRCUIT", conn, body, 1, -1);
if (!args) if (!args)
goto done; goto done;
zero_circ = !strcmp("0", (char*)smartlist_get(args,0)); zero_circ = !strcmp("0", (char*)smartlist_get(args,0));
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));
}
smartlist_split_string(router_nicknames, smartlist_get(args,1), ",", 0, 0);
if (zero_circ && smartlist_len(args)>2) { if (zero_circ) {
char *purp = smartlist_get(args,2); 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); intended_purpose = circuit_purpose_from_string(purp);
if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) { if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) {
connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
smartlist_free(args); 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; 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);
SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
smartlist_free(args); smartlist_free(args);
if (!zero_circ && !circ) { if (!zero_circ && !circ) {