diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-03-22 19:36:38 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-03-22 19:36:38 +0000 |
commit | 7a0072cc1a70b42dd38c58ac20fe873c48beeace (patch) | |
tree | c3a79af68b99022e1045f62de02e0d76cfce8a82 /src/or/control.c | |
parent | ec81f870181940909507fd5356fa5ecc11c7440e (diff) | |
download | tor-7a0072cc1a70b42dd38c58ac20fe873c48beeace.tar.gz tor-7a0072cc1a70b42dd38c58ac20fe873c48beeace.zip |
Specify and implement close-stream and close-circuit control messages
svn:r3814
Diffstat (limited to 'src/or/control.c')
-rw-r--r-- | src/or/control.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/src/or/control.c b/src/or/control.c index a655521ec9..3114dbf2d3 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -48,8 +48,10 @@ const char control_c_id[] = "$Id$"; #define CONTROL_CMD_POSTDESCRIPTOR 0x000F #define CONTROL_CMD_FRAGMENTHEADER 0x0010 #define CONTROL_CMD_FRAGMENT 0x0011 -#define CONTROL_CMD_REDIRECTSTREAM 0x0012 -#define _CONTROL_CMD_MAX_RECOGNIZED 0x0012 +#define CONTROL_CMD_REDIRECTSTREAM 0x0012 +#define CONTROL_CMD_CLOSESTREAM 0x0013 +#define CONTROL_CMD_CLOSECIRCUIT 0x0014 +#define _CONTROL_CMD_MAX_RECOGNIZED 0x0014 /* Recognized error codes. */ #define ERR_UNSPECIFIED 0x0000 @@ -152,6 +154,10 @@ 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); +static int handle_control_closestream(connection_t *conn, uint32_t len, + const char *body); +static int handle_control_closecircuit(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. */ @@ -772,7 +778,72 @@ handle_control_redirectstream(connection_t *conn, uint32_t len, send_control_done(conn); return 0; } +static int +handle_control_closestream(connection_t *conn, uint32_t len, + const char *body) +{ + uint32_t conn_id; + connection_t *ap_conn; + uint8_t reason; + int hold_open; + + if (len < 6) { + send_control_error(conn, ERR_SYNTAX, "closestream message too short"); + return 0; + } + + conn_id = ntohl(get_uint32(body)); + reason = *(uint8_t*)(body+4); + hold_open = (*(uint8_t*)(body+5)) & 1; + + 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; + } + + if (!ap_conn->socks_request->has_finished) { + socks5_reply_status_t status = + connection_edge_end_reason_socks5_response(reason); + connection_ap_handshake_socks_reply(ap_conn, NULL, 0, status); + } + if (hold_open) + ap_conn->hold_open_until_flushed = 1; + connection_mark_for_close(ap_conn); + + send_control_done(conn); + return 0; +} +static int +handle_control_closecircuit(connection_t *conn, uint32_t len, + const char *body) +{ + uint32_t circ_id; + circuit_t *circ; + int safe; + if (len < 5) { + send_control_error(conn, ERR_SYNTAX, "closecircuit message too short"); + return 0; + } + circ_id = ntohl(get_uint32(body)); + safe = (*(uint8_t*)(body+4)) & 1; + + if (!(circ = circuit_get_by_global_id(circ_id))) { + send_control_error(conn, ERR_NO_CIRC, + "No circuit found with given ID"); + return 0; + } + + if (!safe || !circ->p_streams) { + circuit_mark_for_close(circ); + } + + send_control_done(conn); + return 0; +} /** Called when <b>conn</b> has no more bytes left on its outbuf. */ int @@ -882,6 +953,14 @@ connection_control_process_inbuf(connection_t *conn) { if (handle_control_redirectstream(conn, body_len, body)) return -1; break; + case CONTROL_CMD_CLOSESTREAM: + if (handle_control_closestream(conn, body_len, body)) + return -1; + break; + case CONTROL_CMD_CLOSECIRCUIT: + if (handle_control_closecircuit(conn, body_len, body)) + return -1; + break; case CONTROL_CMD_ERROR: case CONTROL_CMD_DONE: case CONTROL_CMD_CONFVALUE: |