diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-10-20 17:54:48 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-10-20 17:54:48 +0000 |
commit | b27cb38dee3aa024e191a974bcf2801d4e87c0a5 (patch) | |
tree | a08aa6d0cd08cea79e981975cb9b75ed803cce87 /src | |
parent | 8e94097edb05b204cff7772588a3376507b3fd0b (diff) | |
download | tor-b27cb38dee3aa024e191a974bcf2801d4e87c0a5.tar.gz tor-b27cb38dee3aa024e191a974bcf2801d4e87c0a5.zip |
r9307@Kushana: nickm | 2006-10-20 13:53:54 -0400
Have connection_about_to_close use an end_reason field in edge_connection_t to tell what reason to tell the controller for closing the stream. Set end_reason in connection_edge_end, connection_mark_unattached_ap, and everwhere we set edge_has_sent_end. Add a changelog entry.
svn:r8779
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitlist.c | 1 | ||||
-rw-r--r-- | src/or/connection.c | 8 | ||||
-rw-r--r-- | src/or/connection_edge.c | 4 | ||||
-rw-r--r-- | src/or/control.c | 1 | ||||
-rw-r--r-- | src/or/main.c | 3 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/relay.c | 15 |
7 files changed, 29 insertions, 6 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 8f7cb3e192..78fcbb3df9 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -909,6 +909,7 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line, * are closing because the circuit is getting torn down. No need * to send an end cell. */ conn->_base.edge_has_sent_end = 1; + conn->end_reason = END_STREAM_REASON_DESTROY; connection_mark_for_close(TO_CONN(conn)); } conn->on_circuit = NULL; diff --git a/src/or/connection.c b/src/or/connection.c index 25b633a065..b7a3889cdf 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -459,8 +459,14 @@ connection_about_to_close_connection(connection_t *conn) " back a socks reply.", conn->marked_for_close_file, conn->marked_for_close); } + if (!edge_conn->end_reason) { + // XXXX Disable this before 0.1.2.x-final ships. + log_warn(LD_BUG,"Bug: Closing stream (marked at %s:%d) without having" + " set end_reason. Please tell Nick.", + conn->marked_for_close_file, conn->marked_for_close); + } control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED, - END_STREAM_REASON_FIXME_XXXX); + edge_conn->end_reason); break; case CONN_TYPE_EXIT: edge_conn = TO_EDGE_CONN(conn); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 04e7b0f2fa..9e7173ad48 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -63,6 +63,7 @@ _connection_mark_unattached_ap(edge_connection_t *conn, int endreason, _connection_mark_for_close(TO_CONN(conn), line, file); conn->_base.hold_open_until_flushed = 1; + conn->end_reason = endreason; } /** There was an EOF. Send an end and mark the connection for close. @@ -155,6 +156,7 @@ connection_edge_destroy(uint16_t circ_id, edge_connection_t *conn) } else { /* closing the circuit, nothing to send an END to */ conn->_base.edge_has_sent_end = 1; + conn->end_reason = END_STREAM_REASON_DESTROY; connection_mark_for_close(TO_CONN(conn)); conn->_base.hold_open_until_flushed = 1; } @@ -213,6 +215,7 @@ connection_edge_end(edge_connection_t *conn, char reason, } conn->_base.edge_has_sent_end = 1; + conn->end_reason = reason; return 0; } @@ -408,6 +411,7 @@ connection_ap_expire_beginning(void) connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer); /* un-mark it as ending, since we're going to reuse it */ conn->_base.edge_has_sent_end = 0; + conn->end_reason = 0; /* kludge to make us not try this circuit again, yet to allow * current streams on it to survive if they can: make it * unattractive to use for new streams */ diff --git a/src/or/control.c b/src/or/control.c index 6fd88c4ed3..c1e3ab5f94 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2101,6 +2101,7 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len, ap_conn->cpath_layer); /* Un-mark it as ending, since we're going to reuse it. */ ap_conn->_base.edge_has_sent_end = 0; + ap_conn->end_reason = 0; if (tmpcirc) circuit_detach_stream(tmpcirc,ap_conn); ap_conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT; diff --git a/src/or/main.c b/src/or/main.c index 81b555c6cf..b51028ca80 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -447,6 +447,9 @@ conn_write_callback(int fd, short events, void *_conn) tor_fragile_assert(); if (CONN_IS_EDGE(conn)) { /* otherwise we cry wolf about duplicate close */ + edge_connection_t *edge_conn = TO_EDGE_CONN(conn); + if (!edge_conn->end_reason) + edge_conn->end_reason = END_STREAM_REASON_INTERNAL; conn->edge_has_sent_end = 1; } /* XXX do we need a close-immediate here, so we don't try to flush? */ diff --git a/src/or/or.h b/src/or/or.h index 9c1db0f42d..21564707ca 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -756,6 +756,9 @@ typedef struct edge_connection_t { uint16_t stream_id; /**< The stream ID used for this edge connection on its * circuit */ + /** The reason why this connection is closing; passed to the controller. */ + uint16_t end_reason; + /** Quasi-global identifier for this connection; used for control.c */ /* XXXX NM This can get re-used after 2**32 streams */ uint32_t global_identifier; diff --git a/src/or/relay.c b/src/or/relay.c index 2d99453574..93b272c75e 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -533,6 +533,7 @@ connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ, } else { log_info(LD_EXIT,"no circ. Closing conn."); fromconn->_base.edge_has_sent_end = 1; /* no circ to send to */ + fromconn->end_reason = END_STREAM_REASON_INTERNAL; connection_mark_for_close(TO_CONN(fromconn)); } return -1; @@ -817,10 +818,11 @@ connection_edge_process_end_not_open( connection_edge_end_reason_str(rh->length > 0 ? reason : -1)); if (conn->_base.type == CONN_TYPE_AP) { circuit_log_path(LOG_INFO,LD_APP,circ); - connection_mark_unattached_ap(conn, reason); + connection_mark_unattached_ap(conn, control_reason); } else { /* we just got an 'end', don't need to send one */ conn->_base.edge_has_sent_end = 1; + conn->end_reason = control_reason; connection_mark_for_close(TO_CONN(conn)); } return 0; @@ -1024,23 +1026,25 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_edge_consider_sending_sendme(conn); return 0; case RELAY_COMMAND_END: + reason = rh.length > 0 ? + *(uint8_t *)(cell->payload+RELAY_HEADER_SIZE) : END_STREAM_REASON_MISC; if (!conn) { log_info(domain,"end cell (%s) dropped, unknown stream.", - connection_edge_end_reason_str(rh.length > 0 ? - *(char *)(cell->payload+RELAY_HEADER_SIZE) : -1)); + connection_edge_end_reason_str(reason)); return 0; } /* XXX add to this log_fn the exit node's nickname? */ log_info(domain,"%d: end cell (%s) for stream %d. Removing stream.", conn->_base.s, - connection_edge_end_reason_str(rh.length > 0 ? - *(char *)(cell->payload+RELAY_HEADER_SIZE) : -1), + connection_edge_end_reason_str(reason), conn->stream_id); if (conn->socks_request && !conn->socks_request->has_finished) log_warn(LD_BUG, "Bug: open stream hasn't sent socks answer yet? Closing."); /* We just *got* an end; no reason to send one. */ conn->_base.edge_has_sent_end = 1; + if (!conn->end_reason) + conn->end_reason = reason | END_STREAM_REASON_FLAG_REMOTE; if (!conn->_base.marked_for_close) { /* only mark it if not already marked. it's possible to * get the 'end' right around when the client hangs up on us. */ @@ -1216,6 +1220,7 @@ repeat_connection_edge_package_raw_inbuf: circ = circuit_get_by_edge_conn(conn); if (!circ) { log_info(domain,"conn has no circuit! Closing."); + conn->end_reason = END_STREAM_REASON_CANT_ATTACH; return -1; } |