diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-04-10 16:24:50 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-04-10 16:24:50 +0000 |
commit | f95d232483a0e9fd78563bfdc061016baab6ef97 (patch) | |
tree | 7cb29766f595c542221a3d0a354f55daa6123794 /src/or/relay.c | |
parent | 58a6761056af4c5f50e9550f50625e91e55b30a1 (diff) | |
download | tor-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.c | 34 |
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); } |