summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-03-19 06:05:55 +0000
committerNick Mathewson <nickm@torproject.org>2005-03-19 06:05:55 +0000
commit07a7b6af64483e6d2f863159122b10fd9393601a (patch)
tree55c6b10ca7134d0c5aff41cb9d1885223cd9538e
parent963ddf2953a000774e9021661b741ec643e95c4e (diff)
downloadtor-07a7b6af64483e6d2f863159122b10fd9393601a.tar.gz
tor-07a7b6af64483e6d2f863159122b10fd9393601a.zip
Implement redirectstream in control interface.
svn:r3785
-rw-r--r--doc/control-spec.txt19
-rw-r--r--src/or/control.c84
2 files changed, 97 insertions, 6 deletions
diff --git a/doc/control-spec.txt b/doc/control-spec.txt
index cb3fb178c2..8993f61952 100644
--- a/doc/control-spec.txt
+++ b/doc/control-spec.txt
@@ -102,7 +102,9 @@ the message.
0x000A No such stream
- 0x000B No such circuit.
+ 0x000B No such circuit
+
+ 0x000C No such OR
The rest of the body should be a human-readable description of the error.
@@ -328,8 +330,6 @@ the message.
3.14 EXTENDCIRCUIT (Type 0x000D)
- [Proposal; not finalized]
-
Sent from the client to the server. The message body contains two fields:
Circuit ID [4 octets]
Path [NUL-terminated, comma-delimited string of OR nickname/identity]
@@ -401,7 +401,18 @@ the message.
See FRAGMENTHEADER for more information
-3.19
+3.19 REDIRECTSTREAM (Type 0x0012)
+
+ Sent form the client to the server. The message body contains two fields:
+ Stream ID [4 octets]
+ Address [variable-length, NUL-terminated.]
+
+ Tells the server to change the exit address on the specified stream. No
+ remapping is performed on the new provided address.
+
+ To be sure that the modified address will be used, this event must be sent
+ after a new stream event is received, and before attaching this stream to
+ a circuit.
4. Implementation notes
diff --git a/src/or/control.c b/src/or/control.c
index bf784a9cb3..e8f6d0e35e 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -48,7 +48,8 @@ const char control_c_id[] = "$Id$";
#define CONTROL_CMD_POSTDESCRIPTOR 0x000F
#define CONTROL_CMD_FRAGMENTHEADER 0x0010
#define CONTROL_CMD_FRAGMENT 0x0011
-#define _CONTROL_CMD_MAX_RECOGNIZED 0x0011
+#define CONTROL_CMD_REDIRECTSTREAM 0x0012
+#define _CONTROL_CMD_MAX_RECOGNIZED 0x0012
/* Recognized error codes. */
#define ERR_UNSPECIFIED 0x0000
@@ -63,6 +64,7 @@ const char control_c_id[] = "$Id$";
#define ERR_RESOURCE_EXHAUSETED 0x0009
#define ERR_NO_STREAM 0x000A
#define ERR_NO_CIRC 0x000B
+#define ERR_NO_ROUTER 0x000C
/* Recognized asynchronous event types. */
#define _EVENT_MIN 0x0001
@@ -148,6 +150,8 @@ 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,
const char *body);
+static int handle_control_redirectstream(connection_t *conn, uint32_t len,
+ const char *body);
/** Given a possibly invalid message type code <b>cmd</b>, return a
* human-readable string equivalent. */
@@ -631,7 +635,52 @@ static int
handle_control_extendcircuit(connection_t *conn, uint32_t len,
const char *body)
{
- send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
+ smartlist_t *router_nicknames, *routers;
+ uint32_t circ_id;
+ circuit_t *circ;
+ if (len<5) {
+ send_control_error(conn, ERR_SYNTAX, "extendcircuit message too short");
+ return 0;
+ }
+ circ_id = ntohl(get_uint32(body));
+ if (!(circ = circuit_get_by_global_id(circ_id))) {
+ send_control_error(conn, ERR_NO_STREAM,
+ "No connection found with given ID");
+ return 0;
+ }
+
+ router_nicknames = smartlist_create();
+ routers = smartlist_create();
+ smartlist_split_string(router_nicknames, body, ",", 0, 0);
+ SMARTLIST_FOREACH(router_nicknames, const char *, n,
+ {
+ routerinfo_t *r = router_get_by_nickname(n);
+ if (!r) {
+ send_control_error(conn, ERR_NO_ROUTER, "Unrecognized router name");
+ goto done;
+ }
+ smartlist_add(routers, r);
+ });
+
+#if 1
+ /*XXXX RD*/
+ send_control_error(conn, ERR_INTERNAL, "EXTENDCIRCUIT not implemented.");
+#else
+ SMARTLIST_FOREACH(routers, routerinfo_t *, r,
+ {
+ /*XXXX RD*/
+ if (circuit_extend_path(circ, r)<0) {
+ send_control_error(conn, ERR_INTERNAL, "Unable to extend path.");
+ goto done;
+ }
+ });
+#endif
+
+ send_control_done(conn);
+ done:
+ SMARTLIST_FOREACH(router_nicknames, char *, n, tor_free(n));
+ smartlist_free(router_nicknames);
+ smartlist_free(routers);
return 0;
}
static int handle_control_attachstream(connection_t *conn, uint32_t len,
@@ -677,6 +726,7 @@ static int handle_control_attachstream(connection_t *conn, uint32_t len,
send_control_error(conn, ERR_INTERNAL, "Unable to attach stream.");
return 0;
}
+ send_control_done(conn);
return 0;
}
static int
@@ -693,6 +743,32 @@ handle_control_postdescriptor(connection_t *conn, uint32_t len,
send_control_done(conn);
return 0;
}
+static int
+handle_control_redirectstream(connection_t *conn, uint32_t len,
+ const char *body)
+{
+ connection_t *ap_conn;
+ uint32_t conn_id;
+ if (len < 6) {
+ send_control_error(conn, ERR_SYNTAX, "attachstream message too short");
+ return 0;
+ }
+ conn_id = ntohl(get_uint32(body));
+
+ if (!(ap_conn = connection_get_by_global_id(conn_id))
+ || ap_conn->state != CONN_TYPE_AP
+ || !ap_conn->socks_request) {
+ send_control_error(conn, ERR_NO_STREAM,
+ "No AP connection found with given ID");
+ return 0;
+ }
+ strlcpy(ap_conn->socks_request->address, body+1,
+ sizeof(ap_conn->socks_request->address));
+
+ send_control_done(conn);
+ return 0;
+}
+
/** Called when <b>conn</b> has no more bytes left on its outbuf. */
int
@@ -798,6 +874,10 @@ connection_control_process_inbuf(connection_t *conn) {
if (handle_control_postdescriptor(conn, body_len, body))
return -1;
break;
+ case CONTROL_CMD_REDIRECTSTREAM:
+ if (handle_control_redirectstream(conn, body_len, body))
+ return -1;
+ break;
case CONTROL_CMD_ERROR:
case CONTROL_CMD_DONE:
case CONTROL_CMD_CONFVALUE: