diff options
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r-- | src/or/circuitlist.c | 518 |
1 files changed, 311 insertions, 207 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index d9b74bd4c2..b73822635d 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -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,190 @@ 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; + int make_active, attached = 0; 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; + 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; + 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) { + /* + * If we're changing channels or ID and had an old channel and a non + * zero old ID and weren't marked for close (i.e., we should have been + * attached), detach the circuit. ID changes require this because + * circuitmux hashes on (channel_id, circuit_id). + */ + if (old_id != 0 && (old_chan != chan || old_id != id) && + !(circ->marked_for_close)) { + tor_assert(old_chan->cmux); + circuitmux_detach_circuit(old_chan->cmux, circ); + } + + /* we may need to remove it from the conn-circid map */ 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; + if (direction == CELL_DIRECTION_OUT) { + /* One fewer circuits use old_chan as n_chan */ + --(old_chan->num_n_circuits); + } else { + /* One fewer circuits use old_chan as p_chan */ + --(old_chan->num_p_circuits); + } } - if (was_active && old_conn != conn) - make_circuit_inactive_on_conn(circ,old_conn); } /* 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); - ++conn->n_circuits; + /* + * Attach to the circuitmux if we're changing channels or IDs and + * have a new channel and ID to use and the circuit is not marked for + * close. + */ + if (chan && id != 0 && (old_chan != chan || old_id != id) && + !(circ->marked_for_close)) { + tor_assert(chan->cmux); + circuitmux_attach_circuit(chan->cmux, circ, direction); + attached = 1; + } + + /* + * This is a no-op if we have no cells, but if we do it marks us active to + * the circuitmux + */ + if (make_active && attached) + update_circuit_on_cmux(circ, direction); + + /* Adjust circuit counts on new channel */ + if (direction == CELL_DIRECTION_OUT) { + ++chan->num_n_circuits; + } else { + ++chan->num_p_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 +239,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,51 +269,53 @@ 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); - 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, - circ->n_hop->identity_digest, DIGEST_LEN)) + if (tor_memneq(chan->identity_digest, + circ->n_hop->identity_digest, DIGEST_LEN)) continue; } smartlist_add(out, circ); } 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); + + 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->nickname ? chan->nickname : "NULL", + channel_get_canonical_remote_descr(chan), cnt); return cnt; } @@ -324,7 +363,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); @@ -518,12 +557,6 @@ init_circuit_base(circuit_t *circ) circ->package_window = circuit_initial_package_window(); circ->deliver_window = CIRCWINDOW_START; - /* Initialize the cell_ewma_t structure */ - 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; - circuit_add(circ); } @@ -556,7 +589,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,23 +597,13 @@ 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; init_circuit_base(TO_CIRCUIT(circ)); - /* Initialize the cell_ewma_t structure */ - - /* 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; - - /* It's not in any heap yet. */ - circ->p_cell_ewma.heap_index = -1; - return circ; } @@ -641,22 +664,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 +725,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 +765,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 +791,101 @@ 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); + + 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->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 +910,39 @@ 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 " U64_FORMAT " (%p)", + found->circuit, circ_id, + U64_PRINTF_ARG(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 " U64_FORMAT " (%p)", + circ_id, + U64_PRINTF_ARG(chan->global_identifier), chan); return NULL; /* The rest of this checks for bugs. Disabled by default. */ @@ -862,15 +952,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,26 +970,38 @@ 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 return circ; } +/** 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>chan</b>, either as p_chan or n_chan. + * Return NULL if no such circuit exists. + */ +circuit_t * +circuit_get_by_circid_channel_even_if_marked(circid_t circ_id, + channel_t *chan) +{ + return circuit_get_by_circid_channel_impl(circ_id, chan); +} + /** 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 +1018,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_circuits(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 +1369,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 +1408,10 @@ _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); + circuitmux_detach_circuit(circ->n_chan->cmux, circ); } if (! CIRCUIT_IS_ORIGIN(circ)) { @@ -1333,9 +1436,10 @@ _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); + circuitmux_detach_circuit(or_circ->p_chan->cmux, circ); } } else { origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); @@ -1438,22 +1542,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 +1568,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 +1576,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); |