diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitlist.c | 3 | ||||
-rw-r--r-- | src/or/connection_edge.c | 3 | ||||
-rw-r--r-- | src/or/control.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 8 |
4 files changed, 18 insertions, 2 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index acbea47487..93784a485d 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -953,6 +953,9 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line, * to send an end cell. */ conn->_base.edge_has_sent_end = 1; conn->end_reason = END_STREAM_REASON_DESTROY; + conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED; + control_event_stream_status(conn, STREAM_EVENT_CLOSED, + END_STREAM_REASON_DESTROY); connection_mark_for_close(TO_CONN(conn)); } conn->on_circuit = NULL; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 21143ac09d..4d329e2e3f 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -158,6 +158,9 @@ connection_edge_destroy(uint16_t circ_id, edge_connection_t *conn) /* closing the circuit, nothing to send an END to */ conn->_base.edge_has_sent_end = 1; conn->end_reason = END_STREAM_REASON_DESTROY; + conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED; + control_event_stream_status(conn, STREAM_EVENT_CLOSED, + END_STREAM_REASON_DESTROY); connection_mark_for_close(TO_CONN(conn)); conn->_base.hold_open_until_flushed = 1; } diff --git a/src/or/control.c b/src/or/control.c index cbea14f22c..402ca267d8 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3140,7 +3140,7 @@ write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len) static const char * stream_end_reason_to_string(int reason) { - reason &= ~END_CIRC_REASON_FLAG_REMOTE; + reason &= END_STREAM_REASON_MASK; switch (reason) { case END_STREAM_REASON_MISC: return "MISC"; case END_STREAM_REASON_RESOLVEFAILED: return "RESOLVEFAILED"; @@ -3179,6 +3179,10 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp, if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS)) return 0; + if (tp == STREAM_EVENT_CLOSED && + (reason_code & END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED)) + return 0; + write_stream_target_to_buf(conn, buf, sizeof(buf)); if (EVENT_IS_INTERESTING0(EVENT_STREAM_STATUS)) { len = strlen(buf); diff --git a/src/or/or.h b/src/or/or.h index 26998c272d..e0c680983d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -531,9 +531,15 @@ typedef enum { /** DOCDOC */ #define END_STREAM_REASON_INVALID_NATD_DEST 261 +/** Bitwise-and this value with endreason to mask out all flags. */ +#define END_STREAM_REASON_MASK 511 + /** Bitwise-or this with the argument to control_event_stream_status * to indicate that the reason came from an END cell. */ -#define END_STREAM_REASON_FLAG_REMOTE 512 +#define END_STREAM_REASON_FLAG_REMOTE 512 +/** Bitwise-or this with the argument to control_event_stream_status + * to indicate that we already sent a CLOSED stream event. */ +#define END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED 1024 /* DOCDOC */ #define RESOLVED_TYPE_HOSTNAME 0 |