diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-10-20 14:57:46 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-10-20 14:57:46 +0000 |
commit | 136ed3307140ff82ade78f21765e43c87902d240 (patch) | |
tree | 99b1d79e39d022885b82f52f02b5df05ee0c7015 /src/or/relay.c | |
parent | 77936aa337b05cfea073bced284d764b1a96e852 (diff) | |
download | tor-136ed3307140ff82ade78f21765e43c87902d240.tar.gz tor-136ed3307140ff82ade78f21765e43c87902d240.zip |
r9289@31-35-219: nickm | 2006-10-20 09:43:22 -0400
Fix longstanding bug in connection_exit_begin_conn(): Since connection_edge_end() exits when the connection is unattached, we were never sending RELAY_END cells back for failed RELAY_BEGIN attempts. Fix this. This might make clients that were otherwise timing out either fail faster or retry faster, which is good news for us.
svn:r8770
Diffstat (limited to 'src/or/relay.c')
-rw-r--r-- | src/or/relay.c | 83 |
1 files changed, 53 insertions, 30 deletions
diff --git a/src/or/relay.c b/src/or/relay.c index bfea129270..f70ed23170 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -446,17 +446,17 @@ relay_header_unpack(relay_header_t *dest, const char *src) dest->length = ntohs(get_uint16(src+9)); } -/** Make a relay cell out of <b>relay_command</b> and <b>payload</b>, and - * send it onto the open circuit <b>circ</b>. <b>fromconn</b> is the stream - * that's sending the relay cell, or NULL if it's a control cell. - * <b>cpath_layer</b> is NULL for OR->OP cells, or the destination hop - * for OP->OR cells. +/** Make a relay cell out of <b>relay_command</b> and <b>payload</b>, and send + * it onto the open circuit <b>circ</b>. <b>stream_id</b> is the ID on + * <b>circ</b> for the stream that's sending the relay cell, or 0 if it's a + * control cell. <b>cpath_layer</b> is NULL for OR->OP cells, or the + * destination hop for OP->OR cells. * - * If you can't send the cell, mark the circuit for close and - * return -1. Else return 0. + * If you can't send the cell, mark the circuit for close and return -1. Else + * return 0. */ int -connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ, +relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ, int relay_command, const char *payload, size_t payload_len, crypt_path_t *cpath_layer) { @@ -465,26 +465,7 @@ connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ, int cell_direction; /* XXXX NM Split this function into a separate versions per circuit type? */ - if (fromconn && fromconn->_base.marked_for_close) { - log_warn(LD_BUG, - "Bug: called on conn that's already marked for close at %s:%d.", - fromconn->_base.marked_for_close_file, - fromconn->_base.marked_for_close); - return 0; - } - - if (!circ) { - tor_assert(fromconn); - if (fromconn->_base.type == CONN_TYPE_AP) { - log_info(LD_APP,"no circ. Closing conn."); - connection_mark_unattached_ap(fromconn, END_STREAM_REASON_INTERNAL); - } else { - log_info(LD_EXIT,"no circ. Closing conn."); - fromconn->_base.edge_has_sent_end = 1; /* no circ to send to */ - connection_mark_for_close(TO_CONN(fromconn)); - } - return -1; - } + tor_assert(circ); memset(&cell, 0, sizeof(cell_t)); cell.command = CELL_RELAY; @@ -500,8 +481,7 @@ connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ, memset(&rh, 0, sizeof(rh)); rh.command = relay_command; - if (fromconn) - rh.stream_id = fromconn->stream_id; /* else it's 0 */ + rh.stream_id = stream_id; rh.length = payload_len; relay_header_pack(cell.payload, &rh); if (payload_len) { @@ -521,6 +501,48 @@ connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ, return 0; } +/** Make a relay cell out of <b>relay_command</b> and <b>payload</b>, and + * send it onto the open circuit <b>circ</b>. <b>fromconn</b> is the stream + * that's sending the relay cell, or NULL if it's a control cell. + * <b>cpath_layer</b> is NULL for OR->OP cells, or the destination hop + * for OP->OR cells. + * + * If you can't send the cell, mark the circuit for close and + * return -1. Else return 0. + */ +int +connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ, + int relay_command, const char *payload, + size_t payload_len, crypt_path_t *cpath_layer) +{ + /* XXXX NM Split this function into a separate versions per circuit type? */ + + if (fromconn && fromconn->_base.marked_for_close) { + log_warn(LD_BUG, + "Bug: called on conn that's already marked for close at %s:%d.", + fromconn->_base.marked_for_close_file, + fromconn->_base.marked_for_close); + return 0; + } + + if (!circ) { + tor_assert(fromconn); + if (fromconn->_base.type == CONN_TYPE_AP) { + log_info(LD_APP,"no circ. Closing conn."); + connection_mark_unattached_ap(fromconn, END_STREAM_REASON_INTERNAL); + } else { + log_info(LD_EXIT,"no circ. Closing conn."); + fromconn->_base.edge_has_sent_end = 1; /* no circ to send to */ + connection_mark_for_close(TO_CONN(fromconn)); + } + return -1; + } + + return relay_send_command_from_edge(fromconn ? fromconn->stream_id : 0, + circ, relay_command, payload, + payload_len, cpath_layer); +} + /** Translate <b>reason</b>, which came from a relay 'end' cell, * into a static const string describing why the stream is closing. * <b>reason</b> is -1 if no reason was provided. @@ -545,6 +567,7 @@ connection_edge_end_reason_str(int reason) case END_STREAM_REASON_RESOURCELIMIT: return "server out of resources"; case END_STREAM_REASON_CONNRESET: return "connection reset"; case END_STREAM_REASON_TORPROTOCOL: return "Tor protocol error"; + case END_STREAM_REASON_NOTDIRECTORY: return "not a directory"; default: log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Reason for ending (%d) not recognized.",reason); |