diff options
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r-- | src/or/circuitlist.c | 491 |
1 files changed, 324 insertions, 167 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 73513c4030..69e611dd98 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -68,35 +68,14 @@ HT_GENERATE(orconn_circid_map, orconn_circid_circuit_map_t, node, */ orconn_circid_circuit_map_t *_last_circid_orconn_ent = NULL; -/** 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) +static void +circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id, + connection_t *conn, + uint16_t old_id, connection_t *old_conn) { - 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) || @@ -135,6 +114,47 @@ circuit_set_circid_orconn(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, + connection_t *conn) +{ + uint16_t old_id; + 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, + connection_t *conn) +{ + uint16_t old_id; + 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 @@ -224,36 +244,53 @@ circuit_state_to_string(int state) } } -/** 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. - */ -circuit_t * -circuit_new(uint16_t p_circ_id, connection_t *p_conn) +/* DOCDOC */ +static void +init_circuit_base(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 */ - - circ = tor_malloc_zero(sizeof(circuit_t)); - circ->magic = CIRCUIT_MAGIC; - circ->timestamp_created = time(NULL); - /* CircIDs */ - 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->package_window = CIRCWINDOW_START; circ->deliver_window = CIRCWINDOW_START; - - circ->next_stream_id = crypto_rand_int(1<<16); circ->global_identifier = n_circuits_allocated++; 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) +{ + origin_circuit_t *circ; + + circ = tor_malloc_zero(sizeof(origin_circuit_t)); + circ->_base.magic = ORIGIN_CIRCUIT_MAGIC; + + circ->next_stream_id = crypto_rand_int(1<<16); + + init_circuit_base(TO_CIRCUIT(circ)); + + return circ; +} + +or_circuit_t * +or_circuit_new(uint16_t p_circ_id, connection_t *p_conn) +{ + /* CircIDs */ + or_circuit_t *circ; + + 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); + + init_circuit_base(TO_CIRCUIT(circ)); return circ; } @@ -263,35 +300,53 @@ circuit_new(uint16_t p_circ_id, connection_t *p_conn) static void circuit_free(circuit_t *circ) { + void *mem; tor_assert(circ); - 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; + 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); } + /* Remove from map. */ - circuit_set_circid_orconn(circ, 0, NULL, P_CONN_CHANGED); - circuit_set_circid_orconn(circ, 0, NULL, N_CONN_CHANGED); + circuit_set_n_circid_orconn(circ, 0, NULL); memset(circ, 0xAA, sizeof(circuit_t)); /* poison memory */ - tor_free(circ); + tor_free(mem); } /** Deallocate space associated with the linked list <b>cpath</b>. */ @@ -321,11 +376,14 @@ circuit_free_all(void) circuit_t *next; while (global_circuitlist) { next = global_circuitlist->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; + if (! CIRCUIT_IS_ORIGIN(global_circuitlist)) { + or_circuit_t *or_circ = TO_OR_CIRCUIT(global_circuitlist); + while (or_circ->resolving_streams) { + connection_t *next; + next = or_circ->resolving_streams->next_stream; + connection_free(or_circ->resolving_streams); + or_circ->resolving_streams = next; + } } circuit_free(global_circuitlist); global_circuitlist = next; @@ -358,6 +416,76 @@ 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 poll_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:", + poll_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; + 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 == conn) + circuit_dump_details(severity, circ, conn->poll_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 (tmpconn == conn) { + circuit_dump_details(severity, circ, conn->poll_index, "App-ward", + p_circ_id, n_circ_id); + } + } + } + if (circ->n_conn == conn) + circuit_dump_details(severity, circ, conn->poll_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 (tmpconn == conn) { + circuit_dump_details(severity, circ, conn->poll_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 && + !memcmp(conn->identity_digest, circ->n_conn_id_digest, DIGEST_LEN)) { + circuit_dump_details(severity, circ, conn->poll_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. */ circuit_t * @@ -407,10 +535,13 @@ circuit_get_by_circid_orconn_impl(uint16_t circ_id, connection_t *conn) { circuit_t *circ; for (circ=global_circuitlist;circ;circ = circ->next) { - 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 (! 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->n_conn == conn && circ->n_circ_id == circ_id) { log_warn(LD_BUG, @@ -462,7 +593,9 @@ circuit_get_by_edge_conn(connection_t *conn) tor_assert(CONN_IS_EDGE(conn)); circ = conn->on_circuit; - tor_assert(!circ || circ->magic == CIRCUIT_MAGIC); + tor_assert(!circ || + (CIRCUIT_IS_ORIGIN(circ) ? circ->magic == ORIGIN_CIRCUIT_MAGIC + : circ->magic == OR_CIRCUIT_MAGIC)); return circ; } @@ -476,14 +609,20 @@ circuit_unlink_all_from_or_conn(connection_t *conn, int reason) { circuit_t *circ; for (circ = global_circuitlist; circ; circ = circ->next) { - 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); + 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 (mark && !circ->marked_for_close) + circuit_mark_for_close(circ, reason); } } @@ -536,7 +675,7 @@ circuit_get_next_by_pk_and_purpose(circuit_t *start, /** Return the circuit waiting for a rendezvous with the provided cookie. * Return NULL if no such circuit is found. */ -circuit_t * +or_circuit_t * circuit_get_rendezvous(const char *cookie) { circuit_t *circ; @@ -544,7 +683,7 @@ circuit_get_rendezvous(const char *cookie) if (! circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_REND_POINT_WAITING && ! memcmp(circ->rend_cookie, cookie, REND_COOKIE_LEN) ) - return circ; + return TO_OR_CIRCUIT(circ); } return NULL; } @@ -559,41 +698,43 @@ circuit_get_rendezvous(const char *cookie) * * Only return internal circuits if that is requested. */ -circuit_t * +origin_circuit_t * circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, int need_uptime, int need_capacity, int internal) { - circuit_t *circ; - circuit_t *best=NULL; + circuit_t *_circ; + origin_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 && - (!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; + 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: ; + } } } return best; @@ -685,7 +826,7 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line, } if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) { - onion_pending_remove(circ); + onion_pending_remove(TO_OR_CIRCUIT(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 @@ -693,60 +834,72 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line, */ if (circ->state != CIRCUIT_STATE_OPEN) { if (CIRCUIT_IS_ORIGIN(circ)) { - circuit_build_failed(circ); /* take actions if necessary */ + origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); + circuit_build_failed(ocirc); /* take actions if necessary */ + circuit_rep_hist_note_result(ocirc); } - 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(circ, + control_event_circuit_status(TO_ORIGIN_CIRCUIT(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(circ->build_state->chosen_exit); + tor_assert(ocirc->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(circ->rend_query), - safe_str(build_state_get_exit_nickname(circ->build_state))); - rend_client_remove_intro_point(circ->build_state->chosen_exit, + safe_str(build_state_get_exit_nickname(ocirc->build_state))); + rend_client_remove_intro_point(ocirc->build_state->chosen_exit, circ->rend_query); } - if (circ->n_conn) connection_or_send_destroy(circ->n_circ_id, circ->n_conn, reason); - 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 (! CIRCUIT_IS_ORIGIN(circ)) { + or_circuit_t *or_circ = TO_OR_CIRCUIT(circ); + 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->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); + } + conn->on_circuit = NULL; } - conn->on_circuit = NULL; + + 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); + for (conn=ocirc->p_streams; conn; conn=conn->next_stream) + connection_edge_destroy(circ->n_circ_id, conn); } - 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 (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); + 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; } - circ->rend_splice = NULL; } } @@ -810,12 +963,19 @@ void assert_circuit_ok(const circuit_t *c) { connection_t *conn; + const or_circuit_t *or_circ = NULL; + const origin_circuit_t *origin_circ = NULL; tor_assert(c); - tor_assert(c->magic == CIRCUIT_MAGIC); + tor_assert(c->magic == ORIGIN_CIRCUIT_MAGIC || c->magic == OR_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, @@ -823,32 +983,28 @@ assert_circuit_ok(const circuit_t *c) if (c->n_circ_id) tor_assert(c == circuit_get_by_circid_orconn(c->n_circ_id, c->n_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 (or_circ && or_circ->p_conn) { + tor_assert(or_circ->p_conn->type == CONN_TYPE_OR); + if (or_circ->p_circ_id) + tor_assert(c == circuit_get_by_circid_orconn(or_circ->p_circ_id, + or_circ->p_conn)); } - 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); + if (origin_circ) + for (conn = origin_circ->p_streams; conn; conn = conn->next_stream) + tor_assert(conn->type == CONN_TYPE_AP); + if (or_circ) + for (conn = or_circ->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 (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 (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->state == CIRCUIT_STATE_OR_WAIT && !c->marked_for_close) { @@ -858,17 +1014,18 @@ assert_circuit_ok(const circuit_t *c) tor_assert(!circuits_pending_or_conns || !smartlist_isin(circuits_pending_or_conns, c)); } - if (c->cpath) { - assert_cpath_ok(c->cpath); + if (origin_circ->cpath) { + assert_cpath_ok(origin_circ->cpath); } if (c->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED) { + tor_assert(or_circ); if (!c->marked_for_close) { - tor_assert(c->rend_splice); - tor_assert(c->rend_splice->rend_splice == c); + tor_assert(or_circ->rend_splice); + tor_assert(or_circ->rend_splice->rend_splice == or_circ); } - tor_assert(c->rend_splice != c); + tor_assert(or_circ->rend_splice != or_circ); } else { - tor_assert(!c->rend_splice); + tor_assert(!or_circ || !or_circ->rend_splice); } } |