mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
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
This commit is contained in:
parent
2bfd2a2400
commit
329af979e0
@ -405,19 +405,32 @@ $Id$
|
||||
3.10. EXTENDCIRCUIT
|
||||
|
||||
Sent from the client to the server. The format is:
|
||||
"EXTENDCIRCUIT" SP CircuitID SP ServerID *("," ServerID) CRLF
|
||||
"EXTENDCIRCUIT" SP CircuitID SP
|
||||
ServerID *("," ServerID) SP
|
||||
("purpose=" Purpose) CRLF
|
||||
|
||||
This request takes one of two forms: either the Circuit ID 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
|
||||
to the specified path, or the Circuit ID is nonzero, in which case it is a
|
||||
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.
|
||||
|
||||
If the request is successful, the server sends a reply containing a message
|
||||
body consisting of the Circuit ID of the (maybe newly created) circuit.
|
||||
The syntax is "250" SP "EXTENDED" SP CircuitID CRLF.
|
||||
If CircuitID is 0 and "purpose=" is specified, then the circuit's
|
||||
purpose is set. Two choices are recognized: "general" and
|
||||
"controller". If not specified, circuits are created as "general".
|
||||
|
||||
3.11. ATTACHSTREAM
|
||||
If the request is successful, the server sends a reply containing a
|
||||
message body consisting of the CircuitID of the (maybe newly created)
|
||||
circuit. The syntax is "250" SP "EXTENDED" SP CircuitID CRLF.
|
||||
|
||||
3.11. SETCIRCUITPURPOSE
|
||||
|
||||
Sent from the client to the server. The format is:
|
||||
"SETCIRCUITPURPOSE" SP CircuitID SP Purpose CRLF
|
||||
|
||||
This changes the circuit's purpose. See EXTENDCIRCUIT above for details.
|
||||
|
||||
3.12. ATTACHSTREAM
|
||||
|
||||
Sent from the client to the server. The syntax is:
|
||||
"ATTACHSTREAM" SP StreamID SP CircuitID CRLF
|
||||
@ -446,7 +459,7 @@ $Id$
|
||||
via TC when "__LeaveStreamsUnattached" is false may cause a race between
|
||||
Tor and the controller, as both attempt to attach streams to circuits.}
|
||||
|
||||
3.12. POSTDESCRIPTOR
|
||||
3.13. POSTDESCRIPTOR
|
||||
|
||||
Sent from the client to the server. The syntax is:
|
||||
"+POSTDESCRIPTOR" CRLF Descriptor CRLF "." CRLF
|
||||
@ -462,7 +475,7 @@ $Id$
|
||||
why the server was not added. If the descriptor is added, Tor replies with
|
||||
"250 OK".
|
||||
|
||||
3.13. REDIRECTSTREAM
|
||||
3.14. REDIRECTSTREAM
|
||||
|
||||
Sent from the client to the server. The syntax is:
|
||||
"REDIRECTSTREAM" SP StreamID SP Address (SP Port) CRLF
|
||||
@ -477,7 +490,7 @@ $Id$
|
||||
|
||||
Tor replies with "250 OK" on success.
|
||||
|
||||
3.14. CLOSESTREAM
|
||||
3.15. CLOSESTREAM
|
||||
|
||||
Sent from the client to the server. The syntax is:
|
||||
|
||||
@ -491,7 +504,7 @@ $Id$
|
||||
Tor replies with "250 OK" on success, or a 512 if there aren't enough
|
||||
arguments, or a 552 if it doesn't recognize the StreamID or reason.
|
||||
|
||||
3.15. CLOSECIRCUIT
|
||||
3.16. CLOSECIRCUIT
|
||||
|
||||
The syntax is:
|
||||
CLOSECIRCUIT SP CircuitID *(SP Flag) CRLF
|
||||
@ -506,7 +519,7 @@ $Id$
|
||||
Tor replies with "250 OK" on success, or a 512 if there aren't enough
|
||||
arguments, or a 552 if it doesn't recognize the CircuitID.
|
||||
|
||||
3.16. QUIT
|
||||
3.17. QUIT
|
||||
|
||||
Tells the server to hang up on this controller connection. This command
|
||||
can be used before authenticating.
|
||||
|
@ -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;
|
||||
|
@ -423,7 +423,9 @@ typedef enum {
|
||||
#define CIRCUIT_PURPOSE_S_REND_JOINED 16
|
||||
/** A testing circuit; not meant to be used for actual traffic. */
|
||||
#define CIRCUIT_PURPOSE_TESTING 17
|
||||
#define _CIRCUIT_PURPOSE_MAX 17
|
||||
/** A controller made this circuit and Tor should not use it. */
|
||||
#define CIRCUIT_PURPOSE_CONTROLLER 18
|
||||
#define _CIRCUIT_PURPOSE_MAX 18
|
||||
|
||||
/** True iff the circuit purpose <b>p</b> is for a circuit that
|
||||
* originated at this node. */
|
||||
|
Loading…
Reference in New Issue
Block a user