diff options
Diffstat (limited to 'src/or/circuituse.c')
-rw-r--r-- | src/or/circuituse.c | 417 |
1 files changed, 173 insertions, 244 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 310e8278fb..2aec912c17 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -26,13 +26,12 @@ static void circuit_increment_failure_count(void); * Else return 0. */ static int -circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn, +circuit_is_acceptable(circuit_t *circ, connection_t *conn, int must_be_open, uint8_t purpose, int need_uptime, int need_internal, time_t now) { routerinfo_t *exitrouter; - cpath_build_state_t *build_state; tor_assert(circ); tor_assert(conn); tor_assert(conn->socks_request); @@ -72,12 +71,11 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn, * circuit, it's the magical extra bob hop. so just check the nickname * of the one we meant to finish at. */ - build_state = TO_ORIGIN_CIRCUIT(circ)->build_state; - exitrouter = build_state_get_exit_router(build_state); + exitrouter = build_state_get_exit_router(circ->build_state); - if (need_uptime && !build_state->need_uptime) + if (need_uptime && !circ->build_state->need_uptime) return 0; - if (need_internal != build_state->is_internal) + if (need_internal != circ->build_state->is_internal) return 0; if (purpose == CIRCUIT_PURPOSE_C_GENERAL) { @@ -91,8 +89,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn, return 0; } } else { /* not general */ - if (rend_cmp_service_ids(conn->rend_query, - TO_ORIGIN_CIRCUIT(circ)->rend_query)) { + if (rend_cmp_service_ids(conn->rend_query, circ->rend_query)) { /* this circ is not for this conn */ return 0; } @@ -117,11 +114,9 @@ circuit_is_better(circuit_t *a, circuit_t *b, uint8_t purpose) return 1; } else { if (a->timestamp_dirty || + b->build_state->is_internal || a->timestamp_created > b->timestamp_created) return 1; - if (CIRCUIT_IS_ORIGIN(b) && - TO_ORIGIN_CIRCUIT(b)->build_state->is_internal) - return 1; } break; case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT: @@ -154,8 +149,8 @@ circuit_is_better(circuit_t *a, circuit_t *b, uint8_t purpose) * If it's INTRODUCE_ACK_WAIT and must_be_open==0, then return the * closest introduce-purposed circuit that you can find. */ -static origin_circuit_t * -circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose, +static circuit_t * +circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose, int need_uptime, int need_internal) { circuit_t *circ, *best=NULL; @@ -168,8 +163,6 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose, purpose == CIRCUIT_PURPOSE_C_REND_JOINED); for (circ=global_circuitlist;circ;circ = circ->next) { - if (!CIRCUIT_IS_ORIGIN(circ)) - continue; if (!circuit_is_acceptable(circ,conn,must_be_open,purpose, need_uptime,need_internal,now)) continue; @@ -181,7 +174,7 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose, best = circ; } - return best ? TO_ORIGIN_CIRCUIT(best) : NULL; + return best; } /** Close all circuits that start at us, aren't open, and were born @@ -237,8 +230,7 @@ circuit_expire_building(time_t now) /* c_rend_ready circs measure age since timestamp_dirty, * because that's set when they switch purposes */ - if (TO_ORIGIN_CIRCUIT(victim)->rend_query[0] || - victim->timestamp_dirty > cutoff) + if (!victim->rend_query[0] || victim->timestamp_dirty > cutoff) continue; break; case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED: @@ -255,8 +247,7 @@ circuit_expire_building(time_t now) if (victim->n_conn) log_info(LD_CIRC,"Abandoning circ %s:%d:%d (state %d:%s, purpose %d)", - victim->n_conn->_base.address, victim->n_port, - victim->n_circ_id, + victim->n_conn->address, victim->n_port, victim->n_circ_id, victim->state, circuit_state_to_string(victim->state), victim->purpose); else @@ -264,7 +255,7 @@ circuit_expire_building(time_t now) victim->n_circ_id, victim->state, circuit_state_to_string(victim->state), victim->purpose); - circuit_log_path(LOG_INFO,LD_CIRC,TO_ORIGIN_CIRCUIT(victim)); + circuit_log_path(LOG_INFO,LD_CIRC,victim); circuit_mark_for_close(victim, END_CIRC_AT_ORIGIN); } } @@ -297,8 +288,7 @@ circuit_remove_handled_ports(smartlist_t *needed_ports) * Else return 0. */ int -circuit_stream_is_being_handled(edge_connection_t *conn, - uint16_t port, int min) +circuit_stream_is_being_handled(connection_t *conn, uint16_t port, int min) { circuit_t *circ; routerinfo_t *exitrouter; @@ -311,14 +301,12 @@ circuit_stream_is_being_handled(edge_connection_t *conn, if (CIRCUIT_IS_ORIGIN(circ) && !circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_C_GENERAL && + !circ->build_state->is_internal && (!circ->timestamp_dirty || circ->timestamp_dirty + get_options()->MaxCircuitDirtiness > now)) { - cpath_build_state_t *build_state = TO_ORIGIN_CIRCUIT(circ)->build_state; - if (build_state->is_internal) - continue; - - exitrouter = build_state_get_exit_router(build_state); - if (exitrouter && (!need_uptime || build_state->need_uptime)) { + exitrouter = build_state_get_exit_router(circ->build_state); + if (exitrouter && + (!need_uptime || circ->build_state->need_uptime)) { int ok; if (conn) { ok = connection_ap_can_use_exit(conn, exitrouter); @@ -355,7 +343,6 @@ circuit_predict_and_launch_new(void) /* First, count how many of each type of circuit we have already. */ for (circ=global_circuitlist;circ;circ = circ->next) { - cpath_build_state_t *build_state; if (!CIRCUIT_IS_ORIGIN(circ)) continue; if (circ->marked_for_close) @@ -365,10 +352,9 @@ circuit_predict_and_launch_new(void) if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL) continue; /* only pay attention to general-purpose circs */ num++; - build_state = TO_ORIGIN_CIRCUIT(circ)->build_state; - if (build_state->is_internal) + if (circ->build_state->is_internal) num_internal++; - if (build_state->need_uptime && build_state->is_internal) + if (circ->build_state->need_uptime && circ->build_state->is_internal) num_uptime_internal++; } @@ -459,9 +445,9 @@ circuit_build_needed_circs(time_t now) * lists of <b>circ</b>, then remove it from the list. */ void -circuit_detach_stream(circuit_t *circ, edge_connection_t *conn) +circuit_detach_stream(circuit_t *circ, connection_t *conn) { - edge_connection_t *prevconn; + connection_t *prevconn; tor_assert(circ); tor_assert(conn); @@ -469,49 +455,44 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn) conn->cpath_layer = NULL; /* make sure we don't keep a stale pointer */ conn->on_circuit = NULL; - if (CIRCUIT_IS_ORIGIN(circ)) { - origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ); - if (conn == origin_circ->p_streams) { - origin_circ->p_streams = conn->next_stream; - return; - } + if (conn == circ->p_streams) { + circ->p_streams = conn->next_stream; + return; + } + if (conn == circ->n_streams) { + circ->n_streams = conn->next_stream; + return; + } + if (conn == circ->resolving_streams) { + circ->resolving_streams = conn->next_stream; + return; + } - for (prevconn = origin_circ->p_streams; - prevconn && prevconn->next_stream && prevconn->next_stream != conn; - prevconn = prevconn->next_stream) - ; - if (prevconn && prevconn->next_stream) { - prevconn->next_stream = conn->next_stream; - return; - } - } else { - or_circuit_t *or_circ = TO_OR_CIRCUIT(circ); - if (conn == or_circ->n_streams) { - or_circ->n_streams = conn->next_stream; - return; - } - if (conn == or_circ->resolving_streams) { - or_circ->resolving_streams = conn->next_stream; - return; - } + for (prevconn = circ->p_streams; + prevconn && prevconn->next_stream && prevconn->next_stream != conn; + prevconn = prevconn->next_stream) + ; + if (prevconn && prevconn->next_stream) { + prevconn->next_stream = conn->next_stream; + return; + } - for (prevconn = or_circ->n_streams; - prevconn && prevconn->next_stream && prevconn->next_stream != conn; - prevconn = prevconn->next_stream) - ; - if (prevconn && prevconn->next_stream) { - prevconn->next_stream = conn->next_stream; - return; - } + for (prevconn = circ->n_streams; + prevconn && prevconn->next_stream && prevconn->next_stream != conn; + prevconn = prevconn->next_stream) + ; + if (prevconn && prevconn->next_stream) { + prevconn->next_stream = conn->next_stream; + return; + } - for (prevconn = or_circ->resolving_streams; - prevconn && prevconn->next_stream && prevconn->next_stream != conn; - prevconn = prevconn->next_stream) - ; - if (prevconn && prevconn->next_stream) { - prevconn->next_stream = conn->next_stream; - return; - } + for (prevconn = circ->resolving_streams; + prevconn && prevconn->next_stream && prevconn->next_stream != conn; + prevconn = prevconn->next_stream) + ; + if (prevconn && prevconn->next_stream) { + prevconn->next_stream = conn->next_stream; + return; } log_err(LD_BUG,"edge conn not in circuit's list?"); @@ -538,11 +519,10 @@ circuit_about_to_close_connection(connection_t *conn) if (!connection_state_is_open(conn)) { /* Inform any pending (not attached) circs that they should * give up. */ - circuit_n_conn_done(TO_OR_CONN(conn), 0); + circuit_n_conn_done(conn, 0); } /* Now close all the attached circuits on it. */ - circuit_unlink_all_from_or_conn(TO_OR_CONN(conn), - END_CIRC_REASON_OR_CONN_CLOSED); + circuit_unlink_all_from_or_conn(conn, END_CIRC_REASON_OR_CONN_CLOSED); return; } case CONN_TYPE_AP: @@ -553,17 +533,17 @@ circuit_about_to_close_connection(connection_t *conn) * been sent. But don't kill the circuit. */ - circ = circuit_get_by_edge_conn(TO_EDGE_CONN(conn)); + circ = circuit_get_by_edge_conn(conn); if (!circ) return; - circuit_detach_stream(circ, TO_EDGE_CONN(conn)); + circuit_detach_stream(circ, conn); } } /* end switch */ } -/** Find each circuit that has been unused for too long, or dirty - * for too long and has no streax=ms on it: mark it for close. +/** Find each circuit that has been dirty for too long, and has + * no streams on it: mark it for close. */ static void circuit_expire_old_circuits(time_t now) @@ -572,19 +552,23 @@ circuit_expire_old_circuits(time_t now) time_t cutoff = now - get_options()->CircuitIdleTimeout; for (circ = global_circuitlist; circ; circ = circ->next) { - if (circ->marked_for_close || ! CIRCUIT_IS_ORIGIN(circ)) + if (circ->marked_for_close) continue; /* If the circuit has been dirty for too long, and there are no streams * on it, mark it for close. */ if (circ->timestamp_dirty && circ->timestamp_dirty + get_options()->MaxCircuitDirtiness < now && - !TO_ORIGIN_CIRCUIT(circ)->p_streams /* nothing attached */ ) { + CIRCUIT_IS_ORIGIN(circ) && + !circ->p_streams /* nothing attached */ ) { log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %d secs ago, purp %d)", circ->n_circ_id, (int)(now - circ->timestamp_dirty), circ->purpose); + /* (only general and purpose_c circs can get dirty) */ + tor_assert(!circ->n_streams); + tor_assert(circ->purpose <= CIRCUIT_PURPOSE_C_REND_JOINED); circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN); - } else if (!circ->timestamp_dirty && + } else if (!circ->timestamp_dirty && CIRCUIT_IS_ORIGIN(circ) && circ->state == CIRCUIT_STATE_OPEN && circ->purpose == CIRCUIT_PURPOSE_C_GENERAL) { if (circ->timestamp_created < cutoff) { @@ -597,72 +581,30 @@ circuit_expire_old_circuits(time_t now) } } -#define NUM_PARALLEL_TESTING_CIRCS 4 - -static int have_performed_bandwidth_test = 0; - -/** Reset have_performed_bandwidth_test, so we'll start building - * testing circuits again so we can exercise our bandwidth. */ -void -reset_bandwidth_test(void) -{ - have_performed_bandwidth_test = 0; -} - -/** Return 1 if we've already exercised our bandwidth, or if we - * have fewer than NUM_PARALLEL_TESTING_CIRCS testing circuits - * established or on the way. Else return 0. - */ -int -circuit_enough_testing_circs(void) -{ - circuit_t *circ; - int num = 0; - - if (have_performed_bandwidth_test) - return 1; - - for (circ = global_circuitlist; circ; circ = circ->next) { - if (!circ->marked_for_close && CIRCUIT_IS_ORIGIN(circ) && - circ->purpose == CIRCUIT_PURPOSE_TESTING && - circ->state == CIRCUIT_STATE_OPEN) - num++; - } - return num >= NUM_PARALLEL_TESTING_CIRCS; -} - -/** A testing circuit has completed. Take whatever stats we want. - * Noticing reachability is taken care of in onionskin_answer(), - * so there's no need to record anything here. But if we still want - * to do the bandwidth test, and we now have enough testing circuits - * open, do it. - */ +/** A testing circuit has completed. Take whatever stats we want. */ static void -circuit_testing_opened(origin_circuit_t *circ) +circuit_testing_opened(circuit_t *circ) { - if (have_performed_bandwidth_test) { - circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN); - } else if (circuit_enough_testing_circs()) { - router_perform_bandwidth_test(NUM_PARALLEL_TESTING_CIRCS, time(NULL)); - have_performed_bandwidth_test = 1; - } else - consider_testing_reachability(1, 0); + /* For now, we only use testing circuits to see if our ORPort is + reachable. But we remember reachability in onionskin_answer(), + so there's no need to record anything here. Just close the circ. */ + circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN); } /** A testing circuit has failed to build. Take whatever stats we want. */ static void -circuit_testing_failed(origin_circuit_t *circ, int at_last_hop) +circuit_testing_failed(circuit_t *circ, int at_last_hop) { - if (server_mode(get_options()) && check_whether_orport_reachable()) - return; +#if 0 + routerinfo_t *me = router_get_my_routerinfo(); + if (!at_last_hop) + circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me, 0, 1, 1); + else +#endif log_info(LD_GENERAL, "Our testing circuit (to see if your ORPort is reachable) " "has failed. I'll try again later."); - - /* These aren't used yet. */ - (void)circ; - (void)at_last_hop; } /** The circuit <b>circ</b> has just become open. Take the next @@ -672,11 +614,11 @@ circuit_testing_failed(origin_circuit_t *circ, int at_last_hop) * that could use circ. */ void -circuit_has_opened(origin_circuit_t *circ) +circuit_has_opened(circuit_t *circ) { control_event_circuit_status(circ, CIRC_EVENT_BUILT); - switch (TO_CIRCUIT(circ)->purpose) { + switch (circ->purpose) { case CIRCUIT_PURPOSE_C_ESTABLISH_REND: rend_client_rendcirc_has_opened(circ); connection_ap_attach_pending(); @@ -701,7 +643,7 @@ circuit_has_opened(origin_circuit_t *circ) circuit_testing_opened(circ); break; default: - log_err(LD_BUG,"unhandled purpose %d",circ->_base.purpose); + log_err(LD_BUG,"unhandled purpose %d",circ->purpose); tor_assert(0); } } @@ -709,7 +651,7 @@ circuit_has_opened(origin_circuit_t *circ) /** Called whenever a circuit could not be successfully built. */ void -circuit_build_failed(origin_circuit_t *circ) +circuit_build_failed(circuit_t *circ) { /* we should examine circ and see if it failed because of * the last hop or an earlier hop. then use this info below. @@ -726,35 +668,38 @@ circuit_build_failed(origin_circuit_t *circ) circ->cpath->state != CPATH_STATE_OPEN) { /* We failed at the first hop. If there's an OR connection to blame, blame it. */ - or_connection_t *n_conn = NULL; - if (circ->_base.n_conn) { - n_conn = circ->_base.n_conn; - } else if (circ->_base.state == CIRCUIT_STATE_OR_WAIT) { + connection_t *n_conn = NULL; + if (circ->n_conn) { + n_conn = circ->n_conn; + } else if (circ->state == CIRCUIT_STATE_OR_WAIT) { /* we have to hunt for it */ - n_conn = connection_or_get_by_identity_digest( - circ->_base.n_conn_id_digest); + n_conn = connection_or_get_by_identity_digest(circ->n_conn_id_digest); } if (n_conn) { log_info(LD_OR, "Our circuit failed to get a response from the first hop " "(%s:%d). I'm going to try to rotate to a better connection.", - n_conn->_base.address, n_conn->_base.port); - n_conn->_base.or_is_obsolete = 1; + n_conn->address, n_conn->port); + n_conn->is_obsolete = 1; entry_guard_set_status(n_conn->identity_digest, 0); } } - switch (circ->_base.purpose) { + switch (circ->purpose) { case CIRCUIT_PURPOSE_C_GENERAL: - /* If we never built the circuit, note it as a failure. */ - circuit_increment_failure_count(); + if (circ->state != CIRCUIT_STATE_OPEN) { + /* If we never built the circuit, note it as a failure. */ + /* Note that we can't just check circ->cpath here, because if + * circuit-building failed immediately, it won't be set yet. */ + circuit_increment_failure_count(); + } break; case CIRCUIT_PURPOSE_TESTING: circuit_testing_failed(circ, failed_at_last_hop); break; case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: /* at Bob, waiting for introductions */ - if (circ->_base.state != CIRCUIT_STATE_OPEN) { + if (circ->state != CIRCUIT_STATE_OPEN) { circuit_increment_failure_count(); } /* no need to care here, because bob will rebuild intro @@ -769,7 +714,9 @@ circuit_build_failed(origin_circuit_t *circ) break; case CIRCUIT_PURPOSE_C_ESTABLISH_REND: /* at Alice, waiting for Bob */ - circuit_increment_failure_count(); + if (circ->state != CIRCUIT_STATE_OPEN) { + circuit_increment_failure_count(); + } /* Alice will pick a new rend point when this one dies, if * the stream in question still cares. No need to act here. */ break; @@ -803,11 +750,11 @@ static int did_circs_fail_last_period = 0; /** Launch a new circuit; see circuit_launch_by_extend_info() for * details on arguments. */ -origin_circuit_t * +circuit_t * circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit, int need_uptime, int need_capacity, int internal) { - origin_circuit_t *circ; + circuit_t *circ; extend_info_t *info = NULL; if (exit) info = extend_info_from_router(exit); @@ -824,11 +771,11 @@ circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit, * choose among routers with high bandwidth. If <b>internal</b> is true, the * last hop need not be an exit node. Return the newly allocated circuit on * success, or NULL on failure. */ -origin_circuit_t * +circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int need_uptime, int need_capacity, int internal) { - origin_circuit_t *circ; + circuit_t *circ; if (!router_have_minimum_dir_info()) { log_debug(LD_CIRC,"Haven't fetched enough directory info yet; canceling " @@ -844,11 +791,11 @@ circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, if (circ) { log_info(LD_CIRC,"Cannibalizing circ '%s' for purpose %d", build_state_get_exit_nickname(circ->build_state), purpose); - circ->_base.purpose = purpose; + circ->purpose = purpose; /* reset the birth date of this circ, else expire_building * will see it and think it's been trying to build since it * began. */ - circ->_base.timestamp_created = time(NULL); + circ->timestamp_created = time(NULL); switch (purpose) { case CIRCUIT_PURPOSE_C_ESTABLISH_REND: case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: @@ -888,7 +835,7 @@ circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, /** Launch a new circuit; see circuit_launch_by_extend_info() for * details on arguments. */ -origin_circuit_t * +circuit_t * circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname, int need_uptime, int need_capacity, int internal) { @@ -929,26 +876,25 @@ circuit_reset_failure_count(int timeout) n_circuit_failures = 0; } -/** Find an open circ that we're happy to use for <b>conn</b> and return 1. If - * there isn't one, and there isn't one on the way, launch one and return - * 0. If it will never work, return -1. +/** Find an open circ that we're happy with: return 1. If there isn't + * one, and there isn't one on the way, launch one and return 0. If it + * will never work, return -1. * * Write the found or in-progress or launched circ into *circp. */ static int -circuit_get_open_circ_or_launch(edge_connection_t *conn, +circuit_get_open_circ_or_launch(connection_t *conn, uint8_t desired_circuit_purpose, - origin_circuit_t **circp) + circuit_t **circp) { - origin_circuit_t *circ; + circuit_t *circ; int is_resolve; int need_uptime, need_internal; tor_assert(conn); tor_assert(circp); - tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT); - is_resolve = (conn->socks_request->command == SOCKS_COMMAND_RESOLVE || - conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR); + tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT); + is_resolve = conn->socks_request->command == SOCKS_COMMAND_RESOLVE; need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts, conn->socks_request->port); @@ -1010,7 +956,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, "No intro points for '%s': refetching service descriptor.", safe_str(conn->rend_query)); rend_client_refetch_renddesc(conn->rend_query); - conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT; + conn->state = AP_CONN_STATE_RENDDESC_WAIT; return 0; } log_info(LD_REND,"Chose '%s' as intro point for '%s'.", @@ -1023,16 +969,11 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) { if (conn->chosen_exit_name) { routerinfo_t *r; - int opt = conn->_base.chosen_exit_optional; if (!(r = router_get_by_nickname(conn->chosen_exit_name, 1))) { - log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP, - "Requested exit point '%s' is not known. %s.", - conn->chosen_exit_name, opt ? "Trying others" : "Closing"); - if (opt) { - conn->_base.chosen_exit_optional = 0; - tor_free(conn->chosen_exit_name); - return 0; - } + /*XXXX NM domain? */ + log_notice(LD_CIRC, + "Requested exit point '%s' is not known. Closing.", + conn->chosen_exit_name); return -1; } extend_info = extend_info_from_router(r); @@ -1057,8 +998,8 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, if (circ) { /* write the service_id into circ */ strlcpy(circ->rend_query, conn->rend_query, sizeof(circ->rend_query)); - if (circ->_base.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND && - circ->_base.state == CIRCUIT_STATE_OPEN) + if (circ->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND && + circ->state == CIRCUIT_STATE_OPEN) rend_client_rendcirc_has_opened(circ); } } @@ -1077,18 +1018,19 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, * circ's cpath. */ static void -link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ) +link_apconn_to_circ(connection_t *apconn, circuit_t *circ) { /* add it into the linked list of streams on this circuit */ log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %d.", - circ->_base.n_circ_id); + circ->n_circ_id); /* reset it, so we can measure circ timeouts */ - apconn->_base.timestamp_lastread = time(NULL); + apconn->timestamp_lastread = time(NULL); apconn->next_stream = circ->p_streams; - apconn->on_circuit = TO_CIRCUIT(circ); + apconn->on_circuit = circ; /* assert_connection_ok(conn, time(NULL)); */ circ->p_streams = apconn; + tor_assert(CIRCUIT_IS_ORIGIN(circ)); tor_assert(circ->cpath); tor_assert(circ->cpath->prev); tor_assert(circ->cpath->prev->state == CPATH_STATE_OPEN); @@ -1098,7 +1040,7 @@ link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ) /** If an exit wasn't specifically chosen, save the history for future * use. */ static void -consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ) +consider_recording_trackhost(connection_t *conn, circuit_t *circ) { int found_needle = 0; char *str; @@ -1110,7 +1052,7 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ) /* Search the addressmap for this conn's destination. */ /* If he's not in the address map.. */ if (!options->TrackHostExits || - addressmap_have_mapping(conn->socks_request->address)) + addressmap_already_mapped(conn->socks_request->address)) return; /* nothing to track, or already mapped */ SMARTLIST_FOREACH(options->TrackHostExits, const char *, cp, { @@ -1152,20 +1094,21 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ) * send a begin or resolve cell as appropriate. Return values are as * for connection_ap_handshake_attach_circuit. */ int -connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn, - origin_circuit_t *circ) +connection_ap_handshake_attach_chosen_circuit(connection_t *conn, + circuit_t *circ) { tor_assert(conn); - tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT || - conn->_base.state == AP_CONN_STATE_CONTROLLER_WAIT); + tor_assert(conn->type == CONN_TYPE_AP); + tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT || + conn->state == AP_CONN_STATE_CONTROLLER_WAIT); tor_assert(conn->socks_request); tor_assert(circ); - tor_assert(circ->_base.state == CIRCUIT_STATE_OPEN); + tor_assert(circ->state == CIRCUIT_STATE_OPEN); - conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT; + conn->state = AP_CONN_STATE_CIRCUIT_WAIT; - if (!circ->_base.timestamp_dirty) - circ->_base.timestamp_dirty = time(NULL); + if (!circ->timestamp_dirty) + circ->timestamp_dirty = time(NULL); link_apconn_to_circ(conn, circ); tor_assert(conn->socks_request); @@ -1189,18 +1132,19 @@ connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn, * right next step, and return 1. */ int -connection_ap_handshake_attach_circuit(edge_connection_t *conn) +connection_ap_handshake_attach_circuit(connection_t *conn) { int retval; int conn_age; int severity; tor_assert(conn); - tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT); + tor_assert(conn->type == CONN_TYPE_AP); + tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT); tor_assert(conn->socks_request); - conn_age = time(NULL) - conn->_base.timestamp_created; - severity = (!conn->_base.addr && !conn->_base.port) ? LOG_INFO : LOG_NOTICE; + conn_age = time(NULL) - conn->timestamp_created; + severity = (!conn->addr && !conn->port) ? LOG_INFO : LOG_NOTICE; if (conn_age > get_options()->SocksTimeout) { log_fn(severity, LD_APP, "Tried for %d seconds to get a connection to %s:%d. Giving up.", @@ -1210,32 +1154,20 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) } if (!connection_edge_is_rendezvous_stream(conn)) { /* we're a general conn */ - origin_circuit_t *circ=NULL; + circuit_t *circ=NULL; if (conn->chosen_exit_name) { routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1); - int opt = conn->_base.chosen_exit_optional; if (!router) { - log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP, - "Requested exit point '%s' is not known. %s.", - conn->chosen_exit_name, opt ? "Trying others" : "Closing"); - if (opt) { - conn->_base.chosen_exit_optional = 0; - tor_free(conn->chosen_exit_name); - return 0; - } + log_warn(LD_APP, + "Requested exit point '%s' is not known. Closing.", + conn->chosen_exit_name); return -1; } - if (conn->_base.purpose != EXIT_PURPOSE_RESOLVE && - !connection_ap_can_use_exit(conn, router)) { - log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP, - "Requested exit point '%s' would refuse request. %s.", - conn->chosen_exit_name, opt ? "Trying others" : "Closing"); - if (opt) { - conn->_base.chosen_exit_optional = 0; - tor_free(conn->chosen_exit_name); - return 0; - } + if (!connection_ap_can_use_exit(conn, router)) { + log_warn(LD_APP, + "Requested exit point '%s' would refuse request. Closing.", + conn->chosen_exit_name); return -1; } } @@ -1248,7 +1180,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) log_debug(LD_APP|LD_CIRC, "Attaching apconn to circ %d (stream %d sec old).", - circ->_base.n_circ_id, conn_age); + circ->n_circ_id, conn_age); /* here, print the circ's path. so people can figure out which circs are * sucking. */ circuit_log_path(LOG_INFO,LD_APP|LD_CIRC,circ); @@ -1257,7 +1189,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) return connection_ap_handshake_attach_chosen_circuit(conn, circ); } else { /* we're a rendezvous conn */ - origin_circuit_t *rendcirc=NULL, *introcirc=NULL; + circuit_t *rendcirc=NULL, *introcirc=NULL; tor_assert(!conn->cpath_layer); @@ -1273,25 +1205,25 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) log_info(LD_REND, "rend joined circ %d already here. attaching. " "(stream %d sec old)", - rendcirc->_base.n_circ_id, conn_age); + rendcirc->n_circ_id, conn_age); /* Mark rendezvous circuits as 'newly dirty' every time you use * them, since the process of rebuilding a rendezvous circ is so * expensive. There is a tradeoffs between linkability and * feasibility, at this point. */ - rendcirc->_base.timestamp_dirty = time(NULL); + rendcirc->timestamp_dirty = time(NULL); link_apconn_to_circ(conn, rendcirc); if (connection_ap_handshake_send_begin(conn, rendcirc) < 0) return 0; /* already marked, let them fade away */ return 1; } - if (rendcirc && (rendcirc->_base.purpose == + if (rendcirc && (rendcirc->purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED)) { log_info(LD_REND, "pending-join circ %d already here, with intro ack. " "Stalling. (stream %d sec old)", - rendcirc->_base.n_circ_id, conn_age); + rendcirc->n_circ_id, conn_age); return 0; } @@ -1305,8 +1237,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) tor_assert(introcirc); log_info(LD_REND, "Intro circ %d present and awaiting ack (rend %d). " "Stalling. (stream %d sec old)", - introcirc->_base.n_circ_id, - rendcirc ? rendcirc->_base.n_circ_id : 0, + introcirc->n_circ_id, rendcirc ? rendcirc->n_circ_id : 0, conn_age); return 0; } @@ -1314,34 +1245,32 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) /* now rendcirc and introcirc are each either undefined or not finished */ if (rendcirc && introcirc && - rendcirc->_base.purpose == CIRCUIT_PURPOSE_C_REND_READY) { + rendcirc->purpose == CIRCUIT_PURPOSE_C_REND_READY) { log_info(LD_REND, "ready rend circ %d already here (no intro-ack yet on " "intro %d). (stream %d sec old)", - rendcirc->_base.n_circ_id, - introcirc->_base.n_circ_id, conn_age); + rendcirc->n_circ_id, introcirc->n_circ_id, conn_age); - tor_assert(introcirc->_base.purpose == CIRCUIT_PURPOSE_C_INTRODUCING); - if (introcirc->_base.state == CIRCUIT_STATE_OPEN) { + tor_assert(introcirc->purpose == CIRCUIT_PURPOSE_C_INTRODUCING); + if (introcirc->state == CIRCUIT_STATE_OPEN) { log_info(LD_REND,"found open intro circ %d (rend %d); sending " "introduction. (stream %d sec old)", - introcirc->_base.n_circ_id, rendcirc->_base.n_circ_id, - conn_age); + introcirc->n_circ_id, rendcirc->n_circ_id, conn_age); if (rend_client_send_introduction(introcirc, rendcirc) < 0) { return -1; } - rendcirc->_base.timestamp_dirty = time(NULL); - introcirc->_base.timestamp_dirty = time(NULL); - assert_circuit_ok(TO_CIRCUIT(rendcirc)); - assert_circuit_ok(TO_CIRCUIT(introcirc)); + rendcirc->timestamp_dirty = time(NULL); + introcirc->timestamp_dirty = time(NULL); + assert_circuit_ok(rendcirc); + assert_circuit_ok(introcirc); return 0; } } log_info(LD_REND, "Intro (%d) and rend (%d) circs are not both ready. " "Stalling conn. (%d sec old)", - introcirc ? introcirc->_base.n_circ_id : 0, - rendcirc ? rendcirc->_base.n_circ_id : 0, conn_age); + introcirc ? introcirc->n_circ_id : 0, + rendcirc ? rendcirc->n_circ_id : 0, conn_age); return 0; } } |