summaryrefslogtreecommitdiff
path: root/src/or/relay.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-04-10 16:24:50 +0000
committerNick Mathewson <nickm@torproject.org>2007-04-10 16:24:50 +0000
commitf95d232483a0e9fd78563bfdc061016baab6ef97 (patch)
tree7cb29766f595c542221a3d0a354f55daa6123794 /src/or/relay.c
parent58a6761056af4c5f50e9550f50625e91e55b30a1 (diff)
downloadtor-f95d232483a0e9fd78563bfdc061016baab6ef97.tar.gz
tor-f95d232483a0e9fd78563bfdc061016baab6ef97.zip
r12332@catbus: nickm | 2007-04-10 12:24:45 -0400
Yet another attempted Bug 411 fix: Under some circumstances, a circuit can have cells without being active. The likeliest is that it has been unlinked from all connections in preparation for closing. Therefore, stop enforcing this non-invariant. svn:r9936
Diffstat (limited to 'src/or/relay.c')
-rw-r--r--src/or/relay.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/or/relay.c b/src/or/relay.c
index 2b8fe8d2e8..4cc0635314 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1581,35 +1581,46 @@ prev_circ_on_conn_p(circuit_t *circ, or_connection_t *conn)
}
/** Add <b>circ</b> to the list of circuits with pending cells on
- * <b>conn</b>. */
+ * <b>conn</b>. No effect if <b>circ</b> is already unlinked. */
void
make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn)
{
- tor_assert(! *prev_circ_on_conn_p(circ, conn));
- tor_assert(! *next_circ_on_conn_p(circ, conn));
+ circuit_t **nextp = next_circ_on_conn_p(circ, conn);
+ circuit_t **prevp = prev_circ_on_conn_p(circ, conn);
+
+ if (*nextp && *prevp) {
+ /* Already active. */
+ return;
+ }
if (! conn->active_circuits) {
conn->active_circuits = circ;
- *prev_circ_on_conn_p(circ, conn) = circ;
- *next_circ_on_conn_p(circ, conn) = circ;
+ *prevp = *nextp = circ;
} else {
circuit_t *head = conn->active_circuits;
circuit_t *old_tail = *prev_circ_on_conn_p(head, conn);
*next_circ_on_conn_p(old_tail, conn) = circ;
- *next_circ_on_conn_p(circ, conn) = head;
+ *nextp = head;
*prev_circ_on_conn_p(head, conn) = circ;
- *prev_circ_on_conn_p(circ, conn) = old_tail;
+ *prevp = old_tail;
}
assert_active_circuits_ok_paranoid(conn);
}
/** Remove <b>circ</b> to the list of circuits with pending cells on
- * <b>conn</b>. */
+ * <b>conn</b>. No effect if <b>circ</b> is already unlinked. */
void
make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn)
{
- circuit_t *next = *next_circ_on_conn_p(circ, conn);
- circuit_t *prev = *prev_circ_on_conn_p(circ, conn);
+ circuit_t **nextp = next_circ_on_conn_p(circ, conn);
+ circuit_t **prevp = prev_circ_on_conn_p(circ, conn);
+ circuit_t *next = *nextp, *prev = *prevp;
+
+ if (!next && !prev) {
+ /* Already inactive. */
+ return;
+ }
+
tor_assert(next && prev);
tor_assert(*prev_circ_on_conn_p(next, conn) == circ);
tor_assert(*next_circ_on_conn_p(prev, conn) == circ);
@@ -1622,8 +1633,7 @@ make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn)
if (conn->active_circuits == circ)
conn->active_circuits = next;
}
- *prev_circ_on_conn_p(circ, conn) = NULL;
- *next_circ_on_conn_p(circ, conn) = NULL;
+ *prevp = *nextp = NULL;
assert_active_circuits_ok_paranoid(conn);
}