summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/circuitlist.c29
-rw-r--r--src/or/or.h12
-rw-r--r--src/or/relay.c34
3 files changed, 42 insertions, 33 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 4f8b17d8b3..73ca7e1fa0 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -80,21 +80,25 @@ orconn_circid_circuit_map_t *_last_circid_orconn_ent = NULL;
static void
circuit_set_circid_orconn_helper(circuit_t *circ, int direction,
uint16_t id,
- or_connection_t *conn,
- int active)
+ or_connection_t *conn)
{
orconn_circid_circuit_map_t search;
orconn_circid_circuit_map_t *found;
or_connection_t *old_conn, **conn_ptr;
uint16_t old_id, *circid_ptr;
+ int was_active, make_active;
if (direction == CELL_DIRECTION_OUT) {
conn_ptr = &circ->n_conn;
circid_ptr = &circ->n_circ_id;
+ was_active = circ->next_active_on_n_conn != NULL;
+ make_active = circ->n_conn_cells.n > 0;
} else {
or_circuit_t *c = TO_OR_CIRCUIT(circ);
conn_ptr = &c->p_conn;
circid_ptr = &c->p_circ_id;
+ was_active = c->next_active_on_p_conn != NULL;
+ make_active = c->p_conn_cells.n > 0;
}
old_conn = *conn_ptr;
old_id = *circid_ptr;
@@ -119,7 +123,7 @@ circuit_set_circid_orconn_helper(circuit_t *circ, int direction,
tor_free(found);
--old_conn->n_circuits;
}
- if (active && old_conn != conn)
+ if (was_active && old_conn != conn)
make_circuit_inactive_on_conn(circ,old_conn);
}
@@ -144,7 +148,7 @@ circuit_set_circid_orconn_helper(circuit_t *circ, int direction,
found->circuit = circ;
HT_INSERT(orconn_circid_map, &orconn_circid_circuit_map, found);
}
- if (active && old_conn != conn)
+ if (make_active && old_conn != conn)
make_circuit_active_on_conn(circ,conn);
++conn->n_circuits;
@@ -157,15 +161,11 @@ void
circuit_set_p_circid_orconn(or_circuit_t *circ, uint16_t id,
or_connection_t *conn)
{
- int active = circ->p_conn_cells.n > 0;
-
- tor_assert(bool_eq(active, circ->next_active_on_p_conn));
-
circuit_set_circid_orconn_helper(TO_CIRCUIT(circ), CELL_DIRECTION_IN,
- id, conn, active);
+ id, conn);
if (conn)
- tor_assert(bool_eq(active, circ->next_active_on_p_conn));
+ tor_assert(bool_eq(circ->p_conn_cells.n, circ->next_active_on_p_conn));
}
/** Set the n_conn field of a circuit <b>circ</b>, along
@@ -175,15 +175,10 @@ void
circuit_set_n_circid_orconn(circuit_t *circ, uint16_t id,
or_connection_t *conn)
{
- int active = circ->n_conn_cells.n > 0;
-
- tor_assert(bool_eq(active, circ->next_active_on_n_conn));
-
- circuit_set_circid_orconn_helper(circ, CELL_DIRECTION_OUT,
- id, conn, active);
+ circuit_set_circid_orconn_helper(circ, CELL_DIRECTION_OUT, id, conn);
if (conn)
- tor_assert(bool_eq(active, circ->next_active_on_n_conn));
+ tor_assert(bool_eq(circ->n_conn_cells.n, circ->next_active_on_n_conn));
}
/** Change the state of <b>circ</b> to <b>state</b>, adding it to or removing
diff --git a/src/or/or.h b/src/or/or.h
index 7345d27ba0..cca9c96e07 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1430,10 +1430,12 @@ typedef struct circuit_t {
* circuit marked for close? */
/** Next circuit in the doubly-linked ring of circuits waiting to add
- * cells to n_conn. NULL if we have no cells pending. */
+ * cells to n_conn. NULL if we have no cells pending, or if we're not
+ * linked to an OR connection. */
struct circuit_t *next_active_on_n_conn;
/** Previous circuit in the doubly-linked ring of circuits waiting to add
- * cells to n_conn. NULL if we have no cells pending. */
+ * cells to n_conn. NULL if we have no cells pending, or if we're not
+ * linked to an OR connection. */
struct circuit_t *prev_active_on_n_conn;
struct circuit_t *next; /**< Next circuit in linked list of all circuits. */
} circuit_t;
@@ -1490,10 +1492,12 @@ typedef struct or_circuit_t {
circuit_t _base;
/** Next circuit in the doubly-linked ring of circuits waiting to add
- * cells to p_conn. NULL if we have no cells pending. */
+ * cells to p_conn. NULL if we have no cells pending, or if we're not
+ * linked to an OR connection. */
struct circuit_t *next_active_on_p_conn;
/** Previous circuit in the doubly-linked ring of circuits waiting to add
- * cells to p_conn. NULL if we have no cells pending. */
+ * cells to p_conn. NULL if we have no cells pending, or if we're not
+ * linked to an OR connection. */
struct circuit_t *prev_active_on_p_conn;
/** The circuit_id used in the previous (backward) hop of this circuit. */
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);
}