summaryrefslogtreecommitdiff
path: root/src/or/circuitlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r--src/or/circuitlist.c589
1 files changed, 201 insertions, 388 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index dba7864861..73513c4030 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -33,7 +33,7 @@ static void circuit_free_cpath_node(crypt_path_t *victim);
* 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;
+ connection_t *or_conn;
uint16_t circ_id;
circuit_t *circuit;
} orconn_circid_circuit_map_t;
@@ -68,14 +68,35 @@ HT_GENERATE(orconn_circid_map, orconn_circid_circuit_map_t, node,
*/
orconn_circid_circuit_map_t *_last_circid_orconn_ent = NULL;
-static void
-circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id,
- or_connection_t *conn,
- uint16_t old_id, or_connection_t *old_conn)
+/** Set the p_conn or 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. */
+void
+circuit_set_circid_orconn(circuit_t *circ, uint16_t id,
+ connection_t *conn,
+ enum which_conn_changed_t which)
{
+ uint16_t old_id;
+ connection_t *old_conn;
orconn_circid_circuit_map_t search;
orconn_circid_circuit_map_t *found;
+ tor_assert(!conn || conn->type == CONN_TYPE_OR);
+
+ if (which == P_CONN_CHANGED) {
+ old_id = circ->p_circ_id;
+ old_conn = circ->p_conn;
+ circ->p_circ_id = id;
+ circ->p_conn = conn;
+ } else {
+ old_id = circ->n_circ_id;
+ old_conn = circ->n_conn;
+ circ->n_circ_id = id;
+ circ->n_conn = conn;
+ }
+ if (conn == old_conn && old_id == id)
+ return;
+
if (_last_circid_orconn_ent &&
((old_id == _last_circid_orconn_ent->circ_id &&
old_conn == _last_circid_orconn_ent->or_conn) ||
@@ -85,7 +106,7 @@ circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id,
}
if (old_conn) { /* we may need to remove it from the conn-circid map */
- tor_assert(old_conn->_base.magic == OR_CONNECTION_MAGIC);
+ tor_assert(old_conn->magic == CONNECTION_MAGIC);
search.circ_id = old_id;
search.or_conn = old_conn;
found = HT_REMOVE(orconn_circid_map, &orconn_circid_circuit_map, &search);
@@ -114,47 +135,6 @@ circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id,
++conn->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. */
-void
-circuit_set_p_circid_orconn(or_circuit_t *circ, uint16_t id,
- or_connection_t *conn)
-{
- uint16_t old_id;
- or_connection_t *old_conn;
-
- old_id = circ->p_circ_id;
- old_conn = circ->p_conn;
- circ->p_circ_id = id;
- circ->p_conn = conn;
-
- if (id == old_id && conn == old_conn)
- return;
- circuit_set_circid_orconn_helper(TO_CIRCUIT(circ), id, conn,
- old_id, old_conn);
-}
-
-/** 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. */
-void
-circuit_set_n_circid_orconn(circuit_t *circ, uint16_t id,
- or_connection_t *conn)
-{
- uint16_t old_id;
- or_connection_t *old_conn;
-
- old_id = circ->n_circ_id;
- old_conn = circ->n_conn;
- circ->n_circ_id = id;
- circ->n_conn = conn;
-
- if (id == old_id && conn == old_conn)
- return;
- circuit_set_circid_orconn_helper(circ, id, conn, old_id, old_conn);
-}
-
/** Change the state of <b>circ</b> to <b>state</b>, adding it to or removing
* it from lists as appropriate. */
void
@@ -220,7 +200,7 @@ circuit_close_all_marked(void)
}
}
-/** Return the head of the global linked list of circuits. */
+/** Return the head of the global linked list of circuits. **/
circuit_t *
_circuit_get_global_list(void)
{
@@ -244,53 +224,36 @@ circuit_state_to_string(int state)
}
}
-/* DOCDOC */
-static void
-init_circuit_base(circuit_t *circ)
-{
- circ->timestamp_created = time(NULL);
-
- circ->package_window = CIRCWINDOW_START;
- circ->deliver_window = CIRCWINDOW_START;
-
- circuit_add(circ);
-}
-
/** Allocate space for a new circuit, initializing with <b>p_circ_id</b>
* and <b>p_conn</b>. Add it to the global circuit list.
*/
-origin_circuit_t *
-origin_circuit_new(void)
+circuit_t *
+circuit_new(uint16_t p_circ_id, connection_t *p_conn)
{
- origin_circuit_t *circ;
+ circuit_t *circ;
+ static uint32_t n_circuits_allocated = 1;
/* never zero, since a global ID of 0 is treated specially by the
* controller */
- static uint32_t n_circuits_allocated = 1;
- circ = tor_malloc_zero(sizeof(origin_circuit_t));
- circ->_base.magic = ORIGIN_CIRCUIT_MAGIC;
+ circ = tor_malloc_zero(sizeof(circuit_t));
+ circ->magic = CIRCUIT_MAGIC;
- circ->next_stream_id = crypto_rand_int(1<<16);
- circ->global_identifier = n_circuits_allocated++;
-
- init_circuit_base(TO_CIRCUIT(circ));
-
- return circ;
-}
+ circ->timestamp_created = time(NULL);
-or_circuit_t *
-or_circuit_new(uint16_t p_circ_id, or_connection_t *p_conn)
-{
/* CircIDs */
- or_circuit_t *circ;
+ if (p_conn) {
+ circuit_set_circid_orconn(circ, p_circ_id, p_conn, P_CONN_CHANGED);
+ }
+ /* circ->n_circ_id remains 0 because we haven't identified the next hop
+ * yet */
- circ = tor_malloc_zero(sizeof(or_circuit_t));
- circ->_base.magic = OR_CIRCUIT_MAGIC;
+ circ->package_window = CIRCWINDOW_START;
+ circ->deliver_window = CIRCWINDOW_START;
- if (p_conn)
- circuit_set_p_circid_orconn(circ, p_circ_id, p_conn);
+ circ->next_stream_id = crypto_rand_int(1<<16);
+ circ->global_identifier = n_circuits_allocated++;
- init_circuit_base(TO_CIRCUIT(circ));
+ circuit_add(circ);
return circ;
}
@@ -300,53 +263,35 @@ or_circuit_new(uint16_t p_circ_id, or_connection_t *p_conn)
static void
circuit_free(circuit_t *circ)
{
- void *mem;
tor_assert(circ);
- if (CIRCUIT_IS_ORIGIN(circ)) {
- origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
- mem = ocirc;
- tor_assert(circ->magic == ORIGIN_CIRCUIT_MAGIC);
- if (ocirc->build_state) {
- if (ocirc->build_state->chosen_exit)
- extend_info_free(ocirc->build_state->chosen_exit);
- if (ocirc->build_state->pending_final_cpath)
- circuit_free_cpath_node(ocirc->build_state->pending_final_cpath);
- }
- tor_free(ocirc->build_state);
-
- circuit_free_cpath(ocirc->cpath);
-
- } else {
- or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
- mem = ocirc;
- tor_assert(circ->magic == OR_CIRCUIT_MAGIC);
-
- if (ocirc->p_crypto)
- crypto_free_cipher_env(ocirc->p_crypto);
- if (ocirc->p_digest)
- crypto_free_digest_env(ocirc->p_digest);
- if (ocirc->n_crypto)
- crypto_free_cipher_env(ocirc->n_crypto);
- if (ocirc->n_digest)
- crypto_free_digest_env(ocirc->n_digest);
-
- if (ocirc->rend_splice) {
- or_circuit_t *other = ocirc->rend_splice;
- tor_assert(other->_base.magic == OR_CIRCUIT_MAGIC);
- other->rend_splice = NULL;
- }
-
- tor_free(circ->onionskin);
-
- /* remove from map. */
- circuit_set_p_circid_orconn(ocirc, 0, NULL);
+ tor_assert(circ->magic == CIRCUIT_MAGIC);
+ if (circ->n_crypto)
+ crypto_free_cipher_env(circ->n_crypto);
+ if (circ->p_crypto)
+ crypto_free_cipher_env(circ->p_crypto);
+ if (circ->n_digest)
+ crypto_free_digest_env(circ->n_digest);
+ if (circ->p_digest)
+ crypto_free_digest_env(circ->p_digest);
+ if (circ->build_state) {
+ if (circ->build_state->chosen_exit)
+ extend_info_free(circ->build_state->chosen_exit);
+ if (circ->build_state->pending_final_cpath)
+ circuit_free_cpath_node(circ->build_state->pending_final_cpath);
+ }
+ tor_free(circ->build_state);
+ tor_free(circ->onionskin);
+ circuit_free_cpath(circ->cpath);
+ if (circ->rend_splice) {
+ tor_assert(circ->rend_splice->magic == CIRCUIT_MAGIC);
+ circ->rend_splice->rend_splice = NULL;
}
-
/* Remove from map. */
- circuit_set_n_circid_orconn(circ, 0, NULL);
+ circuit_set_circid_orconn(circ, 0, NULL, P_CONN_CHANGED);
+ circuit_set_circid_orconn(circ, 0, NULL, N_CONN_CHANGED);
memset(circ, 0xAA, sizeof(circuit_t)); /* poison memory */
- tor_free(mem);
+ tor_free(circ);
}
/** Deallocate space associated with the linked list <b>cpath</b>. */
@@ -376,14 +321,11 @@ circuit_free_all(void)
circuit_t *next;
while (global_circuitlist) {
next = global_circuitlist->next;
- if (! CIRCUIT_IS_ORIGIN(global_circuitlist)) {
- or_circuit_t *or_circ = TO_OR_CIRCUIT(global_circuitlist);
- while (or_circ->resolving_streams) {
- edge_connection_t *next;
- next = or_circ->resolving_streams->next_stream;
- connection_free(TO_CONN(or_circ->resolving_streams));
- or_circ->resolving_streams = next;
- }
+ while (global_circuitlist->resolving_streams) {
+ connection_t *next;
+ next = global_circuitlist->resolving_streams->next_stream;
+ connection_free(global_circuitlist->resolving_streams);
+ global_circuitlist->resolving_streams = next;
}
circuit_free(global_circuitlist);
global_circuitlist = next;
@@ -416,92 +358,18 @@ circuit_free_cpath_node(crypt_path_t *victim)
tor_free(victim);
}
-/** A helper function for circuit_dump_by_conn() below. Log a bunch
- * 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)
-{
- log(severity, LD_CIRC, "Conn %d has %s circuit: circID %d (other side %d), "
- "state %d (%s), born %d:",
- conn_array_index, type, this_circid, other_circid, circ->state,
- circuit_state_to_string(circ->state), (int)circ->timestamp_created);
- 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>conn</b>.
- */
-void
-circuit_dump_by_conn(connection_t *conn, int severity)
-{
- circuit_t *circ;
- edge_connection_t *tmpconn;
-
- 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_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);
- }
- }
- }
- 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);
- }
- }
- }
- if (!circ->n_conn && circ->n_addr && circ->n_port &&
- circ->n_addr == conn->addr &&
- circ->n_port == conn->port &&
- conn->type == CONN_TYPE_OR &&
- !memcmp(TO_OR_CONN(conn)->identity_digest, circ->n_conn_id_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);
- }
- }
-}
-
/** Return the circuit whose global ID is <b>id</b>, or NULL if no
* such circuit exists. */
-origin_circuit_t *
+circuit_t *
circuit_get_by_global_id(uint32_t id)
{
circuit_t *circ;
for (circ=global_circuitlist;circ;circ = circ->next) {
- if (CIRCUIT_IS_ORIGIN(circ) &&
- TO_ORIGIN_CIRCUIT(circ)->global_identifier == id) {
+ if (circ->global_identifier == id) {
if (circ->marked_for_close)
return NULL;
else
- return TO_ORIGIN_CIRCUIT(circ);
+ return circ;
}
}
return NULL;
@@ -513,11 +381,13 @@ circuit_get_by_global_id(uint32_t id)
* Return NULL if no such circuit exists.
*/
static INLINE circuit_t *
-circuit_get_by_circid_orconn_impl(uint16_t circ_id, or_connection_t *conn)
+circuit_get_by_circid_orconn_impl(uint16_t circ_id, connection_t *conn)
{
orconn_circid_circuit_map_t search;
orconn_circid_circuit_map_t *found;
+ tor_assert(conn->type == CONN_TYPE_OR);
+
if (_last_circid_orconn_ent &&
circ_id == _last_circid_orconn_ent->circ_id &&
conn == _last_circid_orconn_ent->or_conn) {
@@ -537,13 +407,10 @@ circuit_get_by_circid_orconn_impl(uint16_t circ_id, or_connection_t *conn)
{
circuit_t *circ;
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) {
- log_warn(LD_BUG,
- "circuit matches p_conn, but not in hash table (Bug!)");
- return circ;
- }
+ if (circ->p_conn == conn && circ->p_circ_id == circ_id) {
+ log_warn(LD_BUG,
+ "circuit matches p_conn, but not in hash table (Bug!)");
+ return circ;
}
if (circ->n_conn == conn && circ->n_circ_id == circ_id) {
log_warn(LD_BUG,
@@ -562,7 +429,7 @@ circuit_get_by_circid_orconn_impl(uint16_t circ_id, or_connection_t *conn)
* Return NULL if no such circuit exists.
*/
circuit_t *
-circuit_get_by_circid_orconn(uint16_t circ_id, or_connection_t *conn)
+circuit_get_by_circid_orconn(uint16_t circ_id, connection_t *conn)
{
circuit_t *circ = circuit_get_by_circid_orconn_impl(circ_id, conn);
if (!circ || circ->marked_for_close)
@@ -577,7 +444,7 @@ circuit_get_by_circid_orconn(uint16_t circ_id, or_connection_t *conn)
* Return NULL if no such circuit exists.
*/
int
-circuit_id_used_on_conn(uint16_t circ_id, or_connection_t *conn)
+circuit_id_used_on_conn(uint16_t circ_id, connection_t *conn)
{
circuit_t *circ = circuit_get_by_circid_orconn_impl(circ_id, conn);
if (circ && circ->marked_for_close)
@@ -589,14 +456,13 @@ circuit_id_used_on_conn(uint16_t circ_id, or_connection_t *conn)
/** Return the circuit that a given edge connection is using. */
circuit_t *
-circuit_get_by_edge_conn(edge_connection_t *conn)
+circuit_get_by_edge_conn(connection_t *conn)
{
circuit_t *circ;
+ tor_assert(CONN_IS_EDGE(conn));
circ = conn->on_circuit;
- tor_assert(!circ ||
- (CIRCUIT_IS_ORIGIN(circ) ? circ->magic == ORIGIN_CIRCUIT_MAGIC
- : circ->magic == OR_CIRCUIT_MAGIC));
+ tor_assert(!circ || circ->magic == CIRCUIT_MAGIC);
return circ;
}
@@ -606,24 +472,18 @@ circuit_get_by_edge_conn(edge_connection_t *conn)
* been marked already.
*/
void
-circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason)
+circuit_unlink_all_from_or_conn(connection_t *conn, int reason)
{
circuit_t *circ;
for (circ = global_circuitlist; circ; circ = circ->next) {
- int mark = 0;
- if (circ->n_conn == conn) {
- circuit_set_n_circid_orconn(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);
- mark = 1;
- }
+ if (circ->n_conn == conn || circ->p_conn == conn) {
+ if (circ->n_conn == conn)
+ circuit_set_circid_orconn(circ, 0, NULL, N_CONN_CHANGED);
+ if (circ->p_conn == conn)
+ circuit_set_circid_orconn(circ, 0, NULL, P_CONN_CHANGED);
+ if (!circ->marked_for_close)
+ circuit_mark_for_close(circ, reason);
}
- if (mark && !circ->marked_for_close)
- circuit_mark_for_close(circ, reason);
}
}
@@ -633,91 +493,62 @@ circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason)
*
* Return NULL if no such circuit exists.
*/
-origin_circuit_t *
+circuit_t *
circuit_get_by_rend_query_and_purpose(const char *rend_query, uint8_t purpose)
{
circuit_t *circ;
- tor_assert(CIRCUIT_PURPOSE_IS_ORIGIN(purpose));
-
for (circ = global_circuitlist; circ; circ = circ->next) {
if (!circ->marked_for_close &&
circ->purpose == purpose &&
- !rend_cmp_service_ids(rend_query, TO_ORIGIN_CIRCUIT(circ)->rend_query))
- return TO_ORIGIN_CIRCUIT(circ);
+ !rend_cmp_service_ids(rend_query, circ->rend_query))
+ return circ;
}
return NULL;
}
/** Return the first circuit in global_circuitlist after <b>start</b>
- * whose purpose is <b>purpose</b> is purpose, and (if set) whose
- * <b>digest</b> matches the rend_pk_digest field. Return NULL if no
- * circuit is found.
+ * whose rend_pk_digest field is <b>digest</b> and whose purpose is
+ * <b>purpose</b>. Returns NULL if no circuit is found.
* If <b>start</b> is NULL, begin at the start of the list.
- * DOCDOC origin.
*/
-origin_circuit_t *
-circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
+circuit_t *
+circuit_get_next_by_pk_and_purpose(circuit_t *start,
const char *digest, uint8_t purpose)
{
circuit_t *circ;
- tor_assert(CIRCUIT_PURPOSE_IS_ORIGIN(purpose));
if (start == NULL)
circ = global_circuitlist;
else
- circ = TO_CIRCUIT(start)->next;
+ circ = start->next;
for ( ; circ; circ = circ->next) {
if (circ->marked_for_close)
continue;
if (circ->purpose != purpose)
continue;
- if (!digest)
- return TO_ORIGIN_CIRCUIT(circ);
- else if (!memcmp(TO_ORIGIN_CIRCUIT(circ)->rend_pk_digest,
- digest, DIGEST_LEN))
- return TO_ORIGIN_CIRCUIT(circ);
+ if (!memcmp(circ->rend_pk_digest, digest, DIGEST_LEN))
+ return circ;
}
return NULL;
}
-/* DOCDOC */
-static or_circuit_t *
-circuit_get_by_rend_token_and_purpose(uint8_t purpose, const char *token,
- size_t len)
+/** Return the circuit waiting for a rendezvous with the provided cookie.
+ * Return NULL if no such circuit is found.
+ */
+circuit_t *
+circuit_get_rendezvous(const char *cookie)
{
circuit_t *circ;
for (circ = global_circuitlist; circ; circ = circ->next) {
if (! circ->marked_for_close &&
- circ->purpose == purpose &&
- ! memcmp(TO_OR_CIRCUIT(circ)->rend_token, token, len))
- return TO_OR_CIRCUIT(circ);
+ circ->purpose == CIRCUIT_PURPOSE_REND_POINT_WAITING &&
+ ! memcmp(circ->rend_cookie, cookie, REND_COOKIE_LEN) )
+ return circ;
}
return NULL;
}
-/** Return the circuit waiting for a rendezvous with the provided cookie.
- * Return NULL if no such circuit is found.
- */
-or_circuit_t *
-circuit_get_rendezvous(const char *cookie)
-{
- return circuit_get_by_rend_token_and_purpose(
- CIRCUIT_PURPOSE_REND_POINT_WAITING,
- cookie, REND_COOKIE_LEN);
-}
-
-/** Return the circuit waiting for intro cells of the given digest.
- * Return NULL if no such circuit is found.
- */
-or_circuit_t *
-circuit_get_intro_point(const char *digest)
-{
- return circuit_get_by_rend_token_and_purpose(
- CIRCUIT_PURPOSE_INTRO_POINT, digest,
- DIGEST_LEN);
-}
-
/** Return a circuit that is open, has specified <b>purpose</b>,
* has a timestamp_dirty value of 0, is uptime/capacity/internal
* if required, and if info is defined, does not already use info
@@ -728,43 +559,41 @@ circuit_get_intro_point(const char *digest)
*
* Only return internal circuits if that is requested.
*/
-origin_circuit_t *
+circuit_t *
circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
int need_uptime,
int need_capacity, int internal)
{
- circuit_t *_circ;
- origin_circuit_t *best=NULL;
+ circuit_t *circ;
+ circuit_t *best=NULL;
log_debug(LD_CIRC,
"Hunting for a circ to cannibalize: purpose %d, uptime %d, "
"capacity %d, internal %d",
purpose, need_uptime, need_capacity, internal);
- for (_circ=global_circuitlist; _circ; _circ = _circ->next) {
- if (CIRCUIT_IS_ORIGIN(_circ) &&
- _circ->state == CIRCUIT_STATE_OPEN &&
- !_circ->marked_for_close &&
- _circ->purpose == purpose &&
- !_circ->timestamp_dirty) {
- origin_circuit_t *circ = TO_ORIGIN_CIRCUIT(_circ);
- if ((!need_uptime || circ->build_state->need_uptime) &&
- (!need_capacity || circ->build_state->need_capacity) &&
- (internal == circ->build_state->is_internal)) {
- if (info) {
- /* need to make sure we don't duplicate hops */
- crypt_path_t *hop = circ->cpath;
- do {
- if (!memcmp(hop->extend_info->identity_digest,
- info->identity_digest, DIGEST_LEN))
- goto next;
- hop=hop->next;
- } while (hop!=circ->cpath);
- }
- if (!best || (best->build_state->need_uptime && !need_uptime))
- best = circ;
- next: ;
+ for (circ=global_circuitlist; circ; circ = circ->next) {
+ if (CIRCUIT_IS_ORIGIN(circ) &&
+ circ->state == CIRCUIT_STATE_OPEN &&
+ !circ->marked_for_close &&
+ circ->purpose == purpose &&
+ !circ->timestamp_dirty &&
+ (!need_uptime || circ->build_state->need_uptime) &&
+ (!need_capacity || circ->build_state->need_capacity) &&
+ (internal == circ->build_state->is_internal)) {
+ if (info) {
+ /* need to make sure we don't duplicate hops */
+ crypt_path_t *hop = circ->cpath;
+ do {
+ if (!memcmp(hop->extend_info->identity_digest,
+ info->identity_digest, DIGEST_LEN))
+ goto next;
+ hop=hop->next;
+ } while (hop!=circ->cpath);
}
+ if (!best || (best->build_state->need_uptime && !need_uptime))
+ best = circ;
+ next: ;
}
}
return best;
@@ -825,6 +654,8 @@ void
_circuit_mark_for_close(circuit_t *circ, int reason, int line,
const char *file)
{
+ connection_t *conn;
+
assert_circuit_ok(circ);
tor_assert(line);
tor_assert(file);
@@ -854,7 +685,7 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
}
if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) {
- onion_pending_remove(TO_OR_CIRCUIT(circ));
+ onion_pending_remove(circ);
}
/* If the circuit ever became OPEN, we sent it to the reputation history
* module then. If it isn't OPEN, we send it there now to remember which
@@ -862,74 +693,60 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
*/
if (circ->state != CIRCUIT_STATE_OPEN) {
if (CIRCUIT_IS_ORIGIN(circ)) {
- origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
- circuit_build_failed(ocirc); /* take actions if necessary */
- circuit_rep_hist_note_result(ocirc);
+ circuit_build_failed(circ); /* take actions if necessary */
}
+ circuit_rep_hist_note_result(circ);
}
if (circ->state == CIRCUIT_STATE_OR_WAIT) {
if (circuits_pending_or_conns)
smartlist_remove(circuits_pending_or_conns, circ);
}
if (CIRCUIT_IS_ORIGIN(circ)) {
- control_event_circuit_status(TO_ORIGIN_CIRCUIT(circ),
+ control_event_circuit_status(circ,
(circ->state == CIRCUIT_STATE_OPEN)?CIRC_EVENT_CLOSED:CIRC_EVENT_FAILED);
}
if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
- origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
tor_assert(circ->state == CIRCUIT_STATE_OPEN);
- tor_assert(ocirc->build_state->chosen_exit);
+ tor_assert(circ->build_state->chosen_exit);
/* treat this like getting a nack from it */
log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). "
"Removing from descriptor.",
- safe_str(ocirc->rend_query),
- safe_str(build_state_get_exit_nickname(ocirc->build_state)));
- rend_client_remove_intro_point(ocirc->build_state->chosen_exit,
- ocirc->rend_query);
+ safe_str(circ->rend_query),
+ safe_str(build_state_get_exit_nickname(circ->build_state)));
+ rend_client_remove_intro_point(circ->build_state->chosen_exit,
+ circ->rend_query);
}
+
if (circ->n_conn)
connection_or_send_destroy(circ->n_circ_id, circ->n_conn, reason);
-
- if (! CIRCUIT_IS_ORIGIN(circ)) {
- or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
- edge_connection_t *conn;
- for (conn=or_circ->n_streams; conn; conn=conn->next_stream)
- connection_edge_destroy(or_circ->p_circ_id, conn);
-
- while (or_circ->resolving_streams) {
- conn = or_circ->resolving_streams;
- or_circ->resolving_streams = conn->next_stream;
- if (!conn->_base.marked_for_close) {
- /* The other side will see a DESTROY, and infer that the connections
- * are closing because the circuit is getting torn down. No need
- * to send an end cell. */
- conn->_base.edge_has_sent_end = 1;
- connection_mark_for_close(TO_CONN(conn));
- }
- conn->on_circuit = NULL;
+ for (conn=circ->n_streams; conn; conn=conn->next_stream)
+ connection_edge_destroy(circ->n_circ_id, conn);
+ while (circ->resolving_streams) {
+ conn = circ->resolving_streams;
+ circ->resolving_streams = conn->next_stream;
+ if (!conn->marked_for_close) {
+ /* The other side will see a DESTROY, and infer that the connections
+ * are closing because the circuit is getting torn down. No need
+ * to send an end cell. */
+ conn->has_sent_end = 1;
+ connection_mark_for_close(conn);
}
-
- if (or_circ->p_conn)
- connection_or_send_destroy(or_circ->p_circ_id, or_circ->p_conn, reason);
- } else {
- origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
- edge_connection_t *conn;
- for (conn=ocirc->p_streams; conn; conn=conn->next_stream)
- connection_edge_destroy(circ->n_circ_id, conn);
+ conn->on_circuit = NULL;
}
+ if (circ->p_conn)
+ connection_or_send_destroy(circ->p_circ_id, circ->p_conn, reason);
+ for (conn=circ->p_streams; conn; conn=conn->next_stream)
+ connection_edge_destroy(circ->p_circ_id, conn);
circ->marked_for_close = line;
circ->marked_for_close_file = file;
- if (! CIRCUIT_IS_ORIGIN(circ)) {
- or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
- if (or_circ->rend_splice) {
- if (!or_circ->rend_splice->_base.marked_for_close) {
- /* do this after marking this circuit, to avoid infinite recursion. */
- circuit_mark_for_close(TO_CIRCUIT(or_circ->rend_splice), reason);
- }
- or_circ->rend_splice = NULL;
+ if (circ->rend_splice) {
+ if (!circ->rend_splice->marked_for_close) {
+ /* do this after marking this circuit, to avoid infinite recursion. */
+ circuit_mark_for_close(circ->rend_splice, reason);
}
+ circ->rend_splice = NULL;
}
}
@@ -992,49 +809,46 @@ assert_cpath_ok(const crypt_path_t *cp)
void
assert_circuit_ok(const circuit_t *c)
{
- edge_connection_t *conn;
- const or_circuit_t *or_circ = NULL;
- const origin_circuit_t *origin_circ = NULL;
+ connection_t *conn;
tor_assert(c);
- tor_assert(c->magic == ORIGIN_CIRCUIT_MAGIC || c->magic == OR_CIRCUIT_MAGIC);
+ tor_assert(c->magic == CIRCUIT_MAGIC);
tor_assert(c->purpose >= _CIRCUIT_PURPOSE_MIN &&
c->purpose <= _CIRCUIT_PURPOSE_MAX);
- if (CIRCUIT_IS_ORIGIN(c))
- origin_circ = TO_ORIGIN_CIRCUIT((circuit_t*)c);
- else
- or_circ = TO_OR_CIRCUIT((circuit_t*)c);
-
if (c->n_conn) {
+ tor_assert(c->n_conn->type == CONN_TYPE_OR);
tor_assert(!memcmp(c->n_conn->identity_digest, c->n_conn_id_digest,
DIGEST_LEN));
if (c->n_circ_id)
tor_assert(c == circuit_get_by_circid_orconn(c->n_circ_id, c->n_conn));
}
- if (or_circ && or_circ->p_conn) {
- if (or_circ->p_circ_id)
- tor_assert(c == circuit_get_by_circid_orconn(or_circ->p_circ_id,
- or_circ->p_conn));
+ if (c->p_conn) {
+ tor_assert(c->p_conn->type == CONN_TYPE_OR);
+ if (c->p_circ_id)
+ tor_assert(c == circuit_get_by_circid_orconn(c->p_circ_id, c->p_conn));
}
-#if 0 /* false now that rendezvous exits are attached to p_streams */
- if (origin_circ)
- for (conn = origin_circ->p_streams; conn; conn = conn->next_stream)
- tor_assert(conn->_base.type == CONN_TYPE_AP);
-#endif
- if (or_circ)
- for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
- tor_assert(conn->_base.type == CONN_TYPE_EXIT);
+ for (conn = c->p_streams; conn; conn = conn->next_stream)
+ tor_assert(conn->type == CONN_TYPE_AP);
+ for (conn = c->n_streams; conn; conn = conn->next_stream)
+ tor_assert(conn->type == CONN_TYPE_EXIT);
tor_assert(c->deliver_window >= 0);
tor_assert(c->package_window >= 0);
if (c->state == CIRCUIT_STATE_OPEN) {
tor_assert(!c->onionskin);
- if (or_circ) {
- tor_assert(or_circ->n_crypto);
- tor_assert(or_circ->p_crypto);
- tor_assert(or_circ->n_digest);
- tor_assert(or_circ->p_digest);
+ if (c->cpath) {
+ tor_assert(CIRCUIT_IS_ORIGIN(c));
+ tor_assert(!c->n_crypto);
+ tor_assert(!c->p_crypto);
+ tor_assert(!c->n_digest);
+ tor_assert(!c->p_digest);
+ } else {
+ tor_assert(!CIRCUIT_IS_ORIGIN(c));
+ tor_assert(c->n_crypto);
+ tor_assert(c->p_crypto);
+ tor_assert(c->n_digest);
+ tor_assert(c->p_digest);
}
}
if (c->state == CIRCUIT_STATE_OR_WAIT && !c->marked_for_close) {
@@ -1044,18 +858,17 @@ assert_circuit_ok(const circuit_t *c)
tor_assert(!circuits_pending_or_conns ||
!smartlist_isin(circuits_pending_or_conns, c));
}
- if (origin_circ && origin_circ->cpath) {
- assert_cpath_ok(origin_circ->cpath);
+ if (c->cpath) {
+ assert_cpath_ok(c->cpath);
}
if (c->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED) {
- tor_assert(or_circ);
if (!c->marked_for_close) {
- tor_assert(or_circ->rend_splice);
- tor_assert(or_circ->rend_splice->rend_splice == or_circ);
+ tor_assert(c->rend_splice);
+ tor_assert(c->rend_splice->rend_splice == c);
}
- tor_assert(or_circ->rend_splice != or_circ);
+ tor_assert(c->rend_splice != c);
} else {
- tor_assert(!or_circ || !or_circ->rend_splice);
+ tor_assert(!c->rend_splice);
}
}