summaryrefslogtreecommitdiff
path: root/src/or/circuitlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r--src/or/circuitlist.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index a90af469b4..ab60327a2d 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -470,7 +470,7 @@ circuit_get_by_edge_conn(connection_t *conn)
* been marked already.
*/
void
-circuit_unlink_all_from_or_conn(connection_t *conn)
+circuit_unlink_all_from_or_conn(connection_t *conn, int reason)
{
circuit_t *circ;
for (circ = global_circuitlist; circ; circ = circ->next) {
@@ -480,7 +480,7 @@ circuit_unlink_all_from_or_conn(connection_t *conn)
if (circ->p_conn == conn)
circuit_set_circid_orconn(circ, 0, NULL, P_CONN_CHANGED);
if (!circ->marked_for_close)
- circuit_mark_for_close(circ);
+ circuit_mark_for_close(circ, reason);
}
}
}
@@ -607,7 +607,7 @@ circuit_mark_all_unused_circs(void)
if (CIRCUIT_IS_ORIGIN(circ) &&
!circ->marked_for_close &&
!circ->timestamp_dirty)
- circuit_mark_for_close(circ);
+ circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN);
}
}
@@ -648,7 +648,8 @@ circuit_expire_all_dirty_circs(void)
* rendezvous stream), then mark the other circuit to close as well.
*/
void
-_circuit_mark_for_close(circuit_t *circ, int line, const char *file)
+_circuit_mark_for_close(circuit_t *circ, int reason, int line,
+ const char *file)
{
connection_t *conn;
@@ -663,6 +664,22 @@ _circuit_mark_for_close(circuit_t *circ, int line, const char *file)
circ->marked_for_close_file, circ->marked_for_close);
return;
}
+ if (reason == END_CIRC_AT_ORIGIN) {
+ if (!CIRCUIT_IS_ORIGIN(circ)) {
+ warn(LD_BUG, "Specified 'at-origin' non-reason for ending circuit, "
+ "but circuit was not at origin. (called %s:%d, purpose=%d)",
+ file, line, circ->purpose);
+ }
+ reason = END_CIRC_REASON_NONE;
+ } else if (CIRCUIT_IS_ORIGIN(circ) && reason != END_CIRC_REASON_NONE) {
+ /* Don't warn about this; there are plenty of places where our code
+ * is origin-agnosic. */
+ reason = END_CIRC_REASON_NONE;
+ }
+ if (reason < _END_CIRC_REASON_MIN || reason > _END_CIRC_REASON_MAX) {
+ warn(LD_BUG, "Reason %d out of range at %s:%d", reason, file, line);
+ reason = END_CIRC_REASON_NONE;
+ }
if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) {
onion_pending_remove(circ);
@@ -698,7 +715,7 @@ _circuit_mark_for_close(circuit_t *circ, int line, const char *file)
}
if (circ->n_conn)
- connection_send_destroy(circ->n_circ_id, circ->n_conn);
+ connection_or_send_destroy(circ->n_circ_id, circ->n_conn, reason);
for (conn=circ->n_streams; conn; conn=conn->next_stream)
connection_edge_destroy(circ->n_circ_id, conn);
while (circ->resolving_streams) {
@@ -714,7 +731,7 @@ _circuit_mark_for_close(circuit_t *circ, int line, const char *file)
conn->on_circuit = NULL;
}
if (circ->p_conn)
- connection_send_destroy(circ->p_circ_id, circ->p_conn);
+ connection_or_send_destroy(circ->p_circ_id, circ->p_conn, reason);
for (conn=circ->p_streams; conn; conn=conn->next_stream)
connection_edge_destroy(circ->p_circ_id, conn);
@@ -724,7 +741,7 @@ _circuit_mark_for_close(circuit_t *circ, int line, const char *file)
if (circ->rend_splice) {
if (!circ->rend_splice->marked_for_close) {
/* do this after marking this circuit, to avoid infinite recursion. */
- circuit_mark_for_close(circ->rend_splice);
+ circuit_mark_for_close(circ->rend_splice, reason);
}
circ->rend_splice = NULL;
}