summaryrefslogtreecommitdiff
path: root/src/or/relay.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-01-05 21:23:03 +0000
committerNick Mathewson <nickm@torproject.org>2006-01-05 21:23:03 +0000
commit878962bee11eb47042d49ebd7df0d18d403c98c0 (patch)
tree04b1c7ef50ea43a81b1b2b3536fb5b00584d88ed /src/or/relay.c
parentd8e3bc02884cfb85f113e44c9f61a1035789f0bc (diff)
downloadtor-878962bee11eb47042d49ebd7df0d18d403c98c0.tar.gz
tor-878962bee11eb47042d49ebd7df0d18d403c98c0.zip
Add reasons to DESTROY and RELAY_TRUNCATED cells.
svn:r5734
Diffstat (limited to 'src/or/relay.c')
-rw-r--r--src/or/relay.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/src/or/relay.c b/src/or/relay.c
index f923ae59a3..8ec5142e7f 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -138,6 +138,8 @@ relay_crypt_one_payload(crypto_cipher_env_t *cipher, char *in,
* connection_edge.
* - Else connection_or_write_cell_to_buf to the conn on the other
* side of the circuit.
+ *
+ * Return -reason on failure.
*/
int
circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
@@ -145,6 +147,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
connection_t *conn=NULL;
crypt_path_t *layer_hint=NULL;
char recognized=0;
+ int reason;
tor_assert(cell);
tor_assert(circ);
@@ -163,20 +166,21 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
if (cell_direction == CELL_DIRECTION_OUT) {
++stats_n_relay_cells_delivered;
debug(LD_OR,"Sending away from origin.");
- if (connection_edge_process_relay_cell(cell, circ, conn, NULL) < 0) {
+ if ((reason=connection_edge_process_relay_cell(cell, circ, conn, NULL))
+ < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"connection_edge_process_relay_cell (away from origin) "
"failed.");
- return -1;
+ return reason;
}
}
if (cell_direction == CELL_DIRECTION_IN) {
++stats_n_relay_cells_delivered;
debug(LD_OR,"Sending to origin.");
- if (connection_edge_process_relay_cell(cell, circ, conn,
- layer_hint) < 0) {
+ if ((reason = connection_edge_process_relay_cell(cell, circ, conn,
+ layer_hint)) < 0) {
warn(LD_OR,"connection_edge_process_relay_cell (at origin) failed.");
- return -1;
+ return reason;
}
}
return 0;
@@ -197,19 +201,19 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
tor_assert(circ->rend_splice->purpose ==
CIRCUIT_PURPOSE_REND_ESTABLISHED);
cell->circ_id = circ->rend_splice->p_circ_id;
- if (circuit_receive_relay_cell(cell, circ->rend_splice,
- CELL_DIRECTION_IN) < 0) {
+ if ((reason = circuit_receive_relay_cell(cell, circ->rend_splice,
+ CELL_DIRECTION_IN)) < 0) {
warn(LD_REND, "Error relaying cell across rendezvous; closing "
"circuits");
/* XXXX Do this here, or just return -1? */
- circuit_mark_for_close(circ);
- return -1;
+ circuit_mark_for_close(circ, -reason);
+ return reason;
}
return 0;
}
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Didn't recognize cell, but circ stops here! Closing circ.");
- return -1;
+ return -END_CIRC_REASON_TORPROTOCOL;
}
debug(LD_OR,"Passing on unrecognized cell.");
@@ -489,7 +493,7 @@ connection_edge_send_command(connection_t *fromconn, circuit_t *circ,
if (circuit_package_relay_cell(&cell, circ, cell_direction, cpath_layer)
< 0) {
warn(LD_BUG,"circuit_package_relay_cell failed. Closing.");
- circuit_mark_for_close(circ);
+ circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
return -1;
}
return 0;
@@ -655,7 +659,7 @@ connection_edge_process_end_not_open(
warn(LD_PROTOCOL,
"Got an end because of %s, but we're not an AP. Closing.",
connection_edge_end_reason_str(reason));
- return -1;
+ return - END_CIRC_REASON_TORPROTOCOL;
}
info(LD_APP,"Address '%s' refused due to '%s'. Considering retrying.",
safe_str(conn->socks_request->address),
@@ -848,7 +852,7 @@ connection_edge_process_relay_cell_not_open(
* If <b>layer_hint</b> is defined, then we're the origin of the
* circuit, and it specifies the hop that packaged <b>cell</b>.
*
- * Return -1 if you want to warn and tear down the circuit, else 0.
+ * Return -reason if you want to warn and tear down the circuit, else 0.
*/
static int
connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
@@ -858,6 +862,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
static int num_seen=0;
relay_header_t rh;
unsigned domain = layer_hint?LD_APP:LD_EXIT;
+ int reason;
tor_assert(cell);
tor_assert(circ);
@@ -869,7 +874,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
if (rh.length > RELAY_PAYLOAD_SIZE) {
warn(LD_PROTOCOL, "Relay cell length field too long. Closing circuit.");
- return -1;
+ return - END_CIRC_REASON_TORPROTOCOL;
}
/* either conn is NULL, in which case we've got a control cell, or else
@@ -904,7 +909,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL,
conn->cpath_layer);
connection_mark_for_close(conn);
- return -1;
+ return -END_CIRC_REASON_TORPROTOCOL;
}
debug(domain,"circ deliver_window now %d.", layer_hint ?
layer_hint->deliver_window : circ->deliver_window);
@@ -919,7 +924,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
if (--conn->deliver_window < 0) { /* is it below 0 after decrement? */
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"(relay data) conn deliver_window below 0. Killing.");
- return -1; /* somebody's breaking protocol. kill the whole circuit. */
+ return -END_CIRC_REASON_TORPROTOCOL;
}
stats_n_data_bytes_received += rh.length;
@@ -974,14 +979,14 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
return 0;
}
debug(domain,"Got an extended cell! Yay.");
- if (circuit_finish_handshake(circ, CELL_CREATED,
- cell->payload+RELAY_HEADER_SIZE) < 0) {
+ if ((reason = circuit_finish_handshake(circ, CELL_CREATED,
+ cell->payload+RELAY_HEADER_SIZE)) < 0) {
warn(domain,"circuit_finish_handshake failed.");
- return -1;
+ return reason;
}
- if (circuit_send_next_onion_skin(circ)<0) {
+ if ((reason=circuit_send_next_onion_skin(circ))<0) {
info(domain,"circuit_send_next_onion_skin() failed.");
- return -1;
+ return reason;
}
return 0;
case RELAY_COMMAND_TRUNCATE:
@@ -990,12 +995,17 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
return 0;
}
if (circ->n_conn) {
- connection_send_destroy(circ->n_circ_id, circ->n_conn);
+ uint8_t reason = *(uint8_t*)(cell->payload + RELAY_HEADER_SIZE);
+ connection_or_send_destroy(circ->n_circ_id, circ->n_conn, reason);
circuit_set_circid_orconn(circ, 0, NULL, N_CONN_CHANGED);
}
debug(LD_EXIT, "Processed 'truncate', replying.");
- connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED,
- NULL, 0, NULL);
+ {
+ char payload[1];
+ payload[0] = (char)END_CIRC_REASON_REQUESTED;
+ connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED,
+ payload, sizeof(payload), NULL);
+ }
return 0;
case RELAY_COMMAND_TRUNCATED:
if (!layer_hint) {
@@ -1008,7 +1018,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
if (conn) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"'connected' unsupported while open. Closing circ.");
- return -1;
+ return -END_CIRC_REASON_TORPROTOCOL;
}
info(domain,"'connected' received, no conn attached anymore. Ignoring.");
return 0;
@@ -1055,7 +1065,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
case RELAY_COMMAND_RESOLVED:
if (conn) {
warn(domain,"'resolved' unsupported while open. Closing circ.");
- return -1;
+ return -END_CIRC_REASON_TORPROTOCOL;
}
info(domain,"'resolved' received, no conn attached anymore. Ignoring.");
return 0;