|
@@ -10,6 +10,7 @@
|
|
|
**/
|
|
|
|
|
|
#include "or.h"
|
|
|
+#include "channel.h"
|
|
|
#include "circuitbuild.h"
|
|
|
#include "circuitlist.h"
|
|
|
#include "circuituse.h"
|
|
@@ -34,8 +35,8 @@
|
|
|
/** A global list of all circuits at this hop. */
|
|
|
circuit_t *global_circuitlist=NULL;
|
|
|
|
|
|
-/** A list of all the circuits in CIRCUIT_STATE_OR_WAIT. */
|
|
|
-static smartlist_t *circuits_pending_or_conns=NULL;
|
|
|
+/** A list of all the circuits in CIRCUIT_STATE_CHAN_WAIT. */
|
|
|
+static smartlist_t *circuits_pending_chans = NULL;
|
|
|
|
|
|
static void circuit_free(circuit_t *circ);
|
|
|
static void circuit_free_cpath(crypt_path_t *cpath);
|
|
@@ -44,154 +45,156 @@ static void cpath_ref_decref(crypt_path_reference_t *cpath_ref);
|
|
|
|
|
|
/********* END VARIABLES ************/
|
|
|
|
|
|
-/** A map from OR connection and circuit ID to circuit. (Lookup performance is
|
|
|
+/** A map from channel and circuit ID to circuit. (Lookup performance is
|
|
|
* very important here, since we need to do it every time a cell arrives.) */
|
|
|
-typedef struct orconn_circid_circuit_map_t {
|
|
|
- HT_ENTRY(orconn_circid_circuit_map_t) node;
|
|
|
- or_connection_t *or_conn;
|
|
|
+typedef struct chan_circid_circuit_map_t {
|
|
|
+ HT_ENTRY(chan_circid_circuit_map_t) node;
|
|
|
+ channel_t *chan;
|
|
|
circid_t circ_id;
|
|
|
circuit_t *circuit;
|
|
|
-} orconn_circid_circuit_map_t;
|
|
|
+} chan_circid_circuit_map_t;
|
|
|
|
|
|
-/** Helper for hash tables: compare the OR connection and circuit ID for a and
|
|
|
+/** Helper for hash tables: compare the channel and circuit ID for a and
|
|
|
* b, and return less than, equal to, or greater than zero appropriately.
|
|
|
*/
|
|
|
static INLINE int
|
|
|
-_orconn_circid_entries_eq(orconn_circid_circuit_map_t *a,
|
|
|
- orconn_circid_circuit_map_t *b)
|
|
|
+_chan_circid_entries_eq(chan_circid_circuit_map_t *a,
|
|
|
+ chan_circid_circuit_map_t *b)
|
|
|
{
|
|
|
- return a->or_conn == b->or_conn && a->circ_id == b->circ_id;
|
|
|
+ return a->chan == b->chan && a->circ_id == b->circ_id;
|
|
|
}
|
|
|
|
|
|
/** Helper: return a hash based on circuit ID and the pointer value of
|
|
|
- * or_conn in <b>a</b>. */
|
|
|
+ * chan in <b>a</b>. */
|
|
|
static INLINE unsigned int
|
|
|
-_orconn_circid_entry_hash(orconn_circid_circuit_map_t *a)
|
|
|
+_chan_circid_entry_hash(chan_circid_circuit_map_t *a)
|
|
|
{
|
|
|
- return (((unsigned)a->circ_id)<<8) ^ (unsigned)(uintptr_t)(a->or_conn);
|
|
|
+ return (((unsigned)a->circ_id)<<8) ^ (unsigned)(uintptr_t)(a->chan);
|
|
|
}
|
|
|
|
|
|
-/** Map from [orconn,circid] to circuit. */
|
|
|
-static HT_HEAD(orconn_circid_map, orconn_circid_circuit_map_t)
|
|
|
- orconn_circid_circuit_map = HT_INITIALIZER();
|
|
|
-HT_PROTOTYPE(orconn_circid_map, orconn_circid_circuit_map_t, node,
|
|
|
- _orconn_circid_entry_hash, _orconn_circid_entries_eq)
|
|
|
-HT_GENERATE(orconn_circid_map, orconn_circid_circuit_map_t, node,
|
|
|
- _orconn_circid_entry_hash, _orconn_circid_entries_eq, 0.6,
|
|
|
+/** Map from [chan,circid] to circuit. */
|
|
|
+static HT_HEAD(chan_circid_map, chan_circid_circuit_map_t)
|
|
|
+ chan_circid_map = HT_INITIALIZER();
|
|
|
+HT_PROTOTYPE(chan_circid_map, chan_circid_circuit_map_t, node,
|
|
|
+ _chan_circid_entry_hash, _chan_circid_entries_eq)
|
|
|
+HT_GENERATE(chan_circid_map, chan_circid_circuit_map_t, node,
|
|
|
+ _chan_circid_entry_hash, _chan_circid_entries_eq, 0.6,
|
|
|
malloc, realloc, free)
|
|
|
|
|
|
-/** The most recently returned entry from circuit_get_by_circid_orconn;
|
|
|
+/** The most recently returned entry from circuit_get_by_circid_chan;
|
|
|
* used to improve performance when many cells arrive in a row from the
|
|
|
* same circuit.
|
|
|
*/
|
|
|
-orconn_circid_circuit_map_t *_last_circid_orconn_ent = NULL;
|
|
|
+chan_circid_circuit_map_t *_last_circid_chan_ent = NULL;
|
|
|
|
|
|
-/** Implementation helper for circuit_set_{p,n}_circid_orconn: A circuit ID
|
|
|
- * and/or or_connection for circ has just changed from <b>old_conn, old_id</b>
|
|
|
- * to <b>conn, id</b>. Adjust the conn,circid map as appropriate, removing
|
|
|
+/** Implementation helper for circuit_set_{p,n}_circid_channel: A circuit ID
|
|
|
+ * and/or channel for circ has just changed from <b>old_chan, old_id</b>
|
|
|
+ * to <b>chan, id</b>. Adjust the chan,circid map as appropriate, removing
|
|
|
* the old entry (if any) and adding a new one. */
|
|
|
static void
|
|
|
-circuit_set_circid_orconn_helper(circuit_t *circ, int direction,
|
|
|
- circid_t id,
|
|
|
- or_connection_t *conn)
|
|
|
+circuit_set_circid_chan_helper(circuit_t *circ, int direction,
|
|
|
+ circid_t id,
|
|
|
+ channel_t *chan)
|
|
|
{
|
|
|
- orconn_circid_circuit_map_t search;
|
|
|
- orconn_circid_circuit_map_t *found;
|
|
|
- or_connection_t *old_conn, **conn_ptr;
|
|
|
+ chan_circid_circuit_map_t search;
|
|
|
+ chan_circid_circuit_map_t *found;
|
|
|
+ channel_t *old_chan, **chan_ptr;
|
|
|
circid_t old_id, *circid_ptr;
|
|
|
int was_active, make_active;
|
|
|
|
|
|
+ if (chan) tor_assert(!(chan->is_listener));
|
|
|
+
|
|
|
if (direction == CELL_DIRECTION_OUT) {
|
|
|
- conn_ptr = &circ->n_conn;
|
|
|
+ chan_ptr = &circ->n_chan;
|
|
|
circid_ptr = &circ->n_circ_id;
|
|
|
- was_active = circ->next_active_on_n_conn != NULL;
|
|
|
- make_active = circ->n_conn_cells.n > 0;
|
|
|
+ was_active = circ->next_active_on_n_chan != NULL;
|
|
|
+ make_active = circ->n_chan_cells.n > 0;
|
|
|
} else {
|
|
|
or_circuit_t *c = TO_OR_CIRCUIT(circ);
|
|
|
- conn_ptr = &c->p_conn;
|
|
|
+ chan_ptr = &c->p_chan;
|
|
|
circid_ptr = &c->p_circ_id;
|
|
|
- was_active = c->next_active_on_p_conn != NULL;
|
|
|
- make_active = c->p_conn_cells.n > 0;
|
|
|
+ was_active = c->next_active_on_p_chan != NULL;
|
|
|
+ make_active = c->p_chan_cells.n > 0;
|
|
|
}
|
|
|
- old_conn = *conn_ptr;
|
|
|
+ old_chan = *chan_ptr;
|
|
|
old_id = *circid_ptr;
|
|
|
|
|
|
- if (id == old_id && conn == old_conn)
|
|
|
+ if (id == old_id && chan == old_chan)
|
|
|
return;
|
|
|
|
|
|
- if (_last_circid_orconn_ent &&
|
|
|
- ((old_id == _last_circid_orconn_ent->circ_id &&
|
|
|
- old_conn == _last_circid_orconn_ent->or_conn) ||
|
|
|
- (id == _last_circid_orconn_ent->circ_id &&
|
|
|
- conn == _last_circid_orconn_ent->or_conn))) {
|
|
|
- _last_circid_orconn_ent = NULL;
|
|
|
+ if (_last_circid_chan_ent &&
|
|
|
+ ((old_id == _last_circid_chan_ent->circ_id &&
|
|
|
+ old_chan == _last_circid_chan_ent->chan) ||
|
|
|
+ (id == _last_circid_chan_ent->circ_id &&
|
|
|
+ chan == _last_circid_chan_ent->chan))) {
|
|
|
+ _last_circid_chan_ent = NULL;
|
|
|
}
|
|
|
|
|
|
- if (old_conn) { /* we may need to remove it from the conn-circid map */
|
|
|
- tor_assert(old_conn->_base.magic == OR_CONNECTION_MAGIC);
|
|
|
+ if (old_chan) { /* we may need to remove it from the conn-circid map */
|
|
|
+ tor_assert(!(old_chan->is_listener));
|
|
|
search.circ_id = old_id;
|
|
|
- search.or_conn = old_conn;
|
|
|
- found = HT_REMOVE(orconn_circid_map, &orconn_circid_circuit_map, &search);
|
|
|
+ search.chan = old_chan;
|
|
|
+ found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
|
|
|
if (found) {
|
|
|
tor_free(found);
|
|
|
- --old_conn->n_circuits;
|
|
|
+ --old_chan->u.cell_chan.n_circuits;
|
|
|
}
|
|
|
- if (was_active && old_conn != conn)
|
|
|
- make_circuit_inactive_on_conn(circ,old_conn);
|
|
|
+ if (was_active && old_chan != chan)
|
|
|
+ make_circuit_inactive_on_chan(circ, old_chan);
|
|
|
}
|
|
|
|
|
|
/* Change the values only after we have possibly made the circuit inactive
|
|
|
- * on the previous conn. */
|
|
|
- *conn_ptr = conn;
|
|
|
+ * on the previous chan. */
|
|
|
+ *chan_ptr = chan;
|
|
|
*circid_ptr = id;
|
|
|
|
|
|
- if (conn == NULL)
|
|
|
+ if (chan == NULL)
|
|
|
return;
|
|
|
|
|
|
/* now add the new one to the conn-circid map */
|
|
|
search.circ_id = id;
|
|
|
- search.or_conn = conn;
|
|
|
- found = HT_FIND(orconn_circid_map, &orconn_circid_circuit_map, &search);
|
|
|
+ search.chan = chan;
|
|
|
+ found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
|
|
|
if (found) {
|
|
|
found->circuit = circ;
|
|
|
} else {
|
|
|
- found = tor_malloc_zero(sizeof(orconn_circid_circuit_map_t));
|
|
|
+ found = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
|
|
|
found->circ_id = id;
|
|
|
- found->or_conn = conn;
|
|
|
+ found->chan = chan;
|
|
|
found->circuit = circ;
|
|
|
- HT_INSERT(orconn_circid_map, &orconn_circid_circuit_map, found);
|
|
|
+ HT_INSERT(chan_circid_map, &chan_circid_map, found);
|
|
|
}
|
|
|
- if (make_active && old_conn != conn)
|
|
|
- make_circuit_active_on_conn(circ,conn);
|
|
|
+ if (make_active && old_chan != chan)
|
|
|
+ make_circuit_active_on_chan(circ,chan);
|
|
|
|
|
|
- ++conn->n_circuits;
|
|
|
+ ++chan->u.cell_chan.n_circuits;
|
|
|
}
|
|
|
|
|
|
/** Set the p_conn field of a circuit <b>circ</b>, along
|
|
|
* with the corresponding circuit ID, and add the circuit as appropriate
|
|
|
- * to the (orconn,id)-\>circuit map. */
|
|
|
+ * to the (chan,id)-\>circuit map. */
|
|
|
void
|
|
|
-circuit_set_p_circid_orconn(or_circuit_t *circ, circid_t id,
|
|
|
- or_connection_t *conn)
|
|
|
+circuit_set_p_circid_chan(or_circuit_t *circ, circid_t id,
|
|
|
+ channel_t *chan)
|
|
|
{
|
|
|
- circuit_set_circid_orconn_helper(TO_CIRCUIT(circ), CELL_DIRECTION_IN,
|
|
|
- id, conn);
|
|
|
+ circuit_set_circid_chan_helper(TO_CIRCUIT(circ), CELL_DIRECTION_IN,
|
|
|
+ id, chan);
|
|
|
|
|
|
- if (conn)
|
|
|
- tor_assert(bool_eq(circ->p_conn_cells.n, circ->next_active_on_p_conn));
|
|
|
+ if (chan)
|
|
|
+ tor_assert(bool_eq(circ->p_chan_cells.n, circ->next_active_on_p_chan));
|
|
|
}
|
|
|
|
|
|
/** Set the n_conn field of a circuit <b>circ</b>, along
|
|
|
* with the corresponding circuit ID, and add the circuit as appropriate
|
|
|
- * to the (orconn,id)-\>circuit map. */
|
|
|
+ * to the (chan,id)-\>circuit map. */
|
|
|
void
|
|
|
-circuit_set_n_circid_orconn(circuit_t *circ, circid_t id,
|
|
|
- or_connection_t *conn)
|
|
|
+circuit_set_n_circid_chan(circuit_t *circ, circid_t id,
|
|
|
+ channel_t *chan)
|
|
|
{
|
|
|
- circuit_set_circid_orconn_helper(circ, CELL_DIRECTION_OUT, id, conn);
|
|
|
+ circuit_set_circid_chan_helper(circ, CELL_DIRECTION_OUT, id, chan);
|
|
|
|
|
|
- if (conn)
|
|
|
- tor_assert(bool_eq(circ->n_conn_cells.n, circ->next_active_on_n_conn));
|
|
|
+ if (chan)
|
|
|
+ tor_assert(bool_eq(circ->n_chan_cells.n, circ->next_active_on_n_chan));
|
|
|
}
|
|
|
|
|
|
/** Change the state of <b>circ</b> to <b>state</b>, adding it to or removing
|
|
@@ -202,18 +205,18 @@ circuit_set_state(circuit_t *circ, uint8_t state)
|
|
|
tor_assert(circ);
|
|
|
if (state == circ->state)
|
|
|
return;
|
|
|
- if (!circuits_pending_or_conns)
|
|
|
- circuits_pending_or_conns = smartlist_new();
|
|
|
- if (circ->state == CIRCUIT_STATE_OR_WAIT) {
|
|
|
+ if (!circuits_pending_chans)
|
|
|
+ circuits_pending_chans = smartlist_new();
|
|
|
+ if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
|
|
|
/* remove from waiting-circuit list. */
|
|
|
- smartlist_remove(circuits_pending_or_conns, circ);
|
|
|
+ smartlist_remove(circuits_pending_chans, circ);
|
|
|
}
|
|
|
- if (state == CIRCUIT_STATE_OR_WAIT) {
|
|
|
+ if (state == CIRCUIT_STATE_CHAN_WAIT) {
|
|
|
/* add to waiting-circuit list. */
|
|
|
- smartlist_add(circuits_pending_or_conns, circ);
|
|
|
+ smartlist_add(circuits_pending_chans, circ);
|
|
|
}
|
|
|
if (state == CIRCUIT_STATE_OPEN)
|
|
|
- tor_assert(!circ->n_conn_onionskin);
|
|
|
+ tor_assert(!circ->n_chan_onionskin);
|
|
|
circ->state = state;
|
|
|
}
|
|
|
|
|
@@ -232,31 +235,31 @@ circuit_add(circuit_t *circ)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/** Append to <b>out</b> all circuits in state OR_WAIT waiting for
|
|
|
+/** Append to <b>out</b> all circuits in state CHAN_WAIT waiting for
|
|
|
* the given connection. */
|
|
|
void
|
|
|
-circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
|
|
|
+circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
|
|
|
{
|
|
|
tor_assert(out);
|
|
|
- tor_assert(or_conn);
|
|
|
+ tor_assert(chan);
|
|
|
+ tor_assert(!(chan->is_listener));
|
|
|
|
|
|
- if (!circuits_pending_or_conns)
|
|
|
+ if (!circuits_pending_chans)
|
|
|
return;
|
|
|
|
|
|
- SMARTLIST_FOREACH_BEGIN(circuits_pending_or_conns, circuit_t *, circ) {
|
|
|
+ SMARTLIST_FOREACH_BEGIN(circuits_pending_chans, circuit_t *, circ) {
|
|
|
if (circ->marked_for_close)
|
|
|
continue;
|
|
|
if (!circ->n_hop)
|
|
|
continue;
|
|
|
- tor_assert(circ->state == CIRCUIT_STATE_OR_WAIT);
|
|
|
+ tor_assert(circ->state == CIRCUIT_STATE_CHAN_WAIT);
|
|
|
if (tor_digest_is_zero(circ->n_hop->identity_digest)) {
|
|
|
/* Look at addr/port. This is an unkeyed connection. */
|
|
|
- if (!tor_addr_eq(&circ->n_hop->addr, &or_conn->_base.addr) ||
|
|
|
- circ->n_hop->port != or_conn->_base.port)
|
|
|
+ if (!channel_matches_extend_info(chan, circ->n_hop))
|
|
|
continue;
|
|
|
} else {
|
|
|
/* We expected a key. See if it's the right one. */
|
|
|
- if (tor_memneq(or_conn->identity_digest,
|
|
|
+ if (tor_memneq(chan->u.cell_chan.identity_digest,
|
|
|
circ->n_hop->identity_digest, DIGEST_LEN))
|
|
|
continue;
|
|
|
}
|
|
@@ -264,19 +267,24 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
|
|
|
} SMARTLIST_FOREACH_END(circ);
|
|
|
}
|
|
|
|
|
|
-/** Return the number of circuits in state OR_WAIT, waiting for the given
|
|
|
- * connection. */
|
|
|
+/** Return the number of circuits in state CHAN_WAIT, waiting for the given
|
|
|
+ * channel. */
|
|
|
int
|
|
|
-circuit_count_pending_on_or_conn(or_connection_t *or_conn)
|
|
|
+circuit_count_pending_on_channel(channel_t *chan)
|
|
|
{
|
|
|
int cnt;
|
|
|
smartlist_t *sl = smartlist_new();
|
|
|
- circuit_get_all_pending_on_or_conn(sl, or_conn);
|
|
|
+
|
|
|
+ tor_assert(chan);
|
|
|
+ tor_assert(!(chan->is_listener));
|
|
|
+
|
|
|
+ circuit_get_all_pending_on_channel(sl, chan);
|
|
|
cnt = smartlist_len(sl);
|
|
|
smartlist_free(sl);
|
|
|
log_debug(LD_CIRC,"or_conn to %s at %s, %d pending circs",
|
|
|
- or_conn->nickname ? or_conn->nickname : "NULL",
|
|
|
- or_conn->_base.address,
|
|
|
+ chan->u.cell_chan.nickname ?
|
|
|
+ chan->u.cell_chan.nickname : "NULL",
|
|
|
+ channel_get_canonical_remote_descr(chan),
|
|
|
cnt);
|
|
|
return cnt;
|
|
|
}
|
|
@@ -324,7 +332,7 @@ circuit_state_to_string(int state)
|
|
|
switch (state) {
|
|
|
case CIRCUIT_STATE_BUILDING: return "doing handshakes";
|
|
|
case CIRCUIT_STATE_ONIONSKIN_PENDING: return "processing the onion";
|
|
|
- case CIRCUIT_STATE_OR_WAIT: return "connecting to server";
|
|
|
+ case CIRCUIT_STATE_CHAN_WAIT: return "connecting to server";
|
|
|
case CIRCUIT_STATE_OPEN: return "open";
|
|
|
default:
|
|
|
log_warn(LD_BUG, "Unknown circuit state %d", state);
|
|
@@ -522,7 +530,7 @@ init_circuit_base(circuit_t *circ)
|
|
|
circ->n_cell_ewma.last_adjusted_tick = cell_ewma_get_tick();
|
|
|
circ->n_cell_ewma.cell_count = 0.0;
|
|
|
circ->n_cell_ewma.heap_index = -1;
|
|
|
- circ->n_cell_ewma.is_for_p_conn = 0;
|
|
|
+ circ->n_cell_ewma.is_for_p_chan = 0;
|
|
|
|
|
|
circuit_add(circ);
|
|
|
}
|
|
@@ -556,7 +564,7 @@ origin_circuit_new(void)
|
|
|
/** Allocate a new or_circuit_t, connected to <b>p_conn</b> as
|
|
|
* <b>p_circ_id</b>. If <b>p_conn</b> is NULL, the circuit is unattached. */
|
|
|
or_circuit_t *
|
|
|
-or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn)
|
|
|
+or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
|
|
|
{
|
|
|
/* CircIDs */
|
|
|
or_circuit_t *circ;
|
|
@@ -564,8 +572,8 @@ or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn)
|
|
|
circ = tor_malloc_zero(sizeof(or_circuit_t));
|
|
|
circ->_base.magic = OR_CIRCUIT_MAGIC;
|
|
|
|
|
|
- if (p_conn)
|
|
|
- circuit_set_p_circid_orconn(circ, p_circ_id, p_conn);
|
|
|
+ if (p_chan)
|
|
|
+ circuit_set_p_circid_chan(circ, p_circ_id, p_chan);
|
|
|
|
|
|
circ->remaining_relay_early_cells = MAX_RELAY_EARLY_CELLS_PER_CIRCUIT;
|
|
|
|
|
@@ -576,7 +584,7 @@ or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn)
|
|
|
/* Initialize the cell counts to 0 */
|
|
|
circ->p_cell_ewma.cell_count = 0.0;
|
|
|
circ->p_cell_ewma.last_adjusted_tick = cell_ewma_get_tick();
|
|
|
- circ->p_cell_ewma.is_for_p_conn = 1;
|
|
|
+ circ->p_cell_ewma.is_for_p_chan = 1;
|
|
|
|
|
|
/* It's not in any heap yet. */
|
|
|
circ->p_cell_ewma.heap_index = -1;
|
|
@@ -641,22 +649,22 @@ circuit_free(circuit_t *circ)
|
|
|
}
|
|
|
|
|
|
/* remove from map. */
|
|
|
- circuit_set_p_circid_orconn(ocirc, 0, NULL);
|
|
|
+ circuit_set_p_circid_chan(ocirc, 0, NULL);
|
|
|
|
|
|
/* Clear cell queue _after_ removing it from the map. Otherwise our
|
|
|
* "active" checks will be violated. */
|
|
|
- cell_queue_clear(ô->p_conn_cells);
|
|
|
+ cell_queue_clear(ô->p_chan_cells);
|
|
|
}
|
|
|
|
|
|
extend_info_free(circ->n_hop);
|
|
|
- tor_free(circ->n_conn_onionskin);
|
|
|
+ tor_free(circ->n_chan_onionskin);
|
|
|
|
|
|
/* Remove from map. */
|
|
|
- circuit_set_n_circid_orconn(circ, 0, NULL);
|
|
|
+ circuit_set_n_circid_chan(circ, 0, NULL);
|
|
|
|
|
|
/* Clear cell queue _after_ removing it from the map. Otherwise our
|
|
|
* "active" checks will be violated. */
|
|
|
- cell_queue_clear(&circ->n_conn_cells);
|
|
|
+ cell_queue_clear(&circ->n_chan_cells);
|
|
|
|
|
|
memset(mem, 0xAA, memlen); /* poison memory */
|
|
|
tor_free(mem);
|
|
@@ -702,10 +710,10 @@ circuit_free_all(void)
|
|
|
global_circuitlist = next;
|
|
|
}
|
|
|
|
|
|
- smartlist_free(circuits_pending_or_conns);
|
|
|
- circuits_pending_or_conns = NULL;
|
|
|
+ smartlist_free(circuits_pending_chans);
|
|
|
+ circuits_pending_chans = NULL;
|
|
|
|
|
|
- HT_CLEAR(orconn_circid_map, &orconn_circid_circuit_map);
|
|
|
+ HT_CLEAR(chan_circid_map, &chan_circid_map);
|
|
|
}
|
|
|
|
|
|
/** Deallocate space associated with the cpath node <b>victim</b>. */
|
|
@@ -742,8 +750,12 @@ cpath_ref_decref(crypt_path_reference_t *cpath_ref)
|
|
|
* of information about circuit <b>circ</b>.
|
|
|
*/
|
|
|
static void
|
|
|
-circuit_dump_details(int severity, circuit_t *circ, int conn_array_index,
|
|
|
- const char *type, int this_circid, int other_circid)
|
|
|
+circuit_dump_conn_details(int severity,
|
|
|
+ circuit_t *circ,
|
|
|
+ int conn_array_index,
|
|
|
+ const char *type,
|
|
|
+ int this_circid,
|
|
|
+ int other_circid)
|
|
|
{
|
|
|
log(severity, LD_CIRC, "Conn %d has %s circuit: circID %d (other side %d), "
|
|
|
"state %d (%s), born %ld:",
|
|
@@ -764,50 +776,102 @@ circuit_dump_by_conn(connection_t *conn, int severity)
|
|
|
circuit_t *circ;
|
|
|
edge_connection_t *tmpconn;
|
|
|
|
|
|
- for (circ=global_circuitlist;circ;circ = circ->next) {
|
|
|
+ for (circ = global_circuitlist; circ; circ = circ->next) {
|
|
|
circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
|
|
|
- if (circ->marked_for_close)
|
|
|
+
|
|
|
+ if (circ->marked_for_close) {
|
|
|
continue;
|
|
|
+ }
|
|
|
|
|
|
- if (! CIRCUIT_IS_ORIGIN(circ))
|
|
|
+ if (!CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
p_circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
|
|
|
+ }
|
|
|
|
|
|
- if (! CIRCUIT_IS_ORIGIN(circ) && TO_OR_CIRCUIT(circ)->p_conn &&
|
|
|
- TO_CONN(TO_OR_CIRCUIT(circ)->p_conn) == conn)
|
|
|
- circuit_dump_details(severity, circ, conn->conn_array_index, "App-ward",
|
|
|
- p_circ_id, n_circ_id);
|
|
|
if (CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
for (tmpconn=TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
|
|
|
tmpconn=tmpconn->next_stream) {
|
|
|
if (TO_CONN(tmpconn) == conn) {
|
|
|
- circuit_dump_details(severity, circ, conn->conn_array_index,
|
|
|
- "App-ward", p_circ_id, n_circ_id);
|
|
|
+ circuit_dump_conn_details(severity, circ, conn->conn_array_index,
|
|
|
+ "App-ward", p_circ_id, n_circ_id);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (circ->n_conn && TO_CONN(circ->n_conn) == conn)
|
|
|
- circuit_dump_details(severity, circ, conn->conn_array_index, "Exit-ward",
|
|
|
- n_circ_id, p_circ_id);
|
|
|
+
|
|
|
if (! CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
for (tmpconn=TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
|
|
|
tmpconn=tmpconn->next_stream) {
|
|
|
if (TO_CONN(tmpconn) == conn) {
|
|
|
- circuit_dump_details(severity, circ, conn->conn_array_index,
|
|
|
- "Exit-ward", n_circ_id, p_circ_id);
|
|
|
+ circuit_dump_conn_details(severity, circ, conn->conn_array_index,
|
|
|
+ "Exit-ward", n_circ_id, p_circ_id);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (!circ->n_conn && circ->n_hop &&
|
|
|
- tor_addr_eq(&circ->n_hop->addr, &conn->addr) &&
|
|
|
- circ->n_hop->port == conn->port &&
|
|
|
- conn->type == CONN_TYPE_OR &&
|
|
|
- tor_memeq(TO_OR_CONN(conn)->identity_digest,
|
|
|
- circ->n_hop->identity_digest, DIGEST_LEN)) {
|
|
|
- circuit_dump_details(severity, circ, conn->conn_array_index,
|
|
|
- (circ->state == CIRCUIT_STATE_OPEN &&
|
|
|
- !CIRCUIT_IS_ORIGIN(circ)) ?
|
|
|
- "Endpoint" : "Pending",
|
|
|
- n_circ_id, p_circ_id);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** A helper function for circuit_dump_by_chan() below. Log a bunch
|
|
|
+ * of information about circuit <b>circ</b>.
|
|
|
+ */
|
|
|
+static void
|
|
|
+circuit_dump_chan_details(int severity,
|
|
|
+ circuit_t *circ,
|
|
|
+ channel_t *chan,
|
|
|
+ const char *type,
|
|
|
+ int this_circid,
|
|
|
+ int other_circid)
|
|
|
+{
|
|
|
+ log(severity, LD_CIRC, "Conn %p has %s circuit: circID %d (other side %d), "
|
|
|
+ "state %d (%s), born %ld:",
|
|
|
+ chan, type, this_circid, other_circid, circ->state,
|
|
|
+ circuit_state_to_string(circ->state),
|
|
|
+ (long)circ->timestamp_created.tv_sec);
|
|
|
+ if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
|
|
|
+ circuit_log_path(severity, LD_CIRC, TO_ORIGIN_CIRCUIT(circ));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** Log, at severity <b>severity</b>, information about each circuit
|
|
|
+ * that is connected to <b>chan</b>.
|
|
|
+ */
|
|
|
+void
|
|
|
+circuit_dump_by_chan(channel_t *chan, int severity)
|
|
|
+{
|
|
|
+ circuit_t *circ;
|
|
|
+
|
|
|
+ tor_assert(chan);
|
|
|
+ tor_assert(!(chan->is_listener));
|
|
|
+
|
|
|
+ for (circ = global_circuitlist; circ; circ = circ->next) {
|
|
|
+ circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
|
|
|
+
|
|
|
+ if (circ->marked_for_close) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
+ p_circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (! CIRCUIT_IS_ORIGIN(circ) && TO_OR_CIRCUIT(circ)->p_chan &&
|
|
|
+ TO_OR_CIRCUIT(circ)->p_chan == chan) {
|
|
|
+ circuit_dump_chan_details(severity, circ, chan, "App-ward",
|
|
|
+ p_circ_id, n_circ_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (circ->n_chan && circ->n_chan == chan) {
|
|
|
+ circuit_dump_chan_details(severity, circ, chan, "Exit-ward",
|
|
|
+ n_circ_id, p_circ_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!circ->n_chan && circ->n_hop &&
|
|
|
+ channel_matches_extend_info(chan, circ->n_hop) &&
|
|
|
+ tor_memeq(chan->u.cell_chan.identity_digest,
|
|
|
+ circ->n_hop->identity_digest, DIGEST_LEN)) {
|
|
|
+ circuit_dump_chan_details(severity, circ, chan,
|
|
|
+ (circ->state == CIRCUIT_STATE_OPEN &&
|
|
|
+ !CIRCUIT_IS_ORIGIN(circ)) ?
|
|
|
+ "Endpoint" : "Pending",
|
|
|
+ n_circ_id, p_circ_id);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -832,27 +896,37 @@ circuit_get_by_global_id(uint32_t id)
|
|
|
|
|
|
/** Return a circ such that:
|
|
|
* - circ-\>n_circ_id or circ-\>p_circ_id is equal to <b>circ_id</b>, and
|
|
|
- * - circ is attached to <b>conn</b>, either as p_conn or n_conn.
|
|
|
+ * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
|
|
|
* Return NULL if no such circuit exists.
|
|
|
*/
|
|
|
static INLINE circuit_t *
|
|
|
-circuit_get_by_circid_orconn_impl(circid_t circ_id, or_connection_t *conn)
|
|
|
+circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan)
|
|
|
{
|
|
|
- orconn_circid_circuit_map_t search;
|
|
|
- orconn_circid_circuit_map_t *found;
|
|
|
+ chan_circid_circuit_map_t search;
|
|
|
+ chan_circid_circuit_map_t *found;
|
|
|
|
|
|
- if (_last_circid_orconn_ent &&
|
|
|
- circ_id == _last_circid_orconn_ent->circ_id &&
|
|
|
- conn == _last_circid_orconn_ent->or_conn) {
|
|
|
- found = _last_circid_orconn_ent;
|
|
|
+ if (_last_circid_chan_ent &&
|
|
|
+ circ_id == _last_circid_chan_ent->circ_id &&
|
|
|
+ chan == _last_circid_chan_ent->chan) {
|
|
|
+ found = _last_circid_chan_ent;
|
|
|
} else {
|
|
|
search.circ_id = circ_id;
|
|
|
- search.or_conn = conn;
|
|
|
- found = HT_FIND(orconn_circid_map, &orconn_circid_circuit_map, &search);
|
|
|
- _last_circid_orconn_ent = found;
|
|
|
+ search.chan = chan;
|
|
|
+ found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
|
|
|
+ _last_circid_chan_ent = found;
|
|
|
}
|
|
|
- if (found && found->circuit)
|
|
|
+ if (found && found->circuit) {
|
|
|
+ log_debug(LD_CIRC,
|
|
|
+ "circuit_get_by_circid_channel_impl() returning circuit %p for"
|
|
|
+ " circ_id %d, channel ID %lu (%p)",
|
|
|
+ found->circuit, circ_id, chan->global_identifier, chan);
|
|
|
return found->circuit;
|
|
|
+ }
|
|
|
+
|
|
|
+ log_debug(LD_CIRC,
|
|
|
+ "circuit_get_by_circid_channel_impl() found nothing for"
|
|
|
+ " circ_id %d, channel ID %lu (%p)",
|
|
|
+ circ_id, chan->global_identifier, chan);
|
|
|
|
|
|
return NULL;
|
|
|
/* The rest of this checks for bugs. Disabled by default. */
|
|
@@ -862,15 +936,15 @@ circuit_get_by_circid_orconn_impl(circid_t circ_id, or_connection_t *conn)
|
|
|
for (circ=global_circuitlist;circ;circ = circ->next) {
|
|
|
if (! CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
|
|
|
- if (or_circ->p_conn == conn && or_circ->p_circ_id == circ_id) {
|
|
|
+ if (or_circ->p_chan == chan && or_circ->p_circ_id == circ_id) {
|
|
|
log_warn(LD_BUG,
|
|
|
- "circuit matches p_conn, but not in hash table (Bug!)");
|
|
|
+ "circuit matches p_chan, but not in hash table (Bug!)");
|
|
|
return circ;
|
|
|
}
|
|
|
}
|
|
|
- if (circ->n_conn == conn && circ->n_circ_id == circ_id) {
|
|
|
+ if (circ->n_chan == chan && circ->n_circ_id == circ_id) {
|
|
|
log_warn(LD_BUG,
|
|
|
- "circuit matches n_conn, but not in hash table (Bug!)");
|
|
|
+ "circuit matches n_chan, but not in hash table (Bug!)");
|
|
|
return circ;
|
|
|
}
|
|
|
}
|
|
@@ -880,14 +954,14 @@ circuit_get_by_circid_orconn_impl(circid_t circ_id, or_connection_t *conn)
|
|
|
|
|
|
/** Return a circ such that:
|
|
|
* - circ-\>n_circ_id or circ-\>p_circ_id is equal to <b>circ_id</b>, and
|
|
|
- * - circ is attached to <b>conn</b>, either as p_conn or n_conn.
|
|
|
+ * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
|
|
|
* - circ is not marked for close.
|
|
|
* Return NULL if no such circuit exists.
|
|
|
*/
|
|
|
circuit_t *
|
|
|
-circuit_get_by_circid_orconn(circid_t circ_id, or_connection_t *conn)
|
|
|
+circuit_get_by_circid_channel(circid_t circ_id, channel_t *chan)
|
|
|
{
|
|
|
- circuit_t *circ = circuit_get_by_circid_orconn_impl(circ_id, conn);
|
|
|
+ circuit_t *circ = circuit_get_by_circid_channel_impl(circ_id, chan);
|
|
|
if (!circ || circ->marked_for_close)
|
|
|
return NULL;
|
|
|
else
|
|
@@ -895,11 +969,11 @@ circuit_get_by_circid_orconn(circid_t circ_id, or_connection_t *conn)
|
|
|
}
|
|
|
|
|
|
/** Return true iff the circuit ID <b>circ_id</b> is currently used by a
|
|
|
- * circuit, marked or not, on <b>conn</b>. */
|
|
|
+ * circuit, marked or not, on <b>chan</b>. */
|
|
|
int
|
|
|
-circuit_id_in_use_on_orconn(circid_t circ_id, or_connection_t *conn)
|
|
|
+circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan)
|
|
|
{
|
|
|
- return circuit_get_by_circid_orconn_impl(circ_id, conn) != NULL;
|
|
|
+ return circuit_get_by_circid_channel_impl(circ_id, chan) != NULL;
|
|
|
}
|
|
|
|
|
|
/** Return the circuit that a given edge connection is using. */
|
|
@@ -916,27 +990,27 @@ circuit_get_by_edge_conn(edge_connection_t *conn)
|
|
|
return circ;
|
|
|
}
|
|
|
|
|
|
-/** For each circuit that has <b>conn</b> as n_conn or p_conn, unlink the
|
|
|
- * circuit from the orconn,circid map, and mark it for close if it hasn't
|
|
|
+/** For each circuit that has <b>chan</b> as n_chan or p_chan, unlink the
|
|
|
+ * circuit from the chan,circid map, and mark it for close if it hasn't
|
|
|
* been marked already.
|
|
|
*/
|
|
|
void
|
|
|
-circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason)
|
|
|
+circuit_unlink_all_from_channel(channel_t *chan, int reason)
|
|
|
{
|
|
|
circuit_t *circ;
|
|
|
|
|
|
- connection_or_unlink_all_active_circs(conn);
|
|
|
+ channel_unlink_all_active_circs(chan);
|
|
|
|
|
|
for (circ = global_circuitlist; circ; circ = circ->next) {
|
|
|
int mark = 0;
|
|
|
- if (circ->n_conn == conn) {
|
|
|
- circuit_set_n_circid_orconn(circ, 0, NULL);
|
|
|
+ if (circ->n_chan == chan) {
|
|
|
+ circuit_set_n_circid_chan(circ, 0, NULL);
|
|
|
mark = 1;
|
|
|
}
|
|
|
if (! CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
|
|
|
- if (or_circ->p_conn == conn) {
|
|
|
- circuit_set_p_circid_orconn(or_circ, 0, NULL);
|
|
|
+ if (or_circ->p_chan == chan) {
|
|
|
+ circuit_set_p_circid_chan(or_circ, 0, NULL);
|
|
|
mark = 1;
|
|
|
}
|
|
|
}
|
|
@@ -1267,9 +1341,9 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
|
|
|
circuit_rep_hist_note_result(ocirc);
|
|
|
}
|
|
|
}
|
|
|
- if (circ->state == CIRCUIT_STATE_OR_WAIT) {
|
|
|
- if (circuits_pending_or_conns)
|
|
|
- smartlist_remove(circuits_pending_or_conns, circ);
|
|
|
+ if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
|
|
|
+ if (circuits_pending_chans)
|
|
|
+ smartlist_remove(circuits_pending_chans, circ);
|
|
|
}
|
|
|
if (CIRCUIT_IS_ORIGIN(circ)) {
|
|
|
control_event_circuit_status(TO_ORIGIN_CIRCUIT(circ),
|
|
@@ -1306,9 +1380,9 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
|
|
|
INTRO_POINT_FAILURE_UNREACHABLE);
|
|
|
}
|
|
|
}
|
|
|
- if (circ->n_conn) {
|
|
|
- circuit_clear_cell_queue(circ, circ->n_conn);
|
|
|
- connection_or_send_destroy(circ->n_circ_id, circ->n_conn, reason);
|
|
|
+ if (circ->n_chan) {
|
|
|
+ circuit_clear_cell_queue(circ, circ->n_chan);
|
|
|
+ channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
|
|
|
}
|
|
|
|
|
|
if (! CIRCUIT_IS_ORIGIN(circ)) {
|
|
@@ -1333,9 +1407,9 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
|
|
|
conn->on_circuit = NULL;
|
|
|
}
|
|
|
|
|
|
- if (or_circ->p_conn) {
|
|
|
- circuit_clear_cell_queue(circ, or_circ->p_conn);
|
|
|
- connection_or_send_destroy(or_circ->p_circ_id, or_circ->p_conn, reason);
|
|
|
+ if (or_circ->p_chan) {
|
|
|
+ circuit_clear_cell_queue(circ, or_circ->p_chan);
|
|
|
+ channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
|
|
|
}
|
|
|
} else {
|
|
|
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
|
|
@@ -1438,22 +1512,22 @@ assert_circuit_ok(const circuit_t *c)
|
|
|
or_circ = TO_OR_CIRCUIT(nonconst_circ);
|
|
|
}
|
|
|
|
|
|
- if (c->n_conn) {
|
|
|
+ if (c->n_chan) {
|
|
|
tor_assert(!c->n_hop);
|
|
|
|
|
|
if (c->n_circ_id) {
|
|
|
/* We use the _impl variant here to make sure we don't fail on marked
|
|
|
* circuits, which would not be returned by the regular function. */
|
|
|
- circuit_t *c2 = circuit_get_by_circid_orconn_impl(c->n_circ_id,
|
|
|
- c->n_conn);
|
|
|
+ circuit_t *c2 = circuit_get_by_circid_channel_impl(c->n_circ_id,
|
|
|
+ c->n_chan);
|
|
|
tor_assert(c == c2);
|
|
|
}
|
|
|
}
|
|
|
- if (or_circ && or_circ->p_conn) {
|
|
|
+ if (or_circ && or_circ->p_chan) {
|
|
|
if (or_circ->p_circ_id) {
|
|
|
/* ibid */
|
|
|
- circuit_t *c2 = circuit_get_by_circid_orconn_impl(or_circ->p_circ_id,
|
|
|
- or_circ->p_conn);
|
|
|
+ circuit_t *c2 = circuit_get_by_circid_channel_impl(or_circ->p_circ_id,
|
|
|
+ or_circ->p_chan);
|
|
|
tor_assert(c == c2);
|
|
|
}
|
|
|
}
|
|
@@ -1464,7 +1538,7 @@ assert_circuit_ok(const circuit_t *c)
|
|
|
tor_assert(c->deliver_window >= 0);
|
|
|
tor_assert(c->package_window >= 0);
|
|
|
if (c->state == CIRCUIT_STATE_OPEN) {
|
|
|
- tor_assert(!c->n_conn_onionskin);
|
|
|
+ tor_assert(!c->n_chan_onionskin);
|
|
|
if (or_circ) {
|
|
|
tor_assert(or_circ->n_crypto);
|
|
|
tor_assert(or_circ->p_crypto);
|
|
@@ -1472,12 +1546,12 @@ assert_circuit_ok(const circuit_t *c)
|
|
|
tor_assert(or_circ->p_digest);
|
|
|
}
|
|
|
}
|
|
|
- if (c->state == CIRCUIT_STATE_OR_WAIT && !c->marked_for_close) {
|
|
|
- tor_assert(circuits_pending_or_conns &&
|
|
|
- smartlist_isin(circuits_pending_or_conns, c));
|
|
|
+ if (c->state == CIRCUIT_STATE_CHAN_WAIT && !c->marked_for_close) {
|
|
|
+ tor_assert(circuits_pending_chans &&
|
|
|
+ smartlist_isin(circuits_pending_chans, c));
|
|
|
} else {
|
|
|
- tor_assert(!circuits_pending_or_conns ||
|
|
|
- !smartlist_isin(circuits_pending_or_conns, c));
|
|
|
+ tor_assert(!circuits_pending_chans ||
|
|
|
+ !smartlist_isin(circuits_pending_chans, c));
|
|
|
}
|
|
|
if (origin_circ && origin_circ->cpath) {
|
|
|
assert_cpath_ok(origin_circ->cpath);
|